summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
committerOswald Buddenhagen <oswald.buddenhagen@digia.com>2014-02-19 10:06:25 +0100
commit30fd22b9574def54726e7b193127cc0c901c1b4c (patch)
tree96dfc923044db0515064ba39d052d9ed577e3e40
parentd7b0581c1c2ef60c08d238dae39298af6904918f (diff)
parent6aa09bbce59828d028f6d1e81d2bfc6ba537aae1 (diff)
Merge remote-tracking branch 'origin/dev' into stable
-rw-r--r--config.tests/qpa/direct2d/direct2d.cpp57
-rw-r--r--config.tests/qpa/direct2d/direct2d.pro4
-rw-r--r--config.tests/qpa/egl-x11/egl-x11.cpp62
-rw-r--r--config.tests/qpa/egl-x11/egl-x11.pro12
-rw-r--r--config.tests/unix/iconv/iconv.pro2
-rw-r--r--config.tests/unix/journald/journald.c48
-rw-r--r--config.tests/unix/journald/journald.pro6
-rw-r--r--config.tests/unix/lgmon/lgmon.cpp49
-rw-r--r--config.tests/unix/lgmon/lgmon.pro3
-rw-r--r--config.tests/unix/neon/neon.pro4
-rw-r--r--config.tests/unix/odbc/odbc.pro2
-rw-r--r--config.tests/unix/qqnx_imf/qqnx_imf.cpp (renamed from config.tests/unix/neon/neon.cpp)13
-rw-r--r--config.tests/unix/qqnx_imf/qqnx_imf.pro3
-rw-r--r--config.tests/x11/opengl/opengl.pro2
-rwxr-xr-xconfigure159
-rw-r--r--dist/changes-5.3.036
-rw-r--r--examples/embedded/styleexample/stylewidget.cpp2
-rw-r--r--examples/ipc/sharedmemory/dialog.cpp6
-rw-r--r--examples/network/bearermonitor/bearermonitor.cpp8
-rw-r--r--examples/network/bearermonitor/bearermonitor.h4
-rw-r--r--examples/network/dnslookup/dnslookup.cpp13
-rw-r--r--examples/network/loopback/dialog.cpp4
-rw-r--r--examples/network/network.pro2
-rw-r--r--examples/network/securesocketclient/main.cpp4
-rw-r--r--examples/network/torrent/peerwireclient.cpp2
-rw-r--r--examples/network/torrent/torrentserver.cpp2
-rw-r--r--examples/opengl/cube/geometryengine.cpp48
-rw-r--r--examples/opengl/framebufferobject2/glwidget.cpp30
-rw-r--r--examples/opengl/framebufferobject2/main.cpp4
-rw-r--r--examples/opengl/pbuffers/main.cpp4
-rw-r--r--examples/opengl/pbuffers2/main.cpp4
-rw-r--r--examples/opengl/samplebuffers/main.cpp8
-rw-r--r--examples/opengl/textures/glwidget.cpp36
-rw-r--r--examples/opengl/textures/glwidget.h2
-rw-r--r--examples/touch/fingerpaint/mainwindow.cpp2
-rw-r--r--examples/widgets/doc/src/treemodelcompleter.qdoc2
-rw-r--r--examples/widgets/effects/blurpicker/blurpicker.cpp2
-rw-r--r--examples/widgets/effects/lighting/lighting.cpp2
-rw-r--r--examples/widgets/graphicsview/boxes/glbuffers.h6
-rw-r--r--examples/widgets/graphicsview/boxes/glextensions.cpp70
-rw-r--r--examples/widgets/graphicsview/boxes/glextensions.h46
-rw-r--r--examples/widgets/graphicsview/boxes/scene.cpp16
-rw-r--r--examples/widgets/graphicsview/elasticnodes/graphwidget.cpp4
-rw-r--r--examples/widgets/itemviews/pixelator/mainwindow.cpp10
-rw-r--r--examples/widgets/layouts/basiclayouts/dialog.cpp2
-rw-r--r--examples/widgets/layouts/borderlayout/borderlayout.h12
-rw-r--r--examples/widgets/mainwindows/mainwindow/colorswatch.cpp2
-rw-r--r--examples/widgets/mainwindows/mainwindow/colorswatch.h2
-rw-r--r--examples/widgets/mainwindows/mdi/mdichild.cpp4
-rw-r--r--examples/widgets/mainwindows/sdi/mainwindow.cpp4
-rw-r--r--examples/widgets/richtext/textedit/textedit.cpp2
-rw-r--r--examples/widgets/tools/codecs/mainwindow.cpp2
-rw-r--r--examples/widgets/tutorials/modelview/5_edit/mymodel.cpp12
-rw-r--r--examples/widgets/widgets/calculator/calculator.cpp24
-rw-r--r--examples/widgets/widgets/lineedits/window.cpp4
-rw-r--r--examples/widgets/widgets/scribble/mainwindow.cpp2
-rw-r--r--examples/widgets/widgets/spinboxes/window.cpp29
-rw-r--r--examples/widgets/widgets/spinboxes/window.h3
-rw-r--r--examples/widgets/widgets/tetrix/tetrixboard.cpp54
-rw-r--r--examples/widgets/widgets/wiggly/wigglywidget.cpp4
-rw-r--r--mkspecs/common/clang.conf1
-rw-r--r--mkspecs/common/gcc-base.conf1
-rw-r--r--mkspecs/common/mac/qplatformdefs.h4
-rw-r--r--mkspecs/common/wince/qplatformdefs.h82
-rw-r--r--mkspecs/common/winrt_winphone/assets/logo_large.pngbin0 -> 2638 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/logo_medium.pngbin0 -> 1907 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/logo_small.pngbin0 -> 737 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/logo_splash.pngbin0 -> 5752 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/logo_store.pngbin0 -> 1159 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/tile_iconic_medium.pngbin0 -> 3166 bytes
-rw-r--r--mkspecs/common/winrt_winphone/assets/tile_iconic_small.pngbin0 -> 1958 bytes
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.0/AppxManifest.xml.in39
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in39
-rw-r--r--mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in44
-rw-r--r--mkspecs/common/winrt_winphone/qmake.conf25
-rw-r--r--mkspecs/common/winrt_winphone/qplatformdefs.h141
-rw-r--r--mkspecs/cygwin-g++/qplatformdefs.h6
-rw-r--r--mkspecs/darwin-g++/qplatformdefs.h4
-rw-r--r--mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp7
-rw-r--r--mkspecs/devices/linux-tegra2-g++/qmake.conf4
-rw-r--r--mkspecs/features/configure.prf6
-rw-r--r--mkspecs/features/create_cmake.prf2
-rw-r--r--mkspecs/features/ctest_testcase_common.prf2
-rw-r--r--mkspecs/features/default_post.prf2
-rw-r--r--mkspecs/features/mac/default_post.prf22
-rw-r--r--mkspecs/features/moc.prf57
-rw-r--r--mkspecs/features/precompile_header.prf24
-rw-r--r--mkspecs/features/qlalr.prf49
-rw-r--r--mkspecs/features/qml_plugin.prf2
-rw-r--r--mkspecs/features/qt.prf2
-rw-r--r--mkspecs/features/qt_common.prf22
-rw-r--r--mkspecs/features/qt_module.prf31
-rw-r--r--mkspecs/features/qt_parts.prf2
-rw-r--r--mkspecs/features/qt_plugin.prf2
-rw-r--r--mkspecs/features/simd.prf4
-rw-r--r--mkspecs/features/win32/windeployqt.prf19
-rw-r--r--mkspecs/features/win32/windows.prf2
-rw-r--r--mkspecs/features/winrt/console.prf5
-rw-r--r--mkspecs/features/winrt/package_manifest.prf121
-rw-r--r--mkspecs/freebsd-g++/qplatformdefs.h4
-rw-r--r--mkspecs/hurd-g++/qplatformdefs.h4
-rw-r--r--mkspecs/irix-cc-64/qplatformdefs.h4
-rw-r--r--mkspecs/irix-cc/qplatformdefs.h4
-rw-r--r--mkspecs/irix-g++/qplatformdefs.h4
-rw-r--r--mkspecs/linux-clang/qplatformdefs.h8
-rw-r--r--mkspecs/linux-cxx/qplatformdefs.h4
-rw-r--r--mkspecs/linux-g++/qplatformdefs.h4
-rw-r--r--mkspecs/linux-icc/qmake.conf1
-rw-r--r--mkspecs/linux-kcc/qplatformdefs.h4
-rw-r--r--mkspecs/linux-llvm/qplatformdefs.h4
-rw-r--r--mkspecs/linux-lsb-g++/qplatformdefs.h4
-rw-r--r--mkspecs/linux-pgcc/qplatformdefs.h4
-rw-r--r--mkspecs/lynxos-g++/qplatformdefs.h4
-rw-r--r--mkspecs/macx-icc/qmake.conf43
-rw-r--r--mkspecs/macx-ios-clang/features/default_post.prf21
-rw-r--r--mkspecs/macx-ios-clang/features/default_pre.prf9
-rw-r--r--mkspecs/macx-ios-clang/features/qt_parts.prf5
-rw-r--r--mkspecs/netbsd-g++/qplatformdefs.h4
-rw-r--r--mkspecs/openbsd-g++/qplatformdefs.h4
-rw-r--r--mkspecs/qnx-armv7le-qcc/qplatformdefs.h7
-rw-r--r--mkspecs/qnx-x86-qcc/qplatformdefs.h7
-rw-r--r--mkspecs/sco-cc/qplatformdefs.h4
-rw-r--r--mkspecs/sco-g++/qplatformdefs.h4
-rw-r--r--mkspecs/solaris-cc-64/qplatformdefs.h4
-rw-r--r--mkspecs/solaris-cc/qplatformdefs.h4
-rw-r--r--mkspecs/solaris-g++-64/qplatformdefs.h4
-rw-r--r--mkspecs/solaris-g++/qplatformdefs.h4
-rw-r--r--mkspecs/tru64-cxx/qplatformdefs.h4
-rw-r--r--mkspecs/tru64-g++/qplatformdefs.h4
-rw-r--r--mkspecs/unixware-cc/qplatformdefs.h4
-rw-r--r--mkspecs/unixware-g++/qplatformdefs.h4
-rw-r--r--mkspecs/unsupported/freebsd-clang/qmake.conf38
-rw-r--r--mkspecs/unsupported/freebsd-clang/qplatformdefs.h42
-rw-r--r--mkspecs/unsupported/integrity-ghs/qplatformdefs.h54
-rw-r--r--mkspecs/unsupported/linux-armcc/qplatformdefs.h4
-rw-r--r--mkspecs/unsupported/linux-libc++-clang/qmake.conf20
-rw-r--r--mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h100
-rw-r--r--mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h4
-rw-r--r--mkspecs/unsupported/win32-msvc2003/qplatformdefs.h80
-rw-r--r--mkspecs/win32-g++/qmake.conf6
-rw-r--r--mkspecs/win32-g++/qplatformdefs.h86
-rw-r--r--mkspecs/win32-icc/qmake.conf5
-rw-r--r--mkspecs/win32-msvc2005/qmake.conf5
-rw-r--r--mkspecs/win32-msvc2005/qplatformdefs.h82
-rw-r--r--mkspecs/win32-msvc2008/qmake.conf5
-rw-r--r--mkspecs/win32-msvc2010/qmake.conf5
-rw-r--r--mkspecs/win32-msvc2012/qmake.conf5
-rw-r--r--mkspecs/win32-msvc2013/qmake.conf5
-rw-r--r--mkspecs/winphone-arm-msvc2012/qmake.conf5
-rw-r--r--mkspecs/winphone-arm-msvc2012/qplatformdefs.h2
-rw-r--r--mkspecs/winphone-x86-msvc2012/qmake.conf7
-rw-r--r--mkspecs/winphone-x86-msvc2012/qplatformdefs.h2
-rw-r--r--mkspecs/winrt-arm-msvc2012/qmake.conf6
-rw-r--r--mkspecs/winrt-arm-msvc2012/qplatformdefs.h2
-rw-r--r--mkspecs/winrt-arm-msvc2013/qmake.conf22
-rw-r--r--mkspecs/winrt-arm-msvc2013/qplatformdefs.h42
-rw-r--r--mkspecs/winrt-x64-msvc2012/qmake.conf6
-rw-r--r--mkspecs/winrt-x64-msvc2012/qplatformdefs.h2
-rw-r--r--mkspecs/winrt-x64-msvc2013/qmake.conf22
-rw-r--r--mkspecs/winrt-x64-msvc2013/qplatformdefs.h42
-rw-r--r--mkspecs/winrt-x86-msvc2012/qmake.conf10
-rw-r--r--mkspecs/winrt-x86-msvc2012/qplatformdefs.h2
-rw-r--r--mkspecs/winrt-x86-msvc2013/qmake.conf22
-rw-r--r--mkspecs/winrt-x86-msvc2013/qplatformdefs.h42
-rw-r--r--qmake/Makefile.unix6
-rw-r--r--qmake/Makefile.win327
-rw-r--r--qmake/generators/makefile.cpp26
-rw-r--r--qmake/generators/makefile.h20
-rw-r--r--qmake/generators/makefiledeps.cpp26
-rw-r--r--qmake/generators/makefiledeps.h6
-rw-r--r--qmake/generators/unix/unixmake.cpp29
-rw-r--r--qmake/generators/unix/unixmake2.cpp58
-rw-r--r--qmake/generators/win32/mingw_make.cpp60
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp103
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.h1
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp74
-rw-r--r--qmake/generators/win32/msvc_nmake.h2
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp50
-rw-r--r--qmake/generators/win32/msvc_objectmodel.h24
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp45
-rw-r--r--qmake/generators/win32/msvc_vcproj.h1
-rw-r--r--qmake/generators/win32/winmakefile.cpp44
-rw-r--r--qmake/option.cpp4
-rw-r--r--qmake/project.h1
-rw-r--r--qmake/qmake.pri3
-rw-r--r--qtbase.pro1
-rw-r--r--src/3rdparty/angle/include/EGL/eglplatform.h10
-rw-r--r--src/3rdparty/angle/src/compiler/osinclude.h35
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_posix.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_win.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_winrt.cpp75
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp8
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h4
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp45
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h7
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp4
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.cpp8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp55
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h27
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp298
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp32
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/utilities.cpp53
-rw-r--r--src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-shape.h1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/config.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc840
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.h50
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc138
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh28
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h5
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc184
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc417
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc172
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh2083
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh369
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh38
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc61
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc36
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh15
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h54
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot.h9
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh21
-rw-r--r--src/3rdparty/harfbuzz.pri16
-rw-r--r--src/3rdparty/libjpeg.pri2
-rw-r--r--src/3rdparty/libpng/pngpriv.h2
-rw-r--r--src/3rdparty/pcre/AUTHORS6
-rw-r--r--src/3rdparty/pcre/LICENCE6
-rw-r--r--src/3rdparty/pcre/config.h1
-rw-r--r--src/3rdparty/pcre/patches/bug_1423_jit_condition_misoptimization_fix.diff15
-rw-r--r--src/3rdparty/pcre/patches/r1340_fix_jit_on_android.patch18
-rw-r--r--src/3rdparty/pcre/pcre.h50
-rw-r--r--src/3rdparty/pcre/pcre16_valid_utf16.c25
-rw-r--r--src/3rdparty/pcre/pcre_byte_order.c19
-rw-r--r--src/3rdparty/pcre/pcre_chartables.c2
-rw-r--r--src/3rdparty/pcre/pcre_compile.c3621
-rw-r--r--src/3rdparty/pcre/pcre_config.c4
-rw-r--r--src/3rdparty/pcre/pcre_dfa_exec.c230
-rw-r--r--src/3rdparty/pcre/pcre_exec.c959
-rw-r--r--src/3rdparty/pcre/pcre_fullinfo.c16
-rw-r--r--src/3rdparty/pcre/pcre_internal.h453
-rw-r--r--src/3rdparty/pcre/pcre_jit_compile.c3414
-rw-r--r--src/3rdparty/pcre/pcre_maketables.c27
-rw-r--r--src/3rdparty/pcre/pcre_string_utils.c8
-rw-r--r--src/3rdparty/pcre/pcre_study.c86
-rw-r--r--src/3rdparty/pcre/pcre_tables.c15
-rw-r--r--src/3rdparty/pcre/pcre_ucd.c753
-rw-r--r--src/3rdparty/pcre/pcre_valid_utf8.c15
-rw-r--r--src/3rdparty/pcre/pcre_xclass.c101
-rw-r--r--src/3rdparty/pcre/sljit/sljitConfig.h1
-rw-r--r--src/3rdparty/pcre/sljit/sljitConfigInternal.h19
-rw-r--r--src/3rdparty/pcre/sljit/sljitExecAllocator.c23
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.c60
-rw-r--r--src/3rdparty/pcre/sljit/sljitLir.h37
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c10
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeARM_v5.c12
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c10
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativePPC_common.c10
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeSPARC_common.c37
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_32.c10
-rw-r--r--src/3rdparty/pcre/sljit/sljitNativeX86_common.c151
-rw-r--r--src/3rdparty/pcre/ucp.h5
-rw-r--r--src/3rdparty/sqlite/shell.c758
-rw-r--r--src/3rdparty/sqlite/sqlite3.c26239
-rw-r--r--src/3rdparty/sqlite/sqlite3.h251
-rw-r--r--src/3rdparty/xkbcommon.pri2
-rw-r--r--src/3rdparty/zlib_dependency.pri2
-rw-r--r--src/android/jar/AndroidManifest.xml1
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java148
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtLayout.java11
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java80
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java105
-rw-r--r--src/angle/patches/0012-ANGLE-Support-WinRT.patch1131
-rw-r--r--src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch990
-rw-r--r--src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch51
-rw-r--r--src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch85
-rw-r--r--src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch28
-rw-r--r--src/angle/src/common/common.pri2
-rw-r--r--src/angle/src/compiler/translator_common.pro9
-rw-r--r--src/angle/src/compiler/translator_hlsl.pro2
-rw-r--r--src/angle/src/config.pri5
-rw-r--r--src/angle/src/d3dcompiler/d3dcompiler.pro15
-rw-r--r--src/angle/src/d3dcompiler/d3dcompiler_qt.def3
-rw-r--r--src/angle/src/d3dcompiler/d3dcompiler_qtd.def3
-rw-r--r--src/angle/src/d3dcompiler/main.cpp315
-rw-r--r--src/angle/src/libEGL/libEGL.pro2
-rw-r--r--src/angle/src/libGLESv2/libGLESv2.pro10
-rw-r--r--src/angle/src/src.pro1
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp2
-rw-r--r--src/corelib/arch/arch.pri8
-rw-r--r--src/corelib/arch/qatomic_alpha.h527
-rw-r--r--src/corelib/arch/qatomic_armv5.h10
-rw-r--r--src/corelib/arch/qatomic_armv6.h123
-rw-r--r--src/corelib/arch/qatomic_bfin.h350
-rw-r--r--src/corelib/arch/qatomic_bootstrap.h1
-rw-r--r--src/corelib/arch/qatomic_cxx11.h49
-rw-r--r--src/corelib/arch/qatomic_gcc.h26
-rw-r--r--src/corelib/arch/qatomic_ia64.h63
-rw-r--r--src/corelib/arch/qatomic_integrity.h295
-rw-r--r--src/corelib/arch/qatomic_mips.h38
-rw-r--r--src/corelib/arch/qatomic_msvc.h224
-rw-r--r--src/corelib/arch/qatomic_power.h521
-rw-r--r--src/corelib/arch/qatomic_s390.h433
-rw-r--r--src/corelib/arch/qatomic_sh4a.h540
-rw-r--r--src/corelib/arch/qatomic_sparc.h532
-rw-r--r--src/corelib/arch/qatomic_unix.cpp13
-rw-r--r--src/corelib/arch/qatomic_unix.h43
-rw-r--r--src/corelib/arch/qatomic_vxworks.h330
-rw-r--r--src/corelib/arch/qatomic_x86.h56
-rw-r--r--src/corelib/codecs/qutfcodec.cpp392
-rw-r--r--src/corelib/codecs/qutfcodec_p.h224
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/doc/snippets/code/doc_src_properties.cpp2
-rw-r--r--src/corelib/doc/snippets/code/doc_src_qalgorithms.cpp10
-rw-r--r--src/corelib/doc/snippets/code/doc_src_qiterator.cpp16
-rw-r--r--src/corelib/doc/snippets/code/qlogging/qlogging.cpp4
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp8
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qstringiterator.cpp72
-rw-r--r--src/corelib/doc/snippets/qbytearraylist/main.cpp51
-rw-r--r--src/corelib/doc/snippets/qbytearraylist/qbytearraylist.pro2
-rw-r--r--src/corelib/doc/snippets/qloggingcategory/main.cpp21
-rw-r--r--src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp8
-rw-r--r--src/corelib/global/global.pri6
-rw-r--r--src/corelib/global/qcompilerdetection.h81
-rw-r--r--src/corelib/global/qflags.h12
-rw-r--r--src/corelib/global/qglobal.cpp43
-rw-r--r--src/corelib/global/qglobal.h42
-rw-r--r--src/corelib/global/qlibraryinfo.cpp108
-rw-r--r--src/corelib/global/qlibraryinfo.h6
-rw-r--r--src/corelib/global/qlogging.cpp327
-rw-r--r--src/corelib/global/qlogging.h17
-rw-r--r--src/corelib/global/qnamespace.h35
-rw-r--r--src/corelib/global/qnamespace.qdoc82
-rw-r--r--src/corelib/global/qnumeric.cpp136
-rw-r--r--src/corelib/global/qnumeric.h3
-rw-r--r--src/corelib/global/qprocessordetection.h20
-rw-r--r--src/corelib/global/qtypeinfo.h17
-rw-r--r--src/corelib/io/io.pri10
-rw-r--r--src/corelib/io/qdatastream.cpp3
-rw-r--r--src/corelib/io/qdatastream.h5
-rw-r--r--src/corelib/io/qdebug.h32
-rw-r--r--src/corelib/io/qdir.cpp2
-rw-r--r--src/corelib/io/qdiriterator.cpp2
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp192
-rw-r--r--src/corelib/io/qfilesystementry.cpp6
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp4
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp14
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h6
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp8
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm507
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h142
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp6
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp15
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp73
-rw-r--r--src/corelib/io/qlockfile_win.cpp14
-rw-r--r--src/corelib/io/qloggingcategory.cpp151
-rw-r--r--src/corelib/io/qloggingcategory.h36
-rw-r--r--src/corelib/io/qloggingregistry.cpp137
-rw-r--r--src/corelib/io/qloggingregistry_p.h36
-rw-r--r--src/corelib/io/qprocess.cpp40
-rw-r--r--src/corelib/io/qprocess.h1
-rw-r--r--src/corelib/io/qprocess_unix.cpp100
-rw-r--r--src/corelib/io/qprocess_win.cpp2
-rw-r--r--src/corelib/io/qresource.cpp24
-rw-r--r--src/corelib/io/qsettings.cpp87
-rw-r--r--src/corelib/io/qsettings.h2
-rw-r--r--src/corelib/io/qstandardpaths.cpp244
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp9
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp25
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp28
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp127
-rw-r--r--src/corelib/io/qtemporaryfile.cpp17
-rw-r--r--src/corelib/io/qtextstream.cpp32
-rw-r--r--src/corelib/io/qurlidna.cpp2
-rw-r--r--src/corelib/io/qurlrecode.cpp186
-rw-r--r--src/corelib/io/qwindowspipereader.cpp3
-rw-r--r--src/corelib/io/qwindowspipereader_p.h2
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp4
-rw-r--r--src/corelib/io/qwinoverlappedionotifier.cpp139
-rw-r--r--src/corelib/io/qwinoverlappedionotifier_p.h47
-rw-r--r--src/corelib/itemmodels/qitemselectionmodel.cpp3
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp10
-rw-r--r--src/corelib/json/qjsonarray.cpp25
-rw-r--r--src/corelib/json/qjsonarray.h8
-rw-r--r--src/corelib/json/qjsonparser.cpp45
-rw-r--r--src/corelib/json/qjsonvalue.cpp22
-rw-r--r--src/corelib/json/qjsonvalue.h5
-rw-r--r--src/corelib/json/qjsonwriter.cpp54
-rw-r--r--src/corelib/kernel/kernel.pri28
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp6
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h2
-rw-r--r--src/corelib/kernel/qcore_mac_p.h14
-rw-r--r--src/corelib/kernel/qcore_unix_p.h2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp102
-rw-r--r--src/corelib/kernel/qcoreapplication.h7
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h1
-rw-r--r--src/corelib/kernel/qcorecmdlineargs_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h20
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h32
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp457
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt_p.h109
-rw-r--r--src/corelib/kernel/qfunctions_p.h2
-rw-r--r--src/corelib/kernel/qfunctions_winrt.cpp105
-rw-r--r--src/corelib/kernel/qfunctions_winrt.h122
-rw-r--r--src/corelib/kernel/qjni_p.h12
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp35
-rw-r--r--src/corelib/kernel/qjnihelpers_p.h13
-rw-r--r--src/corelib/kernel/qmetaobject.cpp14
-rw-r--r--src/corelib/kernel/qmetaobjectbuilder.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp133
-rw-r--r--src/corelib/kernel/qobject.h77
-rw-r--r--src/corelib/kernel/qobject_p.h5
-rw-r--r--src/corelib/kernel/qobjectdefs.h6
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h4
-rw-r--r--src/corelib/kernel/qppsattribute.cpp308
-rw-r--r--src/corelib/kernel/qppsattribute_p.h139
-rw-r--r--src/corelib/kernel/qppsattributeprivate_p.h91
-rw-r--r--src/corelib/kernel/qppsobject.cpp964
-rw-r--r--src/corelib/kernel/qppsobject_p.h130
-rw-r--r--src/corelib/kernel/qppsobjectprivate_p.h128
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
-rw-r--r--src/corelib/kernel/qvariant_p.h2
-rw-r--r--src/corelib/kernel/qwineventnotifier.cpp4
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp2
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp6
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp108
-rw-r--r--src/corelib/thread/qatomic.cpp811
-rw-r--r--src/corelib/thread/qatomic.h71
-rw-r--r--src/corelib/thread/qbasicatomic.h126
-rw-r--r--src/corelib/thread/qgenericatomic.h160
-rw-r--r--src/corelib/thread/qmutex_win.cpp9
-rw-r--r--src/corelib/thread/qoldbasicatomic.h143
-rw-r--r--src/corelib/thread/qthread.cpp2
-rw-r--r--src/corelib/thread/qthread_p.h9
-rw-r--r--src/corelib/thread/qthread_win.cpp154
-rw-r--r--src/corelib/thread/qthreadpool.cpp28
-rw-r--r--src/corelib/thread/qthreadpool_p.h3
-rw-r--r--src/corelib/thread/qwaitcondition.h6
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp11
-rw-r--r--src/corelib/thread/thread.pri3
-rw-r--r--src/corelib/tools/qalgorithms.h86
-rw-r--r--src/corelib/tools/qarraydata.h4
-rw-r--r--src/corelib/tools/qbitarray.cpp4
-rw-r--r--src/corelib/tools/qbytearray.cpp125
-rw-r--r--src/corelib/tools/qbytearraylist.cpp258
-rw-r--r--src/corelib/tools/qbytearraylist.h125
-rw-r--r--src/corelib/tools/qchar.cpp70
-rw-r--r--src/corelib/tools/qchar.h34
-rw-r--r--src/corelib/tools/qcollator_win.cpp24
-rw-r--r--src/corelib/tools/qdatetime.cpp18
-rw-r--r--src/corelib/tools/qhash.cpp95
-rw-r--r--src/corelib/tools/qhash.h5
-rw-r--r--src/corelib/tools/qlinkedlist.h2
-rw-r--r--src/corelib/tools/qlocale.cpp444
-rw-r--r--src/corelib/tools/qlocale.h5
-rw-r--r--src/corelib/tools/qlocale.qdoc5
-rw-r--r--src/corelib/tools/qlocale_data_p.h8890
-rw-r--r--src/corelib/tools/qlocale_p.h197
-rw-r--r--src/corelib/tools/qlocale_tools.cpp78
-rw-r--r--src/corelib/tools/qlocale_tools_p.h3
-rw-r--r--src/corelib/tools/qlocale_win.cpp218
-rw-r--r--src/corelib/tools/qregexp.h2
-rw-r--r--src/corelib/tools/qsimd.cpp10
-rw-r--r--src/corelib/tools/qsimd_p.h70
-rw-r--r--src/corelib/tools/qstring.cpp1169
-rw-r--r--src/corelib/tools/qstring.h63
-rw-r--r--src/corelib/tools/qstring_compat.cpp67
-rw-r--r--src/corelib/tools/qstringbuilder.h13
-rw-r--r--src/corelib/tools/qstringiterator.qdoc328
-rw-r--r--src/corelib/tools/qstringiterator_p.h233
-rw-r--r--src/corelib/tools/qstringlist.cpp2
-rw-r--r--src/corelib/tools/qtimezone.cpp34
-rw-r--r--src/corelib/tools/qtimezoneprivate.cpp48
-rw-r--r--src/corelib/tools/qtimezoneprivate_data_p.h1712
-rw-r--r--src/corelib/tools/qtimezoneprivate_icu.cpp10
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm12
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h16
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp46
-rw-r--r--src/corelib/tools/qtimezoneprivate_win.cpp28
-rw-r--r--src/corelib/tools/qunicodetables.cpp11458
-rw-r--r--src/corelib/tools/qunicodetables_p.h7
-rw-r--r--src/corelib/tools/qunicodetools.cpp80
-rw-r--r--src/corelib/tools/qvarlengtharray.h49
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc39
-rw-r--r--src/corelib/tools/qvector_msvc.cpp60
-rw-r--r--src/corelib/tools/tools.pri14
-rw-r--r--src/corelib/xml/qxmlstream.cpp2
-rw-r--r--src/dbus/qdbus_symbols_p.h3
-rw-r--r--src/dbus/qdbusabstractinterface.cpp54
-rw-r--r--src/dbus/qdbusabstractinterface_p.h2
-rw-r--r--src/dbus/qdbusconnection_p.h2
-rw-r--r--src/dbus/qdbusdemarshaller.cpp4
-rw-r--r--src/dbus/qdbusintegrator.cpp13
-rw-r--r--src/dbus/qdbusinternalfilters.cpp6
-rw-r--r--src/dbus/qdbusserver.cpp27
-rw-r--r--src/dbus/qdbusserver.h3
-rw-r--r--src/dbus/qdbusxmlgenerator.cpp21
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp2
-rw-r--r--src/gui/doc/snippets/image/supportedformat.cpp8
-rw-r--r--src/gui/doc/src/coordsys.qdoc2
-rw-r--r--src/gui/doc/src/paintsystem.qdoc4
-rw-r--r--src/gui/gui.pro4
-rw-r--r--src/gui/image/image.pri15
-rw-r--r--src/gui/image/qbmphandler.cpp107
-rw-r--r--src/gui/image/qimage.cpp2509
-rw-r--r--src/gui/image/qimage.h29
-rw-r--r--src/gui/image/qimage_compat.cpp (renamed from src/gui/image/qimage_avx.cpp)35
-rw-r--r--src/gui/image/qimage_conversions.cpp2183
-rw-r--r--src/gui/image/qimage_neon.cpp4
-rw-r--r--src/gui/image/qimage_p.h13
-rw-r--r--src/gui/image/qimage_sse2.cpp2
-rw-r--r--src/gui/image/qimagereader.cpp29
-rw-r--r--src/gui/image/qjpeghandler.cpp10
-rw-r--r--src/gui/image/qpixmap.cpp22
-rw-r--r--src/gui/image/qpixmap.h7
-rw-r--r--src/gui/image/qpixmap_blitter.cpp2
-rw-r--r--src/gui/image/qpixmap_raster.cpp13
-rw-r--r--src/gui/image/qpixmap_raster_p.h1
-rw-r--r--src/gui/image/qplatformpixmap.h9
-rw-r--r--src/gui/image/qpnghandler.pri2
-rw-r--r--src/gui/image/qxbmhandler.cpp24
-rw-r--r--src/gui/kernel/kernel.pri3
-rw-r--r--src/gui/kernel/qdrag.cpp6
-rw-r--r--src/gui/kernel/qevent.cpp32
-rw-r--r--src/gui/kernel/qevent.h3
-rw-r--r--src/gui/kernel/qguiapplication.cpp174
-rw-r--r--src/gui/kernel/qguiapplication.h4
-rw-r--r--src/gui/kernel/qguiapplication_p.h16
-rw-r--r--src/gui/kernel/qguivariant.cpp2
-rw-r--r--src/gui/kernel/qinputmethod.cpp25
-rw-r--r--src/gui/kernel/qinputmethod.h3
-rw-r--r--src/gui/kernel/qkeysequence.cpp2
-rw-r--r--src/gui/kernel/qopenglcontext.cpp59
-rw-r--r--src/gui/kernel/qplatformdialoghelper.cpp88
-rw-r--r--src/gui/kernel/qplatformdialoghelper.h120
-rw-r--r--src/gui/kernel/qplatformintegration.cpp2
-rw-r--r--src/gui/kernel/qplatformintegration.h6
-rw-r--r--src/gui/kernel/qplatformmenu.cpp55
-rw-r--r--src/gui/kernel/qplatformmenu.h2
-rw-r--r--src/gui/kernel/qplatformsessionmanager.h6
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon.h2
-rw-r--r--src/gui/kernel/qplatformsystemtrayicon_qpa.cpp16
-rw-r--r--src/gui/kernel/qplatformtheme.cpp65
-rw-r--r--src/gui/kernel/qplatformtheme.h6
-rw-r--r--src/gui/kernel/qplatformwindow.cpp41
-rw-r--r--src/gui/kernel/qplatformwindow.h3
-rw-r--r--src/gui/kernel/qscreen.cpp11
-rw-r--r--src/gui/kernel/qshortcutmap.cpp2
-rw-r--r--src/gui/kernel/qstylehints.cpp117
-rw-r--r--src/gui/kernel/qstylehints.h8
-rw-r--r--src/gui/kernel/qsurface.cpp16
-rw-r--r--src/gui/kernel/qsurface.h4
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp124
-rw-r--r--src/gui/kernel/qsurfaceformat.h12
-rw-r--r--src/gui/kernel/qwindow.cpp53
-rw-r--r--src/gui/kernel/qwindow_p.h4
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp20
-rw-r--r--src/gui/kernel/qwindowsysteminterface.h16
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h11
-rw-r--r--src/gui/math3d/qvector2d.h82
-rw-r--r--src/gui/math3d/qvector3d.h86
-rw-r--r--src/gui/math3d/qvector4d.h90
-rw-r--r--src/gui/opengl/opengl.pri10
-rw-r--r--src/gui/opengl/qopengl.h10
-rw-r--r--src/gui/opengl/qopenglbuffer.cpp16
-rw-r--r--src/gui/opengl/qopenglengineshadermanager.cpp5
-rw-r--r--src/gui/opengl/qopenglengineshadersource_p.h8
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp228
-rw-r--r--src/gui/opengl/qopenglframebufferobject.h13
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h13
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp318
-rw-r--r--src/gui/opengl/qopenglfunctions.h11
-rw-r--r--src/gui/opengl/qopenglgradientcache.cpp10
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp123
-rw-r--r--src/gui/opengl/qopenglproxy_win.cpp4600
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp28
-rw-r--r--src/gui/opengl/qopengltexture.cpp734
-rw-r--r--src/gui/opengl/qopengltexture.h44
-rw-r--r--src/gui/opengl/qopengltexture_p.h4
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp393
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h86
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp21
-rw-r--r--src/gui/opengl/qopengltexturehelper.cpp450
-rw-r--r--src/gui/opengl/qopengltexturehelper_p.h641
-rw-r--r--src/gui/opengl/qopengltimerquery.cpp6
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp8
-rw-r--r--src/gui/painting/painting.pri13
-rw-r--r--src/gui/painting/qbrush.cpp81
-rw-r--r--src/gui/painting/qcolor.cpp55
-rw-r--r--src/gui/painting/qdrawhelper.cpp884
-rw-r--r--src/gui/painting/qdrawhelper_avx.cpp70
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp6
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h4
-rw-r--r--src/gui/painting/qdrawhelper_p.h36
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp38
-rw-r--r--src/gui/painting/qdrawhelper_x86_p.h27
-rw-r--r--src/gui/painting/qdrawingprimitive_sse2_p.h4
-rw-r--r--src/gui/painting/qemulationpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintbuffer.cpp6
-rw-r--r--src/gui/painting/qpaintengine.cpp1
-rw-r--r--src/gui/painting/qpaintengine.h1
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp38
-rw-r--r--src/gui/painting/qpainter.cpp12
-rw-r--r--src/gui/painting/qpainterpath.cpp24
-rw-r--r--src/gui/painting/qpainterpath.h2
-rw-r--r--src/gui/painting/qpen.cpp4
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp247
-rw-r--r--src/gui/painting/qplatformbackingstore.h34
-rw-r--r--src/gui/painting/qrgb.h43
-rw-r--r--src/gui/text/qdistancefield.cpp14
-rw-r--r--src/gui/text/qfont.cpp18
-rw-r--r--src/gui/text/qfont.h2
-rw-r--r--src/gui/text/qfont_p.h17
-rw-r--r--src/gui/text/qfontdatabase.h2
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp17
-rw-r--r--src/gui/text/qfontengine.cpp221
-rw-r--r--src/gui/text/qfontengine_ft.cpp35
-rw-r--r--src/gui/text/qfontengine_p.h1
-rw-r--r--src/gui/text/qfontengine_qpa.cpp8
-rw-r--r--src/gui/text/qfontmetrics.cpp163
-rw-r--r--src/gui/text/qfontsubset.cpp18
-rw-r--r--src/gui/text/qharfbuzzng.cpp39
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp6
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qrawfont.cpp21
-rw-r--r--src/gui/text/qtextcursor.cpp1
-rw-r--r--src/gui/text/qtextdocument.cpp94
-rw-r--r--src/gui/text/qtextdocument.h8
-rw-r--r--src/gui/text/qtextdocument_p.h1
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp2
-rw-r--r--src/gui/text/qtextengine.cpp208
-rw-r--r--src/gui/text/qtextengine_p.h46
-rw-r--r--src/gui/text/qtextformat.cpp127
-rw-r--r--src/gui/text/qtextformat.h11
-rw-r--r--src/gui/text/qtextformat_p.h6
-rw-r--r--src/gui/text/qtexthtmlparser.cpp28
-rw-r--r--src/gui/text/qtextlayout.cpp29
-rw-r--r--src/gui/text/qtextobject.cpp50
-rw-r--r--src/gui/text/qtextobject.h4
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo.cpp53
-rw-r--r--src/gui/util/qabstractlayoutstyleinfo_p.h97
-rw-r--r--src/gui/util/qgridlayoutengine.cpp (renamed from src/widgets/graphicsview/qgridlayoutengine.cpp)432
-rw-r--r--src/gui/util/qgridlayoutengine_p.h (renamed from src/widgets/graphicsview/qgridlayoutengine_p.h)151
-rw-r--r--src/gui/util/qlayoutpolicy.cpp136
-rw-r--r--src/gui/util/qlayoutpolicy_p.h185
-rw-r--r--src/gui/util/qvalidator.cpp22
-rw-r--r--src/gui/util/util.pri10
-rw-r--r--src/network/access/access.pri4
-rw-r--r--src/network/access/qabstractprotocolhandler.cpp68
-rw-r--r--src/network/access/qabstractprotocolhandler_p.h88
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp4
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h1
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp382
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h4
-rw-r--r--src/network/access/qhttpnetworkreply_p.h1
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp16
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h6
-rw-r--r--src/network/access/qhttpprotocolhandler.cpp431
-rw-r--r--src/network/access/qhttpprotocolhandler_p.h77
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp25
-rw-r--r--src/network/access/qnetworkcookie.cpp36
-rw-r--r--src/network/access/qnetworkreply.cpp18
-rw-r--r--src/network/access/qnetworkreply.h10
-rw-r--r--src/network/doc/snippets/network/tcpwait.cpp8
-rw-r--r--src/network/kernel/kernel.pri14
-rw-r--r--src/network/kernel/qauthenticator.cpp21
-rw-r--r--src/network/kernel/qdnslookup.cpp23
-rw-r--r--src/network/kernel/qdnslookup.h6
-rw-r--r--src/network/kernel/qdnslookup_android.cpp3
-rw-r--r--src/network/kernel/qdnslookup_p.h7
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp39
-rw-r--r--src/network/kernel/qdnslookup_win.cpp22
-rw-r--r--src/network/kernel/qdnslookup_winrt.cpp149
-rw-r--r--src/network/kernel/qhostaddress.cpp6
-rw-r--r--src/network/kernel/qhostinfo.cpp2
-rw-r--r--src/network/kernel/qhostinfo_unix.cpp6
-rw-r--r--src/network/kernel/qhostinfo_winrt.cpp194
-rw-r--r--src/network/kernel/qnetworkinterface_unix.cpp2
-rw-r--r--src/network/kernel/qnetworkinterface_winrt.cpp198
-rw-r--r--src/network/socket/qabstractsocket.cpp37
-rw-r--r--src/network/socket/qabstractsocket.h4
-rw-r--r--src/network/socket/qabstractsocketengine.cpp4
-rw-r--r--src/network/socket/qabstractsocketengine_p.h2
-rw-r--r--src/network/socket/qlocalserver.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_p.h6
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp28
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp1182
-rw-r--r--src/network/socket/qnativesocketengine_winrt_p.h209
-rw-r--r--src/network/socket/qsocks5socketengine.cpp7
-rw-r--r--src/network/socket/socket.pri19
-rw-r--r--src/network/ssl/qsslcipher.cpp20
-rw-r--r--src/network/ssl/qsslcipher.h1
-rw-r--r--src/network/ssl/qsslconfiguration.cpp108
-rw-r--r--src/network/ssl/qsslconfiguration.h16
-rw-r--r--src/network/ssl/qsslconfiguration_p.h8
-rw-r--r--src/network/ssl/qsslcontext.cpp60
-rw-r--r--src/network/ssl/qsslcontext_p.h20
-rw-r--r--src/network/ssl/qsslkey.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp14
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp15
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp20
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h55
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp5
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp10
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp88
-rw-r--r--src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp21
-rw-r--r--src/opengl/opengl.pro3
-rw-r--r--src/opengl/qgl.cpp466
-rw-r--r--src/opengl/qgl_qpa.cpp26
-rw-r--r--src/opengl/qglbuffer.cpp16
-rw-r--r--src/opengl/qglframebufferobject.cpp87
-rw-r--r--src/opengl/qglframebufferobject.h12
-rw-r--r--src/opengl/qglframebufferobject_p.h12
-rw-r--r--src/opengl/qglfunctions.cpp174
-rw-r--r--src/opengl/qglfunctions.h1
-rw-r--r--src/opengl/qglpixelbuffer.cpp9
-rw-r--r--src/opengl/qglshaderprogram.cpp33
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.mm1
-rw-r--r--src/platformsupport/devicediscovery/devicediscovery.pri13
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp)31
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_p.h9
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri34
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor.cpp150
-rw-r--r--src/platformsupport/eglconvenience/qeglcompositor_p.h (renamed from src/plugins/platforms/ios/qiossoftwareinputhandler.h)35
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp134
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience_p.h10
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer.cpp12
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp242
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h92
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp77
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h7
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor.cpp (renamed from src/plugins/platforms/eglfs/qeglfscursor.cpp)195
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor_p.h (renamed from src/plugins/platforms/eglfs/qeglfscursor.h)64
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp299
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h111
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen.cpp110
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen_p.h81
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp130
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h78
-rw-r--r--src/platformsupport/fbconvenience/fbconvenience.pri7
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler.cpp (renamed from src/plugins/platforms/kms/qkmsvthandler.cpp)37
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler_p.h (renamed from src/plugins/platforms/kms/qkmsvthandler.h)14
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp17
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp310
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm204
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h25
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm20
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp29
-rw-r--r--src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h4
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h2
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp24
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes_p.h3
-rw-r--r--src/plugins/accessible/widgets/itemviews.cpp3
-rw-r--r--src/plugins/bearer/connman/connman.pro2
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.cpp401
-rw-r--r--src/plugins/bearer/connman/qconnmanengine.h24
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux.cpp866
-rw-r--r--src/plugins/bearer/connman/qconnmanservice_linux_p.h213
-rw-r--r--src/plugins/bearer/connman/qofonoservice_linux.cpp899
-rw-r--r--src/plugins/bearer/connman/qofonoservice_linux_p.h222
-rw-r--r--src/plugins/bearer/networkmanager/qnetworkmanagerservice.h24
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp11
-rw-r--r--src/plugins/platforms/android/android.json (renamed from src/plugins/platforms/android/src/android.json)0
-rw-r--r--src/plugins/platforms/android/android.pro83
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp (renamed from src/plugins/platforms/android/src/androidjniaccessibility.cpp)0
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.h (renamed from src/plugins/platforms/android/src/androidjniaccessibility.h)0
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.cpp (renamed from src/plugins/platforms/android/src/androidjniclipboard.cpp)0
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.h (renamed from src/plugins/platforms/android/src/androidjniclipboard.h)0
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp (renamed from src/plugins/platforms/android/src/androidjniinput.cpp)9
-rw-r--r--src/plugins/platforms/android/androidjniinput.h (renamed from src/plugins/platforms/android/src/androidjniinput.h)0
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp (renamed from src/plugins/platforms/android/src/androidjnimain.cpp)497
-rw-r--r--src/plugins/platforms/android/androidjnimain.h (renamed from src/plugins/platforms/android/src/androidjnimain.h)23
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp (renamed from src/plugins/platforms/android/src/androidjnimenu.cpp)18
-rw-r--r--src/plugins/platforms/android/androidjnimenu.h (renamed from src/plugins/platforms/android/src/androidjnimenu.h)0
-rw-r--r--src/plugins/platforms/android/androidplatformplugin.cpp (renamed from src/plugins/platforms/android/src/androidplatformplugin.cpp)0
-rw-r--r--src/plugins/platforms/android/androidsurfaceclient.h (renamed from src/plugins/platforms/android/src/raster/qandroidplatformscreen.h)28
-rw-r--r--src/plugins/platforms/android/opengl/opengl.pro32
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp (renamed from src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp)1
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h (renamed from src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h)0
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp (renamed from src/plugins/platforms/android/src/qandroidinputcontext.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h (renamed from src/plugins/platforms/android/src/qandroidinputcontext.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformaccessibility.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformaccessibility.h (renamed from src/plugins/platforms/android/src/qandroidplatformaccessibility.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.cpp78
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.h66
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformclipboard.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformclipboard.h (renamed from src/plugins/platforms/android/src/qandroidplatformclipboard.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp)57
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.h (renamed from src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.h (renamed from src/plugins/platforms/android/src/qandroidplatformfontdatabase.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.cpp70
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.h61
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformintegration.cpp)161
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h (renamed from src/plugins/platforms/android/src/qandroidplatformintegration.h)41
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenu.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenu.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenubar.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenubar.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.h (renamed from src/plugins/platforms/android/src/qandroidplatformmenuitem.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp)48
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h)22
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.cpp149
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglwindow.h82
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.cpp78
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.h70
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp352
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h118
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformservices.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.h (renamed from src/plugins/platforms/android/src/qandroidplatformservices.h)0
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp (renamed from src/plugins/platforms/android/src/qandroidplatformtheme.cpp)50
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h (renamed from src/plugins/platforms/android/src/qandroidplatformtheme.h)2
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp (renamed from src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp)116
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h)62
-rw-r--r--src/plugins/platforms/android/qandroidsystemlocale.cpp (renamed from src/plugins/platforms/android/src/qandroidsystemlocale.cpp)0
-rw-r--r--src/plugins/platforms/android/qandroidsystemlocale.h (renamed from src/plugins/platforms/android/src/qandroidsystemlocale.h)0
-rw-r--r--src/plugins/platforms/android/raster/raster.pro19
-rw-r--r--src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp178
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp161
-rw-r--r--src/plugins/platforms/android/src/raster/raster.pri7
-rw-r--r--src/plugins/platforms/android/src/src.pri55
-rw-r--r--src/plugins/platforms/cocoa/messages.cpp5
-rw-r--r--src/plugins/platforms/cocoa/messages.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h34
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h35
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm53
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h8
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h41
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm515
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm51
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm4
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm126
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h1
-rw-r--r--src/plugins/platforms/direct2d/direct2d.json3
-rw-r--r--src/plugins/platforms/direct2d/direct2d.pro41
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp103
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h71
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp205
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h (renamed from src/plugins/platforms/eglfs/qeglfscompositor.h)54
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp218
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h84
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp135
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h95
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h96
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp131
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h79
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp64
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h58
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp131
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h71
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp1168
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h98
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp179
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h85
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp66
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp177
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h74
-rw-r--r--src/plugins/platforms/directfb/qdirectfbconvenience.cpp4
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pri12
-rw-r--r--src/plugins/platforms/eglfs/qeglfsbackingstore.cpp157
-rw-r--r--src/plugins/platforms/eglfs/qeglfscompositor.cpp203
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.cpp33
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.h9
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks.h4
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp131
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.cpp216
-rw-r--r--src/plugins/platforms/eglfs/qeglfsintegration.h54
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp72
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h40
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.cpp64
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h41
-rw-r--r--src/plugins/platforms/ios/ios.pro6
-rw-r--r--src/plugins/platforms/ios/qiosglobal.mm8
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h13
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm145
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm8
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm184
-rw-r--r--src/plugins/platforms/ios/quiview.h78
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm557
-rw-r--r--src/plugins/platforms/kms/kms.pro7
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.cpp41
-rw-r--r--src/plugins/platforms/kms/qkmsintegration.h19
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp25
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h14
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp32
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp17
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.cpp10
-rw-r--r--src/plugins/platforms/offscreen/qoffscreenintegration.cpp8
-rw-r--r--src/plugins/platforms/platforms.pro7
-rw-r--r--src/plugins/platforms/qnx/main.cpp7
-rw-r--r--src/plugins/platforms/qnx/qnx.pro14
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp46
-rw-r--r--src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h24
-rw-r--r--src/plugins/platforms/qnx/qqnxbuffer.cpp28
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp23
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp9
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.cpp63
-rw-r--r--src/plugins/platforms/qnx/qqnxglobal.h59
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp1601
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_imf.h76
-rw-r--r--src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp9
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp99
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h12
-rw-r--r--src/plugins/platforms/qnx/qqnxlgmon.cpp49
-rw-r--r--src/plugins/platforms/qnx/qqnxlgmon.h80
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp39
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.h9
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp12
-rw-r--r--src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h1
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.cpp55
-rw-r--r--src/plugins/platforms/qnx/qqnxrasterwindow.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp29
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventfilter.h58
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp183
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h11
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp50
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp91
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h6
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp192
-rw-r--r--src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h17
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp331
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h16
-rw-r--r--src/plugins/platforms/windows/accessible/accessible.pri4
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp10
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp47
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp25
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h7
-rw-r--r--src/plugins/platforms/windows/main.cpp4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp45
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp24
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp102
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h24
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp73
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h7
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp82
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp308
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h1
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp77
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp164
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.h5
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp71
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp23
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.cpp81
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.h66
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp62
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.h58
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp89
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp316
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h8
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp20
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp34
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp180
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h94
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp42
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.cpp30
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp308
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h56
-rw-r--r--src/plugins/platforms/windows/windows.pri184
-rw-r--r--src/plugins/platforms/windows/windows.pro181
-rw-r--r--src/plugins/platforms/winrt/blit.hlsl14
-rw-r--r--src/plugins/platforms/winrt/main.cpp74
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp393
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h (renamed from src/plugins/platforms/eglfs/qeglfsbackingstore.h)40
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.cpp153
-rw-r--r--src/plugins/platforms/winrt/qwinrtcursor.h77
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.cpp63
-rw-r--r--src/plugins/platforms/winrt/qwinrteglcontext.h63
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.cpp69
-rw-r--r--src/plugins/platforms/winrt/qwinrteventdispatcher.h62
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp64
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h (renamed from src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h)15
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.cpp300
-rw-r--r--src/plugins/platforms/winrt/qwinrtinputcontext.h121
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp205
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.h88
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp203
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h85
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformtheme.cpp74
-rw-r--r--src/plugins/platforms/winrt/qwinrtplatformtheme.h60
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp1003
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.h179
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp138
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.h80
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp119
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.h (renamed from src/plugins/platforms/android/src/raster/qandroidplatformwindow.h)40
-rw-r--r--src/plugins/platforms/winrt/winrt.json3
-rw-r--r--src/plugins/platforms/winrt/winrt.pro64
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp40
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp80
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h20
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp134
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp22
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp96
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.h1
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro4
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp2
-rw-r--r--src/printsupport/dialogs/qprintdialog_win.cpp4
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp11
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp44
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp186
-rw-r--r--src/printsupport/kernel/qprintengine_win_p.h1
-rw-r--r--src/printsupport/kernel/qprinter.cpp32
-rw-r--r--src/printsupport/kernel/qprinter.h7
-rw-r--r--src/printsupport/printsupport.pro1
-rw-r--r--src/printsupport/widgets/qprintpreviewwidget.cpp7
-rw-r--r--src/sql/doc/src/sql-driver.qdoc4
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp2
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp7
-rw-r--r--src/sql/drivers/psql/qsql_psql.pri2
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp2
-rw-r--r--src/sql/drivers/tds/qsql_tds.pri2
-rw-r--r--src/sql/kernel/qsqldriver.cpp2
-rw-r--r--src/sql/kernel/qsqlerror.cpp107
-rw-r--r--src/sql/kernel/qsqlerror.h25
-rw-r--r--src/sql/kernel/qsqlquery.cpp33
-rw-r--r--src/sql/kernel/qsqlquery.h1
-rw-r--r--src/src.pro16
-rw-r--r--src/testlib/doc/src/qttestlib-manual.qdoc3
-rw-r--r--src/testlib/qabstracttestlogger_p.h2
-rw-r--r--src/testlib/qcsvbenchmarklogger.cpp (renamed from src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp)79
-rw-r--r--src/testlib/qcsvbenchmarklogger_p.h82
-rw-r--r--src/testlib/qplaintestlogger.cpp4
-rw-r--r--src/testlib/qplaintestlogger_p.h2
-rw-r--r--src/testlib/qtest.h16
-rw-r--r--src/testlib/qtestcase.cpp122
-rw-r--r--src/testlib/qtestcase.h90
-rw-r--r--src/testlib/qtestlog.cpp97
-rw-r--r--src/testlib/qtestlog_p.h4
-rw-r--r--src/testlib/qxmltestlogger.cpp22
-rw-r--r--src/testlib/qxmltestlogger_p.h5
-rw-r--r--src/testlib/qxunittestlogger.cpp8
-rw-r--r--src/testlib/qxunittestlogger_p.h2
-rw-r--r--src/testlib/testlib.pro3
-rw-r--r--src/tools/bootstrap/bootstrap.pro7
-rw-r--r--src/tools/moc/generator.cpp98
-rw-r--r--src/tools/moc/generator.h5
-rw-r--r--src/tools/moc/main.cpp2
-rw-r--r--src/tools/moc/moc.cpp21
-rw-r--r--src/tools/moc/moc.h4
-rw-r--r--src/tools/qlalr/compress.cpp286
-rw-r--r--src/tools/qlalr/compress.h60
-rw-r--r--src/tools/qlalr/cppgenerator.cpp750
-rw-r--r--src/tools/qlalr/cppgenerator.h98
-rw-r--r--src/tools/qlalr/doc/qlalr.qdocconf64
-rw-r--r--src/tools/qlalr/doc/src/classic.css97
-rw-r--r--src/tools/qlalr/doc/src/images/qt-logo.pngbin0 -> 1422 bytes
-rw-r--r--src/tools/qlalr/doc/src/qlalr.qdoc106
-rw-r--r--src/tools/qlalr/dotgraph.cpp102
-rw-r--r--src/tools/qlalr/dotgraph.h61
-rw-r--r--src/tools/qlalr/examples/dummy-xml/dummy-xml.pro2
-rw-r--r--src/tools/qlalr/examples/dummy-xml/ll/dummy-xml-ll.cpp123
-rw-r--r--src/tools/qlalr/examples/dummy-xml/xml.g242
-rw-r--r--src/tools/qlalr/examples/glsl/build.sh47
-rwxr-xr-xsrc/tools/qlalr/examples/glsl/glsl4
-rw-r--r--src/tools/qlalr/examples/glsl/glsl-lex.l245
-rw-r--r--src/tools/qlalr/examples/glsl/glsl.g671
-rw-r--r--src/tools/qlalr/examples/glsl/glsl.pro4
-rw-r--r--src/tools/qlalr/examples/lambda/COMPILE3
-rw-r--r--src/tools/qlalr/examples/lambda/lambda.g81
-rw-r--r--src/tools/qlalr/examples/lambda/lambda.pro3
-rw-r--r--src/tools/qlalr/examples/lambda/main.cpp199
-rw-r--r--src/tools/qlalr/examples/qparser/COMPILE3
-rw-r--r--src/tools/qlalr/examples/qparser/calc.g133
-rw-r--r--src/tools/qlalr/examples/qparser/calc.l61
-rw-r--r--src/tools/qlalr/examples/qparser/qparser.cpp43
-rw-r--r--src/tools/qlalr/examples/qparser/qparser.h152
-rw-r--r--src/tools/qlalr/examples/qparser/qparser.pro4
-rw-r--r--src/tools/qlalr/grammar.cpp127
-rw-r--r--src/tools/qlalr/grammar_p.h131
-rw-r--r--src/tools/qlalr/lalr.cpp781
-rw-r--r--src/tools/qlalr/lalr.g802
-rw-r--r--src/tools/qlalr/lalr.h503
-rw-r--r--src/tools/qlalr/main.cpp185
-rw-r--r--src/tools/qlalr/parsetable.cpp128
-rw-r--r--src/tools/qlalr/parsetable.h61
-rw-r--r--src/tools/qlalr/qlalr.pro25
-rw-r--r--src/tools/qlalr/recognizer.cpp490
-rw-r--r--src/tools/qlalr/recognizer.h113
-rw-r--r--src/tools/uic/cpp/cppwriteincludes.cpp3
-rw-r--r--src/tools/uic/main.cpp6
-rw-r--r--src/tools/uic/option.h1
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp35
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h2
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp5
-rw-r--r--src/widgets/dialogs/qfileinfogatherer.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp2
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp6
-rw-r--r--src/widgets/dialogs/qinputdialog.cpp9
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp16
-rw-r--r--src/widgets/dialogs/qmessagebox.h7
-rw-r--r--src/widgets/dialogs/qwizard.cpp97
-rw-r--r--src/widgets/dialogs/qwizard.h3
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp50
-rw-r--r--src/widgets/dialogs/qwizard_win_p.h4
-rw-r--r--src/widgets/doc/snippets/code/doc_src_layout.cpp2
-rw-r--r--src/widgets/doc/snippets/customstyle/customstyle.cpp48
-rw-r--r--src/widgets/doc/snippets/mainwindowsnippet.cpp2
-rw-r--r--src/widgets/doc/snippets/mdiareasnippets.cpp2
-rw-r--r--src/widgets/doc/snippets/textdocument-imagedrop/textedit.cpp2
-rw-r--r--src/widgets/doc/snippets/timeline/main.cpp2
-rw-r--r--src/widgets/graphicsview/graphicsview.pri6
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayout.cpp55
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp106
-rw-r--r--src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h129
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp114
-rw-r--r--src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h96
-rw-r--r--src/widgets/graphicsview/qgraphicslinearlayout.cpp54
-rw-r--r--src/widgets/graphicsview/qgraphicsproxywidget.cpp16
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex.cpp70
-rw-r--r--src/widgets/graphicsview/qgraphicssceneindex_p.h33
-rw-r--r--src/widgets/graphicsview/qsimplex_p.cpp4
-rw-r--r--src/widgets/graphicsview/qsimplex_p.h11
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp3
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp8
-rw-r--r--src/widgets/itemviews/qheaderview.cpp133
-rw-r--r--src/widgets/itemviews/qheaderview_p.h28
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp8
-rw-r--r--src/widgets/itemviews/qtreeview.cpp14
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp9
-rw-r--r--src/widgets/kernel/kernel.pri5
-rw-r--r--src/widgets/kernel/qapplication.cpp124
-rw-r--r--src/widgets/kernel/qapplication.h4
-rw-r--r--src/widgets/kernel/qapplication_p.h7
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp4
-rw-r--r--src/widgets/kernel/qformlayout.h2
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp183
-rw-r--r--src/widgets/kernel/qopenglwidget_p.h135
-rw-r--r--src/widgets/kernel/qwidget.cpp114
-rw-r--r--src/widgets/kernel/qwidget_p.h33
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp5
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp138
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h27
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp59
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h1
-rw-r--r--src/widgets/kernel/win.pri2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm20
-rw-r--r--src/widgets/styles/qmacstyle_mac_p_p.h45
-rw-r--r--src/widgets/styles/qstyle.h2
-rw-r--r--src/widgets/styles/qstyleanimation.cpp42
-rw-r--r--src/widgets/styles/qstyleanimation_p.h22
-rw-r--r--src/widgets/styles/qwindowscestyle.cpp2
-rw-r--r--src/widgets/styles/qwindowsmobilestyle.cpp5572
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp20
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp16
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp4
-rw-r--r--src/widgets/util/qsystemtrayicon_qpa.cpp8
-rw-r--r--src/widgets/util/util.pri2
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp33
-rw-r--r--src/widgets/widgets/qabstractspinbox.h4
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h1
-rw-r--r--src/widgets/widgets/qcombobox.cpp12
-rw-r--r--src/widgets/widgets/qdatetimeedit.cpp12
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp216
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h5
-rw-r--r--src/widgets/widgets/qdockarealayout.cpp16
-rw-r--r--src/widgets/widgets/qdockwidget.cpp6
-rw-r--r--src/widgets/widgets/qdockwidget_p.h2
-rw-r--r--src/widgets/widgets/qeffects.cpp42
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp7
-rw-r--r--src/widgets/widgets/qlcdnumber.h1
-rw-r--r--src/widgets/widgets/qlineedit.cpp11
-rw-r--r--src/widgets/widgets/qlineedit_p.h5
-rw-r--r--src/widgets/widgets/qmdiarea.cpp3
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp6
-rw-r--r--src/widgets/widgets/qmenu.cpp52
-rw-r--r--src/widgets/widgets/qmenu.h1
-rw-r--r--src/widgets/widgets/qmenu_p.h2
-rw-r--r--src/widgets/widgets/qmenubar.cpp6
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp87
-rw-r--r--src/widgets/widgets/qplaintextedit.h7
-rw-r--r--src/widgets/widgets/qplaintextedit_p.h1
-rw-r--r--src/widgets/widgets/qpushbutton.cpp6
-rw-r--r--src/widgets/widgets/qsizegrip.cpp2
-rw-r--r--src/widgets/widgets/qslider.cpp4
-rw-r--r--src/widgets/widgets/qspinbox.cpp16
-rw-r--r--src/widgets/widgets/qsplashscreen.cpp4
-rw-r--r--src/widgets/widgets/qtabwidget.cpp3
-rw-r--r--src/widgets/widgets/qtextbrowser.cpp2
-rw-r--r--src/widgets/widgets/qtextedit.cpp34
-rw-r--r--src/widgets/widgets/qtextedit.h4
-rw-r--r--src/widgets/widgets/qtoolbar.cpp4
-rw-r--r--src/widgets/widgets/qtoolbar.h2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp62
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h5
-rw-r--r--src/winmain/qtmain_winrt.cpp95
-rw-r--r--src/winmain/winmain.pro3
-rw-r--r--src/xml/sax/qxml.cpp10
-rw-r--r--tests/auto/auto.pro2
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/echo/main.cpp3
-rw-r--r--tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp76
-rw-r--r--tests/auto/corelib/codecs/utf8/tst_utf8.cpp4
-rw-r--r--tests/auto/corelib/corelib.pro8
-rw-r--r--tests/auto/corelib/global/qlogging/tst_qlogging.cpp4
-rw-r--r--tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp93
-rw-r--r--tests/auto/corelib/io/io.pro11
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp18
-rw-r--r--tests/auto/corelib/io/qfile/test/test.pro7
-rw-r--r--tests/auto/corelib/io/qfile/tst_qfile.cpp24
-rw-r--r--tests/auto/corelib/io/qfileinfo/qfileinfo.pro2
-rw-r--r--tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp16
-rw-r--r--tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp6
-rw-r--r--tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp54
-rw-r--r--tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro8
-rw-r--r--tests/auto/corelib/io/qloggingregistry/qtlogging.ini2
-rw-r--r--tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp179
-rw-r--r--tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp6
-rw-r--r--tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro2
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp4
-rw-r--r--tests/auto/corelib/io/qsettings/tst_qsettings.cpp8
-rw-r--r--tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp6
-rw-r--r--tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp4
-rw-r--r--tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp4
-rw-r--r--tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp2
-rw-r--r--tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp1
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp4
-rw-r--r--tests/auto/corelib/json/tst_qtjson.cpp57
-rw-r--r--tests/auto/corelib/kernel/kernel.pro3
-rw-r--r--tests/auto/corelib/kernel/qeventloop/qeventloop.pro2
-rw-r--r--tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp2
-rw-r--r--tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp4
-rw-r--r--tests/auto/corelib/kernel/qmetatype/qmetatype.pro4
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp46
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/.gitignore1
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro7
-rw-r--r--tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp180
-rw-r--r--tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp4
-rw-r--r--tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp110
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char/char.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/int/int.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/long/long.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri7
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro19
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/schar/schar.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/short/short.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp821
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/uint/uint.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro2
-rw-r--r--tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp53
-rw-r--r--tests/auto/corelib/thread/qthread/tst_qthread.cpp36
-rw-r--r--tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp28
-rw-r--r--tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp2
-rw-r--r--tests/auto/corelib/thread/thread.pro1
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp15
-rw-r--r--tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro4
-rw-r--r--tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp223
-rw-r--r--tests/auto/corelib/tools/qchar/data/NormalizationTest.txt6
-rw-r--r--tests/auto/corelib/tools/qchar/tst_qchar.cpp58
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp4
-rw-r--r--tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp8
-rw-r--r--tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp2
-rw-r--r--tests/auto/corelib/tools/qhash/tst_qhash.cpp15
-rw-r--r--tests/auto/corelib/tools/qlocale/test/test.pro1
-rw-r--r--tests/auto/corelib/tools/qlocale/tst_qlocale.cpp81
-rw-r--r--tests/auto/corelib/tools/qstring/tst_qstring.cpp126
-rw-r--r--tests/auto/corelib/tools/qstringiterator/qstringiterator.pro5
-rw-r--r--tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp675
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt6
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt18
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt6
-rw-r--r--tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt978
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp2
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp65
-rw-r--r--tests/auto/corelib/tools/tools.pro2
-rw-r--r--tests/auto/gui/gui.pro7
-rw-r--r--tests/auto/gui/image/qimage/qimage.pro1
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp364
-rw-r--r--tests/auto/gui/image/qpixmap/qpixmap.pro2
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp6
-rw-r--r--tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp2
-rw-r--r--tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp12
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/black.pngbin0 -> 697 bytes
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/black2.pngbin0 -> 697 bytes
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/test.pro1
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp41
-rw-r--r--tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc6
-rw-r--r--tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp30
-rw-r--r--tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp24
-rw-r--r--tests/auto/gui/kernel/qmouseevent_modal/tst_qmouseevent_modal.cpp8
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp63
-rw-r--r--tests/auto/gui/painting/qpainter/tst_qpainter.cpp162
-rw-r--r--tests/auto/gui/painting/qpainter/utils/createImages/main.cpp100
-rw-r--r--tests/auto/gui/painting/qpen/tst_qpen.cpp24
-rw-r--r--tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp10
-rw-r--r--tests/auto/gui/painting/qregion/tst_qregion.cpp186
-rw-r--r--tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp218
-rw-r--r--tests/auto/gui/qopengl/tst_qopengl.cpp241
-rw-r--r--tests/auto/gui/text/qfont/tst_qfont.cpp158
-rw-r--r--tests/auto/gui/text/qfontdatabase/FreeMono.ttfbin267400 -> 0 bytes
-rw-r--r--tests/auto/gui/text/qfontdatabase/LED_REAL.TTFbin0 -> 4708 bytes
-rw-r--r--tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt34
-rw-r--r--tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp12
-rw-r--r--tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp2
-rw-r--r--tests/auto/gui/text/qtextdocument/common.h10
-rw-r--r--tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp50
-rw-r--r--tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp205
-rw-r--r--tests/auto/gui/text/qtextformat/qtextformat.pro2
-rw-r--r--tests/auto/gui/text/qtextformat/tst_qtextformat.cpp243
-rw-r--r--tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp110
-rw-r--r--tests/auto/gui/text/qtextlist/tst_qtextlist.cpp2
-rw-r--r--tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp180
-rw-r--r--tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp7
-rw-r--r--tests/auto/network/access/qftp/tst_qftp.cpp17
-rw-r--r--tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp11
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp46
-rw-r--r--tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp12
-rw-r--r--tests/auto/network/kernel/kernel.pro4
-rw-r--r--tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp6
-rw-r--r--tests/auto/network/kernel/qhostinfo/qhostinfo.pro2
-rw-r--r--tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp2
-rw-r--r--tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp14
-rw-r--r--tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp2
-rw-r--r--tests/auto/network/socket/qtcpserver/crashingServer/crashingServer.pro2
-rw-r--r--tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp38
-rw-r--r--tests/auto/network/socket/qtcpsocket/stressTest/Test.h2
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp77
-rw-r--r--tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp16
-rw-r--r--tests/auto/network/socket/socket.pro4
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp32
-rw-r--r--tests/auto/network/ssl/ssl.pro4
-rw-r--r--tests/auto/opengl/qgl/tst_qgl.cpp36
-rw-r--r--tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp182
-rw-r--r--tests/auto/opengl/qglthreads/tst_qglthreads.cpp93
-rw-r--r--tests/auto/other/atwrapper/atWrapperAutotest.cpp2
-rw-r--r--tests/auto/other/collections/tst_collections.cpp1628
-rw-r--r--tests/auto/other/d3dcompiler/d3dcompiler.pro5
-rw-r--r--tests/auto/other/d3dcompiler/tst_d3dcompiler.cpp372
-rw-r--r--tests/auto/other/languagechange/tst_languagechange.cpp8
-rw-r--r--tests/auto/other/other.pro3
-rw-r--r--tests/auto/other/qaccessibility/qaccessibility.pro5
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp4
-rw-r--r--tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp3
-rw-r--r--tests/auto/other/qcomplextext/tst_qcomplextext.cpp58
-rw-r--r--tests/auto/other/qfocusevent/tst_qfocusevent.cpp7
-rw-r--r--tests/auto/other/qvariant_common/tst_qvariant_common.h2
-rw-r--r--tests/auto/printsupport/dialogs/dialogs.pro3
-rw-r--r--tests/auto/printsupport/dialogs/qabstractprintdialog/.gitignore (renamed from tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore)0
-rw-r--r--tests/auto/printsupport/dialogs/qabstractprintdialog/qabstractprintdialog.pro (renamed from tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro)0
-rw-r--r--tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp (renamed from tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp)0
-rw-r--r--tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp1401
-rw-r--r--tests/auto/printsupport/printsupport.pro1
-rw-r--r--tests/auto/shared/platformclipboard.h4
-rw-r--r--tests/auto/sql/kernel/qsql/qsql.pro2
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h15
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp224
-rw-r--r--tests/auto/sql/kernel/qsqldriver/qsqldriver.pro2
-rw-r--r--tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp18
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp10
-rw-r--r--tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp98
-rw-r--r--tests/auto/sql/kernel/qsqlresult/qsqlresult.pro2
-rw-r--r--tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp16
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro2
-rw-r--r--tests/auto/testlib/selftests/badxml/tst_badxml.cpp21
-rw-r--r--tests/auto/testlib/selftests/crashes/tst_crashes.cpp2
-rw-r--r--tests/auto/testlib/selftests/expected_assert.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_assert.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_badxml.lightxml21
-rw-r--r--tests/auto/testlib/selftests/expected_badxml.txt12
-rw-r--r--tests/auto/testlib/selftests/expected_badxml.xml21
-rw-r--r--tests/auto/testlib/selftests/expected_badxml.xunitxml6
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcallgrind.csv1
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcounting.csv1
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcounting.lightxml10
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcounting.txt4
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibcounting.xml10
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibeventcounter.csv7
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibeventcounter.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_benchliboptions.csv3
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibtickcounter.csv1
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibtickcounter.lightxml9
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibtickcounter.txt4
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibtickcounter.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibwalltime.csv3
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibwalltime.lightxml23
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibwalltime.txt12
-rw-r--r--tests/auto/testlib/selftests/expected_benchlibwalltime.xml12
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.lightxml79
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.txt68
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xml79
-rw-r--r--tests/auto/testlib/selftests/expected_cmptest.xunitxml28
-rw-r--r--tests/auto/testlib/selftests/expected_commandlinedata.lightxml17
-rw-r--r--tests/auto/testlib/selftests/expected_commandlinedata.txt12
-rw-r--r--tests/auto/testlib/selftests/expected_commandlinedata.xml17
-rw-r--r--tests/auto/testlib/selftests/expected_counting.lightxml52
-rw-r--r--tests/auto/testlib/selftests/expected_counting.txt36
-rw-r--r--tests/auto/testlib/selftests/expected_counting.xml52
-rw-r--r--tests/auto/testlib/selftests/expected_counting.xunitxml8
-rw-r--r--tests/auto/testlib/selftests/expected_datatable.lightxml37
-rw-r--r--tests/auto/testlib/selftests/expected_datatable.txt26
-rw-r--r--tests/auto/testlib/selftests/expected_datatable.xml37
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.lightxml11
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.txt6
-rw-r--r--tests/auto/testlib/selftests/expected_datetime.xml11
-rw-r--r--tests/auto/testlib/selftests/expected_exceptionthrow.lightxml5
-rw-r--r--tests/auto/testlib/selftests/expected_exceptionthrow.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_exceptionthrow.xml5
-rw-r--r--tests/auto/testlib/selftests/expected_expectfail.lightxml43
-rw-r--r--tests/auto/testlib/selftests/expected_expectfail.txt28
-rw-r--r--tests/auto/testlib/selftests/expected_expectfail.xml43
-rw-r--r--tests/auto/testlib/selftests/expected_failcleanup.lightxml6
-rw-r--r--tests/auto/testlib/selftests/expected_failcleanup.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_failcleanup.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_failinit.lightxml5
-rw-r--r--tests/auto/testlib/selftests/expected_failinit.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_failinit.xml5
-rw-r--r--tests/auto/testlib/selftests/expected_failinitdata.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_failinitdata.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_failinitdata.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_fetchbogus.lightxml3
-rw-r--r--tests/auto/testlib/selftests/expected_fetchbogus.xml3
-rw-r--r--tests/auto/testlib/selftests/expected_findtestdata.lightxml6
-rw-r--r--tests/auto/testlib/selftests/expected_findtestdata.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_findtestdata.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_float.txt12
-rw-r--r--tests/auto/testlib/selftests/expected_globaldata.lightxml81
-rw-r--r--tests/auto/testlib/selftests/expected_globaldata.txt74
-rw-r--r--tests/auto/testlib/selftests/expected_globaldata.xml81
-rw-r--r--tests/auto/testlib/selftests/expected_globaldata.xunitxml132
-rw-r--r--tests/auto/testlib/selftests/expected_longstring.lightxml6
-rw-r--r--tests/auto/testlib/selftests/expected_longstring.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_longstring.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_maxwarnings.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_maxwarnings.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_silent.txt4
-rw-r--r--tests/auto/testlib/selftests/expected_singleskip.lightxml6
-rw-r--r--tests/auto/testlib/selftests/expected_singleskip.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_singleskip.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_skip.lightxml12
-rw-r--r--tests/auto/testlib/selftests/expected_skip.txt6
-rw-r--r--tests/auto/testlib/selftests/expected_skip.xml12
-rw-r--r--tests/auto/testlib/selftests/expected_skipcleanup.lightxml6
-rw-r--r--tests/auto/testlib/selftests/expected_skipcleanup.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_skipcleanup.xml6
-rw-r--r--tests/auto/testlib/selftests/expected_skipinit.lightxml5
-rw-r--r--tests/auto/testlib/selftests/expected_skipinit.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_skipinit.xml5
-rw-r--r--tests/auto/testlib/selftests/expected_skipinitdata.lightxml4
-rw-r--r--tests/auto/testlib/selftests/expected_skipinitdata.txt2
-rw-r--r--tests/auto/testlib/selftests/expected_skipinitdata.xml4
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.lightxml25
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.txt16
-rw-r--r--tests/auto/testlib/selftests/expected_strcmp.xml25
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.lightxml80
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.txt74
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.xml80
-rw-r--r--tests/auto/testlib/selftests/expected_subtest.xunitxml132
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.lightxml52
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.txt36
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.xml52
-rw-r--r--tests/auto/testlib/selftests/expected_verbose1.xunitxml8
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.lightxml88
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.txt72
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.xml88
-rw-r--r--tests/auto/testlib/selftests/expected_verbose2.xunitxml8
-rw-r--r--tests/auto/testlib/selftests/expected_verifyexceptionthrown.lightxml61
-rw-r--r--tests/auto/testlib/selftests/expected_verifyexceptionthrown.txt21
-rw-r--r--tests/auto/testlib/selftests/expected_verifyexceptionthrown.xml64
-rw-r--r--tests/auto/testlib/selftests/expected_verifyexceptionthrown.xunitxml31
-rw-r--r--tests/auto/testlib/selftests/expected_warnings.lightxml21
-rw-r--r--tests/auto/testlib/selftests/expected_warnings.txt6
-rw-r--r--tests/auto/testlib/selftests/expected_warnings.xml21
-rw-r--r--tests/auto/testlib/selftests/expected_warnings.xunitxml11
-rw-r--r--tests/auto/testlib/selftests/expected_xunit.lightxml24
-rw-r--r--tests/auto/testlib/selftests/expected_xunit.txt14
-rw-r--r--tests/auto/testlib/selftests/expected_xunit.xml24
-rwxr-xr-xtests/auto/testlib/selftests/generate_expected_output.py124
-rw-r--r--tests/auto/testlib/selftests/selftests.pri1
-rw-r--r--tests/auto/testlib/selftests/selftests.qrc9
-rw-r--r--tests/auto/testlib/selftests/tst_selftests.cpp77
-rw-r--r--tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp162
-rw-r--r--tests/auto/testlib/selftests/verifyexceptionthrown/verifyexceptionthrown.pro8
-rw-r--r--tests/auto/testlib/selftests/warnings/tst_warnings.cpp21
-rw-r--r--tests/auto/tools/moc/assign-namespace.h4
-rw-r--r--tests/auto/tools/moc/backslash-newlines.h4
-rw-r--r--tests/auto/tools/moc/c-comments.h4
-rw-r--r--tests/auto/tools/moc/cstyle-enums.h4
-rw-r--r--tests/auto/tools/moc/cxx11-enums.h4
-rw-r--r--tests/auto/tools/moc/dir-in-include-path.h4
-rw-r--r--tests/auto/tools/moc/dollars.h4
-rw-r--r--tests/auto/tools/moc/error-on-wrong-notify.h4
-rw-r--r--tests/auto/tools/moc/escapes-in-string-literals.h4
-rw-r--r--tests/auto/tools/moc/extraqualification.h4
-rw-r--r--tests/auto/tools/moc/forgotten-qinterface.h4
-rw-r--r--tests/auto/tools/moc/forward-declared-param.h6
-rw-r--r--tests/auto/tools/moc/function-with-attributes.h4
-rw-r--r--tests/auto/tools/moc/interface-from-framework.h3
-rw-r--r--tests/auto/tools/moc/macro-on-cmdline.h4
-rw-r--r--tests/auto/tools/moc/moc.pro6
-rw-r--r--tests/auto/tools/moc/namespaced-flags.h4
-rw-r--r--tests/auto/tools/moc/no-keywords.h4
-rw-r--r--tests/auto/tools/moc/oldstyle-casts.h6
-rw-r--r--tests/auto/tools/moc/parse-boost.h4
-rw-r--r--tests/auto/tools/moc/pp-dollar-signs.h4
-rw-r--r--tests/auto/tools/moc/pure-virtual-signals.h4
-rw-r--r--tests/auto/tools/moc/qinvokable.h4
-rw-r--r--tests/auto/tools/moc/qprivateslots.h4
-rw-r--r--tests/auto/tools/moc/qtbug-35657-gadget.h56
-rw-r--r--tests/auto/tools/moc/related-metaobjects-in-gadget.h59
-rw-r--r--tests/auto/tools/moc/related-metaobjects-in-namespaces.h65
-rw-r--r--tests/auto/tools/moc/related-metaobjects-name-conflict.h117
-rw-r--r--tests/auto/tools/moc/single-quote-digit-separator-n3781.h4
-rw-r--r--tests/auto/tools/moc/single_function_keyword.h4
-rw-r--r--tests/auto/tools/moc/slots-with-void-template.h4
-rw-r--r--tests/auto/tools/moc/task192552.h4
-rw-r--r--tests/auto/tools/moc/task234909.h4
-rw-r--r--tests/auto/tools/moc/task87883.h4
-rw-r--r--tests/auto/tools/moc/template-gtgt.h4
-rw-r--r--tests/auto/tools/moc/trigraphs.h4
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp145
-rw-r--r--tests/auto/tools/moc/unterminated-function-macro.h4
-rw-r--r--tests/auto/tools/moc/using-namespaces.h4
-rw-r--r--tests/auto/tools/moc/warn-on-multiple-qobject-subclasses.h4
-rw-r--r--tests/auto/tools/moc/warn-on-property-without-read.h4
-rw-r--r--tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h50
-rw-r--r--tests/auto/tools/uic/tst_uic.cpp52
-rw-r--r--tests/auto/widgets/dialogs/dialogs.pro5
-rw-r--r--tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp4
-rw-r--r--tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp17
-rw-r--r--tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp10
-rw-r--r--tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp4
-rw-r--r--tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp47
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp96
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp36
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro2
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp8
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro1
-rw-r--r--tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp162
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro2
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp2
-rw-r--r--tests/auto/widgets/itemviews/qlistview/qlistview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp4
-rw-r--r--tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp28
-rw-r--r--tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp22
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/qtreeview.pro2
-rw-r--r--tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp5
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp30
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp114
-rw-r--r--tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp2
-rw-r--r--tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp4
-rw-r--r--tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp318
-rw-r--r--tests/auto/widgets/kernel/qwidget/qwidget.pro2
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp237
-rw-r--r--tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp2
-rw-r--r--tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp2
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp30
-rw-r--r--tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp2
-rw-r--r--tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp18
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp48
-rw-r--r--tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp4
-rw-r--r--tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp217
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp6
-rw-r--r--tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp4
-rw-r--r--tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp40
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp56
-rw-r--r--tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp44
-rw-r--r--tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp6
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp49
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro2
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp2
-rw-r--r--tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp60
-rw-r--r--tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp6
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/parser/parser.cpp284
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/parser/parser.h16
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp82
-rw-r--r--tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref2
-rw-r--r--tests/baselineserver/shared/baselineprotocol.cpp6
-rw-r--r--tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp5
-rw-r--r--tests/benchmarks/corelib/io/qdiriterator/main.cpp5
-rw-r--r--tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp5
-rw-r--r--tests/benchmarks/corelib/io/qfile/main.cpp26
-rw-r--r--tests/benchmarks/corelib/io/qfileinfo/main.cpp4
-rw-r--r--tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp4
-rw-r--r--tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp174
-rw-r--r--tests/benchmarks/corelib/thread/thread.pro1
-rw-r--r--tests/benchmarks/corelib/tools/qhash/main.cpp42
-rw-r--r--tests/benchmarks/corelib/tools/qhash/main.h10
-rw-r--r--tests/benchmarks/corelib/tools/qhash/outofline.cpp10
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp20
-rw-r--r--tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h6
-rw-r--r--tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp140
-rw-r--r--tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp8
-rw-r--r--tests/manual/bearerex/bearerex.cpp16
-rw-r--r--tests/manual/cocoa/qmaccocoaviewcontainer/main.mm1
-rw-r--r--tests/manual/dialogs/printdialogpanel.cpp29
-rw-r--r--tests/manual/dialogs/printdialogpanel.h1
-rw-r--r--tests/manual/manual.pro3
-rw-r--r--tests/manual/qopengltextureblitter/main.cpp53
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitter.pro12
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp182
-rw-r--r--tests/manual/qopengltextureblitter/qopengltextureblitwindow.h70
-rw-r--r--tests/manual/qopenglwidget/openglwidget/main.cpp73
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.cpp191
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.h63
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.pro9
-rw-r--r--tests/manual/qpainfo/main.cpp7
-rw-r--r--tests/manual/qsslsocket/main.cpp164
-rw-r--r--tests/manual/qsslsocket/qsslsocket.pro6
-rw-r--r--tests/manual/windowchildgeometry/controllerwidget.cpp536
-rw-r--r--tests/manual/windowchildgeometry/controllerwidget.h158
-rw-r--r--tests/manual/windowchildgeometry/main.cpp51
-rw-r--r--tests/manual/windowchildgeometry/windowchildgeometry.pro10
-rw-r--r--tests/shared/fakedirmodel.h130
-rw-r--r--tests/shared/filesystem.h4
-rw-r--r--tests/tests.pro2
-rw-r--r--tools/configure/Makefile.mingw5
-rw-r--r--tools/configure/Makefile.win327
-rw-r--r--tools/configure/configure.pro3
-rw-r--r--tools/configure/configureapp.cpp142
-rw-r--r--tools/configure/configureapp.h15
-rw-r--r--tools/configure/environment.cpp18
-rw-r--r--tools/configure/main.cpp12
-rw-r--r--tools/configure/tools.cpp4
-rwxr-xr-xutil/local_database/cldr2qlocalexml.py18
-rwxr-xr-xutil/local_database/cldr2qtimezone.py29
-rw-r--r--util/local_database/enumdata.py5
-rw-r--r--util/unicode/data/ArabicShaping.txt227
-rw-r--r--util/unicode/data/BidiMirroring.txt14
-rw-r--r--util/unicode/data/Blocks.txt4
-rw-r--r--util/unicode/data/CaseFolding.txt6
-rw-r--r--util/unicode/data/DerivedAge.txt20
-rw-r--r--util/unicode/data/DerivedNormalizationProps.txt22
-rw-r--r--util/unicode/data/GraphemeBreakProperty.txt21
-rw-r--r--util/unicode/data/LineBreak.txt30
-rw-r--r--util/unicode/data/NormalizationCorrections.txt6
-rw-r--r--util/unicode/data/Scripts.txt27
-rw-r--r--util/unicode/data/SentenceBreakProperty.txt24
-rw-r--r--util/unicode/data/SpecialCasing.txt8
-rw-r--r--util/unicode/data/UnicodeData.txt21
-rw-r--r--util/unicode/data/WordBreakProperty.txt61
-rw-r--r--util/unicode/main.cpp194
1722 files changed, 116585 insertions, 57807 deletions
diff --git a/config.tests/qpa/direct2d/direct2d.cpp b/config.tests/qpa/direct2d/direct2d.cpp
new file mode 100644
index 0000000000..66966ae385
--- /dev/null
+++ b/config.tests/qpa/direct2d/direct2d.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <d3d11_1.h>
+#include <d2d1_1.h>
+#include <d2d1_1helper.h>
+#include <dxgi1_2.h>
+#include <wrl.h>
+#include <dwrite.h>
+
+using Microsoft::WRL::ComPtr;
+
+int main(int, char**)
+{
+ ComPtr<ID2D1Factory1> d2dFactory;
+ D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, d2dFactory.ReleaseAndGetAddressOf());
+
+ return 0;
+}
diff --git a/config.tests/qpa/direct2d/direct2d.pro b/config.tests/qpa/direct2d/direct2d.pro
new file mode 100644
index 0000000000..ab62a1da5c
--- /dev/null
+++ b/config.tests/qpa/direct2d/direct2d.pro
@@ -0,0 +1,4 @@
+SOURCES = direct2d.cpp
+LIBS += -ld2d1 -ldwrite -ld3d11
+CONFIG -= qt
+CONFIG += console
diff --git a/config.tests/qpa/egl-x11/egl-x11.cpp b/config.tests/qpa/egl-x11/egl-x11.cpp
new file mode 100644
index 0000000000..f5c2ae7260
--- /dev/null
+++ b/config.tests/qpa/egl-x11/egl-x11.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <EGL/egl.h>
+#include <xcb/xcb.h>
+#include <X11/Xlib.h>
+#include <X11/Xlib-xcb.h>
+
+// Check if EGL is compatible with X. Some EGL implementations, typically on
+// embedded devices, are not intended to be used together with X. EGL support
+// has to be disabled in plugins like xcb in this case since the native display,
+// window and pixmap types will be different than what an X-based platform
+// plugin would expect.
+
+int main(int, char **)
+{
+ Display *dpy = EGL_DEFAULT_DISPLAY;
+ EGLNativeDisplayType egldpy = XOpenDisplay("");
+ dpy = egldpy;
+ EGLNativeWindowType w = XCreateWindow(dpy, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ XDestroyWindow(dpy, w);
+ XCloseDisplay(dpy);
+ return 0;
+}
diff --git a/config.tests/qpa/egl-x11/egl-x11.pro b/config.tests/qpa/egl-x11/egl-x11.pro
new file mode 100644
index 0000000000..c4e94ca40c
--- /dev/null
+++ b/config.tests/qpa/egl-x11/egl-x11.pro
@@ -0,0 +1,12 @@
+SOURCES = egl-x11.cpp
+
+for(p, QMAKE_LIBDIR_EGL) {
+ exists($$p):LIBS += -L$$p
+}
+
+!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL
+!isEmpty(QMAKE_LIBS_EGL): LIBS += $$QMAKE_LIBS_EGL
+
+CONFIG -= qt
+
+LIBS += -lxcb -lX11 -lX11-xcb
diff --git a/config.tests/unix/iconv/iconv.pro b/config.tests/unix/iconv/iconv.pro
index 1ef6aa7207..65a67f16d3 100644
--- a/config.tests/unix/iconv/iconv.pro
+++ b/config.tests/unix/iconv/iconv.pro
@@ -1,3 +1,3 @@
SOURCES = iconv.cpp
CONFIG -= qt dylib
-mac|win32-g++*|qnx:LIBS += -liconv
+mac|mingw|qnx:LIBS += -liconv
diff --git a/config.tests/unix/journald/journald.c b/config.tests/unix/journald/journald.c
new file mode 100644
index 0000000000..470d526e68
--- /dev/null
+++ b/config.tests/unix/journald/journald.c
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <robin.burchell@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <systemd/sd-journal.h>
+
+int main(int argc, char **argv)
+{
+ sd_journal_print_with_location(LOG_INFO, "CODE_FILE=foo.c", "CODE_LINE=0", "unknown_function", "test message");
+ return 0;
+}
diff --git a/config.tests/unix/journald/journald.pro b/config.tests/unix/journald/journald.pro
new file mode 100644
index 0000000000..2bb50ceb71
--- /dev/null
+++ b/config.tests/unix/journald/journald.pro
@@ -0,0 +1,6 @@
+SOURCES = journald.c
+
+CONFIG += link_pkgconfig
+PKGCONFIG_PRIVATE += libsystemd-journal
+
+CONFIG -= qt
diff --git a/config.tests/unix/lgmon/lgmon.cpp b/config.tests/unix/lgmon/lgmon.cpp
new file mode 100644
index 0000000000..4935775806
--- /dev/null
+++ b/config.tests/unix/lgmon/lgmon.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <lgmon.h>
+
+int main(int, char **)
+{
+ lgmon_supported(getpid());
+ return 0;
+}
+
diff --git a/config.tests/unix/lgmon/lgmon.pro b/config.tests/unix/lgmon/lgmon.pro
new file mode 100644
index 0000000000..7bd094dc86
--- /dev/null
+++ b/config.tests/unix/lgmon/lgmon.pro
@@ -0,0 +1,3 @@
+SOURCES = lgmon.cpp
+CONFIG -= qt
+LIBS += -llgmon
diff --git a/config.tests/unix/neon/neon.pro b/config.tests/unix/neon/neon.pro
deleted file mode 100644
index efd608bd63..0000000000
--- a/config.tests/unix/neon/neon.pro
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES = neon.cpp
-CONFIG -= x11 qt
-isEmpty(QMAKE_CFLAGS_NEON):error("This compiler does not support Neon")
-else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_NEON
diff --git a/config.tests/unix/odbc/odbc.pro b/config.tests/unix/odbc/odbc.pro
index 418a0e0d54..70f3b668da 100644
--- a/config.tests/unix/odbc/odbc.pro
+++ b/config.tests/unix/odbc/odbc.pro
@@ -1,4 +1,4 @@
SOURCES = odbc.cpp
CONFIG -= qt dylib
-win32-g++*:LIBS += -lodbc32
+mingw:LIBS += -lodbc32
else:LIBS += -lodbc
diff --git a/config.tests/unix/neon/neon.cpp b/config.tests/unix/qqnx_imf/qqnx_imf.cpp
index ccbb476367..b88593bf33 100644
--- a/config.tests/unix/neon/neon.cpp
+++ b/config.tests/unix/qqnx_imf/qqnx_imf.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the config.tests of the Qt Toolkit.
@@ -39,13 +39,10 @@
**
****************************************************************************/
-#include <arm_neon.h>
+#include "imf/imf_client.h"
-int main(int, char**)
+int main(int, char **)
{
- int32x4_t null = vdupq_n_s32(0x0);
-
- int result;
- vst1q_lane_s32(&result, null, 0);
- return result;
+ imf_client_init();
+ return 0;
}
diff --git a/config.tests/unix/qqnx_imf/qqnx_imf.pro b/config.tests/unix/qqnx_imf/qqnx_imf.pro
new file mode 100644
index 0000000000..c51adb65ad
--- /dev/null
+++ b/config.tests/unix/qqnx_imf/qqnx_imf.pro
@@ -0,0 +1,3 @@
+SOURCES = qqnx_imf.cpp
+CONFIG -= qt
+LIBS += -linput_client
diff --git a/config.tests/x11/opengl/opengl.pro b/config.tests/x11/opengl/opengl.pro
index 5c3a1c50cb..d6814f1bd5 100644
--- a/config.tests/x11/opengl/opengl.pro
+++ b/config.tests/x11/opengl/opengl.pro
@@ -7,5 +7,5 @@ for(p, QMAKE_LIBDIR_OPENGL) {
}
CONFIG -= qt
-win32-g++*:LIBS += -lopengl32
+mingw:LIBS += -lopengl32
else:LIBS += -lGL
diff --git a/configure b/configure
index 90c349cfc7..e491836533 100755
--- a/configure
+++ b/configure
@@ -596,6 +596,7 @@ CFG_XINERAMA=runtime
CFG_XFIXES=runtime
CFG_ZLIB=auto
CFG_MTDEV=auto
+CFG_JOURNALD=no
CFG_SQLITE=qt
CFG_GIF=auto
CFG_PNG=yes
@@ -612,6 +613,7 @@ CFG_OPENVG_LC_INCLUDES=no
CFG_OPENVG_SHIVA=auto
CFG_OPENVG_ON_OPENGL=auto
CFG_EGL=auto
+CFG_EGL_X=auto
CFG_FONTCONFIG=auto
CFG_FREETYPE=auto
CFG_HARFBUZZ=no
@@ -630,6 +632,8 @@ CFG_PKGCONFIG=auto
CFG_STACK_PROTECTOR_STRONG=auto
CFG_SLOG2=auto
CFG_PPS=auto
+CFG_QNX_IMF=auto
+CFG_LGMON=auto
CFG_SYSTEM_PROXIES=no
# Target architecture
@@ -778,6 +782,8 @@ QT_LIBS_GLIB=
# default qpa platform
QT_QPA_DEFAULT_PLATFORM=
+# default print support plugin
+QT_PRINTSUPPORT_DEFAULT_PLUGIN=
# Android vars
CFG_DEFAULT_ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT
@@ -1471,6 +1477,7 @@ while [ "$#" -gt 0 ]; do
egl)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_EGL="$VAL"
+ CFG_EGL_X="$VAL"
else
UNKNOWN_OPT=yes
fi
@@ -1551,13 +1558,6 @@ while [ "$#" -gt 0 ]; do
iwmmxt)
CFG_IWMMXT="yes"
;;
- neon)
- if [ "$VAL" = "no" ]; then
- CFG_NEON="$VAL"
- else
- UNKNOWN_OPT=yes
- fi
- ;;
mips_dsp)
if [ "$VAL" = "no" ]; then
CFG_MIPS_DSP="$VAL"
@@ -1596,6 +1596,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
+ journald)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_JOURNALD="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
sqlite)
if [ "$VAL" = "system" ]; then
CFG_SQLITE=system
@@ -1780,6 +1787,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
+ imf)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_QNX_IMF="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
pps)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_PPS="$VAL"
@@ -1787,6 +1801,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
+ lgmon)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_LGMON="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
gtkstyle)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_QGTKSTYLE="$VAL"
@@ -2275,7 +2296,6 @@ Configure options:
-no-sse4.2 ......... Do not compile with use of SSE4.2 instructions.
-no-avx ............ Do not compile with use of AVX instructions.
-no-avx2 ........... Do not compile with use of AVX2 instructions.
- -no-neon ........... Do not compile with use of NEON instructions.
-no-mips_dsp ....... Do not compile with use of MIPS DSP instructions.
-no-mips_dspr2 ..... Do not compile with use of MIPS DSP rev2 instructions.
@@ -2307,6 +2327,9 @@ Third Party Libraries:
-no-mtdev ......... Do not compile mtdev support.
+ -mtdev ............. Enable mtdev support.
+ + -no-journald ....... Do not send logging output to journald.
+ -journald .......... Send logging output to journald.
+
-no-gif ............ Do not compile GIF reading support.
-no-libpng ......... Do not compile PNG support.
@@ -2484,6 +2507,12 @@ QNX/Blackberry options:
-no-pps ............ Do not compile with pps support.
-pps ............... Compile with pps support.
+ -no-imf ............ Do not compile with imf support.
+ -imf ............... Compile with imf support.
+
+ -no-lgmon .......... Do not compile with lgmon support.
+ -lgmon ............. Compile with lgmon support.
+
MacOS/iOS options:
-Fstring ........... Add an explicit framework path.
@@ -3344,9 +3373,8 @@ fi
if [ "$XPLATFORM_IOS" = "yes" ]; then
CFG_RPATH="no"
CFG_PKGCONFIG="no"
- CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples tests"
+ CFG_NOBUILD_PARTS="$CFG_NOBUILD_PARTS examples"
CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
- CFG_CXX11="no" # C++11 support disabled for now
CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtconnectivity qtdoc qtlocation qtmacextras qtserialport qttools qtwebkit qtwebkit-examples"
# If the user passes -sdk on the command line we build a SDK-specific Qt build.
@@ -4011,13 +4039,19 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ];
if [ $QT_EDITION = "QT_EDITION_OPENSOURCE" ]; then
echo "EXTRA_CPPFLAGS = -DQMAKE_OPENSOURCE_EDITION" >> "$mkfile"
fi
- cat "$in_mkfile" >> "$mkfile"
- if "$WHICH" makedepend >/dev/null 2>&1 && grep 'depend:' "$mkfile" >/dev/null 2>&1; then
- (cd "$outpath/qmake" && "$MAKE" -f "$mkfile" depend) >/dev/null 2>&1
- sed 's,^.*/\([^/]*.o\):,\1:,g' "$mkfile" >"$mkfile.tmp"
- sed "s,$outpath,$adjoutpath,g" "$mkfile.tmp" >"$mkfile"
- rm "$mkfile.tmp"
+ if [ "$BUILD_ON_MAC" = "yes" ]; then
+ echo "EXTRA_CXXFLAGS += -MMD" >> "$mkfile"
+ cat "$in_mkfile" >> "$mkfile"
+ echo "-include \$(notdir \$(DEPEND_SRC:%.cpp=%.d))" >> "$mkfile"
+ else
+ cat "$in_mkfile" >> "$mkfile"
+ if "$WHICH" makedepend >/dev/null 2>&1 && grep 'depend:' "$mkfile" >/dev/null 2>&1; then
+ (cd "$outpath/qmake" && "$MAKE" -f "$mkfile" depend) >/dev/null 2>&1
+ sed 's,^.*/\([^/]*.o\):,\1:,g' "$mkfile" >"$mkfile.tmp"
+ sed "s,$outpath,$adjoutpath,g" "$mkfile.tmp" >"$mkfile"
+ rm "$mkfile.tmp"
+ fi
fi
done
@@ -4328,17 +4362,6 @@ if [ "$CFG_IWMMXT" = "yes" ]; then
fi
fi
-# detect neon support
-if [ "$CFG_ARCH" = "arm" ] && [ "${CFG_NEON}" = "auto" ]; then
- if compileTest unix/neon "neon"; then
- CFG_NEON=yes
- else
- CFG_NEON=no
- fi
-elif [ "$CFG_ARCH" != "arm" ]; then
- CFG_NEON=no
-fi
-
# detect mips_dsp support
if [ "$CFG_ARCH" = "mips" ] && [ "${CFG_MIPS_DSP}" = "auto" ]; then
if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/mips_dsp "mips_dsp" $L_FLAGS $I_FLAGS $D_FLAGS $l_FLAGS; then
@@ -4388,7 +4411,14 @@ if [ "$XPLATFORM_QNX" = "yes" ]; then
CFG_SLOG2=no
fi
fi
-
+ if [ "$CFG_QNX_IMF" != "no" ]; then
+ if compileTest unix/qqnx_imf "qqnx_imf"; then
+ CFG_QNX_IMF=yes
+ QMAKE_CONFIG="$QMAKE_CONFIG qqnx_imf"
+ else
+ CFG_QNX_IMF=no
+ fi
+ fi
if [ "$CFG_PPS" != "no" ]; then
if compileTest unix/pps "pps"; then
CFG_PPS=yes
@@ -4397,6 +4427,15 @@ if [ "$XPLATFORM_QNX" = "yes" ]; then
CFG_PPS=no
fi
fi
+
+ if [ "$CFG_LGMON" != "no" ]; then
+ if compileTest unix/lgmon "lgmon"; then
+ CFG_LGMON=yes
+ QMAKE_CONFIG="$QMAKE_CONFIG lgmon"
+ else
+ CFG_LGMON=no
+ fi
+ fi
fi
if [ "$CFG_ZLIB" = "auto" ]; then
@@ -4418,6 +4457,23 @@ if [ "$CFG_MTDEV" = "no" ]; then
QMakeVar add DEFINES QT_NO_MTDEV
fi
+if [ "$CFG_JOURNALD" != "no" ]; then
+ if compileTest unix/journald "journald"; then
+ CFG_JOURNALD=yes
+ QMAKE_CONFIG="$QMAKE_CONFIG journald"
+ else
+ if [ "$CFG_JOURNALD" != "auto" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
+ echo "journald support cannot be enabled due to functionality tests!"
+ echo " Turn on verbose messaging (-v) to $0 to see the final report."
+ echo " If you believe this message is in error you may use the continue"
+ echo " switch (-continue) to $0 to continue."
+ exit 101
+ else
+ CFG_JOURNALD=no
+ fi
+ fi
+fi
+
if [ "$CFG_LARGEFILE" = "auto" ]; then
#Large files should be enabled for all Linux systems
CFG_LARGEFILE=yes
@@ -5161,6 +5217,14 @@ if [ "$CFG_XCB" != "no" ]; then
QMAKE_CFLAGS_XCB="`$PKG_CONFIG --cflags xcb 2>/dev/null`"
QMAKE_LIBS_XCB="`$PKG_CONFIG --libs xcb 2>/dev/null`"
fi
+ if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "x11" 2> /dev/null; then
+ QMAKE_X11_PREFIX="`$PKG_CONFIG --variable=prefix x11`"
+ else
+ # default to LSB prefix
+ QMAKE_X11_PREFIX="/usr"
+ fi
+ QMakeVar set QMAKE_X11_PREFIX "$QMAKE_X11_PREFIX"
+
if compileTest qpa/xcb "xcb" $QMAKE_CFLAGS_XCB $QMAKE_LIBS_XCB; then
if [ "$CFG_XCB" = "qt" ]; then
@@ -5326,6 +5390,11 @@ if [ "$CFG_EGL" != "no" ]; then
fi # detect EGL support
if compileTest qpa/egl "EGL" $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then
CFG_EGL=yes
+ if compileTest qpa/egl-x11 "EGL-X11" $QMAKE_CFLAGS_EGL $QMAKE_LIBS_EGL; then
+ CFG_EGL_X=yes
+ else
+ CFG_EGL_X=no
+ fi
elif [ "$CFG_EGL" = "yes" ]; then
echo " The EGL functionality test failed; EGL is required by some QPA plugins to manage contexts & surfaces."
echo " You might need to modify the include and library search paths by editing"
@@ -5333,6 +5402,7 @@ if [ "$CFG_EGL" != "no" ]; then
exit 1
else
CFG_EGL=no
+ CFG_EGL_X=no
fi
fi
@@ -5387,6 +5457,15 @@ if [ -z "$QT_QPA_DEFAULT_PLATFORM" ]; then
fi
fi
+# Determine print support plugin belonging to the default QPA platform
+if [ "$QT_QPA_DEFAULT_PLATFORM" = "cocoa" ]; then
+ QT_PRINTSUPPORT_DEFAULT_PLUGIN=cocoaprintersupport
+elif [ "$QT_QPA_DEFAULT_PLATFORM" = "windows" ]; then
+ QT_PRINTSUPPORT_DEFAULT_PLUGIN=windowsprintersupport
+elif [ "$QT_QPA_DEFAULT_PLATFORM" = "xcb" ]; then
+ QT_PRINTSUPPORT_DEFAULT_PLUGIN=cupsprintersupport
+fi
+
if [ -n "$QMAKE_CFLAGS_XCB" ] || [ -n "$QMAKE_LIBS_XCB" ]; then
QMakeVar set QMAKE_CFLAGS_XCB "$QMAKE_CFLAGS_XCB"
QMakeVar set QMAKE_LIBS_XCB "$QMAKE_LIBS_XCB"
@@ -5431,6 +5510,7 @@ fi
# harfbuzz support
[ "$XPLATFORM_MINGW" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=no
+[ "$XPLATFORM_MAC" = "yes" ] && [ "$CFG_HARFBUZZ" = "auto" ] && CFG_HARFBUZZ=yes
if [ "$CFG_HARFBUZZ" = "auto" ]; then
if compileTest unix/harfbuzz "HarfBuzz"; then
CFG_HARFBUZZ=system
@@ -5438,6 +5518,11 @@ if [ "$CFG_HARFBUZZ" = "auto" ]; then
CFG_HARFBUZZ=yes
fi
fi
+if [ "$XPLATFORM_MAC" = "yes" -a "$CFG_HARFBUZZ" = "system" ]; then
+ echo
+ echo "WARNING: AAT is not supported with -system-harfbuzz on Mac OS X."
+ echo
+fi
if ! compileTest unix/stl "STL" &&
[ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
@@ -5706,6 +5791,13 @@ else
QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EGL"
fi
+# enable egl on X
+if [ "$CFG_EGL_X" = "yes" ]; then
+ QT_CONFIG="$QT_CONFIG egl_x11"
+else
+ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EGL_X11"
+fi
+
# enable eglfs
if [ "$CFG_EGLFS" = "yes" ]; then
QT_CONFIG="$QT_CONFIG eglfs"
@@ -5782,7 +5874,6 @@ fi
[ "$CFG_AVX" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx"
[ "$CFG_AVX2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG avx2"
[ "$CFG_IWMMXT" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG iwmmxt"
-[ "$CFG_NEON" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG neon"
if [ "$CFG_ARCH" = "mips" ]; then
[ "$CFG_MIPS_DSP" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mips_dsp"
[ "$CFG_MIPS_DSPR2" = "yes" ] && QMAKE_CONFIG="$QMAKE_CONFIG mips_dspr2"
@@ -6216,7 +6307,7 @@ fi
echo "" >>"$outpath/src/corelib/global/qconfig.h.new"
echo "// Compiler sub-arch support" >>"$outpath/src/corelib/global/qconfig.h.new"
for SUBARCH in SSE2 SSE3 SSSE3 SSE4_1 SSE4_2 AVX AVX2 \
- IWMMXT NEON \
+ IWMMXT \
MIPS_DSP MIPS_DSPR2; do
eval "VAL=\$CFG_$SUBARCH"
case "$VAL" in
@@ -6367,6 +6458,7 @@ EOF
fi
echo "#define QT_QPA_DEFAULT_PLATFORM_NAME \"$QT_QPA_DEFAULT_PLATFORM\"" >>"$outpath/src/corelib/global/qconfig.h.new"
+echo "#define QT_QPA_DEFAULT_PRINTSUPPORTPLUGIN_NAME \"QT_PRINTSUPPORT_DEFAULT_PLUGIN\"" >>"$outpath/src/corelib/global/qconfig.h.new"
# avoid unecessary rebuilds by copying only if qconfig.h has changed
if cmp -s "$outpath/src/corelib/global/qconfig.h" "$outpath/src/corelib/global/qconfig.h.new"; then
@@ -6454,6 +6546,7 @@ EOF
if [ "$CFG_SHARED" = "no" ]; then
echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp"
+ echo "QT_DEFAULT_PRINTSUPPORTPLUGIN = $QT_PRINTSUPPORT_DEFAULT_PLUGIN" >> "$QTCONFIG.tmp"
echo >> "$QTCONFIG.tmp"
fi
@@ -6719,6 +6812,7 @@ report_support_plugin " JPEG ................." "$CFG_JPEG" "$CFG_LIBJPEG" Qt
report_support_plugin " PNG .................." "$CFG_PNG" "$CFG_LIBPNG" QtGui
report_support " Glib ..................." "$CFG_GLIB"
report_support " GTK theme .............." "$CFG_QGTKSTYLE"
+report_support " journald ..............." "$CFG_JOURNALD"
report_support " Large File ............." "$CFG_LARGEFILE"
report_support " mtdev .................." "$CFG_MTDEV" yes "system library"
report_support " Networking:"
@@ -6729,6 +6823,9 @@ report_support " getifaddrs ..........." "$CFG_GETIFADDRS"
report_support " IPv6 ifname .........." "$CFG_IPV6IFNAME"
report_support " OpenSSL .............." "$CFG_OPENSSL" yes "loading libraries at run-time" linked "linked to the libraries"
report_support " NIS ...................." "$CFG_NIS"
+report_support " EGL ...................." "$CFG_EGL"
+report_support " EGL on X ..............." "$CFG_EGL_X"
+report_support " GLX ...................." "$CFG_XCB_GLX"
report_support " OpenGL ................." "$CFG_OPENGL" yes "Desktop OpenGL" es2 "OpenGL ES 2.x"
report_support " OpenVG ................." "$CFG_OPENVG-$CFG_OPENVG_SHIVA" yes-yes "ShivaVG" yes-no "native"
report_support " PCRE ..................." "$CFG_PCRE" yes "system library" qt "bundled copy"
@@ -6762,7 +6859,9 @@ fi
report_support " Session management ....." "$CFG_SM"
if [ "$XPLATFORM_QNX" = "yes" ]; then
report_support " SLOG2 .................." "$CFG_SLOG2"
+ report_support " IMF ...................." "$CFG_QNX_IMF"
report_support " PPS ...................." "$CFG_PPS"
+ report_support " LGMON .................." "$CFG_LGMON"
fi
report_support " SQL drivers:"
report_support " DB2 .................." "$CFG_SQL_db2" plugin "plugin" yes "built into QtSql"
diff --git a/dist/changes-5.3.0 b/dist/changes-5.3.0
new file mode 100644
index 0000000000..35fc9cabb0
--- /dev/null
+++ b/dist/changes-5.3.0
@@ -0,0 +1,36 @@
+Qt 5.3 introduces many new features and improvements as well as bugfixes
+over the 5.2.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+ http://qt-project.org/doc/qt-5.3
+
+The Qt version 5.3 series is binary compatible with the 5.2.x series.
+Applications compiled for 5.2 will continue to run with 5.3.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ http://bugreports.qt-project.org/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+QtWidgets
+---------
+
+QtCore
+------
+
+ - Added QSignalBlocker, a RAII-style wrapper around
+ QObject::blockSignals().
+
+QtGui
+-----
+
+ - Added setSwapInterval() to QSurfaceFormat. Platforms that support
+ setting the swap interval are now defaulting to the value of 1,
+ meaning vsync is enabled.
diff --git a/examples/embedded/styleexample/stylewidget.cpp b/examples/embedded/styleexample/stylewidget.cpp
index 411df77293..c45949e0f0 100644
--- a/examples/embedded/styleexample/stylewidget.cpp
+++ b/examples/embedded/styleexample/stylewidget.cpp
@@ -49,7 +49,7 @@
StyleWidget::StyleWidget(QWidget *parent)
: QFrame(parent)
{
- m_ui.setupUi(this);
+ m_ui.setupUi(this);
}
diff --git a/examples/ipc/sharedmemory/dialog.cpp b/examples/ipc/sharedmemory/dialog.cpp
index 2be62b1b47..c504f3a202 100644
--- a/examples/ipc/sharedmemory/dialog.cpp
+++ b/examples/ipc/sharedmemory/dialog.cpp
@@ -73,8 +73,8 @@ Dialog::Dialog(QWidget *parent)
ui.setupUi(this);
connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile()));
connect(ui.loadFromSharedMemoryButton,
- SIGNAL(clicked()),
- SLOT(loadFromMemory()));
+ SIGNAL(clicked()),
+ SLOT(loadFromMemory()));
setWindowTitle(tr("SharedMemory Example"));
}
//! [0]
@@ -155,7 +155,7 @@ void Dialog::loadFromMemory()
{
if (!sharedMemory.attach()) {
ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
- "Load an image first."));
+ "Load an image first."));
return;
}
diff --git a/examples/network/bearermonitor/bearermonitor.cpp b/examples/network/bearermonitor/bearermonitor.cpp
index 58421e52b1..4590a91f4f 100644
--- a/examples/network/bearermonitor/bearermonitor.cpp
+++ b/examples/network/bearermonitor/bearermonitor.cpp
@@ -84,10 +84,10 @@ BearerMonitor::BearerMonitor(QWidget *parent)
this, SLOT(configurationChanged(const QNetworkConfiguration)));
connect(&manager, SIGNAL(updateCompleted()), this, SLOT(updateConfigurations()));
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
connect(registerButton, SIGNAL(clicked()), this, SLOT(registerNetwork()));
connect(unregisterButton, SIGNAL(clicked()), this, SLOT(unregisterNetwork()));
-#else
+#else // Q_OS_WIN && !Q_OS_WINRT
nlaGroup->hide();
#endif
@@ -257,7 +257,7 @@ void BearerMonitor::onlineStateChanged(bool isOnline)
onlineState->setText(tr("Offline"));
}
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void BearerMonitor::registerNetwork()
{
QTreeWidgetItem *item = treeWidget->currentItem();
@@ -301,7 +301,7 @@ void BearerMonitor::unregisterNetwork()
if (WSASetService(&networkInfo, RNRSERVICE_DELETE, 0) == SOCKET_ERROR)
qDebug() << "WSASetService(RNRSERVICE_DELETE) returned" << WSAGetLastError();
}
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
void BearerMonitor::showConfigurationFor(QTreeWidgetItem *item)
{
diff --git a/examples/network/bearermonitor/bearermonitor.h b/examples/network/bearermonitor/bearermonitor.h
index aaa2c18424..307262c2b4 100644
--- a/examples/network/bearermonitor/bearermonitor.h
+++ b/examples/network/bearermonitor/bearermonitor.h
@@ -66,10 +66,10 @@ private slots:
void onlineStateChanged(bool isOnline);
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void registerNetwork();
void unregisterNetwork();
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
void showConfigurationFor(QTreeWidgetItem *item);
diff --git a/examples/network/dnslookup/dnslookup.cpp b/examples/network/dnslookup/dnslookup.cpp
index 77e8abc927..202a5f9580 100644
--- a/examples/network/dnslookup/dnslookup.cpp
+++ b/examples/network/dnslookup/dnslookup.cpp
@@ -50,7 +50,7 @@
static void usage() {
printf("Qt DNS example - performs DNS lookups\n"
- "Usage: dnslookup [-t <type>] name\n\n");
+ "Usage: dnslookup [-t <type>] [-s nameserver] name\n\n");
}
DnsManager::DnsManager()
@@ -93,6 +93,17 @@ void DnsManager::execute()
return;
}
}
+ if (args.size() > 1 && args.first() == "-s") {
+ args.takeFirst();
+ const QString ns = args.takeFirst();
+ QHostAddress nameserver(ns);
+ if (nameserver.isNull() || nameserver.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) {
+ printf("Bad nameserver address: %s\n", qPrintable(ns));
+ QCoreApplication::instance()->quit();
+ return;
+ }
+ dns->setNameserver(nameserver);
+ }
if (args.isEmpty()) {
usage();
QCoreApplication::instance()->quit();
diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp
index a378ccabaa..da5dbce854 100644
--- a/examples/network/loopback/dialog.cpp
+++ b/examples/network/loopback/dialog.cpp
@@ -99,9 +99,9 @@ void Dialog::start()
QMessageBox::StandardButton ret = QMessageBox::critical(this,
tr("Loopback"),
tr("Unable to start the test: %1.")
- .arg(tcpServer.errorString()),
+ .arg(tcpServer.errorString()),
QMessageBox::Retry
- | QMessageBox::Cancel);
+ | QMessageBox::Cancel);
if (ret == QMessageBox::Cancel)
return;
}
diff --git a/examples/network/network.pro b/examples/network/network.pro
index be4ccdbddf..8ed72315e2 100644
--- a/examples/network/network.pro
+++ b/examples/network/network.pro
@@ -23,7 +23,7 @@ qtHaveModule(widgets) {
multicastsender
# no QProcess
- !vxworks:!qnx:SUBDIRS += network-chat
+ !vxworks:!qnx:!winrt:SUBDIRS += network-chat
contains(QT_CONFIG, openssl):SUBDIRS += securesocketclient
contains(QT_CONFIG, openssl-linked):SUBDIRS += securesocketclient
diff --git a/examples/network/securesocketclient/main.cpp b/examples/network/securesocketclient/main.cpp
index de89fafa32..46beaf0d4f 100644
--- a/examples/network/securesocketclient/main.cpp
+++ b/examples/network/securesocketclient/main.cpp
@@ -50,8 +50,8 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
if (!QSslSocket::supportsSsl()) {
- QMessageBox::information(0, "Secure Socket Client",
- "This system does not support OpenSSL.");
+ QMessageBox::information(0, "Secure Socket Client",
+ "This system does not support OpenSSL.");
return -1;
}
diff --git a/examples/network/torrent/peerwireclient.cpp b/examples/network/torrent/peerwireclient.cpp
index a0be01d363..2b5fe3ada1 100644
--- a/examples/network/torrent/peerwireclient.cpp
+++ b/examples/network/torrent/peerwireclient.cpp
@@ -215,7 +215,7 @@ void PeerWireClient::sendPieceList(const QBitArray &bitField)
// Don't send the bitfield if it's all zeros.
if (bitField.count(true) == 0)
- return;
+ return;
int bitFieldSize = bitField.size();
int size = (bitFieldSize + 7) / 8;
diff --git a/examples/network/torrent/torrentserver.cpp b/examples/network/torrent/torrentserver.cpp
index 2196863ca0..0a9d836098 100644
--- a/examples/network/torrent/torrentserver.cpp
+++ b/examples/network/torrent/torrentserver.cpp
@@ -64,7 +64,7 @@ void TorrentServer::removeClient(TorrentClient *client)
void TorrentServer::incomingConnection(qintptr socketDescriptor)
{
PeerWireClient *client =
- new PeerWireClient(ConnectionManager::instance()->clientId(), this);
+ new PeerWireClient(ConnectionManager::instance()->clientId(), this);
if (client->setSocketDescriptor(socketDescriptor)) {
if (ConnectionManager::instance()->canAddConnection() && !clients.isEmpty()) {
diff --git a/examples/opengl/cube/geometryengine.cpp b/examples/opengl/cube/geometryengine.cpp
index bf63934656..0a34213084 100644
--- a/examples/opengl/cube/geometryengine.cpp
+++ b/examples/opengl/cube/geometryengine.cpp
@@ -79,40 +79,40 @@ void GeometryEngine::initCubeGeometry()
// is different.
VertexData vertices[] = {
// Vertex data for face 0
- {QVector3D(-1.0, -1.0, 1.0), QVector2D(0.0, 0.0)}, // v0
- {QVector3D( 1.0, -1.0, 1.0), QVector2D(0.33, 0.0)}, // v1
- {QVector3D(-1.0, 1.0, 1.0), QVector2D(0.0, 0.5)}, // v2
- {QVector3D( 1.0, 1.0, 1.0), QVector2D(0.33, 0.5)}, // v3
+ {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.0f, 0.0f)}, // v0
+ {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D(0.33f, 0.0f)}, // v1
+ {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(0.0f, 0.5f)}, // v2
+ {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v3
// Vertex data for face 1
- {QVector3D( 1.0, -1.0, 1.0), QVector2D( 0.0, 0.5)}, // v4
- {QVector3D( 1.0, -1.0, -1.0), QVector2D(0.33, 0.5)}, // v5
- {QVector3D( 1.0, 1.0, 1.0), QVector2D(0.0, 1.0)}, // v6
- {QVector3D( 1.0, 1.0, -1.0), QVector2D(0.33, 1.0)}, // v7
+ {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D( 0.0f, 0.5f)}, // v4
+ {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.5f)}, // v5
+ {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.0f, 1.0f)}, // v6
+ {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v7
// Vertex data for face 2
- {QVector3D( 1.0, -1.0, -1.0), QVector2D(0.66, 0.5)}, // v8
- {QVector3D(-1.0, -1.0, -1.0), QVector2D(1.0, 0.5)}, // v9
- {QVector3D( 1.0, 1.0, -1.0), QVector2D(0.66, 1.0)}, // v10
- {QVector3D(-1.0, 1.0, -1.0), QVector2D(1.0, 1.0)}, // v11
+ {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v8
+ {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(1.0f, 0.5f)}, // v9
+ {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.66f, 1.0f)}, // v10
+ {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(1.0f, 1.0f)}, // v11
// Vertex data for face 3
- {QVector3D(-1.0, -1.0, -1.0), QVector2D(0.66, 0.0)}, // v12
- {QVector3D(-1.0, -1.0, 1.0), QVector2D(1.0, 0.0)}, // v13
- {QVector3D(-1.0, 1.0, -1.0), QVector2D(0.66, 0.5)}, // v14
- {QVector3D(-1.0, 1.0, 1.0), QVector2D(1.0, 0.5)}, // v15
+ {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v12
+ {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(1.0f, 0.0f)}, // v13
+ {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(0.66f, 0.5f)}, // v14
+ {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(1.0f, 0.5f)}, // v15
// Vertex data for face 4
- {QVector3D(-1.0, -1.0, -1.0), QVector2D(0.33, 0.0)}, // v16
- {QVector3D( 1.0, -1.0, -1.0), QVector2D(0.66, 0.0)}, // v17
- {QVector3D(-1.0, -1.0, 1.0), QVector2D(0.33, 0.5)}, // v18
- {QVector3D( 1.0, -1.0, 1.0), QVector2D(0.66, 0.5)}, // v19
+ {QVector3D(-1.0f, -1.0f, -1.0f), QVector2D(0.33f, 0.0f)}, // v16
+ {QVector3D( 1.0f, -1.0f, -1.0f), QVector2D(0.66f, 0.0f)}, // v17
+ {QVector3D(-1.0f, -1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v18
+ {QVector3D( 1.0f, -1.0f, 1.0f), QVector2D(0.66f, 0.5f)}, // v19
// Vertex data for face 5
- {QVector3D(-1.0, 1.0, 1.0), QVector2D(0.33, 0.5)}, // v20
- {QVector3D( 1.0, 1.0, 1.0), QVector2D(0.66, 0.5)}, // v21
- {QVector3D(-1.0, 1.0, -1.0), QVector2D(0.33, 1.0)}, // v22
- {QVector3D( 1.0, 1.0, -1.0), QVector2D(0.66, 1.0)} // v23
+ {QVector3D(-1.0f, 1.0f, 1.0f), QVector2D(0.33f, 0.5f)}, // v20
+ {QVector3D( 1.0f, 1.0f, 1.0f), QVector2D(0.66f, 0.5f)}, // v21
+ {QVector3D(-1.0f, 1.0f, -1.0f), QVector2D(0.33f, 1.0f)}, // v22
+ {QVector3D( 1.0f, 1.0f, -1.0f), QVector2D(0.66f, 1.0f)} // v23
};
// Indices for drawing cube faces using triangle strips.
diff --git a/examples/opengl/framebufferobject2/glwidget.cpp b/examples/opengl/framebufferobject2/glwidget.cpp
index 27dc603f3c..32b9799a4a 100644
--- a/examples/opengl/framebufferobject2/glwidget.cpp
+++ b/examples/opengl/framebufferobject2/glwidget.cpp
@@ -112,20 +112,20 @@ void GLWidget::initializeGL()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
- // draw cube background
+ // draw cube background
glPushMatrix();
glLoadIdentity();
glTranslatef(0.5f, 0.5f, -2.0f);
- glDisable(GL_TEXTURE_2D);
- glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(2, GL_INT, 0, faceArray);
- glDrawArrays(GL_QUADS, 0, 4);
- glVertexPointer(3, GL_INT, 0, cubeArray);
- glDisableClientState(GL_COLOR_ARRAY);
- glEnable(GL_TEXTURE_2D);
+ glDisable(GL_TEXTURE_2D);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(2, GL_INT, 0, faceArray);
+ glDrawArrays(GL_QUADS, 0, 4);
+ glVertexPointer(3, GL_INT, 0, cubeArray);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glEnable(GL_TEXTURE_2D);
glPopMatrix();
- // draw cube
+ // draw cube
glTranslatef(0.5f, 0.5f, 0.5f);
glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
glTranslatef(-0.5f, -0.5f, -0.5f);
@@ -205,12 +205,12 @@ void GLWidget::paintGL()
glTranslatef(-1.2f, -0.8f, 0.0f);
glScalef(0.2f, 0.2f, 0.2f);
for (int y = 0; y < 5; ++y) {
- for (int x = 0; x < 5; ++x) {
- glTranslatef(2.0f, 0, 0);
- glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
- glDrawArrays(GL_QUADS, 0, 4);
- }
- glTranslatef(-10.0f, 2.0f, 0);
+ for (int x = 0; x < 5; ++x) {
+ glTranslatef(2.0f, 0, 0);
+ glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
+ glDrawArrays(GL_QUADS, 0, 4);
+ }
+ glTranslatef(-10.0f, 2.0f, 0);
}
glVertexPointer(3, GL_INT, 0, cubeArray);
diff --git a/examples/opengl/framebufferobject2/main.cpp b/examples/opengl/framebufferobject2/main.cpp
index ab7359bef3..4c9aa9840f 100644
--- a/examples/opengl/framebufferobject2/main.cpp
+++ b/examples/opengl/framebufferobject2/main.cpp
@@ -48,8 +48,8 @@ int main(int argc, char **argv)
QApplication a(argc, argv);
if (!QGLFormat::hasOpenGL() || !QGLFramebufferObject::hasOpenGLFramebufferObjects()) {
- QMessageBox::information(0, "OpenGL framebuffer objects 2",
- "This system does not support OpenGL/framebuffer objects.");
+ QMessageBox::information(0, "OpenGL framebuffer objects 2",
+ "This system does not support OpenGL/framebuffer objects.");
return -1;
}
diff --git a/examples/opengl/pbuffers/main.cpp b/examples/opengl/pbuffers/main.cpp
index e6b1fc5f48..8be6640e92 100644
--- a/examples/opengl/pbuffers/main.cpp
+++ b/examples/opengl/pbuffers/main.cpp
@@ -54,8 +54,8 @@ int main(int argc, char **argv)
widget.makeCurrent();
if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) {
- QMessageBox::information(0, "OpenGL pbuffers",
- "This system does not support OpenGL/pbuffers.");
+ QMessageBox::information(0, "OpenGL pbuffers",
+ "This system does not support OpenGL/pbuffers.");
return -1;
}
diff --git a/examples/opengl/pbuffers2/main.cpp b/examples/opengl/pbuffers2/main.cpp
index 60d8787c58..79fd88a3c8 100644
--- a/examples/opengl/pbuffers2/main.cpp
+++ b/examples/opengl/pbuffers2/main.cpp
@@ -51,8 +51,8 @@ int main(int argc, char **argv)
widget.resize(640, 480);
widget.makeCurrent();
if (!QGLFormat::hasOpenGL() || !QGLPixelBuffer::hasOpenGLPbuffers()) {
- QMessageBox::information(0, "OpenGL pbuffers 2",
- "This system does not support OpenGL/pbuffers.");
+ QMessageBox::information(0, "OpenGL pbuffers 2",
+ "This system does not support OpenGL/pbuffers.");
return -1;
}
widget.show();
diff --git a/examples/opengl/samplebuffers/main.cpp b/examples/opengl/samplebuffers/main.cpp
index cb25ffb3ec..a1272af4db 100644
--- a/examples/opengl/samplebuffers/main.cpp
+++ b/examples/opengl/samplebuffers/main.cpp
@@ -50,16 +50,16 @@ int main(int argc, char **argv)
f.setSampleBuffers(true);
QGLFormat::setDefaultFormat(f);
if (!QGLFormat::hasOpenGL()) {
- QMessageBox::information(0, "OpenGL samplebuffers",
- "This system does not support OpenGL.");
+ QMessageBox::information(0, "OpenGL samplebuffers",
+ "This system does not support OpenGL.");
return 0;
}
GLWidget widget(0);
if (!widget.format().sampleBuffers()) {
- QMessageBox::information(0, "OpenGL samplebuffers",
- "This system does not have sample buffer support.");
+ QMessageBox::information(0, "OpenGL samplebuffers",
+ "This system does not have sample buffer support.");
return 0;
}
diff --git a/examples/opengl/textures/glwidget.cpp b/examples/opengl/textures/glwidget.cpp
index 6cb0c2d6ec..ac1e7965af 100644
--- a/examples/opengl/textures/glwidget.cpp
+++ b/examples/opengl/textures/glwidget.cpp
@@ -50,9 +50,7 @@ GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
xRot = 0;
yRot = 0;
zRot = 0;
-#ifdef QT_OPENGL_ES_2
program = 0;
-#endif
}
GLWidget::~GLWidget()
@@ -89,12 +87,10 @@ void GLWidget::initializeGL()
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
-#ifndef QT_OPENGL_ES_2
+#ifdef GL_TEXTURE_2D
glEnable(GL_TEXTURE_2D);
#endif
-#ifdef QT_OPENGL_ES_2
-
#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1
@@ -130,8 +126,6 @@ void GLWidget::initializeGL()
program->bind();
program->setUniformValue("texture", 0);
-
-#endif
}
void GLWidget::paintGL()
@@ -139,21 +133,6 @@ void GLWidget::paintGL()
qglClearColor(clearColor);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-#if !defined(QT_OPENGL_ES_2)
-
- glLoadIdentity();
- glTranslatef(0.0f, 0.0f, -10.0f);
- glRotatef(xRot / 16.0f, 1.0f, 0.0f, 0.0f);
- glRotatef(yRot / 16.0f, 0.0f, 1.0f, 0.0f);
- glRotatef(zRot / 16.0f, 0.0f, 0.0f, 1.0f);
-
- glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
-#else
-
QMatrix4x4 m;
m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);
m.translate(0.0f, 0.0f, -10.0f);
@@ -169,8 +148,6 @@ void GLWidget::paintGL()
program->setAttributeArray
(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
-#endif
-
for (int i = 0; i < 6; ++i) {
glBindTexture(GL_TEXTURE_2D, textures[i]);
glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
@@ -181,17 +158,6 @@ void GLWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);
-
-#if !defined(QT_OPENGL_ES_2)
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-#ifndef QT_OPENGL_ES
- glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
-#else
- glOrthof(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
-#endif
- glMatrixMode(GL_MODELVIEW);
-#endif
}
void GLWidget::mousePressEvent(QMouseEvent *event)
diff --git a/examples/opengl/textures/glwidget.h b/examples/opengl/textures/glwidget.h
index 3ffb35d1ab..fee47b9b48 100644
--- a/examples/opengl/textures/glwidget.h
+++ b/examples/opengl/textures/glwidget.h
@@ -81,9 +81,7 @@ private:
GLuint textures[6];
QVector<QVector3D> vertices;
QVector<QVector2D> texCoords;
-#ifdef QT_OPENGL_ES_2
QGLShaderProgram *program;
-#endif
};
#endif
diff --git a/examples/touch/fingerpaint/mainwindow.cpp b/examples/touch/fingerpaint/mainwindow.cpp
index 9481f888b5..f0477011d3 100644
--- a/examples/touch/fingerpaint/mainwindow.cpp
+++ b/examples/touch/fingerpaint/mainwindow.cpp
@@ -186,7 +186,7 @@ bool MainWindow::maybeSave()
tr("The image has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard
- | QMessageBox::Cancel);
+ | QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
return saveFile("png");
} else if (ret == QMessageBox::Cancel) {
diff --git a/examples/widgets/doc/src/treemodelcompleter.qdoc b/examples/widgets/doc/src/treemodelcompleter.qdoc
index f18db0db65..9411371d12 100644
--- a/examples/widgets/doc/src/treemodelcompleter.qdoc
+++ b/examples/widgets/doc/src/treemodelcompleter.qdoc
@@ -1,4 +1,4 @@
- /****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
diff --git a/examples/widgets/effects/blurpicker/blurpicker.cpp b/examples/widgets/effects/blurpicker/blurpicker.cpp
index 4ccfed8317..4f3308f07d 100644
--- a/examples/widgets/effects/blurpicker/blurpicker.cpp
+++ b/examples/widgets/effects/blurpicker/blurpicker.cpp
@@ -137,7 +137,7 @@ void BlurPicker::keyPressEvent(QKeyEvent *event)
}
}
-void BlurPicker::resizeEvent(QResizeEvent */*event*/)
+void BlurPicker::resizeEvent(QResizeEvent * /* event */)
{
}
diff --git a/examples/widgets/effects/lighting/lighting.cpp b/examples/widgets/effects/lighting/lighting.cpp
index f40b4f97ba..0c83dfc016 100644
--- a/examples/widgets/effects/lighting/lighting.cpp
+++ b/examples/widgets/effects/lighting/lighting.cpp
@@ -134,6 +134,6 @@ void Lighting::animate()
m_scene.update();
}
-void Lighting::resizeEvent(QResizeEvent */*event*/)
+void Lighting::resizeEvent(QResizeEvent * /* event */)
{
}
diff --git a/examples/widgets/graphicsview/boxes/glbuffers.h b/examples/widgets/graphicsview/boxes/glbuffers.h
index 8b95ec2ea5..304b3da87a 100644
--- a/examples/widgets/graphicsview/boxes/glbuffers.h
+++ b/examples/widgets/graphicsview/boxes/glbuffers.h
@@ -196,9 +196,9 @@ public:
{
GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers && glBindBuffer && glBufferData, return)
- glGenBuffers(1, &m_buffer);
- glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
- glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
+ glGenBuffers(1, &m_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
+ glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode);
}
~GLVertexBuffer()
diff --git a/examples/widgets/graphicsview/boxes/glextensions.cpp b/examples/widgets/graphicsview/boxes/glextensions.cpp
index eb0fe0ec6a..d10c0b4a62 100644
--- a/examples/widgets/graphicsview/boxes/glextensions.cpp
+++ b/examples/widgets/graphicsview/boxes/glextensions.cpp
@@ -45,54 +45,54 @@
bool GLExtensionFunctions::resolve(const QGLContext *context)
{
- bool ok = true;
+ bool ok = true;
- RESOLVE_GL_FUNC(GenFramebuffersEXT)
- RESOLVE_GL_FUNC(GenRenderbuffersEXT)
- RESOLVE_GL_FUNC(BindRenderbufferEXT)
- RESOLVE_GL_FUNC(RenderbufferStorageEXT)
- RESOLVE_GL_FUNC(DeleteFramebuffersEXT)
- RESOLVE_GL_FUNC(DeleteRenderbuffersEXT)
- RESOLVE_GL_FUNC(BindFramebufferEXT)
- RESOLVE_GL_FUNC(FramebufferTexture2DEXT)
- RESOLVE_GL_FUNC(FramebufferRenderbufferEXT)
- RESOLVE_GL_FUNC(CheckFramebufferStatusEXT)
+ RESOLVE_GL_FUNC(GenFramebuffersEXT)
+ RESOLVE_GL_FUNC(GenRenderbuffersEXT)
+ RESOLVE_GL_FUNC(BindRenderbufferEXT)
+ RESOLVE_GL_FUNC(RenderbufferStorageEXT)
+ RESOLVE_GL_FUNC(DeleteFramebuffersEXT)
+ RESOLVE_GL_FUNC(DeleteRenderbuffersEXT)
+ RESOLVE_GL_FUNC(BindFramebufferEXT)
+ RESOLVE_GL_FUNC(FramebufferTexture2DEXT)
+ RESOLVE_GL_FUNC(FramebufferRenderbufferEXT)
+ RESOLVE_GL_FUNC(CheckFramebufferStatusEXT)
- RESOLVE_GL_FUNC(ActiveTexture)
- RESOLVE_GL_FUNC(TexImage3D)
+ RESOLVE_GL_FUNC(ActiveTexture)
+ RESOLVE_GL_FUNC(TexImage3D)
- RESOLVE_GL_FUNC(GenBuffers)
- RESOLVE_GL_FUNC(BindBuffer)
- RESOLVE_GL_FUNC(BufferData)
- RESOLVE_GL_FUNC(DeleteBuffers)
- RESOLVE_GL_FUNC(MapBuffer)
- RESOLVE_GL_FUNC(UnmapBuffer)
+ RESOLVE_GL_FUNC(GenBuffers)
+ RESOLVE_GL_FUNC(BindBuffer)
+ RESOLVE_GL_FUNC(BufferData)
+ RESOLVE_GL_FUNC(DeleteBuffers)
+ RESOLVE_GL_FUNC(MapBuffer)
+ RESOLVE_GL_FUNC(UnmapBuffer)
- return ok;
+ return ok;
}
bool GLExtensionFunctions::fboSupported() {
return GenFramebuffersEXT
- && GenRenderbuffersEXT
- && BindRenderbufferEXT
- && RenderbufferStorageEXT
- && DeleteFramebuffersEXT
- && DeleteRenderbuffersEXT
- && BindFramebufferEXT
- && FramebufferTexture2DEXT
- && FramebufferRenderbufferEXT
- && CheckFramebufferStatusEXT;
+ && GenRenderbuffersEXT
+ && BindRenderbufferEXT
+ && RenderbufferStorageEXT
+ && DeleteFramebuffersEXT
+ && DeleteRenderbuffersEXT
+ && BindFramebufferEXT
+ && FramebufferTexture2DEXT
+ && FramebufferRenderbufferEXT
+ && CheckFramebufferStatusEXT;
}
bool GLExtensionFunctions::openGL15Supported() {
return ActiveTexture
- && TexImage3D
+ && TexImage3D
&& GenBuffers
- && BindBuffer
- && BufferData
- && DeleteBuffers
- && MapBuffer
- && UnmapBuffer;
+ && BindBuffer
+ && BufferData
+ && DeleteBuffers
+ && MapBuffer
+ && UnmapBuffer;
}
#undef RESOLVE_GL_FUNC
diff --git a/examples/widgets/graphicsview/boxes/glextensions.h b/examples/widgets/graphicsview/boxes/glextensions.h
index 46f2c11967..d92d5c304f 100644
--- a/examples/widgets/graphicsview/boxes/glextensions.h
+++ b/examples/widgets/graphicsview/boxes/glextensions.h
@@ -145,37 +145,37 @@ typedef GLboolean (APIENTRY *_glUnmapBuffer) (GLenum);
struct GLExtensionFunctions
{
- bool resolve(const QGLContext *context);
+ bool resolve(const QGLContext *context);
bool fboSupported();
bool openGL15Supported(); // the rest: multi-texture, 3D-texture, vertex buffer objects
- _glGenFramebuffersEXT GenFramebuffersEXT;
- _glGenRenderbuffersEXT GenRenderbuffersEXT;
- _glBindRenderbufferEXT BindRenderbufferEXT;
- _glRenderbufferStorageEXT RenderbufferStorageEXT;
- _glDeleteFramebuffersEXT DeleteFramebuffersEXT;
- _glDeleteRenderbuffersEXT DeleteRenderbuffersEXT;
- _glBindFramebufferEXT BindFramebufferEXT;
- _glFramebufferTexture2DEXT FramebufferTexture2DEXT;
- _glFramebufferRenderbufferEXT FramebufferRenderbufferEXT;
- _glCheckFramebufferStatusEXT CheckFramebufferStatusEXT;
-
- _glActiveTexture ActiveTexture;
- _glTexImage3D TexImage3D;
-
- _glGenBuffers GenBuffers;
- _glBindBuffer BindBuffer;
- _glBufferData BufferData;
- _glDeleteBuffers DeleteBuffers;
- _glMapBuffer MapBuffer;
- _glUnmapBuffer UnmapBuffer;
+ _glGenFramebuffersEXT GenFramebuffersEXT;
+ _glGenRenderbuffersEXT GenRenderbuffersEXT;
+ _glBindRenderbufferEXT BindRenderbufferEXT;
+ _glRenderbufferStorageEXT RenderbufferStorageEXT;
+ _glDeleteFramebuffersEXT DeleteFramebuffersEXT;
+ _glDeleteRenderbuffersEXT DeleteRenderbuffersEXT;
+ _glBindFramebufferEXT BindFramebufferEXT;
+ _glFramebufferTexture2DEXT FramebufferTexture2DEXT;
+ _glFramebufferRenderbufferEXT FramebufferRenderbufferEXT;
+ _glCheckFramebufferStatusEXT CheckFramebufferStatusEXT;
+
+ _glActiveTexture ActiveTexture;
+ _glTexImage3D TexImage3D;
+
+ _glGenBuffers GenBuffers;
+ _glBindBuffer BindBuffer;
+ _glBufferData BufferData;
+ _glDeleteBuffers DeleteBuffers;
+ _glMapBuffer MapBuffer;
+ _glUnmapBuffer UnmapBuffer;
};
inline GLExtensionFunctions &getGLExtensionFunctions()
{
- static GLExtensionFunctions funcs;
- return funcs;
+ static GLExtensionFunctions funcs;
+ return funcs;
}
#define glGenFramebuffersEXT getGLExtensionFunctions().GenFramebuffersEXT
diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp
index 11e9f4ea5a..621068ab0b 100644
--- a/examples/widgets/graphicsview/boxes/scene.cpp
+++ b/examples/widgets/graphicsview/boxes/scene.cpp
@@ -186,10 +186,10 @@ TwoSidedGraphicsWidget::TwoSidedGraphicsWidget(QGraphicsScene *scene)
void TwoSidedGraphicsWidget::setWidget(int index, QWidget *widget)
{
if (index < 0 || index >= 2)
- {
- qWarning("TwoSidedGraphicsWidget::setWidget: Index out of bounds, index == %d", index);
- return;
- }
+ {
+ qWarning("TwoSidedGraphicsWidget::setWidget: Index out of bounds, index == %d", index);
+ return;
+ }
GraphicsWidget *proxy = new GraphicsWidget;
proxy->setWidget(widget);
@@ -210,10 +210,10 @@ void TwoSidedGraphicsWidget::setWidget(int index, QWidget *widget)
QWidget *TwoSidedGraphicsWidget::widget(int index)
{
if (index < 0 || index >= 2)
- {
- qWarning("TwoSidedGraphicsWidget::widget: Index out of bounds, index == %d", index);
- return 0;
- }
+ {
+ qWarning("TwoSidedGraphicsWidget::widget: Index out of bounds, index == %d", index);
+ return 0;
+ }
return m_proxyWidgets[index]->widget();
}
diff --git a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
index 8ae8749091..973b630235 100644
--- a/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
+++ b/examples/widgets/graphicsview/elasticnodes/graphwidget.cpp
@@ -193,9 +193,9 @@ void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
QRectF rightShadow(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height());
QRectF bottomShadow(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5);
if (rightShadow.intersects(rect) || rightShadow.contains(rect))
- painter->fillRect(rightShadow, Qt::darkGray);
+ painter->fillRect(rightShadow, Qt::darkGray);
if (bottomShadow.intersects(rect) || bottomShadow.contains(rect))
- painter->fillRect(bottomShadow, Qt::darkGray);
+ painter->fillRect(bottomShadow, Qt::darkGray);
// Fill
QLinearGradient gradient(sceneRect.topLeft(), sceneRect.bottomRight());
diff --git a/examples/widgets/itemviews/pixelator/mainwindow.cpp b/examples/widgets/itemviews/pixelator/mainwindow.cpp
index 1f6a403efc..aca5545af0 100644
--- a/examples/widgets/itemviews/pixelator/mainwindow.cpp
+++ b/examples/widgets/itemviews/pixelator/mainwindow.cpp
@@ -156,11 +156,11 @@ void MainWindow::printImage()
{
#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
if (model->rowCount(QModelIndex())*model->columnCount(QModelIndex()) > 90000) {
- QMessageBox::StandardButton answer;
- answer = QMessageBox::question(this, tr("Large Image Size"),
- tr("The printed image may be very large. Are you sure that "
- "you want to print it?"),
- QMessageBox::Yes | QMessageBox::No);
+ QMessageBox::StandardButton answer;
+ answer = QMessageBox::question(this, tr("Large Image Size"),
+ tr("The printed image may be very large. Are you sure that "
+ "you want to print it?"),
+ QMessageBox::Yes | QMessageBox::No);
if (answer == QMessageBox::No)
return;
}
diff --git a/examples/widgets/layouts/basiclayouts/dialog.cpp b/examples/widgets/layouts/basiclayouts/dialog.cpp
index d162cd8541..f8b8d68d4f 100644
--- a/examples/widgets/layouts/basiclayouts/dialog.cpp
+++ b/examples/widgets/layouts/basiclayouts/dialog.cpp
@@ -101,7 +101,7 @@ void Dialog::createHorizontalGroupBox()
for (int i = 0; i < NumButtons; ++i) {
buttons[i] = new QPushButton(tr("Button %1").arg(i + 1));
- layout->addWidget(buttons[i]);
+ layout->addWidget(buttons[i]);
}
horizontalGroupBox->setLayout(layout);
}
diff --git a/examples/widgets/layouts/borderlayout/borderlayout.h b/examples/widgets/layouts/borderlayout/borderlayout.h
index d818462035..eae425d5e6 100644
--- a/examples/widgets/layouts/borderlayout/borderlayout.h
+++ b/examples/widgets/layouts/borderlayout/borderlayout.h
@@ -69,13 +69,13 @@ public:
private:
struct ItemWrapper
{
- ItemWrapper(QLayoutItem *i, Position p) {
- item = i;
- position = p;
- }
+ ItemWrapper(QLayoutItem *i, Position p) {
+ item = i;
+ position = p;
+ }
- QLayoutItem *item;
- Position position;
+ QLayoutItem *item;
+ Position position;
};
enum SizeType { MinimumSize, SizeHint };
diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp
index 00a35afa4c..b39c45118c 100644
--- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp
+++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp
@@ -636,7 +636,7 @@ void BlueTitleBar::paintEvent(QPaintEvent*)
centerPm.height(), centerPm);
}
-void BlueTitleBar::mousePressEvent(QMouseEvent *event)
+void BlueTitleBar::mouseReleaseEvent(QMouseEvent *event)
{
QPoint pos = event->pos();
diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.h b/examples/widgets/mainwindows/mainwindow/colorswatch.h
index 11f924ddb7..b83a6ba76a 100644
--- a/examples/widgets/mainwindows/mainwindow/colorswatch.h
+++ b/examples/widgets/mainwindows/mainwindow/colorswatch.h
@@ -124,7 +124,7 @@ public:
QSize minimumSizeHint() const;
protected:
void paintEvent(QPaintEvent *event);
- void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
public slots:
void updateMask();
diff --git a/examples/widgets/mainwindows/mdi/mdichild.cpp b/examples/widgets/mainwindows/mdi/mdichild.cpp
index f55e08a249..95c95e45e0 100644
--- a/examples/widgets/mainwindows/mdi/mdichild.cpp
+++ b/examples/widgets/mainwindows/mdi/mdichild.cpp
@@ -145,13 +145,13 @@ void MdiChild::documentWasModified()
bool MdiChild::maybeSave()
{
if (document()->isModified()) {
- QMessageBox::StandardButton ret;
+ QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("MDI"),
tr("'%1' has been modified.\n"
"Do you want to save your changes?")
.arg(userFriendlyCurrentFile()),
QMessageBox::Save | QMessageBox::Discard
- | QMessageBox::Cancel);
+ | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
diff --git a/examples/widgets/mainwindows/sdi/mainwindow.cpp b/examples/widgets/mainwindows/sdi/mainwindow.cpp
index b7af4ffd9d..6db9bd6261 100644
--- a/examples/widgets/mainwindows/sdi/mainwindow.cpp
+++ b/examples/widgets/mainwindows/sdi/mainwindow.cpp
@@ -282,12 +282,12 @@ void MainWindow::writeSettings()
bool MainWindow::maybeSave()
{
if (textEdit->document()->isModified()) {
- QMessageBox::StandardButton ret;
+ QMessageBox::StandardButton ret;
ret = QMessageBox::warning(this, tr("SDI"),
tr("The document has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard
- | QMessageBox::Cancel);
+ | QMessageBox::Cancel);
if (ret == QMessageBox::Save)
return save();
else if (ret == QMessageBox::Cancel)
diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp
index 873a29eb0e..128924ef4e 100644
--- a/examples/widgets/richtext/textedit/textedit.cpp
+++ b/examples/widgets/richtext/textedit/textedit.cpp
@@ -283,7 +283,7 @@ void TextEdit::setupTextActions()
tr("&Bold"), this);
actionTextBold->setShortcut(Qt::CTRL + Qt::Key_B);
actionTextBold->setPriority(QAction::LowPriority);
- QFont bold;
+ QFont bold;
bold.setBold(true);
actionTextBold->setFont(bold);
connect(actionTextBold, SIGNAL(triggered()), this, SLOT(textBold()));
diff --git a/examples/widgets/tools/codecs/mainwindow.cpp b/examples/widgets/tools/codecs/mainwindow.cpp
index e8f08bea6c..1e722ac6df 100644
--- a/examples/widgets/tools/codecs/mainwindow.cpp
+++ b/examples/widgets/tools/codecs/mainwindow.cpp
@@ -162,7 +162,7 @@ void MainWindow::createActions()
QString text = tr("%1...").arg(QString(codec->name()));
QAction *action = new QAction(text, this);
- action->setData(codec->name());
+ action->setData(codec->name());
connect(action, SIGNAL(triggered()), this, SLOT(save()));
saveAsActs.append(action);
}
diff --git a/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp b/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp
index 317c4760fb..0a2c301f9c 100644
--- a/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp
+++ b/examples/widgets/tutorials/modelview/5_edit/mymodel.cpp
@@ -77,14 +77,14 @@ bool MyModel::setData(const QModelIndex & index, const QVariant & value, int rol
{
//save value from editor to member m_gridData
m_gridData[index.row()][index.column()] = value.toString();
- //for presentation purposes only: build and emit a joined string
+ //for presentation purposes only: build and emit a joined string
QString result;
- for(int row= 0; row < ROWS; row++)
- {
+ for (int row= 0; row < ROWS; row++)
+ {
for(int col= 0; col < COLS; col++)
- {
- result += m_gridData[row][col] + " ";
- }
+ {
+ result += m_gridData[row][col] + " ";
+ }
}
emit editCompleted( result );
}
diff --git a/examples/widgets/widgets/calculator/calculator.cpp b/examples/widgets/widgets/calculator/calculator.cpp
index 5b6b69ba03..bb3836bd70 100644
--- a/examples/widgets/widgets/calculator/calculator.cpp
+++ b/examples/widgets/widgets/calculator/calculator.cpp
@@ -69,7 +69,7 @@ Calculator::Calculator(QWidget *parent)
//! [4]
for (int i = 0; i < NumDigitButtons; ++i) {
- digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
+ digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
}
Button *pointButton = createButton(tr("."), SLOT(pointClicked()));
@@ -144,7 +144,7 @@ void Calculator::digitClicked()
if (waitingForOperand) {
display->clear();
- waitingForOperand = false;
+ waitingForOperand = false;
}
display->setText(display->text() + QString::number(digitValue));
}
@@ -169,8 +169,8 @@ void Calculator::unaryOperatorClicked()
result = pow(operand, 2.0);
} else if (clickedOperator == tr("1/x")) {
if (operand == 0.0) {
- abortOperation();
- return;
+ abortOperation();
+ return;
}
result = 1.0 / operand;
}
@@ -192,7 +192,7 @@ void Calculator::additiveOperatorClicked()
//! [12] //! [13]
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
- return;
+ return;
}
display->setText(QString::number(factorSoFar));
operand = factorSoFar;
@@ -205,7 +205,7 @@ void Calculator::additiveOperatorClicked()
//! [14] //! [15]
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
- return;
+ return;
}
display->setText(QString::number(sumSoFar));
} else {
@@ -229,7 +229,7 @@ void Calculator::multiplicativeOperatorClicked()
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
- return;
+ return;
}
display->setText(QString::number(factorSoFar));
} else {
@@ -249,7 +249,7 @@ void Calculator::equalClicked()
if (!pendingMultiplicativeOperator.isEmpty()) {
if (!calculate(operand, pendingMultiplicativeOperator)) {
abortOperation();
- return;
+ return;
}
operand = factorSoFar;
factorSoFar = 0.0;
@@ -258,7 +258,7 @@ void Calculator::equalClicked()
if (!pendingAdditiveOperator.isEmpty()) {
if (!calculate(operand, pendingAdditiveOperator)) {
abortOperation();
- return;
+ return;
}
pendingAdditiveOperator.clear();
} else {
@@ -387,9 +387,9 @@ bool Calculator::calculate(double rightOperand, const QString &pendingOperator)
} else if (pendingOperator == tr("\303\227")) {
factorSoFar *= rightOperand;
} else if (pendingOperator == tr("\303\267")) {
- if (rightOperand == 0.0)
- return false;
- factorSoFar /= rightOperand;
+ if (rightOperand == 0.0)
+ return false;
+ factorSoFar /= rightOperand;
}
return true;
}
diff --git a/examples/widgets/widgets/lineedits/window.cpp b/examples/widgets/widgets/lineedits/window.cpp
index a0871e7c77..fe241208f6 100644
--- a/examples/widgets/widgets/lineedits/window.cpp
+++ b/examples/widgets/widgets/lineedits/window.cpp
@@ -182,7 +182,7 @@ void Window::echoChanged(int index)
echoLineEdit->setEchoMode(QLineEdit::Password);
break;
case 2:
- echoLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
+ echoLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
break;
case 3:
echoLineEdit->setEchoMode(QLineEdit::NoEcho);
@@ -221,7 +221,7 @@ void Window::alignmentChanged(int index)
alignmentLineEdit->setAlignment(Qt::AlignCenter);
break;
case 2:
- alignmentLineEdit->setAlignment(Qt::AlignRight);
+ alignmentLineEdit->setAlignment(Qt::AlignRight);
}
}
//! [11]
diff --git a/examples/widgets/widgets/scribble/mainwindow.cpp b/examples/widgets/widgets/scribble/mainwindow.cpp
index 65550ae606..5f175c15b5 100644
--- a/examples/widgets/widgets/scribble/mainwindow.cpp
+++ b/examples/widgets/widgets/scribble/mainwindow.cpp
@@ -219,7 +219,7 @@ bool MainWindow::maybeSave()
tr("The image has been modified.\n"
"Do you want to save your changes?"),
QMessageBox::Save | QMessageBox::Discard
- | QMessageBox::Cancel);
+ | QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
return saveFile("png");
} else if (ret == QMessageBox::Cancel) {
diff --git a/examples/widgets/widgets/spinboxes/window.cpp b/examples/widgets/widgets/spinboxes/window.cpp
index acce642ec6..6503d60f22 100644
--- a/examples/widgets/widgets/spinboxes/window.cpp
+++ b/examples/widgets/widgets/spinboxes/window.cpp
@@ -94,6 +94,16 @@ void Window::createSpinBoxes()
priceSpinBox->setValue(99);
//! [4] //! [5]
+ groupSeparatorSpinBox = new QSpinBox;
+ groupSeparatorSpinBox->setRange(-99999999, 99999999);
+ groupSeparatorSpinBox->setValue(1000);
+ groupSeparatorSpinBox->setGroupSeparatorShown(true);
+ QCheckBox *groupSeparatorChkBox = new QCheckBox;
+ groupSeparatorChkBox->setText(tr("Show group separator"));
+ groupSeparatorChkBox->setChecked(true);
+ connect(groupSeparatorChkBox, &QCheckBox::toggled, groupSeparatorSpinBox,
+ &QSpinBox::setGroupSeparatorShown);
+
QLabel *hexLabel = new QLabel(tr("Enter a value between "
"%1 and %2:").arg('-' + QString::number(31, 16)).arg(QString::number(31, 16)));
QSpinBox *hexSpinBox = new QSpinBox;
@@ -111,6 +121,8 @@ void Window::createSpinBoxes()
spinBoxLayout->addWidget(priceSpinBox);
spinBoxLayout->addWidget(hexLabel);
spinBoxLayout->addWidget(hexSpinBox);
+ spinBoxLayout->addWidget(groupSeparatorChkBox);
+ spinBoxLayout->addWidget(groupSeparatorSpinBox);
spinBoxesGroup->setLayout(spinBoxLayout);
}
//! [5]
@@ -182,12 +194,12 @@ void Window::setFormatString(const QString &formatString)
meetingEdit->setDateRange(QDate(2004, 11, 1), QDate(2005, 11, 30));
meetingLabel->setText(tr("Meeting date (between %0 and %1):")
.arg(meetingEdit->minimumDate().toString(Qt::ISODate))
- .arg(meetingEdit->maximumDate().toString(Qt::ISODate)));
+ .arg(meetingEdit->maximumDate().toString(Qt::ISODate)));
} else {
meetingEdit->setTimeRange(QTime(0, 7, 20, 0), QTime(21, 0, 0, 0));
meetingLabel->setText(tr("Meeting time (between %0 and %1):")
.arg(meetingEdit->minimumTime().toString(Qt::ISODate))
- .arg(meetingEdit->maximumTime().toString(Qt::ISODate)));
+ .arg(meetingEdit->maximumTime().toString(Qt::ISODate)));
}
}
//! [13]
@@ -237,6 +249,17 @@ void Window::createDoubleSpinBoxes()
//! [17]
this, SLOT(changePrecision(int)));
+ groupSeparatorSpinBox_d = new QDoubleSpinBox;
+ groupSeparatorSpinBox_d->setRange(-99999999, 99999999);
+ groupSeparatorSpinBox_d->setDecimals(2);
+ groupSeparatorSpinBox_d->setValue(1000.00);
+ groupSeparatorSpinBox_d->setGroupSeparatorShown(true);
+ QCheckBox *groupSeparatorChkBox = new QCheckBox;
+ groupSeparatorChkBox->setText(tr("Show group separator"));
+ groupSeparatorChkBox->setChecked(true);
+ connect(groupSeparatorChkBox, &QCheckBox::toggled, groupSeparatorSpinBox_d,
+ &QDoubleSpinBox::setGroupSeparatorShown);
+
//! [18]
QVBoxLayout *spinBoxLayout = new QVBoxLayout;
spinBoxLayout->addWidget(precisionLabel);
@@ -247,6 +270,8 @@ void Window::createDoubleSpinBoxes()
spinBoxLayout->addWidget(scaleSpinBox);
spinBoxLayout->addWidget(priceLabel);
spinBoxLayout->addWidget(priceSpinBox);
+ spinBoxLayout->addWidget(groupSeparatorChkBox);
+ spinBoxLayout->addWidget(groupSeparatorSpinBox_d);
doubleSpinBoxesGroup->setLayout(spinBoxLayout);
}
//! [18]
diff --git a/examples/widgets/widgets/spinboxes/window.h b/examples/widgets/widgets/spinboxes/window.h
index ef7af04f59..32622c2c24 100644
--- a/examples/widgets/widgets/spinboxes/window.h
+++ b/examples/widgets/widgets/spinboxes/window.h
@@ -45,6 +45,7 @@
QT_BEGIN_NAMESPACE
class QDateTimeEdit;
+class QSpinBox;
class QDoubleSpinBox;
class QGroupBox;
class QLabel;
@@ -75,6 +76,8 @@ private:
QGroupBox *editsGroup;
QGroupBox *doubleSpinBoxesGroup;
QLabel *meetingLabel;
+ QSpinBox *groupSeparatorSpinBox;
+ QDoubleSpinBox *groupSeparatorSpinBox_d;
};
//! [0]
diff --git a/examples/widgets/widgets/tetrix/tetrixboard.cpp b/examples/widgets/widgets/tetrix/tetrixboard.cpp
index 15a2e8e6dd..c286af6406 100644
--- a/examples/widgets/widgets/tetrix/tetrixboard.cpp
+++ b/examples/widgets/widgets/tetrix/tetrixboard.cpp
@@ -109,9 +109,9 @@ void TetrixBoard::pause()
isPaused = !isPaused;
if (isPaused) {
- timer.stop();
+ timer.stop();
} else {
- timer.start(timeoutTime(), this);
+ timer.start(timeoutTime(), this);
}
update();
//! [5] //! [6]
@@ -128,7 +128,7 @@ void TetrixBoard::paintEvent(QPaintEvent *event)
//! [7]
if (isPaused) {
- painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
+ painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
return;
}
@@ -138,7 +138,7 @@ void TetrixBoard::paintEvent(QPaintEvent *event)
for (int i = 0; i < BoardHeight; ++i) {
for (int j = 0; j < BoardWidth; ++j) {
TetrixShape shape = shapeAt(j, BoardHeight - i - 1);
- if (shape != NoShape)
+ if (shape != NoShape)
drawSquare(painter, rect.left() + j * squareWidth(),
boardTop + i * squareHeight(), shape);
}
@@ -165,7 +165,7 @@ void TetrixBoard::paintEvent(QPaintEvent *event)
void TetrixBoard::keyPressEvent(QKeyEvent *event)
{
if (!isStarted || isPaused || curPiece.shape() == NoShape) {
- QFrame::keyPressEvent(event);
+ QFrame::keyPressEvent(event);
return;
}
//! [13]
@@ -174,24 +174,24 @@ void TetrixBoard::keyPressEvent(QKeyEvent *event)
switch (event->key()) {
case Qt::Key_Left:
tryMove(curPiece, curX - 1, curY);
- break;
+ break;
case Qt::Key_Right:
tryMove(curPiece, curX + 1, curY);
- break;
+ break;
case Qt::Key_Down:
tryMove(curPiece.rotatedRight(), curX, curY);
- break;
+ break;
case Qt::Key_Up:
tryMove(curPiece.rotatedLeft(), curX, curY);
- break;
+ break;
case Qt::Key_Space:
- dropDown();
- break;
+ dropDown();
+ break;
case Qt::Key_D:
- oneLineDown();
- break;
+ oneLineDown();
+ break;
default:
- QFrame::keyPressEvent(event);
+ QFrame::keyPressEvent(event);
}
//! [14]
}
@@ -201,9 +201,9 @@ void TetrixBoard::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timer.timerId()) {
if (isWaitingAfterLine) {
- isWaitingAfterLine = false;
- newPiece();
- timer.start(timeoutTime(), this);
+ isWaitingAfterLine = false;
+ newPiece();
+ timer.start(timeoutTime(), this);
} else {
oneLineDown();
}
@@ -243,7 +243,7 @@ void TetrixBoard::dropDown()
void TetrixBoard::oneLineDown()
{
if (!tryMove(curPiece, curX, curY - 1))
- pieceDropped(0);
+ pieceDropped(0);
}
//! [21]
@@ -290,24 +290,24 @@ void TetrixBoard::removeFullLines()
if (lineIsFull) {
//! [24] //! [25]
- ++numFullLines;
- for (int k = i; k < BoardHeight - 1; ++k) {
+ ++numFullLines;
+ for (int k = i; k < BoardHeight - 1; ++k) {
for (int j = 0; j < BoardWidth; ++j)
shapeAt(j, k) = shapeAt(j, k + 1);
- }
+ }
//! [25] //! [26]
- for (int j = 0; j < BoardWidth; ++j)
+ for (int j = 0; j < BoardWidth; ++j)
shapeAt(j, BoardHeight - 1) = NoShape;
- }
+ }
//! [26] //! [27]
}
//! [27]
//! [28]
if (numFullLines > 0) {
- numLinesRemoved += numFullLines;
- score += 10 * numFullLines;
- emit linesRemovedChanged(numLinesRemoved);
+ numLinesRemoved += numFullLines;
+ score += 10 * numFullLines;
+ emit linesRemovedChanged(numLinesRemoved);
emit scoreChanged(score);
timer.start(500, this);
@@ -329,7 +329,7 @@ void TetrixBoard::newPiece()
curY = BoardHeight - 1 + curPiece.minY();
if (!tryMove(curPiece, curX, curY)) {
- curPiece.setShape(NoShape);
+ curPiece.setShape(NoShape);
timer.stop();
isStarted = false;
}
diff --git a/examples/widgets/widgets/wiggly/wigglywidget.cpp b/examples/widgets/widgets/wiggly/wigglywidget.cpp
index cfd45a611a..a68bafb77d 100644
--- a/examples/widgets/widgets/wiggly/wigglywidget.cpp
+++ b/examples/widgets/widgets/wiggly/wigglywidget.cpp
@@ -63,7 +63,7 @@ void WigglyWidget::paintEvent(QPaintEvent * /* event */)
//! [1] //! [2]
{
static const int sineTable[16] = {
- 0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
+ 0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
};
QFontMetrics metrics(font());
@@ -94,7 +94,7 @@ void WigglyWidget::timerEvent(QTimerEvent *event)
++step;
update();
} else {
- QWidget::timerEvent(event);
+ QWidget::timerEvent(event);
}
//! [6]
}
diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf
index ace2496f10..d58b44b295 100644
--- a/mkspecs/common/clang.conf
+++ b/mkspecs/common/clang.conf
@@ -13,6 +13,7 @@ QMAKE_LINK_SHLIB = $$QMAKE_CXX
CONFIG += clang_pch_style
QMAKE_PCH_OUTPUT_EXT = .pch
+QMAKE_CFLAGS_ISYSTEM = -isystem
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf
index b1f2ad4979..e3e72741ab 100644
--- a/mkspecs/common/gcc-base.conf
+++ b/mkspecs/common/gcc-base.conf
@@ -40,6 +40,7 @@ QMAKE_CFLAGS_DEBUG += -g
QMAKE_CFLAGS_SHLIB += -fPIC
QMAKE_CFLAGS_STATIC_LIB += -fPIC
QMAKE_CFLAGS_APP += -fPIE
+QMAKE_CFLAGS_ISYSTEM = -isystem
QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
QMAKE_CFLAGS_EXCEPTIONS_OFF += -fno-exceptions
diff --git a/mkspecs/common/mac/qplatformdefs.h b/mkspecs/common/mac/qplatformdefs.h
index 7ee337cce4..aad3b2330c 100644
--- a/mkspecs/common/mac/qplatformdefs.h
+++ b/mkspecs/common/mac/qplatformdefs.h
@@ -87,7 +87,7 @@
#define QT_SIGNAL_IGNORE (void (*)(int))1
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/common/wince/qplatformdefs.h b/mkspecs/common/wince/qplatformdefs.h
index d46a03d5ca..b4d44c1dc5 100644
--- a/mkspecs/common/wince/qplatformdefs.h
+++ b/mkspecs/common/wince/qplatformdefs.h
@@ -63,48 +63,48 @@
#include <windows.h>
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_STATBUF struct _stati64 // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
-#define QT_STAT ::_stati64
-#define QT_FSTAT ::_fstati64
+#define QT_STATBUF struct _stati64 // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
+#define QT_STAT ::_stati64
+#define QT_FSTAT ::_fstati64
#else
-#define QT_STATBUF struct stat // non-ANSI defs
-#define QT_STATBUF4TSTAT struct stat // non-ANSI defs
-#define QT_STAT ::qt_wince_stat
-#define QT_FSTAT ::qt_wince__fstat
+#define QT_STATBUF struct stat // non-ANSI defs
+#define QT_STATBUF4TSTAT struct stat // non-ANSI defs
+#define QT_STAT ::qt_wince_stat
+#define QT_FSTAT ::qt_wince__fstat
#endif
-#define QT_STAT_REG _S_IFREG
-#define QT_STAT_DIR _S_IFDIR
-#define QT_STAT_MASK _S_IFMT
+#define QT_STAT_REG _S_IFREG
+#define QT_STAT_DIR _S_IFDIR
+#define QT_STAT_MASK _S_IFMT
#if defined(_S_IFLNK)
-# define QT_STAT_LNK _S_IFLNK
+# define QT_STAT_LNK _S_IFLNK
#endif
-#define QT_FILENO ::qt_wince___fileno
-#define QT_OPEN ::qt_wince_open
-#define QT_CLOSE ::qt_wince__close
+#define QT_FILENO ::qt_wince___fileno
+#define QT_OPEN ::qt_wince_open
+#define QT_CLOSE ::qt_wince__close
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_LSEEK ::_lseeki64
-#define QT_TSTAT ::_tstati64
+#define QT_LSEEK ::_lseeki64
+#define QT_TSTAT ::_tstati64
#else
-#define QT_LSEEK ::qt_wince__lseek
-#define QT_TSTAT ::_tstat
+#define QT_LSEEK ::qt_wince__lseek
+#define QT_TSTAT ::_tstat
#endif
-#define QT_READ ::qt_wince__read
-#define QT_WRITE ::qt_wince__write
-#define QT_ACCESS ::qt_wince__access
-#define QT_GETCWD ::_getcwd
-#define QT_CHDIR ::_chdir
-#define QT_MKDIR ::qt_wince__mkdir
-#define QT_RMDIR ::qt_wince__rmdir
-#define QT_OPEN_LARGEFILE 0
-#define QT_OPEN_RDONLY _O_RDONLY
-#define QT_OPEN_WRONLY _O_WRONLY
-#define QT_OPEN_RDWR _O_RDWR
-#define QT_OPEN_CREAT _O_CREAT
-#define QT_OPEN_TRUNC _O_TRUNC
-#define QT_OPEN_APPEND _O_APPEND
-# define QT_OPEN_TEXT _O_TEXT
-# define QT_OPEN_BINARY _O_BINARY
+#define QT_READ ::qt_wince__read
+#define QT_WRITE ::qt_wince__write
+#define QT_ACCESS ::qt_wince__access
+#define QT_GETCWD ::_getcwd
+#define QT_CHDIR ::_chdir
+#define QT_MKDIR ::qt_wince__mkdir
+#define QT_RMDIR ::qt_wince__rmdir
+#define QT_OPEN_LARGEFILE 0
+#define QT_OPEN_RDONLY _O_RDONLY
+#define QT_OPEN_WRONLY _O_WRONLY
+#define QT_OPEN_RDWR _O_RDWR
+#define QT_OPEN_CREAT _O_CREAT
+#define QT_OPEN_TRUNC _O_TRUNC
+#define QT_OPEN_APPEND _O_APPEND
+# define QT_OPEN_TEXT _O_TEXT
+# define QT_OPEN_BINARY _O_BINARY
#define QT_FOPEN ::fopen
#define QT_FSEEK ::fseek
@@ -115,17 +115,17 @@
#define QT_FPOS_T fpos_t
#define QT_OFF_T long
-#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_ARGS int
#define QT_VSNPRINTF(buffer, count, format, arg) \
_vsnprintf(buffer, count, format, arg)
-#define QT_SNPRINTF ::_snprintf
+#define QT_SNPRINTF ::_snprintf
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
typedef int mode_t;
diff --git a/mkspecs/common/winrt_winphone/assets/logo_large.png b/mkspecs/common/winrt_winphone/assets/logo_large.png
new file mode 100644
index 0000000000..069171ca4d
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/logo_large.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/logo_medium.png b/mkspecs/common/winrt_winphone/assets/logo_medium.png
new file mode 100644
index 0000000000..fa0d9fb64a
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/logo_medium.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/logo_small.png b/mkspecs/common/winrt_winphone/assets/logo_small.png
new file mode 100644
index 0000000000..2acac59e73
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/logo_small.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/logo_splash.png b/mkspecs/common/winrt_winphone/assets/logo_splash.png
new file mode 100644
index 0000000000..a2be79f5d7
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/logo_splash.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/logo_store.png b/mkspecs/common/winrt_winphone/assets/logo_store.png
new file mode 100644
index 0000000000..417ccdcb5f
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/logo_store.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/tile_iconic_medium.png b/mkspecs/common/winrt_winphone/assets/tile_iconic_medium.png
new file mode 100644
index 0000000000..e42f8255db
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/tile_iconic_medium.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/assets/tile_iconic_small.png b/mkspecs/common/winrt_winphone/assets/tile_iconic_small.png
new file mode 100644
index 0000000000..c7b7ee7893
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/assets/tile_iconic_small.png
Binary files differ
diff --git a/mkspecs/common/winrt_winphone/manifests/8.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.0/AppxManifest.xml.in
new file mode 100644
index 0000000000..6a0ca444c3
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/manifests/8.0/AppxManifest.xml.in
@@ -0,0 +1,39 @@
+<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\">
+ <Identity
+ Name=\"$${WINRT_MANIFEST.identity}\"
+ ProcessorArchitecture=\"$${WINRT_MANIFEST.architecture}\"
+ Publisher=\"$${WINRT_MANIFEST.publisherid}\"
+ Version=\"$${WINRT_MANIFEST.version}\" />
+ <Properties>
+ <DisplayName>$${WINRT_MANIFEST.name}</DisplayName>
+ <PublisherDisplayName>$${WINRT_MANIFEST.publisher}</PublisherDisplayName>
+ <Logo>$${WINRT_MANIFEST.logo_store}</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.2.0</OSMinVersion>
+ <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language=\"en\" />
+ </Resources>
+ <Applications>
+ <Application
+ Id=\"App\"
+ Executable=\"$${WINRT_MANIFEST.target}.exe\"
+ EntryPoint=\"$${WINRT_MANIFEST.target}.App\">
+ <VisualElements
+ DisplayName=\"$${WINRT_MANIFEST.name}\"
+ Logo=\"$${WINRT_MANIFEST.logo_large}\"
+ SmallLogo=\"$${WINRT_MANIFEST.logo_small}\"
+ Description=\"$${WINRT_MANIFEST.description}\"
+ BackgroundColor=\"$${WINRT_MANIFEST.background}\"
+ ForegroundText=\"$${WINRT_MANIFEST.foreground}\">
+ <SplashScreen Image=\"$${WINRT_MANIFEST.logo_splash}\" />
+ </VisualElements>
+ </Application>
+ </Applications>
+ <Capabilities>$${WINRT_MANIFEST.capabilities}</Capabilities>
+ <Dependencies>$${WINRT_MANIFEST.dependencies}</Dependencies>
+</Package>
+<!-- Generated by qmake using the $$[QMAKE_XSPEC] mkspec. Remove this line to prevent this file from getting overwritten by qmake. -->
diff --git a/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
new file mode 100644
index 0000000000..e1d3d071e9
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
@@ -0,0 +1,39 @@
+<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<Deployment xmlns=\"http://schemas.microsoft.com/windowsphone/2012/deployment\" AppPlatformVersion=\"8.0\">
+ <DefaultLanguage xmlns=\"\" code=\"en-US\" />
+ <App xmlns=\"\"
+ ProductID=\"$${WINRT_MANIFEST.identity}\"
+ Title=\"$${WINRT_MANIFEST.name}\"
+ RuntimeType=\"Modern Native\"
+ Version=\"$${WINRT_MANIFEST.version}\"
+ Genre=\"$${WINRT_MANIFEST.genre}\"
+ Author=\"$${WINRT_MANIFEST.author}\"
+ Description=\"$${WINRT_MANIFEST.description}\"
+ Publisher=\"$${WINRT_MANIFEST.publisher}\"
+ PublisherID=\"$${WINRT_MANIFEST.publisherid}\">
+ <IconPath IsRelative=\"true\" IsResource=\"false\">$${WINRT_MANIFEST.logo_medium}</IconPath>
+ <Capabilities>$${WINRT_MANIFEST.capabilities}</Capabilities>
+ <Tasks>
+ <DefaultTask
+ Name=\"_default\"
+ ImagePath=\"$${WINRT_MANIFEST.target}.exe\"
+ ImageParams=\"$${WINRT_MANIFEST.arguments}\" />
+ </Tasks>
+ <Tokens>
+ <PrimaryToken TokenID=\"$${WINRT_MANIFEST.target}\" TaskName=\"_default\">
+ <TemplateIconic>
+ <SmallImageURI IsRelative=\"true\" IsResource=\"false\">$${WINRT_MANIFEST.tile_iconic_small}</SmallImageURI>
+ <IconImageURI IsRelative=\"true\" IsResource=\"false\">$${WINRT_MANIFEST.tile_iconic_medium}</IconImageURI>
+ <Title>$${WINRT_MANIFEST.name}</Title>
+ <BackgroundColor>$${WINRT_MANIFEST.background}</BackgroundColor>
+ </TemplateIconic>
+ </PrimaryToken>
+ </Tokens>
+ <ScreenResolutions>
+ <ScreenResolution Name=\"ID_RESOLUTION_WVGA\" />
+ <ScreenResolution Name=\"ID_RESOLUTION_WXGA\" />
+ <ScreenResolution Name=\"ID_RESOLUTION_HD720P\" />
+ </ScreenResolutions>
+ </App>
+</Deployment>
+<!-- Generated by qmake using the $$[QMAKE_XSPEC] mkspec. Remove this line to prevent this file from getting overwritten by qmake. -->
diff --git a/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
new file mode 100644
index 0000000000..8c214871e3
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
@@ -0,0 +1,44 @@
+<?xml version=\"1.0\" encoding=\"utf-8\"?>
+<Package xmlns=\"http://schemas.microsoft.com/appx/2010/manifest\" xmlns:v2=\"http://schemas.microsoft.com/appx/2013/manifest\">
+ <Identity
+ Name=\"$${WINRT_MANIFEST.identity}\"
+ ProcessorArchitecture=\"$${WINRT_MANIFEST.architecture}\"
+ Publisher=\"$${WINRT_MANIFEST.publisherid}\"
+ Version=\"$${WINRT_MANIFEST.version}\" />
+ <Properties>
+ <DisplayName>$${WINRT_MANIFEST.name}</DisplayName>
+ <PublisherDisplayName>$${WINRT_MANIFEST.publisher}</PublisherDisplayName>
+ <Logo>$${WINRT_MANIFEST.logo_store}</Logo>
+ </Properties>
+ <Prerequisites>
+ <OSMinVersion>6.3.0</OSMinVersion>
+ <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
+ </Prerequisites>
+ <Resources>
+ <Resource Language=\"en\" />
+ </Resources>
+ <Applications>
+ <Application
+ Id=\"App\"
+ Executable=\"$${WINRT_MANIFEST.target}.exe\"
+ EntryPoint=\"$${WINRT_MANIFEST.target}.App\">
+ <v2:VisualElements
+ DisplayName=\"$${WINRT_MANIFEST.name}\"
+ Description=\"$${WINRT_MANIFEST.description}\"
+ BackgroundColor=\"$${WINRT_MANIFEST.background}\"
+ ForegroundText=\"$${WINRT_MANIFEST.foreground}\"
+ Square150x150Logo=\"$${WINRT_MANIFEST.logo_large}\"
+ Square30x30Logo=\"$${WINRT_MANIFEST.logo_small}\">
+ <v2:DefaultTile>
+ <v2:ShowNameOnTiles>
+ <v2:ShowOn Tile=\"square150x150Logo\" />
+ </v2:ShowNameOnTiles>
+ </v2:DefaultTile>
+ <v2:SplashScreen Image=\"$${WINRT_MANIFEST.logo_splash}\" />
+ </v2:VisualElements>
+ </Application>
+ </Applications>
+ <Capabilities>$${WINRT_MANIFEST.capabilities}</Capabilities>
+ <Dependencies>$${WINRT_MANIFEST.dependencies}</Dependencies>
+</Package>
+<!-- Generated by qmake using the $$[QMAKE_XSPEC] mkspec. Remove this line to prevent this file from getting overwritten by qmake. -->
diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf
index a8c9582c31..d7296afe95 100644
--- a/mkspecs/common/winrt_winphone/qmake.conf
+++ b/mkspecs/common/winrt_winphone/qmake.conf
@@ -1,16 +1,15 @@
#
# qmake configuration for winrt and windows phone 8
#
-# Written for Microsoft Visual C++ 2012
+# Written for Microsoft Visual C++
#
MAKEFILE_GENERATOR = MSBUILD
QMAKE_COMPILER = msvc
QMAKE_PLATFORM = winrt win32
-CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target no_generated_target_info autogen_wmappmanifest rtti
-DEFINES += UNICODE WINRT QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN \
+CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target no_generated_target_info package_manifest rtti
+DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN \
QT_NO_PRINTER QT_NO_PRINTDIALOG # TODO: Remove when printing is re-enabled
-QMAKE_COMPILER_DEFINES += _MSC_VER=1700 WINRT
DEPLOYMENT_PLUGIN += qwinrt
@@ -19,7 +18,6 @@ QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = byacc
QMAKE_YACCFLAGS = -d
-#QMAKE_CFLAGS = -nologo -Zm200 -Zc:wchar_t-
QMAKE_CFLAGS = -nologo -Zm200
QMAKE_CFLAGS_WARN_ON = -W3
QMAKE_CFLAGS_WARN_OFF = -W0
@@ -64,22 +62,24 @@ QMAKE_RUN_CXX_IMP = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ $<
QMAKE_RUN_CXX_IMP_BATCH = $(CXX) -c $(CXXFLAGS) $(INCPATH) -Fo$@ @<<
QMAKE_LINK = link
-QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /NODEFAULTLIB:ole32.lib
+QMAKE_LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /NODEFAULTLIB:ole32.lib /APPCONTAINER
QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO
QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO = /DEBUG /OPT:REF /INCREMENTAL:NO
QMAKE_LFLAGS_DEBUG = /DEBUG
-QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE
QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS
-QMAKE_LFLAGS_EXE = /WINMD /MANIFEST:NO
-QMAKE_LFLAGS_DLL = /WINMD /MANIFEST:NO /DLL /WINMDFILE:$(DESTDIR_TARGET).winmd
+QMAKE_LFLAGS_EXE = /MANIFEST:NO
+QMAKE_LFLAGS_DLL = /MANIFEST:NO /DLL
QMAKE_LFLAGS_LTCG = /LTCG
QMAKE_EXTENSION_STATICLIB = lib
+QMAKE_LIBS += runtimeobject.lib
QMAKE_LIBS_CORE =
-QMAKE_LIBS_GUI = d3d11.lib
+QMAKE_LIBS_GUI =
QMAKE_LIBS_NETWORK =
+QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib
+QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib
-QMAKE_LIBS_QT_ENTRY = -lqtmain /ENTRY:wmainCRTStartup
+QMAKE_LIBS_QT_ENTRY = -lqtmain
QMAKE_IDL = midl
QMAKE_LIB = lib /NOLOGO
@@ -89,5 +89,6 @@ include(../shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
-VCPROJ_KEYWORD = Qt4VSv1.0
+VCPROJ_KEYWORD = Qt4VSv1.0
+WINRT_ASSETS_PATH = $$PWD/assets
load(qt_config)
diff --git a/mkspecs/common/winrt_winphone/qplatformdefs.h b/mkspecs/common/winrt_winphone/qplatformdefs.h
new file mode 100644
index 0000000000..96f20569d2
--- /dev/null
+++ b/mkspecs/common/winrt_winphone/qplatformdefs.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+#ifdef UNICODE
+#ifndef _UNICODE
+#define _UNICODE
+#endif
+#endif
+
+// Get Qt defines/settings
+
+#include "qglobal.h"
+#include "qfunctions_winrt.h"
+
+#define _POSIX_
+#include <limits.h>
+#undef _POSIX_
+
+#include <tchar.h>
+#include <io.h>
+#include <direct.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_STATBUF struct _stati64 // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
+#define QT_STAT ::_stati64
+#define QT_FSTAT ::_fstati64
+#else
+#define QT_STATBUF struct _stat // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
+#define QT_STAT ::_stat
+#define QT_FSTAT ::_fstat
+#endif
+#define QT_STAT_REG _S_IFREG
+#define QT_STAT_DIR _S_IFDIR
+#define QT_STAT_MASK _S_IFMT
+#if defined(_S_IFLNK)
+# define QT_STAT_LNK _S_IFLNK
+#endif
+#define QT_FILENO _fileno
+#define QT_OPEN ::_open
+#define QT_CLOSE ::_close
+#ifdef QT_LARGEFILE_SUPPORT
+#define QT_LSEEK ::_lseeki64
+#define QT_TSTAT ::_tstati64
+#else
+#define QT_LSEEK ::_lseek
+#define QT_TSTAT ::_tstat
+#endif
+#define QT_READ ::_read
+#define QT_WRITE ::_write
+#define QT_ACCESS ::_access
+#define QT_GETCWD ::_getcwd
+#define QT_CHDIR ::_chdir
+#define QT_MKDIR ::_mkdir
+#define QT_RMDIR ::_rmdir
+#define QT_OPEN_LARGEFILE 0
+#define QT_OPEN_RDONLY _O_RDONLY
+#define QT_OPEN_WRONLY _O_WRONLY
+#define QT_OPEN_RDWR _O_RDWR
+#define QT_OPEN_CREAT _O_CREAT
+#define QT_OPEN_TRUNC _O_TRUNC
+#define QT_OPEN_APPEND _O_APPEND
+#if defined(O_TEXT)
+# define QT_OPEN_TEXT _O_TEXT
+# define QT_OPEN_BINARY _O_BINARY
+#endif
+
+#include "../common/c89/qplatformdefs.h"
+
+#ifdef QT_LARGEFILE_SUPPORT
+#undef QT_FSEEK
+#undef QT_FTELL
+#undef QT_OFF_T
+
+#define QT_FSEEK ::_fseeki64
+#define QT_FTELL ::_ftelli64
+#define QT_OFF_T __int64
+#endif
+
+#define QT_SIGNAL_ARGS int
+
+#define QT_VSNPRINTF(buffer, count, format, arg) \
+ vsnprintf_s(buffer, count, count-1, format, arg)
+
+#define QT_SNPRINTF ::_snprintf
+
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+
+typedef int mode_t;
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/cygwin-g++/qplatformdefs.h b/mkspecs/cygwin-g++/qplatformdefs.h
index e7255a9342..b3ecc0f84d 100644
--- a/mkspecs/cygwin-g++/qplatformdefs.h
+++ b/mkspecs/cygwin-g++/qplatformdefs.h
@@ -73,7 +73,7 @@
#include <sys/ioctl.h>
// Cygwin does not provide <sys/ipc.h> and <sys/shm.h> because it
// doesn't support SysV IPC or shared memory. See for example:
-// http://afni.nimh.nih.gov/afni/afniboard/messages/1725.html
+// http://afni.nimh.nih.gov/afni/afniboard/messages/1725.html
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -88,8 +88,8 @@
#define QT_OPEN_LARGEFILE 0
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/darwin-g++/qplatformdefs.h b/mkspecs/darwin-g++/qplatformdefs.h
index 20ffac9e5b..f89d4bee80 100644
--- a/mkspecs/darwin-g++/qplatformdefs.h
+++ b/mkspecs/darwin-g++/qplatformdefs.h
@@ -79,7 +79,7 @@
#undef QT_OPEN_LARGEFILE
#define QT_OPEN_LARGEFILE 0
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
index 5e57ba382a..c4737a4559 100644
--- a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
+++ b/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
#include <QtDebug>
@@ -107,12 +106,6 @@ static void moveDispmanxLayer(EGLNativeWindowType window, const QPoint &pos)
dst_rect.width = size.width();
dst_rect.height = size.height();
- VC_RECT_T src_rect;
- src_rect.x = 0;
- src_rect.y = 0;
- src_rect.width = size.width() << 16;
- src_rect.height = size.height() << 16;
-
DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0);
vc_dispmanx_element_change_attributes(dispman_update,
eglWindow->element,
diff --git a/mkspecs/devices/linux-tegra2-g++/qmake.conf b/mkspecs/devices/linux-tegra2-g++/qmake.conf
index 320e1b8a21..adadc4d5b0 100644
--- a/mkspecs/devices/linux-tegra2-g++/qmake.conf
+++ b/mkspecs/devices/linux-tegra2-g++/qmake.conf
@@ -6,9 +6,7 @@
# A typical configure line looks like this:
# <path-to-qt-src>/configure -opensource -confirm-license -make libs -prefix /usr/local/Qt-5.0.0/Qt5-tegra2
# -device tegra2 -device-option CROSS_COMPILE=<path-to-crosstoolchain>/bin/arm-none-linux-gnueabi- \
-# -sysroot <path-to-rootfs> -no-neon
-
-# CAUTION: The Tegra2 chips don't support neon, make sure it will not be used (-no-neon)
+# -sysroot <path-to-rootfs>
include(../common/linux_device_pre.conf)
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index 39144e7216..fe41c541a2 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -53,6 +53,12 @@ defineTest(qtCompileTest) {
# Disable qmake features which are typically counterproductive for tests
qmake_configs = "\"CONFIG -= qt debug_and_release app_bundle lib_bundle\""
+ # On WinRT we need to change the entry point as we cannot create windows
+ # applications
+ winrt {
+ qmake_configs += " \"QMAKE_LFLAGS+=/ENTRY:main\""
+ }
+
# Clean up after previous run
exists($$test_out_dir/Makefile):qtRunLoggedCommand("$$test_cmd_base $$QMAKE_MAKE distclean")
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index 19b26460a0..82e2812f3b 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -195,7 +195,7 @@ mac {
CMAKE_LIB_FILE_LOCATION_DEBUG = $${CMAKE_QT_STEM}d.dll
CMAKE_LIB_FILE_LOCATION_RELEASE = $${CMAKE_QT_STEM}.dll
- win32-g++ {
+ mingw {
CMAKE_WINMAIN_FILE_LOCATION_DEBUG = libqtmain$${QT_LIBINFIX}d.a
CMAKE_WINMAIN_FILE_LOCATION_RELEASE = libqtmain$${QT_LIBINFIX}.a
diff --git a/mkspecs/features/ctest_testcase_common.prf b/mkspecs/features/ctest_testcase_common.prf
index a9461eb4ae..a2b7e8e72b 100644
--- a/mkspecs/features/ctest_testcase_common.prf
+++ b/mkspecs/features/ctest_testcase_common.prf
@@ -51,7 +51,7 @@ load(cmake_functions)
CMAKE_BUILD_TYPE = Debug
CONFIG(release, debug|release):CMAKE_BUILD_TYPE = Release
-win32-g++*:isEmpty(CROSS_COMPILE):CMAKE_GENERATOR = -G \"MinGW Makefiles\"
+mingw:isEmpty(CROSS_COMPILE):CMAKE_GENERATOR = -G \"MinGW Makefiles\"
win32:equals(QT_ARCH, x86_64) {
win32-msvc2010:CMAKE_GENERATOR = -G \"Visual Studio 10 Win64\"
win32-msvc2012:CMAKE_GENERATOR = -G \"Visual Studio 11 Win64\"
diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf
index ee0fdfef48..dd2923f9be 100644
--- a/mkspecs/features/default_post.prf
+++ b/mkspecs/features/default_post.prf
@@ -82,5 +82,7 @@ breakpad {
!isEmpty(QMAKE_STRIP):QMAKE_POST_LINK = $$QMAKE_POST_LINK$$escape_expand(\\n\\t)$$quote($$QMAKE_STRIP $$DEBUGFILENAME)
}
+!precompile_header: SOURCES += $$NO_PCH_SOURCES
+
QMAKE_INCDIR += $$QMAKE_INCDIR_POST
QMAKE_LIBDIR += $$QMAKE_LIBDIR_POST
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index c3addf9319..da3e22b5f3 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -15,8 +15,26 @@ qt:!isEmpty(QT_CONFIG) {
contains(QT_CONFIG, x86_64):!contains(QT_CONFIG, x86):CONFIG += x86_64
}
- # Ensure that C++11 is always used when linking against a static Qt build
- contains(QT_CONFIG, static):contains(QT_CONFIG, c++11): CONFIG += c++11
+ contains(QT_CONFIG, static) {
+ # C++11 support means using libc++ instead of libstd++. As the
+ # two libraries are incompatible we need to ensure the end user
+ # project is built using the same C++11 support/no support as Qt.
+ contains(QT_CONFIG, c++11) {
+ CONFIG += c++11
+ } else: c++11 {
+ warning("Qt was not built with C++11 enabled, disabling feature")
+ CONFIG -= c++11
+ }
+
+ !c++11 {
+ # Explicitly use libstdc++ if C++11 support is not enabled,
+ # as otherwise the compiler will choose the standard library
+ # based on the deployment target, which for iOS 7 and OS X 10.9
+ # is libc++, and we can't mix and match the two.
+ QMAKE_CXXFLAGS += -stdlib=libstdc++
+ QMAKE_LFLAGS += -stdlib=libstdc++
+ }
+ }
}
cache(QMAKE_XCODE_DEVELOPER_PATH, stash)
diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf
index 59ac9db05b..c0b5682446 100644
--- a/mkspecs/features/moc.prf
+++ b/mkspecs/features/moc.prf
@@ -5,49 +5,36 @@ isEmpty(MOC_DIR):MOC_DIR = .
isEmpty(QMAKE_H_MOD_MOC):QMAKE_H_MOD_MOC = moc_
isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc
+MOC_INCLUDEPATH =
+for (inc, INCLUDEPATH): \
+ MOC_INCLUDEPATH += $$absolute_path($$inc, $$_PRO_FILE_PWD_)
+!no_include_pwd:!isEqual(OUT_PWD, $$_PRO_FILE_PWD_): \
+ MOC_INCLUDEPATH += .
+MOC_INCLUDEPATH = $$QMAKESPEC $$_PRO_FILE_PWD_ $$MOC_INCLUDEPATH $$QMAKE_DEFAULT_INCDIRS
+
# On Windows, put the includes into a .inc file which moc will read, if the project
# has too many includes. We do this to overcome a command-line limit on Win < XP
-INCLUDETEMP=
WIN_INCLUDETEMP=
-win32:count(INCLUDEPATH, 40, >) {
- INCLUDETEMP = $$MOC_DIR/mocinclude.tmp
-
- WIN_INCLUDETEMP=$$INCLUDETEMP
-
- EOC = $$escape_expand(\\n\\t)
+win32:count(MOC_INCLUDEPATH, 40, >) {
+ WIN_INCLUDETEMP = $$MOC_DIR/mocinclude.tmp
- contains(TEMPLATE, "vc.*") {
- # the VCPROJ generator will replace the \r\h with the coded \r\n: &#x0d;&#x0a;
- EOC = $$escape_expand(\\r\\h)
- }
-
- unset(INCFILELIST)
- RET =
- for(incfile, INCLUDEPATH) {
- INCFILELIST = -I$$incfile
- isEmpty(RET): RET += @echo $$INCFILELIST> $$WIN_INCLUDETEMP $$EOC
- else: RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC
- }
- !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC
-
- build_pass|isEmpty(BUILDS) {
- mocinclude.target = $$INCLUDETEMP
- mocinclude.commands = $$RET
- QMAKE_EXTRA_TARGETS += mocinclude
- }
+ WIN_INCLUDETEMP_CONT =
+ for (inc, MOC_INCLUDEPATH): \
+ WIN_INCLUDETEMP_CONT += -I$$inc
+ write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONT)|error("Aborting.")
}
defineReplace(mocCmdBase) {
RET =
!isEmpty(WIN_INCLUDETEMP) {
- contains(TEMPLATE, "vc.*") {
- RET += $$mocinclude.commands
- }
incvar = @$$WIN_INCLUDETEMP
} else {
- incvar = $(INCPATH)
+ incvar =
+ for (inc, MOC_INCLUDEPATH): \
+ incvar += -I$$shell_quote($$inc)
+ incvar += $$QMAKE_FRAMEWORKPATH_FLAGS
}
- RET += $$QMAKE_MOC $(DEFINES) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$incvar $$join(QMAKE_DEFAULT_INCDIRS, " -I", -I) $$QMAKE_MOC_OPTIONS
+ RET += $$QMAKE_MOC $(DEFINES) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$incvar $$QMAKE_MOC_OPTIONS
return($$RET)
}
@@ -59,9 +46,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK
moc_header.input = HEADERS
moc_header.variable_out = SOURCES
moc_header.name = MOC ${QMAKE_FILE_IN}
-!contains(TEMPLATE, "vc.*") {
- !isEmpty(INCLUDETEMP):moc_header.depends += $$INCLUDETEMP
-}
+moc_header.depends += $$WIN_INCLUDETEMP
silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands
QMAKE_EXTRA_COMPILERS += moc_header
INCREDIBUILD_XGE += moc_header
@@ -73,9 +58,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_
moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC}
moc_source.input = SOURCES OBJECTIVE_SOURCES
moc_source.name = MOC ${QMAKE_FILE_IN}
-!contains(TEMPLATE, "vc.*") {
- !isEmpty(INCLUDETEMP):moc_source.depends += $$INCLUDETEMP
-}
+moc_source.depends += $$WIN_INCLUDETEMP
silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands
QMAKE_EXTRA_COMPILERS += moc_source
INCREDIBUILD_XGE += moc_source
diff --git a/mkspecs/features/precompile_header.prf b/mkspecs/features/precompile_header.prf
new file mode 100644
index 0000000000..9b233dd872
--- /dev/null
+++ b/mkspecs/features/precompile_header.prf
@@ -0,0 +1,24 @@
+#
+# W A R N I N G
+# -------------
+#
+# This file is not part of the Qt API. It exists purely as an
+# implementation detail. It may change from version to version
+# without notice, or even be removed.
+#
+# We mean it.
+#
+
+#
+# Set up extra compiler for PCH disabled sources
+#
+no_pch_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH) ${QMAKE_FILE_IN}
+msvc: no_pch_compiler.commands += -Fo${QMAKE_FILE_OUT}
+else: no_pch_compiler.commands += -o ${QMAKE_FILE_OUT}
+no_pch_compiler.dependency_type = TYPE_C
+no_pch_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
+no_pch_compiler.input = NO_PCH_SOURCES
+no_pch_compiler.variable_out = OBJECTS
+no_pch_compiler.name = compiling[no_pch] ${QMAKE_FILE_IN}
+silent: no_pch_compiler.commands = @echo compiling[no_pch] ${QMAKE_FILE_IN} && $$no_pch_compiler.commands
+QMAKE_EXTRA_COMPILERS += no_pch_compiler
diff --git a/mkspecs/features/qlalr.prf b/mkspecs/features/qlalr.prf
new file mode 100644
index 0000000000..e5e4b87802
--- /dev/null
+++ b/mkspecs/features/qlalr.prf
@@ -0,0 +1,49 @@
+qtPrepareTool(QMAKE_QLALR, qlalr)
+
+isEmpty(QLALR_DIR): QLALR_DIR = .
+
+!isEmpty(QLALRSOURCES) {
+ INCLUDEPATH += $$absolute_path($$QLALR_DIR, $$OUT_PWD)
+}
+
+for (s, QLALRSOURCES) {
+ sf = $$absolute_path($$s, $$_PRO_FILE_PWD_)
+ QMAKE_INTERNAL_INCLUDED_FILES += $$sf
+ sfl = $$cat($$sf, lines)
+ parser = $$lower($$member($$list($$find(sfl, "^%parser\\s")), 1))
+ isEmpty(parser): error("Could not extract %parser from $$sf")
+ decl = $$member($$list($$find(sfl, "^%decl\\s")), 1)
+ isEmpty(decl): error("Could not extract %decl from $$sf")
+ impl = $$member($$list($$find(sfl, "^%impl\\s")), 1)
+ isEmpty(impl): error("Could not extract %impl from $$sf")
+ base = qlalr_$$replace(sf, ^.*/([^./]+)[^/]*$, \\1)
+
+ invar = $$upper($$base)_SOURCES
+ $$invar = $$sf
+ $${base}.input = $$invar
+ $${base}.output = $$QLALR_DIR/$${parser}.cpp
+ $${base}.variable_out = GENERATED_SOURCES
+ $${base}.commands = $$QMAKE_QLALR $$QMAKE_QLALRFLAGS ${QMAKE_FILE_IN}
+ silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $${base}.commands
+ $${base}.name = QLALR ${QMAKE_FILE_IN}
+
+ $${base}_h.input = $$invar
+ $${base}_h.output = $$QLALR_DIR/$${parser}_p.h
+ $${base}_h.CONFIG = no_link
+ $${base}_h.depends = $$QLALR_DIR/$${parser}.cpp
+ $${base}_h.commands = $$escape_expand(\\n) # force creation of rule
+
+ $${base}_decl.input = $$invar
+ $${base}_decl.output = $$QLALR_DIR/$${decl}
+ $${base}_decl.CONFIG = no_link
+ $${base}_decl.depends = $$QLALR_DIR/$${parser}.cpp
+ $${base}_decl.commands = $$escape_expand(\\n) # force creation of rule
+
+ $${base}_impl.input = $$invar
+ $${base}_impl.output = $$QLALR_DIR/$${impl}
+ $${base}_impl.variable_out = GENERATED_SOURCES
+ $${base}_impl.depends = $$QLALR_DIR/$${parser}.cpp
+ $${base}_impl.commands = $$escape_expand(\\n) # force creation of rule
+
+ QMAKE_EXTRA_COMPILERS += $$base $${base}_h $${base}_decl $${base}_impl
+}
diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf
index af941058db..f3739572c7 100644
--- a/mkspecs/features/qml_plugin.prf
+++ b/mkspecs/features/qml_plugin.prf
@@ -101,7 +101,7 @@ load(qt_common)
load(qml_module)
-unix|win32-g++* {
+unix|mingw {
!isEmpty(_QMAKE_SUPER_CACHE_): \
lib_replace.match = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*/lib
else: \
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index 83a8778654..fb83e59e65 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -172,6 +172,8 @@ contains(QT_CONFIG, static) {
else: \
QTPLUGIN += $$QT_DEFAULT_QPA_PLUGIN
}
+ needs_printsupport_plugin: \
+ QTPLUGIN += $$QT_DEFAULT_PRINTSUPPORTPLUGIN
import_plugins:!isEmpty(QTPLUGIN) {
IMPORT_FILE_CONT = \
"// This file is autogenerated by qmake. It imports static plugin classes for" \
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf
index 22d66e8907..051420e4f1 100644
--- a/mkspecs/features/qt_common.prf
+++ b/mkspecs/features/qt_common.prf
@@ -27,11 +27,15 @@ warnings_are_errors:warning_clean {
# This setting is compiler-dependent anyway because it depends on the version of the
# compiler.
clang {
- # Apple clang 4.0-4.2
- # Regular clang is not tested
- ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
- contains(ver, "4\\.[012]") {
- QMAKE_CXXFLAGS += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR
+ # Apple clang 4.0-4.2,5.0
+ # Regular clang 3.3 & 3.4
+ apple_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
+ reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
+ contains(apple_ver, "4\\.[012]|5\\.0")|contains(reg_ver, "3\\.[34]") {
+ QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR
+
+ # glibc's bswap_XX macros use the "register" keyword
+ linux:equals(reg_ver, "3.4"): QMAKE_CXXFLAGS_WARN_ON += -Wno-error=deprecated-register
}
} else:intel_icc:linux {
# Intel CC 13.0 - 14.0, on Linux only
@@ -43,20 +47,20 @@ warnings_are_errors:warning_clean {
# 1478: function "entity" (declared at line N) was declared deprecated
# 1881: argument must be a constant null pointer value
# (NULL in C++ is usually a literal 0)
- QMAKE_CXXFLAGS += -Werror -ww177,1224,1478,1881 $$WERROR
+ QMAKE_CXXFLAGS_WARN_ON += -Werror -ww177,1224,1478,1881 $$WERROR
}
} else:gcc:!clang:!intel_icc {
# GCC 4.6-4.8
ver = $${QT_GCC_MAJOR_VERSION}.$${QT_GCC_MINOR_VERSION}
contains(ver, "4\\.[678]") {
- QMAKE_CXXFLAGS += -Werror -Wno-error=cpp -Wno-error=deprecated-declarations $$WERROR
+ QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=cpp -Wno-error=deprecated-declarations $$WERROR
# GCC prints this bogus warning, after it has inlined a lot of code
# error: assuming signed overflow does not occur when assuming that (X + c) < X is always false
- QMAKE_CXXFLAGS += -Wno-error=strict-overflow
+ QMAKE_CXXFLAGS_WARN_ON += -Wno-error=strict-overflow
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
- android: QMAKE_CXXFLAGS += -Wno-error=literal-suffix
+ android: QMAKE_CXXFLAGS_WARN_ON += -Wno-error=literal-suffix
}
}
unset(ver)
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index c6369732c1..2134077ed3 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -134,6 +134,33 @@ aix-g++* {
QMAKE_CXXFLAGS += -mminimal-toc
}
+sse2:!contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):!host_build:!if(static:contains(QT_CONFIG, shared)) {
+ # If the compiler supports SSE2, enable it unconditionally in all of Qt shared libraries
+ # (and only the libraries). This is not expected to be a problem because:
+ # - on Windows, sharing of libraries is uncommon
+ # - on Mac OS X, all x86 CPUs already have SSE2 support (we won't even reach here)
+ # - on Linux, the dynamic loader can find the libraries on LIBDIR/sse2/
+ # The last guarantee does not apply to executables and plugins, so we can't enable for them.
+ QT_CPU_FEATURES.$$QT_ARCH += sse sse2
+ QMAKE_CFLAGS += $$QMAKE_CFLAGS_SSE2
+ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
+}
+
+clang {
+ apple_clang_ver = $${QT_APPLE_CLANG_MAJOR_VERSION}.$${QT_APPLE_CLANG_MINOR_VERSION}
+ reg_clang_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION}
+ !lessThan(apple_clang_ver, "5.1")|!lessThan(reg_clang_ver, "3.4"): \
+ CONFIG += compiler_supports_fpmath
+} else: gcc {
+ CONFIG += compiler_supports_fpmath
+}
+
+equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_supports_fpmath {
+ # Turn on SSE-based floating-point math
+ QMAKE_CFLAGS += -mfpmath=sse
+ QMAKE_CXXFLAGS += -mfpmath=sse
+}
+
android: CONFIG += qt_android_deps
#install directives
@@ -154,7 +181,7 @@ else: \
lib_replace.CONFIG = path
QMAKE_PRL_INSTALL_REPLACE += include_replace lib_replace
-unix|win32-g++* {
+unix|mingw {
CONFIG += create_pc
QMAKE_PKGCONFIG_LIBDIR = $$lib_replace.replace
QMAKE_PKGCONFIG_INCDIR = $$include_replace.replace
@@ -169,7 +196,7 @@ unix {
QMAKE_LIBTOOL_INSTALL_REPLACE += include_replace lib_replace
}
-unix|win32-g++* {
+unix|mingw {
QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$section(VERSION, ., 0, 0) ")
QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$section(VERSION, ., 0, 0))
for(i, MODULE_DEPENDS): \
diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf
index ed028d59d3..fee711aeb8 100644
--- a/mkspecs/features/qt_parts.prf
+++ b/mkspecs/features/qt_parts.prf
@@ -60,7 +60,7 @@ exists($$_PRO_FILE_PWD_/tests/tests.pro) {
sub_tests.CONFIG = no_default_install
!contains(QT_BUILD_PARTS, tests) {
sub_tests.CONFIG += no_default_target
- } else {
+ } else: !ios {
# Make sure these are there in case we need them
sub_tools.CONFIG -= no_default_target
sub_examples.CONFIG -= no_default_target
diff --git a/mkspecs/features/qt_plugin.prf b/mkspecs/features/qt_plugin.prf
index c9fe22688b..f710bbff43 100644
--- a/mkspecs/features/qt_plugin.prf
+++ b/mkspecs/features/qt_plugin.prf
@@ -55,7 +55,7 @@ load(qt_common)
wince*:LIBS += $$QMAKE_LIBS_GUI
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
-unix|win32-g++* {
+unix|mingw {
!isEmpty(_QMAKE_SUPER_CACHE_): \
rplbase = $$dirname(_QMAKE_SUPER_CACHE_)/[^/][^/]*
else: \
diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf
index ad8c545819..84a5d16d77 100644
--- a/mkspecs/features/simd.prf
+++ b/mkspecs/features/simd.prf
@@ -18,7 +18,7 @@ QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
#
# Set up compilers for SIMD (SSE/AVX, NEON etc)
#
-*-g++*|linux-icc*|*-clang*|*-qcc* {
+*-g++*|intel_icc|*-clang*|*-qcc* {
sse2 {
HEADERS += $$SSE2_HEADERS
@@ -289,7 +289,7 @@ QT_CPU_FEATURES = $$eval(QT_CPU_FEATURES.$$QT_ARCH)
avx2 {
HEADERS += $$AVX2_HEADERS
- avx2_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) -D_M_AVX2
+ avx2_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS)
!contains(QT_CPU_FEATURES, avx):avx2_compiler.commands += $$QMAKE_CFLAGS_AVX2
avx2_compiler.commands += $(INCPATH) ${QMAKE_FILE_IN} -Fo${QMAKE_FILE_OUT}
avx2_compiler.dependency_type = TYPE_C
diff --git a/mkspecs/features/win32/windeployqt.prf b/mkspecs/features/win32/windeployqt.prf
new file mode 100644
index 0000000000..f49df47ffe
--- /dev/null
+++ b/mkspecs/features/win32/windeployqt.prf
@@ -0,0 +1,19 @@
+# Extra target for running windeployqt
+qtPrepareTool(QMAKE_WINDEPLOYQT, windeployqt)
+build_pass {
+ load(resolve_target)
+
+ isEmpty(WINDEPLOYQT_OPTIONS): WINDEPLOYQT_OPTIONS = -qmldir $$shell_quote($$shell_path($$_PRO_FILE_PWD_))
+ WINDEPLOYQT_TARGET = $$shell_quote($$shell_path($$QMAKE_RESOLVED_TARGET))
+ WINDEPLOYQT_OUTPUT = $$shell_quote($$shell_path($$dirname(QMAKE_RESOLVED_TARGET)/$$basename(TARGET).windeployqt))
+ windeployqt.target = windeployqt
+ windeployqt.commands = $$QMAKE_WINDEPLOYQT $$WINDEPLOYQT_OPTIONS -list target $$WINDEPLOYQT_TARGET > $$WINDEPLOYQT_OUTPUT
+
+ windeployqt_clean.commands = if exist $$WINDEPLOYQT_OUTPUT for /f %i in ($$WINDEPLOYQT_OUTPUT) do $$QMAKE_DEL_FILE %~fi && $$QMAKE_DEL_DIR %~pi
+ QMAKE_EXTRA_TARGETS += windeployqt_clean
+ DISTCLEAN_DEPS += windeployqt_clean
+ QMAKE_DISTCLEAN += $$WINDEPLOYQT_OUTPUT
+} else {
+ windeployqt.CONFIG += recursive
+}
+QMAKE_EXTRA_TARGETS += windeployqt
diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf
index d0b59e05e0..82e0ebe1b5 100644
--- a/mkspecs/features/win32/windows.prf
+++ b/mkspecs/features/win32/windows.prf
@@ -1,7 +1,7 @@
CONFIG -= console
contains(TEMPLATE, ".*app"){
QMAKE_LFLAGS += $$QMAKE_LFLAGS_WINDOWS $$QMAKE_LFLAGS_EXE
- win32-g++:DEFINES += QT_NEEDS_QMAIN
+ mingw:DEFINES += QT_NEEDS_QMAIN
qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) {
isEqual(entryLib, -lqtmain): {
diff --git a/mkspecs/features/winrt/console.prf b/mkspecs/features/winrt/console.prf
new file mode 100644
index 0000000000..c4afe5b96e
--- /dev/null
+++ b/mkspecs/features/winrt/console.prf
@@ -0,0 +1,5 @@
+# This is an empty prf file to overwrite the win32 version.
+# On Windows RT all applications need to be windows applications
+# and also link to winmain. Inside winmain we create the launch
+# arguments and also initialize the UI.
+
diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf
new file mode 100644
index 0000000000..969a6780ce
--- /dev/null
+++ b/mkspecs/features/winrt/package_manifest.prf
@@ -0,0 +1,121 @@
+# This performs basic variable replacement on the contents of the WinRT manifest template, as
+# specified by WINRT_MANIFEST. The resulting manifest file is written to the output directory.
+# While the most common options are covered by the default template, the developer is expected
+# to make an application-level copy of the template in order to customize the manifest further.
+# Afterwards, they can override the default template by assigning their template to WINRT_MANIFEST.
+#
+# All subkeys in WINRT_MANIFEST will be replaced if defined/found, so new variables can be easily
+# added. The following keys have default values and are present in the default templates:
+# WINRT_MANIFEST: The name of the input manifest file. Defaults to a file defined by the mkspec.
+# WINRT_MANIFEST.target: The name of the target (.exe). Defaults to TARGET.
+# WINRT_MANIFEST.identity: The unique ID of the app. Defaults to reusing the existing generated manifest's UUID, or generates a new UUID if none is present.
+# WINRT_MANIFEST.name: The name of the package as displayed to the user. Defaults to TARGET.
+# WINRT_MANIFEST.architecture: The target architecture. Defaults to VCPROJ_ARCH.
+# WINRT_MANIFEST.version: The version number of the package. Defaults to "1.0.0.0".
+# WINRT_MANIFEST.arguments: Allows arguments to be passed to the executable.
+# WINRT_MANIFEST.publisher: Display name of the publisher. Defaults to "Default publisher display name".
+# WINRT_MANIFEST.publisher_id: On Windows 8/RT, the publisher's distinguished name (default: CN=MyCN). On Windows Phone, the publisher's UUID (default: invalid UUID string).
+# WINRT_MANIFEST.description: Package description. Defaults to "Default package description".
+# WINRT_MANIFEST.author: Package author (Windows Phone only). Defaults to "Default package author".
+# WINRT_MANIFEST.genre: Package genre (Windows Phone only). Defaults to "apps.normal".
+# WINRT_MANIFEST.background: Tile background color. Defaults to "green".
+# WINRT_MANIFEST.foreground: Tile foreground (text) color (Windows 8/RT only). Defaults to "light".
+# WINRT_MANIFEST.logo_store: Logo image file for Windows Store. Default provided by the mkspec.
+# WINRT_MANIFEST.logo_small: Small logo image file. Default provided by the mkspec.
+# WINRT_MANIFEST.logo_medium: Medium logo image file. Default provided by the mkspec.
+# WINRT_MANIFEST.logo_large: Large logo image file. Default provided by the mkspec.
+# WINRT_MANIFEST.splash_screen: Splash screen image file. Default provided by the mkspec.
+# WINRT_MANIFEST.iconic_tile_icon: Image file for the "iconic" tile template icon. Default provided by the mkspec.
+# WINRT_MANIFEST.iconic_tile_small: Image file for the small "iconic" tile template logo. Default provided by the mkspec.
+# WINRT_MANIFEST.capabilities: Specifies capabilities to add to the capability list.
+# WINRT_MANIFEST.dependencies: Specifies dependencies required by the package.
+
+# The manifest is generated for each build pass for normal apps, and only once for vcapps.
+# - Normal apps have their package root directory in the same place as the target (one for each build pass).
+# - Visual Studio requires a design-mode manifest in the same location as the vcproj.
+!isEmpty(WINRT_MANIFEST): \
+ if(build_pass:equals(TEMPLATE, "app"))| \
+ if(!build_pass:equals(TEMPLATE, "vcapp")) {
+
+ manifest_file.input = $$WINRT_MANIFEST
+
+ load(resolve_target)
+ BUILD_DIR = $$dirname(QMAKE_RESOLVED_TARGET)
+ winphone: \
+ manifest_file.output = $$BUILD_DIR/WMAppManifest.xml
+ else: contains(TEMPLATE, "vc.*"): \
+ manifest_file.output = $$BUILD_DIR/Package.appxmanifest
+ else: \
+ manifest_file.output = $$BUILD_DIR/AppxManifest.xml
+
+ # Provide the C-runtime dependency
+ equals(TEMPLATE, "app") {
+ VCLIBS = Microsoft.VCLibs.$$replace(MSVC_VER, \\., ).00
+ CONFIG(debug, debug|release): \
+ WINRT_MANIFEST.dependencies += $${VCLIBS}.Debug
+ else: \
+ WINRT_MANIFEST.dependencies += $$VCLIBS
+ }
+
+ # Provide default values for required variables
+ isEmpty(WINRT_MANIFEST.target): WINRT_MANIFEST.target = $$TARGET
+ isEmpty(WINRT_MANIFEST.identity) {
+ # Reuse the existing UUID if possible
+ UUID_CACHE = $$OUT_PWD/.qmake.winrt_uuid_$$TARGET
+ exists($$UUID_CACHE) {
+ include($$UUID_CACHE)
+ } else {
+ WINRT_UUID = "WINRT_MANIFEST.identity = $$system(uuidgen)"
+ write_file($$UUID_CACHE, WINRT_UUID)|error("Unable to write the UUID cache; aborting.")
+ eval($$WINRT_UUID)
+ }
+ winphone: WINRT_MANIFEST.identity = {$$WINRT_MANIFEST.identity}
+ }
+ isEmpty(WINRT_MANIFEST.name): WINRT_MANIFEST.name = $$TARGET
+ isEmpty(WINRT_MANIFEST.architecture): WINRT_MANIFEST.architecture = $$VCPROJ_ARCH
+ isEmpty(WINRT_MANIFEST.version): WINRT_MANIFEST.version = 1.0.0.0
+ isEmpty(WINRT_MANIFEST.publisher): WINRT_MANIFEST.publisher = Default publisher display name
+ isEmpty(WINRT_MANIFEST.publisherid) {
+ winphone: WINRT_MANIFEST.publisherid = {00000000-0000-0000-0000-000000000000}
+ else: WINRT_MANIFEST.publisherid = CN=$$(USERNAME)
+ }
+ isEmpty(WINRT_MANIFEST.description): WINRT_MANIFEST.description = Default package description
+ isEmpty(WINRT_MANIFEST.author): WINRT_MANIFEST.author = Default package author
+ isEmpty(WINRT_MANIFEST.genre): WINRT_MANIFEST.genre = apps.normal
+ isEmpty(WINRT_MANIFEST.background): WINRT_MANIFEST.background = green
+ isEmpty(WINRT_MANIFEST.foreground): WINRT_MANIFEST.foreground = light
+
+ winphone: INDENT = "$$escape_expand(\\r\\n) "
+ else: INDENT = "$$escape_expand(\\r\\n) "
+ # Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
+ WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities)
+ for(CAPABILITY, WINRT_MANIFEST.capabilities): \
+ MANIFEST_CAPABILITIES += " <Capability Name=\"$$CAPABILITY\" />"
+ WINRT_MANIFEST.capabilities = $$join(MANIFEST_CAPABILITIES, $$INDENT, $$INDENT, $$INDENT)
+ # Dependencies are given as a string list. The CRT dependency is added automatically above.
+ WINRT_MANIFEST.dependencies = $$unique(WINRT_MANIFEST.dependencies)
+ for(DEPENDENCY, WINRT_MANIFEST.dependencies): \
+ MANIFEST_DEPENDENCIES += " <PackageDependency Name=\"$$DEPENDENCY\" />"
+ WINRT_MANIFEST.dependencies = $$join(MANIFEST_DEPENDENCIES, $$INDENT, $$INDENT, $$INDENT)
+
+ # Provide default icons where needed
+ isEmpty(WINRT_ASSETS_PATH): WINRT_ASSETS_PATH = $$[QT_HOST_DATA/get]/mkspecs/common/winrt_winphone/assets
+ TEMPLATE_CONTENTS = $$cat($$WINRT_MANIFEST, lines)
+ ICONS_FOUND = $$find(TEMPLATE_CONTENTS, \\\$\\\$\\{WINRT_MANIFEST\\.(logo|tile)_)
+ ICONS_FOUND ~= s/.*\\\$\\\$\\{WINRT_MANIFEST\\.((logo|tile)_[^\}]+)\\}.*/\\1/g
+ for (ICON_NAME, ICONS_FOUND) {
+ ICON_FILE = $$eval(WINRT_MANIFEST.$$ICON_NAME)
+ isEmpty(ICON_FILE) {
+ icon_$${ICON_NAME}.input = $$WINRT_ASSETS_PATH/$${ICON_NAME}.png
+ icon_$${ICON_NAME}.output = $$BUILD_DIR/assets/$${ICON_NAME}.png
+ WINRT_MANIFEST.$${ICON_NAME} = assets/$${ICON_NAME}.png
+ } else {
+ icon_$${ICON_NAME}.input = $$ICON_FILE
+ icon_$${ICON_NAME}.output = $$BUILD_DIR/$$ICON_FILE
+ }
+ icon_$${ICON_NAME}.CONFIG = verbatim
+ QMAKE_SUBSTITUTES += icon_$${ICON_NAME}
+ }
+
+ QMAKE_SUBSTITUTES += manifest_file
+}
diff --git a/mkspecs/freebsd-g++/qplatformdefs.h b/mkspecs/freebsd-g++/qplatformdefs.h
index 329c46e8d6..358e93aaf9 100644
--- a/mkspecs/freebsd-g++/qplatformdefs.h
+++ b/mkspecs/freebsd-g++/qplatformdefs.h
@@ -82,7 +82,7 @@
#define QT_OPEN_LARGEFILE 0
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/hurd-g++/qplatformdefs.h b/mkspecs/hurd-g++/qplatformdefs.h
index 8b47450abe..a6642eb83a 100644
--- a/mkspecs/hurd-g++/qplatformdefs.h
+++ b/mkspecs/hurd-g++/qplatformdefs.h
@@ -85,8 +85,8 @@
#include "../common/posix/qplatformdefs.h"
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/irix-cc-64/qplatformdefs.h b/mkspecs/irix-cc-64/qplatformdefs.h
index 5d8a792950..7338595bc8 100644
--- a/mkspecs/irix-cc-64/qplatformdefs.h
+++ b/mkspecs/irix-cc-64/qplatformdefs.h
@@ -88,8 +88,8 @@
// Irix 6.5 and better
#if defined(_SGIAPI)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/irix-cc/qplatformdefs.h b/mkspecs/irix-cc/qplatformdefs.h
index 5d8a792950..7338595bc8 100644
--- a/mkspecs/irix-cc/qplatformdefs.h
+++ b/mkspecs/irix-cc/qplatformdefs.h
@@ -88,8 +88,8 @@
// Irix 6.5 and better
#if defined(_SGIAPI)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/irix-g++/qplatformdefs.h b/mkspecs/irix-g++/qplatformdefs.h
index 38d107e1e0..90c3349c21 100644
--- a/mkspecs/irix-g++/qplatformdefs.h
+++ b/mkspecs/irix-g++/qplatformdefs.h
@@ -95,8 +95,8 @@
// Irix 6.5 and better
#if defined(_SGIAPI)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-clang/qplatformdefs.h b/mkspecs/linux-clang/qplatformdefs.h
index bdf4d5056d..7366ca9bfa 100644
--- a/mkspecs/linux-clang/qplatformdefs.h
+++ b/mkspecs/linux-clang/qplatformdefs.h
@@ -87,14 +87,14 @@
#undef QT_SOCKLEN_T
#if defined(__GLIBC__) && (__GLIBC__ >= 2)
-#define QT_SOCKLEN_T socklen_t
+#define QT_SOCKLEN_T socklen_t
#else
-#define QT_SOCKLEN_T int
+#define QT_SOCKLEN_T int
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-cxx/qplatformdefs.h b/mkspecs/linux-cxx/qplatformdefs.h
index a948d169f0..ed36408e2e 100644
--- a/mkspecs/linux-cxx/qplatformdefs.h
+++ b/mkspecs/linux-cxx/qplatformdefs.h
@@ -94,8 +94,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-g++/qplatformdefs.h b/mkspecs/linux-g++/qplatformdefs.h
index 82d0e1663c..0e3e6077e3 100644
--- a/mkspecs/linux-g++/qplatformdefs.h
+++ b/mkspecs/linux-g++/qplatformdefs.h
@@ -93,8 +93,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf
index f9a04d2cce..1b71588b8c 100644
--- a/mkspecs/linux-icc/qmake.conf
+++ b/mkspecs/linux-icc/qmake.conf
@@ -21,6 +21,7 @@ QMAKE_CFLAGS_DEBUG = -O0 -g
QMAKE_CFLAGS_SHLIB = -fPIC -fno-jump-tables
QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CFLAGS_YACC =
+QMAKE_CFLAGS_ISYSTEM = -isystem
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_SSE2 += -xSSE2
diff --git a/mkspecs/linux-kcc/qplatformdefs.h b/mkspecs/linux-kcc/qplatformdefs.h
index a491e7ed6c..dbad004602 100644
--- a/mkspecs/linux-kcc/qplatformdefs.h
+++ b/mkspecs/linux-kcc/qplatformdefs.h
@@ -97,8 +97,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-llvm/qplatformdefs.h b/mkspecs/linux-llvm/qplatformdefs.h
index cbbe04e80c..6dae1a8ae5 100644
--- a/mkspecs/linux-llvm/qplatformdefs.h
+++ b/mkspecs/linux-llvm/qplatformdefs.h
@@ -94,8 +94,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-lsb-g++/qplatformdefs.h b/mkspecs/linux-lsb-g++/qplatformdefs.h
index 5060e1a222..a4855bcde5 100644
--- a/mkspecs/linux-lsb-g++/qplatformdefs.h
+++ b/mkspecs/linux-lsb-g++/qplatformdefs.h
@@ -105,8 +105,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/linux-pgcc/qplatformdefs.h b/mkspecs/linux-pgcc/qplatformdefs.h
index a948d169f0..ed36408e2e 100644
--- a/mkspecs/linux-pgcc/qplatformdefs.h
+++ b/mkspecs/linux-pgcc/qplatformdefs.h
@@ -94,8 +94,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/lynxos-g++/qplatformdefs.h b/mkspecs/lynxos-g++/qplatformdefs.h
index 469d032299..314c61443f 100644
--- a/mkspecs/lynxos-g++/qplatformdefs.h
+++ b/mkspecs/lynxos-g++/qplatformdefs.h
@@ -86,8 +86,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf
index 69f0b4cc0c..0bbb1be4ee 100644
--- a/mkspecs/macx-icc/qmake.conf
+++ b/mkspecs/macx-icc/qmake.conf
@@ -1,15 +1,7 @@
#
# qmake configuration for macx-icc
#
-# Written for Intel C++ Compiler versions 8.x and 9.x for OS X
-#
-# Note: Some of the remarks from the Intel compiler are disabled (even
-# with 'warn_on' specified):
-#
-# remark #858: type qualifier on return type is meaningless
-# warning #1572: floating-point equality and inequality comparisons are unreliable
-# warning #279: controlling expression is constant
-# warning #1569: potential redeclared typedef
+# Written for Intel C++ Compiler version 14.0 for OS X
#
MAKEFILE_GENERATOR = UNIX
@@ -17,21 +9,29 @@ CONFIG += app_bundle
QMAKE_INCREMENTAL_STYLE = sublibs
QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__
-QMAKE_COMPILER = gcc intel_icc # icc pretends to be gcc
+QMAKE_COMPILER = gcc clang intel_icc # icc pretends to be gcc and clang
QMAKE_CC = icc
-QMAKE_CFLAGS = -wd858,1572,1569,279
+QMAKE_CFLAGS =
QMAKE_CFLAGS_DEPS = -M
-QMAKE_CFLAGS_WARN_ON =
+QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE =
QMAKE_CFLAGS_DEBUG = -g
-QMAKE_CFLAGS_SHLIB = -fpic
+QMAKE_CFLAGS_SHLIB = -fPIC -fno-jump-tables
QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD =
-QMAKE_OBJECTIVE_CC = gcc
+QMAKE_CFLAGS_SSE2 += -xSSE2
+QMAKE_CFLAGS_SSE3 += -xSSE3
+QMAKE_CFLAGS_SSSE3 += -xSSSE3
+QMAKE_CFLAGS_SSE4_1 += -xSSE4.1
+QMAKE_CFLAGS_SSE4_2 += -xSSE4.2
+QMAKE_CFLAGS_AVX += -xAVX
+QMAKE_CFLAGS_AVX2 += -xCORE-AVX2
+
+QMAKE_OBJECTIVE_CC = clang
QMAKE_OBJECTIVE_CFLAGS = -pipe
QMAKE_OBJECTIVE_CFLAGS_WARN_ON = -Wall -W
QMAKE_OBJECTIVE_CFLAGS_WARN_OFF = -w
@@ -50,13 +50,14 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_LINK = icpc
QMAKE_LINK_SHLIB = icpc
QMAKE_LFLAGS = -headerpad_max_install_names
QMAKE_LFLAGS_RELEASE =
QMAKE_LFLAGS_DEBUG =
-QMAKE_LFLAGS_SHLIB = -ingle_module -dynamiclib
+QMAKE_LFLAGS_SHLIB = -single_module -dynamiclib
QMAKE_LFLAGS_INCREMENTAL = -undefined suppress -flat_namespace
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}
@@ -68,6 +69,18 @@ QMAKE_LFLAGS_COMPAT_VERSION = -compatibility_version$${LITERAL_WHITESPACE}
QMAKE_CLEAN = -r $(OBJECTS_DIR)/ti_files
+# pch support
+CONFIG += icc_pch_style
+QMAKE_PCH_OUTPUT_EXT = .pchi
+QMAKE_CXXFLAGS_USE_PRECOMPILE = -pch-use ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT}
+QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_TEMP_OBJECT} ${QMAKE_PCH_TEMP_SOURCE}
+
+# Symbol visibility control
+QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
+QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
+
+QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6
+
include(../common/macx.conf)
load(qt_config)
diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf
index 3428823624..28ad095da7 100644
--- a/mkspecs/macx-ios-clang/features/default_post.prf
+++ b/mkspecs/macx-ios-clang/features/default_post.prf
@@ -7,6 +7,9 @@ contains(QMAKE_MAC_SDK, ^iphonesimulator.*) {
CONFIG += iphonesimulator
}
+iphonesimulator_and_iphoneos:iphonesimulator: \
+ QMAKE_MAC_SDK ~= s,^iphoneos,iphonesimulator,
+
# Resolve config so we don't need to use CONFIG() later on
CONFIG(iphonesimulator, iphonesimulator|iphoneos) {
CONFIG -= iphoneos
@@ -118,15 +121,6 @@ equals(TEMPLATE, app) {
iphonesimulator.name = Simulator
iphoneos.name = Device
addExclusiveBuilds(iphonesimulator, iphoneos)
-
- iphonesimulator_and_iphoneos:iphonesimulator {
- QT_ARCH = i386
- QMAKE_MAC_SDK ~= s,^iphoneos,iphonesimulator,
-
- # Since the CPU feature detection done by configure is limited to one
- # target at the moment, we disable SIMD support for simulator.
- CONFIG -= simd
- }
} else: equals(TEMPLATE, subdirs) {
# Prevent recursion into host_builds
for(subdir, SUBDIRS) {
@@ -184,15 +178,6 @@ macx-xcode {
launch_images.files = $$copy_image.output
QMAKE_BUNDLE_DATA += launch_images
- !c++11 {
- # Explicitly use libstdc++ if C++11 support is not enabled,
- # as otherwise Xcode will choose the compiler default based
- # on the deployment target, which for iOS 7 is libc++. This
- # breaks compilation since Qt was built against libstdc++.
- QMAKE_CXXFLAGS += -stdlib=libstdc++
- QMAKE_LFLAGS += -stdlib=libstdc++
- }
-
# Make the default debug information format for debug builds
# DWARF instead of DWARF with dSYM. This cuts down build times
# for application debug builds significantly, as Xcode doesn't
diff --git a/mkspecs/macx-ios-clang/features/default_pre.prf b/mkspecs/macx-ios-clang/features/default_pre.prf
index 3501f5eae0..7b8f9c9b5d 100644
--- a/mkspecs/macx-ios-clang/features/default_pre.prf
+++ b/mkspecs/macx-ios-clang/features/default_pre.prf
@@ -8,3 +8,12 @@ load(default_pre)
# Check for supported Xcode versions
lessThan(QMAKE_XCODE_VERSION, "4.3"): \
error("This mkspec requires Xcode 4.3 or later")
+
+iphonesimulator_and_iphoneos:iphonesimulator {
+ # For a iphonesimulator_and_iphoneos build all the config tests
+ # are based on the iPhoneOS ARM SDK, but we know that the simulator
+ # is i386 and that we support SSE/SSE2.
+ QT_ARCH = i386
+ QT_CPU_FEATURES.i386 = sse sse2
+ DEFINES += QT_COMPILER_SUPPORTS_SSE2
+}
diff --git a/mkspecs/macx-ios-clang/features/qt_parts.prf b/mkspecs/macx-ios-clang/features/qt_parts.prf
new file mode 100644
index 0000000000..81814a62b0
--- /dev/null
+++ b/mkspecs/macx-ios-clang/features/qt_parts.prf
@@ -0,0 +1,5 @@
+
+# Disable tests for anything but qtbase for now
+!equals(TARGET, qtbase): QT_BUILD_PARTS -= tests
+
+load(qt_parts)
diff --git a/mkspecs/netbsd-g++/qplatformdefs.h b/mkspecs/netbsd-g++/qplatformdefs.h
index af7d0acf24..5388141931 100644
--- a/mkspecs/netbsd-g++/qplatformdefs.h
+++ b/mkspecs/netbsd-g++/qplatformdefs.h
@@ -84,8 +84,8 @@
// NetBSD 1.0 - 1.3.3 int
// NetBSD 1.4 - 1.5 socklen_t
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
// Older NetBSD versions may still use the a.out format instead of ELF.
#ifndef __ELF__
diff --git a/mkspecs/openbsd-g++/qplatformdefs.h b/mkspecs/openbsd-g++/qplatformdefs.h
index 9901bc632f..51844ee657 100644
--- a/mkspecs/openbsd-g++/qplatformdefs.h
+++ b/mkspecs/openbsd-g++/qplatformdefs.h
@@ -85,8 +85,8 @@
// OpenBSD 2.2 - 2.4 int
// OpenBSD 2.5 - 2.8 socklen_t
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
// 1003.1c-1995 says on page 38 (2.9.3, paragraph 3) that if _POSIX_THREADS
// is defined, then _POSIX_THREAD_SAFE_FUNCTIONS must also be defined.
diff --git a/mkspecs/qnx-armv7le-qcc/qplatformdefs.h b/mkspecs/qnx-armv7le-qcc/qplatformdefs.h
index 2fac2ae3d2..b47aecde0d 100644
--- a/mkspecs/qnx-armv7le-qcc/qplatformdefs.h
+++ b/mkspecs/qnx-armv7le-qcc/qplatformdefs.h
@@ -83,8 +83,15 @@
#include <arpa/inet.h>
#define QT_USE_XOPEN_LFS_EXTENSIONS
+#if !defined(__EXT_QNX__READDIR64_R)
#define QT_NO_READDIR64
+#endif
#include "../common/posix/qplatformdefs.h"
+#if defined(__EXT_QNX__READDIR64_R)
+#define QT_EXT_QNX_READDIR_R ::_readdir64_r
+#elif defined(__EXT_QNX__READDIR_R)
+#define QT_EXT_QNX_READDIR_R ::_readdir_r
+#endif
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
diff --git a/mkspecs/qnx-x86-qcc/qplatformdefs.h b/mkspecs/qnx-x86-qcc/qplatformdefs.h
index 2fac2ae3d2..b47aecde0d 100644
--- a/mkspecs/qnx-x86-qcc/qplatformdefs.h
+++ b/mkspecs/qnx-x86-qcc/qplatformdefs.h
@@ -83,8 +83,15 @@
#include <arpa/inet.h>
#define QT_USE_XOPEN_LFS_EXTENSIONS
+#if !defined(__EXT_QNX__READDIR64_R)
#define QT_NO_READDIR64
+#endif
#include "../common/posix/qplatformdefs.h"
+#if defined(__EXT_QNX__READDIR64_R)
+#define QT_EXT_QNX_READDIR_R ::_readdir64_r
+#elif defined(__EXT_QNX__READDIR_R)
+#define QT_EXT_QNX_READDIR_R ::_readdir_r
+#endif
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
diff --git a/mkspecs/sco-cc/qplatformdefs.h b/mkspecs/sco-cc/qplatformdefs.h
index a880f4579b..5d039f6b3b 100644
--- a/mkspecs/sco-cc/qplatformdefs.h
+++ b/mkspecs/sco-cc/qplatformdefs.h
@@ -81,7 +81,7 @@
#undef QT_SOCKLEN_T
#define QT_SOCKLEN_T size_t
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/sco-g++/qplatformdefs.h b/mkspecs/sco-g++/qplatformdefs.h
index f0e5eb8293..cff39e6d1a 100644
--- a/mkspecs/sco-g++/qplatformdefs.h
+++ b/mkspecs/sco-g++/qplatformdefs.h
@@ -85,7 +85,7 @@
#undef QT_SOCKLEN_T
#define QT_SOCKLEN_T int
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/solaris-cc-64/qplatformdefs.h b/mkspecs/solaris-cc-64/qplatformdefs.h
index acdc14c81b..a0560c0157 100644
--- a/mkspecs/solaris-cc-64/qplatformdefs.h
+++ b/mkspecs/solaris-cc-64/qplatformdefs.h
@@ -87,8 +87,8 @@ static inline int qt_socket_connect(int s, struct sockaddr *addr, QT_SOCKLEN_T a
{ return ::connect(s, addr, addrlen); }
// Only Solaris 7 and better support 64-bit
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#ifdef connect
#undef connect
diff --git a/mkspecs/solaris-cc/qplatformdefs.h b/mkspecs/solaris-cc/qplatformdefs.h
index f905ad55c3..0b72174c6f 100644
--- a/mkspecs/solaris-cc/qplatformdefs.h
+++ b/mkspecs/solaris-cc/qplatformdefs.h
@@ -113,8 +113,8 @@ extern "C" int gethostname(char *, int);
#if defined(_XOPEN_UNIX)
// Solaris 2.6 and better
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#ifdef connect
diff --git a/mkspecs/solaris-g++-64/qplatformdefs.h b/mkspecs/solaris-g++-64/qplatformdefs.h
index 4d408bf89e..11f25a5fc7 100644
--- a/mkspecs/solaris-g++-64/qplatformdefs.h
+++ b/mkspecs/solaris-g++-64/qplatformdefs.h
@@ -100,7 +100,7 @@ static inline int qt_socket_bind(int s, struct sockaddr *addr, QT_SOCKLEN_T addr
#endif
// Only Solaris 7 and better support 64-bit
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/solaris-g++/qplatformdefs.h b/mkspecs/solaris-g++/qplatformdefs.h
index 44ab7bbb53..a1cd5797fa 100644
--- a/mkspecs/solaris-g++/qplatformdefs.h
+++ b/mkspecs/solaris-g++/qplatformdefs.h
@@ -128,8 +128,8 @@ extern "C" int gethostname(char *, int);
#if defined(_XOPEN_UNIX)
// Solaris 2.6 and better
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/tru64-cxx/qplatformdefs.h b/mkspecs/tru64-cxx/qplatformdefs.h
index 0ff0aa83e7..71e9bb4ace 100644
--- a/mkspecs/tru64-cxx/qplatformdefs.h
+++ b/mkspecs/tru64-cxx/qplatformdefs.h
@@ -102,8 +102,8 @@ extern "C" int usleep(useconds_t);
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE-0 >= 400)
// Tru64 5.0 and better
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/tru64-g++/qplatformdefs.h b/mkspecs/tru64-g++/qplatformdefs.h
index 0ff0aa83e7..71e9bb4ace 100644
--- a/mkspecs/tru64-g++/qplatformdefs.h
+++ b/mkspecs/tru64-g++/qplatformdefs.h
@@ -102,8 +102,8 @@ extern "C" int usleep(useconds_t);
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE-0 >= 400)
// Tru64 5.0 and better
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unixware-cc/qplatformdefs.h b/mkspecs/unixware-cc/qplatformdefs.h
index 795e7cc98e..73e25a3b79 100644
--- a/mkspecs/unixware-cc/qplatformdefs.h
+++ b/mkspecs/unixware-cc/qplatformdefs.h
@@ -85,7 +85,7 @@
#define QT_OFF_T off_t
#define QT_SOCKLEN_T size_t
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unixware-g++/qplatformdefs.h b/mkspecs/unixware-g++/qplatformdefs.h
index 795e7cc98e..73e25a3b79 100644
--- a/mkspecs/unixware-g++/qplatformdefs.h
+++ b/mkspecs/unixware-g++/qplatformdefs.h
@@ -85,7 +85,7 @@
#define QT_OFF_T off_t
#define QT_SOCKLEN_T size_t
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/unsupported/freebsd-clang/qmake.conf
new file mode 100644
index 0000000000..0769983097
--- /dev/null
+++ b/mkspecs/unsupported/freebsd-clang/qmake.conf
@@ -0,0 +1,38 @@
+#
+# qmake configuration for freebsd-clang
+#
+
+MAKEFILE_GENERATOR = UNIX
+QMAKE_PLATFORM = freebsd bsd
+CONFIG += gdb_dwarf_index
+
+QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
+
+QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
+
+# Addon software goes into /usr/local on the BSDs, by default we will look there
+QMAKE_INCDIR = /usr/local/include
+QMAKE_LIBDIR = /usr/local/lib
+QMAKE_INCDIR_X11 = /usr/X11R6/include
+QMAKE_LIBDIR_X11 = /usr/X11R6/lib
+QMAKE_INCDIR_OPENGL = /usr/X11R6/include
+QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
+
+QMAKE_LFLAGS_THREAD = -pthread
+
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_X11 = -lXext -lX11 -lm
+QMAKE_LIBS_OPENGL = -lGL
+QMAKE_LIBS_THREAD =
+
+QMAKE_AR = ar cqs
+QMAKE_OBJCOPY = objcopy
+QMAKE_NM = nm -P
+QMAKE_RANLIB =
+
+include(../../common/unix.conf)
+include(../../common/gcc-base-unix.conf)
+include(../../common/g++-unix.conf)
+include(../../common/clang.conf)
+load(qt_config)
diff --git a/mkspecs/unsupported/freebsd-clang/qplatformdefs.h b/mkspecs/unsupported/freebsd-clang/qplatformdefs.h
new file mode 100644
index 0000000000..4743a28b99
--- /dev/null
+++ b/mkspecs/unsupported/freebsd-clang/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../freebsd-g++/qplatformdefs.h"
diff --git a/mkspecs/unsupported/integrity-ghs/qplatformdefs.h b/mkspecs/unsupported/integrity-ghs/qplatformdefs.h
index 75b2c59972..ab0c134138 100644
--- a/mkspecs/unsupported/integrity-ghs/qplatformdefs.h
+++ b/mkspecs/unsupported/integrity-ghs/qplatformdefs.h
@@ -110,37 +110,37 @@
#define QT_OFF_T long
#endif
-#define QT_STAT_REG S_IFREG
-#define QT_STAT_DIR S_IFDIR
-#define QT_STAT_MASK S_IFMT
-#define QT_STAT_LNK S_IFLNK
-#define QT_SOCKET_CONNECT ::connect
-#define QT_SOCKET_BIND ::bind
-#define QT_FILENO fileno
+#define QT_STAT_REG S_IFREG
+#define QT_STAT_DIR S_IFDIR
+#define QT_STAT_MASK S_IFMT
+#define QT_STAT_LNK S_IFLNK
+#define QT_SOCKET_CONNECT ::connect
+#define QT_SOCKET_BIND ::bind
+#define QT_FILENO fileno
#ifndef QT_CLOSE
-#define QT_CLOSE ::close
+#define QT_CLOSE ::close
#endif
#ifndef QT_READ
-#define QT_READ ::read
+#define QT_READ ::read
#endif
#ifndef QT_WRITE
-#define QT_WRITE ::write
+#define QT_WRITE ::write
#endif
-#define QT_ACCESS ::access
-#define QT_GETCWD ::getcwd
-#define QT_CHDIR ::chdir
-#define QT_MKDIR ::mkdir
-#define QT_RMDIR ::rmdir
-#define QT_OPEN_RDONLY O_RDONLY
-#define QT_OPEN_WRONLY O_WRONLY
-#define QT_OPEN_RDWR O_RDWR
-#define QT_OPEN_CREAT O_CREAT
-#define QT_OPEN_TRUNC O_TRUNC
-#define QT_OPEN_APPEND O_APPEND
-
-#define QT_SIGNAL_RETTYPE void
-#define QT_SIGNAL_ARGS int
-#define QT_SIGNAL_IGNORE SIG_IGN
+#define QT_ACCESS ::access
+#define QT_GETCWD ::getcwd
+#define QT_CHDIR ::chdir
+#define QT_MKDIR ::mkdir
+#define QT_RMDIR ::rmdir
+#define QT_OPEN_RDONLY O_RDONLY
+#define QT_OPEN_WRONLY O_WRONLY
+#define QT_OPEN_RDWR O_RDWR
+#define QT_OPEN_CREAT O_CREAT
+#define QT_OPEN_TRUNC O_TRUNC
+#define QT_OPEN_APPEND O_APPEND
+
+#define QT_SIGNAL_RETTYPE void
+#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_IGNORE SIG_IGN
#define QT_MMAP ::mmap
@@ -166,8 +166,8 @@
#define QT_SOCKLEN_T socklen_t
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
// INTEGRITY doesn't enable the declaration in _POSIX_SOURCE mode,
diff --git a/mkspecs/unsupported/linux-armcc/qplatformdefs.h b/mkspecs/unsupported/linux-armcc/qplatformdefs.h
index 2f023824ec..c1066ee9a2 100644
--- a/mkspecs/unsupported/linux-armcc/qplatformdefs.h
+++ b/mkspecs/unsupported/linux-armcc/qplatformdefs.h
@@ -93,8 +93,8 @@
#endif
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unsupported/linux-libc++-clang/qmake.conf b/mkspecs/unsupported/linux-libc++-clang/qmake.conf
new file mode 100644
index 0000000000..bf0abb2a54
--- /dev/null
+++ b/mkspecs/unsupported/linux-libc++-clang/qmake.conf
@@ -0,0 +1,20 @@
+#
+# qmake configuration for linux-clang
+#
+
+MAKEFILE_GENERATOR = UNIX
+CONFIG += incremental
+
+QMAKE_INCREMENTAL_STYLE = sublib
+
+include(../../common/linux.conf)
+include(../../common/gcc-base-unix.conf)
+include(../../common/clang.conf)
+
+QMAKE_CFLAGS_RELEASE = -Os
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+
+QMAKE_CXXFLAGS_CXX11 += -std=c++11 -stdlib=libc++
+QMAKE_LFLAGS_CXX11 += -stdlib=libc++ -lc++abi
+
+load(qt_config)
diff --git a/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h b/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h
new file mode 100644
index 0000000000..c1066ee9a2
--- /dev/null
+++ b/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+// Get Qt defines/settings
+
+#include "qglobal.h"
+
+// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
+
+// 1) need to reset default environment if _BSD_SOURCE is defined
+// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
+// 3) it seems older glibc need this to include the X/Open stuff
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <unistd.h>
+
+
+// We are hot - unistd.h should have turned on the specific APIs we requested
+
+#include <features.h>
+#include <pthread.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/time.h>
+#include <sys/shm.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+#define QT_USE_XOPEN_LFS_EXTENSIONS
+#include "../../common/posix/qplatformdefs.h"
+
+#undef QT_SOCKLEN_T
+
+#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+#define QT_SOCKLEN_T socklen_t
+#else
+#define QT_SOCKLEN_T int
+#endif
+
+#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
+#endif
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h b/mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h
index b75598f12f..9e902ebfcd 100644
--- a/mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h
+++ b/mkspecs/unsupported/qnx-X11-g++/qplatformdefs.h
@@ -84,8 +84,8 @@
#define QT_USE_XOPEN_LFS_EXTENSIONS
#include "../../common/posix/qplatformdefs.h"
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
// QNX6 doesn't have getpagesize()
inline int getpagesize()
diff --git a/mkspecs/unsupported/win32-msvc2003/qplatformdefs.h b/mkspecs/unsupported/win32-msvc2003/qplatformdefs.h
index da924e4631..21f9399f33 100644
--- a/mkspecs/unsupported/win32-msvc2003/qplatformdefs.h
+++ b/mkspecs/unsupported/win32-msvc2003/qplatformdefs.h
@@ -68,49 +68,49 @@
#define Q_FS_FAT
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_STATBUF struct _stati64 // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
-#define QT_STAT ::_stati64
-#define QT_FSTAT ::_fstati64
+#define QT_STATBUF struct _stati64 // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
+#define QT_STAT ::_stati64
+#define QT_FSTAT ::_fstati64
#else
-#define QT_STATBUF struct _stat // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
-#define QT_STAT ::_stat
-#define QT_FSTAT ::_fstat
+#define QT_STATBUF struct _stat // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
+#define QT_STAT ::_stat
+#define QT_FSTAT ::_fstat
#endif
-#define QT_STAT_REG _S_IFREG
-#define QT_STAT_DIR _S_IFDIR
-#define QT_STAT_MASK _S_IFMT
+#define QT_STAT_REG _S_IFREG
+#define QT_STAT_DIR _S_IFDIR
+#define QT_STAT_MASK _S_IFMT
#if defined(_S_IFLNK)
-# define QT_STAT_LNK _S_IFLNK
+# define QT_STAT_LNK _S_IFLNK
#endif
-#define QT_FILENO _fileno
-#define QT_OPEN ::_open
-#define QT_CLOSE ::_close
+#define QT_FILENO _fileno
+#define QT_OPEN ::_open
+#define QT_CLOSE ::_close
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_LSEEK ::_lseeki64
-#define QT_TSTAT ::_tstati64
+#define QT_LSEEK ::_lseeki64
+#define QT_TSTAT ::_tstati64
#else
-#define QT_LSEEK ::_lseek
-#define QT_TSTAT ::_tstat
+#define QT_LSEEK ::_lseek
+#define QT_TSTAT ::_tstat
#endif
-#define QT_READ ::_read
-#define QT_WRITE ::_write
-#define QT_ACCESS ::_access
-#define QT_GETCWD ::_getcwd
-#define QT_CHDIR ::_chdir
-#define QT_MKDIR ::_mkdir
-#define QT_RMDIR ::_rmdir
+#define QT_READ ::_read
+#define QT_WRITE ::_write
+#define QT_ACCESS ::_access
+#define QT_GETCWD ::_getcwd
+#define QT_CHDIR ::_chdir
+#define QT_MKDIR ::_mkdir
+#define QT_RMDIR ::_rmdir
#define QT_OPEN_LARGEFILE 0
-#define QT_OPEN_RDONLY _O_RDONLY
-#define QT_OPEN_WRONLY _O_WRONLY
-#define QT_OPEN_RDWR _O_RDWR
-#define QT_OPEN_CREAT _O_CREAT
-#define QT_OPEN_TRUNC _O_TRUNC
-#define QT_OPEN_APPEND _O_APPEND
+#define QT_OPEN_RDONLY _O_RDONLY
+#define QT_OPEN_WRONLY _O_WRONLY
+#define QT_OPEN_RDWR _O_RDWR
+#define QT_OPEN_CREAT _O_CREAT
+#define QT_OPEN_TRUNC _O_TRUNC
+#define QT_OPEN_APPEND _O_APPEND
#if defined(O_TEXT)
-# define QT_OPEN_TEXT _O_TEXT
-# define QT_OPEN_BINARY _O_BINARY
+# define QT_OPEN_TEXT _O_TEXT
+# define QT_OPEN_BINARY _O_BINARY
#endif
#include "../../common/c89/qplatformdefs.h"
@@ -125,15 +125,15 @@
#define QT_OFF_T __int64
#endif
-#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_ARGS int
#define QT_VSNPRINTF ::_vsnprintf
-#define QT_SNPRINTF ::_snprintf
+#define QT_SNPRINTF ::_snprintf
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
typedef int mode_t;
diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf
index d514b6d0d3..d739fd04a1 100644
--- a/mkspecs/win32-g++/qmake.conf
+++ b/mkspecs/win32-g++/qmake.conf
@@ -8,6 +8,7 @@
#
load(device_config)
+load(qt_config)
MAKEFILE_GENERATOR = MINGW
QMAKE_PLATFORM = win32 mingw
@@ -32,7 +33,7 @@ QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE = -O2
QMAKE_CFLAGS_DEBUG = -g
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
-QMAKE_CFLAGS_SSE2 = -msse2
+QMAKE_CFLAGS_SSE2 = -msse2 -mstackrealign
QMAKE_CFLAGS_SSE3 = -msse3
QMAKE_CFLAGS_SSSE3 = -mssse3
QMAKE_CFLAGS_SSE4_1 = -msse4.1
@@ -84,7 +85,7 @@ QMAKE_LIBS =
QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK = -lws2_32
-QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2 = -llibEGL -llibGLESv2 -lgdi32 -luser32
QMAKE_LIBS_OPENGL_ES2_DEBUG = -llibEGLd -llibGLESv2d -lgdi32 -luser32
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
@@ -110,4 +111,3 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
-load(qt_config)
diff --git a/mkspecs/win32-g++/qplatformdefs.h b/mkspecs/win32-g++/qplatformdefs.h
index 4f339cbea6..a5401075ab 100644
--- a/mkspecs/win32-g++/qplatformdefs.h
+++ b/mkspecs/win32-g++/qplatformdefs.h
@@ -79,57 +79,57 @@ typedef enum {
#endif
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_STATBUF struct _stati64 // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
-#define QT_STAT ::_stati64
-#define QT_FSTAT ::_fstati64
+#define QT_STATBUF struct _stati64 // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
+#define QT_STAT ::_stati64
+#define QT_FSTAT ::_fstati64
#else
-#define QT_STATBUF struct _stat // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
-#define QT_STAT ::_stat
-#define QT_FSTAT ::_fstat
+#define QT_STATBUF struct _stat // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
+#define QT_STAT ::_stat
+#define QT_FSTAT ::_fstat
#endif
-#define QT_STAT_REG _S_IFREG
-#define QT_STAT_DIR _S_IFDIR
-#define QT_STAT_MASK _S_IFMT
+#define QT_STAT_REG _S_IFREG
+#define QT_STAT_DIR _S_IFDIR
+#define QT_STAT_MASK _S_IFMT
#if defined(_S_IFLNK)
-# define QT_STAT_LNK _S_IFLNK
+# define QT_STAT_LNK _S_IFLNK
#endif
-#define QT_FILENO _fileno
-#define QT_OPEN ::_open
-#define QT_CLOSE ::_close
+#define QT_FILENO _fileno
+#define QT_OPEN ::_open
+#define QT_CLOSE ::_close
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_LSEEK ::_lseeki64
+#define QT_LSEEK ::_lseeki64
#ifndef UNICODE
-#define QT_TSTAT ::_stati64
+#define QT_TSTAT ::_stati64
#else
-#define QT_TSTAT ::_wstati64
+#define QT_TSTAT ::_wstati64
#endif
#else
-#define QT_LSEEK ::_lseek
+#define QT_LSEEK ::_lseek
#ifndef UNICODE
-#define QT_TSTAT ::_stat
+#define QT_TSTAT ::_stat
#else
-#define QT_TSTAT ::_wstat
+#define QT_TSTAT ::_wstat
#endif
#endif
-#define QT_READ ::_read
-#define QT_WRITE ::_write
-#define QT_ACCESS ::_access
-#define QT_GETCWD ::_getcwd
-#define QT_CHDIR ::_chdir
-#define QT_MKDIR ::_mkdir
-#define QT_RMDIR ::_rmdir
+#define QT_READ ::_read
+#define QT_WRITE ::_write
+#define QT_ACCESS ::_access
+#define QT_GETCWD ::_getcwd
+#define QT_CHDIR ::_chdir
+#define QT_MKDIR ::_mkdir
+#define QT_RMDIR ::_rmdir
#define QT_OPEN_LARGEFILE 0
-#define QT_OPEN_RDONLY _O_RDONLY
-#define QT_OPEN_WRONLY _O_WRONLY
-#define QT_OPEN_RDWR _O_RDWR
-#define QT_OPEN_CREAT _O_CREAT
-#define QT_OPEN_TRUNC _O_TRUNC
-#define QT_OPEN_APPEND _O_APPEND
+#define QT_OPEN_RDONLY _O_RDONLY
+#define QT_OPEN_WRONLY _O_WRONLY
+#define QT_OPEN_RDWR _O_RDWR
+#define QT_OPEN_CREAT _O_CREAT
+#define QT_OPEN_TRUNC _O_TRUNC
+#define QT_OPEN_APPEND _O_APPEND
#if defined(O_TEXT)
-# define QT_OPEN_TEXT _O_TEXT
-# define QT_OPEN_BINARY _O_BINARY
+# define QT_OPEN_TEXT _O_TEXT
+# define QT_OPEN_BINARY _O_BINARY
#endif
#include "../common/c89/qplatformdefs.h"
@@ -144,15 +144,15 @@ typedef enum {
#define QT_OFF_T off64_t
#endif
-#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_ARGS int
-#define QT_VSNPRINTF ::_vsnprintf
-#define QT_SNPRINTF ::_snprintf
+#define QT_VSNPRINTF ::_vsnprintf
+#define QT_SNPRINTF ::_snprintf
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf
index 1ee07c64b6..0c6290335e 100644
--- a/mkspecs/win32-icc/qmake.conf
+++ b/mkspecs/win32-icc/qmake.conf
@@ -4,6 +4,8 @@
# Written for Intel C++
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat debug_and_release debug_and_release_target
@@ -61,7 +63,7 @@ QMAKE_LIBS =
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
QMAKE_LIBS_QT_ENTRY = -lqtmain
@@ -72,4 +74,3 @@ QMAKE_RC = rc
include(../common/shell-win32.conf)
DSP_EXTENSION = .dsp
-load(qt_config)
diff --git a/mkspecs/win32-msvc2005/qmake.conf b/mkspecs/win32-msvc2005/qmake.conf
index 4a0fab761e..5c8247605d 100644
--- a/mkspecs/win32-msvc2005/qmake.conf
+++ b/mkspecs/win32-msvc2005/qmake.conf
@@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2005
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@@ -75,7 +77,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@@ -91,4 +93,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
-load(qt_config)
diff --git a/mkspecs/win32-msvc2005/qplatformdefs.h b/mkspecs/win32-msvc2005/qplatformdefs.h
index c7370f1c63..f621d08956 100644
--- a/mkspecs/win32-msvc2005/qplatformdefs.h
+++ b/mkspecs/win32-msvc2005/qplatformdefs.h
@@ -66,51 +66,51 @@
#include <stdlib.h>
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_STATBUF struct _stati64 // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
-#define QT_STAT ::_stati64
-#define QT_FSTAT ::_fstati64
+#define QT_STATBUF struct _stati64 // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stati64 // non-ANSI defs
+#define QT_STAT ::_stati64
+#define QT_FSTAT ::_fstati64
#else
-#define QT_STATBUF struct _stat // non-ANSI defs
-#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
-#define QT_STAT ::_stat
-#define QT_FSTAT ::_fstat
+#define QT_STATBUF struct _stat // non-ANSI defs
+#define QT_STATBUF4TSTAT struct _stat // non-ANSI defs
+#define QT_STAT ::_stat
+#define QT_FSTAT ::_fstat
#endif
-#define QT_STAT_REG _S_IFREG
-#define QT_STAT_DIR _S_IFDIR
-#define QT_STAT_MASK _S_IFMT
+#define QT_STAT_REG _S_IFREG
+#define QT_STAT_DIR _S_IFDIR
+#define QT_STAT_MASK _S_IFMT
#if defined(_S_IFLNK)
-# define QT_STAT_LNK _S_IFLNK
+# define QT_STAT_LNK _S_IFLNK
#else
-# define QT_STAT_LNK 0120000
+# define QT_STAT_LNK 0120000
#endif
-#define QT_FILENO _fileno
-#define QT_OPEN ::_open
-#define QT_CLOSE ::_close
+#define QT_FILENO _fileno
+#define QT_OPEN ::_open
+#define QT_CLOSE ::_close
#ifdef QT_LARGEFILE_SUPPORT
-#define QT_LSEEK ::_lseeki64
-#define QT_TSTAT ::_tstati64
+#define QT_LSEEK ::_lseeki64
+#define QT_TSTAT ::_tstati64
#else
-#define QT_LSEEK ::_lseek
-#define QT_TSTAT ::_tstat
+#define QT_LSEEK ::_lseek
+#define QT_TSTAT ::_tstat
#endif
-#define QT_READ ::_read
-#define QT_WRITE ::_write
-#define QT_ACCESS ::_access
-#define QT_GETCWD ::_getcwd
-#define QT_CHDIR ::_chdir
-#define QT_MKDIR ::_mkdir
-#define QT_RMDIR ::_rmdir
+#define QT_READ ::_read
+#define QT_WRITE ::_write
+#define QT_ACCESS ::_access
+#define QT_GETCWD ::_getcwd
+#define QT_CHDIR ::_chdir
+#define QT_MKDIR ::_mkdir
+#define QT_RMDIR ::_rmdir
#define QT_OPEN_LARGEFILE 0
-#define QT_OPEN_RDONLY _O_RDONLY
-#define QT_OPEN_WRONLY _O_WRONLY
-#define QT_OPEN_RDWR _O_RDWR
-#define QT_OPEN_CREAT _O_CREAT
-#define QT_OPEN_TRUNC _O_TRUNC
-#define QT_OPEN_APPEND _O_APPEND
+#define QT_OPEN_RDONLY _O_RDONLY
+#define QT_OPEN_WRONLY _O_WRONLY
+#define QT_OPEN_RDWR _O_RDWR
+#define QT_OPEN_CREAT _O_CREAT
+#define QT_OPEN_TRUNC _O_TRUNC
+#define QT_OPEN_APPEND _O_APPEND
#if defined(O_TEXT)
-# define QT_OPEN_TEXT _O_TEXT
-# define QT_OPEN_BINARY _O_BINARY
+# define QT_OPEN_TEXT _O_TEXT
+# define QT_OPEN_BINARY _O_BINARY
#endif
#include "../common/c89/qplatformdefs.h"
@@ -125,17 +125,17 @@
#define QT_OFF_T __int64
#endif
-#define QT_SIGNAL_ARGS int
+#define QT_SIGNAL_ARGS int
#define QT_VSNPRINTF(buffer, count, format, arg) \
vsnprintf_s(buffer, count, count-1, format, arg)
-#define QT_SNPRINTF ::_snprintf
+#define QT_SNPRINTF ::_snprintf
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
typedef int mode_t;
diff --git a/mkspecs/win32-msvc2008/qmake.conf b/mkspecs/win32-msvc2008/qmake.conf
index 8fd6eb0c7d..142eda5e67 100644
--- a/mkspecs/win32-msvc2008/qmake.conf
+++ b/mkspecs/win32-msvc2008/qmake.conf
@@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2008
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSVC.NET
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@@ -77,7 +79,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@@ -93,4 +95,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
-load(qt_config)
diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf
index 25304b6893..7a06fe7aee 100644
--- a/mkspecs/win32-msvc2010/qmake.conf
+++ b/mkspecs/win32-msvc2010/qmake.conf
@@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2010
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
-load(qt_config)
diff --git a/mkspecs/win32-msvc2012/qmake.conf b/mkspecs/win32-msvc2012/qmake.conf
index f32aa82e3c..7582117f22 100644
--- a/mkspecs/win32-msvc2012/qmake.conf
+++ b/mkspecs/win32-msvc2012/qmake.conf
@@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2012
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
-load(qt_config)
diff --git a/mkspecs/win32-msvc2013/qmake.conf b/mkspecs/win32-msvc2013/qmake.conf
index 0f5c01903f..61e4f48d6b 100644
--- a/mkspecs/win32-msvc2013/qmake.conf
+++ b/mkspecs/win32-msvc2013/qmake.conf
@@ -4,6 +4,8 @@
# Written for Microsoft Visual C++ 2013
#
+load(qt_config)
+
MAKEFILE_GENERATOR = MSBUILD
QMAKE_PLATFORM = win32
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
@@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
QMAKE_LIBS_NETWORK = ws2_32.lib
-QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
+!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
@@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
VCPROJ_EXTENSION = .vcxproj
VCSOLUTION_EXTENSION = .sln
VCPROJ_KEYWORD = Qt4VSv1.0
-load(qt_config)
diff --git a/mkspecs/winphone-arm-msvc2012/qmake.conf b/mkspecs/winphone-arm-msvc2012/qmake.conf
index 1e31ac51d0..c4e3d2bab7 100644
--- a/mkspecs/winphone-arm-msvc2012/qmake.conf
+++ b/mkspecs/winphone-arm-msvc2012/qmake.conf
@@ -5,6 +5,7 @@
#
include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1700
QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP ARM __ARM__ __arm__ QT_NO_CURSOR
@@ -13,3 +14,7 @@ QMAKE_LFLAGS += /MACHINE:ARM
QMAKE_LIBS += WindowsPhoneCore.lib PhoneAppModelHost.lib ws2_32.lib
VCPROJ_ARCH = ARM
+MSVC_VER = 11.0
+WINSDK_VER = 8.0
+WINTARGET_VER = WP80
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
diff --git a/mkspecs/winphone-arm-msvc2012/qplatformdefs.h b/mkspecs/winphone-arm-msvc2012/qplatformdefs.h
index e03bce8e6c..781107b2dc 100644
--- a/mkspecs/winphone-arm-msvc2012/qplatformdefs.h
+++ b/mkspecs/winphone-arm-msvc2012/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../win32-msvc2005/qplatformdefs.h"
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winphone-x86-msvc2012/qmake.conf b/mkspecs/winphone-x86-msvc2012/qmake.conf
index 8836de58cf..4b8a92ea3b 100644
--- a/mkspecs/winphone-x86-msvc2012/qmake.conf
+++ b/mkspecs/winphone-x86-msvc2012/qmake.conf
@@ -5,6 +5,7 @@
#
include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1700
QMAKE_PLATFORM = winphone $$QMAKE_PLATFORM
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP X86 __X86__ __x86__ QT_NO_CURSOR
@@ -12,4 +13,8 @@ QMAKE_LFLAGS += /MACHINE:X86
QMAKE_LIBS += WindowsPhoneCore.lib PhoneAppModelHost.lib ws2_32.lib
-VCPROJ_ARCH = x86
+VCPROJ_ARCH = Win32
+MSVC_VER = 11.0
+WINSDK_VER = 8.0
+WINTARGET_VER = WP80
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.0/WMAppManifest.xml.in
diff --git a/mkspecs/winphone-x86-msvc2012/qplatformdefs.h b/mkspecs/winphone-x86-msvc2012/qplatformdefs.h
index e03bce8e6c..781107b2dc 100644
--- a/mkspecs/winphone-x86-msvc2012/qplatformdefs.h
+++ b/mkspecs/winphone-x86-msvc2012/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../win32-msvc2005/qplatformdefs.h"
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-arm-msvc2012/qmake.conf b/mkspecs/winrt-arm-msvc2012/qmake.conf
index cafdbf4a93..b2603cfb2f 100644
--- a/mkspecs/winrt-arm-msvc2012/qmake.conf
+++ b/mkspecs/winrt-arm-msvc2012/qmake.conf
@@ -5,6 +5,7 @@
#
include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1700
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__
QMAKE_LFLAGS += /MACHINE:ARM
@@ -12,3 +13,8 @@ QMAKE_LFLAGS += /MACHINE:ARM
QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
VCPROJ_ARCH = ARM
+MSVC_VER = 11.0
+WINSDK_VER = 8.0
+WINTARGET_VER = win8
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.0/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = arm
diff --git a/mkspecs/winrt-arm-msvc2012/qplatformdefs.h b/mkspecs/winrt-arm-msvc2012/qplatformdefs.h
index e03bce8e6c..781107b2dc 100644
--- a/mkspecs/winrt-arm-msvc2012/qplatformdefs.h
+++ b/mkspecs/winrt-arm-msvc2012/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../win32-msvc2005/qplatformdefs.h"
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-arm-msvc2013/qmake.conf b/mkspecs/winrt-arm-msvc2013/qmake.conf
new file mode 100644
index 0000000000..d1ab60723d
--- /dev/null
+++ b/mkspecs/winrt-arm-msvc2013/qmake.conf
@@ -0,0 +1,22 @@
+#
+# qmake configuration for winrt-arm-msvc2013
+#
+# Written for Microsoft Visual C++ 2013
+#
+
+include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1800
+DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__
+
+QMAKE_CFLAGS += -FS
+QMAKE_CXXFLAGS += -FS
+QMAKE_LFLAGS += /MACHINE:ARM
+
+QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
+
+VCPROJ_ARCH = ARM
+MSVC_VER = 12.0
+WINSDK_VER = 8.1
+WINTARGET_VER = winv6.3
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = arm
diff --git a/mkspecs/winrt-arm-msvc2013/qplatformdefs.h b/mkspecs/winrt-arm-msvc2013/qplatformdefs.h
new file mode 100644
index 0000000000..781107b2dc
--- /dev/null
+++ b/mkspecs/winrt-arm-msvc2013/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-x64-msvc2012/qmake.conf b/mkspecs/winrt-x64-msvc2012/qmake.conf
index 784d0ccb7e..a0c64c695f 100644
--- a/mkspecs/winrt-x64-msvc2012/qmake.conf
+++ b/mkspecs/winrt-x64-msvc2012/qmake.conf
@@ -5,6 +5,7 @@
#
include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1700
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__
QMAKE_LFLAGS += /MACHINE:X64
@@ -12,3 +13,8 @@ QMAKE_LFLAGS += /MACHINE:X64
QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
VCPROJ_ARCH = x64
+MSVC_VER = 11.0
+WINSDK_VER = 8.0
+WINTARGET_VER = win8
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.0/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = x64
diff --git a/mkspecs/winrt-x64-msvc2012/qplatformdefs.h b/mkspecs/winrt-x64-msvc2012/qplatformdefs.h
index e03bce8e6c..781107b2dc 100644
--- a/mkspecs/winrt-x64-msvc2012/qplatformdefs.h
+++ b/mkspecs/winrt-x64-msvc2012/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../win32-msvc2005/qplatformdefs.h"
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-x64-msvc2013/qmake.conf b/mkspecs/winrt-x64-msvc2013/qmake.conf
new file mode 100644
index 0000000000..594d0dafd0
--- /dev/null
+++ b/mkspecs/winrt-x64-msvc2013/qmake.conf
@@ -0,0 +1,22 @@
+#
+# qmake configuration for winrt-x64-msvc2013
+#
+# Written for Microsoft Visual C++ 2013
+#
+
+include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1800
+DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__
+
+QMAKE_CFLAGS += -FS
+QMAKE_CXXFLAGS += -FS
+QMAKE_LFLAGS += /MACHINE:X64
+
+QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
+
+VCPROJ_ARCH = x64
+MSVC_VER = 12.0
+WINSDK_VER = 8.1
+WINTARGET_VER = winv6.3
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = x64
diff --git a/mkspecs/winrt-x64-msvc2013/qplatformdefs.h b/mkspecs/winrt-x64-msvc2013/qplatformdefs.h
new file mode 100644
index 0000000000..781107b2dc
--- /dev/null
+++ b/mkspecs/winrt-x64-msvc2013/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-x86-msvc2012/qmake.conf b/mkspecs/winrt-x86-msvc2012/qmake.conf
index 559c9b5d05..6e6ea4664d 100644
--- a/mkspecs/winrt-x86-msvc2012/qmake.conf
+++ b/mkspecs/winrt-x86-msvc2012/qmake.conf
@@ -5,10 +5,16 @@
#
include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1700
DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__
-QMAKE_LFLAGS += /MACHINE:X86
+QMAKE_LFLAGS += /SAFESEH /MACHINE:X86
QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
-VCPROJ_ARCH = x86
+VCPROJ_ARCH = Win32
+MSVC_VER = 11.0
+WINSDK_VER = 8.0
+WINTARGET_VER = win8
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.0/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = x86
diff --git a/mkspecs/winrt-x86-msvc2012/qplatformdefs.h b/mkspecs/winrt-x86-msvc2012/qplatformdefs.h
index e03bce8e6c..781107b2dc 100644
--- a/mkspecs/winrt-x86-msvc2012/qplatformdefs.h
+++ b/mkspecs/winrt-x86-msvc2012/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../win32-msvc2005/qplatformdefs.h"
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/mkspecs/winrt-x86-msvc2013/qmake.conf b/mkspecs/winrt-x86-msvc2013/qmake.conf
new file mode 100644
index 0000000000..77b906c7d3
--- /dev/null
+++ b/mkspecs/winrt-x86-msvc2013/qmake.conf
@@ -0,0 +1,22 @@
+#
+# qmake configuration for winrt-x86-msvc2013
+#
+# Written for Microsoft Visual C++ 2013
+#
+
+include(../common/winrt_winphone/qmake.conf)
+QMAKE_COMPILER_DEFINES += _MSC_VER=1800 _WIN32
+DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__
+
+QMAKE_CFLAGS += -FS
+QMAKE_CXXFLAGS += -FS
+QMAKE_LFLAGS += /SAFESEH /MACHINE:X86
+
+QMAKE_LIBS += windowscodecs.lib kernel32.lib ole32.lib
+
+VCPROJ_ARCH = Win32
+MSVC_VER = 12.0
+WINSDK_VER = 8.1
+WINTARGET_VER = winv6.3
+WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/8.1/AppxManifest.xml.in
+WINRT_MANIFEST.architecture = x86
diff --git a/mkspecs/winrt-x86-msvc2013/qplatformdefs.h b/mkspecs/winrt-x86-msvc2013/qplatformdefs.h
new file mode 100644
index 0000000000..781107b2dc
--- /dev/null
+++ b/mkspecs/winrt-x86-msvc2013/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../common/winrt_winphone/qplatformdefs.h"
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix
index ce83960884..ef1c542f57 100644
--- a/qmake/Makefile.unix
+++ b/qmake/Makefile.unix
@@ -12,7 +12,7 @@ OBJS=project.o option.o property.o main.o ioutils.o proitems.o \
gbuild.o cesdkhandler.o
#qt code
-QOBJS=qtextcodec.o qutfcodec.o qstring.o qstringbuilder.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
+QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \
qarraydata.o qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \
qfilesystementry.o qfilesystemengine.o qfsfileengine.o qfsfileengine_iterator.o qregexp.o qvector.o \
qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o qfileinfo.o qdatetime.o qstringlist.o \
@@ -40,6 +40,7 @@ DEPEND_SRC = \
$(QMKGENSRC)/win32/msvc_objectmodel.cpp $(QMKGENSRC)/win32/msbuild_objectmodel.cpp \
$(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \
$(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \
+ $(SOURCE_PATH)/src/corelib/tools/qstring_compat.cpp \
$(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \
$(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \
$(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \
@@ -272,6 +273,9 @@ qtextcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp
qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring.cpp
+qstring_compat.o: $(SOURCE_PATH)/src/corelib/tools/qstring_compat.cpp
+ $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstring_compat.cpp
+
qstringbuilder.o: $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp
diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32
index af1da918c6..b1936f3cec 100644
--- a/qmake/Makefile.win32
+++ b/qmake/Makefile.win32
@@ -48,7 +48,7 @@ CXXFLAGS_BARE = $(CFLAGS_BARE)
CXXFLAGS = $(CFLAGS)
LFLAGS =
-LIBS = ole32.lib advapi32.lib
+LIBS = ole32.lib advapi32.lib shell32.lib
LINKQMAKE = $(LINKER) $(LFLAGS) -OUT:qmake.exe $(OBJS) $(QTOBJS) $(LIBS)
ADDCLEAN = qmake.pdb qmake.ilk
@@ -105,6 +105,7 @@ QTOBJS= \
qtextcodec.obj \
qutfcodec.obj \
qstring.obj \
+ qstring_compat.obj \
qstringlist.obj \
qstringbuilder.obj \
qsystemerror.obj \
@@ -218,3 +219,7 @@ qmake_pch.obj:
{$(SOURCE_PATH)\tools\shared\windows}.cpp{}.obj::
$(CXX) $(CXXFLAGS) $<
+
+# Make sure qstring_compat.obj isn't compiled with PCH enabled
+qstring_compat.obj: $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp
+ $(CXX) -c $(CXXFLAGS_BARE) $(SOURCE_PATH)\src\corelib\tools\qstring_compat.cpp
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 946a1ee986..fe8d289a7c 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -456,6 +456,8 @@ MakefileGenerator::init()
if (v["QMAKE_LINK_O_FLAG"].isEmpty())
v["QMAKE_LINK_O_FLAG"].append("-o ");
+ setSystemIncludes(v["QMAKE_DEFAULT_INCDIRS"]);
+
ProStringList &quc = v["QMAKE_EXTRA_COMPILERS"];
//make sure the COMPILERS are in the correct input/output chain order
@@ -1420,31 +1422,31 @@ MakefileGenerator::writeInstalls(QTextStream &t, bool noBuild)
}
QString
-MakefileGenerator::var(const ProKey &var)
+MakefileGenerator::var(const ProKey &var) const
{
return val(project->values(var));
}
QString
-MakefileGenerator::val(const ProStringList &varList)
+MakefileGenerator::val(const ProStringList &varList) const
{
return valGlue(varList, "", " ", "");
}
QString
-MakefileGenerator::val(const QStringList &varList)
+MakefileGenerator::val(const QStringList &varList) const
{
return valGlue(varList, "", " ", "");
}
QString
-MakefileGenerator::varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after)
+MakefileGenerator::varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const
{
return valGlue(project->values(var), before, glue, after);
}
QString
-MakefileGenerator::fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after)
+MakefileGenerator::fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const
{
ProStringList varList;
foreach (const ProString &val, project->values(var))
@@ -1453,7 +1455,7 @@ MakefileGenerator::fileVarGlue(const ProKey &var, const QString &before, const Q
}
QString
-MakefileGenerator::valGlue(const ProStringList &varList, const QString &before, const QString &glue, const QString &after)
+MakefileGenerator::valGlue(const ProStringList &varList, const QString &before, const QString &glue, const QString &after) const
{
QString ret;
for (ProStringList::ConstIterator it = varList.begin(); it != varList.end(); ++it) {
@@ -1467,7 +1469,7 @@ MakefileGenerator::valGlue(const ProStringList &varList, const QString &before,
}
QString
-MakefileGenerator::valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after)
+MakefileGenerator::valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) const
{
QString ret;
for(QStringList::ConstIterator it = varList.begin(); it != varList.end(); ++it) {
@@ -1482,19 +1484,19 @@ MakefileGenerator::valGlue(const QStringList &varList, const QString &before, co
QString
-MakefileGenerator::varList(const ProKey &var)
+MakefileGenerator::varList(const ProKey &var) const
{
return valList(project->values(var));
}
QString
-MakefileGenerator::valList(const ProStringList &varList)
+MakefileGenerator::valList(const ProStringList &varList) const
{
return valGlue(varList, "", " \\\n\t\t", "");
}
QString
-MakefileGenerator::valList(const QStringList &varList)
+MakefileGenerator::valList(const QStringList &varList) const
{
return valGlue(varList, "", " \\\n\t\t", "");
}
@@ -2464,8 +2466,6 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
t << "include " << (*qeui_it) << endl;
if (!(flags & SubTargetSkipDefaultVariables)) {
- /* Calling Option::fixPathToTargetOS() is necessary for MinGW/MSYS, which requires
- * back-slashes to be turned into slashes. */
t << "QMAKE = " << var("QMAKE_QMAKE") << endl;
t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
@@ -2617,6 +2617,8 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT
t << varGlue("ALL_DEPS"," "," ","");
if(suffix == "clean")
t << varGlue("CLEAN_DEPS"," "," ","");
+ else if (suffix == "distclean")
+ t << varGlue("DISTCLEAN_DEPS"," "," ","");
t << " FORCE\n";
if(suffix == "clean") {
t << fileVarGlue("QMAKE_CLEAN", "\t-$(DEL_FILE) ", "\n\t-$(DEL_FILE) ", "\n");
diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h
index 4b8a96c15f..a382ca6bf6 100644
--- a/qmake/generators/makefile.h
+++ b/qmake/generators/makefile.h
@@ -225,16 +225,16 @@ protected:
virtual bool findLibraries();
//for retrieving values and lists of values
- virtual QString var(const ProKey &var);
- QString varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after);
- QString fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after);
- QString varList(const ProKey &var);
- QString val(const ProStringList &varList);
- QString val(const QStringList &varList);
- QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after);
- QString valGlue(const ProStringList &varList, const QString &before, const QString &glue, const QString &after);
- QString valList(const QStringList &varList);
- QString valList(const ProStringList &varList);
+ virtual QString var(const ProKey &var) const;
+ QString varGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const;
+ QString fileVarGlue(const ProKey &var, const QString &before, const QString &glue, const QString &after) const;
+ QString varList(const ProKey &var) const;
+ QString val(const ProStringList &varList) const;
+ QString val(const QStringList &varList) const;
+ QString valGlue(const QStringList &varList, const QString &before, const QString &glue, const QString &after) const;
+ QString valGlue(const ProStringList &varList, const QString &before, const QString &glue, const QString &after) const;
+ QString valList(const QStringList &varList) const;
+ QString valList(const ProStringList &varList) const;
QString filePrefixRoot(const QString &, const QString &);
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index df37957f9b..edc9a0ed7f 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -345,6 +345,30 @@ bool QMakeSourceFileInfo::containsSourceFile(const QString &f, SourceFileType ty
return false;
}
+bool QMakeSourceFileInfo::isSystemInclude(const QString &name)
+{
+ if (QDir::isRelativePath(name)) {
+ // if we got a relative path here, it's either an -I flag with a relative path
+ // or an include file we couldn't locate. Either way, conclude it's not
+ // a system include.
+ return false;
+ }
+
+ for (int i = 0; i < systemIncludes.size(); ++i) {
+ // check if name is located inside the system include dir:
+ QDir systemDir(systemIncludes.at(i));
+ QString relativePath = systemDir.relativeFilePath(name);
+
+ // the relative path might be absolute if we're crossing drives on Windows
+ if (QDir::isAbsolutePath(relativePath) || relativePath.startsWith("../"))
+ continue;
+ debug_msg(5, "File/dir %s is in system dir %s, skipping",
+ qPrintable(name), qPrintable(systemIncludes.at(i)));
+ return true;
+ }
+ return false;
+}
+
char *QMakeSourceFileInfo::getBuffer(int s) {
if(!spare_buffer || spare_buffer_size < s)
spare_buffer = (char *)realloc(spare_buffer, spare_buffer_size=s);
@@ -655,7 +679,7 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
} else {
exists = QFile::exists(lfn.real());
}
- if(!lfn.isNull()) {
+ if (!lfn.isNull() && !isSystemInclude(lfn.real())) {
dep = files->lookupFile(lfn);
if(!dep) {
dep = new SourceFile;
diff --git a/qmake/generators/makefiledeps.h b/qmake/generators/makefiledeps.h
index ba55c36998..516abd4afd 100644
--- a/qmake/generators/makefiledeps.h
+++ b/qmake/generators/makefiledeps.h
@@ -78,6 +78,7 @@ private:
SourceFiles *files, *includes;
bool files_changed;
QList<QMakeLocalFileName> depdirs;
+ QStringList systemIncludes;
//sleezy buffer code
char *spare_buffer;
@@ -98,6 +99,7 @@ protected:
virtual QFileInfo findFileInfo(const QMakeLocalFileName &);
public:
+
QMakeSourceFileInfo(const QString &cachefile="");
virtual ~QMakeSourceFileInfo();
@@ -108,11 +110,15 @@ public:
inline void setDependencyMode(DependencyMode mode) { dep_mode = mode; }
inline DependencyMode dependencyMode() const { return dep_mode; }
+ void setSystemIncludes(const ProStringList &list)
+ { systemIncludes = list.toQStringList(); }
+
enum SourceFileType { TYPE_UNKNOWN, TYPE_C, TYPE_UI, TYPE_QRC };
enum SourceFileSeek { SEEK_DEPS=0x01, SEEK_MOCS=0x02 };
void addSourceFiles(const ProStringList &, uchar seek, SourceFileType type=TYPE_C);
void addSourceFile(const QString &, uchar seek, SourceFileType type=TYPE_C);
bool containsSourceFile(const QString &, SourceFileType type=TYPE_C);
+ bool isSystemInclude(const QString &);
int included(const QString &file);
QStringList dependencies(const QString &file);
diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp
index ea6a6a6e90..cadd5cf316 100644
--- a/qmake/generators/unix/unixmake.cpp
+++ b/qmake/generators/unix/unixmake.cpp
@@ -94,6 +94,27 @@ UnixMakefileGenerator::init()
if(project->isEmpty("QMAKE_SYMBOLIC_LINK"))
project->values("QMAKE_SYMBOLIC_LINK").append("ln -f -s");
+ if (!project->isEmpty("TARGET"))
+ project->values("TARGET") = escapeFilePaths(project->values("TARGET"));
+ project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
+
+ //version handling
+ if (project->isEmpty("VERSION")) {
+ project->values("VERSION").append(
+ "1.0." + (project->isEmpty("VER_PAT") ? QString("0") : project->first("VER_PAT")));
+ }
+ QStringList l = project->first("VERSION").toQString().split('.');
+ l << "0" << "0"; //make sure there are three
+ project->values("VER_MAJ").append(l[0]);
+ project->values("VER_MIN").append(l[1]);
+ project->values("VER_PAT").append(l[2]);
+
+ QString sroot = project->sourceRoot();
+ foreach (const ProString &iif, project->values("QMAKE_INTERNAL_INCLUDED_FILES")) {
+ if (iif.startsWith(sroot) && iif.at(sroot.length()) == QLatin1Char('/'))
+ project->values("DISTFILES") += fileFixify(iif.toQString(), FileFixifyRelative);
+ }
+
/* this should probably not be here, but I'm using it to wrap the .t files */
if(project->first("TEMPLATE") == "app")
project->values("QMAKE_APP_FLAG").append("1");
@@ -106,10 +127,6 @@ UnixMakefileGenerator::init()
return; /* subdirs is done */
}
- if (!project->isEmpty("TARGET"))
- project->values("TARGET") = escapeFilePaths(project->values("TARGET"));
-
- project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR");
project->values("QMAKE_LIBS") += escapeFilePaths(project->values("LIBS"));
project->values("QMAKE_LIBS_PRIVATE") += escapeFilePaths(project->values("LIBS_PRIVATE"));
@@ -304,10 +321,6 @@ UnixMakefileGenerator::init()
project->values("QMAKE_BUNDLE_LOCATION").clear();
}
- if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES"))
- project->values("DISTFILES") += project->values("QMAKE_INTERNAL_INCLUDED_FILES");
- project->values("DISTFILES") += project->projectFile();
-
init2();
project->values("QMAKE_INTERNAL_PRL_LIBS") << "QMAKE_LIBS";
if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index bc4c167744..8959305238 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -125,10 +125,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << " -I" << pwd;
}
{
+ QString isystem = var("QMAKE_CFLAGS_ISYSTEM");
const ProStringList &incs = project->values("INCLUDEPATH");
for(int i = 0; i < incs.size(); ++i) {
ProString inc = escapeFilePath(incs.at(i));
- if(!inc.isEmpty())
+ if (inc.isEmpty())
+ continue;
+
+ if (!isystem.isEmpty() && isSystemInclude(inc.toQString()))
+ t << ' ' << isystem << ' ' << inc;
+ else
t << " -I" << inc;
}
}
@@ -210,7 +216,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
}
if(do_incremental && !src_incremental)
do_incremental = false;
- t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << endl;
+ t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " "
+ << valList(escapeFilePaths(project->values("SOURCES"))) << endl;
t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
// The comment is important for mingw32-make.exe on Windows as otherwise trailing slashes
// would be interpreted as line continuation. The lack of spacing between the value and the
@@ -813,7 +820,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
Option::output_dir, Option::output_dir));
t << "dist: \n\t"
<< mkdir_p_asstring(ddir_c, false) << "\n\t"
- << "$(COPY_FILE) --parents $(SOURCES) $(DIST) " << ddir_c << Option::dir_sep << " && ";
+ << "$(COPY_FILE) --parents $(DIST) " << ddir_c << Option::dir_sep << " && ";
if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
const ProStringList &quc = project->values("QMAKE_EXTRA_COMPILERS");
for (ProStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) {
@@ -901,22 +908,11 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
<< "-$(DEL_FILE) *~ core *.core\n"
<< varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl;
- t << "####### Sub-libraries\n\n";
- if (!project->values("SUBLIBS").isEmpty()) {
- ProString libdir = "tmp/";
- if(!project->isEmpty("SUBLIBS_DIR"))
- libdir = project->first("SUBLIBS_DIR");
- const ProStringList &l = project->values("SUBLIBS");
- for(it = l.begin(); it != l.end(); ++it)
- t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
- << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t"
- << var(ProKey("MAKELIB" + *it)) << endl << endl;
- }
ProString destdir = project->first("DESTDIR");
if (!destdir.isEmpty() && !destdir.endsWith(Option::dir_sep))
destdir += Option::dir_sep;
- t << "distclean: clean\n";
+ t << "distclean: clean " << var("DISTCLEAN_DEPS") << '\n';
if(!project->isEmpty("QMAKE_BUNDLE")) {
QString bundlePath = escapeFilePath(destdir + project->first("QMAKE_BUNDLE"));
t << "\t-$(DEL_FILE) -r " << bundlePath << endl;
@@ -938,9 +934,21 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
}
t << endl << endl;
+ t << "####### Sub-libraries\n\n";
+ if (!project->values("SUBLIBS").isEmpty()) {
+ ProString libdir = "tmp/";
+ if (!project->isEmpty("SUBLIBS_DIR"))
+ libdir = project->first("SUBLIBS_DIR");
+ const ProStringList &l = project->values("SUBLIBS");
+ for (it = l.begin(); it != l.end(); ++it)
+ t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
+ << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t"
+ << var(ProKey("MAKELIB" + *it)) << endl << endl;
+ }
+
if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
QString pchInput = project->first("PRECOMPILED_HEADER").toQString();
- t << "###### Prefix headers\n";
+ t << "###### Precompiled headers\n";
QString comps[] = { "C", "CXX", "OBJC", "OBJCXX", QString() };
for(int i = 0; !comps[i].isNull(); i++) {
QString pchFlags = var(ProKey("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE"));
@@ -1017,16 +1025,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
void UnixMakefileGenerator::init2()
{
- //version handling
- if(project->isEmpty("VERSION"))
- project->values("VERSION").append("1.0." +
- (project->isEmpty("VER_PAT") ? QString("0") :
- project->first("VER_PAT")));
- QStringList l = project->first("VERSION").toQString().split('.');
- l << "0" << "0"; //make sure there are three
- project->values("VER_MAJ").append(l[0]);
- project->values("VER_MIN").append(l[1]);
- project->values("VER_PAT").append(l[2]);
if(project->isEmpty("QMAKE_FRAMEWORK_VERSION"))
project->values("QMAKE_FRAMEWORK_VERSION").append(project->values("VER_MAJ").first());
@@ -1235,8 +1233,10 @@ void UnixMakefileGenerator::init2()
}
if (include_deps && project->isActiveConfig("gcc_MD_depends")) {
- project->values("QMAKE_CFLAGS") += "-MD";
- project->values("QMAKE_CXXFLAGS") += "-MD";
+ // use -MMD if we know about -isystem too
+ ProString MD_flag(project->values("QMAKE_CFLAGS_ISYSTEM").isEmpty() ? "-MD" : "-MMD");
+ project->values("QMAKE_CFLAGS") += MD_flag;
+ project->values("QMAKE_CXXFLAGS") += MD_flag;
}
if(!project->isEmpty("QMAKE_BUNDLE")) {
@@ -1318,7 +1318,7 @@ UnixMakefileGenerator::writeLibtoolFile()
t << "# " << lname << " - a libtool library file\n";
t << "# Generated by qmake/libtool (" QMAKE_VERSION_STR ") (Qt "
<< QT_VERSION_STR << ") on: " << QDateTime::currentDateTime().toString();
- t << "\n";
+ t << "\n";
t << "# The name that we can dlopen(3).\n"
<< "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x")
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index 29b27cb7d7..6d5764f59c 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -101,7 +101,7 @@ bool MingwMakefileGenerator::findLibraries()
}
if (!out.isEmpty()) // We assume if it never finds it that its correct
(*it) = out;
- } else if((*it).startsWith("-L")) {
+ } else if ((*it).startsWith("-L")) {
dirs.append(QMakeLocalFileName((*it).mid(2).toQString()));
}
@@ -159,7 +159,7 @@ void createLdObjectScriptFile(const QString &fileName, const ProStringList &objL
t << path << endl;
}
t << ");\n";
- t.flush();
+ t.flush();
file.close();
}
}
@@ -175,7 +175,7 @@ void createArObjectScriptFile(const QString &fileName, const QString &target, co
t << "ADDMOD " << *it << endl;
}
t << "SAVE\n";
- t.flush();
+ t.flush();
file.close();
}
}
@@ -204,16 +204,16 @@ void MingwMakefileGenerator::writeMingwParts(QTextStream &t)
if (!preCompHeaderOut.isEmpty()) {
QString header = project->first("PRECOMPILED_HEADER").toQString();
- QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
- t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " "
+ QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
+ t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " "
<< escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
- << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
+ << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
<< "\n\t$(CC) -x c-header -c $(CFLAGS) $(INCPATH) -o " << cHeader << " " << header
<< endl << endl;
- QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
- t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " "
+ QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
+ t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " "
<< escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
- << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
+ << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
<< "\n\t$(CXX) -x c++-header -c $(CXXFLAGS) $(INCPATH) -o " << cppHeader << " " << header
<< endl << endl;
}
@@ -269,7 +269,7 @@ void MingwMakefileGenerator::init()
destDir = Option::fixPathToTargetOS(project->first("DESTDIR") + Option::dir_sep, false, false);
project->values("MINGW_IMPORT_LIB").prepend(destDir + "lib" + project->first("TARGET")
+ project->first("TARGET_VERSION_EXT") + ".a");
- project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + project->first("MINGW_IMPORT_LIB"));
+ project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + project->first("MINGW_IMPORT_LIB"));
}
if (!project->values("DEF_FILE").isEmpty()) {
@@ -287,21 +287,21 @@ void MingwMakefileGenerator::init()
&& project->isActiveConfig("precompile_header")) {
QString preCompHeader = var("PRECOMPILED_DIR")
+ QFileInfo(project->first("PRECOMPILED_HEADER").toQString()).fileName();
- preCompHeaderOut = preCompHeader + ".gch";
- project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c");
- project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++");
+ preCompHeaderOut = preCompHeader + ".gch";
+ project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c");
+ project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++");
- project->values("QMAKE_RUN_CC").clear();
- project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CC").clear();
+ project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader +
" $(CFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$obj $src");
project->values("QMAKE_RUN_CC_IMP").clear();
- project->values("QMAKE_RUN_CC_IMP").append("$(CC) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CC_IMP").append("$(CC) -c -include " + preCompHeader +
" $(CFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$@ $<");
project->values("QMAKE_RUN_CXX").clear();
- project->values("QMAKE_RUN_CXX").append("$(CXX) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CXX").append("$(CXX) -c -include " + preCompHeader +
" $(CXXFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$obj $src");
project->values("QMAKE_RUN_CXX_IMP").clear();
- project->values("QMAKE_RUN_CXX_IMP").append("$(CXX) -c -include " + preCompHeader +
+ project->values("QMAKE_RUN_CXX_IMP").append("$(CXX) -c -include " + preCompHeader +
" $(CXXFLAGS) $(INCPATH) " + var("QMAKE_CC_O_FLAG") + "$@ $<");
}
@@ -321,12 +321,18 @@ void MingwMakefileGenerator::writeIncPart(QTextStream &t)
t << "-I" << pwd << " ";
}
+ QString isystem = var("QMAKE_CFLAGS_ISYSTEM");
const ProStringList &incs = project->values("INCLUDEPATH");
for (ProStringList::ConstIterator incit = incs.begin(); incit != incs.end(); ++incit) {
QString inc = (*incit).toQString();
inc.replace(QRegExp("\\\\$"), "");
inc.replace(QRegExp("\""), "");
- t << "-I" << quote << inc << quote << " ";
+
+ if (!isystem.isEmpty() && isSystemInclude(inc))
+ t << isystem << ' ';
+ else
+ t << "-I";
+ t << quote << inc << quote << " ";
}
t << "-I" << quote << specdir() << quote
<< endl;
@@ -350,10 +356,10 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
objectsLinkLine = "$(OBJECTS)";
} else if (project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
- QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
- if (!var("BUILD_NAME").isEmpty()) {
- ar_script_file += "." + var("BUILD_NAME");
- }
+ QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
+ if (!var("BUILD_NAME").isEmpty()) {
+ ar_script_file += "." + var("BUILD_NAME");
+ }
// QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix.
if (project->isActiveConfig("rvct_linker")) {
createRvctObjectScriptFile(ar_script_file, project->values("OBJECTS"));
@@ -371,9 +377,9 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
}
} else {
QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
- if (!var("BUILD_NAME").isEmpty()) {
- ld_script_file += "." + var("BUILD_NAME");
- }
+ if (!var("BUILD_NAME").isEmpty()) {
+ ld_script_file += "." + var("BUILD_NAME");
+ }
if (project->isActiveConfig("rvct_linker")) {
createRvctObjectScriptFile(ld_script_file, project->values("OBJECTS"));
objectsLinkLine = QString::fromLatin1("--via ") + escapeFilePath(ld_script_file);
@@ -393,7 +399,7 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
if(!project->isEmpty("QMAKE_PRE_LINK"))
t << "\n\t" <<var("QMAKE_PRE_LINK");
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
- if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
+ if (project->values("OBJECTS").count() < var("QMAKE_LINK_OBJECT_MAX").toInt()) {
t << "\n\t$(LIB) $(DESTDIR_TARGET) " << objectsLinkLine << " " ;
} else {
t << "\n\t" << objectsLinkLine << " " ;
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index fdb664f3f4..7702496f3c 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -614,12 +614,16 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< tag("ItemGroup")
<< attrTag("Label", "ProjectConfigurations");
+ bool isWinRT = false;
+ bool isPhone = false;
for (int i = 0; i < tool.SingleProjects.count(); ++i) {
xml << tag("ProjectConfiguration")
<< attrTag("Include" , tool.SingleProjects.at(i).Configuration.Name)
<< tagValue("Configuration", tool.SingleProjects.at(i).Configuration.ConfigurationName)
<< tagValue("Platform", tool.SingleProjects.at(i).PlatformName)
<< closetag();
+ isWinRT = isWinRT || tool.SingleProjects.at(i).Configuration.WinRT;
+ isPhone = isPhone || tool.SingleProjects.at(i).Configuration.WinPhone;
}
xml << closetag()
@@ -629,18 +633,19 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< tagValue("RootNamespace", tool.Name)
<< tagValue("Keyword", tool.Keyword);
- if (tool.SingleProjects.at(0).Configuration.WinRT) {
- xml << tagValue("MinimumVisualStudioVersion", "11.0");
- if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ if (isWinRT) {
+ xml << tagValue("MinimumVisualStudioVersion", tool.Version);
+ if (isPhone) {
xml << tagValue("WinMDAssembly", "true");
- else
- xml << tagValue("AppContainerApplication", "true");
- }
-
- if (tool.SingleProjects.at(0).Configuration.WinPhone
- && tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) {
- xml << tagValue("XapOutputs", "true");
- xml << tagValue("XapFilename", "$(RootNamespace)_$(Configuration)_$(Platform).xap");
+ if (tool.SingleProjects.at(0).Configuration.ConfigurationType == typeApplication) {
+ xml << tagValue("XapOutputs", "true");
+ xml << tagValue("XapFilename", "$(RootNamespace)_$(Configuration)_$(Platform).xap");
+ }
+ } else {
+ xml << tagValue("AppContainerApplication", "true")
+ << tagValue("ApplicationType", "Windows Store")
+ << tagValue("ApplicationTypeRevision", tool.SdkVersion);
+ }
}
xml << closetag();
@@ -769,6 +774,10 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
write(xml, config.preLink);
xml << closetag();
+
+ // windeployqt
+ if (!config.windeployqt.ExcludedFromBuild)
+ write(xml, config.windeployqt);
}
// The file filters are added in a separate file for MSBUILD.
@@ -824,9 +833,43 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool)
<< closetag();
}
+ // App manifest
+ if (isWinRT) {
+ QString manifest = isPhone ? QStringLiteral("WMAppManifest.xml") : QStringLiteral("Package.appxmanifest");
+
+ // Find all icons referenced in the manifest
+ QSet<QString> icons;
+ QFile manifestFile(Option::output_dir + QLatin1Char('/') + manifest);
+ if (manifestFile.open(QFile::ReadOnly)) {
+ const QString contents = manifestFile.readAll();
+ QRegExp regexp("[\\\\/a-zA-Z0-9_\\-\\!]*\\.(png|jpg|jpeg)");
+ int pos = 0;
+ while (pos > -1) {
+ pos = regexp.indexIn(contents, pos);
+ if (pos >= 0) {
+ const QString match = regexp.cap(0);
+ icons.insert(match);
+ pos += match.length();
+ }
+ }
+ }
+
+ // Write out manifest + icons as content items
+ xml << tag(_ItemGroup)
+ << tag(isPhone ? "Xml" : "AppxManifest")
+ << attrTag("Include", manifest)
+ << closetag();
+ foreach (const QString &icon, icons) {
+ xml << tag("Image")
+ << attrTag("Include", icon)
+ << closetag();
+ }
+ xml << closetag();
+ }
+
xml << import("Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
- if (tool.SingleProjects.at(0).Configuration.WinPhone)
+ if (isPhone)
xml << import("Project", "$(MSBuildExtensionsPath)\\Microsoft\\WindowsPhone\\v8.0\\Microsoft.Cpp.WindowsPhone.8.0.targets");
xml << tag("ImportGroup")
@@ -1695,6 +1738,42 @@ void VCXProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
// SmartDevice deployment not supported in VS 2010
}
+void VCXProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
+{
+ const QString name = QStringLiteral("WinDeployQt_") + tool.config->Name;
+ xml << tag("Target")
+ << attrTag(_Name, name)
+ << attrTag("Condition", generateCondition(*tool.config))
+ << attrTag("Inputs", "$(OutDir)\\$(TargetName).exe")
+ << attrTag("Outputs", tool.Record)
+ << tag(_Message)
+ << attrTag("Text", tool.CommandLine)
+ << closetag()
+ << tag("Exec")
+ << attrTag("Command", tool.CommandLine)
+ << closetag()
+ << closetag()
+ << tag("Target")
+ << attrTag(_Name, QStringLiteral("PopulateWinDeployQtItems_") + tool.config->Name)
+ << attrTag("Condition", generateCondition(*tool.config))
+ << attrTag("AfterTargets", "Link")
+ << attrTag("DependsOnTargets", name)
+ << tag("ReadLinesFromFile")
+ << attrTag("File", tool.Record)
+ << tag("Output")
+ << attrTag("TaskParameter", "Lines")
+ << attrTag("ItemName", "DeploymentItems")
+ << closetag()
+ << closetag()
+ << tag(_ItemGroup)
+ << tag("None")
+ << attrTag("Include", "@(DeploymentItems)")
+ << attrTagT("DeploymentContent", _True)
+ << closetag()
+ << closetag()
+ << closetag();
+}
+
void VCXProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
{
xml << tag("PropertyGroup")
diff --git a/qmake/generators/win32/msbuild_objectmodel.h b/qmake/generators/win32/msbuild_objectmodel.h
index 7fb83233f4..2f02e66eb9 100644
--- a/qmake/generators/win32/msbuild_objectmodel.h
+++ b/qmake/generators/win32/msbuild_objectmodel.h
@@ -174,6 +174,7 @@ public:
void write(XmlOutput &, const VCResourceCompilerTool &);
void write(XmlOutput &, const VCEventTool &);
void write(XmlOutput &, const VCDeploymentTool &);
+ void write(XmlOutput &, const VCWinDeployQtTool &);
void write(XmlOutput &, const VCConfiguration &);
void write(XmlOutput &, VCFilter &);
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index 0abbd133cc..24465ad152 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -123,29 +123,64 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
} else if (arch == QStringLiteral("x64")) {
compiler = QStringLiteral("x86_amd64");
compilerArch = QStringLiteral("amd64");
+ } else {
+ arch = QStringLiteral("x86");
+ }
+
+ const QString msvcVer = project->first("MSVC_VER").toQString();
+ if (msvcVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify MSVC_VER. Cannot continue.\n");
+ return false;
+ }
+ const QString winsdkVer = project->first("WINSDK_VER").toQString();
+ if (winsdkVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify WINSDK_VER. Cannot continue.\n");
+ return false;
}
+ const QString targetVer = project->first("WINTARGET_VER").toQString();
+ if (targetVer.isEmpty()) {
+ fprintf(stderr, "Mkspec does not specify WINTARGET_VER. Cannot continue.\n");
+ return false;
+ }
+
+ const bool isPhone = project->isActiveConfig(QStringLiteral("winphone"));
#ifdef Q_OS_WIN
-#ifdef Q_OS_WIN64
- const QString regKey = QStringLiteral("Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir");
-#else
- const QString regKey = QStringLiteral("Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir");
+ QString regKeyPrefix;
+#if !defined(Q_OS_WIN64) && _WIN32_WINNT >= 0x0501
+ BOOL isWow64;
+ IsWow64Process(GetCurrentProcess(), &isWow64);
+ if (!isWow64)
+ regKeyPrefix = QStringLiteral("Software\\");
+ else
#endif
+ regKeyPrefix = QStringLiteral("Software\\Wow6432Node\\");
+
+ QString regKey = regKeyPrefix + QStringLiteral("Microsoft\\VisualStudio\\") + msvcVer + ("\\Setup\\VC\\ProductDir");
const QString vcInstallDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey);
if (vcInstallDir.isEmpty()) {
- fprintf(stderr, "Failed to find the Visual Studio 2012 installation directory.\n"
- "Is it installed?.\n");
+ fprintf(stderr, "Failed to find the Visual Studio installation directory.\n");
+ return false;
+ }
+
+ regKey = regKeyPrefix
+ + (isPhone ? QStringLiteral("Microsoft\\Microsoft SDKs\\WindowsPhone\\v")
+ : QStringLiteral("Microsoft\\Microsoft SDKs\\Windows\\v"))
+ + winsdkVer + QStringLiteral("\\InstallationFolder");
+ const QString kitDir = qt_readRegistryKey(HKEY_LOCAL_MACHINE, regKey);
+ if (kitDir.isEmpty()) {
+ fprintf(stderr, "Failed to find the Windows Kit installation directory.\n");
return false;
}
#else
const QString vcInstallDir = "/fake/vc_install_dir";
+ const QString kitDir = "/fake/sdk_install_dir";
#endif // Q_OS_WIN
QStringList incDirs;
QStringList libDirs;
QStringList binDirs;
- const bool isPhone = project->isActiveConfig(QStringLiteral("winphone"));
if (isPhone) {
- QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/WP80");
+ QString sdkDir = vcInstallDir + QStringLiteral("/WPSDK/") + targetVer;
if (!QDir(sdkDir).exists()) {
fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n"
"Check that it is properly installed.\n",
@@ -155,14 +190,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
incDirs << sdkDir + QStringLiteral("/include");
libDirs << sdkDir + QStringLiteral("/lib/") + compilerArch;
binDirs << sdkDir + QStringLiteral("/bin/") + compiler;
-
- QString kitDir = vcInstallDir + QStringLiteral("/../../Windows Phone Kits/8.0");
- if (!QDir(kitDir).exists()) {
- fprintf(stderr, "Failed to find the Windows Phone Kit in %s.\n"
- "Check that it is properly installed.\n",
- qPrintable(QDir::toNativeSeparators(kitDir)));
- return false;
- }
libDirs << kitDir + QStringLiteral("/lib/") + arch;
incDirs << kitDir + QStringLiteral("/include")
<< kitDir + QStringLiteral("/include/abi")
@@ -170,18 +197,11 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t)
<< kitDir + QStringLiteral("/include/minwin");
} else {
incDirs << vcInstallDir + QStringLiteral("/include");
- libDirs << vcInstallDir + QStringLiteral("/lib/") + compilerArch;
+ libDirs << vcInstallDir + QStringLiteral("/lib/store/") + compilerArch
+ << vcInstallDir + QStringLiteral("/lib/") + compilerArch;
binDirs << vcInstallDir + QStringLiteral("/bin/") + compiler
<< vcInstallDir + QStringLiteral("/../Common7/IDE");
-
- QString kitDir = vcInstallDir + QStringLiteral("/../../Windows Kits/8.0");
- if (!QDir(kitDir).exists()) {
- fprintf(stderr, "Failed to find the Windows Kit in %s.\n"
- "Check that it is properly installed.\n",
- qPrintable(QDir::toNativeSeparators(kitDir)));
- return false;
- }
- libDirs << kitDir + QStringLiteral("/Lib/win8/um/") + arch;
+ libDirs << kitDir + QStringLiteral("/Lib/") + targetVer + ("/um/") + arch;
incDirs << kitDir + QStringLiteral("/include/um")
<< kitDir + QStringLiteral("/include/shared")
<< kitDir + QStringLiteral("/include/winrt");
@@ -285,7 +305,7 @@ void NmakeMakefileGenerator::writeNmakeParts(QTextStream &t)
}
}
-QString NmakeMakefileGenerator::var(const ProKey &value)
+QString NmakeMakefileGenerator::var(const ProKey &value) const
{
if (usePCH) {
if ((value == "QMAKE_RUN_CXX_IMP_BATCH"
diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h
index 7a47bb8cec..4d3c69bdd6 100644
--- a/qmake/generators/win32/msvc_nmake.h
+++ b/qmake/generators/win32/msvc_nmake.h
@@ -62,7 +62,7 @@ protected:
virtual QString getPdbTarget();
virtual QString defaultInstall(const QString &t);
virtual QStringList &findDependencies(const QString &file);
- QString var(const ProKey &value);
+ QString var(const ProKey &value) const;
QString precompH, precompObj, precompPch;
bool usePCH;
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index a2a441c6bf..633682baf4 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -1537,7 +1537,7 @@ bool VCLinkerTool::parseOption(const char* option)
AdditionalOptions.append(option);
}
break;
- case 0x379ED25:
+ case 0x379ED25:
case 0x157cf65: // /MACHINE:{AM33|ARM|CEE|IA64|X86|M32R|MIPS|MIPS16|MIPSFPU|MIPSFPU16|MIPSR41XX|PPC|SH3|SH4|SH5|THUMB|TRICORE}
switch (elfHash(option+9)) {
// Very limited documentation on all options but X86,
@@ -1667,7 +1667,7 @@ bool VCLinkerTool::parseOption(const char* option)
else
AdditionalOptions += option;
break;
- case 0x9B3C00D:
+ case 0x9B3C00D:
case 0x78dc00d: // /SUBSYSTEM:{CONSOLE|EFI_APPLICATION|EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|NATIVE|POSIX|WINDOWS|WINDOWSCE}[,major[.minor]]
{
// Split up in subsystem, and version number
@@ -2253,7 +2253,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
CustomBuildTool.Description.clear();
CustomBuildTool.Outputs.clear();
CustomBuildTool.ToolPath.clear();
- CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
+ CustomBuildTool.ToolName = QLatin1String(_VCCustomBuildTool);
for (int x = 0; x < extraCompilers.count(); ++x) {
const QString &extraCompilerName = extraCompilers.at(x);
@@ -2291,13 +2291,13 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
}
// Dependency for the output
- if(!tmp_dep.isEmpty())
- deps = tmp_dep;
- if(!tmp_dep_cmd.isEmpty()) {
+ if (!tmp_dep.isEmpty())
+ deps = tmp_dep;
+ if (!tmp_dep_cmd.isEmpty()) {
// Execute dependency command, and add every line as a dep
- char buff[256];
- QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
- Option::fixPathToLocalOS(inFile, true, false),
+ char buff[256];
+ QString dep_cmd = Project->replaceExtraCompilerVariables(tmp_dep_cmd,
+ Option::fixPathToLocalOS(inFile, true, false),
out);
if(Project->canExecute(dep_cmd)) {
dep_cmd.prepend(QLatin1String("cd ")
@@ -2324,7 +2324,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
}
}
for (int i = 0; i < deps.count(); ++i)
- deps[i] = Option::fixPathToTargetOS(
+ deps[i] = Option::fixPathToTargetOS(
Project->replaceExtraCompilerVariables(deps.at(i), inFile, out),
false).trimmed();
// Command for file
@@ -2353,18 +2353,18 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
out);
}
// Name for command
- if(!tmp_cmd_name.isEmpty()) {
- cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
- } else {
- int space = cmd.indexOf(' ');
- if(space != -1)
- cmd_name = cmd.left(space);
- else
- cmd_name = cmd;
- if((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
- cmd_name[0] == cmd_name[cmd_name.length()-1])
- cmd_name = cmd_name.mid(1,cmd_name.length()-2);
- }
+ if (!tmp_cmd_name.isEmpty()) {
+ cmd_name = Project->replaceExtraCompilerVariables(tmp_cmd_name, inFile, out);
+ } else {
+ int space = cmd.indexOf(' ');
+ if (space != -1)
+ cmd_name = cmd.left(space);
+ else
+ cmd_name = cmd;
+ if ((cmd_name[0] == '\'' || cmd_name[0] == '"') &&
+ cmd_name[0] == cmd_name[cmd_name.length()-1])
+ cmd_name = cmd_name.mid(1,cmd_name.length()-2);
+ }
// Fixify paths
for (int i = 0; i < deps.count(); ++i)
@@ -2799,6 +2799,12 @@ void VCProjectWriter::write(XmlOutput &xml, const VCDeploymentTool &tool)
<< closetag(tool.DeploymentTag);
}
+void VCProjectWriter::write(XmlOutput &xml, const VCWinDeployQtTool &tool)
+{
+ Q_UNUSED(xml);
+ Q_UNUSED(tool);
+}
+
void VCProjectWriter::write(XmlOutput &xml, const VCConfiguration &tool)
{
xml << tag(_Configuration)
diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h
index 58b528301c..0aa5736d2a 100644
--- a/qmake/generators/win32/msvc_objectmodel.h
+++ b/qmake/generators/win32/msvc_objectmodel.h
@@ -860,6 +860,24 @@ public:
~VCPreLinkEventTool(){}
};
+class VCWinDeployQtTool : public VCToolBase
+{
+public:
+ VCWinDeployQtTool() {}
+ ~VCWinDeployQtTool() {}
+
+protected:
+ bool parseOption(const char *) { return false; }
+
+public:
+ // Variables
+ QString Record;
+ QString CommandLine;
+ bool ExcludedFromBuild;
+
+ VCConfiguration * config;
+};
+
class VCConfiguration
{
public:
@@ -900,6 +918,7 @@ public:
VCDeploymentTool deployment;
VCPreLinkEventTool preLink;
VCResourceCompilerTool resource;
+ VCWinDeployQtTool windeployqt;
};
struct VCFilterFile
@@ -955,7 +974,7 @@ public:
VCConfiguration* Config;
QList<VCFilterFile> Files;
- customBuildCheck CustomBuild;
+ customBuildCheck CustomBuild;
bool useCustomBuildTool;
VCCustomBuildTool CustomBuildTool;
@@ -990,6 +1009,7 @@ public:
QString SccProjectName;
QString SccLocalPath;
QString PlatformName;
+ QString SdkVersion;
// XML sub-parts
VCConfiguration Configuration;
@@ -1129,6 +1149,7 @@ public:
QString SccProjectName;
QString SccLocalPath;
QString PlatformName;
+ QString SdkVersion;
// Single projects
QList<VCProjectSingleConfig> SingleProjects;
@@ -1154,6 +1175,7 @@ public:
virtual void write(XmlOutput &, const VCResourceCompilerTool &);
virtual void write(XmlOutput &, const VCEventTool &);
virtual void write(XmlOutput &, const VCDeploymentTool &);
+ virtual void write(XmlOutput &, const VCWinDeployQtTool &);
virtual void write(XmlOutput &, const VCConfiguration &);
virtual void write(XmlOutput &, VCFilter &);
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index f86c8512d4..ce9dc6d9ec 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -111,9 +111,10 @@ QT_END_NAMESPACE
#endif
QT_BEGIN_NAMESPACE
-DotNET which_dotnet_version()
+DotNET which_dotnet_version(const QByteArray &preferredVersion = QByteArray())
{
#ifndef Q_OS_WIN32
+ Q_UNUSED(preferredVersion);
return NET2002; // Always generate 7.0 versions on other platforms
#else
// Only search for the version once
@@ -135,6 +136,10 @@ DotNET which_dotnet_version()
installPaths.insert(lowestInstalledVersion->version, path);
++installed;
current_version = lowestInstalledVersion->version;
+ if (QByteArray(lowestInstalledVersion->versionStr).contains(preferredVersion)) {
+ installed = 1;
+ break;
+ }
}
}
@@ -286,6 +291,7 @@ bool VcprojGenerator::writeProjectMakefile()
mergedProjects.at(0)->writePrlFile();
mergedProject.Name = project->first("QMAKE_PROJECT_NAME").toQString();
mergedProject.Version = mergedProjects.at(0)->vcProject.Version;
+ mergedProject.SdkVersion = mergedProjects.at(0)->vcProject.SdkVersion;
mergedProject.ProjectGUID = project->isEmpty("QMAKE_UUID") ? getProjectUUID().toString().toUpper() : project->first("QMAKE_UUID").toQString();
mergedProject.Keyword = project->first("VCPROJ_KEYWORD").toQString();
mergedProject.SccProjectName = mergedProjects.at(0)->vcProject.SccProjectName;
@@ -585,7 +591,7 @@ void VcprojGenerator::writeSubDirs(QTextStream &t)
return;
}
- switch(which_dotnet_version()) {
+ switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) {
case NET2013:
t << _slnHeader120;
break;
@@ -874,12 +880,12 @@ void VcprojGenerator::initProject()
// Own elements -----------------------------
vcProject.Name = unescapeFilePath(project->first("QMAKE_ORIG_TARGET").toQString());
- switch(which_dotnet_version()) {
+ switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) {
case NET2013:
- vcProject.Version = "13.00";
+ vcProject.Version = "12.00";
break;
case NET2012:
- vcProject.Version = "12.00";
+ vcProject.Version = "11.00";
break;
case NET2010:
vcProject.Version = "10.00";
@@ -912,6 +918,7 @@ void VcprojGenerator::initProject()
} else {
vcProject.PlatformName = project->values("CE_SDK").join(' ') + " (" + project->first("CE_ARCH") + ")";
}
+ vcProject.SdkVersion = project->first("WINSDK_VER").toQString();
// These are not used by Qt, but may be used by customers
vcProject.SccProjectName = project->first("SCCPROJECTNAME").toQString();
vcProject.SccLocalPath = project->first("SCCLOCALPATH").toQString();
@@ -924,7 +931,7 @@ void VcprojGenerator::initConfiguration()
// - Do this first since main configuration elements may need
// - to know of certain compiler/linker options
VCConfiguration &conf = vcProject.Configuration;
- conf.CompilerVersion = which_dotnet_version();
+ conf.CompilerVersion = which_dotnet_version(project->first("MSVC_VER").toLatin1());
initCompilerTool();
@@ -970,8 +977,13 @@ void VcprojGenerator::initConfiguration()
if (conf.CompilerVersion >= NET2012) {
conf.WinRT = project->isActiveConfig("winrt");
- if (conf.WinRT)
+ if (conf.WinRT) {
conf.WinPhone = project->isActiveConfig("winphone");
+ // Saner defaults
+ conf.compiler.UsePrecompiledHeader = pchNone;
+ conf.compiler.CompileAsWinRT = _False;
+ conf.linker.GenerateWindowsMetadata = _False;
+ }
}
conf.Name = project->values("BUILD_NAME").join(' ');
@@ -988,7 +1000,7 @@ void VcprojGenerator::initConfiguration()
conf.ATLMinimizesCRunTimeLibraryUsage = (project->first("ATLMinimizesCRunTimeLibraryUsage").isEmpty() ? _False : _True);
conf.BuildBrowserInformation = triState(temp.isEmpty() ? (short)unset : temp.toShort());
temp = project->first("CharacterSet");
- conf.CharacterSet = charSet(temp.isEmpty() ? (short)charSetNotSet : temp.toShort());
+ conf.CharacterSet = charSet(temp.isEmpty() ? short(conf.WinRT ? charSetUnicode : charSetNotSet) : temp.toShort());
conf.DeleteExtensionsOnClean = project->first("DeleteExtensionsOnClean").toQString();
conf.ImportLibrary = conf.linker.ImportLibrary;
conf.IntermediateDirectory = project->first("OBJECTS_DIR").toQString();
@@ -1009,6 +1021,7 @@ void VcprojGenerator::initConfiguration()
if ((!project->isHostBuild() && !project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH"))
|| conf.WinRT)
initDeploymentTool();
+ initWinDeployQtTool();
initPreLinkEventTools();
if (!isDebug)
@@ -1311,6 +1324,22 @@ void VcprojGenerator::initDeploymentTool()
}
}
+void VcprojGenerator::initWinDeployQtTool()
+{
+ VCConfiguration &conf = vcProject.Configuration;
+ conf.windeployqt.ExcludedFromBuild = true;
+ if (project->isActiveConfig("windeployqt")) {
+ conf.windeployqt.Record = QStringLiteral("$(TargetName).windeployqt.$(Platform).$(Configuration)");
+ conf.windeployqt.CommandLine =
+ MakefileGenerator::shellQuote(QDir::toNativeSeparators(project->first("QMAKE_WINDEPLOYQT").toQString()))
+ + QLatin1Char(' ') + project->values("WINDEPLOYQT_OPTIONS").join(QLatin1Char(' '))
+ + QStringLiteral(" -list relative -dir \"$(MSBuildProjectDirectory)\" \"$(OutDir)\\$(TargetName).exe\" > ")
+ + MakefileGenerator::shellQuote(conf.windeployqt.Record);
+ conf.windeployqt.config = &vcProject.Configuration;
+ conf.windeployqt.ExcludedFromBuild = false;
+ }
+}
+
void VcprojGenerator::initPreLinkEventTools()
{
VCConfiguration &conf = vcProject.Configuration;
diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h
index d531085307..4a25d11766 100644
--- a/qmake/generators/win32/msvc_vcproj.h
+++ b/qmake/generators/win32/msvc_vcproj.h
@@ -109,6 +109,7 @@ protected:
void initPreBuildEventTools();
void initPostBuildEventTools();
void initDeploymentTool();
+ void initWinDeployQtTool();
void initPreLinkEventTools();
void initRootFiles();
void initSourceFiles();
diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp
index 30d28e6e11..484062d56e 100644
--- a/qmake/generators/win32/winmakefile.cpp
+++ b/qmake/generators/win32/winmakefile.cpp
@@ -89,12 +89,12 @@ Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem
QRegExp regx(QString("((lib)?%1([0-9]*)).(%2|prl)$").arg(stem).arg(ext), Qt::CaseInsensitive);
for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) {
if(regx.exactMatch((*it))) {
- if (!regx.cap(3).isEmpty()) {
- bool ok = true;
- int num = regx.cap(3).toInt(&ok);
- biggest = qMax(biggest, (!ok ? -1 : num));
- }
- }
+ if (!regx.cap(3).isEmpty()) {
+ bool ok = true;
+ int num = regx.cap(3).toInt(&ok);
+ biggest = qMax(biggest, (!ok ? -1 : num));
+ }
+ }
}
}
if(libInfoRead
@@ -485,20 +485,20 @@ void Win32MakefileGenerator::processRcFileVar()
rcFile.close();
}
if (writeRcFile) {
- bool ok;
- ok = rcFile.open(QFile::WriteOnly);
- if (!ok) {
- // The file can't be opened... try creating the containing
- // directory first (needed for clean shadow builds)
- QDir().mkpath(QFileInfo(rcFile).path());
- ok = rcFile.open(QFile::WriteOnly);
- }
- if (!ok) {
- ::fprintf(stderr, "Cannot open for writing: %s", rcFile.fileName().toLatin1().constData());
- ::exit(1);
- }
- rcFile.write(rcString);
- rcFile.close();
+ bool ok;
+ ok = rcFile.open(QFile::WriteOnly);
+ if (!ok) {
+ // The file can't be opened... try creating the containing
+ // directory first (needed for clean shadow builds)
+ QDir().mkpath(QFileInfo(rcFile).path());
+ ok = rcFile.open(QFile::WriteOnly);
+ }
+ if (!ok) {
+ ::fprintf(stderr, "Cannot open for writing: %s", rcFile.fileName().toLatin1().constData());
+ ::exit(1);
+ }
+ rcFile.write(rcString);
+ rcFile.close();
}
if (project->values("QMAKE_WRITE_DEFAULT_RC").isEmpty())
project->values("RC_FILE").insert(0, rcFile.fileName());
@@ -530,7 +530,7 @@ void Win32MakefileGenerator::processRcFileVar()
}
project->values("RES_FILE").first() = Option::fixPathToTargetOS(
project->values("RES_FILE").first().toQString(), false, false);
- project->values("POST_TARGETDEPS") += project->values("RES_FILE");
+ project->values("POST_TARGETDEPS") += project->values("RES_FILE");
project->values("CLEAN_FILES") += project->values("RES_FILE");
}
}
@@ -565,7 +565,7 @@ void Win32MakefileGenerator::writeCleanParts(QTextStream &t)
}
t << endl << endl;
- t << "distclean: clean";
+ t << "distclean: clean " << var("DISTCLEAN_DEPS");
{
const char *clean_targets[] = { "QMAKE_DISTCLEAN", 0 };
for(int i = 0; clean_targets[i]; ++i) {
diff --git a/qmake/option.cpp b/qmake/option.cpp
index 7b93144d82..a2bd938666 100644
--- a/qmake/option.cpp
+++ b/qmake/option.cpp
@@ -329,9 +329,9 @@ Option::init(int argc, char **argv)
globals->qmake_abslocation = argv0;
} else if (argv0.contains(QLatin1Char('/'))
#ifdef Q_OS_WIN
- || argv0.contains(QLatin1Char('\\'))
+ || argv0.contains(QLatin1Char('\\'))
#endif
- ) { //relative PWD
+ ) { //relative PWD
globals->qmake_abslocation = QDir::current().absoluteFilePath(argv0);
} else { //in the PATH
QByteArray pEnv = qgetenv("PATH");
diff --git a/qmake/project.h b/qmake/project.h
index 26037bb912..fc203c4d7d 100644
--- a/qmake/project.h
+++ b/qmake/project.h
@@ -57,6 +57,7 @@ public:
bool read(const QString &project, LoadFlags what = LoadAll);
QString projectFile() const { return m_projectFile; }
+ QString sourceRoot() const { return m_sourceRoot.isEmpty() ? m_buildRoot : m_sourceRoot; }
QString buildRoot() const { return m_buildRoot; }
QString confFile() const { return m_conffile; }
QString cacheFile() const { return m_cachefile; }
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index 661b787a55..acc9975843 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -67,6 +67,7 @@ bootstrap { #Qt code
qtextcodec.cpp \
qutfcodec.cpp \
qstring.cpp \
+ qstring_compat.cpp \
qstringlist.cpp \
qtemporaryfile.cpp \
qtextstream.cpp \
@@ -149,7 +150,7 @@ bootstrap { #Qt code
SOURCES += qfilesystemengine_win.cpp qfsfileengine_win.cpp qfilesystemiterator_win.cpp qsettings_win.cpp \
qsystemlibrary.cpp qlocale_win.cpp registry.cpp
win32-msvc*:LIBS += ole32.lib advapi32.lib
- win32-g++*:LIBS += -lole32 -luuid -ladvapi32 -lkernel32
+ mingw:LIBS += -lole32 -luuid -ladvapi32 -lkernel32
}
qnx {
diff --git a/qtbase.pro b/qtbase.pro
index 140a137099..1cd82bbc84 100644
--- a/qtbase.pro
+++ b/qtbase.pro
@@ -32,6 +32,7 @@ unix {
(cd config.tests/unix/libjpeg && $(MAKE) distclean); \
(cd config.tests/unix/libpng && $(MAKE) distclean); \
(cd config.tests/unix/slog2 && $(MAKE) distclean); \
+ (cd config.tests/unix/lgmon && $(MAKE) distclean); \
(cd config.tests/x11/xcursor && $(MAKE) distclean); \
(cd config.tests/x11/xrender && $(MAKE) distclean); \
(cd config.tests/x11/xrandr && $(MAKE) distclean); \
diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
index 34283f2e90..eb15ae569d 100644
--- a/src/3rdparty/angle/include/EGL/eglplatform.h
+++ b/src/3rdparty/angle/include/EGL/eglplatform.h
@@ -67,7 +67,15 @@
* implementations.
*/
-#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
+
+struct IUnknown;
+
+typedef int EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef IUnknown *EGLNativeWindowType;
+
+#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
index d8bb1a797c..60177d5fe5 100644
--- a/src/3rdparty/angle/src/compiler/osinclude.h
+++ b/src/3rdparty/angle/src/compiler/osinclude.h
@@ -13,27 +13,26 @@
//
#if defined(_WIN32) || defined(_WIN64)
+#define STRICT
+#define VC_EXTRALEAN 1
+#include <windows.h>
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define ANGLE_OS_WINRT
+#else
#define ANGLE_OS_WIN
+#endif
#elif defined(__APPLE__) || defined(__linux__) || \
defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun) || defined(ANDROID) || \
defined(__GLIBC__) || defined(__GNU__) || \
defined(__QNX__)
#define ANGLE_OS_POSIX
-#else
-#error Unsupported platform.
-#endif
-
-#if defined(ANGLE_OS_WIN)
-#define STRICT
-#define VC_EXTRALEAN 1
-#include <windows.h>
-#elif defined(ANGLE_OS_POSIX)
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
-#endif // ANGLE_OS_WIN
-
+#else
+#error Unsupported platform.
+#endif
#include "compiler/debug.h"
@@ -43,23 +42,17 @@
#if defined(ANGLE_OS_WIN)
typedef DWORD OS_TLSIndex;
#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
+#elif defined(ANGLE_OS_WINRT)
+typedef size_t OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX ((DWORD)0xFFFFFF)
#elif defined(ANGLE_OS_POSIX)
typedef pthread_key_t OS_TLSIndex;
#define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
#endif // ANGLE_OS_WIN
OS_TLSIndex OS_AllocTLSIndex();
+void *OS_GetTLSValue(OS_TLSIndex nIndex);
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
-{
- ASSERT(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_OS_WIN)
- return TlsGetValue(nIndex);
-#elif defined(ANGLE_OS_POSIX)
- return pthread_getspecific(nIndex);
-#endif // ANGLE_OS_WIN
-}
-
#endif // __OSINCLUDE_H
diff --git a/src/3rdparty/angle/src/compiler/ossource_posix.cpp b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
index 1e1e699aeb..35510c1af5 100644
--- a/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+++ b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
@@ -33,6 +33,14 @@ OS_TLSIndex OS_AllocTLSIndex()
}
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+
+ return pthread_getspecific(nIndex);
+}
+
+
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
{
if (nIndex == OS_INVALID_TLS_INDEX) {
diff --git a/src/3rdparty/angle/src/compiler/ossource_win.cpp b/src/3rdparty/angle/src/compiler/ossource_win.cpp
index 89922fef3f..708a1ad311 100644
--- a/src/3rdparty/angle/src/compiler/ossource_win.cpp
+++ b/src/3rdparty/angle/src/compiler/ossource_win.cpp
@@ -29,6 +29,14 @@ OS_TLSIndex OS_AllocTLSIndex()
}
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+
+ return TlsGetValue(nIndex);
+}
+
+
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
{
if (nIndex == OS_INVALID_TLS_INDEX) {
diff --git a/src/3rdparty/angle/src/compiler/ossource_winrt.cpp b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
new file mode 100644
index 0000000000..84443abc02
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/osinclude.h"
+//
+// This file contains contains Windows Runtime specific functions
+//
+
+#if !defined(ANGLE_OS_WINRT)
+#error Trying to build a WinRT specific file in a non-WinRT build.
+#endif
+
+#include <vector>
+
+
+//
+// Thread Local Storage Operations
+//
+__declspec(thread) std::vector<void *> *tls = nullptr;
+__declspec(thread) std::vector<OS_TLSIndex> *freeIndices = nullptr;
+
+OS_TLSIndex OS_AllocTLSIndex()
+{
+ if (!tls)
+ tls = new std::vector<void*>;
+
+ if (freeIndices && !freeIndices->empty()) {
+ OS_TLSIndex index = freeIndices->back();
+ freeIndices->pop_back();
+ return index;
+ } else {
+ tls->push_back(nullptr);
+ return tls->size() - 1;
+ }
+}
+
+
+void *OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+ ASSERT(tls);
+
+ return tls->at(nIndex);
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
+ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
+ return false;
+ }
+
+ tls->at(nIndex) = lpvValue;
+ return true;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
+ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
+ return false;
+ }
+
+ if (!freeIndices)
+ freeIndices = new std::vector<OS_TLSIndex>;
+
+ freeIndices->push_back(nIndex);
+
+ return true;
+}
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
index 82b48cedcf..b18a876a55 100644
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
@@ -186,7 +186,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
-EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
+EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
{
const Config *configuration = mConfigSet.get(config);
EGLint postSubBufferSupported = EGL_FALSE;
@@ -456,7 +456,7 @@ bool Display::isValidSurface(egl::Surface *surface)
return mSurfaceSet.find(surface) != mSurfaceSet.end();
}
-bool Display::hasExistingWindowSurface(HWND window)
+bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
{
for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
{
@@ -471,7 +471,6 @@ bool Display::hasExistingWindowSurface(HWND window)
void Display::initExtensionString()
{
- HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
bool shareHandleSupported = mRenderer->getShareHandleSupport();
mExtensionString = "";
@@ -487,10 +486,13 @@ void Display::initExtensionString()
mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+#if !defined(ANGLE_OS_WINRT)
+ HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
if (swiftShader)
{
mExtensionString += "EGL_ANGLE_software_display ";
}
+#endif
if (shareHandleSupported)
{
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
index 58c3940331..5d55410440 100644
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ b/src/3rdparty/angle/src/libEGL/Display.h
@@ -40,7 +40,7 @@ class Display
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
+ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
@@ -51,7 +51,7 @@ class Display
bool isValidConfig(EGLConfig config);
bool isValidContext(gl::Context *context);
bool isValidSurface(egl::Surface *surface);
- bool hasExistingWindowSurface(HWND window);
+ bool hasExistingWindowSurface(EGLNativeWindowType window);
rx::Renderer *getRenderer() { return mRenderer; };
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
index 83fbbf5b07..dbff159d0e 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
@@ -22,10 +22,15 @@
#include <algorithm>
+#if defined(ANGLE_OS_WINRT)
+#include <windows.foundation.h>
+#include <windows.ui.core.h>
+#endif
+
namespace egl
{
-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
+Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
mRenderer = mDisplay->getRenderer();
@@ -98,6 +103,7 @@ bool Surface::resetSwapChain()
if (mWindow)
{
+#if !defined(ANGLE_OS_WINRT)
RECT windowRect;
if (!GetClientRect(getWindowHandle(), &windowRect))
{
@@ -109,6 +115,19 @@ bool Surface::resetSwapChain()
width = windowRect.right - windowRect.left;
height = windowRect.bottom - windowRect.top;
+#else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
+ if (FAILED(result))
+ {
+ ASSERT(false);
+ return false;
+ }
+ window->get_Bounds(&windowRect);
+ width = windowRect.Width;
+ height = windowRect.Height;
+#endif
}
else
{
@@ -228,7 +247,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
return true;
}
-HWND Surface::getWindowHandle()
+EGLNativeWindowType Surface::getWindowHandle()
{
return mWindow;
}
@@ -237,6 +256,7 @@ HWND Surface::getWindowHandle()
#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+#if !defined(ANGLE_OS_WINRT)
static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
if (message == WM_SIZE)
@@ -250,9 +270,13 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
}
+#endif
void Surface::subclassWindow()
{
+#if defined(ANGLE_OS_WINRT)
+ mWindowSubclassed = false;
+#else
if (!mWindow)
{
return;
@@ -276,10 +300,12 @@ void Surface::subclassWindow()
SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
mWindowSubclassed = true;
+#endif
}
void Surface::unsubclassWindow()
{
+#if !defined(ANGLE_OS_WINRT)
if(!mWindowSubclassed)
{
return;
@@ -302,10 +328,12 @@ void Surface::unsubclassWindow()
RemoveProp(mWindow, kSurfaceProperty);
RemoveProp(mWindow, kParentWndProc);
mWindowSubclassed = false;
+#endif
}
bool Surface::checkForOutOfDateSwapChain()
{
+#if !defined(ANGLE_OS_WINRT)
RECT client;
if (!GetClientRect(getWindowHandle(), &client))
{
@@ -316,6 +344,19 @@ bool Surface::checkForOutOfDateSwapChain()
// Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
int clientWidth = client.right - client.left;
int clientHeight = client.bottom - client.top;
+#else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
+ if (FAILED(result))
+ {
+ ASSERT(false);
+ return false;
+ }
+ window->get_Bounds(&windowRect);
+ int clientWidth = windowRect.Width;
+ int clientHeight = windowRect.Height;
+#endif
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
if (mSwapIntervalDirty)
diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
index 938b800cdd..ae9a380858 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
@@ -15,6 +15,7 @@
#include <EGL/egl.h>
#include "common/angleutils.h"
+#include "windows.h"
namespace gl
{
@@ -34,7 +35,7 @@ class Config;
class Surface
{
public:
- Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
+ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported);
Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
~Surface();
@@ -43,7 +44,7 @@ class Surface
void release();
bool resetSwapChain();
- HWND getWindowHandle();
+ EGLNativeWindowType getWindowHandle();
bool swap();
bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
@@ -79,7 +80,7 @@ private:
bool resetSwapChain(int backbufferWidth, int backbufferHeight);
bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
- const HWND mWindow; // Window that the surface is created for.
+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index 6e10c3926d..5bcb5d5959 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -308,14 +308,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
return EGL_NO_SURFACE;
}
+#if !defined(ANGLE_OS_WINRT)
HWND window = (HWND)win;
if (!IsWindow(window))
{
return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
+#endif
- return display->createWindowSurface(window, config, attrib_list);
+ return display->createWindowSurface(win, config, attrib_list);
}
catch(std::bad_alloc&)
{
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index 7dea5fc74b..964b4b21fd 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -1,3 +1,4 @@
+#include "../libGLESv2/precompiled.h"
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -12,7 +13,13 @@
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+#if !defined(ANGLE_OS_WINRT)
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+#else
+static __declspec(thread) void *currentTLS = 0;
+#endif
+
+namespace egl { Current *getCurrent(); }
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
@@ -35,22 +42,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
}
#endif
+#if !defined(ANGLE_OS_WINRT)
currentTLS = TlsAlloc();
if (currentTLS == TLS_OUT_OF_INDEXES)
{
return FALSE;
}
+#endif
}
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
TlsSetValue(currentTLS, current);
-
+#endif
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
current->display = EGL_NO_DISPLAY;
@@ -61,24 +71,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+#endif
}
}
break;
case DLL_PROCESS_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ egl::Current *current = egl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
}
TlsFree(currentTLS);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+ }
+#endif
}
break;
default:
@@ -95,7 +116,16 @@ namespace egl
Current *getCurrent()
{
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- return (Current*)TlsGetValue(currentTLS);
+#if !defined(ANGLE_OS_WINRT)
+ Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
+ return current;
+#else
+ if (!currentTLS)
+ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
+ return (Current*)currentTLS;
+#endif
#else
// No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
static Current curr = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
index c007d5d9e9..40baa95760 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
@@ -37,11 +37,11 @@ Buffer::~Buffer()
delete mStaticIndexBuffer;
}
-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target)
{
mBufferStorage->clear();
mIndexRangeCache.clear();
- mBufferStorage->setData(data, size, 0);
+ mBufferStorage->setData(data, size, 0, target);
mUsage = usage;
@@ -54,9 +54,9 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
}
}
-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
+void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target)
{
- mBufferStorage->setData(data, size, offset);
+ mBufferStorage->setData(data, size, offset, target);
mIndexRangeCache.invalidateRange(offset, size);
if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
index 4048f4b906..9b86b9791f 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
@@ -33,8 +33,8 @@ class Buffer : public RefCountObject
virtual ~Buffer();
- void bufferData(const void *data, GLsizeiptr size, GLenum usage);
- void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
+ void bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target);
+ void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target);
GLenum usage() const;
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 320bbccc27..91719f8e6d 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -758,7 +758,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
return gl::error(GL_INVALID_OPERATION);
}
- buffer->bufferData(data, size, usage);
+ buffer->bufferData(data, size, usage, target);
}
}
catch(std::bad_alloc&)
@@ -812,7 +812,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
return gl::error(GL_INVALID_VALUE);
}
- buffer->bufferSubData(data, size, offset);
+ buffer->bufferSubData(data, size, offset, target);
}
}
catch(std::bad_alloc&)
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 730a6ac022..defdf35f77 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -13,7 +13,13 @@
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+#if !defined(ANGLE_OS_WINRT)
static DWORD currentTLS = TLS_OUT_OF_INDEXES;
+#else
+static __declspec(thread) void *currentTLS = 0;
+#endif
+
+namespace gl { Current *getCurrent(); }
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
@@ -21,22 +27,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
{
case DLL_PROCESS_ATTACH:
{
+#if !defined(ANGLE_OS_WINRT)
currentTLS = TlsAlloc();
if (currentTLS == TLS_OUT_OF_INDEXES)
{
return FALSE;
}
+#endif
}
// Fall throught to initialize index
case DLL_THREAD_ATTACH:
{
- gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
TlsSetValue(currentTLS, current);
-
+#endif
current->context = NULL;
current->display = NULL;
}
@@ -44,24 +53,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
break;
case DLL_THREAD_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+#endif
}
}
break;
case DLL_PROCESS_DETACH:
{
- void *current = TlsGetValue(currentTLS);
+ gl::Current *current = gl::getCurrent();
if (current)
{
+#if !defined(ANGLE_OS_WINRT)
LocalFree((HLOCAL)current);
}
TlsFree(currentTLS);
+#else
+ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
+ currentTLS = 0;
+ }
+#endif
}
break;
default:
@@ -78,7 +98,16 @@ namespace gl
Current *getCurrent()
{
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
- return (Current*)TlsGetValue(currentTLS);
+#if !defined(ANGLE_OS_WINRT)
+ Current *current = (Current*)TlsGetValue(currentTLS);
+ if (!current)
+ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
+ return current;
+#else
+ if (!currentTLS)
+ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
+ return (Current*)currentTLS;
+#endif
#else
// No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
static gl::Current curr = { 0, 0 };
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
index 50dec6b084..823d27bb60 100644
--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
+++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
@@ -32,13 +32,28 @@
#include <unordered_map>
#include <vector>
+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
+#define ANGLE_OS_WINRT
+#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
+#define ANGLE_OS_WINPHONE
+#endif
+#endif
+
#ifndef ANGLE_ENABLE_D3D11
#include <d3d9.h>
#else
+#if !defined(ANGLE_OS_WINRT)
#include <D3D11.h>
+#else
+#include <d3d11_1.h>
+#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE)
+#define GetVersion() WINVER
+#endif
#include <dxgi.h>
#endif
+#ifndef ANGLE_OS_WINPHONE
#include <D3Dcompiler.h>
+#endif
#ifdef _MSC_VER
#include <hash_map>
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
index ace1a11bae..14a8c2765b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
@@ -22,7 +22,7 @@ class BufferStorage
// The data returned is only guaranteed valid until next non-const method.
virtual void *getData() = 0;
- virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0;
+ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target) = 0;
virtual void clear() = 0;
virtual unsigned int getSize() const = 0;
virtual bool supportsDirectBinding() const = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
index 3647d8a898..2f694db061 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
@@ -131,7 +131,7 @@ void *BufferStorage11::getData()
return mResolvedData;
}
-void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
+void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset, unsigned int target)
{
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *context = mRenderer->getDeviceContext();
@@ -201,7 +201,10 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
D3D11_BUFFER_DESC bufferDesc;
bufferDesc.ByteWidth = requiredBufferSize;
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
- bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
+ if (mRenderer->getFeatureLevel() > D3D_FEATURE_LEVEL_9_3)
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
+ else
+ bufferDesc.BindFlags = target == GL_ARRAY_BUFFER ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER;
bufferDesc.CPUAccessFlags = 0;
bufferDesc.MiscFlags = 0;
bufferDesc.StructureByteStride = 0;
@@ -324,7 +327,7 @@ unsigned int BufferStorage11::getSize() const
bool BufferStorage11::supportsDirectBinding() const
{
- return true;
+ return mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0;
}
void BufferStorage11::markBufferUsage()
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
index b62348b0c9..c9489627c3 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
@@ -24,7 +24,7 @@ class BufferStorage11 : public BufferStorage
static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
virtual void *getData();
- virtual void setData(const void* data, unsigned int size, unsigned int offset);
+ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target);
virtual void clear();
virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
index e69e7a8921..57fd29bf80 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
@@ -36,7 +36,7 @@ void *BufferStorage9::getData()
return mMemory;
}
-void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset)
+void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset, unsigned int)
{
if (!mMemory || offset + size > mAllocatedSize)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
index 3e803969bc..82ae577e23 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
@@ -23,7 +23,7 @@ class BufferStorage9 : public BufferStorage
static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
virtual void *getData();
- virtual void setData(const void* data, unsigned int size, unsigned int offset);
+ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target = 0);
virtual void clear();
virtual unsigned int getSize() const;
virtual bool supportsDirectBinding() const;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
index 09c8922d07..81e9e9ecb2 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
@@ -136,7 +136,7 @@ bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width,
mHeight = height;
mInternalFormat = internalformat;
// compute the d3d format that will be used
- mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel());
mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
if (mStagingTexture)
@@ -185,7 +185,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
switch (mInternalFormat)
{
case GL_ALPHA8_EXT:
- loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ if (mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0)
+ loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ else
+ loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
break;
case GL_LUMINANCE8_EXT:
loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
index 66604c4558..36a62adc1c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
@@ -170,7 +170,7 @@ DXGI_FORMAT IndexBuffer11::getIndexFormat() const
{
case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT;
case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT;
- case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT;
+ case GL_UNSIGNED_INT: return mRenderer->get32BitIndexSupport() ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
}
}
@@ -180,4 +180,4 @@ ID3D11Buffer *IndexBuffer11::getBuffer() const
return mBuffer;
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
index b3111af72b..fd388dfe08 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
@@ -387,7 +387,8 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
- samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
+ samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0
+ ? gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset) : FLT_MAX;
ID3D11SamplerState *dx11SamplerState = NULL;
HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
index 21ad223467..39fd0f41f0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
@@ -28,13 +28,18 @@
#define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380)
#endif
-#ifdef __MINGW32__
-
#ifndef D3DCOMPILER_DLL
+#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
+#endif
-//Add define + typedefs for older MinGW-w64 headers (pre 5783)
+#ifndef QT_D3DCOMPILER_DLL
+#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
+#endif
-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
+#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+//Add define + typedefs for older MinGW-w64 headers (pre 5783)
+//Also define these on Windows Phone, which doesn't have a shader compiler
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
@@ -43,9 +48,7 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
-#endif // D3DCOMPILER_DLL
-
-#endif // __MINGW32__
+#endif // __MINGW32__ || ANGLE_OS_WINPHONE
namespace rx
{
@@ -80,8 +83,40 @@ bool Renderer::initializeCompiler()
}
}
#else
- // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
- mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
+ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL
+#if !defined(ANGLE_OS_WINRT)
+ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL");
+ if (!defaultCompiler)
+ defaultCompiler = QT_D3DCOMPILER_DLL;
+#else // !ANGLE_OS_WINRT
+# ifdef _DEBUG
+ const wchar_t *defaultCompiler = L"d3dcompiler_qtd.dll";
+# else
+ const wchar_t *defaultCompiler = L"d3dcompiler_qt.dll";
+# endif
+#endif // ANGLE_OS_WINRT
+
+ const wchar_t *compilerDlls[] = {
+ defaultCompiler,
+ L"d3dcompiler_47.dll",
+ L"d3dcompiler_46.dll",
+ L"d3dcompiler_45.dll",
+ L"d3dcompiler_44.dll",
+ L"d3dcompiler_43.dll",
+ 0
+ };
+
+ // Load the first available known compiler DLL
+ for (int i = 0; compilerDlls[i]; ++i)
+ {
+#if !defined(ANGLE_OS_WINRT)
+ mD3dCompilerModule = LoadLibrary(compilerDlls[i]);
+#else
+ mD3dCompilerModule = LoadPackagedLibrary(compilerDlls[i], NULL);
+#endif
+ if (mD3dCompilerModule)
+ break;
+ }
#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
if (!mD3dCompilerModule)
@@ -225,4 +260,4 @@ void glDestroyRenderer(rx::Renderer *renderer)
delete renderer;
}
-} \ No newline at end of file
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
index 04e877ba9e..ac67c27e71 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
@@ -1,3 +1,4 @@
+#include "../precompiled.h"
//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -13,6 +14,30 @@
#include "libGLESv2/Uniform.h"
#include "libGLESv2/angletypes.h"
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0
+#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1
+#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2
+#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
+#endif
+#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3
+#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
+#endif
+#ifndef D3DCOMPILE_DEBUG
+#define D3DCOMPILE_DEBUG (1 << 0)
+#endif
+#ifndef D3DCOMPILE_SKIP_OPTIMIZATION
+#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
+#endif
+#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL
+#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
+#endif
+#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL
+#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
+#endif
#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
#endif
@@ -107,7 +132,7 @@ class Renderer
virtual void sync(bool block) = 0;
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
index a43101807a..f83e9e91ce 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
@@ -137,6 +137,7 @@ EGLint Renderer11::initialize()
return EGL_NOT_INITIALIZED;
}
+#if !defined(ANGLE_OS_WINRT)
mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
@@ -155,12 +156,17 @@ EGLint Renderer11::initialize()
ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
return EGL_NOT_INITIALIZED;
}
+#endif
D3D_FEATURE_LEVEL featureLevels[] =
{
+ D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3,
+ D3D_FEATURE_LEVEL_9_2,
+ D3D_FEATURE_LEVEL_9_1,
};
HRESULT result = S_OK;
@@ -203,8 +209,12 @@ EGLint Renderer11::initialize()
}
}
+#if !defined(ANGLE_OS_WINRT)
IDXGIDevice *dxgiDevice = NULL;
- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+#else
+ IDXGIDevice1 *dxgiDevice = NULL;
+#endif
+ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
if (FAILED(result))
{
@@ -524,7 +534,7 @@ void Renderer11::sync(bool block)
}
}
-SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
{
return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
}
@@ -1108,6 +1118,43 @@ void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLv
}
}
+template <typename T>
+static void drawLineLoopIndexed(T *data, GLenum type, const GLvoid *indices, GLsizei count)
+{
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+}
+
void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
{
// Get the raw indices for an indexed draw
@@ -1156,59 +1203,71 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
return gl::error(GL_OUT_OF_MEMORY);
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ if (get32BitIndexSupport())
+ drawLineLoopIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, count);
+ else
+ drawLineLoopIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, count);
+
unsigned int indexBufferOffset = offset;
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
+ {
+ IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
+
+ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
+ mAppliedIBSerial = mLineLoopIB->getSerial();
+ mAppliedStorageIBSerial = 0;
+ mAppliedIBOffset = indexBufferOffset;
+ }
+
+ mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
+}
+
+template <typename T>
+static void drawTriangleFanIndexed(T *data, GLenum type, const GLvoid *indices, unsigned int numTris)
+{
switch (type)
{
case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
- data[i] = i;
+ data[i*3 + 0] = 0;
+ data[i*3 + 1] = i + 1;
+ data[i*3 + 2] = i + 2;
}
- data[count] = 0;
break;
case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
- data[i] = static_cast<const GLubyte*>(indices)[i];
+ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
}
- data[count] = static_cast<const GLubyte*>(indices)[0];
break;
case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
- data[i] = static_cast<const GLushort*>(indices)[i];
+ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
}
- data[count] = static_cast<const GLushort*>(indices)[0];
break;
case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
+ for (unsigned int i = 0; i < numTris; i++)
{
- data[i] = static_cast<const GLuint*>(indices)[i];
+ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
}
- data[count] = static_cast<const GLuint*>(indices)[0];
break;
default: UNREACHABLE();
}
-
- if (!mLineLoopIB->unmapBuffer())
- {
- ERR("Could not unmap index buffer for GL_LINE_LOOP.");
- return gl::error(GL_OUT_OF_MEMORY);
- }
-
- if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
- {
- IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
-
- mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
- mAppliedIBSerial = mLineLoopIB->getSerial();
- mAppliedStorageIBSerial = 0;
- mAppliedIBOffset = indexBufferOffset;
- }
-
- mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
}
void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
@@ -1261,45 +1320,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
return gl::error(GL_OUT_OF_MEMORY);
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
- unsigned int indexBufferOffset = offset;
+ if (get32BitIndexSupport())
+ drawTriangleFanIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, numTris);
+ else
+ drawTriangleFanIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, numTris);
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = 0;
- data[i*3 + 1] = i + 1;
- data[i*3 + 2] = i + 2;
- }
- break;
- case GL_UNSIGNED_BYTE:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_SHORT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_INT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
- }
- break;
- default: UNREACHABLE();
- }
+ unsigned int indexBufferOffset = offset;
if (!mTriangleFanIB->unmapBuffer())
{
@@ -1509,7 +1535,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
}
// needed for the point sprite geometry shader
- if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+ if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
{
mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
@@ -1923,9 +1949,13 @@ bool Renderer11::testDeviceResettable()
D3D_FEATURE_LEVEL featureLevels[] =
{
+ D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3,
+ D3D_FEATURE_LEVEL_9_2,
+ D3D_FEATURE_LEVEL_9_1,
};
ID3D11Device* dummyDevice;
@@ -2104,11 +2134,17 @@ float Renderer11::getTextureMaxAnisotropy() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
return D3D11_MAX_MAXANISOTROPY;
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return D3D10_MAX_MAXANISOTROPY;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ return 16;
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
default: UNREACHABLE();
return 0;
}
@@ -2123,11 +2159,17 @@ Range Renderer11::getViewportBounds() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
+ case D3D_FEATURE_LEVEL_9_3:
+ return Range(D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return Range(D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
default: UNREACHABLE();
return Range(0, 0);
}
@@ -2138,10 +2180,15 @@ unsigned int Renderer11::getMaxVertexTextureImageUnits() const
META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
default: UNREACHABLE();
return 0;
}
@@ -2165,15 +2212,41 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const
unsigned int Renderer11::getMaxVertexUniformVectors() const
{
META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
- return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return MAX_VERTEX_UNIFORM_VECTORS_D3D9;
+ default:
+ UNIMPLEMENTED();
+ return 0;
+ }
}
unsigned int Renderer11::getMaxFragmentUniformVectors() const
{
META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
- return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
+ case D3D_FEATURE_LEVEL_9_3:
+ return 221;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 29;
+ default: UNREACHABLE();
+ return 0;
+ }
}
unsigned int Renderer11::getMaxVaryingVectors() const
@@ -2181,11 +2254,17 @@ unsigned int Renderer11::getMaxVaryingVectors() const
META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
return D3D11_VS_OUTPUT_REGISTER_COUNT;
case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_VS_OUTPUT_REGISTER_COUNT;
case D3D_FEATURE_LEVEL_10_0:
return D3D10_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 8;
default: UNREACHABLE();
return 0;
}
@@ -2195,10 +2274,15 @@ bool Renderer11::getNonPower2TextureSupport() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return true;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
default: UNREACHABLE();
return false;
}
@@ -2208,10 +2292,15 @@ bool Renderer11::getOcclusionQuerySupport() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
return true;
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
default: UNREACHABLE();
return false;
}
@@ -2221,10 +2310,15 @@ bool Renderer11::getInstancingSupport() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
return true;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
default: UNREACHABLE();
return false;
}
@@ -2242,10 +2336,15 @@ bool Renderer11::getDerivativeInstructionSupport() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
return true;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
default: UNREACHABLE();
return false;
}
@@ -2261,9 +2360,13 @@ int Renderer11::getMajorShaderModel() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return 4; // SM4 level 9, but treat as 4
default: UNREACHABLE(); return 0;
}
}
@@ -2272,9 +2375,13 @@ int Renderer11::getMinorShaderModel() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return 0;
default: UNREACHABLE(); return 0;
}
}
@@ -2295,11 +2402,17 @@ int Renderer11::getMaxViewportDimension() const
switch (mFeatureLevel)
{
- case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
default: UNREACHABLE();
return 0;
}
@@ -2309,9 +2422,13 @@ int Renderer11::getMaxTextureWidth() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
default: UNREACHABLE(); return 0;
}
}
@@ -2320,9 +2437,13 @@ int Renderer11::getMaxTextureHeight() const
{
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
default: UNREACHABLE(); return 0;
}
}
@@ -2331,9 +2452,13 @@ bool Renderer11::get32BitIndexSupport() const
{
switch (mFeatureLevel)
{
- case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1: return false;
default: UNREACHABLE(); return false;
}
}
@@ -2380,14 +2505,22 @@ unsigned int Renderer11::getMaxRenderTargets() const
{
META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ META_ASSERT(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ META_ASSERT(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
switch (mFeatureLevel)
{
+ case D3D_FEATURE_LEVEL_11_1:
case D3D_FEATURE_LEVEL_11_0:
return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
case D3D_FEATURE_LEVEL_10_1:
case D3D_FEATURE_LEVEL_10_0:
return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; // 4
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; // 1
default:
UNREACHABLE();
return 1;
@@ -2815,7 +2948,7 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
{
- const char *profile = NULL;
+ std::string profile;
switch (type)
{
@@ -2833,7 +2966,12 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
return NULL;
}
- ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+ if (mFeatureLevel == D3D_FEATURE_LEVEL_9_3)
+ profile += "_level_9_3";
+ else if (mFeatureLevel == D3D_FEATURE_LEVEL_9_2 || mFeatureLevel == D3D_FEATURE_LEVEL_9_1)
+ profile += "_level_9_1";
+
+ ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile.c_str(), D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
if (!binary)
return NULL;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
index f024855f97..433945da7a 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
@@ -32,6 +32,7 @@ class StreamingIndexBufferInterface;
enum
{
+ MAX_VERTEX_UNIFORM_VECTORS_D3D9 = 254,
MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
};
@@ -52,7 +53,7 @@ class Renderer11 : public Renderer
virtual void sync(bool block);
- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
@@ -177,6 +178,7 @@ class Renderer11 : public Renderer
ID3D11Device *getDevice() { return mDevice; }
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+ D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }
bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
void unapplyRenderTargets();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
index 14c0515fc8..a6870ebedc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
@@ -18,7 +18,7 @@ namespace rx
class SwapChain
{
public:
- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
: mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
{
}
@@ -33,7 +33,7 @@ class SwapChain
virtual HANDLE getShareHandle() {return mShareHandle;};
protected:
- const HWND mWindow; // Window that the surface is created for.
+ const EGLNativeWindowType mWindow; // Window that the surface is created for.
const GLenum mBackBufferFormat;
const GLenum mDepthBufferFormat;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
index 0da58cbe2e..2fe15ff5b8 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
@@ -17,7 +17,7 @@
namespace rx
{
-SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat)
: mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
{
@@ -468,6 +468,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
if (mWindow)
{
+#if !defined(ANGLE_OS_WINRT)
// We cannot create a swap chain for an HWND that is owned by a different process
DWORD currentProcessId = GetCurrentProcessId();
DWORD wndProcessId;
@@ -491,14 +492,39 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.OutputWindow = mWindow;
+#else
+ IDXGIFactory2 *factory;
+ HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory));
+ ASSERT(SUCCEEDED(result));
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ swapChainDesc.Width = backbufferWidth;
+ swapChainDesc.Height = backbufferHeight;
+ swapChainDesc.Stereo = FALSE;
+#if !defined(ANGLE_OS_WINPHONE)
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+#else
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+#endif
+#endif
+
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.Flags = 0;
- swapChainDesc.OutputWindow = mWindow;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
- swapChainDesc.Windowed = TRUE;
+#if !defined(ANGLE_OS_WINRT)
HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+#else
+ IDXGISwapChain1 *swapChain;
+ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
+ mSwapChain = swapChain;
+#endif
if (FAILED(result))
{
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
index 800104602e..2a030c839d 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
@@ -19,7 +19,7 @@ class Renderer11;
class SwapChain11 : public SwapChain
{
public:
- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
GLenum backBufferFormat, GLenum depthBufferFormat);
virtual ~SwapChain11();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
index 408b48ebab..32a407a988 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
@@ -222,14 +222,14 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
}
TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
{
for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
mRenderTarget[i] = NULL;
}
- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
if (d3d11::IsDepthStencilFormat(convertedFormat))
{
mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
@@ -440,7 +440,7 @@ void TextureStorage11_2D::generateMipmap(int level)
}
TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
{
for (unsigned int i = 0; i < 6; i++)
{
@@ -450,7 +450,7 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLe
}
}
- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
if (d3d11::IsDepthStencilFormat(convertedFormat))
{
mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
index 13800da258..0624a61160 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
@@ -329,7 +329,7 @@ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
return DXGI_FORMAT_R8G8B8A8_UNORM;
}
-DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
+DXGI_FORMAT ConvertTextureFormat(GLenum internalformat, D3D_FEATURE_LEVEL featureLevel)
{
switch (internalformat)
{
@@ -342,7 +342,7 @@ DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
case GL_LUMINANCE8_ALPHA8_EXT:
return DXGI_FORMAT_R8G8B8A8_UNORM;
case GL_ALPHA8_EXT:
- return DXGI_FORMAT_A8_UNORM;
+ return featureLevel >= D3D_FEATURE_LEVEL_10_0 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
return DXGI_FORMAT_BC1_UNORM;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
index 1bc48c1a13..70ad4fea2b 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
@@ -32,7 +32,7 @@ FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
-DXGI_FORMAT ConvertTextureFormat(GLenum format);
+DXGI_FORMAT ConvertTextureFormat(GLenum format, D3D_FEATURE_LEVEL featureLevel);
}
namespace d3d11_gl
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
index 042ac699b6..cb132dc99c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
@@ -12,10 +12,12 @@ struct PS_OutputMultiple
float4 color1 : SV_TARGET1;
float4 color2 : SV_TARGET2;
float4 color3 : SV_TARGET3;
+#ifdef SM4
float4 color4 : SV_TARGET4;
float4 color5 : SV_TARGET5;
float4 color6 : SV_TARGET6;
float4 color7 : SV_TARGET7;
+#endif
};
PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
@@ -25,10 +27,12 @@ PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4
outColor.color1 = inColor;
outColor.color2 = inColor;
outColor.color3 = inColor;
+#ifdef SM4
outColor.color4 = inColor;
outColor.color5 = inColor;
outColor.color6 = inColor;
outColor.color7 = inColor;
+#endif
return outColor;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
index 32df49e672..8fd193b164 100644
--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
@@ -10,6 +10,14 @@
#include "libGLESv2/utilities.h"
#include "libGLESv2/mathutil.h"
+#if defined(ANGLE_OS_WINRT)
+#include <locale>
+#include <codecvt>
+#include <wrl.h>
+#include <windows.storage.h>
+using namespace ABI::Windows::Storage;
+#endif
+
namespace gl
{
@@ -737,7 +745,50 @@ bool IsTriangleMode(GLenum drawMode)
std::string getTempPath()
{
+#if defined(ANGLE_OS_WINRT)
+
+ static std::string path;
+
+ while (path.empty()) {
+ IApplicationDataStatics *applicationDataFactory;
+ HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
+ IID_PPV_ARGS(&applicationDataFactory));
+ if (FAILED(result))
+ break;
+
+ IApplicationData *applicationData;
+ result = applicationDataFactory->get_Current(&applicationData);
+ if (FAILED(result))
+ break;
+
+ IStorageFolder *storageFolder;
+ result = applicationData->get_LocalFolder(&storageFolder);
+ if (FAILED(result))
+ break;
+
+ IStorageItem *localFolder;
+ result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder));
+ if (FAILED(result))
+ break;
+
+ HSTRING localFolderPath;
+ result = localFolder->get_Path(&localFolderPath);
+ if (FAILED(result))
+ break;
+
+ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
+ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
+ if (path.empty())
+ {
+ UNREACHABLE();
+ break;
+ }
+ }
+
+#else
+
char path[MAX_PATH];
+
DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
if (pathLen == 0)
{
@@ -751,6 +802,8 @@ std::string getTempPath()
UNREACHABLE();
return std::string();
}
+
+#endif
return path;
}
diff --git a/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-shape.h b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-shape.h
new file mode 100644
index 0000000000..ac21ff2f8c
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/include/harfbuzz/hb-ot-shape.h
@@ -0,0 +1 @@
+#include "../../src/hb-ot-shape.h"
diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h
index fe9a450533..db706987fe 100644
--- a/src/3rdparty/harfbuzz-ng/src/config.h
+++ b/src/3rdparty/harfbuzz-ng/src/config.h
@@ -14,6 +14,10 @@
# define HB_INTERNAL Q_DECL_HIDDEN
#endif
+#if !defined(QT_NO_DEBUG)
+# define NDEBUG
+#endif
+
// because strdup() is not part of strict Posix, declare it here
extern "C" char *strdup(const char *src);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
index 4541db23bd..263bc81dc4 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -204,7 +204,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
*p++ = '+';
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
- if (pos->y_advance)
+ if (pos[i].y_advance)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
index e445504550..c8bfd8825a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -94,6 +94,7 @@ typedef uint32_t hb_tag_t;
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
#define HB_TAG_NONE HB_TAG(0,0,0,0)
+#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
/* len=-1 means str is NUL-terminated. */
hb_tag_t
@@ -270,7 +271,12 @@ typedef enum
/*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
/* No script set. */
- /*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE
+ /*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE,
+
+ /* Dummy value to ensure any hb_tag_t value can be passed/stored as hb_script_t
+ * without risking undefined behavior. */
+ /*---*/ _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX
+
} hb_script_t;
/* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
new file mode 100644
index 0000000000..5a34eddecc
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
@@ -0,0 +1,840 @@
+/*
+ * Copyright © 2012,2013 Mozilla Foundation.
+ * Copyright © 2012,2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#define HB_SHAPER coretext
+#include "hb-shaper-impl-private.hh"
+
+#include "hb-coretext.h"
+
+#include "hb-face-private.hh"
+#include <private/qfontengine_p.h>
+
+
+#ifndef HB_DEBUG_CORETEXT
+#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
+#endif
+
+
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
+HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
+
+
+/*
+ * shaper face data
+ */
+
+struct hb_coretext_shaper_face_data_t {
+ CGFontRef cg_font;
+};
+
+static void
+release_data (void *info, const void *data, size_t size)
+{
+ assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
+ hb_blob_get_data ((hb_blob_t *) info, NULL) == data);
+
+ hb_blob_destroy ((hb_blob_t *) info);
+}
+
+hb_coretext_shaper_face_data_t *
+_hb_coretext_shaper_face_data_create (hb_face_t *face)
+{
+ hb_blob_t *mort_blob = face->reference_table (HB_CORETEXT_TAG_MORT);
+ /* Umm, we just reference the table to check whether it exists.
+ * Maybe add better API for this? */
+ if (!hb_blob_get_length (mort_blob))
+ {
+ hb_blob_destroy (mort_blob);
+ mort_blob = face->reference_table (HB_CORETEXT_TAG_MORX);
+ if (!hb_blob_get_length (mort_blob))
+ {
+ hb_blob_destroy (mort_blob);
+ return NULL;
+ }
+ }
+ hb_blob_destroy (mort_blob);
+
+ hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t));
+ if (unlikely (!data))
+ return NULL;
+
+ QFontEngine *fe = (QFontEngine *) ((QFontEngine::FaceData *) face->user_data)->user_data;
+ if (fe->type () == QFontEngine::Mac)
+ {
+ data->cg_font = (CGFontRef) fe->userData ().value<void *> ();
+ if (likely (data->cg_font))
+ CFRetain (data->cg_font);
+ }
+ else
+ {
+ hb_blob_t *blob = hb_face_reference_blob (face);
+ unsigned int blob_length;
+ const char *blob_data = hb_blob_get_data (blob, &blob_length);
+ if (unlikely (!blob_length))
+ DEBUG_MSG (CORETEXT, face, "Face has empty blob");
+
+ CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
+ data->cg_font = CGFontCreateWithDataProvider (provider);
+ CGDataProviderRelease (provider);
+ }
+
+ if (unlikely (!data->cg_font)) {
+ DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
+ free (data);
+ return NULL;
+ }
+
+ return data;
+}
+
+void
+_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
+{
+ CFRelease (data->cg_font);
+ free (data);
+}
+
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face)
+{
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
+ hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ return face_data->cg_font;
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_coretext_shaper_font_data_t {
+ CTFontRef ct_font;
+};
+
+hb_coretext_shaper_font_data_t *
+_hb_coretext_shaper_font_data_create (hb_font_t *font)
+{
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL;
+
+ hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) calloc (1, sizeof (hb_coretext_shaper_font_data_t));
+ if (unlikely (!data))
+ return NULL;
+
+ hb_face_t *face = font->face;
+ hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+
+ data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale / 64, NULL, NULL);
+ if (unlikely (!data->ct_font)) {
+ DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
+ free (data);
+ return NULL;
+ }
+
+ return data;
+}
+
+void
+_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
+{
+ CFRelease (data->ct_font);
+ free (data);
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+struct hb_coretext_shaper_shape_plan_data_t {};
+
+hb_coretext_shaper_shape_plan_data_t *
+_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED)
+{
+ return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
+{
+}
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font)
+{
+ if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
+ hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+ return font_data->ct_font;
+}
+
+
+/*
+ * shaper
+ */
+
+struct feature_record_t {
+ unsigned int feature;
+ unsigned int setting;
+};
+
+struct active_feature_t {
+ feature_record_t rec;
+ unsigned int order;
+
+ static int cmp (const active_feature_t *a, const active_feature_t *b) {
+ return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
+ a->order < b->order ? -1 : a->order > b->order ? 1 :
+ a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
+ 0;
+ }
+ bool operator== (const active_feature_t *f) {
+ return cmp (this, f) == 0;
+ }
+};
+
+struct feature_event_t {
+ unsigned int index;
+ bool start;
+ active_feature_t feature;
+
+ static int cmp (const feature_event_t *a, const feature_event_t *b) {
+ return a->index < b->index ? -1 : a->index > b->index ? 1 :
+ a->start < b->start ? -1 : a->start > b->start ? 1 :
+ active_feature_t::cmp (&a->feature, &b->feature);
+ }
+};
+
+struct range_record_t {
+ CTFontRef font;
+ unsigned int index_first; /* == start */
+ unsigned int index_last; /* == end - 1 */
+};
+
+
+/* The following enum members are added in OS X 10.8. */
+#define kAltHalfWidthTextSelector 6
+#define kAltProportionalTextSelector 5
+#define kAlternateHorizKanaOffSelector 1
+#define kAlternateHorizKanaOnSelector 0
+#define kAlternateKanaType 34
+#define kAlternateVertKanaOffSelector 3
+#define kAlternateVertKanaOnSelector 2
+#define kCaseSensitiveLayoutOffSelector 1
+#define kCaseSensitiveLayoutOnSelector 0
+#define kCaseSensitiveLayoutType 33
+#define kCaseSensitiveSpacingOffSelector 3
+#define kCaseSensitiveSpacingOnSelector 2
+#define kContextualAlternatesOffSelector 1
+#define kContextualAlternatesOnSelector 0
+#define kContextualAlternatesType 36
+#define kContextualLigaturesOffSelector 19
+#define kContextualLigaturesOnSelector 18
+#define kContextualSwashAlternatesOffSelector 5
+#define kContextualSwashAlternatesOnSelector 4
+#define kDefaultLowerCaseSelector 0
+#define kDefaultUpperCaseSelector 0
+#define kHistoricalLigaturesOffSelector 21
+#define kHistoricalLigaturesOnSelector 20
+#define kHojoCharactersSelector 12
+#define kJIS2004CharactersSelector 11
+#define kLowerCasePetiteCapsSelector 2
+#define kLowerCaseSmallCapsSelector 1
+#define kLowerCaseType 37
+#define kMathematicalGreekOffSelector 11
+#define kMathematicalGreekOnSelector 10
+#define kNLCCharactersSelector 13
+#define kQuarterWidthTextSelector 4
+#define kScientificInferiorsSelector 4
+#define kStylisticAltEightOffSelector 17
+#define kStylisticAltEightOnSelector 16
+#define kStylisticAltEighteenOffSelector 37
+#define kStylisticAltEighteenOnSelector 36
+#define kStylisticAltElevenOffSelector 23
+#define kStylisticAltElevenOnSelector 22
+#define kStylisticAltFifteenOffSelector 31
+#define kStylisticAltFifteenOnSelector 30
+#define kStylisticAltFiveOffSelector 11
+#define kStylisticAltFiveOnSelector 10
+#define kStylisticAltFourOffSelector 9
+#define kStylisticAltFourOnSelector 8
+#define kStylisticAltFourteenOffSelector 29
+#define kStylisticAltFourteenOnSelector 28
+#define kStylisticAltNineOffSelector 19
+#define kStylisticAltNineOnSelector 18
+#define kStylisticAltNineteenOffSelector 39
+#define kStylisticAltNineteenOnSelector 38
+#define kStylisticAltOneOffSelector 3
+#define kStylisticAltOneOnSelector 2
+#define kStylisticAltSevenOffSelector 15
+#define kStylisticAltSevenOnSelector 14
+#define kStylisticAltSeventeenOffSelector 35
+#define kStylisticAltSeventeenOnSelector 34
+#define kStylisticAltSixOffSelector 13
+#define kStylisticAltSixOnSelector 12
+#define kStylisticAltSixteenOffSelector 33
+#define kStylisticAltSixteenOnSelector 32
+#define kStylisticAltTenOffSelector 21
+#define kStylisticAltTenOnSelector 20
+#define kStylisticAltThirteenOffSelector 27
+#define kStylisticAltThirteenOnSelector 26
+#define kStylisticAltThreeOffSelector 7
+#define kStylisticAltThreeOnSelector 6
+#define kStylisticAltTwelveOffSelector 25
+#define kStylisticAltTwelveOnSelector 24
+#define kStylisticAltTwentyOffSelector 41
+#define kStylisticAltTwentyOnSelector 40
+#define kStylisticAltTwoOffSelector 5
+#define kStylisticAltTwoOnSelector 4
+#define kStylisticAlternativesType 35
+#define kSwashAlternatesOffSelector 3
+#define kSwashAlternatesOnSelector 2
+#define kThirdWidthTextSelector 3
+#define kTraditionalNamesCharactersSelector 14
+#define kUpperCasePetiteCapsSelector 2
+#define kUpperCaseSmallCapsSelector 1
+#define kUpperCaseType 38
+
+/* Table data courtesy of Apple. */
+struct feature_mapping_t {
+ FourCharCode otFeatureTag;
+ uint16_t aatFeatureType;
+ uint16_t selectorToEnable;
+ uint16_t selectorToDisable;
+} feature_mappings[] = {
+ { 'c2pc', kUpperCaseType, kUpperCasePetiteCapsSelector, kDefaultUpperCaseSelector },
+ { 'c2sc', kUpperCaseType, kUpperCaseSmallCapsSelector, kDefaultUpperCaseSelector },
+ { 'calt', kContextualAlternatesType, kContextualAlternatesOnSelector, kContextualAlternatesOffSelector },
+ { 'case', kCaseSensitiveLayoutType, kCaseSensitiveLayoutOnSelector, kCaseSensitiveLayoutOffSelector },
+ { 'clig', kLigaturesType, kContextualLigaturesOnSelector, kContextualLigaturesOffSelector },
+ { 'cpsp', kCaseSensitiveLayoutType, kCaseSensitiveSpacingOnSelector, kCaseSensitiveSpacingOffSelector },
+ { 'cswh', kContextualAlternatesType, kContextualSwashAlternatesOnSelector, kContextualSwashAlternatesOffSelector },
+ { 'dlig', kLigaturesType, kRareLigaturesOnSelector, kRareLigaturesOffSelector },
+ { 'expt', kCharacterShapeType, kExpertCharactersSelector, 16 },
+ { 'frac', kFractionsType, kDiagonalFractionsSelector, kNoFractionsSelector },
+ { 'fwid', kTextSpacingType, kMonospacedTextSelector, 7 },
+ { 'halt', kTextSpacingType, kAltHalfWidthTextSelector, 7 },
+ { 'hist', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector },
+ { 'hkna', kAlternateKanaType, kAlternateHorizKanaOnSelector, kAlternateHorizKanaOffSelector, },
+ { 'hlig', kLigaturesType, kHistoricalLigaturesOnSelector, kHistoricalLigaturesOffSelector },
+ { 'hngl', kTransliterationType, kHanjaToHangulSelector, kNoTransliterationSelector },
+ { 'hojo', kCharacterShapeType, kHojoCharactersSelector, 16 },
+ { 'hwid', kTextSpacingType, kHalfWidthTextSelector, 7 },
+ { 'ital', kItalicCJKRomanType, kCJKItalicRomanOnSelector, kCJKItalicRomanOffSelector },
+ { 'jp04', kCharacterShapeType, kJIS2004CharactersSelector, 16 },
+ { 'jp78', kCharacterShapeType, kJIS1978CharactersSelector, 16 },
+ { 'jp83', kCharacterShapeType, kJIS1983CharactersSelector, 16 },
+ { 'jp90', kCharacterShapeType, kJIS1990CharactersSelector, 16 },
+ { 'liga', kLigaturesType, kCommonLigaturesOnSelector, kCommonLigaturesOffSelector },
+ { 'lnum', kNumberCaseType, kUpperCaseNumbersSelector, 2 },
+ { 'mgrk', kMathematicalExtrasType, kMathematicalGreekOnSelector, kMathematicalGreekOffSelector },
+ { 'nlck', kCharacterShapeType, kNLCCharactersSelector, 16 },
+ { 'onum', kNumberCaseType, kLowerCaseNumbersSelector, 2 },
+ { 'ordn', kVerticalPositionType, kOrdinalsSelector, kNormalPositionSelector },
+ { 'palt', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'pcap', kLowerCaseType, kLowerCasePetiteCapsSelector, kDefaultLowerCaseSelector },
+ { 'pkna', kTextSpacingType, kProportionalTextSelector, 7 },
+ { 'pnum', kNumberSpacingType, kProportionalNumbersSelector, 4 },
+ { 'pwid', kTextSpacingType, kProportionalTextSelector, 7 },
+ { 'qwid', kTextSpacingType, kQuarterWidthTextSelector, 7 },
+ { 'ruby', kRubyKanaType, kRubyKanaOnSelector, kRubyKanaOffSelector },
+ { 'sinf', kVerticalPositionType, kScientificInferiorsSelector, kNormalPositionSelector },
+ { 'smcp', kLowerCaseType, kLowerCaseSmallCapsSelector, kDefaultLowerCaseSelector },
+ { 'smpl', kCharacterShapeType, kSimplifiedCharactersSelector, 16 },
+ { 'ss01', kStylisticAlternativesType, kStylisticAltOneOnSelector, kStylisticAltOneOffSelector },
+ { 'ss02', kStylisticAlternativesType, kStylisticAltTwoOnSelector, kStylisticAltTwoOffSelector },
+ { 'ss03', kStylisticAlternativesType, kStylisticAltThreeOnSelector, kStylisticAltThreeOffSelector },
+ { 'ss04', kStylisticAlternativesType, kStylisticAltFourOnSelector, kStylisticAltFourOffSelector },
+ { 'ss05', kStylisticAlternativesType, kStylisticAltFiveOnSelector, kStylisticAltFiveOffSelector },
+ { 'ss06', kStylisticAlternativesType, kStylisticAltSixOnSelector, kStylisticAltSixOffSelector },
+ { 'ss07', kStylisticAlternativesType, kStylisticAltSevenOnSelector, kStylisticAltSevenOffSelector },
+ { 'ss08', kStylisticAlternativesType, kStylisticAltEightOnSelector, kStylisticAltEightOffSelector },
+ { 'ss09', kStylisticAlternativesType, kStylisticAltNineOnSelector, kStylisticAltNineOffSelector },
+ { 'ss10', kStylisticAlternativesType, kStylisticAltTenOnSelector, kStylisticAltTenOffSelector },
+ { 'ss11', kStylisticAlternativesType, kStylisticAltElevenOnSelector, kStylisticAltElevenOffSelector },
+ { 'ss12', kStylisticAlternativesType, kStylisticAltTwelveOnSelector, kStylisticAltTwelveOffSelector },
+ { 'ss13', kStylisticAlternativesType, kStylisticAltThirteenOnSelector, kStylisticAltThirteenOffSelector },
+ { 'ss14', kStylisticAlternativesType, kStylisticAltFourteenOnSelector, kStylisticAltFourteenOffSelector },
+ { 'ss15', kStylisticAlternativesType, kStylisticAltFifteenOnSelector, kStylisticAltFifteenOffSelector },
+ { 'ss16', kStylisticAlternativesType, kStylisticAltSixteenOnSelector, kStylisticAltSixteenOffSelector },
+ { 'ss17', kStylisticAlternativesType, kStylisticAltSeventeenOnSelector, kStylisticAltSeventeenOffSelector },
+ { 'ss18', kStylisticAlternativesType, kStylisticAltEighteenOnSelector, kStylisticAltEighteenOffSelector },
+ { 'ss19', kStylisticAlternativesType, kStylisticAltNineteenOnSelector, kStylisticAltNineteenOffSelector },
+ { 'ss20', kStylisticAlternativesType, kStylisticAltTwentyOnSelector, kStylisticAltTwentyOffSelector },
+ { 'subs', kVerticalPositionType, kInferiorsSelector, kNormalPositionSelector },
+ { 'sups', kVerticalPositionType, kSuperiorsSelector, kNormalPositionSelector },
+ { 'swsh', kContextualAlternatesType, kSwashAlternatesOnSelector, kSwashAlternatesOffSelector },
+ { 'titl', kStyleOptionsType, kTitlingCapsSelector, kNoStyleOptionsSelector },
+ { 'tnam', kCharacterShapeType, kTraditionalNamesCharactersSelector, 16 },
+ { 'tnum', kNumberSpacingType, kMonospacedNumbersSelector, 4 },
+ { 'trad', kCharacterShapeType, kTraditionalCharactersSelector, 16 },
+ { 'twid', kTextSpacingType, kThirdWidthTextSelector, 7 },
+ { 'unic', kLetterCaseType, 14, 15 },
+ { 'valt', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'vert', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector },
+ { 'vhal', kTextSpacingType, kAltHalfWidthTextSelector, 7 },
+ { 'vkna', kAlternateKanaType, kAlternateVertKanaOnSelector, kAlternateVertKanaOffSelector },
+ { 'vpal', kTextSpacingType, kAltProportionalTextSelector, 7 },
+ { 'vrt2', kVerticalSubstitutionType, kSubstituteVerticalFormsOnSelector, kSubstituteVerticalFormsOffSelector },
+ { 'zero', kTypographicExtrasType, kSlashedZeroOnSelector, kSlashedZeroOffSelector },
+};
+
+static int
+_hb_feature_mapping_cmp (const void *key_, const void *entry_)
+{
+ unsigned int key = * (unsigned int *) key_;
+ const feature_mapping_t * entry = (const feature_mapping_t *) entry_;
+ return key < entry->otFeatureTag ? -1 :
+ key > entry->otFeatureTag ? 1 :
+ 0;
+}
+
+hb_bool_t
+_hb_coretext_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ hb_face_t *face = font->face;
+ hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+
+ /*
+ * Set up features.
+ * (copied + modified from code from hb-uniscribe.cc)
+ */
+ hb_auto_array_t<feature_record_t> feature_records;
+ hb_auto_array_t<range_record_t> range_records;
+ if (num_features)
+ {
+ /* Sort features by start/end events. */
+ hb_auto_array_t<feature_event_t> feature_events;
+ for (unsigned int i = 0; i < num_features; i++)
+ {
+ const feature_mapping_t * mapping = (const feature_mapping_t *) bsearch (&features[i].tag,
+ feature_mappings,
+ ARRAY_LENGTH (feature_mappings),
+ sizeof (feature_mappings[0]),
+ _hb_feature_mapping_cmp);
+ if (!mapping)
+ continue;
+
+ active_feature_t feature;
+ feature.rec.feature = mapping->aatFeatureType;
+ feature.rec.setting = features[i].value ? mapping->selectorToEnable : mapping->selectorToDisable;
+ feature.order = i;
+
+ feature_event_t *event;
+
+ event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
+ event->index = features[i].start;
+ event->start = true;
+ event->feature = feature;
+
+ event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
+ event->index = features[i].end;
+ event->start = false;
+ event->feature = feature;
+ }
+ feature_events.sort ();
+ /* Add a strategic final event. */
+ {
+ active_feature_t feature;
+ feature.rec.feature = HB_TAG_NONE;
+ feature.rec.setting = 0;
+ feature.order = num_features + 1;
+
+ feature_event_t *event = feature_events.push ();
+ if (unlikely (!event))
+ goto fail_features;
+ event->index = 0; /* This value does magic. */
+ event->start = false;
+ event->feature = feature;
+ }
+
+ /* Scan events and save features for each range. */
+ hb_auto_array_t<active_feature_t> active_features;
+ unsigned int last_index = 0;
+ for (unsigned int i = 0; i < feature_events.len; i++)
+ {
+ feature_event_t *event = &feature_events[i];
+
+ if (event->index != last_index)
+ {
+ /* Save a snapshot of active features and the range. */
+ range_record_t *range = range_records.push ();
+ if (unlikely (!range))
+ goto fail_features;
+
+ unsigned int offset = feature_records.len;
+
+ if (active_features.len)
+ {
+ CFMutableArrayRef features_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+
+ /* TODO sort and resolve conflicting features? */
+ /* active_features.sort (); */
+ for (unsigned int j = 0; j < active_features.len; j++)
+ {
+ CFStringRef keys[2] = {
+ kCTFontFeatureTypeIdentifierKey,
+ kCTFontFeatureSelectorIdentifierKey
+ };
+ CFNumberRef values[2] = {
+ CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.feature),
+ CFNumberCreate (kCFAllocatorDefault, kCFNumberIntType, &active_features[j].rec.setting)
+ };
+ CFDictionaryRef dict = CFDictionaryCreate (kCFAllocatorDefault,
+ (const void **) keys,
+ (const void **) values,
+ 2,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFRelease (values[0]);
+ CFRelease (values[1]);
+
+ CFArrayAppendValue (features_array, dict);
+ CFRelease (dict);
+
+ }
+
+ CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault,
+ (const void **) &kCTFontFeatureSettingsAttribute,
+ (const void **) &features_array,
+ 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFRelease (features_array);
+
+ CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes);
+ CFRelease (attributes);
+
+ range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc);
+
+ CFRelease (font_desc);
+ }
+ else
+ {
+ range->font = NULL;
+ }
+
+ range->index_first = last_index;
+ range->index_last = event->index - 1;
+
+ last_index = event->index;
+ }
+
+ if (event->start) {
+ active_feature_t *feature = active_features.push ();
+ if (unlikely (!feature))
+ goto fail_features;
+ *feature = event->feature;
+ } else {
+ active_feature_t *feature = active_features.find (&event->feature);
+ if (feature)
+ active_features.remove (feature - active_features.array);
+ }
+ }
+
+ if (!range_records.len) /* No active feature found. */
+ goto fail_features;
+ }
+ else
+ {
+ fail_features:
+ num_features = 0;
+ }
+
+#define FAIL(...) \
+ HB_STMT_START { \
+ DEBUG_MSG (CORETEXT, NULL, __VA_ARGS__); \
+ return false; \
+ } HB_STMT_END;
+
+ unsigned int scratch_size;
+ hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
+
+#define ALLOCATE_ARRAY(Type, name, len) \
+ Type *name = (Type *) scratch; \
+ { \
+ unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
+ assert (_consumed <= scratch_size); \
+ scratch += _consumed; \
+ scratch_size -= _consumed; \
+ }
+
+#define utf16_index() var1.u32
+
+ ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2);
+
+ unsigned int chars_len = 0;
+ for (unsigned int i = 0; i < buffer->len; i++) {
+ hb_codepoint_t c = buffer->info[i].codepoint;
+ buffer->info[i].utf16_index() = chars_len;
+ if (likely (c < 0x10000))
+ pchars[chars_len++] = c;
+ else if (unlikely (c >= 0x110000))
+ pchars[chars_len++] = 0xFFFD;
+ else {
+ pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
+ pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
+ }
+ }
+
+#undef utf16_index
+
+ CFStringRef string_ref = CFStringCreateWithCharactersNoCopy (NULL,
+ pchars, chars_len,
+ kCFAllocatorNull);
+
+ CFMutableAttributedStringRef attr_string = CFAttributedStringCreateMutable (NULL, chars_len);
+ CFAttributedStringReplaceString (attr_string, CFRangeMake (0, 0), string_ref);
+ CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
+ kCTFontAttributeName, font_data->ct_font);
+
+ if (num_features)
+ {
+ ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len);
+
+ /* Need log_clusters to assign features. */
+ chars_len = 0;
+ for (unsigned int i = 0; i < buffer->len; i++)
+ {
+ hb_codepoint_t c = buffer->info[i].codepoint;
+ unsigned int cluster = buffer->info[i].cluster;
+ log_clusters[chars_len++] = cluster;
+ if (c >= 0x10000 && c < 0x110000)
+ log_clusters[chars_len++] = cluster; /* Surrogates. */
+ }
+
+ unsigned int start = 0;
+ range_record_t *last_range = &range_records[0];
+ for (unsigned int k = 0; k < chars_len; k++)
+ {
+ range_record_t *range = last_range;
+ while (log_clusters[k] < range->index_first)
+ range--;
+ while (log_clusters[k] > range->index_last)
+ range++;
+ if (range != last_range)
+ {
+ if (last_range->font)
+ CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, k - start),
+ kCTFontAttributeName, last_range->font);
+
+ start = k;
+ }
+
+ last_range = range;
+ }
+ if (start != chars_len && last_range->font)
+ CFAttributedStringSetAttribute (attr_string, CFRangeMake (start, chars_len - start - 1),
+ kCTFontAttributeName, last_range->font);
+
+ for (unsigned int i = 0; i < range_records.len; i++)
+ if (range_records[i].font)
+ CFRelease (range_records[i].font);
+ }
+
+ CTLineRef line = CTLineCreateWithAttributedString (attr_string);
+ CFRelease (attr_string);
+
+ CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
+ unsigned int num_runs = CFArrayGetCount (glyph_runs);
+
+ buffer->len = 0;
+
+ const CFRange range_all = CFRangeMake (0, 0);
+
+ for (unsigned int i = 0; i < num_runs; i++)
+ {
+ CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i);
+
+ /* CoreText does automatic font fallback (AKA "cascading") for characters
+ * not supported by the requested font, and provides no way to turn it off,
+ * so we detect if the returned run uses a font other than the requested
+ * one and fill in the buffer with .notdef glyphs instead of random glyph
+ * indices from a different font.
+ */
+ CFDictionaryRef attributes = CTRunGetAttributes (run);
+ CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
+ CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
+ if (!CFEqual (run_cg_font, face_data->cg_font))
+ {
+ CFRelease (run_cg_font);
+
+ CFRange range = CTRunGetStringRange (run);
+ buffer->ensure (buffer->len + range.length);
+ if (buffer->in_error)
+ FAIL ("Buffer resize failed");
+ hb_glyph_info_t *info = buffer->info + buffer->len;
+
+ CGGlyph notdef = 0;
+ double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1);
+
+ for (CFIndex j = range.location; j < range.location + range.length; j++)
+ {
+ UniChar ch = CFStringGetCharacterAtIndex (string_ref, j);
+ if (hb_in_range<UniChar> (ch, 0xDC00, 0xDFFF) && range.location < j)
+ {
+ ch = CFStringGetCharacterAtIndex (string_ref, j - 1);
+ if (hb_in_range<UniChar> (ch, 0xD800, 0xDBFF))
+ /* This is the second of a surrogate pair. Don't need .notdef
+ * for this one. */
+ continue;
+ }
+
+ info->codepoint = notdef;
+ /* TODO We have to fixup clusters later. See vis_clusters in
+ * hb-uniscribe.cc for example. */
+ info->cluster = j;
+
+ info->mask = advance * 64;
+ info->var1.u32 = 0;
+ info->var2.u32 = 0;
+
+ info++;
+ buffer->len++;
+ }
+ continue;
+ }
+ CFRelease (run_cg_font);
+
+ unsigned int num_glyphs = CTRunGetGlyphCount (run);
+ if (num_glyphs == 0)
+ continue;
+
+ buffer->ensure (buffer->len + num_glyphs);
+
+ scratch = buffer->get_scratch_buffer (&scratch_size);
+
+ /* Testing indicates that CTRunGetGlyphsPtr, etc (almost?) always
+ * succeed, and so copying data to our own buffer will be rare. */
+
+ const CGGlyph* glyphs = CTRunGetGlyphsPtr (run);
+ if (!glyphs) {
+ ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs);
+ CTRunGetGlyphs (run, range_all, glyph_buf);
+ glyphs = glyph_buf;
+ }
+
+ const CGPoint* positions = CTRunGetPositionsPtr (run);
+ if (!positions) {
+ ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs);
+ CTRunGetPositions (run, range_all, position_buf);
+ positions = position_buf;
+ }
+
+ const CFIndex* string_indices = CTRunGetStringIndicesPtr (run);
+ if (!string_indices) {
+ ALLOCATE_ARRAY (CFIndex, index_buf, num_glyphs);
+ CTRunGetStringIndices (run, range_all, index_buf);
+ string_indices = index_buf;
+ }
+
+#undef ALLOCATE_ARRAY
+
+ double run_width = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
+
+ for (unsigned int j = 0; j < num_glyphs; j++) {
+ double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_width) - positions[j].x;
+
+ hb_glyph_info_t *info = &buffer->info[buffer->len];
+
+ info->codepoint = glyphs[j];
+ info->cluster = string_indices[j];
+
+ /* Currently, we do all x-positioning by setting the advance, we never use x-offset. */
+ info->mask = advance * 64;
+ info->var1.u32 = 0;
+ info->var2.u32 = positions[j].y * 64;
+
+ buffer->len++;
+ }
+ }
+
+ buffer->clear_positions ();
+
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; ++i) {
+ hb_glyph_info_t *info = &buffer->info[i];
+ hb_glyph_position_t *pos = &buffer->pos[i];
+
+ /* TODO vertical */
+ pos->x_advance = info->mask;
+ pos->x_offset = info->var1.u32;
+ pos->y_offset = info->var2.u32;
+ }
+
+ /* Fix up clusters so that we never return out-of-order indices;
+ * if core text has reordered glyphs, we'll merge them to the
+ * beginning of the reordered cluster.
+ *
+ * This does *not* mean we'll form the same clusters as Uniscribe
+ * or the native OT backend, only that the cluster indices will be
+ * monotonic in the output buffer. */
+ if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+ unsigned int prev_cluster = 0;
+ for (unsigned int i = 0; i < count; i++) {
+ unsigned int curr_cluster = buffer->info[i].cluster;
+ if (curr_cluster < prev_cluster) {
+ for (unsigned int j = i; j > 0; j--) {
+ if (buffer->info[j - 1].cluster > curr_cluster)
+ buffer->info[j - 1].cluster = curr_cluster;
+ else
+ break;
+ }
+ }
+ prev_cluster = curr_cluster;
+ }
+ } else {
+ unsigned int prev_cluster = (unsigned int)-1;
+ for (unsigned int i = 0; i < count; i++) {
+ unsigned int curr_cluster = buffer->info[i].cluster;
+ if (curr_cluster > prev_cluster) {
+ for (unsigned int j = i; j > 0; j--) {
+ if (buffer->info[j - 1].cluster < curr_cluster)
+ buffer->info[j - 1].cluster = curr_cluster;
+ else
+ break;
+ }
+ }
+ prev_cluster = curr_cluster;
+ }
+ }
+
+ CFRelease (string_ref);
+ CFRelease (line);
+
+ return true;
+}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
new file mode 100644
index 0000000000..bcf1de7141
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2012 Mozilla Foundation.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Mozilla Author(s): Jonathan Kew
+ */
+
+#ifndef HB_CORETEXT_H
+#define HB_CORETEXT_H
+
+#include "hb.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
+HB_BEGIN_DECLS
+
+
+#define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
+#define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
+
+
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face);
+
+CTFontRef
+hb_coretext_font_get_ct_font (hb_font_t *font);
+
+
+HB_END_DECLS
+
+#endif /* HB_CORETEXT_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
deleted file mode 100644
index b894a4a47d..0000000000
--- a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright © 2011 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#define HB_SHAPER fallback
-#include "hb-shaper-impl-private.hh"
-
-
-/*
- * shaper face data
- */
-
-struct hb_fallback_shaper_face_data_t {};
-
-hb_fallback_shaper_face_data_t *
-_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
-{
- return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_fallback_shaper_font_data_t {};
-
-hb_fallback_shaper_font_data_t *
-_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
-{
- return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper shape_plan data
- */
-
-struct hb_fallback_shaper_shape_plan_data_t {};
-
-hb_fallback_shaper_shape_plan_data_t *
-_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
- const hb_feature_t *user_features HB_UNUSED,
- unsigned int num_user_features HB_UNUSED)
-{
- return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper
- */
-
-hb_bool_t
-_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features HB_UNUSED,
- unsigned int num_features HB_UNUSED)
-{
- /* TODO
- *
- * - Apply fallback kern.
- * - Handle Variation Selectors?
- * - Apply normalization?
- *
- * This will make the fallback shaper into a dumb "TrueType"
- * shaper which many people unfortunately still request.
- */
-
- hb_codepoint_t space;
- font->get_glyph (' ', 0, &space);
-
- buffer->clear_positions ();
-
- unsigned int count = buffer->len;
-
- for (unsigned int i = 0; i < count; i++)
- {
- if (buffer->unicode->is_default_ignorable (buffer->info[i].codepoint)) {
- buffer->info[i].codepoint = space;
- buffer->pos[i].x_advance = 0;
- buffer->pos[i].y_advance = 0;
- continue;
- }
- font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
- font->get_glyph_advance_for_direction (buffer->info[i].codepoint,
- buffer->props.direction,
- &buffer->pos[i].x_advance,
- &buffer->pos[i].y_advance);
- font->subtract_glyph_origin_for_direction (buffer->info[i].codepoint,
- buffer->props.direction,
- &buffer->pos[i].x_offset,
- &buffer->pos[i].y_offset);
- }
-
- if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
- hb_buffer_reverse (buffer);
-
- return true;
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
index 431d0477c2..33bbf7143a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -144,6 +144,12 @@ struct hb_font_t {
/* Public getters */
+ inline hb_bool_t has_glyph (hb_codepoint_t unicode)
+ {
+ hb_codepoint_t glyph;
+ return get_glyph (unicode, 0, &glyph);
+ }
+
inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
index 437ecd57f8..558103a8ec 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -592,7 +592,7 @@ struct LONGDATETIME
TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (this)));
}
- private:
+ protected:
LONG major;
ULONG minor;
public:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
index 5e4326ef0c..7c0a4ea666 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -109,11 +109,13 @@ struct ValueFormat : USHORT
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++));
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++));
if (format & xAdvance) {
- if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values++)); else values++;
+ if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values));
+ values++;
}
/* y_advance values grow downward but font-space grows upward, hence negation */
if (format & yAdvance) {
- if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values++)); else values++;
+ if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values));
+ values++;
}
if (!has_device ()) return;
@@ -125,17 +127,21 @@ struct ValueFormat : USHORT
/* pixel -> fractional pixel */
if (format & xPlaDevice) {
- if (x_ppem) glyph_pos.x_offset += (base + get_device (values++)).get_x_delta (font); else values++;
+ if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font);
+ values++;
}
if (format & yPlaDevice) {
- if (y_ppem) glyph_pos.y_offset += (base + get_device (values++)).get_y_delta (font); else values++;
+ if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font);
+ values++;
}
if (format & xAdvDevice) {
- if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values++)).get_x_delta (font); else values++;
+ if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font);
+ values++;
}
if (format & yAdvDevice) {
/* y_advance values grow downward but font-space grows upward, hence negation */
- if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values++)).get_y_delta (font); else values++;
+ if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font);
+ values++;
}
}
@@ -240,12 +246,12 @@ struct AnchorFormat2
unsigned int x_ppem = font->x_ppem;
unsigned int y_ppem = font->y_ppem;
hb_position_t cx, cy;
- hb_bool_t ret = false;
+ hb_bool_t ret;
- if (x_ppem || y_ppem)
- ret = font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
- *x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
- *y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
+ ret = (x_ppem || y_ppem) &&
+ font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+ *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
+ *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
}
inline bool sanitize (hb_sanitize_context_t *c) {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
index dfc7f2446f..d90eff374d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
@@ -194,11 +194,6 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
hb_set_t *lookup_indexes /* OUT */);
void
-hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
- hb_tag_t table_tag,
- hb_set_t *lookup_indexes /* OUT */);
-
-void
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag,
unsigned int lookup_index,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index 4f6c86e8ee..ea6d85c1e6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -199,7 +199,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_gsub_pause (NULL);
- map->add_global_bool_feature (HB_TAG('c','s','w','h'));
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
}
@@ -366,7 +365,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
data_create_arabic,
data_destroy_arabic,
NULL, /* preprocess_text_arabic */
- NULL, /* normalization_preference */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_arabic,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
index d6afa0e1c1..f7f097eeda 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
@@ -27,194 +27,18 @@
#include "hb-ot-shape-complex-private.hh"
-/* TODO Add kana, and other small shapers here */
-
-
-/* The default shaper *only* adds additional per-script features.*/
-
-static const hb_tag_t hangul_features[] =
-{
- HB_TAG('l','j','m','o'),
- HB_TAG('v','j','m','o'),
- HB_TAG('t','j','m','o'),
- HB_TAG_NONE
-};
-
-static const hb_tag_t tibetan_features[] =
-{
- HB_TAG('a','b','v','s'),
- HB_TAG('b','l','w','s'),
- HB_TAG('a','b','v','m'),
- HB_TAG('b','l','w','m'),
- HB_TAG_NONE
-};
-
-static void
-collect_features_default (hb_ot_shape_planner_t *plan)
-{
- const hb_tag_t *script_features = NULL;
-
- switch ((hb_tag_t) plan->props.script)
- {
- /* Unicode-1.1 additions */
- case HB_SCRIPT_HANGUL:
- script_features = hangul_features;
- break;
-
- /* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN:
- script_features = tibetan_features;
- break;
- }
-
- for (; script_features && *script_features; script_features++)
- plan->map.add_global_bool_feature (*script_features);
-}
-
-static hb_ot_shape_normalization_mode_t
-normalization_preference_default (const hb_segment_properties_t *props)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
-static bool
-compose_default (const hb_ot_shape_normalize_context_t *c,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab)
-{
- /* Hebrew presentation-form shaping.
- * https://bugzilla.mozilla.org/show_bug.cgi?id=728866
- * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
- * Note that some letters do not have a dagesh presForm encoded.
- */
- static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
- 0xFB30, /* ALEF */
- 0xFB31, /* BET */
- 0xFB32, /* GIMEL */
- 0xFB33, /* DALET */
- 0xFB34, /* HE */
- 0xFB35, /* VAV */
- 0xFB36, /* ZAYIN */
- 0x0000, /* HET */
- 0xFB38, /* TET */
- 0xFB39, /* YOD */
- 0xFB3A, /* FINAL KAF */
- 0xFB3B, /* KAF */
- 0xFB3C, /* LAMED */
- 0x0000, /* FINAL MEM */
- 0xFB3E, /* MEM */
- 0x0000, /* FINAL NUN */
- 0xFB40, /* NUN */
- 0xFB41, /* SAMEKH */
- 0x0000, /* AYIN */
- 0xFB43, /* FINAL PE */
- 0xFB44, /* PE */
- 0x0000, /* FINAL TSADI */
- 0xFB46, /* TSADI */
- 0xFB47, /* QOF */
- 0xFB48, /* RESH */
- 0xFB49, /* SHIN */
- 0xFB4A /* TAV */
- };
-
- bool found = c->unicode->compose (a, b, ab);
-
- if (!found && (b & ~0x7F) == 0x0580) {
- /* Special-case Hebrew presentation forms that are excluded from
- * standard normalization, but wanted for old fonts. */
- switch (b) {
- case 0x05B4: /* HIRIQ */
- if (a == 0x05D9) { /* YOD */
- *ab = 0xFB1D;
- found = true;
- }
- break;
- case 0x05B7: /* patah */
- if (a == 0x05F2) { /* YIDDISH YOD YOD */
- *ab = 0xFB1F;
- found = true;
- } else if (a == 0x05D0) { /* ALEF */
- *ab = 0xFB2E;
- found = true;
- }
- break;
- case 0x05B8: /* QAMATS */
- if (a == 0x05D0) { /* ALEF */
- *ab = 0xFB2F;
- found = true;
- }
- break;
- case 0x05B9: /* HOLAM */
- if (a == 0x05D5) { /* VAV */
- *ab = 0xFB4B;
- found = true;
- }
- break;
- case 0x05BC: /* DAGESH */
- if (a >= 0x05D0 && a <= 0x05EA) {
- *ab = sDageshForms[a - 0x05D0];
- found = (*ab != 0);
- } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
- *ab = 0xFB2C;
- found = true;
- } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
- *ab = 0xFB2D;
- found = true;
- }
- break;
- case 0x05BF: /* RAFE */
- switch (a) {
- case 0x05D1: /* BET */
- *ab = 0xFB4C;
- found = true;
- break;
- case 0x05DB: /* KAF */
- *ab = 0xFB4D;
- found = true;
- break;
- case 0x05E4: /* PE */
- *ab = 0xFB4E;
- found = true;
- break;
- }
- break;
- case 0x05C1: /* SHIN DOT */
- if (a == 0x05E9) { /* SHIN */
- *ab = 0xFB2A;
- found = true;
- } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
- *ab = 0xFB2C;
- found = true;
- }
- break;
- case 0x05C2: /* SIN DOT */
- if (a == 0x05E9) { /* SHIN */
- *ab = 0xFB2B;
- found = true;
- } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
- *ab = 0xFB2D;
- found = true;
- }
- break;
- }
- }
-
- return found;
-}
-
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
{
"default",
- collect_features_default,
+ NULL, /* collect_features */
NULL, /* override_features */
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
- normalization_preference_default,
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
- compose_default,
+ NULL, /* compose */
NULL, /* setup_masks */
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
true, /* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
new file mode 100644
index 0000000000..47aa44fedb
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc
@@ -0,0 +1,417 @@
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* Hangul shaper */
+
+
+/* Same order as the feature array below */
+enum {
+ NONE,
+
+ LJMO,
+ VJMO,
+ TJMO,
+
+ FIRST_HANGUL_FEATURE = LJMO,
+ HANGUL_FEATURE_COUNT = TJMO + 1
+};
+
+static const hb_tag_t hangul_features[HANGUL_FEATURE_COUNT] =
+{
+ HB_TAG_NONE,
+ HB_TAG('l','j','m','o'),
+ HB_TAG('v','j','m','o'),
+ HB_TAG('t','j','m','o')
+};
+
+static void
+collect_features_hangul (hb_ot_shape_planner_t *plan)
+{
+ hb_ot_map_builder_t *map = &plan->map;
+
+ for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
+ map->add_feature (hangul_features[i], 1, F_NONE);
+}
+
+struct hangul_shape_plan_t
+{
+ ASSERT_POD ();
+
+ hb_mask_t mask_array[HANGUL_FEATURE_COUNT];
+};
+
+static void *
+data_create_hangul (const hb_ot_shape_plan_t *plan)
+{
+ hangul_shape_plan_t *hangul_plan = (hangul_shape_plan_t *) calloc (1, sizeof (hangul_shape_plan_t));
+ if (unlikely (!hangul_plan))
+ return NULL;
+
+ for (unsigned int i = 0; i < HANGUL_FEATURE_COUNT; i++)
+ hangul_plan->mask_array[i] = plan->map.get_1_mask (hangul_features[i]);
+
+ return hangul_plan;
+}
+
+static void
+data_destroy_hangul (void *data)
+{
+ free (data);
+}
+
+/* Constants for algorithmic hangul syllable [de]composition. */
+#define LBase 0x1100
+#define VBase 0x1161
+#define TBase 0x11A7
+#define LCount 19
+#define VCount 21
+#define TCount 28
+#define SBase 0xAC00
+#define NCount (VCount * TCount)
+#define SCount (LCount * NCount)
+
+#define isCombiningL(u) (hb_in_range<hb_codepoint_t> ((u), LBase, LBase+LCount-1))
+#define isCombiningV(u) (hb_in_range<hb_codepoint_t> ((u), VBase, VBase+VCount-1))
+#define isCombiningT(u) (hb_in_range<hb_codepoint_t> ((u), TBase+1, TBase+TCount-1))
+#define isCombinedS(u) (hb_in_range<hb_codepoint_t> ((u), SBase, SBase+SCount-1))
+
+#define isL(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1100, 0x115F, 0xA960, 0xA97C))
+#define isV(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x1160, 0x11A7, 0xD7B0, 0xD7C6))
+#define isT(u) (hb_in_ranges<hb_codepoint_t> ((u), 0x11A8, 0x11FF, 0xD7CB, 0xD7FB))
+
+#define isHangulTone(u) (hb_in_range<hb_codepoint_t> ((u), 0x302e, 0x302f))
+
+/* buffer var allocations */
+#define hangul_shaping_feature() complex_var_u8_0() /* hangul jamo shaping feature */
+
+static bool
+is_zero_width_char (hb_font_t *font,
+ hb_codepoint_t unicode)
+{
+ hb_codepoint_t glyph;
+ return hb_font_get_glyph (font, unicode, 0, &glyph) && hb_font_get_glyph_h_advance (font, glyph) == 0;
+}
+
+static void
+preprocess_text_hangul (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, hangul_shaping_feature);
+
+ /* Hangul syllables come in two shapes: LV, and LVT. Of those:
+ *
+ * - LV can be precomposed, or decomposed. Lets call those
+ * <LV> and <L,V>,
+ * - LVT can be fully precomposed, partically precomposed, or
+ * fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
+ *
+ * The composition / decomposition is mechanical. However, not
+ * all <L,V> sequences compose, and not all <LV,T> sequences
+ * compose.
+ *
+ * Here are the specifics:
+ *
+ * - <L>: U+1100..115F, U+A960..A97F
+ * - <V>: U+1160..11A7, U+D7B0..D7C7
+ * - <T>: U+11A8..11FF, U+D7CB..D7FB
+ *
+ * - Only the <L,V> sequences for the 11xx ranges combine.
+ * - Only <LV,T> sequences for T in U+11A8..11C3 combine.
+ *
+ * Here is what we want to accomplish in this shaper:
+ *
+ * - If the whole syllable can be precomposed, do that,
+ * - Otherwise, fully decompose and apply ljmo/vjmo/tjmo features.
+ * - If a valid syllable is followed by a Hangul tone mark, reorder the tone
+ * mark to precede the whole syllable - unless it is a zero-width glyph, in
+ * which case we leave it untouched, assuming it's designed to overstrike.
+ *
+ * That is, of the different possible syllables:
+ *
+ * <L>
+ * <L,V>
+ * <L,V,T>
+ * <LV>
+ * <LVT>
+ * <LV, T>
+ *
+ * - <L> needs no work.
+ *
+ * - <LV> and <LVT> can stay the way they are if the font supports them, otherwise we
+ * should fully decompose them if font supports.
+ *
+ * - <L,V> and <L,V,T> we should compose if the whole thing can be composed.
+ *
+ * - <LV,T> we should compose if the whole thing can be composed, otherwise we should
+ * decompose.
+ */
+
+ buffer->clear_output ();
+ unsigned int start = 0, end = 0; /* Extent of most recently seen syllable;
+ * valid only if start < end
+ */
+ unsigned int count = buffer->len;
+
+ for (buffer->idx = 0; buffer->idx < count;)
+ {
+ hb_codepoint_t u = buffer->cur().codepoint;
+
+ if (isHangulTone (u))
+ {
+ /*
+ * We could cache the width of the tone marks and the existence of dotted-circle,
+ * but the use of the Hangul tone mark characters seems to be rare enough that
+ * I didn't bother for now.
+ */
+ if (start < end && end == buffer->out_len)
+ {
+ /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
+ buffer->next_glyph ();
+ if (!is_zero_width_char (font, u))
+ {
+ hb_glyph_info_t *info = buffer->out_info;
+ hb_glyph_info_t tone = info[end];
+ memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t));
+ info[start] = tone;
+ }
+ /* Merge clusters across the (possibly reordered) syllable+tone.
+ * We want to merge even in the zero-width tone mark case here,
+ * so that clustering behavior isn't dependent on how the tone mark
+ * is handled by the font.
+ */
+ buffer->merge_out_clusters (start, end + 1);
+ }
+ else
+ {
+ /* No valid syllable as base for tone mark; try to insert dotted circle. */
+ if (font->has_glyph (0x25cc))
+ {
+ hb_codepoint_t chars[2];
+ if (!is_zero_width_char (font, u)) {
+ chars[0] = u;
+ chars[1] = 0x25cc;
+ } else {
+ chars[0] = 0x25cc;
+ chars[1] = u;
+ }
+ buffer->replace_glyphs (1, 2, chars);
+ }
+ else
+ {
+ /* No dotted circle available in the font; just leave tone mark untouched. */
+ buffer->next_glyph ();
+ }
+ }
+ start = end = buffer->out_len;
+ continue;
+ }
+
+ start = buffer->out_len; /* Remember current position as a potential syllable start;
+ * will only be used if we set end to a later position.
+ */
+
+ if (isL (u) && buffer->idx + 1 < count)
+ {
+ hb_codepoint_t l = u;
+ hb_codepoint_t v = buffer->cur(+1).codepoint;
+ if (isV (v))
+ {
+ /* Have <L,V> or <L,V,T>. */
+ hb_codepoint_t t = 0;
+ unsigned int tindex = 0;
+ if (buffer->idx + 2 < count)
+ {
+ t = buffer->cur(+2).codepoint;
+ if (isT (t))
+ tindex = t - TBase; /* Only used if isCombiningT (t); otherwise invalid. */
+ else
+ t = 0; /* The next character was not a trailing jamo. */
+ }
+
+ /* We've got a syllable <L,V,T?>; see if it can potentially be composed. */
+ if (isCombiningL (l) && isCombiningV (v) && (t == 0 || isCombiningT (t)))
+ {
+ /* Try to compose; if this succeeds, end is set to start+1. */
+ hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
+ if (font->has_glyph (s))
+ {
+ buffer->replace_glyphs (t ? 3 : 2, 1, &s);
+ if (unlikely (buffer->in_error))
+ return;
+ end = start + 1;
+ continue;
+ }
+ }
+
+ /* We didn't compose, either because it's an Old Hangul syllable without a
+ * precomposed character in Unicode, or because the font didn't support the
+ * necessary precomposed glyph.
+ * Set jamo features on the individual glyphs, and advance past them.
+ */
+ buffer->cur().hangul_shaping_feature() = LJMO;
+ buffer->next_glyph ();
+ buffer->cur().hangul_shaping_feature() = VJMO;
+ buffer->next_glyph ();
+ if (t)
+ {
+ buffer->cur().hangul_shaping_feature() = TJMO;
+ buffer->next_glyph ();
+ end = start + 3;
+ }
+ else
+ end = start + 2;
+ buffer->merge_out_clusters (start, end);
+ continue;
+ }
+ }
+
+ else if (isCombinedS (u))
+ {
+ /* Have <LV>, <LVT>, or <LV,T> */
+ hb_codepoint_t s = u;
+ bool has_glyph = font->has_glyph (s);
+ unsigned int lindex = (s - SBase) / NCount;
+ unsigned int nindex = (s - SBase) % NCount;
+ unsigned int vindex = nindex / TCount;
+ unsigned int tindex = nindex % TCount;
+
+ if (!tindex &&
+ buffer->idx + 1 < count &&
+ isCombiningT (buffer->cur(+1).codepoint))
+ {
+ /* <LV,T>, try to combine. */
+ unsigned int new_tindex = buffer->cur(+1).codepoint - TBase;
+ hb_codepoint_t new_s = s + new_tindex;
+ if (font->has_glyph (new_s))
+ {
+ buffer->replace_glyphs (2, 1, &new_s);
+ if (unlikely (buffer->in_error))
+ return;
+ end = start + 1;
+ continue;
+ }
+ }
+
+ /* Otherwise, decompose if font doesn't support <LV> or <LVT>,
+ * or if having non-combining <LV,T>. Note that we already handled
+ * combining <LV,T> above. */
+ if (!has_glyph ||
+ (!tindex &&
+ buffer->idx + 1 < count &&
+ isT (buffer->cur(+1).codepoint)))
+ {
+ hb_codepoint_t decomposed[3] = {LBase + lindex,
+ VBase + vindex,
+ TBase + tindex};
+ if (font->has_glyph (decomposed[0]) &&
+ font->has_glyph (decomposed[1]) &&
+ (!tindex || font->has_glyph (decomposed[2])))
+ {
+ unsigned int s_len = tindex ? 3 : 2;
+ buffer->replace_glyphs (1, s_len, decomposed);
+ if (unlikely (buffer->in_error))
+ return;
+
+ /* We decomposed S: apply jamo features to the individual glyphs
+ * that are now in buffer->out_info.
+ */
+ hb_glyph_info_t *info = buffer->out_info;
+
+ /* If we decomposed an LV because of a non-combining T following,
+ * we want to include this T in the syllable.
+ */
+ if (has_glyph && !tindex)
+ {
+ buffer->next_glyph ();
+ s_len++;
+ }
+ end = start + s_len;
+
+ unsigned int i = start;
+ info[i++].hangul_shaping_feature() = LJMO;
+ info[i++].hangul_shaping_feature() = VJMO;
+ if (i < end)
+ info[i++].hangul_shaping_feature() = TJMO;
+ buffer->merge_out_clusters (start, end);
+ continue;
+ }
+ }
+
+ if (has_glyph)
+ {
+ /* We didn't decompose the S, so just advance past it. */
+ end = start + 1;
+ buffer->next_glyph ();
+ continue;
+ }
+ }
+
+ /* Didn't find a recognizable syllable, so we leave end <= start;
+ * this will prevent tone-mark reordering happening.
+ */
+ buffer->next_glyph ();
+ }
+ buffer->swap_buffers ();
+}
+
+static void
+setup_masks_hangul (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font HB_UNUSED)
+{
+ const hangul_shape_plan_t *hangul_plan = (const hangul_shape_plan_t *) plan->data;
+
+ if (likely (hangul_plan))
+ {
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++, info++)
+ info->mask |= hangul_plan->mask_array[info->hangul_shaping_feature()];
+ }
+
+ HB_BUFFER_DEALLOCATE_VAR (buffer, hangul_shaping_feature);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
+{
+ "hangul",
+ collect_features_hangul,
+ NULL, /* override_features */
+ data_create_hangul, /* data_create */
+ data_destroy_hangul, /* data_destroy */
+ preprocess_text_hangul,
+ HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
+ NULL, /* decompose */
+ NULL, /* compose */
+ setup_masks_hangul, /* setup_masks */
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+ false, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
new file mode 100644
index 0000000000..efef8c14ad
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+static bool
+compose_hebrew (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ /* Hebrew presentation-form shaping.
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=728866
+ * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
+ * Note that some letters do not have a dagesh presForm encoded.
+ */
+ static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
+ 0xFB30, /* ALEF */
+ 0xFB31, /* BET */
+ 0xFB32, /* GIMEL */
+ 0xFB33, /* DALET */
+ 0xFB34, /* HE */
+ 0xFB35, /* VAV */
+ 0xFB36, /* ZAYIN */
+ 0x0000, /* HET */
+ 0xFB38, /* TET */
+ 0xFB39, /* YOD */
+ 0xFB3A, /* FINAL KAF */
+ 0xFB3B, /* KAF */
+ 0xFB3C, /* LAMED */
+ 0x0000, /* FINAL MEM */
+ 0xFB3E, /* MEM */
+ 0x0000, /* FINAL NUN */
+ 0xFB40, /* NUN */
+ 0xFB41, /* SAMEKH */
+ 0x0000, /* AYIN */
+ 0xFB43, /* FINAL PE */
+ 0xFB44, /* PE */
+ 0x0000, /* FINAL TSADI */
+ 0xFB46, /* TSADI */
+ 0xFB47, /* QOF */
+ 0xFB48, /* RESH */
+ 0xFB49, /* SHIN */
+ 0xFB4A /* TAV */
+ };
+
+ bool found = c->unicode->compose (a, b, ab);
+
+ if (!found)
+ {
+ /* Special-case Hebrew presentation forms that are excluded from
+ * standard normalization, but wanted for old fonts. */
+ switch (b) {
+ case 0x05B4: /* HIRIQ */
+ if (a == 0x05D9) { /* YOD */
+ *ab = 0xFB1D;
+ found = true;
+ }
+ break;
+ case 0x05B7: /* patah */
+ if (a == 0x05F2) { /* YIDDISH YOD YOD */
+ *ab = 0xFB1F;
+ found = true;
+ } else if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2E;
+ found = true;
+ }
+ break;
+ case 0x05B8: /* QAMATS */
+ if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2F;
+ found = true;
+ }
+ break;
+ case 0x05B9: /* HOLAM */
+ if (a == 0x05D5) { /* VAV */
+ *ab = 0xFB4B;
+ found = true;
+ }
+ break;
+ case 0x05BC: /* DAGESH */
+ if (a >= 0x05D0 && a <= 0x05EA) {
+ *ab = sDageshForms[a - 0x05D0];
+ found = (*ab != 0);
+ } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
+ *ab = 0xFB2C;
+ found = true;
+ } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ case 0x05BF: /* RAFE */
+ switch (a) {
+ case 0x05D1: /* BET */
+ *ab = 0xFB4C;
+ found = true;
+ break;
+ case 0x05DB: /* KAF */
+ *ab = 0xFB4D;
+ found = true;
+ break;
+ case 0x05E4: /* PE */
+ *ab = 0xFB4E;
+ found = true;
+ break;
+ }
+ break;
+ case 0x05C1: /* SHIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2A;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2C;
+ found = true;
+ }
+ break;
+ case 0x05C2: /* SIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2B;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ }
+ }
+
+ return found;
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
+{
+ "hebrew",
+ NULL, /* collect_features */
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+ NULL, /* decompose */
+ compose_hebrew,
+ NULL, /* setup_masks */
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
+ true, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
index 612f7b788a..71621034ee 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
@@ -55,48 +55,52 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = {
4u, 14u, 5u, 7u, 5u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u,
7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 1u, 16u, 13u, 13u, 4u, 4u, 6u, 6u,
16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
- 6u, 6u, 16u, 16u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u,
- 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u,
- 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
- 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
- 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 3u, 14u, 3u, 14u,
- 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
- 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
- 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u,
- 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
- 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u,
- 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
- 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
- 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u,
- 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
- 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
- 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u,
- 3u, 14u, 4u, 14u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
- 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
- 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u,
- 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u, 3u, 14u,
- 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u,
- 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 3u, 14u, 1u, 16u, 3u, 17u, 1u, 16u, 4u, 14u, 1u, 16u,
- 3u, 17u, 3u, 14u, 4u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 14u, 3u, 14u,
- 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
- 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, 3u, 17u, 3u, 9u, 8u, 9u,
- 3u, 9u, 3u, 13u, 1u, 16u, 0
+ 6u, 6u, 16u, 16u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 18u, 8u, 18u,
+ 5u, 10u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 18u, 3u, 18u, 8u, 18u,
+ 3u, 10u, 8u, 10u, 3u, 18u, 3u, 18u, 3u, 18u, 3u, 18u, 4u, 18u, 5u, 18u,
+ 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u,
+ 6u, 18u, 3u, 18u, 1u, 18u, 4u, 31u, 4u, 18u, 3u, 31u, 3u, 31u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 3u, 31u, 3u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 18u, 8u, 18u,
+ 5u, 10u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 18u, 3u, 18u, 8u, 18u,
+ 3u, 10u, 8u, 10u, 3u, 18u, 3u, 18u, 3u, 18u, 3u, 18u, 4u, 18u, 5u, 18u,
+ 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u,
+ 6u, 18u, 3u, 18u, 1u, 18u, 4u, 31u, 4u, 18u, 3u, 31u, 3u, 31u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 4u, 14u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u,
+ 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u,
+ 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 18u, 8u, 18u, 5u, 10u,
+ 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 18u, 3u, 18u, 8u, 18u, 3u, 10u,
+ 8u, 10u, 3u, 18u, 3u, 18u, 3u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u,
+ 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 6u, 18u,
+ 3u, 18u, 1u, 18u, 4u, 31u, 4u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 4u, 14u, 3u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 1u, 18u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 18u, 8u, 18u,
+ 5u, 10u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 18u, 3u, 18u, 8u, 18u,
+ 3u, 10u, 8u, 10u, 3u, 18u, 3u, 18u, 3u, 18u, 3u, 18u, 4u, 18u, 5u, 18u,
+ 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u,
+ 6u, 18u, 3u, 18u, 1u, 18u, 4u, 31u, 4u, 18u, 3u, 31u, 3u, 31u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 1u, 18u, 3u, 31u, 3u, 31u, 1u, 18u, 1u, 18u, 1u, 18u, 1u, 18u,
+ 1u, 18u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 18u, 1u, 18u, 3u, 31u,
+ 3u, 31u, 4u, 31u, 5u, 10u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 10u,
+ 8u, 10u, 3u, 31u, 3u, 31u, 1u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u,
+ 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 5u, 18u, 3u, 18u, 4u, 18u, 8u, 18u,
+ 3u, 18u, 3u, 18u, 8u, 18u, 3u, 18u, 3u, 18u, 1u, 18u, 3u, 10u, 8u, 10u,
+ 5u, 10u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 0
};
static const char _indic_syllable_machine_key_spans[] = {
@@ -121,48 +125,52 @@ static const char _indic_syllable_machine_key_spans[] = {
11, 3, 3, 3, 3, 1, 3, 3,
1, 3, 3, 1, 16, 1, 1, 1,
1, 4, 1, 1, 4, 1, 1, 4,
- 1, 1, 16, 15, 12, 11, 16, 15,
- 12, 11, 16, 15, 12, 11, 16, 15,
- 12, 11, 16, 15, 12, 11, 10, 7,
- 5, 1, 1, 15, 7, 2, 7, 11,
- 12, 12, 11, 10, 12, 11, 10, 12,
- 11, 10, 12, 11, 9, 12, 11, 16,
- 12, 12, 16, 16, 16, 16, 16, 12,
- 12, 16, 16, 16, 16, 16, 12, 12,
- 16, 16, 16, 16, 16, 12, 12, 16,
- 16, 16, 16, 16, 12, 12, 12, 12,
- 11, 16, 15, 12, 11, 16, 15, 12,
- 11, 16, 15, 12, 11, 16, 15, 12,
- 11, 10, 7, 5, 1, 1, 15, 7,
- 2, 7, 11, 12, 12, 11, 10, 12,
- 11, 10, 12, 11, 10, 12, 11, 9,
- 12, 16, 12, 12, 16, 16, 16, 16,
- 16, 12, 12, 16, 16, 16, 16, 16,
- 12, 12, 16, 16, 16, 16, 16, 12,
- 12, 16, 16, 16, 16, 11, 16, 12,
- 12, 11, 16, 15, 12, 11, 16, 15,
- 12, 11, 16, 15, 12, 11, 16, 15,
- 12, 11, 10, 7, 5, 1, 1, 15,
- 7, 2, 7, 11, 12, 12, 11, 10,
- 12, 11, 10, 12, 11, 10, 12, 11,
- 9, 12, 16, 12, 12, 16, 16, 16,
- 16, 16, 12, 12, 16, 16, 16, 16,
- 16, 12, 12, 16, 16, 16, 16, 16,
- 12, 12, 16, 16, 16, 16, 16, 11,
- 12, 11, 12, 12, 11, 16, 15, 12,
- 11, 16, 15, 12, 11, 16, 15, 12,
- 11, 16, 15, 12, 11, 10, 7, 5,
- 1, 1, 15, 7, 2, 7, 11, 12,
- 12, 11, 10, 12, 11, 10, 12, 11,
- 10, 12, 11, 9, 12, 16, 12, 12,
- 16, 16, 16, 16, 16, 12, 12, 16,
- 16, 16, 16, 16, 12, 12, 16, 16,
- 16, 16, 16, 12, 12, 16, 16, 16,
- 16, 16, 12, 16, 15, 16, 11, 16,
- 15, 12, 11, 5, 1, 1, 12, 12,
- 16, 12, 11, 10, 12, 11, 10, 12,
- 11, 10, 12, 11, 7, 15, 7, 2,
- 7, 11, 16
+ 1, 1, 31, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 14, 11,
+ 6, 2, 2, 1, 6, 16, 16, 11,
+ 8, 3, 16, 16, 16, 16, 15, 14,
+ 16, 15, 14, 16, 15, 14, 16, 15,
+ 13, 16, 18, 28, 15, 29, 29, 18,
+ 18, 18, 18, 18, 29, 29, 18, 18,
+ 18, 18, 18, 29, 29, 18, 18, 18,
+ 18, 18, 29, 29, 18, 18, 18, 18,
+ 18, 29, 29, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 14, 11,
+ 6, 2, 2, 1, 6, 16, 16, 11,
+ 8, 3, 16, 16, 16, 16, 15, 14,
+ 16, 15, 14, 16, 15, 14, 16, 15,
+ 13, 16, 18, 28, 15, 29, 29, 18,
+ 18, 18, 18, 18, 29, 29, 18, 18,
+ 18, 18, 18, 29, 29, 18, 18, 18,
+ 18, 18, 29, 29, 18, 18, 18, 18,
+ 11, 18, 29, 29, 28, 18, 29, 29,
+ 28, 18, 29, 29, 28, 18, 29, 29,
+ 28, 18, 29, 29, 28, 14, 11, 6,
+ 2, 2, 1, 6, 16, 16, 11, 8,
+ 3, 16, 16, 16, 16, 15, 14, 16,
+ 15, 14, 16, 15, 14, 16, 15, 13,
+ 16, 18, 28, 15, 29, 29, 18, 18,
+ 18, 18, 18, 29, 29, 18, 18, 18,
+ 18, 18, 29, 29, 18, 18, 18, 18,
+ 18, 29, 29, 18, 18, 18, 18, 18,
+ 11, 29, 11, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 18, 29,
+ 29, 28, 18, 29, 29, 28, 14, 11,
+ 6, 2, 2, 1, 6, 16, 16, 11,
+ 8, 3, 16, 16, 16, 16, 15, 14,
+ 16, 15, 14, 16, 15, 14, 16, 15,
+ 13, 16, 18, 28, 15, 29, 29, 18,
+ 18, 18, 18, 18, 29, 29, 18, 18,
+ 18, 18, 18, 29, 29, 18, 18, 18,
+ 18, 18, 29, 29, 18, 18, 18, 18,
+ 18, 29, 31, 29, 31, 15, 18, 29,
+ 29, 28, 6, 2, 2, 1, 6, 8,
+ 3, 29, 29, 18, 16, 15, 14, 16,
+ 15, 14, 16, 15, 14, 16, 15, 11,
+ 16, 16, 11, 16, 16, 18, 8, 3,
+ 6, 2, 2, 1, 6
};
static const short _indic_syllable_machine_index_offsets[] = {
@@ -187,48 +195,52 @@ static const short _indic_syllable_machine_index_offsets[] = {
848, 860, 864, 868, 872, 876, 878, 882,
886, 888, 892, 896, 898, 915, 917, 919,
921, 923, 928, 930, 932, 937, 939, 941,
- 946, 948, 950, 967, 983, 996, 1008, 1025,
- 1041, 1054, 1066, 1083, 1099, 1112, 1124, 1141,
- 1157, 1170, 1182, 1199, 1215, 1228, 1240, 1251,
- 1259, 1265, 1267, 1269, 1285, 1293, 1296, 1304,
- 1316, 1329, 1342, 1354, 1365, 1378, 1390, 1401,
- 1414, 1426, 1437, 1450, 1462, 1472, 1485, 1497,
- 1514, 1527, 1540, 1557, 1574, 1591, 1608, 1625,
- 1638, 1651, 1668, 1685, 1702, 1719, 1736, 1749,
- 1762, 1779, 1796, 1813, 1830, 1847, 1860, 1873,
- 1890, 1907, 1924, 1941, 1958, 1971, 1984, 1997,
- 2010, 2022, 2039, 2055, 2068, 2080, 2097, 2113,
- 2126, 2138, 2155, 2171, 2184, 2196, 2213, 2229,
- 2242, 2254, 2265, 2273, 2279, 2281, 2283, 2299,
- 2307, 2310, 2318, 2330, 2343, 2356, 2368, 2379,
- 2392, 2404, 2415, 2428, 2440, 2451, 2464, 2476,
- 2486, 2499, 2516, 2529, 2542, 2559, 2576, 2593,
- 2610, 2627, 2640, 2653, 2670, 2687, 2704, 2721,
- 2738, 2751, 2764, 2781, 2798, 2815, 2832, 2849,
- 2862, 2875, 2892, 2909, 2926, 2943, 2955, 2972,
- 2985, 2998, 3010, 3027, 3043, 3056, 3068, 3085,
- 3101, 3114, 3126, 3143, 3159, 3172, 3184, 3201,
- 3217, 3230, 3242, 3253, 3261, 3267, 3269, 3271,
- 3287, 3295, 3298, 3306, 3318, 3331, 3344, 3356,
- 3367, 3380, 3392, 3403, 3416, 3428, 3439, 3452,
- 3464, 3474, 3487, 3504, 3517, 3530, 3547, 3564,
- 3581, 3598, 3615, 3628, 3641, 3658, 3675, 3692,
- 3709, 3726, 3739, 3752, 3769, 3786, 3803, 3820,
- 3837, 3850, 3863, 3880, 3897, 3914, 3931, 3948,
- 3960, 3973, 3985, 3998, 4011, 4023, 4040, 4056,
- 4069, 4081, 4098, 4114, 4127, 4139, 4156, 4172,
- 4185, 4197, 4214, 4230, 4243, 4255, 4266, 4274,
- 4280, 4282, 4284, 4300, 4308, 4311, 4319, 4331,
- 4344, 4357, 4369, 4380, 4393, 4405, 4416, 4429,
- 4441, 4452, 4465, 4477, 4487, 4500, 4517, 4530,
- 4543, 4560, 4577, 4594, 4611, 4628, 4641, 4654,
- 4671, 4688, 4705, 4722, 4739, 4752, 4765, 4782,
- 4799, 4816, 4833, 4850, 4863, 4876, 4893, 4910,
- 4927, 4944, 4961, 4974, 4991, 5007, 5024, 5036,
- 5053, 5069, 5082, 5094, 5100, 5102, 5104, 5117,
- 5130, 5147, 5160, 5172, 5183, 5196, 5208, 5219,
- 5232, 5244, 5255, 5268, 5280, 5288, 5304, 5312,
- 5315, 5323, 5335
+ 946, 948, 950, 982, 1012, 1042, 1071, 1090,
+ 1120, 1150, 1179, 1198, 1228, 1258, 1287, 1306,
+ 1336, 1366, 1395, 1414, 1444, 1474, 1503, 1518,
+ 1530, 1537, 1540, 1543, 1545, 1552, 1569, 1586,
+ 1598, 1607, 1611, 1628, 1645, 1662, 1679, 1695,
+ 1710, 1727, 1743, 1758, 1775, 1791, 1806, 1823,
+ 1839, 1853, 1870, 1889, 1918, 1934, 1964, 1994,
+ 2013, 2032, 2051, 2070, 2089, 2119, 2149, 2168,
+ 2187, 2206, 2225, 2244, 2274, 2304, 2323, 2342,
+ 2361, 2380, 2399, 2429, 2459, 2478, 2497, 2516,
+ 2535, 2554, 2584, 2614, 2644, 2674, 2703, 2722,
+ 2752, 2782, 2811, 2830, 2860, 2890, 2919, 2938,
+ 2968, 2998, 3027, 3046, 3076, 3106, 3135, 3150,
+ 3162, 3169, 3172, 3175, 3177, 3184, 3201, 3218,
+ 3230, 3239, 3243, 3260, 3277, 3294, 3311, 3327,
+ 3342, 3359, 3375, 3390, 3407, 3423, 3438, 3455,
+ 3471, 3485, 3502, 3521, 3550, 3566, 3596, 3626,
+ 3645, 3664, 3683, 3702, 3721, 3751, 3781, 3800,
+ 3819, 3838, 3857, 3876, 3906, 3936, 3955, 3974,
+ 3993, 4012, 4031, 4061, 4091, 4110, 4129, 4148,
+ 4167, 4179, 4198, 4228, 4258, 4287, 4306, 4336,
+ 4366, 4395, 4414, 4444, 4474, 4503, 4522, 4552,
+ 4582, 4611, 4630, 4660, 4690, 4719, 4734, 4746,
+ 4753, 4756, 4759, 4761, 4768, 4785, 4802, 4814,
+ 4823, 4827, 4844, 4861, 4878, 4895, 4911, 4926,
+ 4943, 4959, 4974, 4991, 5007, 5022, 5039, 5055,
+ 5069, 5086, 5105, 5134, 5150, 5180, 5210, 5229,
+ 5248, 5267, 5286, 5305, 5335, 5365, 5384, 5403,
+ 5422, 5441, 5460, 5490, 5520, 5539, 5558, 5577,
+ 5596, 5615, 5645, 5675, 5694, 5713, 5732, 5751,
+ 5770, 5782, 5812, 5824, 5854, 5884, 5913, 5932,
+ 5962, 5992, 6021, 6040, 6070, 6100, 6129, 6148,
+ 6178, 6208, 6237, 6256, 6286, 6316, 6345, 6360,
+ 6372, 6379, 6382, 6385, 6387, 6394, 6411, 6428,
+ 6440, 6449, 6453, 6470, 6487, 6504, 6521, 6537,
+ 6552, 6569, 6585, 6600, 6617, 6633, 6648, 6665,
+ 6681, 6695, 6712, 6731, 6760, 6776, 6806, 6836,
+ 6855, 6874, 6893, 6912, 6931, 6961, 6991, 7010,
+ 7029, 7048, 7067, 7086, 7116, 7146, 7165, 7184,
+ 7203, 7222, 7241, 7271, 7301, 7320, 7339, 7358,
+ 7377, 7396, 7426, 7458, 7488, 7520, 7536, 7555,
+ 7585, 7615, 7644, 7651, 7654, 7657, 7659, 7666,
+ 7675, 7679, 7709, 7739, 7758, 7775, 7791, 7806,
+ 7823, 7839, 7854, 7871, 7887, 7902, 7919, 7935,
+ 7947, 7964, 7981, 7993, 8010, 8027, 8046, 8055,
+ 8059, 8066, 8069, 8072, 8074
};
static const short _indic_syllable_machine_indicies[] = {
@@ -351,625 +363,970 @@ static const short _indic_syllable_machine_indicies[] = {
172, 0, 173, 0, 174, 159, 159, 160,
0, 175, 0, 176, 0, 177, 156, 156,
157, 0, 178, 0, 179, 0, 181, 182,
- 183, 184, 185, 186, 81, 187, 188, 180,
- 189, 189, 152, 190, 191, 192, 180, 194,
- 195, 196, 197, 5, 198, 199, 200, 193,
- 193, 37, 201, 193, 193, 181, 193, 202,
- 195, 203, 203, 5, 198, 199, 200, 193,
- 193, 193, 201, 193, 195, 203, 203, 5,
- 198, 199, 200, 193, 193, 193, 201, 193,
- 204, 193, 193, 193, 18, 205, 193, 198,
- 199, 193, 193, 193, 193, 206, 193, 204,
- 193, 207, 208, 209, 210, 5, 198, 199,
- 200, 193, 193, 35, 211, 193, 193, 204,
- 193, 212, 208, 213, 213, 5, 198, 199,
- 200, 193, 193, 193, 211, 193, 208, 213,
- 213, 5, 198, 199, 200, 193, 193, 193,
- 211, 193, 214, 193, 193, 193, 18, 215,
- 193, 198, 199, 193, 193, 193, 193, 206,
- 193, 214, 193, 216, 217, 218, 219, 5,
- 198, 199, 200, 193, 193, 33, 220, 193,
- 193, 214, 193, 221, 217, 222, 222, 5,
- 198, 199, 200, 193, 193, 193, 220, 193,
- 217, 222, 222, 5, 198, 199, 200, 193,
- 193, 193, 220, 193, 223, 193, 193, 193,
- 18, 224, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 223, 193, 225, 226, 227,
- 228, 5, 198, 199, 200, 193, 193, 31,
- 229, 193, 193, 223, 193, 230, 226, 231,
- 231, 5, 198, 199, 200, 193, 193, 193,
- 229, 193, 226, 231, 231, 5, 198, 199,
- 200, 193, 193, 193, 229, 193, 232, 193,
- 193, 193, 18, 233, 193, 198, 199, 193,
- 193, 193, 193, 206, 193, 232, 193, 234,
- 235, 236, 237, 5, 198, 199, 200, 193,
- 193, 29, 238, 193, 193, 232, 193, 239,
- 235, 240, 240, 5, 198, 199, 200, 193,
- 193, 193, 238, 193, 235, 240, 240, 5,
- 198, 199, 200, 193, 193, 193, 238, 193,
- 18, 241, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 242, 193, 193, 193, 199,
- 193, 199, 193, 243, 193, 244, 193, 245,
- 246, 193, 198, 199, 193, 193, 193, 3,
- 193, 193, 193, 1, 193, 2, 193, 193,
- 193, 193, 198, 199, 193, 198, 199, 193,
- 244, 193, 193, 193, 193, 198, 199, 193,
- 244, 193, 245, 193, 193, 198, 199, 193,
- 193, 193, 3, 193, 18, 193, 247, 247,
- 5, 198, 199, 193, 193, 193, 193, 206,
- 193, 248, 27, 249, 250, 8, 198, 199,
- 193, 193, 193, 193, 206, 193, 27, 249,
- 250, 8, 198, 199, 193, 193, 193, 193,
- 206, 193, 249, 249, 8, 198, 199, 193,
- 193, 193, 193, 206, 193, 251, 24, 252,
- 253, 11, 198, 199, 193, 193, 193, 193,
- 206, 193, 24, 252, 253, 11, 198, 199,
- 193, 193, 193, 193, 206, 193, 252, 252,
- 11, 198, 199, 193, 193, 193, 193, 206,
- 193, 254, 21, 255, 256, 14, 198, 199,
- 193, 193, 193, 193, 206, 193, 21, 255,
- 256, 14, 198, 199, 193, 193, 193, 193,
- 206, 193, 255, 255, 14, 198, 199, 193,
- 193, 193, 193, 206, 193, 257, 18, 193,
- 258, 193, 198, 199, 193, 193, 193, 193,
- 206, 193, 18, 193, 258, 193, 198, 199,
- 193, 193, 193, 193, 206, 193, 259, 193,
- 198, 199, 193, 193, 193, 193, 206, 193,
- 18, 193, 193, 193, 193, 198, 199, 193,
- 193, 193, 193, 206, 193, 235, 240, 240,
- 5, 198, 199, 193, 193, 193, 193, 238,
- 193, 1, 2, 193, 193, 18, 241, 193,
- 198, 199, 193, 193, 193, 193, 206, 193,
- 1, 193, 234, 235, 240, 240, 5, 198,
- 199, 200, 193, 193, 193, 238, 193, 234,
- 235, 236, 240, 5, 198, 199, 200, 193,
- 193, 29, 238, 193, 232, 193, 260, 193,
- 247, 247, 5, 198, 199, 193, 193, 193,
- 193, 206, 193, 232, 193, 232, 193, 193,
- 193, 193, 193, 193, 198, 199, 193, 193,
- 193, 193, 206, 193, 232, 193, 232, 193,
- 193, 193, 193, 261, 193, 198, 199, 193,
- 193, 193, 193, 206, 193, 232, 193, 232,
- 193, 260, 193, 193, 193, 193, 198, 199,
- 193, 193, 193, 193, 206, 193, 232, 193,
- 232, 2, 193, 193, 18, 233, 193, 198,
- 199, 193, 193, 193, 193, 206, 193, 232,
- 193, 225, 226, 231, 231, 5, 198, 199,
- 200, 193, 193, 193, 229, 193, 225, 226,
- 227, 231, 5, 198, 199, 200, 193, 193,
- 31, 229, 193, 223, 193, 262, 193, 247,
- 247, 5, 198, 199, 193, 193, 193, 193,
- 206, 193, 223, 193, 223, 193, 193, 193,
- 193, 193, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 223, 193, 223, 193, 193,
- 193, 193, 263, 193, 198, 199, 193, 193,
- 193, 193, 206, 193, 223, 193, 223, 193,
- 262, 193, 193, 193, 193, 198, 199, 193,
- 193, 193, 193, 206, 193, 223, 193, 223,
- 2, 193, 193, 18, 224, 193, 198, 199,
- 193, 193, 193, 193, 206, 193, 223, 193,
- 216, 217, 222, 222, 5, 198, 199, 200,
- 193, 193, 193, 220, 193, 216, 217, 218,
- 222, 5, 198, 199, 200, 193, 193, 33,
- 220, 193, 214, 193, 264, 193, 247, 247,
- 5, 198, 199, 193, 193, 193, 193, 206,
- 193, 214, 193, 214, 193, 193, 193, 193,
- 193, 193, 198, 199, 193, 193, 193, 193,
- 206, 193, 214, 193, 214, 193, 193, 193,
- 193, 265, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 214, 193, 214, 193, 264,
- 193, 193, 193, 193, 198, 199, 193, 193,
- 193, 193, 206, 193, 214, 193, 214, 2,
- 193, 193, 18, 215, 193, 198, 199, 193,
- 193, 193, 193, 206, 193, 214, 193, 207,
- 208, 213, 213, 5, 198, 199, 200, 193,
- 193, 193, 211, 193, 207, 208, 209, 213,
- 5, 198, 199, 200, 193, 193, 35, 211,
- 193, 204, 193, 266, 193, 247, 247, 5,
- 198, 199, 193, 193, 193, 193, 206, 193,
- 204, 193, 204, 193, 193, 193, 193, 193,
- 193, 198, 199, 193, 193, 193, 193, 206,
- 193, 204, 193, 204, 193, 193, 193, 193,
- 267, 193, 198, 199, 193, 193, 193, 193,
- 206, 193, 204, 193, 204, 193, 266, 193,
- 193, 193, 193, 198, 199, 193, 193, 193,
- 193, 206, 193, 204, 193, 204, 2, 193,
- 193, 18, 205, 193, 198, 199, 193, 193,
- 193, 193, 206, 193, 204, 193, 194, 195,
- 203, 203, 5, 198, 199, 200, 193, 193,
- 193, 201, 193, 194, 195, 196, 203, 5,
- 198, 199, 200, 193, 193, 37, 201, 193,
- 269, 270, 271, 272, 43, 273, 274, 268,
- 268, 268, 75, 275, 268, 276, 270, 277,
- 272, 43, 273, 274, 268, 268, 268, 268,
- 275, 268, 270, 277, 272, 43, 273, 274,
- 268, 268, 268, 268, 275, 268, 278, 268,
- 268, 268, 56, 279, 268, 273, 274, 268,
- 268, 268, 268, 280, 268, 278, 268, 281,
- 282, 283, 284, 43, 273, 274, 268, 268,
- 268, 73, 285, 268, 268, 278, 268, 286,
- 282, 287, 287, 43, 273, 274, 268, 268,
- 268, 268, 285, 268, 282, 287, 287, 43,
- 273, 274, 268, 268, 268, 268, 285, 268,
- 288, 268, 268, 268, 56, 289, 268, 273,
- 274, 268, 268, 268, 268, 280, 268, 288,
- 268, 290, 291, 292, 293, 43, 273, 274,
- 268, 268, 268, 71, 294, 268, 268, 288,
- 268, 295, 291, 296, 296, 43, 273, 274,
- 268, 268, 268, 268, 294, 268, 291, 296,
- 296, 43, 273, 274, 268, 268, 268, 268,
- 294, 268, 297, 268, 268, 268, 56, 298,
- 268, 273, 274, 268, 268, 268, 268, 280,
- 268, 297, 268, 299, 300, 301, 302, 43,
- 273, 274, 268, 268, 268, 69, 303, 268,
- 268, 297, 268, 304, 300, 305, 305, 43,
- 273, 274, 268, 268, 268, 268, 303, 268,
- 300, 305, 305, 43, 273, 274, 268, 268,
- 268, 268, 303, 268, 306, 268, 268, 268,
- 56, 307, 268, 273, 274, 268, 268, 268,
- 268, 280, 268, 306, 268, 308, 309, 310,
- 311, 43, 273, 274, 268, 268, 268, 67,
- 312, 268, 268, 306, 268, 313, 309, 314,
- 314, 43, 273, 274, 268, 268, 268, 268,
- 312, 268, 309, 314, 314, 43, 273, 274,
- 268, 268, 268, 268, 312, 268, 56, 315,
- 268, 273, 274, 268, 268, 268, 268, 280,
- 268, 273, 274, 268, 268, 268, 268, 280,
- 268, 316, 268, 268, 268, 274, 268, 274,
- 268, 317, 268, 318, 268, 319, 320, 268,
- 273, 274, 268, 268, 268, 41, 268, 268,
- 268, 39, 268, 40, 268, 268, 268, 268,
- 273, 274, 268, 273, 274, 268, 318, 268,
- 268, 268, 268, 273, 274, 268, 318, 268,
- 319, 268, 268, 273, 274, 268, 268, 268,
- 41, 268, 56, 268, 321, 321, 43, 273,
- 274, 268, 268, 268, 268, 280, 268, 322,
- 65, 323, 324, 46, 273, 274, 268, 268,
- 268, 268, 280, 268, 65, 323, 324, 46,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 323, 323, 46, 273, 274, 268, 268, 268,
- 268, 280, 268, 325, 62, 326, 327, 49,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 62, 326, 327, 49, 273, 274, 268, 268,
- 268, 268, 280, 268, 326, 326, 49, 273,
- 274, 268, 268, 268, 268, 280, 268, 328,
- 59, 329, 330, 52, 273, 274, 268, 268,
- 268, 268, 280, 268, 59, 329, 330, 52,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 329, 329, 52, 273, 274, 268, 268, 268,
- 268, 280, 268, 331, 56, 268, 332, 268,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 56, 268, 332, 268, 273, 274, 268, 268,
- 268, 268, 280, 268, 333, 268, 273, 274,
- 268, 268, 268, 268, 280, 268, 56, 268,
- 268, 268, 268, 273, 274, 268, 268, 268,
- 268, 280, 268, 39, 40, 268, 268, 56,
- 315, 268, 273, 274, 268, 268, 268, 268,
- 280, 268, 39, 268, 308, 309, 314, 314,
- 43, 273, 274, 268, 268, 268, 268, 312,
- 268, 308, 309, 310, 314, 43, 273, 274,
- 268, 268, 268, 67, 312, 268, 306, 268,
- 334, 268, 321, 321, 43, 273, 274, 268,
- 268, 268, 268, 280, 268, 306, 268, 306,
- 268, 268, 268, 268, 268, 268, 273, 274,
- 268, 268, 268, 268, 280, 268, 306, 268,
- 306, 268, 268, 268, 268, 335, 268, 273,
- 274, 268, 268, 268, 268, 280, 268, 306,
- 268, 306, 268, 334, 268, 268, 268, 268,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 306, 268, 306, 40, 268, 268, 56, 307,
- 268, 273, 274, 268, 268, 268, 268, 280,
- 268, 306, 268, 299, 300, 305, 305, 43,
- 273, 274, 268, 268, 268, 268, 303, 268,
- 299, 300, 301, 305, 43, 273, 274, 268,
- 268, 268, 69, 303, 268, 297, 268, 336,
- 268, 321, 321, 43, 273, 274, 268, 268,
- 268, 268, 280, 268, 297, 268, 297, 268,
- 268, 268, 268, 268, 268, 273, 274, 268,
- 268, 268, 268, 280, 268, 297, 268, 297,
- 268, 268, 268, 268, 337, 268, 273, 274,
- 268, 268, 268, 268, 280, 268, 297, 268,
- 297, 268, 336, 268, 268, 268, 268, 273,
- 274, 268, 268, 268, 268, 280, 268, 297,
- 268, 297, 40, 268, 268, 56, 298, 268,
- 273, 274, 268, 268, 268, 268, 280, 268,
- 297, 268, 290, 291, 296, 296, 43, 273,
- 274, 268, 268, 268, 268, 294, 268, 290,
- 291, 292, 296, 43, 273, 274, 268, 268,
- 268, 71, 294, 268, 288, 268, 338, 268,
- 321, 321, 43, 273, 274, 268, 268, 268,
- 268, 280, 268, 288, 268, 288, 268, 268,
- 268, 268, 268, 268, 273, 274, 268, 268,
- 268, 268, 280, 268, 288, 268, 288, 268,
- 268, 268, 268, 339, 268, 273, 274, 268,
- 268, 268, 268, 280, 268, 288, 268, 288,
- 268, 338, 268, 268, 268, 268, 273, 274,
- 268, 268, 268, 268, 280, 268, 288, 268,
- 288, 40, 268, 268, 56, 289, 268, 273,
- 274, 268, 268, 268, 268, 280, 268, 288,
- 268, 281, 282, 287, 287, 43, 273, 274,
- 268, 268, 268, 268, 285, 268, 281, 282,
- 283, 287, 43, 273, 274, 268, 268, 268,
- 73, 285, 268, 278, 268, 340, 268, 321,
- 321, 43, 273, 274, 268, 268, 268, 268,
- 280, 268, 278, 268, 278, 268, 268, 268,
- 268, 268, 268, 273, 274, 268, 268, 268,
- 268, 280, 268, 278, 268, 278, 268, 268,
- 268, 268, 341, 268, 273, 274, 268, 268,
- 268, 268, 280, 268, 278, 268, 278, 268,
- 340, 268, 268, 268, 268, 273, 274, 268,
- 268, 268, 268, 280, 268, 278, 268, 74,
- 42, 42, 43, 268, 268, 268, 268, 268,
- 268, 74, 268, 278, 40, 268, 268, 56,
- 279, 268, 273, 274, 268, 268, 268, 268,
- 280, 268, 278, 268, 269, 270, 277, 272,
- 43, 273, 274, 268, 268, 268, 268, 275,
- 268, 343, 184, 344, 344, 81, 187, 188,
- 342, 342, 342, 342, 190, 342, 184, 344,
- 344, 81, 187, 188, 342, 342, 342, 342,
- 190, 342, 345, 342, 342, 342, 95, 346,
- 342, 187, 188, 342, 342, 342, 342, 347,
- 342, 345, 342, 348, 349, 350, 351, 81,
- 187, 188, 342, 342, 342, 112, 352, 342,
- 342, 345, 342, 353, 349, 354, 354, 81,
- 187, 188, 342, 342, 342, 342, 352, 342,
- 349, 354, 354, 81, 187, 188, 342, 342,
- 342, 342, 352, 342, 355, 342, 342, 342,
- 95, 356, 342, 187, 188, 342, 342, 342,
- 342, 347, 342, 355, 342, 357, 358, 359,
- 360, 81, 187, 188, 342, 342, 342, 110,
- 361, 342, 342, 355, 342, 362, 358, 363,
- 363, 81, 187, 188, 342, 342, 342, 342,
- 361, 342, 358, 363, 363, 81, 187, 188,
- 342, 342, 342, 342, 361, 342, 364, 342,
- 342, 342, 95, 365, 342, 187, 188, 342,
- 342, 342, 342, 347, 342, 364, 342, 366,
- 367, 368, 369, 81, 187, 188, 342, 342,
- 342, 108, 370, 342, 342, 364, 342, 371,
- 367, 372, 372, 81, 187, 188, 342, 342,
- 342, 342, 370, 342, 367, 372, 372, 81,
- 187, 188, 342, 342, 342, 342, 370, 342,
- 373, 342, 342, 342, 95, 374, 342, 187,
- 188, 342, 342, 342, 342, 347, 342, 373,
- 342, 375, 376, 377, 378, 81, 187, 188,
- 342, 342, 342, 106, 379, 342, 342, 373,
- 342, 380, 376, 381, 381, 81, 187, 188,
- 342, 342, 342, 342, 379, 342, 376, 381,
- 381, 81, 187, 188, 342, 342, 342, 342,
- 379, 342, 95, 382, 342, 187, 188, 342,
- 342, 342, 342, 347, 342, 187, 188, 342,
- 342, 342, 342, 347, 342, 383, 342, 342,
- 342, 188, 342, 188, 342, 384, 342, 385,
- 342, 386, 387, 342, 187, 188, 342, 342,
- 342, 79, 342, 342, 342, 77, 342, 78,
- 342, 342, 342, 342, 187, 188, 342, 187,
- 188, 342, 385, 342, 342, 342, 342, 187,
- 188, 342, 385, 342, 386, 342, 342, 187,
- 188, 342, 342, 342, 79, 342, 95, 342,
- 388, 388, 81, 187, 188, 342, 342, 342,
- 342, 347, 342, 389, 104, 390, 391, 85,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 104, 390, 391, 85, 187, 188, 342, 342,
- 342, 342, 347, 342, 390, 390, 85, 187,
- 188, 342, 342, 342, 342, 347, 342, 392,
- 101, 393, 394, 88, 187, 188, 342, 342,
- 342, 342, 347, 342, 101, 393, 394, 88,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 393, 393, 88, 187, 188, 342, 342, 342,
- 342, 347, 342, 395, 98, 396, 397, 91,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 98, 396, 397, 91, 187, 188, 342, 342,
- 342, 342, 347, 342, 396, 396, 91, 187,
- 188, 342, 342, 342, 342, 347, 342, 398,
- 95, 342, 399, 342, 187, 188, 342, 342,
- 342, 342, 347, 342, 95, 342, 399, 342,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 400, 342, 187, 188, 342, 342, 342, 342,
- 347, 342, 95, 342, 342, 342, 342, 187,
- 188, 342, 342, 342, 342, 347, 342, 77,
- 78, 342, 342, 95, 382, 342, 187, 188,
- 342, 342, 342, 342, 347, 342, 77, 342,
- 375, 376, 381, 381, 81, 187, 188, 342,
- 342, 342, 342, 379, 342, 375, 376, 377,
- 381, 81, 187, 188, 342, 342, 342, 106,
- 379, 342, 373, 342, 401, 342, 388, 388,
- 81, 187, 188, 342, 342, 342, 342, 347,
- 342, 373, 342, 373, 342, 342, 342, 342,
- 342, 342, 187, 188, 342, 342, 342, 342,
- 347, 342, 373, 342, 373, 342, 342, 342,
- 342, 402, 342, 187, 188, 342, 342, 342,
- 342, 347, 342, 373, 342, 373, 342, 401,
- 342, 342, 342, 342, 187, 188, 342, 342,
- 342, 342, 347, 342, 373, 342, 373, 78,
- 342, 342, 95, 374, 342, 187, 188, 342,
- 342, 342, 342, 347, 342, 373, 342, 366,
- 367, 372, 372, 81, 187, 188, 342, 342,
- 342, 342, 370, 342, 366, 367, 368, 372,
- 81, 187, 188, 342, 342, 342, 108, 370,
- 342, 364, 342, 403, 342, 388, 388, 81,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 364, 342, 364, 342, 342, 342, 342, 342,
- 342, 187, 188, 342, 342, 342, 342, 347,
- 342, 364, 342, 364, 342, 342, 342, 342,
- 404, 342, 187, 188, 342, 342, 342, 342,
- 347, 342, 364, 342, 364, 342, 403, 342,
- 342, 342, 342, 187, 188, 342, 342, 342,
- 342, 347, 342, 364, 342, 364, 78, 342,
- 342, 95, 365, 342, 187, 188, 342, 342,
- 342, 342, 347, 342, 364, 342, 357, 358,
- 363, 363, 81, 187, 188, 342, 342, 342,
- 342, 361, 342, 357, 358, 359, 363, 81,
- 187, 188, 342, 342, 342, 110, 361, 342,
- 355, 342, 405, 342, 388, 388, 81, 187,
- 188, 342, 342, 342, 342, 347, 342, 355,
- 342, 355, 342, 342, 342, 342, 342, 342,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 355, 342, 355, 342, 342, 342, 342, 406,
- 342, 187, 188, 342, 342, 342, 342, 347,
- 342, 355, 342, 355, 342, 405, 342, 342,
- 342, 342, 187, 188, 342, 342, 342, 342,
- 347, 342, 355, 342, 355, 78, 342, 342,
- 95, 356, 342, 187, 188, 342, 342, 342,
- 342, 347, 342, 355, 342, 348, 349, 354,
- 354, 81, 187, 188, 342, 342, 342, 342,
- 352, 342, 348, 349, 350, 354, 81, 187,
- 188, 342, 342, 342, 112, 352, 342, 345,
- 342, 407, 342, 388, 388, 81, 187, 188,
- 342, 342, 342, 342, 347, 342, 345, 342,
- 345, 342, 342, 342, 342, 342, 342, 187,
- 188, 342, 342, 342, 342, 347, 342, 345,
- 342, 345, 342, 342, 342, 342, 408, 342,
- 187, 188, 342, 342, 342, 342, 347, 342,
- 345, 342, 345, 342, 407, 342, 342, 342,
- 342, 187, 188, 342, 342, 342, 342, 347,
- 342, 345, 342, 345, 78, 342, 342, 95,
- 346, 342, 187, 188, 342, 342, 342, 342,
- 347, 342, 345, 342, 113, 80, 80, 81,
- 409, 409, 409, 409, 409, 152, 113, 409,
- 183, 184, 344, 344, 81, 187, 188, 342,
- 342, 342, 342, 190, 342, 113, 80, 80,
- 81, 409, 409, 409, 409, 409, 409, 113,
- 409, 411, 412, 413, 414, 119, 415, 416,
- 410, 410, 410, 151, 417, 410, 418, 412,
- 414, 414, 119, 415, 416, 410, 410, 410,
- 410, 417, 410, 412, 414, 414, 119, 415,
- 416, 410, 410, 410, 410, 417, 410, 419,
- 410, 410, 410, 132, 420, 410, 415, 416,
- 410, 410, 410, 410, 421, 410, 419, 410,
- 422, 423, 424, 425, 119, 415, 416, 410,
- 410, 410, 149, 426, 410, 410, 419, 410,
- 427, 423, 428, 428, 119, 415, 416, 410,
- 410, 410, 410, 426, 410, 423, 428, 428,
- 119, 415, 416, 410, 410, 410, 410, 426,
- 410, 429, 410, 410, 410, 132, 430, 410,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 429, 410, 431, 432, 433, 434, 119, 415,
- 416, 410, 410, 410, 147, 435, 410, 410,
- 429, 410, 436, 432, 437, 437, 119, 415,
- 416, 410, 410, 410, 410, 435, 410, 432,
- 437, 437, 119, 415, 416, 410, 410, 410,
- 410, 435, 410, 438, 410, 410, 410, 132,
- 439, 410, 415, 416, 410, 410, 410, 410,
- 421, 410, 438, 410, 440, 441, 442, 443,
- 119, 415, 416, 410, 410, 410, 145, 444,
- 410, 410, 438, 410, 445, 441, 446, 446,
- 119, 415, 416, 410, 410, 410, 410, 444,
- 410, 441, 446, 446, 119, 415, 416, 410,
- 410, 410, 410, 444, 410, 447, 410, 410,
- 410, 132, 448, 410, 415, 416, 410, 410,
- 410, 410, 421, 410, 447, 410, 449, 450,
- 451, 452, 119, 415, 416, 410, 410, 410,
- 143, 453, 410, 410, 447, 410, 454, 450,
- 455, 455, 119, 415, 416, 410, 410, 410,
- 410, 453, 410, 450, 455, 455, 119, 415,
- 416, 410, 410, 410, 410, 453, 410, 132,
- 456, 410, 415, 416, 410, 410, 410, 410,
- 421, 410, 415, 416, 410, 410, 410, 410,
- 421, 410, 457, 410, 410, 410, 416, 410,
- 416, 410, 458, 410, 459, 410, 460, 461,
- 410, 415, 416, 410, 410, 410, 117, 410,
- 410, 410, 115, 410, 116, 410, 410, 410,
- 410, 415, 416, 410, 415, 416, 410, 459,
- 410, 410, 410, 410, 415, 416, 410, 459,
- 410, 460, 410, 410, 415, 416, 410, 410,
- 410, 117, 410, 132, 410, 462, 462, 119,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 463, 141, 464, 465, 122, 415, 416, 410,
- 410, 410, 410, 421, 410, 141, 464, 465,
- 122, 415, 416, 410, 410, 410, 410, 421,
- 410, 464, 464, 122, 415, 416, 410, 410,
- 410, 410, 421, 410, 466, 138, 467, 468,
- 125, 415, 416, 410, 410, 410, 410, 421,
- 410, 138, 467, 468, 125, 415, 416, 410,
- 410, 410, 410, 421, 410, 467, 467, 125,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 469, 135, 470, 471, 128, 415, 416, 410,
- 410, 410, 410, 421, 410, 135, 470, 471,
- 128, 415, 416, 410, 410, 410, 410, 421,
- 410, 470, 470, 128, 415, 416, 410, 410,
- 410, 410, 421, 410, 472, 132, 410, 473,
- 410, 415, 416, 410, 410, 410, 410, 421,
- 410, 132, 410, 473, 410, 415, 416, 410,
- 410, 410, 410, 421, 410, 474, 410, 415,
- 416, 410, 410, 410, 410, 421, 410, 132,
- 410, 410, 410, 410, 415, 416, 410, 410,
- 410, 410, 421, 410, 115, 116, 410, 410,
- 132, 456, 410, 415, 416, 410, 410, 410,
- 410, 421, 410, 115, 410, 449, 450, 455,
- 455, 119, 415, 416, 410, 410, 410, 410,
- 453, 410, 449, 450, 451, 455, 119, 415,
- 416, 410, 410, 410, 143, 453, 410, 447,
- 410, 475, 410, 462, 462, 119, 415, 416,
- 410, 410, 410, 410, 421, 410, 447, 410,
- 447, 410, 410, 410, 410, 410, 410, 415,
- 416, 410, 410, 410, 410, 421, 410, 447,
- 410, 447, 410, 410, 410, 410, 476, 410,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 447, 410, 447, 410, 475, 410, 410, 410,
- 410, 415, 416, 410, 410, 410, 410, 421,
- 410, 447, 410, 447, 116, 410, 410, 132,
- 448, 410, 415, 416, 410, 410, 410, 410,
- 421, 410, 447, 410, 440, 441, 446, 446,
- 119, 415, 416, 410, 410, 410, 410, 444,
- 410, 440, 441, 442, 446, 119, 415, 416,
- 410, 410, 410, 145, 444, 410, 438, 410,
- 477, 410, 462, 462, 119, 415, 416, 410,
- 410, 410, 410, 421, 410, 438, 410, 438,
- 410, 410, 410, 410, 410, 410, 415, 416,
- 410, 410, 410, 410, 421, 410, 438, 410,
- 438, 410, 410, 410, 410, 478, 410, 415,
- 416, 410, 410, 410, 410, 421, 410, 438,
- 410, 438, 410, 477, 410, 410, 410, 410,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 438, 410, 438, 116, 410, 410, 132, 439,
- 410, 415, 416, 410, 410, 410, 410, 421,
- 410, 438, 410, 431, 432, 437, 437, 119,
- 415, 416, 410, 410, 410, 410, 435, 410,
- 431, 432, 433, 437, 119, 415, 416, 410,
- 410, 410, 147, 435, 410, 429, 410, 479,
- 410, 462, 462, 119, 415, 416, 410, 410,
- 410, 410, 421, 410, 429, 410, 429, 410,
- 410, 410, 410, 410, 410, 415, 416, 410,
- 410, 410, 410, 421, 410, 429, 410, 429,
- 410, 410, 410, 410, 480, 410, 415, 416,
- 410, 410, 410, 410, 421, 410, 429, 410,
- 429, 410, 479, 410, 410, 410, 410, 415,
- 416, 410, 410, 410, 410, 421, 410, 429,
- 410, 429, 116, 410, 410, 132, 430, 410,
- 415, 416, 410, 410, 410, 410, 421, 410,
- 429, 410, 422, 423, 428, 428, 119, 415,
- 416, 410, 410, 410, 410, 426, 410, 422,
- 423, 424, 428, 119, 415, 416, 410, 410,
- 410, 149, 426, 410, 419, 410, 481, 410,
- 462, 462, 119, 415, 416, 410, 410, 410,
- 410, 421, 410, 419, 410, 419, 410, 410,
- 410, 410, 410, 410, 415, 416, 410, 410,
- 410, 410, 421, 410, 419, 410, 419, 410,
- 410, 410, 410, 482, 410, 415, 416, 410,
- 410, 410, 410, 421, 410, 419, 410, 419,
- 410, 481, 410, 410, 410, 410, 415, 416,
- 410, 410, 410, 410, 421, 410, 419, 410,
- 419, 116, 410, 410, 132, 420, 410, 415,
- 416, 410, 410, 410, 410, 421, 410, 419,
- 410, 411, 412, 414, 414, 119, 415, 416,
- 410, 410, 410, 410, 417, 410, 181, 182,
- 183, 184, 483, 344, 81, 187, 188, 342,
- 189, 189, 152, 190, 342, 181, 342, 194,
- 484, 196, 197, 5, 198, 199, 200, 193,
- 193, 37, 201, 193, 193, 181, 193, 204,
- 182, 183, 184, 485, 486, 81, 487, 488,
- 193, 189, 189, 152, 489, 193, 204, 193,
- 113, 80, 80, 81, 198, 199, 193, 193,
- 193, 152, 490, 193, 491, 2, 342, 342,
- 342, 408, 342, 187, 188, 342, 342, 342,
- 342, 347, 342, 491, 342, 492, 349, 493,
- 494, 81, 487, 488, 193, 193, 193, 153,
- 352, 193, 193, 491, 193, 495, 349, 354,
- 354, 81, 487, 488, 193, 193, 193, 193,
- 352, 193, 349, 354, 354, 81, 487, 488,
- 193, 193, 193, 193, 352, 193, 496, 193,
- 193, 193, 488, 193, 488, 193, 243, 193,
- 492, 349, 354, 354, 81, 487, 488, 193,
- 193, 193, 193, 352, 193, 492, 349, 493,
- 354, 81, 487, 488, 193, 193, 193, 153,
- 352, 193, 204, 193, 266, 113, 497, 497,
- 155, 198, 199, 193, 193, 193, 193, 490,
- 193, 204, 193, 498, 179, 499, 500, 157,
- 487, 488, 193, 193, 193, 193, 501, 193,
- 179, 499, 500, 157, 487, 488, 193, 193,
- 193, 193, 501, 193, 499, 499, 157, 487,
- 488, 193, 193, 193, 193, 501, 193, 502,
- 176, 503, 504, 160, 487, 488, 193, 193,
- 193, 193, 501, 193, 176, 503, 504, 160,
- 487, 488, 193, 193, 193, 193, 501, 193,
- 503, 503, 160, 487, 488, 193, 193, 193,
- 193, 501, 193, 505, 173, 506, 507, 163,
- 487, 488, 193, 193, 193, 193, 501, 193,
- 173, 506, 507, 163, 487, 488, 193, 193,
- 193, 193, 501, 193, 506, 506, 163, 487,
- 488, 193, 193, 193, 193, 501, 193, 508,
- 170, 193, 509, 193, 487, 488, 193, 193,
- 193, 193, 501, 193, 170, 193, 509, 193,
- 487, 488, 193, 193, 193, 193, 501, 193,
- 487, 488, 193, 193, 193, 193, 501, 193,
- 510, 193, 511, 512, 193, 487, 488, 193,
- 193, 193, 167, 193, 193, 193, 165, 193,
- 166, 193, 193, 193, 193, 487, 488, 193,
- 487, 488, 193, 510, 193, 193, 193, 193,
- 487, 488, 193, 510, 193, 511, 193, 193,
- 487, 488, 193, 193, 193, 167, 193, 491,
- 166, 342, 342, 95, 346, 342, 187, 188,
- 342, 342, 342, 342, 347, 342, 491, 342,
- 0
+ 183, 184, 185, 186, 81, 187, 188, 189,
+ 190, 190, 152, 191, 192, 193, 194, 195,
+ 180, 180, 180, 180, 180, 180, 180, 180,
+ 180, 180, 180, 180, 196, 180, 198, 199,
+ 200, 201, 5, 202, 203, 204, 197, 197,
+ 37, 205, 197, 197, 206, 207, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 208, 197, 209, 199, 210, 210,
+ 5, 202, 203, 204, 197, 197, 197, 205,
+ 197, 197, 206, 207, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 208, 197, 199, 210, 210, 5, 202, 203,
+ 204, 197, 197, 197, 205, 197, 197, 206,
+ 207, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 208, 197, 211,
+ 197, 197, 197, 18, 212, 197, 202, 203,
+ 204, 197, 197, 197, 213, 197, 211, 197,
+ 207, 197, 214, 215, 216, 217, 5, 202,
+ 203, 204, 197, 197, 35, 218, 197, 197,
+ 206, 207, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 208, 197,
+ 219, 215, 220, 220, 5, 202, 203, 204,
+ 197, 197, 197, 218, 197, 197, 206, 207,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 208, 197, 215, 220,
+ 220, 5, 202, 203, 204, 197, 197, 197,
+ 218, 197, 197, 206, 207, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 208, 197, 221, 197, 197, 197, 18,
+ 222, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 221, 197, 207, 197, 223, 224,
+ 225, 226, 5, 202, 203, 204, 197, 197,
+ 33, 227, 197, 197, 206, 207, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 208, 197, 228, 224, 229, 229,
+ 5, 202, 203, 204, 197, 197, 197, 227,
+ 197, 197, 206, 207, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 208, 197, 224, 229, 229, 5, 202, 203,
+ 204, 197, 197, 197, 227, 197, 197, 206,
+ 207, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 208, 197, 230,
+ 197, 197, 197, 18, 231, 197, 202, 203,
+ 204, 197, 197, 197, 213, 197, 230, 197,
+ 207, 197, 232, 233, 234, 235, 5, 202,
+ 203, 204, 197, 197, 31, 236, 197, 197,
+ 206, 207, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 208, 197,
+ 237, 233, 238, 238, 5, 202, 203, 204,
+ 197, 197, 197, 236, 197, 197, 206, 207,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 208, 197, 233, 238,
+ 238, 5, 202, 203, 204, 197, 197, 197,
+ 236, 197, 197, 206, 207, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 208, 197, 239, 197, 197, 197, 18,
+ 240, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 239, 197, 207, 197, 241, 242,
+ 243, 244, 5, 202, 203, 204, 197, 197,
+ 29, 245, 197, 197, 206, 207, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 208, 197, 246, 242, 247, 247,
+ 5, 202, 203, 204, 197, 197, 197, 245,
+ 197, 197, 206, 207, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 208, 197, 242, 247, 247, 5, 202, 203,
+ 204, 197, 197, 197, 245, 197, 197, 206,
+ 207, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 208, 197, 18,
+ 248, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 202, 203,
+ 204, 197, 197, 197, 213, 197, 197, 197,
+ 207, 197, 249, 197, 197, 250, 203, 204,
+ 197, 203, 204, 197, 203, 251, 197, 203,
+ 197, 249, 197, 197, 197, 203, 204, 197,
+ 252, 197, 253, 254, 197, 202, 203, 204,
+ 197, 197, 3, 197, 197, 197, 197, 207,
+ 197, 2, 197, 197, 197, 197, 202, 203,
+ 204, 197, 197, 197, 197, 197, 197, 197,
+ 207, 197, 202, 203, 204, 197, 197, 197,
+ 197, 197, 197, 197, 207, 197, 255, 197,
+ 197, 197, 197, 202, 203, 204, 197, 202,
+ 203, 204, 197, 252, 197, 197, 197, 197,
+ 202, 203, 204, 197, 197, 197, 197, 197,
+ 197, 197, 207, 197, 252, 197, 253, 197,
+ 197, 202, 203, 204, 197, 197, 3, 197,
+ 197, 197, 197, 207, 197, 18, 197, 256,
+ 256, 5, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 257, 27,
+ 258, 259, 8, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 27,
+ 258, 259, 8, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 258,
+ 258, 8, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 260, 24,
+ 261, 262, 11, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 24,
+ 261, 262, 11, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 261,
+ 261, 11, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 263, 21,
+ 264, 265, 14, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 21,
+ 264, 265, 14, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 264,
+ 264, 14, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 266, 18,
+ 197, 267, 197, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 18,
+ 197, 267, 197, 202, 203, 204, 197, 197,
+ 197, 213, 197, 197, 197, 207, 197, 268,
+ 197, 202, 203, 204, 197, 197, 197, 213,
+ 197, 197, 197, 207, 197, 18, 197, 197,
+ 197, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 197, 197, 207, 197, 1, 2,
+ 197, 197, 18, 248, 197, 202, 203, 204,
+ 197, 197, 197, 213, 197, 1, 197, 207,
+ 197, 242, 247, 247, 5, 202, 203, 204,
+ 197, 197, 197, 245, 197, 197, 197, 207,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 208, 197, 242, 247,
+ 247, 5, 202, 203, 204, 197, 197, 197,
+ 245, 197, 197, 197, 207, 197, 241, 242,
+ 247, 247, 5, 202, 203, 204, 197, 197,
+ 197, 245, 197, 197, 206, 207, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 208, 197, 241, 242, 243, 247,
+ 5, 202, 203, 204, 197, 197, 29, 245,
+ 197, 197, 206, 207, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 208, 197, 239, 197, 269, 197, 256, 256,
+ 5, 202, 203, 204, 197, 197, 197, 213,
+ 197, 239, 197, 207, 197, 239, 197, 197,
+ 197, 197, 197, 197, 202, 203, 204, 197,
+ 197, 197, 213, 197, 239, 197, 207, 197,
+ 239, 197, 197, 197, 197, 270, 197, 202,
+ 203, 204, 197, 197, 197, 213, 197, 239,
+ 197, 207, 197, 239, 197, 269, 197, 197,
+ 197, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 239, 197, 207, 197, 239, 2,
+ 197, 197, 18, 240, 197, 202, 203, 204,
+ 197, 197, 197, 213, 197, 239, 197, 207,
+ 197, 232, 233, 238, 238, 5, 202, 203,
+ 204, 197, 197, 197, 236, 197, 197, 206,
+ 207, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 208, 197, 232,
+ 233, 234, 238, 5, 202, 203, 204, 197,
+ 197, 31, 236, 197, 197, 206, 207, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 208, 197, 230, 197, 271,
+ 197, 256, 256, 5, 202, 203, 204, 197,
+ 197, 197, 213, 197, 230, 197, 207, 197,
+ 230, 197, 197, 197, 197, 197, 197, 202,
+ 203, 204, 197, 197, 197, 213, 197, 230,
+ 197, 207, 197, 230, 197, 197, 197, 197,
+ 272, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 230, 197, 207, 197, 230, 197,
+ 271, 197, 197, 197, 197, 202, 203, 204,
+ 197, 197, 197, 213, 197, 230, 197, 207,
+ 197, 230, 2, 197, 197, 18, 231, 197,
+ 202, 203, 204, 197, 197, 197, 213, 197,
+ 230, 197, 207, 197, 223, 224, 229, 229,
+ 5, 202, 203, 204, 197, 197, 197, 227,
+ 197, 197, 206, 207, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 208, 197, 223, 224, 225, 229, 5, 202,
+ 203, 204, 197, 197, 33, 227, 197, 197,
+ 206, 207, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 208, 197,
+ 221, 197, 273, 197, 256, 256, 5, 202,
+ 203, 204, 197, 197, 197, 213, 197, 221,
+ 197, 207, 197, 221, 197, 197, 197, 197,
+ 197, 197, 202, 203, 204, 197, 197, 197,
+ 213, 197, 221, 197, 207, 197, 221, 197,
+ 197, 197, 197, 274, 197, 202, 203, 204,
+ 197, 197, 197, 213, 197, 221, 197, 207,
+ 197, 221, 197, 273, 197, 197, 197, 197,
+ 202, 203, 204, 197, 197, 197, 213, 197,
+ 221, 197, 207, 197, 221, 2, 197, 197,
+ 18, 222, 197, 202, 203, 204, 197, 197,
+ 197, 213, 197, 221, 197, 207, 197, 214,
+ 215, 220, 220, 5, 202, 203, 204, 197,
+ 197, 197, 218, 197, 197, 206, 207, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 208, 197, 214, 215, 216,
+ 220, 5, 202, 203, 204, 197, 197, 35,
+ 218, 197, 197, 206, 207, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 208, 197, 211, 197, 275, 197, 256,
+ 256, 5, 202, 203, 204, 197, 197, 197,
+ 213, 197, 211, 197, 207, 197, 211, 197,
+ 197, 197, 197, 197, 197, 202, 203, 204,
+ 197, 197, 197, 213, 197, 211, 197, 207,
+ 197, 211, 197, 197, 197, 197, 276, 197,
+ 202, 203, 204, 197, 197, 197, 213, 197,
+ 211, 197, 207, 197, 211, 197, 275, 197,
+ 197, 197, 197, 202, 203, 204, 197, 197,
+ 197, 213, 197, 211, 197, 207, 197, 211,
+ 2, 197, 197, 18, 212, 197, 202, 203,
+ 204, 197, 197, 197, 213, 197, 211, 197,
+ 207, 197, 198, 199, 210, 210, 5, 202,
+ 203, 204, 197, 197, 197, 205, 197, 197,
+ 206, 207, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 208, 197,
+ 198, 199, 200, 210, 5, 202, 203, 204,
+ 197, 197, 37, 205, 197, 197, 206, 207,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 208, 197, 278, 279,
+ 280, 281, 43, 282, 283, 284, 277, 277,
+ 75, 285, 277, 277, 286, 287, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 288, 277, 289, 279, 290, 281,
+ 43, 282, 283, 284, 277, 277, 277, 285,
+ 277, 277, 286, 287, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 288, 277, 279, 290, 281, 43, 282, 283,
+ 284, 277, 277, 277, 285, 277, 277, 286,
+ 287, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 288, 277, 291,
+ 277, 277, 277, 56, 292, 277, 282, 283,
+ 284, 277, 277, 277, 293, 277, 291, 277,
+ 287, 277, 294, 295, 296, 297, 43, 282,
+ 283, 284, 277, 277, 73, 298, 277, 277,
+ 286, 287, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 288, 277,
+ 299, 295, 300, 300, 43, 282, 283, 284,
+ 277, 277, 277, 298, 277, 277, 286, 287,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 288, 277, 295, 300,
+ 300, 43, 282, 283, 284, 277, 277, 277,
+ 298, 277, 277, 286, 287, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 288, 277, 301, 277, 277, 277, 56,
+ 302, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 301, 277, 287, 277, 303, 304,
+ 305, 306, 43, 282, 283, 284, 277, 277,
+ 71, 307, 277, 277, 286, 287, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 288, 277, 308, 304, 309, 309,
+ 43, 282, 283, 284, 277, 277, 277, 307,
+ 277, 277, 286, 287, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 288, 277, 304, 309, 309, 43, 282, 283,
+ 284, 277, 277, 277, 307, 277, 277, 286,
+ 287, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 288, 277, 310,
+ 277, 277, 277, 56, 311, 277, 282, 283,
+ 284, 277, 277, 277, 293, 277, 310, 277,
+ 287, 277, 312, 313, 314, 315, 43, 282,
+ 283, 284, 277, 277, 69, 316, 277, 277,
+ 286, 287, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 288, 277,
+ 317, 313, 318, 318, 43, 282, 283, 284,
+ 277, 277, 277, 316, 277, 277, 286, 287,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 288, 277, 313, 318,
+ 318, 43, 282, 283, 284, 277, 277, 277,
+ 316, 277, 277, 286, 287, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 288, 277, 319, 277, 277, 277, 56,
+ 320, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 319, 277, 287, 277, 321, 322,
+ 323, 324, 43, 282, 283, 284, 277, 277,
+ 67, 325, 277, 277, 286, 287, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 288, 277, 326, 322, 327, 327,
+ 43, 282, 283, 284, 277, 277, 277, 325,
+ 277, 277, 286, 287, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 288, 277, 322, 327, 327, 43, 282, 283,
+ 284, 277, 277, 277, 325, 277, 277, 286,
+ 287, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 288, 277, 56,
+ 328, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 282, 283,
+ 284, 277, 277, 277, 293, 277, 277, 277,
+ 287, 277, 329, 277, 277, 330, 283, 284,
+ 277, 283, 284, 277, 283, 331, 277, 283,
+ 277, 329, 277, 277, 277, 283, 284, 277,
+ 332, 277, 333, 334, 277, 282, 283, 284,
+ 277, 277, 41, 277, 277, 277, 277, 287,
+ 277, 40, 277, 277, 277, 277, 282, 283,
+ 284, 277, 277, 277, 277, 277, 277, 277,
+ 287, 277, 282, 283, 284, 277, 277, 277,
+ 277, 277, 277, 277, 287, 277, 335, 277,
+ 277, 277, 277, 282, 283, 284, 277, 282,
+ 283, 284, 277, 332, 277, 277, 277, 277,
+ 282, 283, 284, 277, 277, 277, 277, 277,
+ 277, 277, 287, 277, 332, 277, 333, 277,
+ 277, 282, 283, 284, 277, 277, 41, 277,
+ 277, 277, 277, 287, 277, 56, 277, 336,
+ 336, 43, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 337, 65,
+ 338, 339, 46, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 65,
+ 338, 339, 46, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 338,
+ 338, 46, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 340, 62,
+ 341, 342, 49, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 62,
+ 341, 342, 49, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 341,
+ 341, 49, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 343, 59,
+ 344, 345, 52, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 59,
+ 344, 345, 52, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 344,
+ 344, 52, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 346, 56,
+ 277, 347, 277, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 56,
+ 277, 347, 277, 282, 283, 284, 277, 277,
+ 277, 293, 277, 277, 277, 287, 277, 348,
+ 277, 282, 283, 284, 277, 277, 277, 293,
+ 277, 277, 277, 287, 277, 56, 277, 277,
+ 277, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 277, 277, 287, 277, 39, 40,
+ 277, 277, 56, 328, 277, 282, 283, 284,
+ 277, 277, 277, 293, 277, 39, 277, 287,
+ 277, 322, 327, 327, 43, 282, 283, 284,
+ 277, 277, 277, 325, 277, 277, 277, 287,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 288, 277, 322, 327,
+ 327, 43, 282, 283, 284, 277, 277, 277,
+ 325, 277, 277, 277, 287, 277, 321, 322,
+ 327, 327, 43, 282, 283, 284, 277, 277,
+ 277, 325, 277, 277, 286, 287, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 288, 277, 321, 322, 323, 327,
+ 43, 282, 283, 284, 277, 277, 67, 325,
+ 277, 277, 286, 287, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 288, 277, 319, 277, 349, 277, 336, 336,
+ 43, 282, 283, 284, 277, 277, 277, 293,
+ 277, 319, 277, 287, 277, 319, 277, 277,
+ 277, 277, 277, 277, 282, 283, 284, 277,
+ 277, 277, 293, 277, 319, 277, 287, 277,
+ 319, 277, 277, 277, 277, 350, 277, 282,
+ 283, 284, 277, 277, 277, 293, 277, 319,
+ 277, 287, 277, 319, 277, 349, 277, 277,
+ 277, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 319, 277, 287, 277, 319, 40,
+ 277, 277, 56, 320, 277, 282, 283, 284,
+ 277, 277, 277, 293, 277, 319, 277, 287,
+ 277, 312, 313, 318, 318, 43, 282, 283,
+ 284, 277, 277, 277, 316, 277, 277, 286,
+ 287, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 288, 277, 312,
+ 313, 314, 318, 43, 282, 283, 284, 277,
+ 277, 69, 316, 277, 277, 286, 287, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 288, 277, 310, 277, 351,
+ 277, 336, 336, 43, 282, 283, 284, 277,
+ 277, 277, 293, 277, 310, 277, 287, 277,
+ 310, 277, 277, 277, 277, 277, 277, 282,
+ 283, 284, 277, 277, 277, 293, 277, 310,
+ 277, 287, 277, 310, 277, 277, 277, 277,
+ 352, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 310, 277, 287, 277, 310, 277,
+ 351, 277, 277, 277, 277, 282, 283, 284,
+ 277, 277, 277, 293, 277, 310, 277, 287,
+ 277, 310, 40, 277, 277, 56, 311, 277,
+ 282, 283, 284, 277, 277, 277, 293, 277,
+ 310, 277, 287, 277, 303, 304, 309, 309,
+ 43, 282, 283, 284, 277, 277, 277, 307,
+ 277, 277, 286, 287, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 288, 277, 303, 304, 305, 309, 43, 282,
+ 283, 284, 277, 277, 71, 307, 277, 277,
+ 286, 287, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 288, 277,
+ 301, 277, 353, 277, 336, 336, 43, 282,
+ 283, 284, 277, 277, 277, 293, 277, 301,
+ 277, 287, 277, 301, 277, 277, 277, 277,
+ 277, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 301, 277, 287, 277, 301, 277,
+ 277, 277, 277, 354, 277, 282, 283, 284,
+ 277, 277, 277, 293, 277, 301, 277, 287,
+ 277, 301, 277, 353, 277, 277, 277, 277,
+ 282, 283, 284, 277, 277, 277, 293, 277,
+ 301, 277, 287, 277, 301, 40, 277, 277,
+ 56, 302, 277, 282, 283, 284, 277, 277,
+ 277, 293, 277, 301, 277, 287, 277, 294,
+ 295, 300, 300, 43, 282, 283, 284, 277,
+ 277, 277, 298, 277, 277, 286, 287, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 288, 277, 294, 295, 296,
+ 300, 43, 282, 283, 284, 277, 277, 73,
+ 298, 277, 277, 286, 287, 277, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 288, 277, 291, 277, 355, 277, 336,
+ 336, 43, 282, 283, 284, 277, 277, 277,
+ 293, 277, 291, 277, 287, 277, 291, 277,
+ 277, 277, 277, 277, 277, 282, 283, 284,
+ 277, 277, 277, 293, 277, 291, 277, 287,
+ 277, 291, 277, 277, 277, 277, 356, 277,
+ 282, 283, 284, 277, 277, 277, 293, 277,
+ 291, 277, 287, 277, 291, 277, 355, 277,
+ 277, 277, 277, 282, 283, 284, 277, 277,
+ 277, 293, 277, 291, 277, 287, 277, 74,
+ 42, 42, 43, 277, 277, 277, 277, 277,
+ 277, 74, 277, 291, 40, 277, 277, 56,
+ 292, 277, 282, 283, 284, 277, 277, 277,
+ 293, 277, 291, 277, 287, 277, 278, 279,
+ 290, 281, 43, 282, 283, 284, 277, 277,
+ 277, 285, 277, 277, 286, 287, 277, 277,
+ 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 288, 277, 358, 184, 359, 359,
+ 81, 187, 188, 189, 357, 357, 357, 191,
+ 357, 357, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 184, 359, 359, 81, 187, 188,
+ 189, 357, 357, 357, 191, 357, 357, 194,
+ 360, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 196, 357, 361,
+ 357, 357, 357, 95, 362, 357, 187, 188,
+ 189, 357, 357, 357, 363, 357, 361, 357,
+ 360, 357, 364, 365, 366, 367, 81, 187,
+ 188, 189, 357, 357, 112, 368, 357, 357,
+ 194, 360, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 196, 357,
+ 369, 365, 370, 370, 81, 187, 188, 189,
+ 357, 357, 357, 368, 357, 357, 194, 360,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 196, 357, 365, 370,
+ 370, 81, 187, 188, 189, 357, 357, 357,
+ 368, 357, 357, 194, 360, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 196, 357, 371, 357, 357, 357, 95,
+ 372, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 371, 357, 360, 357, 373, 374,
+ 375, 376, 81, 187, 188, 189, 357, 357,
+ 110, 377, 357, 357, 194, 360, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 196, 357, 378, 374, 379, 379,
+ 81, 187, 188, 189, 357, 357, 357, 377,
+ 357, 357, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 374, 379, 379, 81, 187, 188,
+ 189, 357, 357, 357, 377, 357, 357, 194,
+ 360, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 196, 357, 380,
+ 357, 357, 357, 95, 381, 357, 187, 188,
+ 189, 357, 357, 357, 363, 357, 380, 357,
+ 360, 357, 382, 383, 384, 385, 81, 187,
+ 188, 189, 357, 357, 108, 386, 357, 357,
+ 194, 360, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 196, 357,
+ 387, 383, 388, 388, 81, 187, 188, 189,
+ 357, 357, 357, 386, 357, 357, 194, 360,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 196, 357, 383, 388,
+ 388, 81, 187, 188, 189, 357, 357, 357,
+ 386, 357, 357, 194, 360, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 196, 357, 389, 357, 357, 357, 95,
+ 390, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 389, 357, 360, 357, 391, 392,
+ 393, 394, 81, 187, 188, 189, 357, 357,
+ 106, 395, 357, 357, 194, 360, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 196, 357, 396, 392, 397, 397,
+ 81, 187, 188, 189, 357, 357, 357, 395,
+ 357, 357, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 392, 397, 397, 81, 187, 188,
+ 189, 357, 357, 357, 395, 357, 357, 194,
+ 360, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 196, 357, 95,
+ 398, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 187, 188,
+ 189, 357, 357, 357, 363, 357, 357, 357,
+ 360, 357, 399, 357, 357, 400, 188, 189,
+ 357, 188, 189, 357, 188, 401, 357, 188,
+ 357, 399, 357, 357, 357, 188, 189, 357,
+ 402, 357, 403, 404, 357, 187, 188, 189,
+ 357, 357, 79, 357, 357, 357, 357, 360,
+ 357, 78, 357, 357, 357, 357, 187, 188,
+ 189, 357, 357, 357, 357, 357, 357, 357,
+ 360, 357, 187, 188, 189, 357, 357, 357,
+ 357, 357, 357, 357, 360, 357, 405, 357,
+ 357, 357, 357, 187, 188, 189, 357, 187,
+ 188, 189, 357, 402, 357, 357, 357, 357,
+ 187, 188, 189, 357, 357, 357, 357, 357,
+ 357, 357, 360, 357, 402, 357, 403, 357,
+ 357, 187, 188, 189, 357, 357, 79, 357,
+ 357, 357, 357, 360, 357, 95, 357, 406,
+ 406, 81, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 407, 104,
+ 408, 409, 85, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 104,
+ 408, 409, 85, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 408,
+ 408, 85, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 410, 101,
+ 411, 412, 88, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 101,
+ 411, 412, 88, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 411,
+ 411, 88, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 413, 98,
+ 414, 415, 91, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 98,
+ 414, 415, 91, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 414,
+ 414, 91, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 416, 95,
+ 357, 417, 357, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 95,
+ 357, 417, 357, 187, 188, 189, 357, 357,
+ 357, 363, 357, 357, 357, 360, 357, 418,
+ 357, 187, 188, 189, 357, 357, 357, 363,
+ 357, 357, 357, 360, 357, 95, 357, 357,
+ 357, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 357, 357, 360, 357, 77, 78,
+ 357, 357, 95, 398, 357, 187, 188, 189,
+ 357, 357, 357, 363, 357, 77, 357, 360,
+ 357, 392, 397, 397, 81, 187, 188, 189,
+ 357, 357, 357, 395, 357, 357, 357, 360,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 196, 357, 392, 397,
+ 397, 81, 187, 188, 189, 357, 357, 357,
+ 395, 357, 357, 357, 360, 357, 391, 392,
+ 397, 397, 81, 187, 188, 189, 357, 357,
+ 357, 395, 357, 357, 194, 360, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 196, 357, 391, 392, 393, 397,
+ 81, 187, 188, 189, 357, 357, 106, 395,
+ 357, 357, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 389, 357, 419, 357, 406, 406,
+ 81, 187, 188, 189, 357, 357, 357, 363,
+ 357, 389, 357, 360, 357, 389, 357, 357,
+ 357, 357, 357, 357, 187, 188, 189, 357,
+ 357, 357, 363, 357, 389, 357, 360, 357,
+ 389, 357, 357, 357, 357, 420, 357, 187,
+ 188, 189, 357, 357, 357, 363, 357, 389,
+ 357, 360, 357, 389, 357, 419, 357, 357,
+ 357, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 389, 357, 360, 357, 389, 78,
+ 357, 357, 95, 390, 357, 187, 188, 189,
+ 357, 357, 357, 363, 357, 389, 357, 360,
+ 357, 382, 383, 388, 388, 81, 187, 188,
+ 189, 357, 357, 357, 386, 357, 357, 194,
+ 360, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 196, 357, 382,
+ 383, 384, 388, 81, 187, 188, 189, 357,
+ 357, 108, 386, 357, 357, 194, 360, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 196, 357, 380, 357, 421,
+ 357, 406, 406, 81, 187, 188, 189, 357,
+ 357, 357, 363, 357, 380, 357, 360, 357,
+ 380, 357, 357, 357, 357, 357, 357, 187,
+ 188, 189, 357, 357, 357, 363, 357, 380,
+ 357, 360, 357, 380, 357, 357, 357, 357,
+ 422, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 380, 357, 360, 357, 380, 357,
+ 421, 357, 357, 357, 357, 187, 188, 189,
+ 357, 357, 357, 363, 357, 380, 357, 360,
+ 357, 380, 78, 357, 357, 95, 381, 357,
+ 187, 188, 189, 357, 357, 357, 363, 357,
+ 380, 357, 360, 357, 373, 374, 379, 379,
+ 81, 187, 188, 189, 357, 357, 357, 377,
+ 357, 357, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 373, 374, 375, 379, 81, 187,
+ 188, 189, 357, 357, 110, 377, 357, 357,
+ 194, 360, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 196, 357,
+ 371, 357, 423, 357, 406, 406, 81, 187,
+ 188, 189, 357, 357, 357, 363, 357, 371,
+ 357, 360, 357, 371, 357, 357, 357, 357,
+ 357, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 371, 357, 360, 357, 371, 357,
+ 357, 357, 357, 424, 357, 187, 188, 189,
+ 357, 357, 357, 363, 357, 371, 357, 360,
+ 357, 371, 357, 423, 357, 357, 357, 357,
+ 187, 188, 189, 357, 357, 357, 363, 357,
+ 371, 357, 360, 357, 371, 78, 357, 357,
+ 95, 372, 357, 187, 188, 189, 357, 357,
+ 357, 363, 357, 371, 357, 360, 357, 364,
+ 365, 370, 370, 81, 187, 188, 189, 357,
+ 357, 357, 368, 357, 357, 194, 360, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 357, 196, 357, 364, 365, 366,
+ 370, 81, 187, 188, 189, 357, 357, 112,
+ 368, 357, 357, 194, 360, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 196, 357, 361, 357, 425, 357, 406,
+ 406, 81, 187, 188, 189, 357, 357, 357,
+ 363, 357, 361, 357, 360, 357, 361, 357,
+ 357, 357, 357, 357, 357, 187, 188, 189,
+ 357, 357, 357, 363, 357, 361, 357, 360,
+ 357, 361, 357, 357, 357, 357, 426, 357,
+ 187, 188, 189, 357, 357, 357, 363, 357,
+ 361, 357, 360, 357, 361, 357, 425, 357,
+ 357, 357, 357, 187, 188, 189, 357, 357,
+ 357, 363, 357, 361, 357, 360, 357, 361,
+ 78, 357, 357, 95, 362, 357, 187, 188,
+ 189, 357, 357, 357, 363, 357, 361, 357,
+ 360, 357, 113, 80, 80, 81, 427, 427,
+ 427, 427, 427, 152, 113, 427, 183, 184,
+ 359, 359, 81, 187, 188, 189, 357, 357,
+ 357, 191, 357, 357, 194, 360, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 357, 357, 196, 357, 113, 80, 80, 81,
+ 427, 427, 427, 427, 427, 427, 113, 427,
+ 429, 430, 431, 432, 119, 433, 434, 435,
+ 428, 428, 151, 436, 428, 428, 437, 438,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 439, 428, 440, 430,
+ 432, 432, 119, 433, 434, 435, 428, 428,
+ 428, 436, 428, 428, 437, 438, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 439, 428, 430, 432, 432, 119,
+ 433, 434, 435, 428, 428, 428, 436, 428,
+ 428, 437, 438, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 439,
+ 428, 441, 428, 428, 428, 132, 442, 428,
+ 433, 434, 435, 428, 428, 428, 443, 428,
+ 441, 428, 438, 428, 444, 445, 446, 447,
+ 119, 433, 434, 435, 428, 428, 149, 448,
+ 428, 428, 437, 438, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 439, 428, 449, 445, 450, 450, 119, 433,
+ 434, 435, 428, 428, 428, 448, 428, 428,
+ 437, 438, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 439, 428,
+ 445, 450, 450, 119, 433, 434, 435, 428,
+ 428, 428, 448, 428, 428, 437, 438, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 439, 428, 451, 428, 428,
+ 428, 132, 452, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 451, 428, 438, 428,
+ 453, 454, 455, 456, 119, 433, 434, 435,
+ 428, 428, 147, 457, 428, 428, 437, 438,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 439, 428, 458, 454,
+ 459, 459, 119, 433, 434, 435, 428, 428,
+ 428, 457, 428, 428, 437, 438, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 439, 428, 454, 459, 459, 119,
+ 433, 434, 435, 428, 428, 428, 457, 428,
+ 428, 437, 438, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 439,
+ 428, 460, 428, 428, 428, 132, 461, 428,
+ 433, 434, 435, 428, 428, 428, 443, 428,
+ 460, 428, 438, 428, 462, 463, 464, 465,
+ 119, 433, 434, 435, 428, 428, 145, 466,
+ 428, 428, 437, 438, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 439, 428, 467, 463, 468, 468, 119, 433,
+ 434, 435, 428, 428, 428, 466, 428, 428,
+ 437, 438, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 439, 428,
+ 463, 468, 468, 119, 433, 434, 435, 428,
+ 428, 428, 466, 428, 428, 437, 438, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 439, 428, 469, 428, 428,
+ 428, 132, 470, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 469, 428, 438, 428,
+ 471, 472, 473, 474, 119, 433, 434, 435,
+ 428, 428, 143, 475, 428, 428, 437, 438,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 439, 428, 476, 472,
+ 477, 477, 119, 433, 434, 435, 428, 428,
+ 428, 475, 428, 428, 437, 438, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 439, 428, 472, 477, 477, 119,
+ 433, 434, 435, 428, 428, 428, 475, 428,
+ 428, 437, 438, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 439,
+ 428, 132, 478, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 433, 434, 435, 428, 428, 428, 443, 428,
+ 428, 428, 438, 428, 479, 428, 428, 480,
+ 434, 435, 428, 434, 435, 428, 434, 481,
+ 428, 434, 428, 479, 428, 428, 428, 434,
+ 435, 428, 482, 428, 483, 484, 428, 433,
+ 434, 435, 428, 428, 117, 428, 428, 428,
+ 428, 438, 428, 116, 428, 428, 428, 428,
+ 433, 434, 435, 428, 428, 428, 428, 428,
+ 428, 428, 438, 428, 433, 434, 435, 428,
+ 428, 428, 428, 428, 428, 428, 438, 428,
+ 485, 428, 428, 428, 428, 433, 434, 435,
+ 428, 433, 434, 435, 428, 482, 428, 428,
+ 428, 428, 433, 434, 435, 428, 428, 428,
+ 428, 428, 428, 428, 438, 428, 482, 428,
+ 483, 428, 428, 433, 434, 435, 428, 428,
+ 117, 428, 428, 428, 428, 438, 428, 132,
+ 428, 486, 486, 119, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 487, 141, 488, 489, 122, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 141, 488, 489, 122, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 488, 488, 122, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 490, 138, 491, 492, 125, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 138, 491, 492, 125, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 491, 491, 125, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 493, 135, 494, 495, 128, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 135, 494, 495, 128, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 494, 494, 128, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 496, 132, 428, 497, 428, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 132, 428, 497, 428, 433, 434, 435,
+ 428, 428, 428, 443, 428, 428, 428, 438,
+ 428, 498, 428, 433, 434, 435, 428, 428,
+ 428, 443, 428, 428, 428, 438, 428, 132,
+ 428, 428, 428, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 428, 428, 438, 428,
+ 115, 116, 428, 428, 132, 478, 428, 433,
+ 434, 435, 428, 428, 428, 443, 428, 115,
+ 428, 438, 428, 472, 477, 477, 119, 433,
+ 434, 435, 428, 428, 428, 475, 428, 428,
+ 428, 438, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 439, 428,
+ 472, 477, 477, 119, 433, 434, 435, 428,
+ 428, 428, 475, 428, 428, 428, 438, 428,
+ 471, 472, 477, 477, 119, 433, 434, 435,
+ 428, 428, 428, 475, 428, 428, 437, 438,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 439, 428, 471, 472,
+ 473, 477, 119, 433, 434, 435, 428, 428,
+ 143, 475, 428, 428, 437, 438, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 439, 428, 469, 428, 499, 428,
+ 486, 486, 119, 433, 434, 435, 428, 428,
+ 428, 443, 428, 469, 428, 438, 428, 469,
+ 428, 428, 428, 428, 428, 428, 433, 434,
+ 435, 428, 428, 428, 443, 428, 469, 428,
+ 438, 428, 469, 428, 428, 428, 428, 500,
+ 428, 433, 434, 435, 428, 428, 428, 443,
+ 428, 469, 428, 438, 428, 469, 428, 499,
+ 428, 428, 428, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 469, 428, 438, 428,
+ 469, 116, 428, 428, 132, 470, 428, 433,
+ 434, 435, 428, 428, 428, 443, 428, 469,
+ 428, 438, 428, 462, 463, 468, 468, 119,
+ 433, 434, 435, 428, 428, 428, 466, 428,
+ 428, 437, 438, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 439,
+ 428, 462, 463, 464, 468, 119, 433, 434,
+ 435, 428, 428, 145, 466, 428, 428, 437,
+ 438, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 439, 428, 460,
+ 428, 501, 428, 486, 486, 119, 433, 434,
+ 435, 428, 428, 428, 443, 428, 460, 428,
+ 438, 428, 460, 428, 428, 428, 428, 428,
+ 428, 433, 434, 435, 428, 428, 428, 443,
+ 428, 460, 428, 438, 428, 460, 428, 428,
+ 428, 428, 502, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 460, 428, 438, 428,
+ 460, 428, 501, 428, 428, 428, 428, 433,
+ 434, 435, 428, 428, 428, 443, 428, 460,
+ 428, 438, 428, 460, 116, 428, 428, 132,
+ 461, 428, 433, 434, 435, 428, 428, 428,
+ 443, 428, 460, 428, 438, 428, 453, 454,
+ 459, 459, 119, 433, 434, 435, 428, 428,
+ 428, 457, 428, 428, 437, 438, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 439, 428, 453, 454, 455, 459,
+ 119, 433, 434, 435, 428, 428, 147, 457,
+ 428, 428, 437, 438, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 439, 428, 451, 428, 503, 428, 486, 486,
+ 119, 433, 434, 435, 428, 428, 428, 443,
+ 428, 451, 428, 438, 428, 451, 428, 428,
+ 428, 428, 428, 428, 433, 434, 435, 428,
+ 428, 428, 443, 428, 451, 428, 438, 428,
+ 451, 428, 428, 428, 428, 504, 428, 433,
+ 434, 435, 428, 428, 428, 443, 428, 451,
+ 428, 438, 428, 451, 428, 503, 428, 428,
+ 428, 428, 433, 434, 435, 428, 428, 428,
+ 443, 428, 451, 428, 438, 428, 451, 116,
+ 428, 428, 132, 452, 428, 433, 434, 435,
+ 428, 428, 428, 443, 428, 451, 428, 438,
+ 428, 444, 445, 450, 450, 119, 433, 434,
+ 435, 428, 428, 428, 448, 428, 428, 437,
+ 438, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 439, 428, 444,
+ 445, 446, 450, 119, 433, 434, 435, 428,
+ 428, 149, 448, 428, 428, 437, 438, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 428, 428, 428, 439, 428, 441, 428, 505,
+ 428, 486, 486, 119, 433, 434, 435, 428,
+ 428, 428, 443, 428, 441, 428, 438, 428,
+ 441, 428, 428, 428, 428, 428, 428, 433,
+ 434, 435, 428, 428, 428, 443, 428, 441,
+ 428, 438, 428, 441, 428, 428, 428, 428,
+ 506, 428, 433, 434, 435, 428, 428, 428,
+ 443, 428, 441, 428, 438, 428, 441, 428,
+ 505, 428, 428, 428, 428, 433, 434, 435,
+ 428, 428, 428, 443, 428, 441, 428, 438,
+ 428, 441, 116, 428, 428, 132, 442, 428,
+ 433, 434, 435, 428, 428, 428, 443, 428,
+ 441, 428, 438, 428, 429, 430, 432, 432,
+ 119, 433, 434, 435, 428, 428, 428, 436,
+ 428, 428, 437, 438, 428, 428, 428, 428,
+ 428, 428, 428, 428, 428, 428, 428, 428,
+ 439, 428, 181, 182, 183, 184, 507, 359,
+ 81, 187, 188, 189, 190, 190, 152, 191,
+ 357, 181, 194, 360, 357, 357, 357, 357,
+ 357, 357, 357, 357, 357, 357, 357, 357,
+ 196, 357, 198, 508, 200, 201, 5, 202,
+ 203, 204, 197, 197, 37, 205, 197, 197,
+ 206, 207, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 208, 197,
+ 211, 182, 183, 184, 509, 510, 81, 511,
+ 203, 512, 190, 190, 152, 513, 197, 211,
+ 194, 514, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 196, 197,
+ 113, 80, 80, 81, 202, 203, 204, 197,
+ 197, 152, 515, 197, 197, 197, 207, 197,
+ 516, 2, 357, 357, 357, 426, 357, 187,
+ 188, 189, 357, 357, 357, 363, 357, 516,
+ 357, 360, 357, 517, 365, 518, 519, 81,
+ 511, 203, 512, 197, 197, 153, 368, 197,
+ 197, 194, 514, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 196,
+ 197, 520, 365, 370, 370, 81, 511, 203,
+ 512, 197, 197, 197, 368, 197, 197, 194,
+ 514, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 197, 197, 196, 197, 365,
+ 370, 370, 81, 511, 203, 512, 197, 197,
+ 197, 368, 197, 197, 194, 514, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 196, 197, 521, 197, 197, 522,
+ 203, 512, 197, 203, 512, 197, 203, 523,
+ 197, 203, 197, 521, 197, 197, 197, 203,
+ 512, 197, 524, 197, 197, 197, 197, 511,
+ 203, 512, 197, 511, 203, 512, 197, 517,
+ 365, 370, 370, 81, 511, 203, 512, 197,
+ 197, 197, 368, 197, 197, 194, 514, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 196, 197, 517, 365, 518,
+ 370, 81, 511, 203, 512, 197, 197, 153,
+ 368, 197, 197, 194, 514, 197, 197, 197,
+ 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 196, 197, 211, 197, 275, 113, 525,
+ 525, 155, 202, 203, 204, 197, 197, 197,
+ 515, 197, 211, 197, 207, 197, 526, 179,
+ 527, 528, 157, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 179,
+ 527, 528, 157, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 527,
+ 527, 157, 511, 203, 512, 197, 197, 197,
+ 529, 197, 197, 197, 514, 197, 530, 176,
+ 531, 532, 160, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 176,
+ 531, 532, 160, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 531,
+ 531, 160, 511, 203, 512, 197, 197, 197,
+ 529, 197, 197, 197, 514, 197, 533, 173,
+ 534, 535, 163, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 173,
+ 534, 535, 163, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 534,
+ 534, 163, 511, 203, 512, 197, 197, 197,
+ 529, 197, 197, 197, 514, 197, 536, 170,
+ 197, 537, 197, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 170,
+ 197, 537, 197, 511, 203, 512, 197, 197,
+ 197, 529, 197, 197, 197, 514, 197, 511,
+ 203, 512, 197, 197, 197, 529, 197, 197,
+ 197, 514, 197, 538, 197, 539, 540, 197,
+ 511, 203, 512, 197, 197, 167, 197, 197,
+ 197, 197, 514, 197, 166, 197, 197, 197,
+ 197, 511, 203, 512, 197, 197, 197, 197,
+ 197, 197, 197, 514, 197, 511, 203, 512,
+ 197, 197, 197, 197, 197, 197, 197, 514,
+ 197, 538, 197, 197, 197, 197, 511, 203,
+ 512, 197, 197, 197, 197, 197, 197, 197,
+ 514, 197, 538, 197, 539, 197, 197, 511,
+ 203, 512, 197, 197, 167, 197, 197, 197,
+ 197, 514, 197, 516, 166, 357, 357, 95,
+ 362, 357, 187, 188, 189, 357, 357, 357,
+ 363, 357, 516, 357, 360, 357, 542, 541,
+ 541, 541, 541, 543, 544, 545, 541, 543,
+ 544, 545, 541, 546, 541, 541, 547, 544,
+ 545, 541, 544, 545, 541, 544, 548, 541,
+ 544, 541, 546, 541, 541, 541, 544, 545,
+ 541, 0
};
static const short _indic_syllable_machine_trans_targs[] = {
- 170, 195, 197, 198, 3, 201, 4, 6,
- 204, 7, 9, 207, 10, 12, 210, 13,
- 15, 16, 191, 18, 19, 209, 21, 22,
- 206, 24, 25, 203, 212, 216, 220, 223,
- 227, 230, 234, 237, 241, 244, 170, 270,
- 272, 273, 39, 276, 40, 42, 279, 43,
- 45, 282, 46, 48, 285, 49, 51, 52,
- 266, 54, 55, 284, 57, 58, 281, 60,
- 61, 278, 287, 290, 294, 297, 301, 304,
- 308, 311, 315, 319, 170, 343, 345, 346,
- 75, 349, 170, 76, 78, 352, 79, 81,
- 355, 82, 84, 358, 85, 87, 88, 339,
- 90, 91, 357, 93, 94, 354, 96, 97,
- 351, 360, 363, 367, 370, 374, 377, 381,
- 384, 388, 170, 418, 420, 421, 110, 424,
- 111, 113, 427, 114, 116, 430, 117, 119,
- 433, 120, 122, 123, 414, 125, 126, 432,
- 128, 129, 429, 131, 132, 426, 435, 438,
- 442, 445, 449, 452, 456, 459, 463, 466,
- 392, 478, 146, 481, 148, 484, 149, 151,
- 487, 152, 154, 490, 155, 493, 495, 496,
- 159, 160, 492, 162, 163, 489, 165, 166,
- 486, 168, 169, 483, 170, 171, 246, 320,
- 322, 391, 393, 340, 342, 394, 390, 467,
- 468, 170, 172, 174, 35, 245, 192, 194,
- 214, 243, 173, 34, 175, 239, 0, 176,
- 178, 33, 238, 236, 177, 32, 179, 232,
- 180, 182, 31, 231, 229, 181, 30, 183,
- 225, 184, 186, 29, 224, 222, 185, 28,
- 187, 218, 188, 190, 27, 217, 215, 189,
- 26, 200, 193, 170, 196, 1, 199, 2,
- 202, 5, 23, 205, 8, 20, 208, 11,
- 17, 211, 14, 213, 219, 221, 226, 228,
- 233, 235, 240, 242, 170, 247, 249, 71,
- 317, 267, 269, 318, 248, 70, 250, 313,
- 36, 251, 253, 69, 312, 310, 252, 68,
- 254, 306, 255, 257, 67, 305, 303, 256,
- 66, 258, 299, 259, 261, 65, 298, 296,
- 260, 64, 262, 292, 263, 265, 63, 291,
- 289, 264, 62, 275, 268, 170, 271, 37,
- 274, 38, 277, 41, 59, 280, 44, 56,
- 283, 47, 53, 286, 50, 288, 293, 295,
- 300, 302, 307, 309, 314, 316, 170, 321,
- 106, 323, 386, 72, 324, 326, 105, 385,
- 383, 325, 104, 327, 379, 328, 330, 103,
- 378, 376, 329, 102, 331, 372, 332, 334,
- 101, 371, 369, 333, 100, 335, 365, 336,
- 338, 99, 364, 362, 337, 98, 348, 341,
- 170, 344, 73, 347, 74, 350, 77, 95,
- 353, 80, 92, 356, 83, 89, 359, 86,
- 361, 366, 368, 373, 375, 380, 382, 387,
- 389, 170, 170, 395, 397, 142, 141, 415,
- 417, 465, 396, 398, 461, 107, 399, 401,
- 140, 460, 458, 400, 139, 402, 454, 403,
- 405, 138, 453, 451, 404, 137, 406, 447,
- 407, 409, 136, 446, 444, 408, 135, 410,
- 440, 411, 413, 134, 439, 437, 412, 133,
- 423, 416, 170, 419, 108, 422, 109, 425,
- 112, 130, 428, 115, 127, 431, 118, 124,
- 434, 121, 436, 441, 443, 448, 450, 455,
- 457, 462, 464, 143, 469, 470, 480, 475,
- 477, 498, 471, 472, 473, 144, 479, 474,
- 476, 145, 482, 147, 167, 156, 485, 150,
- 164, 488, 153, 161, 491, 158, 494, 157,
- 497
+ 170, 197, 199, 202, 3, 205, 4, 6,
+ 208, 7, 9, 211, 10, 12, 214, 13,
+ 15, 16, 191, 18, 19, 213, 21, 22,
+ 210, 24, 25, 207, 216, 221, 225, 228,
+ 232, 235, 239, 242, 246, 249, 170, 277,
+ 279, 282, 39, 285, 40, 42, 288, 43,
+ 45, 291, 46, 48, 294, 49, 51, 52,
+ 271, 54, 55, 293, 57, 58, 290, 60,
+ 61, 287, 296, 301, 305, 308, 312, 315,
+ 319, 322, 326, 330, 170, 356, 358, 361,
+ 75, 364, 170, 76, 78, 367, 79, 81,
+ 370, 82, 84, 373, 85, 87, 88, 350,
+ 90, 91, 372, 93, 94, 369, 96, 97,
+ 366, 375, 380, 384, 387, 391, 394, 398,
+ 401, 405, 170, 437, 439, 442, 110, 445,
+ 111, 113, 448, 114, 116, 451, 117, 119,
+ 454, 120, 122, 123, 431, 125, 126, 453,
+ 128, 129, 450, 131, 132, 447, 456, 461,
+ 465, 468, 472, 475, 479, 482, 486, 489,
+ 409, 505, 146, 508, 148, 511, 149, 151,
+ 514, 152, 154, 517, 155, 520, 522, 523,
+ 159, 160, 519, 162, 163, 516, 165, 166,
+ 513, 168, 169, 510, 170, 171, 251, 331,
+ 333, 408, 410, 351, 170, 353, 411, 407,
+ 490, 491, 378, 526, 379, 170, 172, 174,
+ 35, 250, 192, 170, 194, 248, 219, 200,
+ 220, 173, 34, 175, 244, 0, 176, 178,
+ 33, 243, 241, 177, 32, 179, 237, 180,
+ 182, 31, 236, 234, 181, 30, 183, 230,
+ 184, 186, 29, 229, 227, 185, 28, 187,
+ 223, 188, 190, 27, 222, 218, 189, 26,
+ 204, 193, 196, 195, 198, 1, 203, 201,
+ 2, 206, 5, 23, 209, 8, 20, 212,
+ 11, 17, 215, 14, 217, 224, 226, 231,
+ 233, 238, 240, 245, 247, 170, 252, 254,
+ 71, 328, 272, 170, 274, 329, 299, 280,
+ 300, 253, 70, 255, 324, 36, 256, 258,
+ 69, 323, 321, 257, 68, 259, 317, 260,
+ 262, 67, 316, 314, 261, 66, 263, 310,
+ 264, 266, 65, 309, 307, 265, 64, 267,
+ 303, 268, 270, 63, 302, 298, 269, 62,
+ 284, 273, 276, 275, 278, 37, 283, 281,
+ 38, 286, 41, 59, 289, 44, 56, 292,
+ 47, 53, 295, 50, 297, 304, 306, 311,
+ 313, 318, 320, 325, 327, 170, 332, 106,
+ 359, 334, 403, 72, 335, 337, 105, 402,
+ 400, 336, 104, 338, 396, 339, 341, 103,
+ 395, 393, 340, 102, 342, 389, 343, 345,
+ 101, 388, 386, 344, 100, 346, 382, 347,
+ 349, 99, 381, 377, 348, 98, 363, 352,
+ 355, 354, 357, 73, 362, 360, 74, 365,
+ 77, 95, 368, 80, 92, 371, 83, 89,
+ 374, 86, 376, 383, 385, 390, 392, 397,
+ 399, 404, 406, 170, 170, 412, 414, 142,
+ 141, 432, 170, 434, 488, 459, 440, 460,
+ 413, 415, 484, 107, 416, 418, 140, 483,
+ 481, 417, 139, 419, 477, 420, 422, 138,
+ 476, 474, 421, 137, 423, 470, 424, 426,
+ 136, 469, 467, 425, 135, 427, 463, 428,
+ 430, 134, 462, 458, 429, 133, 444, 433,
+ 436, 435, 438, 108, 443, 441, 109, 446,
+ 112, 130, 449, 115, 127, 452, 118, 124,
+ 455, 121, 457, 464, 466, 471, 473, 478,
+ 480, 485, 487, 143, 492, 493, 507, 498,
+ 500, 525, 503, 494, 495, 496, 144, 506,
+ 497, 499, 502, 501, 504, 145, 509, 147,
+ 167, 156, 512, 150, 164, 515, 153, 161,
+ 518, 158, 521, 157, 524, 170, 527, 528,
+ 170, 530, 529, 532, 531
};
static const char _indic_syllable_machine_trans_actions[] = {
@@ -996,48 +1353,52 @@ static const char _indic_syllable_machine_trans_actions[] = {
2, 0, 0, 2, 0, 2, 0, 0,
0, 0, 2, 0, 0, 2, 0, 0,
2, 0, 0, 2, 11, 2, 2, 6,
- 2, 12, 12, 0, 0, 2, 2, 6,
- 2, 13, 2, 2, 0, 2, 0, 0,
- 2, 2, 2, 0, 2, 2, 0, 2,
+ 2, 12, 12, 0, 13, 0, 2, 2,
+ 6, 2, 6, 0, 6, 14, 2, 2,
+ 0, 2, 0, 15, 0, 2, 2, 0,
+ 2, 2, 0, 2, 2, 0, 2, 2,
+ 0, 2, 2, 2, 0, 2, 2, 2,
2, 0, 2, 2, 2, 0, 2, 2,
2, 2, 0, 2, 2, 2, 0, 2,
2, 2, 2, 0, 2, 2, 2, 0,
- 2, 2, 2, 2, 0, 2, 2, 2,
- 0, 2, 0, 14, 0, 0, 2, 0,
- 2, 0, 0, 2, 0, 0, 2, 0,
- 0, 2, 0, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 15, 2, 2, 0,
- 2, 0, 0, 2, 2, 0, 2, 2,
- 0, 2, 2, 0, 2, 2, 2, 0,
- 2, 2, 2, 2, 0, 2, 2, 2,
- 0, 2, 2, 2, 2, 0, 2, 2,
- 2, 0, 2, 2, 2, 2, 0, 2,
- 2, 2, 0, 2, 0, 16, 0, 0,
- 2, 0, 2, 0, 0, 2, 0, 0,
- 2, 0, 0, 2, 0, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 17, 6,
+ 2, 0, 0, 0, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 2,
+ 0, 0, 2, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 16, 2, 2,
+ 0, 2, 0, 17, 0, 2, 2, 0,
+ 2, 2, 0, 2, 2, 0, 2, 2,
+ 0, 2, 2, 2, 0, 2, 2, 2,
+ 2, 0, 2, 2, 2, 0, 2, 2,
+ 2, 2, 0, 2, 2, 2, 0, 2,
+ 2, 2, 2, 0, 2, 2, 2, 0,
+ 2, 0, 0, 0, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 2,
+ 0, 0, 2, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 18, 6, 0,
0, 6, 6, 0, 6, 2, 0, 6,
2, 6, 0, 6, 6, 6, 2, 0,
6, 2, 6, 0, 6, 6, 6, 2,
0, 6, 2, 6, 0, 6, 6, 6,
2, 0, 6, 2, 6, 0, 6, 0,
- 18, 0, 0, 2, 0, 2, 0, 0,
- 2, 0, 0, 2, 0, 0, 2, 0,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 19, 20, 2, 2, 0, 0, 0,
- 0, 2, 2, 2, 2, 0, 2, 2,
+ 0, 0, 0, 0, 2, 0, 0, 2,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 19, 20, 2, 2, 0,
+ 0, 0, 21, 0, 2, 2, 0, 2,
+ 2, 2, 2, 0, 2, 2, 0, 2,
+ 2, 2, 0, 2, 2, 2, 2, 0,
+ 2, 2, 2, 0, 2, 2, 2, 2,
0, 2, 2, 2, 0, 2, 2, 2,
- 2, 0, 2, 2, 2, 0, 2, 2,
- 2, 2, 0, 2, 2, 2, 0, 2,
- 2, 2, 2, 0, 2, 2, 2, 0,
- 2, 0, 21, 0, 0, 2, 0, 2,
+ 2, 0, 2, 2, 2, 0, 2, 0,
+ 0, 0, 0, 0, 2, 0, 0, 2,
0, 0, 2, 0, 0, 2, 0, 0,
2, 0, 2, 2, 2, 2, 2, 2,
2, 2, 2, 0, 0, 8, 2, 0,
- 0, 2, 2, 8, 8, 0, 8, 8,
- 0, 0, 2, 0, 0, 0, 2, 0,
- 0, 2, 0, 0, 2, 0, 0, 0,
- 2
+ 0, 2, 0, 2, 8, 8, 0, 8,
+ 8, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 0, 2, 22, 0, 0,
+ 23, 0, 0, 0, 0
};
static const char _indic_syllable_machine_to_state_actions[] = {
@@ -1103,7 +1464,11 @@ static const char _indic_syllable_machine_to_state_actions[] = {
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, 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
};
static const char _indic_syllable_machine_from_state_actions[] = {
@@ -1169,7 +1534,11 @@ static const char _indic_syllable_machine_from_state_actions[] = {
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, 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
};
static const short _indic_syllable_machine_eof_trans[] = {
@@ -1194,48 +1563,52 @@ static const short _indic_syllable_machine_eof_trans[] = {
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, 0, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 269, 269, 269, 269, 269, 269, 269, 269,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 343,
- 343, 343, 343, 343, 343, 343, 343, 410,
- 343, 410, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 411, 411, 411, 411, 411,
- 411, 411, 411, 343, 194, 194, 194, 343,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 194, 194, 194, 194, 194, 194,
- 194, 194, 343
+ 1, 1, 0, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 358, 358, 358, 358, 358, 358, 358, 358,
+ 428, 358, 428, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 429, 429, 429, 429, 429, 429,
+ 429, 429, 358, 198, 198, 198, 358, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 198, 198, 198,
+ 198, 198, 198, 198, 198, 358, 542, 542,
+ 542, 542, 542, 542, 542
};
static const int indic_syllable_machine_start = 170;
@@ -1249,7 +1622,7 @@ static const int indic_syllable_machine_en_main = 170;
-#line 91 "hb-ot-shape-complex-indic-machine.rl"
+#line 98 "hb-ot-shape-complex-indic-machine.rl"
#define found_syllable(syllable_type) \
@@ -1269,7 +1642,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 1273 "hb-ot-shape-complex-indic-machine.hh"
+#line 1646 "hb-ot-shape-complex-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -1277,7 +1650,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 112 "hb-ot-shape-complex-indic-machine.rl"
+#line 119 "hb-ot-shape-complex-indic-machine.rl"
p = 0;
@@ -1286,7 +1659,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 1290 "hb-ot-shape-complex-indic-machine.hh"
+#line 1663 "hb-ot-shape-complex-indic-machine.hh"
{
int _slen;
int _trans;
@@ -1300,7 +1673,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 1304 "hb-ot-shape-complex-indic-machine.hh"
+#line 1677 "hb-ot-shape-complex-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1322,60 +1695,68 @@ _eof_trans:
#line 1 "NONE"
{te = p+1;}
break;
- case 14:
-#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ case 15:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
- case 16:
-#line 84 "hb-ot-shape-complex-indic-machine.rl"
+ case 17:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (vowel_syllable); }}
break;
case 21:
-#line 85 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (standalone_cluster); }}
break;
- case 18:
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ case 23:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p+1;{ found_syllable (avagraha_cluster); }}
+ break;
+ case 13:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 11:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 94 "hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (non_indic_cluster); }}
break;
- case 13:
-#line 83 "hb-ot-shape-complex-indic-machine.rl"
+ case 14:
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
- case 15:
-#line 84 "hb-ot-shape-complex-indic-machine.rl"
+ case 16:
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (vowel_syllable); }}
break;
case 20:
-#line 85 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (standalone_cluster); }}
break;
- case 17:
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
+ case 22:
+#line 92 "hb-ot-shape-complex-indic-machine.rl"
+ {te = p;p--;{ found_syllable (avagraha_cluster); }}
+ break;
+ case 18:
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 19:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
+#line 94 "hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (non_indic_cluster); }}
break;
case 1:
-#line 83 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 3:
-#line 84 "hb-ot-shape-complex-indic-machine.rl"
+#line 90 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
break;
case 7:
-#line 85 "hb-ot-shape-complex-indic-machine.rl"
+#line 91 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
break;
case 4:
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
case 5:
@@ -1384,10 +1765,10 @@ _eof_trans:
case 1:
{{p = ((te))-1;} found_syllable (consonant_syllable); }
break;
- case 4:
+ case 5:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
- case 5:
+ case 6:
{{p = ((te))-1;} found_syllable (non_indic_cluster); }
break;
}
@@ -1396,22 +1777,22 @@ _eof_trans:
case 8:
#line 1 "NONE"
{te = p+1;}
-#line 83 "hb-ot-shape-complex-indic-machine.rl"
+#line 89 "hb-ot-shape-complex-indic-machine.rl"
{act = 1;}
break;
case 6:
#line 1 "NONE"
{te = p+1;}
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
- {act = 4;}
+#line 93 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 5;}
break;
case 12:
#line 1 "NONE"
{te = p+1;}
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
- {act = 5;}
+#line 94 "hb-ot-shape-complex-indic-machine.rl"
+ {act = 6;}
break;
-#line 1415 "hb-ot-shape-complex-indic-machine.hh"
+#line 1796 "hb-ot-shape-complex-indic-machine.hh"
}
_again:
@@ -1420,7 +1801,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 1424 "hb-ot-shape-complex-indic-machine.hh"
+#line 1805 "hb-ot-shape-complex-indic-machine.hh"
}
if ( ++p != pe )
@@ -1436,7 +1817,7 @@ _again:
}
-#line 121 "hb-ot-shape-complex-indic-machine.rl"
+#line 128 "hb-ot-shape-complex-indic-machine.rl"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index 9edefe305d..1e07d33177 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -1690,12 +1690,6 @@ clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
-static hb_ot_shape_normalization_mode_t
-normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
-}
-
static bool
decompose_indic (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
@@ -1806,7 +1800,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
data_create_indic,
data_destroy_indic,
NULL, /* preprocess_text */
- normalization_preference_indic,
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_indic,
compose_indic,
setup_masks_indic,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
index e282f0cfb1..a9c8dbeaac 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh
@@ -34,196 +34,197 @@
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
- 1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
+ 1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
- 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
+ 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
- 30, 28, 25, 4, 25, 23, 21, 21,
+ 31, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 27, 27, 27, 27, 25, 4,
25, 23, 21, 21, 27, 27, 27, 27,
28, 27, 30, 27, 27, 27, 27, 27,
- 27, 27, 27, 27
+ 27, 27, 27, 27, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
- 0, 31, 60, 86, 91, 117, 141, 163,
- 185, 213, 241, 269, 297, 314, 342, 370,
- 398, 426, 454, 482, 510, 538, 566, 592,
- 597, 623, 647, 669, 691, 719, 747, 775,
- 803, 832, 860, 891, 919, 947, 975, 1003,
- 1031, 1059, 1087, 1115
+ 0, 32, 61, 87, 92, 118, 142, 164,
+ 186, 214, 242, 270, 298, 315, 343, 371,
+ 399, 427, 455, 483, 511, 539, 567, 593,
+ 598, 624, 648, 670, 692, 720, 748, 776,
+ 804, 833, 861, 892, 920, 948, 976, 1004,
+ 1032, 1060, 1088, 1116, 1144
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 0, 1, 0, 0, 0, 7,
0, 8, 1, 0, 9, 10, 11, 12,
- 13, 14, 15, 16, 17, 18, 0, 20,
- 21, 22, 22, 19, 23, 19, 24, 19,
- 19, 19, 19, 19, 19, 19, 25, 19,
- 19, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 19, 22, 22, 19, 23,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 36, 19, 19, 19, 19, 19, 19,
- 30, 19, 19, 19, 34, 19, 22, 22,
- 19, 23, 19, 22, 22, 19, 23, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 30,
- 19, 19, 19, 34, 19, 37, 19, 22,
- 22, 19, 23, 19, 30, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 30, 19, 22, 22, 19,
- 23, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 38, 19, 19, 19, 19, 19,
- 19, 30, 19, 22, 22, 19, 23, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 30,
- 19, 20, 19, 22, 22, 19, 23, 19,
- 24, 19, 19, 19, 19, 19, 19, 19,
- 39, 19, 19, 39, 19, 19, 19, 30,
- 40, 19, 19, 34, 19, 20, 19, 22,
- 22, 19, 23, 19, 24, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 30, 19, 19, 19, 34,
- 19, 20, 19, 22, 22, 19, 23, 19,
- 24, 19, 19, 19, 19, 19, 19, 19,
- 39, 19, 19, 19, 19, 19, 19, 30,
- 40, 19, 19, 34, 19, 20, 19, 22,
- 22, 19, 23, 19, 24, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 30, 40, 19, 19, 34,
- 19, 1, 1, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 1, 19, 20, 19, 22, 22, 19, 23,
- 19, 24, 19, 19, 19, 19, 19, 19,
- 19, 25, 19, 19, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 19, 20, 19,
- 22, 22, 19, 23, 19, 24, 19, 19,
- 19, 19, 19, 19, 19, 33, 19, 19,
- 19, 19, 19, 19, 30, 31, 32, 33,
- 34, 19, 20, 19, 22, 22, 19, 23,
- 19, 24, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 30, 31, 32, 33, 34, 19, 20, 19,
- 22, 22, 19, 23, 19, 24, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 30, 31, 32, 19,
- 34, 19, 20, 19, 22, 22, 19, 23,
- 19, 24, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 30, 19, 32, 19, 34, 19, 20, 19,
- 22, 22, 19, 23, 19, 24, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 26, 19, 28, 19, 30, 31, 32, 33,
- 34, 19, 20, 19, 22, 22, 19, 23,
- 19, 24, 19, 19, 19, 19, 19, 19,
- 19, 33, 19, 19, 26, 19, 19, 19,
- 30, 31, 32, 33, 34, 19, 20, 19,
- 22, 22, 19, 23, 19, 24, 19, 19,
- 19, 19, 19, 19, 19, 19, 19, 19,
- 26, 27, 28, 19, 30, 31, 32, 33,
- 34, 19, 20, 21, 22, 22, 19, 23,
- 19, 24, 19, 19, 19, 19, 19, 19,
- 19, 25, 19, 19, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 19, 3, 3,
- 41, 5, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 42, 41, 41, 41, 41,
- 41, 41, 13, 41, 41, 41, 17, 41,
- 3, 3, 41, 5, 41, 3, 3, 41,
- 5, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 13, 41, 41, 41, 17, 41, 43,
- 41, 3, 3, 41, 5, 41, 13, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 13, 41, 3,
- 3, 41, 5, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 44, 41, 41, 41,
- 41, 41, 41, 13, 41, 3, 3, 41,
- 5, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 13, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 45, 41, 41, 45, 41, 41,
- 41, 13, 46, 41, 41, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 13, 41, 41,
- 41, 17, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 45, 41, 41, 41, 41, 41,
- 41, 13, 46, 41, 41, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 13, 46, 41,
- 41, 17, 41, 20, 21, 22, 22, 19,
- 23, 19, 24, 19, 19, 19, 19, 19,
- 19, 19, 47, 19, 19, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 19,
- 20, 48, 22, 22, 19, 23, 19, 24,
- 19, 19, 19, 19, 19, 19, 19, 25,
- 19, 19, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 19, 1, 1, 2, 3,
- 3, 3, 41, 5, 41, 6, 41, 1,
- 41, 41, 41, 1, 41, 8, 1, 41,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 8, 41, 41, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 16, 41,
- 41, 41, 41, 41, 41, 13, 14, 15,
- 16, 17, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 13, 14, 15, 16, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 13, 14, 15,
- 41, 17, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 13, 41, 15, 41, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 9, 41, 11, 41, 13, 14, 15,
- 16, 17, 41, 2, 41, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 16, 41, 41, 9, 41, 41,
- 41, 13, 14, 15, 16, 17, 41, 2,
- 41, 3, 3, 41, 5, 41, 6, 41,
- 41, 41, 41, 41, 41, 41, 41, 41,
- 41, 9, 10, 11, 41, 13, 14, 15,
- 16, 17, 41, 2, 3, 3, 3, 41,
- 5, 41, 6, 41, 41, 41, 41, 41,
- 41, 41, 8, 41, 41, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 41, 0
+ 13, 14, 15, 16, 17, 18, 19, 0,
+ 21, 22, 23, 23, 20, 24, 20, 25,
+ 20, 20, 20, 20, 20, 20, 20, 26,
+ 20, 20, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 20, 23, 23, 20,
+ 24, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 37, 20, 20, 20, 20, 20,
+ 20, 31, 20, 20, 20, 35, 20, 23,
+ 23, 20, 24, 20, 23, 23, 20, 24,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 31, 20, 20, 20, 35, 20, 38, 20,
+ 23, 23, 20, 24, 20, 31, 20, 20,
+ 20, 20, 20, 20, 20, 39, 20, 20,
+ 20, 20, 20, 20, 31, 20, 23, 23,
+ 20, 24, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 39, 20, 20, 20, 20,
+ 20, 20, 31, 20, 23, 23, 20, 24,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 31, 20, 21, 20, 23, 23, 20, 24,
+ 20, 25, 20, 20, 20, 20, 20, 20,
+ 20, 40, 20, 20, 40, 20, 20, 20,
+ 31, 41, 20, 20, 35, 20, 21, 20,
+ 23, 23, 20, 24, 20, 25, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 31, 20, 20, 20,
+ 35, 20, 21, 20, 23, 23, 20, 24,
+ 20, 25, 20, 20, 20, 20, 20, 20,
+ 20, 40, 20, 20, 20, 20, 20, 20,
+ 31, 41, 20, 20, 35, 20, 21, 20,
+ 23, 23, 20, 24, 20, 25, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 31, 41, 20, 20,
+ 35, 20, 1, 1, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 1, 20, 21, 20, 23, 23, 20,
+ 24, 20, 25, 20, 20, 20, 20, 20,
+ 20, 20, 26, 20, 20, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 20, 21,
+ 20, 23, 23, 20, 24, 20, 25, 20,
+ 20, 20, 20, 20, 20, 20, 34, 20,
+ 20, 20, 20, 20, 20, 31, 32, 33,
+ 34, 35, 20, 21, 20, 23, 23, 20,
+ 24, 20, 25, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 31, 32, 33, 34, 35, 20, 21,
+ 20, 23, 23, 20, 24, 20, 25, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 31, 32, 33,
+ 20, 35, 20, 21, 20, 23, 23, 20,
+ 24, 20, 25, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 31, 20, 33, 20, 35, 20, 21,
+ 20, 23, 23, 20, 24, 20, 25, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 27, 20, 29, 20, 31, 32, 33,
+ 34, 35, 20, 21, 20, 23, 23, 20,
+ 24, 20, 25, 20, 20, 20, 20, 20,
+ 20, 20, 34, 20, 20, 27, 20, 20,
+ 20, 31, 32, 33, 34, 35, 20, 21,
+ 20, 23, 23, 20, 24, 20, 25, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 27, 28, 29, 20, 31, 32, 33,
+ 34, 35, 20, 21, 22, 23, 23, 20,
+ 24, 20, 25, 20, 20, 20, 20, 20,
+ 20, 20, 26, 20, 20, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 20, 3,
+ 3, 42, 5, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 43, 42, 42, 42,
+ 42, 42, 42, 13, 42, 42, 42, 17,
+ 42, 3, 3, 42, 5, 42, 3, 3,
+ 42, 5, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 13, 42, 42, 42, 17, 42,
+ 44, 42, 3, 3, 42, 5, 42, 13,
+ 42, 42, 42, 42, 42, 42, 42, 45,
+ 42, 42, 42, 42, 42, 42, 13, 42,
+ 3, 3, 42, 5, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 45, 42, 42,
+ 42, 42, 42, 42, 13, 42, 3, 3,
+ 42, 5, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 13, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 46, 42, 42, 46, 42,
+ 42, 42, 13, 47, 42, 42, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 13, 42,
+ 42, 42, 17, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 46, 42, 42, 42, 42,
+ 42, 42, 13, 47, 42, 42, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 13, 47,
+ 42, 42, 17, 42, 21, 22, 23, 23,
+ 20, 24, 20, 25, 20, 20, 20, 20,
+ 20, 20, 20, 48, 20, 20, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36,
+ 20, 21, 49, 23, 23, 20, 24, 20,
+ 25, 20, 20, 20, 20, 20, 20, 20,
+ 26, 20, 20, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 20, 1, 1, 2,
+ 3, 3, 3, 42, 5, 42, 6, 42,
+ 1, 42, 42, 42, 1, 42, 8, 1,
+ 42, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 8, 42, 42, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 16,
+ 42, 42, 42, 42, 42, 42, 13, 14,
+ 15, 16, 17, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 13, 14, 15, 16, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 13, 14,
+ 15, 42, 17, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 13, 42, 15, 42, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 9, 42, 11, 42, 13, 14,
+ 15, 16, 17, 42, 2, 42, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 16, 42, 42, 9, 42,
+ 42, 42, 13, 14, 15, 16, 17, 42,
+ 2, 42, 3, 3, 42, 5, 42, 6,
+ 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 9, 10, 11, 42, 13, 14,
+ 15, 16, 17, 42, 2, 3, 3, 3,
+ 42, 5, 42, 6, 42, 42, 42, 42,
+ 42, 42, 42, 8, 42, 42, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 42,
+ 51, 50, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 22, 0, 0, 23, 29, 32,
35, 36, 40, 41, 42, 25, 38, 39,
- 37, 28, 43, 0, 2, 12, 0, 3,
- 9, 13, 14, 18, 19, 20, 5, 16,
- 17, 15, 8, 21, 4, 6, 7, 10,
- 11, 0, 24, 26, 27, 30, 31, 33,
- 34
+ 37, 28, 43, 44, 0, 2, 12, 0,
+ 3, 9, 13, 14, 18, 19, 20, 5,
+ 16, 17, 15, 8, 21, 4, 6, 7,
+ 10, 11, 0, 24, 26, 27, 30, 31,
+ 33, 34, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 4, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 6, 0, 0, 7, 0,
+ 0, 0, 0, 0, 6, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8, 0, 0, 0, 0, 0, 0,
- 0
+ 0, 0, 8, 0, 0, 0, 0, 0,
+ 0, 0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@@ -232,7 +233,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
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
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@@ -241,16 +242,16 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
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
};
static const short _myanmar_syllable_machine_eof_trans[] = {
- 0, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 42, 42,
- 42, 42, 42, 42, 42, 42, 42, 42,
- 20, 20, 42, 42, 42, 42, 42, 42,
- 42, 42, 42, 42
+ 0, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43,
+ 21, 21, 43, 43, 43, 43, 43, 43,
+ 43, 43, 43, 43, 51
};
static const int myanmar_syllable_machine_start = 0;
@@ -264,7 +265,7 @@ static const int myanmar_syllable_machine_en_main = 0;
-#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
@@ -284,7 +285,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 288 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@@ -292,7 +293,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 111 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@@ -301,7 +302,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 305 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@@ -315,7 +316,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 319 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -334,30 +335,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 7:
-#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 5:
-#line 84 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
+ case 10:
+#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p+1;{ found_syllable (punctuation_cluster); }}
+ break;
case 4:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
-#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 6:
-#line 83 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 8:
-#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
-#line 361 "hb-ot-shape-complex-myanmar-machine.hh"
+ case 9:
+#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
+ {te = p;p--;{ found_syllable (non_myanmar_cluster); }}
+ break;
+#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@@ -366,7 +375,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
@@ -382,7 +391,7 @@ _again:
}
-#line 120 "hb-ot-shape-complex-myanmar-machine.rl"
+#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
index 25ba7264ca..50209ffb0e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -541,13 +541,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
-static hb_ot_shape_normalization_mode_t
-normalization_preference_myanmar (const hb_segment_properties_t *props HB_UNUSED)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
-}
-
-
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{
"myanmar",
@@ -556,7 +549,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
- normalization_preference_myanmar,
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_myanmar,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index ac0072ba56..104726e8af 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -44,7 +44,9 @@ enum hb_ot_shape_zero_width_marks_type_t {
// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
+
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE
};
@@ -52,10 +54,13 @@ enum hb_ot_shape_zero_width_marks_type_t {
#define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
HB_COMPLEX_SHAPER_IMPLEMENT (default) /* should be first */ \
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
HB_COMPLEX_SHAPER_IMPLEMENT (sea) \
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
+ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
/* ^--- Add new shapers here */
@@ -105,12 +110,7 @@ struct hb_ot_complex_shaper_t
hb_font_t *font);
- /* normalization_preference()
- * Called during shape().
- * May be NULL.
- */
- hb_ot_shape_normalization_mode_t
- (*normalization_preference) (const hb_segment_properties_t *props);
+ hb_ot_shape_normalization_mode_t normalization_preference;
/* decompose()
* Called during shape()'s normalization.
@@ -189,19 +189,22 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_thai;
-#if 0
- /* Note:
- * Currently we don't have a separate Hangul shaper. The default shaper handles
- * Hangul by enabling jamo features. We may want to implement a separate shaper
- * in the future. See this thread for details of what such a shaper would do:
- *
- * http://lists.freedesktop.org/archives/harfbuzz/2013-April/003070.html
- */
/* Unicode-1.1 additions */
case HB_SCRIPT_HANGUL:
return &_hb_ot_complex_shaper_hangul;
-#endif
+
+
+ /* Unicode-2.0 additions */
+ case HB_SCRIPT_TIBETAN:
+
+ return &_hb_ot_complex_shaper_tibetan;
+
+
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_HEBREW:
+
+ return &_hb_ot_complex_shaper_hebrew;
/* ^--- Add new shapers here */
@@ -241,9 +244,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
case HB_SCRIPT_LAO:
case HB_SCRIPT_THAI:
- /* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN:
-
/* Unicode-3.2 additions */
case HB_SCRIPT_TAGALOG:
case HB_SCRIPT_TAGBANWA:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
index da687ed646..6288a90c9a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
@@ -360,13 +360,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
-static hb_ot_shape_normalization_mode_t
-normalization_preference_sea (const hb_segment_properties_t *props HB_UNUSED)
-{
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
-}
-
-
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
{
"sea",
@@ -375,7 +368,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea =
NULL, /* data_create */
NULL, /* data_destroy */
NULL, /* preprocess_text */
- normalization_preference_sea,
+ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
NULL, /* decompose */
NULL, /* compose */
setup_masks_sea,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
index 45945339d6..8664eca45c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -369,10 +369,10 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
NULL, /* data_create */
NULL, /* data_destroy */
preprocess_text_thai,
- NULL, /* normalization_preference */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
NULL, /* decompose */
NULL, /* compose */
NULL, /* setup_masks */
- HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE,
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
false,/* fallback_position */
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
new file mode 100644
index 0000000000..01465a426f
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2010,2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+static const hb_tag_t tibetan_features[] =
+{
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+ HB_TAG_NONE
+};
+
+static void
+collect_features_tibetan (hb_ot_shape_planner_t *plan)
+{
+ for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
+ plan->map.add_global_bool_feature (*script_features);
+}
+
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
+{
+ "default",
+ collect_features_tibetan,
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT,
+ NULL, /* decompose */
+ NULL, /* compose */
+ NULL, /* setup_masks */
+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT,
+ true, /* fallback_position */
+};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
index 449b64e5ca..5d526c3a8e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -430,14 +430,12 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
- HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
- if (!kern_mask) return;
+ if (!plan->has_kern) return;
unsigned int count = buffer->len;
OT::hb_apply_context_t c (1, font, buffer);
- c.set_lookup_mask (kern_mask);
+ c.set_lookup_mask (plan->kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
hb_glyph_info_t *info = buffer->info;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
index fb8048caa2..c744e26451 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -36,6 +36,7 @@
struct hb_ot_shape_plan_t;
enum hb_ot_shape_normalization_mode_t {
+ HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* always fully decomposes and then recompose back */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 6531e1b215..2a6a439003 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -213,8 +213,9 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
}
static inline void
-handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
+handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
+ /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
hb_buffer_t * const buffer = c->buffer;
hb_font_t * const font = c->font;
for (; buffer->idx < end - 1;) {
@@ -250,27 +251,26 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns
}
static inline void
-decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
+decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit)
{
hb_buffer_t * const buffer = c->buffer;
- /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
for (unsigned int i = buffer->idx; i < end; i++)
if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
- handle_variation_selector_cluster (c, end);
+ handle_variation_selector_cluster (c, end, short_circuit);
return;
}
while (buffer->idx < end)
- decompose_current_character (c, false);
+ decompose_current_character (c, short_circuit);
}
static inline void
-decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end)
+decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
{
if (likely (c->buffer->idx + 1 == end))
- decompose_current_character (c, short_circuit);
+ decompose_current_character (c, might_short_circuit);
else
- decompose_multi_char_cluster (c, end);
+ decompose_multi_char_cluster (c, end, always_short_circuit);
}
@@ -289,9 +289,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font)
{
- hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ?
- plan->shaper->normalization_preference (&buffer->props) :
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT;
+ hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference;
const hb_ot_shape_normalize_context_t c = {
plan,
buffer,
@@ -301,8 +299,10 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
plan->shaper->compose ? plan->shaper->compose : compose_unicode
};
- bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
- mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
+ bool always_short_circuit = mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE;
+ bool might_short_circuit = always_short_circuit ||
+ (mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
+ mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT);
unsigned int count;
/* We do a fairly straightforward yet custom normalization process in three
@@ -323,7 +323,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (buffer->cur().cluster != buffer->info[end].cluster)
break;
- decompose_cluster (&c, short_circuit, end);
+ decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
}
buffer->swap_buffers ();
@@ -355,7 +355,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
}
- if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
+ if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_NONE ||
+ mode == HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED)
return;
/* Third round, recompose */
@@ -393,8 +394,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
return;
buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */
- buffer->out_info[starter].codepoint = composed; /* Modify starter and carry on. */
- set_glyph (buffer->out_info[starter], font);
+ /* Modify starter and carry on. */
+ buffer->out_info[starter].codepoint = composed;
+ buffer->out_info[starter].glyph_index() = glyph;
_hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode);
continue;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
index cbfab5b40c..df81fa25d9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -40,6 +40,10 @@ struct hb_ot_shape_plan_t
const struct hb_ot_complex_shaper_t *shaper;
hb_ot_map_t map;
const void *data;
+ hb_mask_t rtlm_mask, frac_mask, numr_mask, dnom_mask;
+ hb_mask_t kern_mask;
+ unsigned int has_frac : 1;
+ unsigned int has_kern : 1;
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
{
@@ -77,6 +81,17 @@ struct hb_ot_shape_planner_t
plan.props = props;
plan.shaper = shaper;
map.compile (plan.map);
+
+ plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
+ plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
+ plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
+ plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
+
+ plan.kern_mask = plan.map.get_mask (HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+ HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+
+ plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+ plan.has_kern = !!plan.kern_mask;
}
private:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index 63c36f936f..3080a1d03d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -88,6 +88,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
}
+ map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
+ map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
+ map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
+
if (planner->shaper->collect_features)
planner->shaper->collect_features (planner);
@@ -234,8 +238,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
return;
- hb_codepoint_t dottedcircle_glyph;
- if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
+ if (!font->has_glyph (0x25CC))
return;
hb_glyph_info_t dottedcircle;
@@ -292,7 +295,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
hb_buffer_t *buffer = c->buffer;
hb_unicode_funcs_t *unicode = buffer->unicode;
- hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
+ hb_mask_t rtlm_mask = c->plan->rtlm_mask;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
@@ -306,13 +309,58 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
+{
+ if (!c->plan->has_frac)
+ return;
+
+ hb_buffer_t *buffer = c->buffer;
+
+ /* TODO look in pre/post context text also. */
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ if (info[i].codepoint == 0x2044) /* FRACTION SLASH */
+ {
+ unsigned int start = i, end = i + 1;
+ while (start &&
+ _hb_glyph_info_get_general_category (&info[start - 1]) ==
+ HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
+ start--;
+ while (end < count &&
+ _hb_glyph_info_get_general_category (&info[end]) ==
+ HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
+ end++;
+
+ for (unsigned int j = start; j < i; j++)
+ info[j].mask |= c->plan->numr_mask | c->plan->frac_mask;
+ info[i].mask |= c->plan->frac_mask;
+ for (unsigned int j = i + 1; j < end; j++)
+ info[j].mask |= c->plan->frac_mask | c->plan->dnom_mask;
+
+ i = end - 1;
+ }
+ }
+}
+
+static inline void
+hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
hb_mask_t global_mask = map->get_global_mask ();
buffer->reset_masks (global_mask);
+}
+
+static inline void
+hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
+{
+ hb_ot_map_t *map = &c->plan->map;
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_ot_shape_setup_masks_fraction (c);
if (c->plan->shaper->setup_masks)
c->plan->shaper->setup_masks (c->plan, buffer, c->font);
@@ -358,6 +406,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
if (c->plan->shaper->preprocess_text)
c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
+ hb_ot_shape_initialize_masks (c);
+
hb_ot_mirror_chars (c);
HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h
new file mode 100644
index 0000000000..afe6fe9618
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2013 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_H
+#define HB_OT_SHAPE_H
+#define HB_OT_SHAPE_H_IN
+
+#include "hb.h"
+
+#include "hb-ot-layout.h"
+#include "hb-ot-tag.h"
+
+HB_BEGIN_DECLS
+
+/* TODO port to shape-plan / set. */
+void
+hb_ot_shape_glyphs_closure (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features,
+ hb_set_t *glyphs);
+
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+ hb_tag_t table_tag,
+ hb_set_t *lookup_indexes /* OUT */);
+
+HB_END_DECLS
+
+#undef HB_OT_SHAPE_H_IN
+#endif /* HB_OT_SHAPE_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot.h b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
index 8073906399..e9a280b7dd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot.h
@@ -32,17 +32,10 @@
#include "hb-ot-layout.h"
#include "hb-ot-tag.h"
+#include "hb-ot-shape.h"
HB_BEGIN_DECLS
-/* TODO remove */
-void
-hb_ot_shape_glyphs_closure (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features,
- hb_set_t *glyphs);
-
HB_END_DECLS
#undef HB_OT_H_IN
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
index 4b72260ed5..680b21e2cc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -808,6 +808,12 @@ hb_in_range (T u, T lo, T hi)
}
template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+{
+ return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+}
+
+template <typename T> static inline bool
hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
{
return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
index b9c029e58f..5713e057a0 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh
@@ -35,6 +35,11 @@
HB_SHAPER_IMPLEMENT (graphite2)
#endif
+#ifdef HAVE_CORETEXT
+/* Only picks up fonts that have a "mort" or "morx" table. */
+HB_SHAPER_IMPLEMENT (coretext)
+#endif
+
#ifdef HAVE_OT
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
#endif
@@ -48,8 +53,7 @@ HB_SHAPER_IMPLEMENT (icu_le)
#ifdef HAVE_UNISCRIBE
HB_SHAPER_IMPLEMENT (uniscribe)
#endif
-#ifdef HAVE_CORETEXT
-HB_SHAPER_IMPLEMENT (coretext)
-#endif
+#ifdef HAVE_FALLBACK
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
+#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
index 779d8ae229..ba193e8fa5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -106,7 +106,11 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
modified_combining_class (hb_codepoint_t unicode)
{
/* XXX This hack belongs to the Myanmar shaper. */
- if (unicode == 0x1037) unicode = 0x103A;
+ if (unlikely (unicode == 0x1037)) unicode = 0x103A;
+
+ /* XXX This hack belongs to the SEA shaper (for Tai Tham):
+ * Reorder SAKOT to ensure it comes after any tone marks. */
+ if (unlikely (unicode == 0x1A60)) return 254;
return _hb_modified_combining_class[combining_class (unicode)];
}
@@ -130,10 +134,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 6.3 is also added manually. The new Unicode 6.3 bidi formatting
* characters are encoded in a block that was Default_Ignorable already.
*
- * Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
- * hide them, as the way Uniscribe has implemented them is with regular
- * spacing glyphs, and that's the way fonts are made to work. As such,
- * we make exceptions for those two.
+ * Note: While U+115F, U+1160, U+3164 and U+FFA0 are Default_Ignorable,
+ * we do NOT want to hide them, as the way Uniscribe has implemented them
+ * is with regular spacing glyphs, and that's the way fonts are made to work.
+ * As such, we make exceptions for those four.
*
* Gathered from:
* http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
@@ -155,10 +159,10 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 200B..200F ;RIGHT-TO-LEFT MARK
* 202A..202E ;RIGHT-TO-LEFT OVERRIDE
* 2060..206F ;NOMINAL DIGIT SHAPES
- * 3164 ;HANGUL FILLER
+ * #3164 ;HANGUL FILLER
* FE00..FE0F ;VARIATION SELECTOR-16
* FEFF ;ZERO WIDTH NO-BREAK SPACE
- * FFA0 ;HALFWIDTH HANGUL FILLER
+ * #FFA0 ;HALFWIDTH HANGUL FILLER
* FFF0..FFF8 ;<unassigned-FFF8>
* 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
* E0000..E0FFF ;<unassigned-E0FFF>
@@ -180,9 +184,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
case 0x20: return hb_in_ranges<hb_codepoint_t> (ch, 0x200B, 0x200F,
0x202A, 0x202E,
0x2060, 0x206F);
- case 0x31: return unlikely (ch == 0x3164);
case 0xFE: return hb_in_range<hb_codepoint_t> (ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
- case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0;
+ case 0xFF: return hb_in_range<hb_codepoint_t> (ch, 0xFFF0, 0xFFF8);
default: return false;
}
}
diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri
index 0d55867c74..e61ee7eab6 100644
--- a/src/3rdparty/harfbuzz.pri
+++ b/src/3rdparty/harfbuzz.pri
@@ -9,7 +9,6 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-buffer-serialize.cc \
$$QT_HARFBUZZ_DIR/src/hb-common.cc \
$$QT_HARFBUZZ_DIR/src/hb-face.cc \
- $$QT_HARFBUZZ_DIR/src/hb-fallback-shape.cc \
$$QT_HARFBUZZ_DIR/src/hb-font.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-tag.cc \
$$QT_HARFBUZZ_DIR/src/hb-set.cc \
@@ -65,11 +64,14 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-ot-shape.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-default.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hangul.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hebrew.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-table.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-thai.cc \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-tibetan.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback.cc \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize.cc
@@ -96,8 +98,20 @@ contains(QT_CONFIG, harfbuzz) {
HEADERS += \
$$QT_HARFBUZZ_DIR/src/hb-ot.h \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout.h \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-shape.h \
$$QT_HARFBUZZ_DIR/src/hb-ot-tag.h
+ mac {
+ # Apple Advanced Typography
+ SOURCES += \
+ $$QT_HARFBUZZ_DIR/src/hb-coretext.cc
+
+ HEADERS += \
+ $$QT_HARFBUZZ_DIR/src/hb-coretext.h
+
+ DEFINES += HAVE_CORETEXT
+ }
+
DEFINES += HAVE_CONFIG_H
QT += core-private
diff --git a/src/3rdparty/libjpeg.pri b/src/3rdparty/libjpeg.pri
index e5826eae3c..82c6ed536d 100644
--- a/src/3rdparty/libjpeg.pri
+++ b/src/3rdparty/libjpeg.pri
@@ -4,6 +4,8 @@ wince*: {
contains(CE_ARCH,x86):CONFIG += exceptions_off
}
+winrt: DEFINES += NO_GETENV
+
#Disable warnings in 3rdparty code due to unused arguments
contains(QMAKE_CC, gcc): {
QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-main
diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h
index 592d4ee0cb..f01e56f612 100644
--- a/src/3rdparty/libpng/pngpriv.h
+++ b/src/3rdparty/libpng/pngpriv.h
@@ -362,7 +362,7 @@ typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp;
#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
defined(_WIN32) || defined(__WIN32__)
# include <windows.h> /* defines _WINDOWS_ macro */
-# if defined(WINAPI_FAMILY) && ((WINAPI_FAMILY & WINAPI_FAMILY_DESKTOP_APP) == WINAPI_PARTITION_APP)
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
# define _WINRT_ /* Define a macro for Windows Runtime builds */
# endif
#endif
diff --git a/src/3rdparty/pcre/AUTHORS b/src/3rdparty/pcre/AUTHORS
index ba4753d858..97d8c71dd6 100644
--- a/src/3rdparty/pcre/AUTHORS
+++ b/src/3rdparty/pcre/AUTHORS
@@ -8,7 +8,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2012 University of Cambridge
+Copyright (c) 1997-2013 University of Cambridge
All rights reserved
@@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2012 Zoltan Herczeg
+Copyright(c) 2010-2013 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2012 Zoltan Herczeg
+Copyright(c) 2009-2013 Zoltan Herczeg
All rights reserved.
diff --git a/src/3rdparty/pcre/LICENCE b/src/3rdparty/pcre/LICENCE
index 5ce31a828d..3aff6a62c0 100644
--- a/src/3rdparty/pcre/LICENCE
+++ b/src/3rdparty/pcre/LICENCE
@@ -24,7 +24,7 @@ Email domain: cam.ac.uk
University of Cambridge Computing Service,
Cambridge, England.
-Copyright (c) 1997-2012 University of Cambridge
+Copyright (c) 1997-2013 University of Cambridge
All rights reserved.
@@ -35,7 +35,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2010-2012 Zoltan Herczeg
+Copyright(c) 2010-2013 Zoltan Herczeg
All rights reserved.
@@ -46,7 +46,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2012 Zoltan Herczeg
+Copyright(c) 2009-2013 Zoltan Herczeg
All rights reserved.
diff --git a/src/3rdparty/pcre/config.h b/src/3rdparty/pcre/config.h
index ed388fc9ba..d45d88abd1 100644
--- a/src/3rdparty/pcre/config.h
+++ b/src/3rdparty/pcre/config.h
@@ -8,6 +8,7 @@
#define MAX_NAME_COUNT 10000
#define MAX_NAME_SIZE 32
#define NEWLINE 10
+#define PARENS_NEST_LIMIT 250
#define POSIX_MALLOC_THRESHOLD 10
#define SUPPORT_UCP
diff --git a/src/3rdparty/pcre/patches/bug_1423_jit_condition_misoptimization_fix.diff b/src/3rdparty/pcre/patches/bug_1423_jit_condition_misoptimization_fix.diff
new file mode 100644
index 0000000000..4fd46d57a1
--- /dev/null
+++ b/src/3rdparty/pcre/patches/bug_1423_jit_condition_misoptimization_fix.diff
@@ -0,0 +1,15 @@
+Index: pcre_jit_compile.c
+===================================================================
+--- pcre_jit_compile.c (revision 1413)
++++ pcre_jit_compile.c (working copy)
+@@ -3546,7 +3546,9 @@
+ }
+ return TRUE;
+ }
+- if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
++ if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4])
++ && (ranges[2] | (ranges[4] - ranges[2])) == ranges[4]
++ && is_powerof2(ranges[4] - ranges[2]))
+ {
+ if (readch)
+ read_char(common);
diff --git a/src/3rdparty/pcre/patches/r1340_fix_jit_on_android.patch b/src/3rdparty/pcre/patches/r1340_fix_jit_on_android.patch
deleted file mode 100644
index 41699d4882..0000000000
--- a/src/3rdparty/pcre/patches/r1340_fix_jit_on_android.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Index: sljit/sljitConfigInternal.h
-===================================================================
---- sljit/sljitConfigInternal.h (revision 1339)
-+++ sljit/sljitConfigInternal.h (working copy)
-@@ -221,6 +221,13 @@
- #define SLJIT_CACHE_FLUSH(from, to) \
- sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from))
-
-+#elif defined __ANDROID__
-+
-+/* Android lacks __clear_cache; instead, cacheflush should be used. */
-+
-+#define SLJIT_CACHE_FLUSH(from, to) \
-+ cacheflush((long)(from), (long)(to), 0)
-+
- #elif (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. */
diff --git a/src/3rdparty/pcre/pcre.h b/src/3rdparty/pcre/pcre.h
index a6aa4e934b..c85f36b6bc 100644
--- a/src/3rdparty/pcre/pcre.h
+++ b/src/3rdparty/pcre/pcre.h
@@ -5,7 +5,7 @@
/* 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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE_MAJOR 8
-#define PCRE_MINOR 32
+#define PCRE_MINOR 34
#define PCRE_PRERELEASE
-#define PCRE_DATE 2012-11-30
+#define PCRE_DATE 2013-12-15
/* 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
@@ -96,11 +96,14 @@ extern "C" {
#endif
/* Public 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. Any of the
-compile-time options may be inspected during studying (and therefore JIT
-compiling).
+are both. Most of the compile-time options are saved with the compiled regex so
+that they can be inspected during studying (and therefore JIT compiling). Note
+that pcre_study() has its own set of options. Originally, all the options
+defined here used distinct bits. However, almost all the bits in a 32-bit word
+are now used, so in order to conserve them, option bits that were previously
+only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
+also be used for compile-time options that affect only compiling and are not
+relevant for studying or JIT compiling.
Some options for pcre_compile() change its behaviour but do not affect the
behaviour of the execution functions. Other options are passed through to the
@@ -142,8 +145,15 @@ with J. */
#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */
#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */
#define PCRE_PARTIAL 0x00008000 /* E D J ) */
-#define PCRE_DFA_SHORTEST 0x00010000 /* D */
-#define PCRE_DFA_RESTART 0x00020000 /* D */
+
+/* This pair use the same bit. */
+#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */
+#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */
+
+/* This pair use the same bit. */
+#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */
+#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */
+
#define PCRE_FIRSTLINE 0x00040000 /* C3 */
#define PCRE_DUPNAMES 0x00080000 /* C1 */
#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */
@@ -199,6 +209,7 @@ with J. */
#define PCRE_ERROR_DFA_BADRESTART (-30)
#define PCRE_ERROR_JIT_BADOPTION (-31)
#define PCRE_ERROR_BADLENGTH (-32)
+#define PCRE_ERROR_UNSET (-33)
/* Specific error codes for UTF-8 validity checks */
@@ -224,7 +235,7 @@ with J. */
#define PCRE_UTF8_ERR19 19
#define PCRE_UTF8_ERR20 20
#define PCRE_UTF8_ERR21 21
-#define PCRE_UTF8_ERR22 22
+#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */
/* Specific error codes for UTF-16 validity checks */
@@ -232,13 +243,13 @@ with J. */
#define PCRE_UTF16_ERR1 1
#define PCRE_UTF16_ERR2 2
#define PCRE_UTF16_ERR3 3
-#define PCRE_UTF16_ERR4 4
+#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */
/* Specific error codes for UTF-32 validity checks */
#define PCRE_UTF32_ERR0 0
#define PCRE_UTF32_ERR1 1
-#define PCRE_UTF32_ERR2 2
+#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */
#define PCRE_UTF32_ERR3 3
/* Request types for pcre_fullinfo() */
@@ -263,10 +274,13 @@ with J. */
#define PCRE_INFO_JIT 16
#define PCRE_INFO_JITSIZE 17
#define PCRE_INFO_MAXLOOKBEHIND 18
-#define PCRE_INFO_FIRSTCHARACTER 19
-#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
+#define PCRE_INFO_FIRSTCHARACTER 19
+#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
#define PCRE_INFO_REQUIREDCHAR 21
-#define PCRE_INFO_REQUIREDCHARFLAGS 22
+#define PCRE_INFO_REQUIREDCHARFLAGS 22
+#define PCRE_INFO_MATCHLIMIT 23
+#define PCRE_INFO_RECURSIONLIMIT 24
+#define PCRE_INFO_MATCH_EMPTY 25
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
@@ -284,6 +298,7 @@ compatible. */
#define PCRE_CONFIG_UTF16 10
#define PCRE_CONFIG_JITTARGET 11
#define PCRE_CONFIG_UTF32 12
+#define PCRE_CONFIG_PARENS_LIMIT 13
/* Request types for pcre_study(). Do not re-arrange, in order to remain
compatible. */
@@ -645,6 +660,9 @@ PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
pcre16_jit_callback, void *);
PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
pcre32_jit_callback, void *);
+PCRE_EXP_DECL void pcre_jit_free_unused_memory(void);
+PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void);
+PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/3rdparty/pcre/pcre16_valid_utf16.c b/src/3rdparty/pcre/pcre16_valid_utf16.c
index 1486dfac09..1987f2710c 100644
--- a/src/3rdparty/pcre/pcre16_valid_utf16.c
+++ b/src/3rdparty/pcre/pcre16_valid_utf16.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -69,7 +69,7 @@ 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 Non-character
+PCRE_UTF16_ERR4 Unused (was non-character)
Arguments:
string points to the string
@@ -100,19 +100,10 @@ for (p = string; length-- > 0; p++)
if ((c & 0xf800) != 0xd800)
{
/* Normal UTF-16 code point. Neither high nor low surrogate. */
-
- /* Check for non-characters */
- if ((c & 0xfffeu) == 0xfffeu || (c >= 0xfdd0u && c <= 0xfdefu))
- {
- *erroroffset = p - string;
- return PCRE_UTF16_ERR4;
- }
}
else if ((c & 0x0400) == 0)
{
- /* High surrogate. */
-
- /* Must be a followed by a low surrogate. */
+ /* High surrogate. Must be a followed by a low surrogate. */
if (length == 0)
{
*erroroffset = p - string;
@@ -125,16 +116,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = p - string;
return PCRE_UTF16_ERR2;
}
- else
- {
- /* Valid surrogate, but check for non-characters */
- c = (((c & 0x3ffu) << 10) | (*p & 0x3ffu)) + 0x10000u;
- if ((c & 0xfffeu) == 0xfffeu)
- {
- *erroroffset = p - string;
- return PCRE_UTF16_ERR4;
- }
- }
}
else
{
diff --git a/src/3rdparty/pcre/pcre_byte_order.c b/src/3rdparty/pcre/pcre_byte_order.c
index 9f8eec87a5..02b8050327 100644
--- a/src/3rdparty/pcre/pcre_byte_order.c
+++ b/src/3rdparty/pcre/pcre_byte_order.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -126,14 +126,15 @@ if (re->magic_number == MAGIC_NUMBER)
}
if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
-if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
+if ((swap_uint32(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->flags = swap_uint32(re->flags);
+re->limit_match = swap_uint32(re->limit_match);
+re->limit_recursion = swap_uint32(re->limit_recursion);
+
#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
re->first_char = swap_uint16(re->first_char);
re->req_char = swap_uint16(re->req_char);
@@ -141,15 +142,15 @@ re->req_char = swap_uint16(re->req_char);
re->first_char = swap_uint32(re->first_char);
re->req_char = swap_uint32(re->req_char);
#endif
+
+re->max_lookbehind = swap_uint16(re->max_lookbehind);
+re->top_bracket = swap_uint16(re->top_bracket);
+re->top_backref = swap_uint16(re->top_backref);
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;
-#ifdef COMPILE_PCRE32
-re->dummy1 = swap_uint16(re->dummy1);
-re->dummy2 = swap_uint16(re->dummy2);
-#endif
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
{
diff --git a/src/3rdparty/pcre/pcre_chartables.c b/src/3rdparty/pcre/pcre_chartables.c
index 55df49777d..89cc255a84 100644
--- a/src/3rdparty/pcre/pcre_chartables.c
+++ b/src/3rdparty/pcre/pcre_chartables.c
@@ -163,7 +163,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */
*/
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
- 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
+ 0x00,0x01,0x01,0x01,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, /* - ' */
diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c
index b3b64fb7a0..9708b93923 100644
--- a/src/3rdparty/pcre/pcre_compile.c
+++ b/src/3rdparty/pcre/pcre_compile.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -115,6 +115,13 @@ 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)
+/* This value determines the size of the initial vector that is used for
+remembering named groups during the pre-compile. It is allocated on the stack,
+but if it is too small, it is expanded using malloc(), in a similar way to the
+workspace. The value is the number of slots in the list. */
+
+#define NAMED_GROUP_LIST_SIZE 20
+
/* 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. */
@@ -253,11 +260,25 @@ static const verbitem verbs[] = {
static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+/* Substitutes for [[:<:]] and [[:>:]], which mean start and end of word in
+another regex library. */
+
+static const pcre_uchar sub_start_of_word[] = {
+ CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
+ CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w, CHAR_RIGHT_PARENTHESIS, '\0' };
+
+static const pcre_uchar sub_end_of_word[] = {
+ CHAR_BACKSLASH, CHAR_b, CHAR_LEFT_PARENTHESIS, CHAR_QUESTION_MARK,
+ CHAR_LESS_THAN_SIGN, CHAR_EQUALS_SIGN, CHAR_BACKSLASH, CHAR_w,
+ CHAR_RIGHT_PARENTHESIS, '\0' };
+
+
/* 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. */
+for handling case independence. The indices for graph, print, and punct are
+needed, so identify them. */
static const char posix_names[] =
STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
@@ -268,6 +289,11 @@ static const char posix_names[] =
static const pcre_uint8 posix_name_lengths[] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+#define PC_GRAPH 8
+#define PC_PRINT 9
+#define PC_PUNCT 10
+
+
/* 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
@@ -295,9 +321,8 @@ static const int posix_class_maps[] = {
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. */
+/* Table of substitutes for \d etc when PCRE_UCP is set. They are replaced by
+Unicode property escapes. */
#ifdef SUPPORT_UCP
static const pcre_uchar string_PNd[] = {
@@ -322,12 +347,18 @@ static const pcre_uchar string_pXwd[] = {
static const pcre_uchar *substitutes[] = {
string_PNd, /* \D */
string_pNd, /* \d */
- string_PXsp, /* \S */ /* NOTE: Xsp is Perl space */
- string_pXsp, /* \s */
+ string_PXsp, /* \S */ /* Xsp is Perl space, but from 8.34, Perl */
+ string_pXsp, /* \s */ /* space and POSIX space are the same. */
string_PXwd, /* \W */
string_pXwd /* \w */
};
+/* The POSIX class substitutes must be in the order of the POSIX class names,
+defined above, and there are both positive and negative cases. NULL means no
+general substitute of a Unicode property escape (\p or \P). However, for some
+POSIX classes (e.g. graph, print, punct) a special property code is compiled
+directly. */
+
static const pcre_uchar string_pL[] = {
CHAR_BACKSLASH, CHAR_p, CHAR_LEFT_CURLY_BRACKET,
CHAR_L, CHAR_RIGHT_CURLY_BRACKET, '\0' };
@@ -375,8 +406,8 @@ static const pcre_uchar *posix_substitutes[] = {
NULL, /* graph */
NULL, /* print */
NULL, /* punct */
- string_pXps, /* space */ /* NOTE: Xps is POSIX space */
- string_pXwd, /* word */
+ string_pXps, /* space */ /* Xps is POSIX space, but from 8.34 */
+ string_pXwd, /* word */ /* Perl and POSIX space are the same */
NULL, /* xdigit */
/* Negated cases */
string_PL, /* ^alpha */
@@ -390,8 +421,8 @@ static const pcre_uchar *posix_substitutes[] = {
NULL, /* ^graph */
NULL, /* ^print */
NULL, /* ^punct */
- string_PXps, /* ^space */ /* NOTE: Xps is POSIX space */
- string_PXwd, /* ^word */
+ string_PXps, /* ^space */ /* Xps is POSIX space, but from 8.34 */
+ string_PXwd, /* ^word */ /* Perl and POSIX space are the same */
NULL /* ^xdigit */
};
#define POSIX_SUBSIZE (sizeof(posix_substitutes) / sizeof(pcre_uchar *))
@@ -455,7 +486,7 @@ static const char error_texts[] =
"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"
+ "character value in \\x{} or \\o{} is too large\0"
/* 35 */
"invalid condition (?(0)\0"
"\\C not allowed in lookbehind assertion\0"
@@ -487,7 +518,7 @@ static const char error_texts[] =
"a numbered reference must not be zero\0"
"an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)\0"
/* 60 */
- "(*VERB) not recognized\0"
+ "(*VERB) not recognized or malformed\0"
"number is too big\0"
"subpattern name expected\0"
"digit expected after (?+\0"
@@ -508,6 +539,14 @@ static const char error_texts[] =
"name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0"
"character value in \\u.... sequence is too large\0"
"invalid UTF-32 string\0"
+ "setting UTF is disabled by the application\0"
+ "non-hex character in \\x{} (closing brace missing?)\0"
+ /* 80 */
+ "non-octal character in \\o{} (closing brace missing?)\0"
+ "missing opening brace after \\o\0"
+ "parentheses are too deeply nested\0"
+ "invalid range in character class\0"
+ "group name must start with a non-digit\0"
;
/* Table to identify digits and hex digits. This is used when compiling
@@ -647,6 +686,183 @@ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */
#endif
+/* This table is used to check whether auto-possessification is possible
+between adjacent character-type opcodes. The left-hand (repeated) opcode is
+used to select the row, and the right-hand opcode is use to select the column.
+A value of 1 means that auto-possessification is OK. For example, the second
+value in the first row means that \D+\d can be turned into \D++\d.
+
+The Unicode property types (\P and \p) have to be present to fill out the table
+because of what their opcode values are, but the table values should always be
+zero because property types are handled separately in the code. The last four
+columns apply to items that cannot be repeated, so there is no need to have
+rows for them. 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. */
+
+#define APTROWS (LAST_AUTOTAB_LEFT_OP - FIRST_AUTOTAB_OP + 1)
+#define APTCOLS (LAST_AUTOTAB_RIGHT_OP - FIRST_AUTOTAB_OP + 1)
+
+static const pcre_uint8 autoposstab[APTROWS][APTCOLS] = {
+/* \D \d \S \s \W \w . .+ \C \P \p \R \H \h \V \v \X \Z \z $ $M */
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \D */
+ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \d */
+ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \S */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \s */
+ { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \W */
+ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 }, /* \w */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* . */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* .+ */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, /* \C */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \P */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* \p */
+ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \R */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }, /* \H */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \h */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0 }, /* \V */
+ { 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0 }, /* \v */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 } /* \X */
+};
+
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP). The
+left-hand (repeated) opcode is used to select the row, and the right-hand
+opcode is used to select the column. The values are as follows:
+
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 TRUE if the two opcodes are not the same (PROP vs NOTPROP)
+
+ 4 Check left general category vs right particular category
+ 5 Check right general category vs left particular category
+
+ 6 Left alphanum vs right general category
+ 7 Left space vs right general category
+ 8 Left word vs right general category
+
+ 9 Right alphanum vs left general category
+ 10 Right space vs left general category
+ 11 Right word vs left general category
+
+ 12 Left alphanum vs right particular category
+ 13 Left space vs right particular category
+ 14 Left word vs right particular category
+
+ 15 Right alphanum vs left particular category
+ 16 Right space vs left particular category
+ 17 Right word vs left particular category
+*/
+
+static const pcre_uint8 propposstab[PT_TABSIZE][PT_TABSIZE] = {
+/* ANY LAMP GC PC SC ALNUM SPACE PXSPACE WORD CLIST UCNC */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_ANY */
+ { 0, 3, 0, 0, 0, 3, 1, 1, 0, 0, 0 }, /* PT_LAMP */
+ { 0, 0, 2, 4, 0, 9, 10, 10, 11, 0, 0 }, /* PT_GC */
+ { 0, 0, 5, 2, 0, 15, 16, 16, 17, 0, 0 }, /* PT_PC */
+ { 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0 }, /* PT_SC */
+ { 0, 3, 6, 12, 0, 3, 1, 1, 0, 0, 0 }, /* PT_ALNUM */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_SPACE */
+ { 0, 1, 7, 13, 0, 1, 3, 3, 1, 0, 0 }, /* PT_PXSPACE */
+ { 0, 0, 8, 14, 0, 0, 1, 1, 3, 0, 0 }, /* PT_WORD */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* PT_CLIST */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 } /* PT_UCNC */
+};
+
+/* This table is used to check whether auto-possessification is possible
+between adjacent Unicode property opcodes (OP_PROP and OP_NOTPROP) when one
+specifies a general category and the other specifies a particular category. The
+row is selected by the general category and the column by the particular
+category. The value is 1 if the particular category is not part of the general
+category. */
+
+static const pcre_uint8 catposstab[7][30] = {
+/* Cc Cf Cn Co Cs Ll Lm Lo Lt Lu Mc Me Mn Nd Nl No Pc Pd Pe Pf Pi Po Ps Sc Sk Sm So Zl Zp Zs */
+ { 0, 0, 0, 0, 0, 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 }, /* C */
+ { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* L */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* M */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* N */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1 }, /* P */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1 }, /* S */
+ { 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, 0, 0, 0 } /* Z */
+};
+
+/* This table is used when checking ALNUM, (PX)SPACE, SPACE, and WORD against
+a general or particular category. The properties in each row are those
+that apply to the character set in question. Duplication means that a little
+unnecessary work is done when checking, but this keeps things much simpler
+because they can all use the same code. For more details see the comment where
+this table is used.
+
+Note: SPACE and PXSPACE used to be different because Perl excluded VT from
+"space", but from Perl 5.18 it's included, so both categories are treated the
+same here. */
+
+static const pcre_uint8 posspropstab[3][4] = {
+ { ucp_L, ucp_N, ucp_N, ucp_Nl }, /* ALNUM, 3rd and 4th values redundant */
+ { ucp_Z, ucp_Z, ucp_C, ucp_Cc }, /* SPACE and PXSPACE, 2nd value redundant */
+ { ucp_L, ucp_N, ucp_P, ucp_Po } /* WORD */
+};
+
+/* This table is used when converting repeating opcodes into possessified
+versions as a result of an explicit possessive quantifier such as ++. A zero
+value means there is no possessified version - in those cases the item in
+question must be wrapped in ONCE brackets. The table is truncated at OP_CALLOUT
+because all relevant opcodes are less than that. */
+
+static const pcre_uint8 opcode_possessify[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 15 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 16 - 31 */
+
+ 0, /* NOTI */
+ OP_POSSTAR, 0, /* STAR, MINSTAR */
+ OP_POSPLUS, 0, /* PLUS, MINPLUS */
+ OP_POSQUERY, 0, /* QUERY, MINQUERY */
+ OP_POSUPTO, 0, /* UPTO, MINUPTO */
+ 0, /* EXACT */
+ 0, 0, 0, 0, /* POS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_POSSTARI, 0, /* STARI, MINSTARI */
+ OP_POSPLUSI, 0, /* PLUSI, MINPLUSI */
+ OP_POSQUERYI, 0, /* QUERYI, MINQUERYI */
+ OP_POSUPTOI, 0, /* UPTOI, MINUPTOI */
+ 0, /* EXACTI */
+ 0, 0, 0, 0, /* POS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_NOTPOSSTAR, 0, /* NOTSTAR, NOTMINSTAR */
+ OP_NOTPOSPLUS, 0, /* NOTPLUS, NOTMINPLUS */
+ OP_NOTPOSQUERY, 0, /* NOTQUERY, NOTMINQUERY */
+ OP_NOTPOSUPTO, 0, /* NOTUPTO, NOTMINUPTO */
+ 0, /* NOTEXACT */
+ 0, 0, 0, 0, /* NOTPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_NOTPOSSTARI, 0, /* NOTSTARI, NOTMINSTARI */
+ OP_NOTPOSPLUSI, 0, /* NOTPLUSI, NOTMINPLUSI */
+ OP_NOTPOSQUERYI, 0, /* NOTQUERYI, NOTMINQUERYI */
+ OP_NOTPOSUPTOI, 0, /* NOTUPTOI, NOTMINUPTOI */
+ 0, /* NOTEXACTI */
+ 0, 0, 0, 0, /* NOTPOS{STARI,PLUSI,QUERYI,UPTOI} */
+
+ OP_TYPEPOSSTAR, 0, /* TYPESTAR, TYPEMINSTAR */
+ OP_TYPEPOSPLUS, 0, /* TYPEPLUS, TYPEMINPLUS */
+ OP_TYPEPOSQUERY, 0, /* TYPEQUERY, TYPEMINQUERY */
+ OP_TYPEPOSUPTO, 0, /* TYPEUPTO, TYPEMINUPTO */
+ 0, /* TYPEEXACT */
+ 0, 0, 0, 0, /* TYPEPOS{STAR,PLUS,QUERY,UPTO} */
+
+ OP_CRPOSSTAR, 0, /* CRSTAR, CRMINSTAR */
+ OP_CRPOSPLUS, 0, /* CRPLUS, CRMINPLUS */
+ OP_CRPOSQUERY, 0, /* CRQUERY, CRMINQUERY */
+ OP_CRPOSRANGE, 0, /* CRRANGE, CRMINRANGE */
+ 0, 0, 0, 0, /* CRPOS{STAR,PLUS,QUERY,RANGE} */
+
+ 0, 0, 0, /* CLASS, NCLASS, XCLASS */
+ 0, 0, /* REF, REFI */
+ 0, 0, /* DNREF, DNREFI */
+ 0, 0 /* RECURSE, CALLOUT */
+};
+
+
/*************************************************
* Find an error text *
@@ -674,6 +890,7 @@ return s;
}
+
/*************************************************
* Expand the workspace *
*************************************************/
@@ -751,16 +968,15 @@ return (*p == CHAR_RIGHT_CURLY_BRACKET);
*************************************************/
/* This function is called when a \ has been encountered. It either returns a
-positive value for a simple escape such as \n, or 0 for a data character
-which will be placed in chptr. A backreference to group n is returned as
-negative n. When UTF-8 is enabled, a positive value greater than 255 may
-be returned in chptr.
-On entry,ptr is pointing at the \. On exit, it is on the final character of the
-escape sequence.
+positive value for a simple escape such as \n, or 0 for a data character which
+will be placed in chptr. A backreference to group n is returned as negative n.
+When UTF-8 is enabled, a positive value greater than 255 may be returned in
+chptr. 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
- chptr points to the data character
+ chptr points to a returned data character
errorcodeptr points to the errorcode variable
bracount number of previous extracting brackets
options the options bits
@@ -797,7 +1013,8 @@ 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) { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
+else if ((i = escapes[c - CHAR_0]) != 0)
+ { if (i > 0) c = (pcre_uint32)i; else escape = -i; }
#else /* EBCDIC coding */
/* Not alphanumeric */
@@ -847,11 +1064,11 @@ else
}
#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff))
+ if (c > (utf ? 0x10ffffU : 0xffU))
#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff))
+ if (c > (utf ? 0x10ffffU : 0xffffU))
#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffff)
+ if (utf && c > 0x10ffffU)
#endif
{
*errorcodeptr = ERR76;
@@ -963,16 +1180,20 @@ else
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:
+ starting with one that is not zero is not straightforward. Perl has changed
+ over the years. Nowadays \g{} for backreferences and \o{} for octal are
+ recommended to avoid the ambiguities in the old syntax.
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. */
+ number is less than 8 (used to be 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. \8 and \9 are treated as the literal characters 8 and 9.
+
+ Inside a character class, \ followed by a digit is always either a literal
+ 8 or 9 or 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:
@@ -999,7 +1220,7 @@ else
*errorcodeptr = ERR61;
break;
}
- if (s < 10 || s <= bracount)
+ if (s < 8 || s <= bracount) /* Check for back reference */
{
escape = -s;
break;
@@ -1007,16 +1228,14 @@ else
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. */
+ /* Handle a digit following \ when the number is not a back reference. If
+ the first digit is 8 or 9, Perl used to generate a binary zero byte and
+ then treat the digit as a following literal. At least by Perl 5.18 this
+ changed so as not to insert the binary zero. */
- if ((c = *ptr) >= CHAR_8)
- {
- ptr--;
- c = 0;
- break;
- }
+ if ((c = *ptr) >= CHAR_8) break;
+
+ /* Fall through with a digit less than 8 */
/* \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
@@ -1033,15 +1252,50 @@ else
#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. */
+ /* \o is a relatively new Perl feature, supporting a more general way of
+ specifying character codes in octal. The only supported form is \o{ddd}. */
+
+ case CHAR_o:
+ if (ptr[1] != CHAR_LEFT_CURLY_BRACKET) *errorcodeptr = ERR81; else
+ {
+ ptr += 2;
+ c = 0;
+ overflow = FALSE;
+ while (*ptr >= CHAR_0 && *ptr <= CHAR_7)
+ {
+ register pcre_uint32 cc = *ptr++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+#ifdef COMPILE_PCRE32
+ if (c >= 0x20000000l) { overflow = TRUE; break; }
+#endif
+ c = (c << 3) + cc - CHAR_0 ;
+#if defined COMPILE_PCRE8
+ if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
+#elif defined COMPILE_PCRE16
+ if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
+#elif defined COMPILE_PCRE32
+ if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
+#endif
+ }
+ if (overflow)
+ {
+ while (*ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
+ *errorcodeptr = ERR34;
+ }
+ else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
+ else *errorcodeptr = ERR80;
+ }
+ break;
+
+ /* \x is complicated. In JavaScript, \x must be followed by two hexadecimal
+ numbers. Otherwise it is a lowercase x letter. */
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)
{
@@ -1058,73 +1312,86 @@ else
#endif
}
}
- break;
- }
+ } /* End JavaScript handling */
- if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
- {
- const pcre_uchar *pt = ptr + 2;
+ /* Handle \x in Perl's style. \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, { used to be treated as a data character. However, Perl
+ seems to read hex digits up to the first non-such, and ignore the rest, so
+ that, for example \x{zz} matches a binary zero. This seems crazy, so PCRE
+ now gives an error. */
- c = 0;
- overflow = FALSE;
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0)
+ else
+ {
+ if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
{
- register pcre_uint32 cc = *pt++;
- if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
+ ptr += 2;
+ c = 0;
+ overflow = FALSE;
+ while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0)
+ {
+ register pcre_uint32 cc = *ptr++;
+ if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */
#ifdef COMPILE_PCRE32
- if (c >= 0x10000000l) { overflow = TRUE; break; }
+ if (c >= 0x10000000l) { overflow = TRUE; break; }
#endif
#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));
+ 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));
+ 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
#if defined COMPILE_PCRE8
- if (c > (utf ? 0x10ffff : 0xff)) { overflow = TRUE; break; }
+ if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; }
#elif defined COMPILE_PCRE16
- if (c > (utf ? 0x10ffff : 0xffff)) { overflow = TRUE; break; }
+ if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; }
#elif defined COMPILE_PCRE32
- if (utf && c > 0x10ffff) { overflow = TRUE; break; }
+ if (utf && c > 0x10ffffU) { overflow = TRUE; break; }
#endif
- }
+ }
- if (overflow)
- {
- while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++;
- *errorcodeptr = ERR34;
- }
+ if (overflow)
+ {
+ while (MAX_255(*ptr) && (digitab[*ptr] & ctype_xdigit) != 0) ptr++;
+ *errorcodeptr = ERR34;
+ }
- if (*pt == CHAR_RIGHT_CURLY_BRACKET)
- {
- if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
- ptr = pt;
- break;
- }
+ else if (*ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ if (utf && c >= 0xd800 && c <= 0xdfff) *errorcodeptr = ERR73;
+ }
- /* If the sequence of hex digits does not end with '}', then we don't
- recognize this construct; fall through to the normal \x handling. */
- }
+ /* If the sequence of hex digits does not end with '}', give an error.
+ We used just to recognize this construct and fall through to the normal
+ \x handling, but nowadays Perl gives an error, which seems much more
+ sensible, so we do too. */
- /* Read just a single-byte hex-defined char */
+ else *errorcodeptr = ERR79;
+ } /* End of \x{} processing */
- c = 0;
- while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
- {
- pcre_uint32 cc; /* Some compilers don't like */
- cc = *(++ptr); /* ++ in initializers */
+ /* Read a single-byte hex-defined char (up to two hex digits after \x) */
+
+ else
+ {
+ c = 0;
+ while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0)
+ {
+ pcre_uint32 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));
+ 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));
+ if (cc <= CHAR_z) cc += 64; /* Convert to upper case */
+ c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
#endif
- }
+ }
+ } /* End of \xdd handling */
+ } /* End of Perl-style \x handling */
break;
/* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
@@ -1190,6 +1457,8 @@ if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w)
return escape;
}
+
+
#ifdef SUPPORT_UCP
/*************************************************
* Handle \P and \p *
@@ -1287,7 +1556,6 @@ return FALSE;
-
/*************************************************
* Read repeat counts *
*************************************************/
@@ -1356,302 +1624,6 @@ 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 / UTF-32 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 != CHAR_NULL; 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 != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
- if (*ptr != CHAR_NULL) 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)
- {
- pcre_uchar 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 == (int)(ptr - thisname) &&
- STRNCMP_UC_UC(name, thisname, (unsigned int)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) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) 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 == CHAR_NULL) return -1;
- if (*ptr == CHAR_BACKSLASH)
- {
- if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT;
- if (*ptr == CHAR_Q) for (;;)
- {
- while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {};
- if (*ptr == CHAR_NULL) goto FAIL_EXIT;
- if (*(++ptr) == CHAR_E) break;
- }
- continue;
- }
- }
- continue;
- }
-
- /* Skip comments in /x mode */
-
- if (xmode && *ptr == CHAR_NUMBER_SIGN)
- {
- ptr++;
- while (*ptr != CHAR_NULL)
- {
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
- ptr++;
-#ifdef SUPPORT_UTF
- if (utf) FORWARDCHAR(ptr);
-#endif
- }
- if (*ptr == CHAR_NULL) 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 == CHAR_NULL) 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 / UTF-32 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++ == CHAR_NULL) break;
- }
-
-return rc;
-}
-
-
-
-
-/*************************************************
* Find first significant op code *
*************************************************/
@@ -1690,9 +1662,9 @@ for (;;)
case OP_CALLOUT:
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
code += PRIV(OP_lengths)[*code];
break;
@@ -1706,7 +1678,6 @@ for (;;)
-
/*************************************************
* Find the fixed length of a branch *
*************************************************/
@@ -1830,13 +1801,13 @@ for (;;)
case OP_COMMIT:
case OP_CREF:
case OP_DEF:
+ case OP_DNCREF:
+ case OP_DNRREF:
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:
@@ -1931,16 +1902,20 @@ for (;;)
switch (*cc)
{
- case OP_CRPLUS:
- case OP_CRMINPLUS:
case OP_CRSTAR:
case OP_CRMINSTAR:
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
return -1;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1;
branchlength += (int)GET2(cc,1);
cc += 1 + 2 * IMM2_SIZE;
@@ -2009,6 +1984,8 @@ for (;;)
case OP_QUERYI:
case OP_REF:
case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
case OP_SBRA:
case OP_SBRAPOS:
case OP_SCBRA:
@@ -2045,7 +2022,6 @@ for (;;)
-
/*************************************************
* Scan compiled regex for specific bracket *
*************************************************/
@@ -2129,9 +2105,6 @@ for (;;)
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2249,9 +2222,6 @@ for (;;)
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2353,15 +2323,23 @@ Arguments:
endcode points to where to stop
utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
cd contains pointers to tables etc.
+ recurses chain of recurse_check to catch mutual recursion
Returns: TRUE if what is matched could be empty
*/
+typedef struct recurse_check {
+ struct recurse_check *prev;
+ const pcre_uchar *group;
+} recurse_check;
+
static BOOL
could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode,
- BOOL utf, compile_data *cd)
+ BOOL utf, compile_data *cd, recurse_check *recurses)
{
register pcre_uchar c;
+recurse_check this_recurse;
+
for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
code < endcode;
code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE))
@@ -2389,25 +2367,50 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
if (c == OP_RECURSE)
{
- const pcre_uchar *scode;
+ const pcre_uchar *scode = cd->start_code + GET(code, 1);
BOOL empty_branch;
- /* Test for forward reference */
+ /* Test for forward reference or uncompleted reference. This is disabled
+ when called to scan a completed pattern by setting cd->start_workspace to
+ NULL. */
- for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE)
- if ((int)GET(scode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
+ if (cd->start_workspace != NULL)
+ {
+ const pcre_uchar *tcode;
+ for (tcode = cd->start_workspace; tcode < cd->hwm; tcode += LINK_SIZE)
+ if ((int)GET(tcode, 0) == (int)(code + 1 - cd->start_code)) return TRUE;
+ if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+ }
- /* Not a forward reference, test for completed backward reference */
+ /* If we are scanning a completed pattern, there are no forward references
+ and all groups are complete. We need to detect whether this is a recursive
+ call, as otherwise there will be an infinite loop. If it is a recursion,
+ just skip over it. Simple recursions are easily detected. For mutual
+ recursions we keep a chain on the stack. */
- empty_branch = FALSE;
- scode = cd->start_code + GET(code, 1);
- if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
+ else
+ {
+ recurse_check *r = recurses;
+ const pcre_uchar *endgroup = scode;
- /* Completed backwards reference */
+ do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
+ if (code >= scode && code <= endgroup) continue; /* Simple recursion */
+
+ for (r = recurses; r != NULL; r = r->prev)
+ if (r->group == scode) break;
+ if (r != NULL) continue; /* Mutual recursion */
+ }
+
+ /* Completed reference; scan the referenced group, remembering it on the
+ stack chain to detect mutual recursions. */
+
+ empty_branch = FALSE;
+ this_recurse.prev = recurses;
+ this_recurse.group = scode;
do
{
- if (could_be_empty_branch(scode, endcode, utf, cd))
+ if (could_be_empty_branch(scode, endcode, utf, cd, &this_recurse))
{
empty_branch = TRUE;
break;
@@ -2463,7 +2466,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
empty_branch = FALSE;
do
{
- if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd))
+ if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd, NULL))
empty_branch = TRUE;
code += GET(code, 1);
}
@@ -2505,15 +2508,19 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
break;
default: /* Non-repeat => class must match */
case OP_CRPLUS: /* These repeats aren't empty */
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
return FALSE;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */
break;
}
@@ -2521,34 +2528,57 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
/* Opcodes that must match a character */
+ case OP_ANY:
+ case OP_ALLANY:
+ case OP_ANYBYTE:
+
case OP_PROP:
case OP_NOTPROP:
+ case OP_ANYNL:
+
+ case OP_NOT_HSPACE:
+ case OP_HSPACE:
+ case OP_NOT_VSPACE:
+ case OP_VSPACE:
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_PLUSI:
case OP_MINPLUS:
- case OP_POSPLUS:
- case OP_EXACT:
+ case OP_MINPLUSI:
+
case OP_NOTPLUS:
+ case OP_NOTPLUSI:
case OP_NOTMINPLUS:
+ case OP_NOTMINPLUSI:
+
+ case OP_POSPLUS:
+ case OP_POSPLUSI:
case OP_NOTPOSPLUS:
+ case OP_NOTPOSPLUSI:
+
+ case OP_EXACT:
+ case OP_EXACTI:
case OP_NOTEXACT:
+ case OP_NOTEXACTI:
+
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
@@ -2582,30 +2612,58 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
return TRUE;
/* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
- MINUPTO, and POSUPTO may be followed by a multibyte character */
+ MINUPTO, and POSUPTO and their caseless and negative versions may be
+ followed by a multibyte character. */
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
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:
+
if (utf && HAS_EXTRALEN(code[1])) code += GET_EXTRALEN(code[1]);
break;
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:
+
if (utf && HAS_EXTRALEN(code[1 + IMM2_SIZE])) code += GET_EXTRALEN(code[1 + IMM2_SIZE]);
break;
#endif
@@ -2616,9 +2674,6 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
case OP_MARK:
case OP_PRUNE_ARG:
case OP_SKIP_ARG:
- code += code[1];
- break;
-
case OP_THEN_ARG:
code += code[1];
break;
@@ -2662,7 +2717,7 @@ could_be_empty(const pcre_uchar *code, const pcre_uchar *endcode,
{
while (bcptr != NULL && bcptr->current_branch >= code)
{
- if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd))
+ if (!could_be_empty_branch(bcptr->current_branch, endcode, utf, cd, NULL))
return FALSE;
bcptr = bcptr->outer;
}
@@ -2672,6 +2727,1072 @@ return TRUE;
/*************************************************
+* Base opcode of repeated opcodes *
+*************************************************/
+
+/* Returns the base opcode for repeated single character type opcodes. If the
+opcode is not a repeated character type, it returns with the original value.
+
+Arguments: c opcode
+Returns: base opcode for the type
+*/
+
+static pcre_uchar
+get_repeat_base(pcre_uchar c)
+{
+return (c > OP_TYPEPOSUPTO)? c :
+ (c >= OP_TYPESTAR)? OP_TYPESTAR :
+ (c >= OP_NOTSTARI)? OP_NOTSTARI :
+ (c >= OP_NOTSTAR)? OP_NOTSTAR :
+ (c >= OP_STARI)? OP_STARI :
+ OP_STAR;
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+* 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(pcre_uint32 c, unsigned int ptype, unsigned int pdata,
+ BOOL negated)
+{
+const pcre_uint32 *p;
+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;
+
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included, which
+ means that Perl space and POSIX space are now identical. PCRE was changed
+ at release 8.34. */
+
+ case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ return negated;
+
+ default:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == negated;
+ }
+ break; /* Control never reaches here */
+
+ case PT_WORD:
+ return (PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
+ c == CHAR_UNDERSCORE) == negated;
+
+ case PT_CLIST:
+ p = PRIV(ucd_caseless_sets) + prop->caseset;
+ for (;;)
+ {
+ if (c < *p) return !negated;
+ if (c == *p++) return negated;
+ }
+ break; /* Control never reaches here */
+ }
+
+return FALSE;
+}
+#endif /* SUPPORT_UCP */
+
+
+
+/*************************************************
+* Fill the character property list *
+*************************************************/
+
+/* Checks whether the code points to an opcode that can take part in auto-
+possessification, and if so, fills a list with its properties.
+
+Arguments:
+ code points to start of expression
+ utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
+ fcc points to case-flipping table
+ list points to output list
+ list[0] will be filled with the opcode
+ list[1] will be non-zero if this opcode
+ can match an empty character string
+ list[2..7] depends on the opcode
+
+Returns: points to the start of the next opcode if *code is accepted
+ NULL if *code is not accepted
+*/
+
+static const pcre_uchar *
+get_chr_property_list(const pcre_uchar *code, BOOL utf,
+ const pcre_uint8 *fcc, pcre_uint32 *list)
+{
+pcre_uchar c = *code;
+pcre_uchar base;
+const pcre_uchar *end;
+pcre_uint32 chr;
+
+#ifdef SUPPORT_UCP
+pcre_uint32 *clist_dest;
+const pcre_uint32 *clist_src;
+#else
+utf = utf; /* Suppress "unused parameter" compiler warning */
+#endif
+
+list[0] = c;
+list[1] = FALSE;
+code++;
+
+if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ base = get_repeat_base(c);
+ c -= (base - OP_STAR);
+
+ if (c == OP_UPTO || c == OP_MINUPTO || c == OP_EXACT || c == OP_POSUPTO)
+ code += IMM2_SIZE;
+
+ list[1] = (c != OP_PLUS && c != OP_MINPLUS && c != OP_EXACT && c != OP_POSPLUS);
+
+ switch(base)
+ {
+ case OP_STAR:
+ list[0] = OP_CHAR;
+ break;
+
+ case OP_STARI:
+ list[0] = OP_CHARI;
+ break;
+
+ case OP_NOTSTAR:
+ list[0] = OP_NOT;
+ break;
+
+ case OP_NOTSTARI:
+ list[0] = OP_NOTI;
+ break;
+
+ case OP_TYPESTAR:
+ list[0] = *code;
+ code++;
+ break;
+ }
+ c = list[0];
+ }
+
+switch(c)
+ {
+ 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_DOLL:
+ case OP_DOLLM:
+ return code;
+
+ case OP_CHAR:
+ case OP_NOT:
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+ list[3] = NOTACHAR;
+ return code;
+
+ case OP_CHARI:
+ case OP_NOTI:
+ list[0] = (c == OP_CHARI) ? OP_CHAR : OP_NOT;
+ GETCHARINCTEST(chr, code);
+ list[2] = chr;
+
+#ifdef SUPPORT_UCP
+ if (chr < 128 || (chr < 256 && !utf))
+ list[3] = fcc[chr];
+ else
+ list[3] = UCD_OTHERCASE(chr);
+#elif defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ list[3] = (chr < 256) ? fcc[chr] : chr;
+#else
+ list[3] = fcc[chr];
+#endif
+
+ /* The othercase might be the same value. */
+
+ if (chr == list[3])
+ list[3] = NOTACHAR;
+ else
+ list[4] = NOTACHAR;
+ return code;
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (code[0] != PT_CLIST)
+ {
+ list[2] = code[0];
+ list[3] = code[1];
+ return code + 2;
+ }
+
+ /* Convert only if we have enough space. */
+
+ clist_src = PRIV(ucd_caseless_sets) + code[1];
+ clist_dest = list + 2;
+ code += 2;
+
+ do {
+ if (clist_dest >= list + 8)
+ {
+ /* Early return if there is not enough space. This should never
+ happen, since all clists are shorter than 5 character now. */
+ list[2] = code[0];
+ list[3] = code[1];
+ return code;
+ }
+ *clist_dest++ = *clist_src;
+ }
+ while(*clist_src++ != NOTACHAR);
+
+ /* All characters are stored. The terminating NOTACHAR
+ is copied form the clist itself. */
+
+ list[0] = (c == OP_PROP) ? OP_CHAR : OP_NOT;
+ return code;
+#endif
+
+ case OP_NCLASS:
+ case OP_CLASS:
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ if (c == OP_XCLASS)
+ end = code + GET(code, 0) - 1;
+ else
+#endif
+ end = code + 32 / sizeof(pcre_uchar);
+
+ switch(*end)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
+ list[1] = TRUE;
+ end++;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
+ end++;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
+ list[1] = (GET2(end, 1) == 0);
+ end += 1 + 2 * IMM2_SIZE;
+ break;
+ }
+ list[2] = end - code;
+ return end;
+ }
+return NULL; /* Opcode not accepted */
+}
+
+
+
+/*************************************************
+* Scan further character sets for match *
+*************************************************/
+
+/* Checks whether the base and the current opcode have a common character, in
+which case the base cannot be possessified.
+
+Arguments:
+ code points to the byte code
+ utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
+ cd static compile data
+ base_list the data list of the base opcode
+
+Returns: TRUE if the auto-possessification is possible
+*/
+
+static BOOL
+compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
+ const pcre_uint32 *base_list, const pcre_uchar *base_end)
+{
+pcre_uchar c;
+pcre_uint32 list[8];
+const pcre_uint32 *chr_ptr;
+const pcre_uint32 *ochr_ptr;
+const pcre_uint32 *list_ptr;
+const pcre_uchar *next_code;
+const pcre_uint8 *class_bitset;
+const pcre_uint32 *set1, *set2, *set_end;
+pcre_uint32 chr;
+BOOL accepted, invert_bits;
+
+/* Note: the base_list[1] contains whether the current opcode has greedy
+(represented by a non-zero value) quantifier. This is a different from
+other character type lists, which stores here that the character iterator
+matches to an empty string (also represented by a non-zero value). */
+
+for(;;)
+ {
+ /* All operations move the code pointer forward.
+ Therefore infinite recursions are not possible. */
+
+ c = *code;
+
+ /* Skip over callouts */
+
+ if (c == OP_CALLOUT)
+ {
+ code += PRIV(OP_lengths)[c];
+ continue;
+ }
+
+ if (c == OP_ALT)
+ {
+ do code += GET(code, 1); while (*code == OP_ALT);
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ case OP_KETRPOS:
+ /* TRUE only in greedy case. The non-greedy case could be replaced by
+ an OP_EXACT, but it is probably not worth it. (And note that OP_EXACT
+ uses more memory, which we cannot get at this stage.) */
+
+ return base_list[1] != 0;
+
+ case OP_KET:
+ /* If the bracket is capturing, and referenced by an OP_RECURSE, or
+ it is an atomic sub-pattern (assert, once, etc.) the non-greedy case
+ cannot be converted to a possessive form. */
+
+ if (base_list[1] == 0) return FALSE;
+
+ switch(*(code - GET(code, 1)))
+ {
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ /* Atomic sub-patterns and assertions can always auto-possessify their
+ last iterator. */
+ return TRUE;
+ }
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_CBRA:
+ next_code = code + GET(code, 1);
+ code += PRIV(OP_lengths)[c];
+
+ while (*next_code == OP_ALT)
+ {
+ if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE;
+ code = next_code + 1 + LINK_SIZE;
+ next_code += GET(next_code, 1);
+ }
+ continue;
+
+ case OP_BRAZERO:
+ case OP_BRAMINZERO:
+
+ next_code = code + 1;
+ if (*next_code != OP_BRA && *next_code != OP_CBRA
+ && *next_code != OP_ONCE && *next_code != OP_ONCE_NC) return FALSE;
+
+ do next_code += GET(next_code, 1); while (*next_code == OP_ALT);
+
+ /* The bracket content will be checked by the
+ OP_BRA/OP_CBRA case above. */
+ next_code += 1 + LINK_SIZE;
+ if (!compare_opcodes(next_code, utf, cd, base_list, base_end))
+ return FALSE;
+
+ code += PRIV(OP_lengths)[c];
+ continue;
+ }
+
+ /* Check for a supported opcode, and load its properties. */
+
+ code = get_chr_property_list(code, utf, cd->fcc, list);
+ if (code == NULL) return FALSE; /* Unsupported */
+
+ /* If either opcode is a small character list, set pointers for comparing
+ characters from that list with another list, or with a property. */
+
+ if (base_list[0] == OP_CHAR)
+ {
+ chr_ptr = base_list + 2;
+ list_ptr = list;
+ }
+ else if (list[0] == OP_CHAR)
+ {
+ chr_ptr = list + 2;
+ list_ptr = base_list;
+ }
+
+ /* Character bitsets can also be compared to certain opcodes. */
+
+ else if (base_list[0] == OP_CLASS || list[0] == OP_CLASS
+#ifdef COMPILE_PCRE8
+ /* In 8 bit, non-UTF mode, OP_CLASS and OP_NCLASS are the same. */
+ || (!utf && (base_list[0] == OP_NCLASS || list[0] == OP_NCLASS))
+#endif
+ )
+ {
+#ifdef COMPILE_PCRE8
+ if (base_list[0] == OP_CLASS || (!utf && base_list[0] == OP_NCLASS))
+#else
+ if (base_list[0] == OP_CLASS)
+#endif
+ {
+ set1 = (pcre_uint32 *)(base_end - base_list[2]);
+ list_ptr = list;
+ }
+ else
+ {
+ set1 = (pcre_uint32 *)(code - list[2]);
+ list_ptr = base_list;
+ }
+
+ invert_bits = FALSE;
+ switch(list_ptr[0])
+ {
+ case OP_CLASS:
+ case OP_NCLASS:
+ set2 = (pcre_uint32 *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ break;
+
+ /* OP_XCLASS cannot be supported here, because its bitset
+ is not necessarily complete. E.g: [a-\0x{200}] is stored
+ as a character range, and the appropriate bits are not set. */
+
+ case OP_NOT_DIGIT:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_DIGIT:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_digit);
+ break;
+
+ case OP_NOT_WHITESPACE:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WHITESPACE:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_space);
+ break;
+
+ case OP_NOT_WORDCHAR:
+ invert_bits = TRUE;
+ /* Fall through */
+ case OP_WORDCHAR:
+ set2 = (pcre_uint32 *)(cd->cbits + cbit_word);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ /* Compare 4 bytes to improve speed. */
+ set_end = set1 + (32 / 4);
+ if (invert_bits)
+ {
+ do
+ {
+ if ((*set1++ & ~(*set2++)) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+ else
+ {
+ do
+ {
+ if ((*set1++ & *set2++) != 0) return FALSE;
+ }
+ while (set1 < set_end);
+ }
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Some property combinations also acceptable. Unicode property opcodes are
+ processed specially; the rest can be handled with a lookup table. */
+
+ else
+ {
+ pcre_uint32 leftop, rightop;
+
+ leftop = base_list[0];
+ rightop = list[0];
+
+#ifdef SUPPORT_UCP
+ accepted = FALSE; /* Always set in non-unicode case. */
+ if (leftop == OP_PROP || leftop == OP_NOTPROP)
+ {
+ if (rightop == OP_EOD)
+ accepted = TRUE;
+ else if (rightop == OP_PROP || rightop == OP_NOTPROP)
+ {
+ int n;
+ const pcre_uint8 *p;
+ BOOL same = leftop == rightop;
+ BOOL lisprop = leftop == OP_PROP;
+ BOOL risprop = rightop == OP_PROP;
+ BOOL bothprop = lisprop && risprop;
+
+ /* There's a table that specifies how each combination is to be
+ processed:
+ 0 Always return FALSE (never auto-possessify)
+ 1 Character groups are distinct (possessify if both are OP_PROP)
+ 2 Check character categories in the same group (general or particular)
+ 3 Return TRUE if the two opcodes are not the same
+ ... see comments below
+ */
+
+ n = propposstab[base_list[2]][list[2]];
+ switch(n)
+ {
+ case 0: break;
+ case 1: accepted = bothprop; break;
+ case 2: accepted = (base_list[3] == list[3]) != same; break;
+ case 3: accepted = !same; break;
+
+ case 4: /* Left general category, right particular category */
+ accepted = risprop && catposstab[base_list[3]][list[3]] == same;
+ break;
+
+ case 5: /* Right general category, left particular category */
+ accepted = lisprop && catposstab[list[3]][base_list[3]] == same;
+ break;
+
+ /* This code is logically tricky. Think hard before fiddling with it.
+ The posspropstab table has four entries per row. Each row relates to
+ one of PCRE's special properties such as ALNUM or SPACE or WORD.
+ Only WORD actually needs all four entries, but using repeats for the
+ others means they can all use the same code below.
+
+ The first two entries in each row are Unicode general categories, and
+ apply always, because all the characters they include are part of the
+ PCRE character set. The third and fourth entries are a general and a
+ particular category, respectively, that include one or more relevant
+ characters. One or the other is used, depending on whether the check
+ is for a general or a particular category. However, in both cases the
+ category contains more characters than the specials that are defined
+ for the property being tested against. Therefore, it cannot be used
+ in a NOTPROP case.
+
+ Example: the row for WORD contains ucp_L, ucp_N, ucp_P, ucp_Po.
+ Underscore is covered by ucp_P or ucp_Po. */
+
+ case 6: /* Left alphanum vs right general category */
+ case 7: /* Left space vs right general category */
+ case 8: /* Left word vs right general category */
+ p = posspropstab[n-6];
+ accepted = risprop && lisprop ==
+ (list[3] != p[0] &&
+ list[3] != p[1] &&
+ (list[3] != p[2] || !lisprop));
+ break;
+
+ case 9: /* Right alphanum vs left general category */
+ case 10: /* Right space vs left general category */
+ case 11: /* Right word vs left general category */
+ p = posspropstab[n-9];
+ accepted = lisprop && risprop ==
+ (base_list[3] != p[0] &&
+ base_list[3] != p[1] &&
+ (base_list[3] != p[2] || !risprop));
+ break;
+
+ case 12: /* Left alphanum vs right particular category */
+ case 13: /* Left space vs right particular category */
+ case 14: /* Left word vs right particular category */
+ p = posspropstab[n-12];
+ accepted = risprop && lisprop ==
+ (catposstab[p[0]][list[3]] &&
+ catposstab[p[1]][list[3]] &&
+ (list[3] != p[3] || !lisprop));
+ break;
+
+ case 15: /* Right alphanum vs left particular category */
+ case 16: /* Right space vs left particular category */
+ case 17: /* Right word vs left particular category */
+ p = posspropstab[n-15];
+ accepted = lisprop && risprop ==
+ (catposstab[p[0]][base_list[3]] &&
+ catposstab[p[1]][base_list[3]] &&
+ (base_list[3] != p[3] || !risprop));
+ break;
+ }
+ }
+ }
+
+ else
+#endif /* SUPPORT_UCP */
+
+ accepted = leftop >= FIRST_AUTOTAB_OP && leftop <= LAST_AUTOTAB_LEFT_OP &&
+ rightop >= FIRST_AUTOTAB_OP && rightop <= LAST_AUTOTAB_RIGHT_OP &&
+ autoposstab[leftop - FIRST_AUTOTAB_OP][rightop - FIRST_AUTOTAB_OP];
+
+ if (!accepted)
+ return FALSE;
+
+ if (list[1] == 0) return TRUE;
+ /* Might be an empty repeat. */
+ continue;
+ }
+
+ /* Control reaches here only if one of the items is a small character list.
+ All characters are checked against the other side. */
+
+ do
+ {
+ chr = *chr_ptr;
+
+ switch(list_ptr[0])
+ {
+ case OP_CHAR:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr) return FALSE;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ break;
+
+ case OP_NOT:
+ ochr_ptr = list_ptr + 2;
+ do
+ {
+ if (chr == *ochr_ptr)
+ break;
+ ochr_ptr++;
+ }
+ while(*ochr_ptr != NOTACHAR);
+ if (*ochr_ptr == NOTACHAR) return FALSE; /* Not found */
+ break;
+
+ /* 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:
+ if (chr < 256 && (cd->ctypes[chr] & ctype_digit) != 0) return FALSE;
+ break;
+
+ case OP_NOT_DIGIT:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_digit) == 0) return FALSE;
+ break;
+
+ case OP_WHITESPACE:
+ if (chr < 256 && (cd->ctypes[chr] & ctype_space) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WHITESPACE:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_space) == 0) return FALSE;
+ break;
+
+ case OP_WORDCHAR:
+ if (chr < 255 && (cd->ctypes[chr] & ctype_word) != 0) return FALSE;
+ break;
+
+ case OP_NOT_WORDCHAR:
+ if (chr > 255 || (cd->ctypes[chr] & ctype_word) == 0) return FALSE;
+ break;
+
+ case OP_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_HSPACE:
+ switch(chr)
+ {
+ HSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_ANYNL:
+ case OP_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: return FALSE;
+ default: break;
+ }
+ break;
+
+ case OP_NOT_VSPACE:
+ switch(chr)
+ {
+ VSPACE_CASES: break;
+ default: return FALSE;
+ }
+ break;
+
+ case OP_DOLL:
+ case OP_EODN:
+ switch (chr)
+ {
+ case CHAR_CR:
+ case CHAR_LF:
+ case CHAR_VT:
+ case CHAR_FF:
+ case CHAR_NEL:
+#ifndef EBCDIC
+ case 0x2028:
+ case 0x2029:
+#endif /* Not EBCDIC */
+ return FALSE;
+ }
+ break;
+
+ case OP_EOD: /* Can always possessify before \z */
+ break;
+
+#ifdef SUPPORT_UCP
+ case OP_PROP:
+ case OP_NOTPROP:
+ if (!check_char_prop(chr, list_ptr[2], list_ptr[3],
+ list_ptr[0] == OP_NOTPROP))
+ return FALSE;
+ break;
+#endif
+
+ case OP_NCLASS:
+ if (chr > 255) return FALSE;
+ /* Fall through */
+
+ case OP_CLASS:
+ if (chr > 255) break;
+ class_bitset = (pcre_uint8 *)
+ ((list_ptr == list ? code : base_end) - list_ptr[2]);
+ if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE;
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ if (PRIV(xclass)(chr, (list_ptr == list ? code : base_end) -
+ list_ptr[2] + LINK_SIZE, utf)) return FALSE;
+ break;
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ chr_ptr++;
+ }
+ while(*chr_ptr != NOTACHAR);
+
+ /* At least one character must be matched from this opcode. */
+
+ if (list[1] == 0) return TRUE;
+ }
+
+return FALSE;
+}
+
+
+
+/*************************************************
+* Scan compiled regex for auto-possession *
+*************************************************/
+
+/* Replaces single character iterations with their possessive alternatives
+if appropriate. This function modifies the compiled opcode!
+
+Arguments:
+ code points to start of the byte code
+ utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
+ cd static compile data
+
+Returns: nothing
+*/
+
+static void
+auto_possessify(pcre_uchar *code, BOOL utf, const compile_data *cd)
+{
+register pcre_uchar c;
+const pcre_uchar *end;
+pcre_uchar *repeat_opcode;
+pcre_uint32 list[8];
+
+for (;;)
+ {
+ c = *code;
+
+ if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
+ {
+ c -= get_repeat_base(c) - OP_STAR;
+ end = (c <= OP_MINUPTO) ?
+ get_chr_property_list(code, utf, cd->fcc, list) : NULL;
+ list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
+
+ if (end != NULL && compare_opcodes(end, utf, cd, list, end))
+ {
+ switch(c)
+ {
+ case OP_STAR:
+ *code += OP_POSSTAR - OP_STAR;
+ break;
+
+ case OP_MINSTAR:
+ *code += OP_POSSTAR - OP_MINSTAR;
+ break;
+
+ case OP_PLUS:
+ *code += OP_POSPLUS - OP_PLUS;
+ break;
+
+ case OP_MINPLUS:
+ *code += OP_POSPLUS - OP_MINPLUS;
+ break;
+
+ case OP_QUERY:
+ *code += OP_POSQUERY - OP_QUERY;
+ break;
+
+ case OP_MINQUERY:
+ *code += OP_POSQUERY - OP_MINQUERY;
+ break;
+
+ case OP_UPTO:
+ *code += OP_POSUPTO - OP_UPTO;
+ break;
+
+ case OP_MINUPTO:
+ *code += OP_MINUPTO - OP_UPTO;
+ break;
+ }
+ }
+ c = *code;
+ }
+ else if (c == OP_CLASS || c == OP_NCLASS || c == OP_XCLASS)
+ {
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ if (c == OP_XCLASS)
+ repeat_opcode = code + GET(code, 1);
+ else
+#endif
+ repeat_opcode = code + 1 + (32 / sizeof(pcre_uchar));
+
+ c = *repeat_opcode;
+ if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
+ {
+ /* end must not be NULL. */
+ end = get_chr_property_list(code, utf, cd->fcc, list);
+
+ list[1] = (c & 1) == 0;
+
+ if (compare_opcodes(end, utf, cd, list, end))
+ {
+ switch (c)
+ {
+ case OP_CRSTAR:
+ case OP_CRMINSTAR:
+ *repeat_opcode = OP_CRPOSSTAR;
+ break;
+
+ case OP_CRPLUS:
+ case OP_CRMINPLUS:
+ *repeat_opcode = OP_CRPOSPLUS;
+ break;
+
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ *repeat_opcode = OP_CRPOSQUERY;
+ break;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ *repeat_opcode = OP_CRPOSRANGE;
+ break;
+ }
+ }
+ }
+ c = *code;
+ }
+
+ switch(c)
+ {
+ case OP_END:
+ return;
+
+ 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;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ code += GET(code, 1);
+ break;
+#endif
+
+ case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ 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. */
+
+#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
+ if (utf) switch(c)
+ {
+ 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 (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]);
+ break;
+ }
+#else
+ (void)(utf); /* Keep compiler happy by referencing function argument */
+#endif
+ }
+}
+
+
+
+/*************************************************
* Check for POSIX class syntax *
*************************************************/
@@ -2692,7 +3813,7 @@ 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,
+"l\ower". This is a lesser evil than not diagnosing bad classes when Perl does,
I think.
A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
@@ -2954,476 +4075,11 @@ for (++c; c <= d; c++)
*cptr = c; /* Rest of input range */
return 0;
}
-
-
-
-/*************************************************
-* 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(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated)
-{
-#ifdef SUPPORT_UCP
-const pcre_uint32 *p;
-#endif
-
-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;
-
-#ifdef SUPPORT_UCP
- case PT_CLIST:
- p = PRIV(ucd_caseless_sets) + prop->caseset;
- for (;;)
- {
- if (c < *p) return !negated;
- if (c == *p++) return negated;
- }
- break; /* Control never reaches here */
-#endif
- }
-
-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 / UTF-32 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_uint32 c = NOTACHAR;
-pcre_uint32 next;
-int escape;
-pcre_uchar 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 != CHAR_NULL)
- {
- 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;
- escape = check_escape(&ptr, &next, &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)
- {
- escape = 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 != CHAR_NULL)
- {
- 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;
-
-/* If the previous item is a character, get its value. */
-
-if (op_code == OP_CHAR || op_code == OP_CHARI ||
- op_code == OP_NOT || op_code == OP_NOTI)
- {
-#ifdef SUPPORT_UTF
- GETCHARTEST(c, previous);
-#else
- c = *previous;
-#endif
- }
-
-/* Now compare the next item with the previous opcode. First, handle cases when
-the next item is a character. */
-
-if (escape == 0)
- {
- /* For a caseless UTF match, the next character may have more than one other
- case, which maps to the special PT_CLIST property. Check this first. */
-
-#ifdef SUPPORT_UCP
- if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0)
- {
- unsigned int ocs = UCD_CASESET(next);
- if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT);
- }
-#endif
-
- switch(op_code)
- {
- case OP_CHAR:
- 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. We know that next can have only one other case,
- because multi-other-case characters are dealt with above. */
-
- case OP_CHARI:
- if (c == next) return FALSE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c != othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- case OP_NOT:
- return c == next;
-
- case OP_NOTI:
- if (c == next) return TRUE;
-#ifdef SUPPORT_UTF
- if (utf)
- {
- pcre_uint32 othercase;
- if (next < 128) othercase = cd->fcc[next]; else
-#ifdef SUPPORT_UCP
- othercase = UCD_OTHERCASE(next);
-#else
- othercase = NOTACHAR;
-#endif
- return c == othercase;
- }
- else
-#endif /* SUPPORT_UTF */
- return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */
-
- /* 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 > 255 || (cd->ctypes[next] & ctype_digit) == 0;
-
- case OP_NOT_DIGIT:
- return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0;
-
- case OP_WHITESPACE:
- return next > 255 || (cd->ctypes[next] & ctype_space) == 0;
-
- case OP_NOT_WHITESPACE:
- return next <= 255 && (cd->ctypes[next] & ctype_space) != 0;
-
- case OP_WORDCHAR:
- return next > 255 || (cd->ctypes[next] & ctype_word) == 0;
-
- case OP_NOT_WORDCHAR:
- return next <= 255 && (cd->ctypes[next] & ctype_word) != 0;
-
- case OP_HSPACE:
- case OP_NOT_HSPACE:
- switch(next)
- {
- HSPACE_CASES:
- 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)
- {
- VSPACE_CASES:
- 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:
- switch(escape)
- {
- case ESC_d:
- return c > 255 || (cd->ctypes[c] & ctype_digit) == 0;
-
- case ESC_D:
- return c <= 255 && (cd->ctypes[c] & ctype_digit) != 0;
-
- case ESC_s:
- return c > 255 || (cd->ctypes[c] & ctype_space) == 0;
-
- case ESC_S:
- return c <= 255 && (cd->ctypes[c] & ctype_space) != 0;
-
- case ESC_w:
- return c > 255 || (cd->ctypes[c] & ctype_word) == 0;
-
- case ESC_W:
- return c <= 255 && (cd->ctypes[c] & ctype_word) != 0;
-
- case ESC_h:
- case ESC_H:
- switch(c)
- {
- HSPACE_CASES:
- return escape != ESC_h;
-
- default:
- return escape == ESC_h;
- }
-
- case ESC_v:
- case ESC_V:
- switch(c)
- {
- VSPACE_CASES:
- return escape != ESC_v;
-
- default:
- return escape == 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[escape - ESC_DU];
- escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE);
- if (temperrorcode != 0) return FALSE;
- ptr++; /* For compatibility */
- }
- /* Fall through */
-
- case ESC_p:
- case ESC_P:
- {
- unsigned int ptype = 0, pdata = 0;
- int errorcodeptr;
- BOOL negated;
-
- ptr--; /* Make ptr point at the p or P */
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr))
- 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, (escape == 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 escape == ESC_D || escape == ESC_s || escape == ESC_W ||
- escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_DIGIT:
- return escape == ESC_d;
-
- case OP_WHITESPACE:
- return escape == ESC_S || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_WHITESPACE:
- return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R;
-
- case OP_HSPACE:
- return escape == ESC_S || escape == ESC_H || escape == ESC_d ||
- escape == ESC_w || escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_HSPACE:
- return escape == ESC_h;
-
- /* Can't have \S in here because VT matches \S (Perl anomaly) */
- case OP_ANYNL:
- case OP_VSPACE:
- return escape == ESC_V || escape == ESC_d || escape == ESC_w;
-
- case OP_NOT_VSPACE:
- return escape == ESC_v || escape == ESC_R;
-
- case OP_WORDCHAR:
- return escape == ESC_W || escape == ESC_s || escape == ESC_h ||
- escape == ESC_v || escape == ESC_R;
-
- case OP_NOT_WORDCHAR:
- return escape == ESC_w || escape == ESC_d;
-
- default:
- return FALSE;
- }
-
-/* Control does not reach here */
-}
-
-
-
-/*************************************************
* Add a character or range to a class *
*************************************************/
@@ -3672,22 +4328,22 @@ 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 place to put the first required character
+ 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 place to put the first required character
firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, or a negative number
- 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
+ reqcharptr place to put the last required character
+ reqcharflagsptr place to put the last required character flags, or a negative number
+ 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
@@ -3910,58 +4566,67 @@ for (;; ptr++)
}
goto NORMAL_CHAR;
}
+ /* Control does not reach here. */
}
- /* 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. */
+ /* In extended mode, skip white space and comments. We need a loop in order
+ to check for more white space and more comments after a comment. */
if ((options & PCRE_EXTENDED) != 0)
{
- if (MAX_255(*ptr) && (cd->ctypes[c] & ctype_space) != 0) continue;
- if (c == CHAR_NUMBER_SIGN)
+ for (;;)
{
+ while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr);
+ if (c != CHAR_NUMBER_SIGN) break;
ptr++;
while (*ptr != CHAR_NULL)
{
- if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+ if (IS_NEWLINE(ptr)) /* For non-fixed-length newline cases, */
+ { /* IS_NEWLINE sets cd->nllen. */
+ ptr += cd->nllen;
+ break;
+ }
ptr++;
#ifdef SUPPORT_UTF
if (utf) FORWARDCHAR(ptr);
#endif
}
- if (*ptr != CHAR_NULL) continue;
-
- /* Else fall through to handle end of string */
- c = 0;
+ c = *ptr; /* Either NULL or the char after a newline */
}
}
- /* No auto callout for quantifiers. */
+ /* See if the next thing is a quantifier. */
- if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
+ is_quantifier =
+ c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
+ (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
+
+ /* Fill in length of a previous callout, except when the next thing is a
+ quantifier or when processing a property substitution string in UCP mode. */
+
+ if (!is_quantifier && previous_callout != NULL && nestptr == NULL &&
+ after_manual_callout-- <= 0)
+ {
+ if (lengthptr == NULL) /* Don't attempt in pre-compile phase */
+ complete_callout(previous_callout, ptr, cd);
+ previous_callout = NULL;
+ }
+
+ /* Create auto callout, except for quantifiers, or while processing property
+ strings that are substituted for \w etc in UCP mode. */
+
+ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier && nestptr == NULL)
{
previous_callout = code;
code = auto_callout(code, ptr, cd);
}
+ /* Process the next pattern item. */
+
switch(c)
{
/* ===================================================================*/
- case 0: /* The branch terminates at string end */
+ case CHAR_NULL: /* The branch terminates at string end */
case CHAR_VERTICAL_LINE: /* or | or ) */
case CHAR_RIGHT_PARENTHESIS:
*firstcharptr = firstchar;
@@ -4039,7 +4704,29 @@ for (;; ptr++)
}
goto NORMAL_CHAR;
+ /* In another (POSIX) regex library, the ugly syntax [[:<:]] and [[:>:]] is
+ used for "start of word" and "end of word". As these are otherwise illegal
+ sequences, we don't break anything by recognizing them. They are replaced
+ by \b(?=\w) and \b(?<=\w) respectively. Sequences like [a[:<:]] are
+ erroneous and are handled by the normal code below. */
+
case CHAR_LEFT_SQUARE_BRACKET:
+ if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0)
+ {
+ nestptr = ptr + 7;
+ ptr = sub_start_of_word - 1;
+ continue;
+ }
+
+ if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0)
+ {
+ nestptr = ptr + 7;
+ ptr = sub_end_of_word - 1;
+ continue;
+ }
+
+ /* Handle a real character class. */
+
previous = code;
/* PCRE supports POSIX class stuff inside a class. Perl gives an error if
@@ -4204,24 +4891,58 @@ for (;; ptr++)
posix_class = 0;
/* When PCRE_UCP is set, some of the POSIX classes are converted to
- different escape sequences that use Unicode properties. */
+ different escape sequences that use Unicode properties \p or \P. Others
+ that are not available via \p or \P generate XCL_PROP/XCL_NOTPROP
+ directly. */
#ifdef SUPPORT_UCP
if ((options & PCRE_UCP) != 0)
{
+ unsigned int ptype = 0;
int pc = posix_class + ((local_negate)? POSIX_SUBSIZE/2 : 0);
+
+ /* The posix_substitutes table specifies which POSIX classes can be
+ converted to \p or \P items. */
+
if (posix_substitutes[pc] != NULL)
{
nestptr = tempptr + 1;
ptr = posix_substitutes[pc] - 1;
continue;
}
+
+ /* There are three other classes that generate special property calls
+ that are recognized only in an XCLASS. */
+
+ else switch(posix_class)
+ {
+ case PC_GRAPH:
+ ptype = PT_PXGRAPH;
+ /* Fall through */
+ case PC_PRINT:
+ if (ptype == 0) ptype = PT_PXPRINT;
+ /* Fall through */
+ case PC_PUNCT:
+ if (ptype == 0) ptype = PT_PXPUNCT;
+ *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP;
+ *class_uchardata++ = ptype;
+ *class_uchardata++ = 0;
+ ptr = tempptr + 1;
+ continue;
+
+ /* For all other POSIX classes, no special action is taken in UCP
+ mode. Fall through to the non_UCP case. */
+
+ default:
+ break;
+ }
}
#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. */
+ /* In the non-UCP case, or when UCP makes no difference, 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;
@@ -4277,14 +4998,12 @@ for (;; ptr++)
if (c == CHAR_BACKSLASH)
{
- escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, TRUE);
-
+ escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options,
+ TRUE);
if (*errorcodeptr != 0) goto FAILED;
-
- if (escape == 0)
- c = ec;
+ if (escape == 0) c = ec;
else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */
- else if (escape == ESC_N) /* \N is not supported in a class */
+ else if (escape == ESC_N) /* \N is not supported in a class */
{
*errorcodeptr = ERR71;
goto FAILED;
@@ -4340,21 +5059,20 @@ for (;; ptr++)
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. Luckily, the value of CHAR_VT is 0x0b in both ASCII and
- EBCDIC, so we lazily just adjust the appropriate bit. */
+ /* Perl 5.004 onwards omitted VT from \s, but restored it at Perl
+ 5.18. Before PCRE 8.34, we had to preserve the VT bit if it was
+ previously set by something earlier in the character class.
+ Luckily, the value of CHAR_VT is 0x0b in both ASCII and EBCDIC, so
+ we could just adjust the appropriate bit. From PCRE 8.34 we no
+ longer treat \s and \S specially. */
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];
+ for (c = 0; 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;
/* The rest apply in both UCP and non-UCP cases. */
@@ -4476,26 +5194,43 @@ for (;; ptr++)
#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. */
+ /* The second part of a range can be a single-character escape
+ sequence, but not any of the other escapes. Perl treats a hyphen as a
+ literal in such circumstances. However, in Perl's warning mode, a
+ warning is given, so PCRE now faults it as it is almost certainly a
+ mistake on the user's part. */
- if (!inescq && d == CHAR_BACKSLASH)
+ if (!inescq)
{
- int descape;
- descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
- if (*errorcodeptr != 0) goto FAILED;
+ if (d == CHAR_BACKSLASH)
+ {
+ int descape;
+ descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE);
+ if (*errorcodeptr != 0) goto FAILED;
- /* \b is backspace; any other special means the '-' was literal. */
+ /* 0 means a character was put into d; \b is backspace; any other
+ special causes an error. */
- if (descape != 0)
- {
- if (descape == ESC_b) d = CHAR_BS; else
+ if (descape != 0)
{
- ptr = oldptr;
- goto CLASS_SINGLE_CHARACTER; /* A few lines below */
+ if (descape == ESC_b) d = CHAR_BS; else
+ {
+ *errorcodeptr = ERR83;
+ goto FAILED;
+ }
}
}
+
+ /* A hyphen followed by a POSIX class is treated in the same way. */
+
+ else if (d == CHAR_LEFT_SQUARE_BRACKET &&
+ (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+ ptr[1] == CHAR_EQUALS_SIGN) &&
+ check_posix_syntax(ptr, &tempptr))
+ {
+ *errorcodeptr = ERR83;
+ goto FAILED;
+ }
}
/* Check that the two values are in the correct order. Optimize
@@ -4759,6 +5494,34 @@ for (;; ptr++)
tempcode = previous;
+ /* Before checking for a possessive quantifier, we must skip over
+ whitespace and comments in extended mode because Perl allows white space at
+ this point. */
+
+ if ((options & PCRE_EXTENDED) != 0)
+ {
+ const pcre_uchar *p = ptr + 1;
+ for (;;)
+ {
+ while (MAX_255(*p) && (cd->ctypes[*p] & ctype_space) != 0) p++;
+ if (*p != CHAR_NUMBER_SIGN) break;
+ p++;
+ while (*p != CHAR_NULL)
+ {
+ if (IS_NEWLINE(p)) /* For non-fixed-length newline cases, */
+ { /* IS_NEWLINE sets cd->nllen. */
+ p += cd->nllen;
+ break;
+ }
+ p++;
+#ifdef SUPPORT_UTF
+ if (utf) FORWARDCHAR(p);
+#endif
+ } /* Loop for comment characters */
+ } /* Loop for multiple comments */
+ ptr = p - 1; /* Character before the next significant one. */
+ }
+
/* 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,
@@ -4853,19 +5616,6 @@ for (;; ptr++)
}
}
- /* 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 */
}
@@ -4883,14 +5633,6 @@ for (;; ptr++)
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)
{
@@ -4907,16 +5649,6 @@ for (;; ptr++)
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;
@@ -5049,13 +5781,12 @@ for (;; ptr++)
/* 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 ||
+ 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)
+ *previous == OP_REF || *previous == OP_REFI ||
+ *previous == OP_DNREF || *previous == OP_DNREFI)
{
if (repeat_max == 0)
{
@@ -5063,16 +5794,6 @@ for (;; ptr++)
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)
@@ -5093,8 +5814,9 @@ for (;; ptr++)
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. */
+ ASSERTBACK_NOT, ONCE, ONCE_NC, BRA, BRAPOS, CBRA, CBRAPOS, 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)
{
@@ -5112,7 +5834,7 @@ for (;; ptr++)
/* 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. */
+ maximum is not zero or one, set it to 1. */
if (*previous < OP_ONCE) /* Assertion */
{
@@ -5415,7 +6137,7 @@ for (;; ptr++)
pcre_uchar *scode = bracode;
do
{
- if (could_be_empty_branch(scode, ketcode, utf, cd))
+ if (could_be_empty_branch(scode, ketcode, utf, cd, NULL))
{
*bracode += OP_SBRA - OP_BRA;
break;
@@ -5485,43 +6207,105 @@ for (;; ptr++)
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.
+ /* If the character following a repeat is '+', 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. */
+ 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. */
if (possessive_quantifier)
{
int len;
- if (*tempcode == OP_TYPEEXACT)
+ /* Possessifying an EXACT quantifier has no effect, so we can ignore it.
+ However, QUERY, STAR, or UPTO may follow (for quantifiers such as {5,6},
+ {5,}, or {5,10}). We skip over an EXACT item; if the length of what
+ remains is greater than zero, there's a further opcode that can be
+ handled. If not, do nothing, leaving the EXACT alone. */
+
+ switch(*tempcode)
+ {
+ case OP_TYPEEXACT:
tempcode += PRIV(OP_lengths)[*tempcode] +
((tempcode[1 + IMM2_SIZE] == OP_PROP
|| tempcode[1 + IMM2_SIZE] == OP_NOTPROP)? 2 : 0);
+ break;
- else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
- {
+ /* CHAR opcodes are used for exacts whose count is 1. */
+
+ case OP_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+ case OP_EXACT:
+ case OP_EXACTI:
+ case OP_NOTEXACT:
+ case OP_NOTEXACTI:
tempcode += PRIV(OP_lengths)[*tempcode];
#ifdef SUPPORT_UTF
if (utf && HAS_EXTRALEN(tempcode[-1]))
tempcode += GET_EXTRALEN(tempcode[-1]);
#endif
+ break;
+
+ /* For the class opcodes, the repeat operator appears at the end;
+ adjust tempcode to point to it. */
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ tempcode += 1 + 32/sizeof(pcre_uchar);
+ break;
+
+#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
+ case OP_XCLASS:
+ tempcode += GET(tempcode, 1);
+ break;
+#endif
}
+ /* If tempcode is equal to code (which points to the end of the repeated
+ item), it means we have skipped an EXACT item but there is no following
+ QUERY, STAR, or UPTO; the value of len will be 0, and we do nothing. In
+ all other cases, tempcode will be pointing to the repeat opcode, and will
+ be less than code, so the value of len will be greater than 0. */
+
len = (int)(code - tempcode);
+ if (len > 0)
+ {
+ unsigned int repcode = *tempcode;
+
+ /* There is a table for possessifying opcodes, all of which are less
+ than OP_CALLOUT. A zero entry means there is no possessified version.
+ */
+
+ if (repcode < OP_CALLOUT && opcode_possessify[repcode] > 0)
+ *tempcode = opcode_possessify[repcode];
+
+ /* For opcode without a special possessified version, wrap the item in
+ ONCE brackets. Because we are moving code along, we must ensure that any
+ pending recursive references are updated. */
+
+ else
+ {
+ *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);
+ }
+ }
+
+#ifdef NEVER
if (len > 0) switch (*tempcode)
{
case OP_STAR: *tempcode = OP_POSSTAR; break;
@@ -5549,6 +6333,11 @@ for (;; ptr++)
case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
case OP_TYPEUPTO: *tempcode = OP_TYPEPOSUPTO; break;
+ case OP_CRSTAR: *tempcode = OP_CRPOSSTAR; break;
+ case OP_CRPLUS: *tempcode = OP_CRPOSPLUS; break;
+ case OP_CRQUERY: *tempcode = OP_CRPOSQUERY; break;
+ case OP_CRRANGE: *tempcode = OP_CRPOSRANGE; break;
+
/* Because we are moving code along, we must ensure that any
pending recursive references are updated. */
@@ -5564,6 +6353,7 @@ for (;; ptr++)
PUT(tempcode, 1, len);
break;
}
+#endif
}
/* In all case we no longer have a previous item. We also set the
@@ -5749,30 +6539,44 @@ for (;; ptr++)
/* ------------------------------------------------------------ */
case CHAR_LEFT_PARENTHESIS:
bravalue = OP_COND; /* Conditional group */
+ tempptr = ptr;
/* 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.
+ group's having been set), 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 ways of testing a named group: (?(name)) is used by Python;
+ Perl 5.10 onwards uses (?(<name>) or (?('name')).
- There are several syntaxes for testing a named group: (?(name)) is used
- by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+ There is one unfortunate ambiguity, caused by history. 'R' can be the
+ recursive thing or the name 'R' (and similarly for 'R' followed by
+ digits). We look for a name first; if not found, we try the other case.
- 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 compatibility with auto-callouts, we allow a callout to be
+ specified before a condition that is an assertion. First, check for the
+ syntax of a callout; if found, adjust the temporary pointer that is
+ used to check for an assertion condition. That's all that is needed! */
+
+ if (ptr[1] == CHAR_QUESTION_MARK && ptr[2] == CHAR_C)
+ {
+ for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break;
+ if (ptr[i] == CHAR_RIGHT_PARENTHESIS)
+ tempptr += i + 1;
+ }
/* 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))
+ if (tempptr[1] == CHAR_QUESTION_MARK &&
+ (tempptr[2] == CHAR_EQUALS_SIGN ||
+ tempptr[2] == CHAR_EXCLAMATION_MARK ||
+ tempptr[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. */
+ /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all
+ need to skip at least 1+IMM2_SIZE bytes at the start of the group. */
code[1+LINK_SIZE] = OP_CREF;
skipbytes = 1+IMM2_SIZE;
@@ -5780,7 +6584,8 @@ for (;; ptr++)
/* Check for a test for recursion in a named group. */
- if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
+ ptr++;
+ if (*ptr == CHAR_R && ptr[1] == CHAR_AMPERSAND)
{
terminator = -1;
ptr += 2;
@@ -5788,14 +6593,15 @@ for (;; ptr++)
}
/* Check for a test for a named group's having been set, using the Perl
- syntax (?(<name>) or (?('name') */
+ syntax (?(<name>) or (?('name'), and also allow for the original PCRE
+ syntax of (?(name) or for (?(+n), (?(-n), and just (?(n). */
- else if (ptr[1] == CHAR_LESS_THAN_SIGN)
+ else if (*ptr == CHAR_LESS_THAN_SIGN)
{
terminator = CHAR_GREATER_THAN_SIGN;
ptr++;
}
- else if (ptr[1] == CHAR_APOSTROPHE)
+ else if (*ptr == CHAR_APOSTROPHE)
{
terminator = CHAR_APOSTROPHE;
ptr++;
@@ -5803,35 +6609,55 @@ for (;; ptr++)
else
{
terminator = CHAR_NULL;
- if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
+ if (*ptr == CHAR_MINUS || *ptr == CHAR_PLUS) refsign = *ptr++;
+ else if (IS_DIGIT(*ptr)) refsign = 0;
}
- /* We now expect to read a name; any thing else is an error */
+ /* Handle a number */
- if (!MAX_255(ptr[1]) || (cd->ctypes[ptr[1]] & ctype_word) == 0)
+ if (refsign >= 0)
{
- ptr += 1; /* To get the right offset */
- *errorcodeptr = ERR28;
- goto FAILED;
+ recno = 0;
+ while (IS_DIGIT(*ptr))
+ {
+ recno = recno * 10 + (int)(*ptr - CHAR_0);
+ ptr++;
+ }
}
- /* Read the name, but also get it as a number if it's all digits */
+ /* Otherwise we expect to read a name; anything else is an error. When
+ a name is one of a number of duplicates, a different opcode is used and
+ it needs more memory. Unfortunately we cannot tell whether a name is a
+ duplicate in the first pass, so we have to allow for more memory. */
- recno = 0;
- name = ++ptr;
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ else
{
- if (recno >= 0)
- recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1;
- ptr++;
+ if (IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR84;
+ goto FAILED;
+ }
+ if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_word) == 0)
+ {
+ *errorcodeptr = ERR28; /* Assertion expected */
+ goto FAILED;
+ }
+ name = ptr++;
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0)
+ {
+ ptr++;
+ }
+ namelen = (int)(ptr - name);
+ if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
}
- namelen = (int)(ptr - name);
+
+ /* Check the terminator */
if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) ||
*ptr++ != CHAR_RIGHT_PARENTHESIS)
{
- ptr--; /* Error offset */
- *errorcodeptr = ERR26;
+ ptr--; /* Error offset */
+ *errorcodeptr = ERR26; /* Malformed number or name */
goto FAILED;
}
@@ -5840,18 +6666,18 @@ for (;; ptr++)
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. */
+ reference. If refsign is not negative, it means we have a number in
+ recno. */
- if (refsign > 0)
+ if (refsign >= 0)
{
if (recno <= 0)
{
- *errorcodeptr = ERR58;
+ *errorcodeptr = ERR35;
goto FAILED;
}
- recno = (refsign == CHAR_MINUS)?
- cd->bracount - recno + 1 : recno +cd->bracount;
+ if (refsign != 0) recno = (refsign == CHAR_MINUS)?
+ cd->bracount - recno + 1 : recno + cd->bracount;
if (recno <= 0 || recno > cd->final_bracount)
{
*errorcodeptr = ERR15;
@@ -5861,11 +6687,7 @@ for (;; ptr++)
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. */
+ /* Otherwise look for the name. */
slot = cd->name_table;
for (i = 0; i < cd->names_found; i++)
@@ -5874,29 +6696,40 @@ for (;; ptr++)
slot += cd->name_entry_size;
}
- /* Found a previous named subpattern */
+ /* Found the named subpattern. If the name is duplicated, add one to
+ the opcode to change CREF/RREF into DNCREF/DNRREF and insert
+ appropriate data values. Otherwise, just insert the unique subpattern
+ number. */
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]++;
+ int offset = i++;
+ int count = 1;
+ recno = GET2(slot, 0); /* Number from first found */
+ for (; i < cd->names_found; i++)
+ {
+ slot += cd->name_entry_size;
+ if (STRNCMP_UC_UC(name, slot+IMM2_SIZE, namelen) != 0) break;
+ count++;
+ }
+ if (count > 1)
+ {
+ PUT2(code, 2+LINK_SIZE, offset);
+ PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
+ skipbytes += IMM2_SIZE;
+ code[1+LINK_SIZE]++;
+ }
+ else /* Not a duplicated name */
+ {
+ PUT2(code, 2+LINK_SIZE, recno);
+ }
}
/* If terminator == CHAR_NULL 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. */
+ CHAR_NULL [things like (?(<name>... or (?('name')... or (?(R&name)... ]
+ we have now checked all the possibilities, so give an error. */
else if (terminator != CHAR_NULL)
{
@@ -5933,19 +6766,11 @@ for (;; ptr++)
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) */
+ /* Reference to an unidentified subpattern. */
else
{
- *errorcodeptr = (recno == 0)? ERR35: ERR15;
+ *errorcodeptr = ERR15;
goto FAILED;
}
break;
@@ -5958,11 +6783,18 @@ for (;; ptr++)
ptr++;
break;
+ /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
+ thing to do, but Perl allows all assertions to be quantified, and when
+ they contain capturing parentheses there may be a potential use for
+ this feature. Not that that applies to a quantified (?!) but we allow
+ it for uniformity. */
/* ------------------------------------------------------------ */
case CHAR_EXCLAMATION_MARK: /* Negative lookahead */
ptr++;
- if (*ptr == CHAR_RIGHT_PARENTHESIS) /* Optimize (?!) */
+ if (*ptr == CHAR_RIGHT_PARENTHESIS && ptr[1] != CHAR_ASTERISK &&
+ ptr[1] != CHAR_PLUS && ptr[1] != CHAR_QUESTION_MARK &&
+ (ptr[1] != CHAR_LEFT_CURLY_BRACKET || !is_counted_repeat(ptr+2)))
{
*code++ = OP_FAIL;
previous = NULL;
@@ -6055,124 +6887,110 @@ for (;; ptr++)
/* ------------------------------------------------------------ */
DEFINE_NAME: /* Come here from (?< handling */
case CHAR_APOSTROPHE:
+ terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+ name = ++ptr;
+ if (IS_DIGIT(*ptr))
{
- terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
- CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
- name = ++ptr;
+ *errorcodeptr = ERR84; /* Group name must start with non-digit */
+ goto FAILED;
+ }
+ while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+ namelen = (int)(ptr - name);
- while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
- namelen = (int)(ptr - name);
+ /* In the pre-compile phase, do a syntax check, remember the longest
+ name, and then remember the group in a vector, expanding it if
+ necessary. Duplicates for the same number are skipped; other duplicates
+ are checked for validity. In the actual compile, there is nothing to
+ do. */
+
+ if (lengthptr != NULL)
+ {
+ named_group *ng;
+ pcre_uint32 number = cd->bracount + 1;
- /* In the pre-compile phase, just do a syntax check. */
+ if (*ptr != (pcre_uchar)terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
- if (lengthptr != NULL)
+ if (cd->names_found >= MAX_NAME_COUNT)
{
- if (*ptr != (pcre_uchar)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 = ERR49;
+ *errorcodeptr = ERR48;
goto FAILED;
}
- if (namelen + IMM2_SIZE + 1 > cd->name_entry_size)
+ }
+
+ /* Scan the list to check for duplicates. For duplicate names, if the
+ number is the same, break the loop, which causes the name to be
+ discarded; otherwise, if DUPNAMES is not set, give an error.
+ If it is set, allow the name with a different number, but continue
+ scanning in case this is a duplicate with the same number. For
+ non-duplicate names, give an error if the number is duplicated. */
+
+ ng = cd->named_groups;
+ for (i = 0; i < cd->names_found; i++, ng++)
+ {
+ if (namelen == ng->length &&
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0)
{
- cd->name_entry_size = namelen + IMM2_SIZE + 1;
- if (namelen > MAX_NAME_SIZE)
+ if (ng->number == number) break;
+ if ((options & PCRE_DUPNAMES) == 0)
{
- *errorcodeptr = ERR48;
+ *errorcodeptr = ERR43;
goto FAILED;
}
+ cd->dupnames = TRUE; /* Duplicate names exist */
+ }
+ else if (ng->number == number)
+ {
+ *errorcodeptr = ERR65;
+ 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
+ if (i >= cd->names_found) /* Not a duplicate with same number */
{
- BOOL dupname = FALSE;
- slot = cd->name_table;
+ /* Increase the list size if necessary */
- for (i = 0; i < cd->names_found; i++)
+ if (cd->names_found >= cd->named_group_list_size)
{
- 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. */
+ int newsize = cd->named_group_list_size * 2;
+ named_group *newspace = (PUBL(malloc))
+ (newsize * sizeof(named_group));
- if (crc < 0)
+ if (newspace == NULL)
{
- memmove(slot + cd->name_entry_size, slot,
- IN_UCHARS((cd->names_found - i) * cd->name_entry_size));
- break;
+ *errorcodeptr = ERR21;
+ goto FAILED;
}
- /* 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;
- }
+ memcpy(newspace, cd->named_groups,
+ cd->named_group_list_size * sizeof(named_group));
+ if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ (PUBL(free))((void *)cd->named_groups);
+ cd->named_groups = newspace;
+ cd->named_group_list_size = newsize;
}
- PUT2(slot, 0, cd->bracount + 1);
- memcpy(slot + IMM2_SIZE, name, IN_UCHARS(namelen));
- slot[IMM2_SIZE + namelen] = 0;
+ cd->named_groups[cd->names_found].name = name;
+ cd->named_groups[cd->names_found].length = namelen;
+ cd->named_groups[cd->names_found].number = number;
+ cd->names_found++;
}
}
- /* In both pre-compile and compile, count the number of names we've
- encountered. */
-
- cd->names_found++;
- ptr++; /* Move past > or ' */
+ ptr++; /* Move past > or ' in both passes. */
goto NUMBERED_GROUP;
@@ -6190,6 +7008,11 @@ for (;; ptr++)
NAMED_REF_OR_RECURSE:
name = ++ptr;
+ if (IS_DIGIT(*ptr))
+ {
+ *errorcodeptr = ERR84; /* Group name must start with non-digit */
+ goto FAILED;
+ }
while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
namelen = (int)(ptr - name);
@@ -6202,7 +7025,7 @@ for (;; ptr++)
if (lengthptr != NULL)
{
- const pcre_uchar *temp;
+ named_group *ng;
if (namelen == 0)
{
@@ -6220,27 +7043,29 @@ for (;; ptr++)
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 */
+ /* The name table does not exist in the first pass; instead we must
+ scan the list of names encountered so far in order to get the
+ number. If the name is not found, set the value to 0 for a forward
+ reference. */
+
+ ng = cd->named_groups;
+ for (i = 0; i < cd->names_found; i++, ng++)
+ {
+ if (namelen == ng->length &&
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0)
+ break;
+ }
+ recno = (i < cd->names_found)? ng->number : 0;
+
+ /* Count named back references. */
+
+ if (!is_recurse) cd->namedrefcount++;
}
- /* In the real compile, seek the name in the table. We check the name
+ /* In the real compile, search the name 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. */
+ table. That way, if the name is longer than any in the table, the
+ comparison will fail without reading beyond the table entry. */
else
{
@@ -6253,24 +7078,76 @@ for (;; ptr++)
slot += cd->name_entry_size;
}
- if (i < cd->names_found) /* Back reference */
+ if (i < cd->names_found)
{
recno = GET2(slot, 0);
}
- else if ((recno = /* Forward back reference */
- find_parens(cd, name, namelen,
- (options & PCRE_EXTENDED) != 0, utf)) <= 0)
+ else
{
*errorcodeptr = ERR15;
goto FAILED;
}
}
- /* In both phases, we can now go to the code than handles numerical
- recursion or backreferences. */
+ /* In both phases, for recursions, we can now go to the code than
+ handles numerical recursion. */
if (is_recurse) goto HANDLE_RECURSION;
- else goto HANDLE_REFERENCE;
+
+ /* In the second pass we must see if the name is duplicated. If so, we
+ generate a different opcode. */
+
+ if (lengthptr == NULL && cd->dupnames)
+ {
+ int count = 1;
+ unsigned int index = i;
+ pcre_uchar *cslot = slot + cd->name_entry_size;
+
+ for (i++; i < cd->names_found; i++)
+ {
+ if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
+ count++;
+ cslot += cd->name_entry_size;
+ }
+
+ if (count > 1)
+ {
+ if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
+ previous = code;
+ *code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
+ PUT2INC(code, 0, index);
+ PUT2INC(code, 0, count);
+
+ /* Process each potentially referenced group. */
+
+ for (; slot < cslot; slot += cd->name_entry_size)
+ {
+ open_capitem *oc;
+ recno = GET2(slot, 0);
+ 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;
+ }
+ }
+ }
+
+ continue; /* End of back ref handling */
+ }
+ }
+
+ /* First pass, or a non-duplicated name. */
+
+ goto HANDLE_REFERENCE;
/* ------------------------------------------------------------ */
@@ -6369,8 +7246,7 @@ for (;; ptr++)
if (called == NULL)
{
- if (find_parens(cd, NULL, recno,
- (options & PCRE_EXTENDED) != 0, utf) < 0)
+ if (recno > cd->final_bracount)
{
*errorcodeptr = ERR15;
goto FAILED;
@@ -6529,10 +7405,19 @@ for (;; ptr++)
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. */
+ /* Process nested bracketed regex. First check for parentheses nested too
+ deeply. */
+
+ if ((cd->parens_depth += 1) > PARENS_NEST_LIMIT)
+ {
+ *errorcodeptr = ERR82;
+ goto FAILED;
+ }
+
+ /* 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;
@@ -6563,6 +7448,8 @@ for (;; ptr++)
))
goto FAILED;
+ cd->parens_depth -= 1;
+
/* If this was an atomic group and there are no capturing groups within it,
generate OP_ONCE_NC instead of OP_ONCE. */
@@ -6738,10 +7625,9 @@ for (;; ptr++)
case CHAR_BACKSLASH:
tempptr = ptr;
escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE);
-
if (*errorcodeptr != 0) goto FAILED;
- if (escape == 0)
+ if (escape == 0) /* The escape coded a single character */
c = ec;
else
{
@@ -6778,44 +7664,31 @@ for (;; ptr++)
if (escape == ESC_g)
{
const pcre_uchar *p;
+ pcre_uint32 cf;
+
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
+ fact, because we do the 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 it's not a signed or unsigned number, treat it as a name. */
- if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
+ cf = ptr[1];
+ if (cf != CHAR_PLUS && cf != CHAR_MINUS && !IS_DIGIT(cf))
{
- BOOL is_a_number = TRUE;
- for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)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 != (pcre_uchar)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. */
+ /* Signed or unsigned number (cf = ptr[1]) is known to be plus or minus
+ or a digit. */
p = ptr + 2;
while (IS_DIGIT(*p)) p++;
@@ -6855,7 +7728,10 @@ for (;; ptr++)
open_capitem *oc;
recno = -escape;
- HANDLE_REFERENCE: /* Come here from named backref handling */
+ /* Come here from named backref handling when the reference is to a
+ single group (i.e. not to a duplicated name. */
+
+ HANDLE_REFERENCE:
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
previous = code;
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
@@ -6907,11 +7783,12 @@ for (;; ptr++)
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. Note that \b and \B do a one-character
- lookbehind. */
+ lookbehind, and \A also behaves as if it does. */
else
{
- if ((escape == ESC_b || escape == ESC_B) && cd->max_lookbehind == 0)
+ if ((escape == ESC_b || escape == ESC_B || escape == ESC_A) &&
+ cd->max_lookbehind == 0)
cd->max_lookbehind = 1;
#ifdef SUPPORT_UCP
if (escape >= ESC_DU && escape <= ESC_wu)
@@ -6951,8 +7828,8 @@ for (;; ptr++)
/* ===================================================================*/
/* 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. */
+ when the extended flag is set. If we are in a UTF mode, it may be a
+ multi-unit literal character. */
default:
NORMAL_CHAR:
@@ -6983,7 +7860,8 @@ for (;; ptr++)
*code++ = OP_PROP;
*code++ = PT_CLIST;
*code++ = c;
- if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE;
+ if (firstcharflags == REQ_UNSET)
+ firstcharflags = zerofirstcharflags = REQ_NONE;
break;
}
}
@@ -7072,24 +7950,24 @@ 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
+ 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
firstcharflagsptr place to put the first character flags, or a negative number
- reqcharptr place to put the last required character
- reqcharflagsptr place to put the last required character flags, 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
+ reqcharptr place to put the last required character
+ reqcharflagsptr place to put the last required character flags, 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
@@ -7540,9 +8418,9 @@ do {
switch (*scode)
{
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
return FALSE;
@@ -7626,13 +8504,14 @@ return TRUE;
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.
+char. If all branches start with the same asserted char, or with a
+non-conditional bracket all of whose alternatives start with the same asserted
+char (recurse ad lib), then we return that char, with the flags set to zero or
+REQ_CASELESS; otherwise return zero with REQ_NONE in the flags.
Arguments:
code points to start of expression (the bracket)
- flags points to the first char flags, or to REQ_NONE
+ flags points to the first char flags, or to REQ_NONE
inassert TRUE if in an assertion
Returns: the fixed first char, or 0 with REQ_NONE in flags
@@ -7669,7 +8548,6 @@ do {
case OP_ASSERT:
case OP_ONCE:
case OP_ONCE_NC:
- case OP_COND:
d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT);
if (dflags < 0)
return 0;
@@ -7714,6 +8592,61 @@ return c;
/*************************************************
+* Add an entry to the name/number table *
+*************************************************/
+
+/* This function is called between compiling passes to add an entry to the
+name/number table, maintaining alphabetical order. Checking for permitted
+and forbidden duplicates has already been done.
+
+Arguments:
+ cd the compile data block
+ name the name to add
+ length the length of the name
+ groupno the group number
+
+Returns: nothing
+*/
+
+static void
+add_name(compile_data *cd, const pcre_uchar *name, int length,
+ unsigned int groupno)
+{
+int i;
+pcre_uchar *slot = cd->name_table;
+
+for (i = 0; i < cd->names_found; i++)
+ {
+ int crc = memcmp(name, slot+IMM2_SIZE, IN_UCHARS(length));
+ if (crc == 0 && slot[IMM2_SIZE+length] != 0)
+ 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. In all
+ cases they are in the order in which they appear in the pattern. */
+
+ 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;
+ }
+
+PUT2(slot, 0, groupno);
+memcpy(slot + IMM2_SIZE, name, IN_UCHARS(length));
+slot[IMM2_SIZE + length] = 0;
+cd->names_found++;
+}
+
+
+
+/*************************************************
* Compile a Regular Expression *
*************************************************/
@@ -7775,12 +8708,15 @@ pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr,
{
REAL_PCRE *re;
int length = 1; /* For final END opcode */
-pcre_uint32 firstchar, reqchar;
pcre_int32 firstcharflags, reqcharflags;
+pcre_uint32 firstchar, reqchar;
+pcre_uint32 limit_match = PCRE_UINT32_MAX;
+pcre_uint32 limit_recursion = PCRE_UINT32_MAX;
int newline;
int errorcode = 0;
int skipatstart = 0;
BOOL utf;
+BOOL never_utf = FALSE;
size_t size;
pcre_uchar *code;
const pcre_uchar *codestart;
@@ -7797,6 +8733,11 @@ new memory is obtained from malloc(). */
pcre_uchar cworkspace[COMPILE_WORK_SIZE];
+/* This vector is used for remembering name groups during the pre-compile. In a
+similar way to cworkspace, it can be expanded using malloc() if necessary. */
+
+named_group named_groups[NAMED_GROUP_LIST_SIZE];
+
/* Set this early so that early errors get offset 0. */
ptr = (const pcre_uchar *)pattern;
@@ -7840,9 +8781,15 @@ if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
goto PCRE_EARLY_ERROR_RETURN;
}
+/* If PCRE_NEVER_UTF is set, remember it. */
+
+if ((options & PCRE_NEVER_UTF) != 0) never_utf = TRUE;
+
/* Check for global one-time settings at the start of the pattern, and remember
the offset for later. */
+cd->external_flags = 0; /* Initialize here for LIMIT_MATCH/RECURSION */
+
while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
ptr[skipatstart+1] == CHAR_ASTERISK)
{
@@ -7870,9 +8817,49 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */
{ skipatstart += 6; options |= PCRE_UTF8; continue; }
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_AUTO_POSSESS_RIGHTPAR, 16) == 0)
+ { skipatstart += 18; options |= PCRE_NO_AUTO_POSSESS; continue; }
else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
{ skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_MATCH_EQ, 12) == 0)
+ {
+ pcre_uint32 c = 0;
+ int p = skipatstart + 14;
+ while (isdigit(ptr[p]))
+ {
+ if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow */
+ c = c*10 + ptr[p++] - CHAR_0;
+ }
+ if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
+ if (c < limit_match)
+ {
+ limit_match = c;
+ cd->external_flags |= PCRE_MLSET;
+ }
+ skipatstart = p;
+ continue;
+ }
+
+ else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_LIMIT_RECURSION_EQ, 16) == 0)
+ {
+ pcre_uint32 c = 0;
+ int p = skipatstart + 18;
+ while (isdigit(ptr[p]))
+ {
+ if (c > PCRE_UINT32_MAX / 10 - 1) break; /* Integer overflow check */
+ c = c*10 + ptr[p++] - CHAR_0;
+ }
+ if (ptr[p++] != CHAR_RIGHT_PARENTHESIS) break;
+ if (c < limit_recursion)
+ {
+ limit_recursion = c;
+ cd->external_flags |= PCRE_RLSET;
+ }
+ skipatstart = p;
+ 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)
@@ -7898,6 +8885,11 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */
/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
utf = (options & PCRE_UTF8) != 0;
+if (utf && never_utf)
+ {
+ errorcode = ERR78;
+ goto PCRE_EARLY_ERROR_RETURN2;
+ }
/* 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
@@ -8010,17 +9002,21 @@ cd->bracount = cd->final_bracount = 0;
cd->names_found = 0;
cd->name_entry_size = 0;
cd->name_table = NULL;
+cd->dupnames = FALSE;
+cd->namedrefcount = 0;
cd->start_code = cworkspace;
cd->hwm = cworkspace;
cd->start_workspace = cworkspace;
cd->workspace_size = COMPILE_WORK_SIZE;
+cd->named_groups = named_groups;
+cd->named_group_list_size = NAMED_GROUP_LIST_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->parens_depth = 0;
cd->assert_depth = 0;
cd->max_lookbehind = 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
@@ -8032,6 +9028,7 @@ 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, &firstcharflags, &reqchar, &reqcharflags, NULL,
cd, &length);
@@ -8046,14 +9043,23 @@ if (length > MAX_PATTERN_SIZE)
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. */
+/* If there are groups with duplicate names and there are also references by
+name, we must allow for the possibility of named references to duplicated
+groups. These require an extra data item each. */
-size = sizeof(REAL_PCRE) + (length + cd->names_found * cd->name_entry_size) * sizeof(pcre_uchar);
-re = (REAL_PCRE *)(PUBL(malloc))(size);
+if (cd->dupnames && cd->namedrefcount > 0)
+ length += cd->namedrefcount * IMM2_SIZE * sizeof(pcre_uchar);
+
+/* Compute the size of the data block for storing the compiled pattern. 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);
+
+/* Get the memory. */
+re = (REAL_PCRE *)(PUBL(malloc))(size);
if (re == NULL)
{
errorcode = ERR21;
@@ -8070,6 +9076,8 @@ re->magic_number = MAGIC_NUMBER;
re->size = (int)size;
re->options = cd->external_options;
re->flags = cd->external_flags;
+re->limit_match = limit_match;
+re->limit_recursion = limit_recursion;
re->first_char = 0;
re->req_char = 0;
re->name_table_offset = sizeof(REAL_PCRE) / sizeof(pcre_uchar);
@@ -8079,7 +9087,9 @@ re->ref_count = 0;
re->tables = (tables == PRIV(default_tables))? NULL : tables;
re->nullpad = NULL;
#ifdef COMPILE_PCRE32
-re->dummy1 = re->dummy2 = 0;
+re->dummy = 0;
+#else
+re->dummy1 = re->dummy2 = re->dummy3 = 0;
#endif
/* The starting points of the name/number translation table and of the code are
@@ -8090,10 +9100,10 @@ field; this time it's used for remembering forward references to subpatterns.
*/
cd->final_bracount = cd->bracount; /* Save for checking forward references */
+cd->parens_depth = 0;
cd->assert_depth = 0;
cd->bracount = 0;
cd->max_lookbehind = 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;
@@ -8104,6 +9114,20 @@ cd->had_pruneorskip = FALSE;
cd->check_lookbehind = FALSE;
cd->open_caps = NULL;
+/* If any named groups were found, create the name/number table from the list
+created in the first pass. */
+
+if (cd->names_found > 0)
+ {
+ int i = cd->names_found;
+ named_group *ng = cd->named_groups;
+ cd->names_found = 0;
+ for (; i > 0; i--, ng++)
+ add_name(cd, ng->name, ng->length, ng->number);
+ if (cd->named_group_list_size > NAMED_GROUP_LIST_SIZE)
+ (PUBL(free))((void *)cd->named_groups);
+ }
+
/* 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. */
@@ -8139,7 +9163,7 @@ if (code - codestart > length) errorcode = ERR23;
#ifdef SUPPORT_VALGRIND
/* If the estimated length exceeds the really used length, mark the extra
-allocated memory as unadressable, so that any out-of-bound reads can be
+allocated memory as unaddressable, so that any out-of-bound reads can be
detected. */
VALGRIND_MAKE_MEM_NOACCESS(code, (length - (code - codestart)) * sizeof(pcre_uchar));
#endif
@@ -8167,16 +9191,24 @@ if (cd->hwm > cd->start_workspace)
}
}
-/* If the workspace had to be expanded, free the new memory. */
+/* If the workspace had to be expanded, free the new memory. Set the pointer to
+NULL to indicate that forward references have been filled in. */
if (cd->workspace_size > COMPILE_WORK_SIZE)
(PUBL(free))((void *)cd->start_workspace);
+cd->start_workspace = NULL;
/* 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;
+/* Unless disabled, check whether single character iterators can be
+auto-possessified. The function overwrites the appropriate opcode values. */
+
+if ((options & PCRE_NO_AUTO_POSSESS) == 0)
+ auto_possessify((pcre_uchar *)codestart, utf, cd);
+
/* 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 cannot be fixed
@@ -8374,6 +9406,20 @@ if (code - codestart > length)
}
#endif /* PCRE_DEBUG */
+/* Check for a pattern than can match an empty string, so that this information
+can be provided to applications. */
+
+do
+ {
+ if (could_be_empty_branch(codestart, code, utf, cd, NULL))
+ {
+ re->flags |= PCRE_MATCH_EMPTY;
+ break;
+ }
+ codestart += GET(codestart, 1);
+ }
+while (*codestart == OP_ALT);
+
#if defined COMPILE_PCRE8
return (pcre *)re;
#elif defined COMPILE_PCRE16
@@ -8384,3 +9430,4 @@ return (pcre32 *)re;
}
/* End of pcre_compile.c */
+
diff --git a/src/3rdparty/pcre/pcre_config.c b/src/3rdparty/pcre/pcre_config.c
index db46c77a74..0ae23fdc9b 100644
--- a/src/3rdparty/pcre/pcre_config.c
+++ b/src/3rdparty/pcre/pcre_config.c
@@ -161,6 +161,10 @@ switch (what)
*((int *)where) = POSIX_MALLOC_THRESHOLD;
break;
+ case PCRE_CONFIG_PARENS_LIMIT:
+ *((unsigned long int *)where) = PARENS_NEST_LIMIT;
+ break;
+
case PCRE_CONFIG_MATCH_LIMIT:
*((unsigned long int *)where) = MATCH_LIMIT;
break;
diff --git a/src/3rdparty/pcre/pcre_dfa_exec.c b/src/3rdparty/pcre/pcre_dfa_exec.c
index adb1bbf3f5..243309789e 100644
--- a/src/3rdparty/pcre/pcre_dfa_exec.c
+++ b/src/3rdparty/pcre/pcre_dfa_exec.c
@@ -7,7 +7,7 @@ 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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -120,7 +120,7 @@ static const pcre_uint8 coptable[] = {
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 */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
1, /* Char */
1, /* Chari */
1, /* not */
@@ -151,11 +151,14 @@ static const pcre_uint8 coptable[] = {
/* Character class & ref repeats */
0, 0, 0, 0, 0, 0, /* *, *?, +, +?, ?, ?? */
0, 0, /* CRRANGE, CRMINRANGE */
+ 0, 0, 0, 0, /* Possessive *+, ++, ?+, CRPOSRANGE */
0, /* CLASS */
0, /* NCLASS */
0, /* XCLASS - variable length */
0, /* REF */
0, /* REFI */
+ 0, /* DNREF */
+ 0, /* DNREFI */
0, /* RECURSE */
0, /* CALLOUT */
0, /* Alt */
@@ -171,8 +174,8 @@ static const pcre_uint8 coptable[] = {
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, 0, /* CREF, DNCREF */
+ 0, 0, /* RREF, DNRREF */
0, /* DEF */
0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
@@ -194,7 +197,7 @@ static const pcre_uint8 poptable[] = {
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 */
+ 0, 0, 0, 0, 0, 0, /* \Z, \z, $, $M, ^, ^M */
1, /* Char */
1, /* Chari */
1, /* not */
@@ -220,11 +223,14 @@ static const pcre_uint8 poptable[] = {
/* Character class & ref repeats */
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */
1, 1, /* CRRANGE, CRMINRANGE */
+ 1, 1, 1, 1, /* Possessive *+, ++, ?+, CRPOSRANGE */
1, /* CLASS */
1, /* NCLASS */
1, /* XCLASS - variable length */
0, /* REF */
0, /* REFI */
+ 0, /* DNREF */
+ 0, /* DNREFI */
0, /* RECURSE */
0, /* CALLOUT */
0, /* Alt */
@@ -240,8 +246,8 @@ static const pcre_uint8 poptable[] = {
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, 0, /* CREF, DNCREF */
+ 0, 0, /* RREF, DNRREF */
0, /* DEF */
0, 0, 0, /* BRAZERO, BRAMINZERO, BRAPOSZERO */
0, 0, 0, /* MARK, PRUNE, PRUNE_ARG */
@@ -636,7 +642,7 @@ for (;;)
const pcre_uchar *code;
int state_offset = current_state->offset;
int codevalue, rrc;
- unsigned int count;
+ int count;
#ifdef PCRE_DEBUG
printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
@@ -1094,15 +1100,23 @@ for (;;)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
break;
case PT_WORD:
@@ -1120,6 +1134,12 @@ for (;;)
}
break;
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1249,7 +1269,7 @@ for (;;)
(d != OP_ANY || !IS_NEWLINE(ptr)) &&
((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
{
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
else
{ ADD_NEW(state_offset, count); }
@@ -1283,7 +1303,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
@@ -1338,15 +1358,23 @@ for (;;)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
break;
case PT_WORD:
@@ -1364,6 +1392,12 @@ for (;;)
}
break;
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1576,15 +1610,23 @@ for (;;)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
break;
case PT_WORD:
@@ -1602,6 +1644,12 @@ for (;;)
}
break;
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1705,7 +1753,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, ncount);
break;
default:
@@ -1749,7 +1797,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
}
}
break;
@@ -1790,7 +1838,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- ADD_NEW_DATA(-(state_offset + count), 0, 0);
+ ADD_NEW_DATA(-(state_offset + (int)count), 0, 0);
}
}
break;
@@ -1839,15 +1887,23 @@ for (;;)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ OK = TRUE;
+ break;
+
+ default:
+ OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
+ break;
+ }
break;
case PT_WORD:
@@ -1865,6 +1921,12 @@ for (;;)
}
break;
+ case PT_UCNC:
+ OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000;
+ break;
+
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1879,7 +1941,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
else
{ ADD_NEW(state_offset, count); }
@@ -1918,7 +1980,7 @@ for (;;)
}
if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
reset_could_continue = TRUE;
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
else
{ ADD_NEW_DATA(-state_offset, count, ncount); }
@@ -1960,7 +2022,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
else
{ ADD_NEW_DATA(-state_offset, count, ncount); }
@@ -2000,7 +2062,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
else
{ ADD_NEW_DATA(-state_offset, count, 0); }
@@ -2037,7 +2099,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
else
{ ADD_NEW_DATA(-state_offset, count, 0); }
@@ -2407,7 +2469,7 @@ for (;;)
}
if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
{
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
@@ -2456,7 +2518,7 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
- if (++count >= GET2(code, 1))
+ if (++count >= (int)GET2(code, 1))
{ ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
else
{ ADD_NEW(state_offset, count); }
@@ -2509,31 +2571,65 @@ for (;;)
{
case OP_CRSTAR:
case OP_CRMINSTAR:
+ case OP_CRPOSSTAR:
ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(state_offset, 0); }
+ if (isinclass)
+ {
+ if (*ecode == OP_CRPOSSTAR)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(state_offset, 0);
+ }
break;
case OP_CRPLUS:
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
count = current_state->count; /* Already matched */
if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
- if (isinclass) { count++; ADD_NEW(state_offset, count); }
+ if (isinclass)
+ {
+ if (count > 0 && *ecode == OP_CRPOSPLUS)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ count++;
+ ADD_NEW(state_offset, count);
+ }
break;
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSQUERY:
ADD_ACTIVE(next_state_offset + 1, 0);
- if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
+ if (isinclass)
+ {
+ if (*ecode == OP_CRPOSQUERY)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
+ ADD_NEW(next_state_offset + 1, 0);
+ }
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
count = current_state->count; /* Already matched */
- if (count >= GET2(ecode, 1))
+ if (count >= (int)GET2(ecode, 1))
{ ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
if (isinclass)
{
- unsigned int max = GET2(ecode, 1 + IMM2_SIZE);
+ int max = (int)GET2(ecode, 1 + IMM2_SIZE);
+ if (*ecode == OP_CRPOSRANGE)
+ {
+ active_count--; /* Remove non-match possibility */
+ next_active_state--;
+ }
if (++count >= max && max != 0) /* Max 0 => no limit */
{ ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
else
@@ -2633,9 +2729,11 @@ for (;;)
condcode = code[LINK_SIZE+1];
- /* Back reference conditions are not supported */
+ /* Back reference conditions and duplicate named recursion conditions
+ are not supported */
- if (condcode == OP_CREF || condcode == OP_NCREF)
+ if (condcode == OP_CREF || condcode == OP_DNCREF ||
+ condcode == OP_DNRREF)
return PCRE_ERROR_DFA_UCOND;
/* The DEFINE condition is always false */
@@ -2647,7 +2745,7 @@ for (;;)
which means "test if in any recursion". We can't test for specifically
recursed groups. */
- else if (condcode == OP_RREF || condcode == OP_NRREF)
+ else if (condcode == OP_RREF)
{
int value = GET2(code, LINK_SIZE + 2);
if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
@@ -3023,15 +3121,7 @@ for (;;)
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));
@@ -3545,7 +3635,17 @@ for (;;)
/* 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;
+ if (rc != PCRE_ERROR_NOMATCH || anchored)
+ {
+ if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2)
+ {
+ offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject);
+ offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
+ if (offsetcount > 2)
+ offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject);
+ }
+ return rc;
+ }
/* Advance to the next subject character unless we are at the end of a line
and firstline is set. */
diff --git a/src/3rdparty/pcre/pcre_exec.c b/src/3rdparty/pcre/pcre_exec.c
index c888468a25..913521ff0c 100644
--- a/src/3rdparty/pcre/pcre_exec.c
+++ b/src/3rdparty/pcre/pcre_exec.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -56,6 +56,20 @@ possible. There are also some static supporting functions. */
#undef min
#undef max
+/* The md->capture_last field uses the lower 16 bits for the last captured
+substring (which can never be greater than 65535) and a bit in the top half
+to mean "capture vector overflowed". This odd way of doing things was
+implemented when it was realized that preserving and restoring the overflow bit
+whenever the last capture number was saved/restored made for a neater
+interface, and doing it this way saved on (a) another variable, which would
+have increased the stack frame size (a big NO-NO in PCRE) and (b) another
+separate set of save/restore instructions. The following defines are used in
+implementing this. */
+
+#define CAPLMASK 0x0000ffff /* The bits used for last_capture */
+#define OVFLMASK 0xffff0000 /* The bits used for the overflow flag */
+#define OVFLBIT 0x00010000 /* The bit that is set for overflow */
+
/* 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. */
@@ -73,13 +87,17 @@ defined PCRE_ERROR_xxx codes, which are all negative. */
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_KETRPOS (-998)
+#define MATCH_ONCE (-997)
+/* The next 5 must be kept together and in sequence so that a test that checks
+for any one of them can use a range. */
+#define MATCH_COMMIT (-996)
#define MATCH_PRUNE (-995)
#define MATCH_SKIP (-994)
#define MATCH_SKIP_ARG (-993)
#define MATCH_THEN (-992)
+#define MATCH_BACKTRACK_MAX MATCH_THEN
+#define MATCH_BACKTRACK_MIN MATCH_COMMIT
/* 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,
@@ -89,8 +107,8 @@ because the offset vector is always a multiple of 3 long. */
/* 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 };
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, };
#ifdef PCRE_DEBUG
/*************************************************
@@ -149,7 +167,7 @@ match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
{
PCRE_PUCHAR eptr_start = eptr;
register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
-#ifdef SUPPORT_UTF
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
BOOL utf = md->utf;
#endif
@@ -177,8 +195,7 @@ ASCII characters. */
if (caseless)
{
-#ifdef SUPPORT_UTF
-#ifdef SUPPORT_UCP
+#if defined SUPPORT_UTF && defined SUPPORT_UCP
if (utf)
{
/* Match characters up to the end of the reference. NOTE: the number of
@@ -212,14 +229,13 @@ if (caseless)
}
else
#endif
-#endif
/* The same code works when not in UTF-8 mode and in UTF-8 mode when there
is no UCP support. */
{
while (length-- > 0)
{
- pcre_uchar cc, cp;
+ pcre_uint32 cc, cp;
if (eptr >= md->end_subject) return -2; /* Partial match */
cc = RAWUCHARTEST(eptr);
cp = RAWUCHARTEST(p);
@@ -416,10 +432,10 @@ typedef struct heapframe {
int Xlength;
int Xmax;
int Xmin;
- int Xnumber;
+ unsigned int Xnumber;
int Xoffset;
- int Xop;
- int Xsave_capture_last;
+ unsigned int Xop;
+ pcre_int32 Xsave_capture_last;
int Xsave_offset1, Xsave_offset2, Xsave_offset3;
int Xstacksave[REC_STACK_SAVE_MAX];
@@ -634,8 +650,8 @@ int max;
int min;
unsigned int number;
int offset;
-pcre_uchar op;
-int save_capture_last;
+unsigned int op;
+pcre_int32 save_capture_last;
int save_offset1, save_offset2, save_offset3;
int stacksave[REC_STACK_SAVE_MAX];
@@ -763,23 +779,16 @@ for (;;)
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);
+ if (rrc != MATCH_NOMATCH) 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);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
RRETURN(MATCH_PRUNE);
case OP_PRUNE_ARG:
@@ -789,38 +798,39 @@ for (;;)
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);
+ if (rrc != MATCH_NOMATCH) 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);
+ if (rrc != MATCH_NOMATCH) 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. */
+ nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
+ not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
+ that failed and any that precede it (either they also failed, or were not
+ triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
+ SKIP_ARG gets to top level, the match is re-run with md->ignore_skip_arg
+ set to the count of the one that failed. */
case OP_SKIP_ARG:
- if (md->ignore_skip_arg)
+ md->skip_arg_count++;
+ if (md->skip_arg_count <= 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);
+ if (rrc != MATCH_NOMATCH) 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. */
+ with md->ignore_skip_arg set to the value of md->skip_arg_count. */
md->start_match_ptr = ecode + 2;
RRETURN(MATCH_SKIP_ARG);
@@ -1066,6 +1076,7 @@ for (;;)
/* In all other cases, we have to make another call to match(). */
save_mark = md->mark;
+ save_capture_last = md->capture_last;
RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
RM2);
@@ -1097,6 +1108,7 @@ for (;;)
ecode += GET(ecode, 1);
md->mark = save_mark;
if (*ecode != OP_ALT) break;
+ md->capture_last = save_capture_last;
}
RRETURN(MATCH_NOMATCH);
@@ -1159,6 +1171,7 @@ for (;;)
ecode = md->start_code + code_offset;
save_capture_last = md->capture_last;
matched_once = TRUE;
+ mstart = md->start_match_ptr; /* In case \K changed it */
continue;
}
@@ -1218,6 +1231,7 @@ for (;;)
POSSESSIVE_NON_CAPTURE:
matched_once = FALSE;
code_offset = (int)(ecode - md->start_code);
+ save_capture_last = md->capture_last;
for (;;)
{
@@ -1230,6 +1244,7 @@ for (;;)
eptr = md->end_match_ptr;
ecode = md->start_code + code_offset;
matched_once = TRUE;
+ mstart = md->start_match_ptr; /* In case \K reset it */
continue;
}
@@ -1247,6 +1262,7 @@ for (;;)
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
if (*ecode != OP_ALT) break;
+ md->capture_last = save_capture_last;
}
if (matched_once || allow_zero)
@@ -1258,25 +1274,32 @@ for (;;)
/* 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. */
+ /* 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 of the item if there is only one branch, but that's exactly
+ what we want. */
case OP_COND:
case OP_SCOND:
- codelink = GET(ecode, 1);
+
+ /* The variable codelink will be added to ecode when the condition is
+ false, to get to the second branch. Setting it to the offset to the ALT
+ or KET, then incrementing ecode achieves this effect. We now have ecode
+ pointing to the condition or callout. */
+
+ codelink = GET(ecode, 1); /* Offset to the second branch */
+ ecode += 1 + LINK_SIZE; /* From this opcode */
/* 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 (*ecode == 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.callout_number = ecode[1];
cb.offset_vector = md->offset_vector;
#if defined COMPILE_PCRE8
cb.subject = (PCRE_SPTR)md->start_subject;
@@ -1288,215 +1311,130 @@ for (;;)
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.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.capture_last = md->capture_last & CAPLMASK;
+ /* Internal change requires this for API compatibility. */
+ if (cb.capture_last == 0) cb.capture_last = -1;
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);
}
+
+ /* Advance ecode past the callout, so it now points to the condition. We
+ must adjust codelink so that the value of ecode+codelink is unchanged. */
+
ecode += PRIV(OP_lengths)[OP_CALLOUT];
+ codelink -= PRIV(OP_lengths)[OP_CALLOUT];
}
- condcode = ecode[LINK_SIZE+1];
+ /* Test the various possible conditions */
- /* Now see what the actual condition is */
-
- if (condcode == OP_RREF || condcode == OP_NRREF) /* Recursion test */
+ condition = FALSE;
+ switch(condcode = *ecode)
{
- if (md->recursive == NULL) /* Not recursing => FALSE */
- {
- condition = FALSE;
- ecode += GET(ecode, 1);
- }
- else
+ case OP_RREF: /* Numbered group recursion test */
+ if (md->recursive != NULL) /* Not recursing => FALSE */
{
- unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
+ unsigned int recno = GET2(ecode, 1); /* Recursion group number*/
condition = (recno == RREF_ANY || recno == md->recursive->group_num);
+ }
+ break;
- /* 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)
+ case OP_DNRREF: /* Duplicate named group recursion test */
+ if (md->recursive != NULL)
+ {
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ while (count-- > 0)
{
- 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;
- }
- }
- }
+ unsigned int recno = GET2(slot, 0);
+ condition = recno == md->recursive->group_num;
+ if (condition) break;
+ slot += md->name_entry_size;
}
-
- /* Chose branch according to the condition */
-
- ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
}
- }
+ break;
- else if (condcode == OP_CREF || condcode == OP_NCREF) /* Group used test */
- {
- offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
+ case OP_CREF: /* Numbered group used test */
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
condition = offset < offset_top && md->offset_vector[offset] >= 0;
+ break;
- /* 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)
+ case OP_DNCREF: /* Duplicate named group used test */
{
- unsigned int refno = offset >> 1;
- pcre_uchar *slotA = md->name_table;
-
- for (i = 0; i < md->name_count; i++)
+ int count = GET2(ecode, 1 + IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ while (count-- > 0)
{
- 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;
- }
- }
+ offset = GET2(slot, 0) << 1;
+ condition = offset < offset_top && md->offset_vector[offset] >= 0;
+ if (condition) break;
+ slot += md->name_entry_size;
}
}
+ 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);
- }
+ case OP_DEF: /* DEFINE - always false */
+ break;
- /* 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. */
+ /* 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
- {
+ default:
md->match_function_type = MATCH_CONDASSERT;
- RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM3);
+ RMATCH(eptr, ecode, 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);
+
+ /* Advance ecode past the assertion to the start of the first branch,
+ but adjust it so that the general choosing code below works. */
+
+ ecode += GET(ecode, 1);
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
}
/* PCRE doesn't allow the effect of (*THEN) to escape beyond an
- assertion; it is therefore treated as NOMATCH. */
+ assertion; it is therefore treated as NOMATCH. Any other return is an
+ error. */
else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
{
RRETURN(rrc); /* Need braces because of following else */
}
- else
- {
- condition = FALSE;
- ecode += codelink;
- }
+ break;
}
- /* 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)
+ /* Choose branch according to the condition */
+
+ ecode += condition? PRIV(OP_lengths)[condcode] : codelink;
+
+ /* We are now at the branch that is to be obeyed. As there is only one, we
+ 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[-(1+LINK_SIZE)] == 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);
+ RMATCH(eptr, ecode, offset_top, md, eptrb, RM49);
RRETURN(rrc);
}
@@ -1504,7 +1442,6 @@ for (;;)
else
{
- ecode += 1 + LINK_SIZE;
}
break;
@@ -1513,7 +1450,7 @@ for (;;)
to close any currently open capturing brackets. */
case OP_CLOSE:
- number = GET2(ecode, 1);
+ number = GET2(ecode, 1); /* Must be less than 65536 */
offset = number << 1;
#ifdef PCRE_DEBUG
@@ -1521,8 +1458,8 @@ for (;;)
printf("\n");
#endif
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ md->capture_last = (md->capture_last & OVFLMASK) | number;
+ if (offset >= md->offset_max) md->capture_last |= OVFLBIT; else
{
md->offset_vector[offset] =
md->offset_vector[md->offset_end - number];
@@ -1584,28 +1521,49 @@ for (;;)
}
else condassert = FALSE;
+ /* Loop for each branch */
+
do
{
RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM4);
+
+ /* A match means that the assertion is true; break out of the loop
+ that matches its alternatives. */
+
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
mstart = md->start_match_ptr; /* In case \K reset it */
break;
}
+
+ /* If not matched, restore the previous mark setting. */
+
md->mark = save_mark;
- /* A COMMIT failure must fail the entire assertion, without trying any
- subsequent branches. */
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
- if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
+ if (rrc == MATCH_THEN)
+ {
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ rrc = MATCH_NOMATCH;
+ }
- /* PCRE does not allow THEN to escape beyond an assertion; it
- is treated as NOMATCH. */
+ /* Anything other than NOMATCH causes the entire assertion to fail,
+ passing back the return code. This includes COMMIT, SKIP, PRUNE and an
+ uncaptured THEN, which means they take their normal effect. This
+ consistent approach does not always have exactly the same effect as in
+ Perl. */
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+ if (rrc != MATCH_NOMATCH) RRETURN(rrc);
ecode += GET(ecode, 1);
}
- while (*ecode == OP_ALT);
+ while (*ecode == OP_ALT); /* Continue for next alternative */
+
+ /* If we have tried all the alternative branches, the assertion has
+ failed. If not, we broke out after a match. */
if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
@@ -1613,17 +1571,16 @@ for (;;)
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. */
+ /* Continue from after a successful 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. */
+ /* Negative assertion: all branches must fail to match for the assertion to
+ succeed. */
case OP_ASSERT_NOT:
case OP_ASSERTBACK_NOT:
@@ -1635,28 +1592,64 @@ for (;;)
}
else condassert = FALSE;
+ /* Loop for each alternative branch. */
+
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)
+ md->mark = save_mark; /* Always restore the mark setting */
+
+ switch(rrc)
{
- do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ case MATCH_MATCH: /* A successful match means */
+ case MATCH_ACCEPT: /* the assertion has failed. */
+ RRETURN(MATCH_NOMATCH);
+
+ case MATCH_NOMATCH: /* Carry on with next branch */
break;
+
+ /* See comment in the code for capturing groups above about handling
+ THEN. */
+
+ case MATCH_THEN:
+ next = ecode + GET(ecode,1);
+ if (md->start_match_ptr < next &&
+ (*ecode == OP_ALT || *next == OP_ALT))
+ {
+ rrc = MATCH_NOMATCH;
+ break;
+ }
+ /* Otherwise fall through. */
+
+ /* COMMIT, SKIP, PRUNE, and an uncaptured THEN cause the whole
+ assertion to fail to match, without considering any more alternatives.
+ Failing to match means the assertion is true. This is a consistent
+ approach, but does not always have the same effect as in Perl. */
+
+ case MATCH_COMMIT:
+ case MATCH_SKIP:
+ case MATCH_SKIP_ARG:
+ case MATCH_PRUNE:
+ do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+ goto NEG_ASSERT_TRUE; /* Break out of alternation loop */
+
+ /* Anything else is an error */
+
+ default:
+ RRETURN(rrc);
}
- /* PCRE does not allow THEN to escape beyond an assertion; it is treated
- as NOMATCH. */
+ /* Continue with next branch */
- if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
ecode += GET(ecode,1);
}
while (*ecode == OP_ALT);
- if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+ /* All branches in the assertion failed to match. */
- ecode += 1 + LINK_SIZE;
+ NEG_ASSERT_TRUE:
+ if (condassert) RRETURN(MATCH_MATCH); /* Condition assertion */
+ ecode += 1 + LINK_SIZE; /* Continue with current branch */
continue;
/* Move the subject pointer back. This occurs only at the start of
@@ -1716,7 +1709,9 @@ for (;;)
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.capture_last = md->capture_last & CAPLMASK;
+ /* Internal change requires this for API compatibility. */
+ if (cb.capture_last == 0) cb.capture_last = -1;
cb.callout_data = md->callout_data;
cb.mark = md->nomatch_mark;
if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
@@ -1762,6 +1757,7 @@ for (;;)
/* Add to "recursing stack" */
new_recursive.group_num = recno;
+ new_recursive.saved_capture_last = md->capture_last;
new_recursive.subject_position = eptr;
new_recursive.prevrec = md->recursive;
md->recursive = &new_recursive;
@@ -1785,8 +1781,9 @@ for (;;)
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. */
+ restore the offset data and the last captured value. 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);
@@ -1797,6 +1794,7 @@ for (;;)
md, eptrb, RM6);
memcpy(md->offset_vector, new_recursive.offset_save,
new_recursive.saved_max * sizeof(int));
+ md->capture_last = new_recursive.saved_capture_last;
md->recursive = new_recursive.prevrec;
if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
{
@@ -1813,11 +1811,16 @@ for (;;)
goto RECURSION_MATCHED; /* Exit loop; end processing */
}
- /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
- is treated as NOMATCH. */
+ /* PCRE does not allow THEN, SKIP, PRUNE or COMMIT to escape beyond a
+ recursion; they cause a NOMATCH for the entire recursion. These codes
+ are defined in a range that can be tested for. */
+
+ if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX)
+ RRETURN(MATCH_NOMATCH);
- else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
- rrc != MATCH_COMMIT)
+ /* Any return code other than NOMATCH is an error. */
+
+ if (rrc != MATCH_NOMATCH)
{
DPRINTF(("Recursion gave error %d\n", rrc));
if (new_recursive.offset_save != stacksave)
@@ -1947,8 +1950,8 @@ for (;;)
/* Deal with capturing */
- md->capture_last = number;
- if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+ md->capture_last = (md->capture_last & OVFLMASK) | number;
+ if (offset >= md->offset_max) md->capture_last |= OVFLBIT; 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
@@ -2004,6 +2007,7 @@ for (;;)
if (*ecode == OP_KETRPOS)
{
+ md->start_match_ptr = mstart; /* In case \K reset it */
md->end_match_ptr = eptr;
md->end_offset_top = offset_top;
RRETURN(MATCH_KETRPOS);
@@ -2571,19 +2575,24 @@ for (;;)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) ==
+ (op == OP_NOTPROP)) RRETURN(MATCH_NOMATCH);
+ break;
+ }
break;
case PT_WORD:
@@ -2604,6 +2613,13 @@ for (;;)
}
break;
+ case PT_UCNC:
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == (op == OP_NOTPROP))
+ RRETURN(MATCH_NOMATCH);
+ break;
+
/* This should never occur */
default:
@@ -2650,15 +2666,7 @@ for (;;)
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:
+ loops). 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
@@ -2668,8 +2676,39 @@ for (;;)
so that the back reference matches an empty string.
Otherwise, set the length to the length of what was matched by the
- referenced subpattern. */
+ referenced subpattern.
+
+ The OP_REF and OP_REFI opcodes are used for a reference to a numbered group
+ or to a non-duplicated named group. For a duplicated named group, OP_DNREF
+ and OP_DNREFI are used. In this case we must scan the list of groups to
+ which the name refers, and use the first one that is set. */
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ caseless = op == OP_DNREFI;
+ {
+ int count = GET2(ecode, 1+IMM2_SIZE);
+ pcre_uchar *slot = md->name_table + GET2(ecode, 1) * md->name_entry_size;
+ ecode += 1 + 2*IMM2_SIZE;
+
+ while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ if (offset < offset_top && md->offset_vector[offset] >= 0) break;
+ slot += md->name_entry_size;
+ }
+ if (count < 0)
+ length = (md->jscript_compat)? 0 : -1;
+ else
+ length = md->offset_vector[offset+1] - md->offset_vector[offset];
+ }
+ goto REF_REPEAT;
+ case OP_REF:
+ case OP_REFI:
+ caseless = op == OP_REFI;
+ offset = GET2(ecode, 1) << 1; /* Doubled ref number */
+ ecode += 1 + IMM2_SIZE;
if (offset >= offset_top || md->offset_vector[offset] < 0)
length = (md->jscript_compat)? 0 : -1;
else
@@ -2677,6 +2716,7 @@ for (;;)
/* Set up for repetition, or handle the non-repeated case */
+ REF_REPEAT:
switch (*ecode)
{
case OP_CRSTAR:
@@ -2825,8 +2865,12 @@ for (;;)
case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
@@ -2834,7 +2878,9 @@ for (;;)
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
min = GET2(ecode, 1);
max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
@@ -2976,6 +3022,9 @@ for (;;)
if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr += len;
}
+
+ if (possessive) continue; /* No backtracking */
+
for (;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
@@ -3006,6 +3055,9 @@ for (;;)
if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
eptr++;
}
+
+ if (possessive) continue; /* No backtracking */
+
while (eptr >= pp)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM19);
@@ -3021,9 +3073,10 @@ for (;;)
/* 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. */
+ /* Match an extended character class. In the 8-bit library, this opcode is
+ encountered only when UTF-8 mode mode is supported. In the 16-bit and
+ 32-bit libraries, codepoints greater than 255 may be encountered even when
+ UTF is not supported. */
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
case OP_XCLASS:
@@ -3039,8 +3092,12 @@ for (;;)
case OP_CRMINPLUS:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
c = *ecode++ - OP_CRSTAR;
- minimize = (c & 1) != 0;
+ if (c < OP_CRPOSSTAR - OP_CRSTAR) minimize = (c & 1) != 0;
+ else possessive = TRUE;
min = rep_min[c]; /* Pick up values from tables; */
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
@@ -3048,7 +3105,9 @@ for (;;)
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
minimize = (*ecode == OP_CRMINRANGE);
+ possessive = (*ecode == OP_CRPOSRANGE);
min = GET2(ecode, 1);
max = GET2(ecode, 1 + IMM2_SIZE);
if (max == 0) max = INT_MAX;
@@ -3120,6 +3179,9 @@ for (;;)
if (!PRIV(xclass)(c, data, utf)) break;
eptr += len;
}
+
+ if (possessive) continue; /* No backtracking */
+
for(;;)
{
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
@@ -3190,7 +3252,7 @@ for (;;)
if (fc < 128)
{
- pcre_uchar cc = RAWUCHAR(eptr);
+ pcre_uint32 cc = RAWUCHAR(eptr);
if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
ecode++;
eptr++;
@@ -3295,7 +3357,22 @@ for (;;)
max = rep_max[c]; /* zero for max => infinity */
if (max == 0) max = INT_MAX;
- /* Common code for all repeated single-character matches. */
+ /* Common code for all repeated single-character matches. We first check
+ for the minimum number of characters. If the minimum equals the maximum, we
+ are done. Otherwise, if minimizing, check the rest of the pattern for a
+ match; if there isn't one, advance up to the maximum, one character at a
+ time.
+
+ If maximizing, advance up to the maximum number of matching characters,
+ until eptr is past the end of the maximum run. If possessive, we are
+ then 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. When we reach the first optional
+ character position, we can save stack by doing a tail recurse.
+
+ The various UTF/non-UTF and caseful/caseless cases are handled separately,
+ for speed. */
REPEATCHAR:
#ifdef SUPPORT_UTF
@@ -3379,13 +3456,12 @@ for (;;)
}
}
- if (possessive) continue;
-
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
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);
@@ -3439,8 +3515,7 @@ for (;;)
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -3455,8 +3530,7 @@ for (;;)
{
for (fi = min;; fi++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (fi >= max) RRETURN(MATCH_NOMATCH);
@@ -3476,8 +3550,7 @@ for (;;)
pp = eptr;
for (i = min; i < max; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc; /* Faster than pcre_uchar */
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -3487,18 +3560,16 @@ for (;;)
if (fc != cc && foc != cc) break;
eptr++;
}
-
- if (possessive) continue;
-
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM25);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* Control never gets here */
}
/* Caseful comparisons (includes all multi-byte characters) */
@@ -3546,15 +3617,15 @@ for (;;)
if (fc != RAWUCHARTEST(eptr)) break;
eptr++;
}
- if (possessive) continue;
-
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM27);
eptr--;
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
}
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
}
/* Control never gets here */
@@ -3726,7 +3797,7 @@ for (;;)
}
}
else
-#endif
+#endif /* SUPPORT_UTF */
/* Not UTF mode */
{
for (i = 1; i <= min; i++)
@@ -3764,7 +3835,7 @@ for (;;)
}
}
else
-#endif
+#endif /*SUPPORT_UTF */
/* Not UTF mode */
{
for (fi = min;; fi++)
@@ -3806,17 +3877,18 @@ for (;;)
if (fc == d || (unsigned int)foc == d) break;
eptr += len;
}
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
}
}
else
-#endif
+#endif /* SUPPORT_UTF */
/* Not UTF mode */
{
for (i = min; i < max; i++)
@@ -3829,18 +3901,17 @@ for (;;)
if (fc == *eptr || foc == *eptr) break;
eptr++;
}
- if (possessive) continue;
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM31);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* Control never gets here */
}
/* Caseful comparisons */
@@ -3941,12 +4012,13 @@ for (;;)
if (fc == d) break;
eptr += len;
}
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM34);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
}
}
@@ -3964,16 +4036,16 @@ for (;;)
if (fc == *eptr) break;
eptr++;
}
- if (possessive) continue;
- while (eptr >= pp)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM35);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
}
}
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
}
/* Control never gets here */
@@ -4155,7 +4227,12 @@ for (;;)
}
break;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
for (i = 1; i <= min; i++)
{
if (eptr >= md->end_subject)
@@ -4164,26 +4241,18 @@ for (;;)
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)
+ switch(c)
{
- SCHECK_PARTIAL();
- RRETURN(MATCH_NOMATCH);
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
}
- 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;
@@ -4225,6 +4294,22 @@ for (;;)
}
break;
+ case PT_UCNC:
+ for (i = 1; i <= min; i++)
+ {
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ RRETURN(MATCH_NOMATCH);
+ }
+ GETCHARINCTEST(c, eptr);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ break;
+
/* This should not occur */
default:
@@ -4430,8 +4515,7 @@ for (;;)
case OP_DIGIT:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4448,8 +4532,7 @@ for (;;)
case OP_NOT_WHITESPACE:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4466,8 +4549,7 @@ for (;;)
case OP_WHITESPACE:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4484,8 +4566,7 @@ for (;;)
case OP_NOT_WORDCHAR:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4502,8 +4583,7 @@ for (;;)
case OP_WORDCHAR:
for (i = 1; i <= min; i++)
{
- pcre_uchar cc;
-
+ pcre_uint32 cc;
if (eptr >= md->end_subject)
{
SCHECK_PARTIAL();
@@ -4892,25 +4972,11 @@ for (;;)
}
/* 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 */
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
case PT_PXSPACE: /* POSIX space */
for (fi = min;; fi++)
{
@@ -4923,10 +4989,18 @@ for (;;)
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);
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+ break;
+
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ break;
+ }
}
/* Control never gets here */
@@ -4976,6 +5050,25 @@ for (;;)
}
/* Control never gets here */
+ case PT_UCNC:
+ 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 ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == prop_fail_result)
+ RRETURN(MATCH_NOMATCH);
+ }
+ /* Control never gets here */
+
/* This should never occur */
default:
RRETURN(PCRE_ERROR_INTERNAL);
@@ -5391,7 +5484,12 @@ for (;;)
}
break;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+
case PT_SPACE: /* Perl space */
+ case PT_PXSPACE: /* POSIX space */
for (i = min; i < max; i++)
{
int len = 1;
@@ -5401,30 +5499,21 @@ for (;;)
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)
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (prop_fail_result) goto ENDLOOP99; /* Break the loop */
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();
+ default:
+ if ((UCD_CATEGORY(c) == ucp_Z) == prop_fail_result)
+ goto ENDLOOP99; /* Break the loop */
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;
}
+ ENDLOOP99:
break;
case PT_WORD:
@@ -5470,23 +5559,42 @@ for (;;)
GOT_MAX:
break;
+ case PT_UCNC:
+ for (i = min; i < max; i++)
+ {
+ int len = 1;
+ if (eptr >= md->end_subject)
+ {
+ SCHECK_PARTIAL();
+ break;
+ }
+ GETCHARLENTEST(c, eptr, len);
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
+ c >= 0xe000) == 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;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
if (utf) BACKCHAR(eptr);
}
}
- /* Match extended Unicode sequences. We will get here only if the
+ /* Match extended Unicode grapheme clusters. We will get here only if the
support is in the binary; otherwise a compile-time error occurs. */
else if (ctype == OP_EXTUNI)
@@ -5518,22 +5626,42 @@ for (;;)
/* eptr is now past the end of the maximum run */
- if (possessive) continue;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ int lgb, rgb;
+ PCRE_PUCHAR fptr;
+
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
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 */
+
+ /* Backtracking over an extended grapheme cluster involves inspecting
+ the previous two characters (if present) to see if a break is
+ permitted between them. */
+
+ eptr--;
+ if (!utf) c = *eptr; else
+ {
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ rgb = UCD_GRAPHBREAK(c);
+
+ for (;;)
{
- if (!utf) c = *eptr; else
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
+ fptr = eptr - 1;
+ if (!utf) c = *fptr; else
{
- BACKCHAR(eptr);
- GETCHAR(c, eptr);
+ BACKCHAR(fptr);
+ GETCHAR(c, fptr);
}
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr--;
+ lgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ eptr = fptr;
+ rgb = lgb;
}
}
}
@@ -5799,18 +5927,13 @@ for (;;)
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;
+ if (possessive) continue; /* No backtracking */
for(;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM46);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
- if (eptr-- == pp) break; /* Stop if tried at original pos */
+ eptr--;
BACKCHAR(eptr);
if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL &&
RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
@@ -6048,15 +6171,10 @@ for (;;)
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)
+ if (possessive) continue; /* No backtracking */
+ for (;;)
{
+ if (eptr == pp) goto TAIL_RECURSE;
RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
eptr--;
@@ -6065,11 +6183,8 @@ for (;;)
}
}
- /* Get here if we can't make it match with any permitted repetitions */
-
- RRETURN(MATCH_NOMATCH);
+ /* Control never gets here */
}
- /* 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. */
@@ -6103,10 +6218,10 @@ switch (frame->Xwhere)
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)
+ LBL(20) LBL(21)
#endif
#ifdef SUPPORT_UTF
- LBL(16) LBL(18) LBL(20)
+ LBL(16) LBL(18)
LBL(22) LBL(23) LBL(28) LBL(30)
LBL(32) LBL(34) LBL(42) LBL(46)
#ifdef SUPPORT_UCP
@@ -6264,6 +6379,7 @@ 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 match_partial = NULL;
PCRE_PUCHAR req_char_ptr = start_match - 1;
const pcre_study_data *study;
@@ -6393,6 +6509,8 @@ md->callout_data = NULL;
tables = re->tables;
+/* The two limit values override the defaults, whatever their value. */
+
if (extra_data != NULL)
{
register unsigned int flags = extra_data->flags;
@@ -6407,6 +6525,15 @@ if (extra_data != NULL)
if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
}
+/* Limits in the regex override only if they are smaller. */
+
+if ((re->flags & PCRE_MLSET) != 0 && re->limit_match < md->match_limit)
+ md->match_limit = re->limit_match;
+
+if ((re->flags & PCRE_RLSET) != 0 &&
+ re->limit_recursion < md->match_limit_recursion)
+ md->match_limit_recursion = re->limit_recursion;
+
/* 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. */
@@ -6432,7 +6559,7 @@ 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;
+md->ignore_skip_arg = 0;
/* Some options are unpacked into BOOL variables in the hope that testing
them will be faster than individual option bits. */
@@ -6542,11 +6669,9 @@ if (re->top_backref > 0 && re->top_backref >= ocount/3)
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;
+md->capture_last = 0;
/* 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
@@ -6816,8 +6941,13 @@ for(;;)
md->match_call_count = 0;
md->match_function_type = 0;
md->end_offset_top = 0;
+ md->skip_arg_count = 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;
+ if (md->hitend && start_partial == NULL)
+ {
+ start_partial = md->start_used_ptr;
+ match_partial = start_match;
+ }
switch(rc)
{
@@ -6830,14 +6960,14 @@ for(;;)
case MATCH_SKIP_ARG:
new_start_match = start_match;
- md->ignore_skip_arg = TRUE;
+ md->ignore_skip_arg = md->skip_arg_count;
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. */
+ /* SKIP passes back the next starting point explicitly, but if it is no
+ greater than the match we have just done, treat it as NOMATCH. */
case MATCH_SKIP:
- if (md->start_match_ptr != start_match)
+ if (md->start_match_ptr > start_match)
{
new_start_match = md->start_match_ptr;
break;
@@ -6845,12 +6975,12 @@ for(;;)
/* Fall through */
/* NOMATCH and PRUNE advance by one character. THEN at this level acts
- exactly like PRUNE. Unset the ignore SKIP-with-argument flag. */
+ exactly like PRUNE. Unset ignore SKIP-with-argument. */
case MATCH_NOMATCH:
case MATCH_PRUNE:
case MATCH_THEN:
- md->ignore_skip_arg = FALSE;
+ md->ignore_skip_arg = 0;
new_start_match = start_match + 1;
#ifdef SUPPORT_UTF
if (utf)
@@ -6943,7 +7073,7 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
(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;
+ if (md->end_offset_top > arg_offset_max) md->capture_last |= OVFLBIT;
DPRINTF(("Freeing temporary memory\n"));
(PUBL(free))(md->offset_vector);
}
@@ -6951,7 +7081,8 @@ if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
/* 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)?
+ rc = ((md->capture_last & OVFLBIT) != 0 &&
+ 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
@@ -7016,7 +7147,7 @@ if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
/* Handle partial matches - disable any mark data */
-if (start_partial != NULL)
+if (match_partial != NULL)
{
DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
md->mark = NULL;
@@ -7024,6 +7155,8 @@ if (start_partial != NULL)
{
offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
+ if (offsetcount > 2)
+ offsets[2] = (int)(match_partial - (PCRE_PUCHAR)subject);
}
rc = PCRE_ERROR_PARTIAL;
}
diff --git a/src/3rdparty/pcre/pcre_fullinfo.c b/src/3rdparty/pcre/pcre_fullinfo.c
index e64da06eb4..dfac243573 100644
--- a/src/3rdparty/pcre/pcre_fullinfo.c
+++ b/src/3rdparty/pcre/pcre_fullinfo.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -222,6 +222,20 @@ switch (what)
*((int *)where) = re->max_lookbehind;
break;
+ case PCRE_INFO_MATCHLIMIT:
+ if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET;
+ *((pcre_uint32 *)where) = re->limit_match;
+ break;
+
+ case PCRE_INFO_RECURSIONLIMIT:
+ if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET;
+ *((pcre_uint32 *)where) = re->limit_recursion;
+ break;
+
+ case PCRE_INFO_MATCH_EMPTY:
+ *((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0;
+ break;
+
default: return PCRE_ERROR_BADOPTION;
}
diff --git a/src/3rdparty/pcre/pcre_internal.h b/src/3rdparty/pcre/pcre_internal.h
index f3cb001fea..0b9798c554 100644
--- a/src/3rdparty/pcre/pcre_internal.h
+++ b/src/3rdparty/pcre/pcre_internal.h
@@ -7,7 +7,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -194,23 +194,31 @@ preprocessor time in standard C environments. */
typedef unsigned char pcre_uint8;
#if USHRT_MAX == 65535
- typedef unsigned short pcre_uint16;
- typedef short pcre_int16;
+typedef unsigned short pcre_uint16;
+typedef short pcre_int16;
+#define PCRE_UINT16_MAX USHRT_MAX
+#define PCRE_INT16_MAX SHRT_MAX
#elif UINT_MAX == 65535
- typedef unsigned int pcre_uint16;
- typedef int pcre_int16;
+typedef unsigned int pcre_uint16;
+typedef int pcre_int16;
+#define PCRE_UINT16_MAX UINT_MAX
+#define PCRE_INT16_MAX INT_MAX
#else
-# error Cannot determine a type for 16-bit unsigned integers
+#error Cannot determine a type for 16-bit 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;
+#if UINT_MAX == 4294967295U
+typedef unsigned int pcre_uint32;
+typedef int pcre_int32;
+#define PCRE_UINT32_MAX UINT_MAX
+#define PCRE_INT32_MAX INT_MAX
+#elif ULONG_MAX == 4294967295UL
+typedef unsigned long int pcre_uint32;
+typedef long int pcre_int32;
+#define PCRE_UINT32_MAX ULONG_MAX
+#define PCRE_INT32_MAX LONG_MAX
#else
-# error Cannot determine a type for 32-bit unsigned integers
+#error Cannot determine a type for 32-bit integers
#endif
/* When checking for integer overflow in pcre_compile(), we need to handle
@@ -1121,23 +1129,27 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
/* 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
+live at the top end of the options word, but that got almost full, so they were
+moved to a 16-bit flags word - which got almost full, so now they are in a
+32-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. */
-#define PCRE_MODE8 0x0001 /* compiled in 8 bit mode */
-#define PCRE_MODE16 0x0002 /* compiled in 16 bit mode */
-#define PCRE_MODE32 0x0004 /* compiled in 32 bit mode */
-#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) */
+#define PCRE_MODE8 0x00000001 /* compiled in 8 bit mode */
+#define PCRE_MODE16 0x00000002 /* compiled in 16 bit mode */
+#define PCRE_MODE32 0x00000004 /* compiled in 32 bit mode */
+#define PCRE_FIRSTSET 0x00000010 /* first_char is set */
+#define PCRE_FCH_CASELESS 0x00000020 /* caseless first char */
+#define PCRE_REQCHSET 0x00000040 /* req_byte is set */
+#define PCRE_RCH_CASELESS 0x00000080 /* caseless requested char */
+#define PCRE_STARTLINE 0x00000100 /* start after \n for multiline */
+#define PCRE_NOPARTIAL 0x00000200 /* can't use partial with this regex */
+#define PCRE_JCHANGED 0x00000400 /* j option used in regex */
+#define PCRE_HASCRORLF 0x00000800 /* explicit \r or \n in pattern */
+#define PCRE_HASTHEN 0x00001000 /* pattern contains (*THEN) */
+#define PCRE_MLSET 0x00002000 /* match limit set by regex */
+#define PCRE_RLSET 0x00004000 /* recursion limit set by regex */
+#define PCRE_MATCH_EMPTY 0x00008000 /* pattern can match empty string */
#if defined COMPILE_PCRE8
#define PCRE_MODE PCRE_MODE8
@@ -1162,9 +1174,10 @@ time, run time, or study time, respectively. */
#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_NO_AUTO_CAPTURE|PCRE_NO_AUTO_POSSESS| \
+ 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)
+ PCRE_JAVASCRIPT_COMPAT|PCRE_UCP|PCRE_NO_START_OPTIMIZE|PCRE_NEVER_UTF)
#define PUBLIC_EXEC_OPTIONS \
(PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
@@ -1520,20 +1533,25 @@ a positive value. */
#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)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
-#define STRING_UTF16_RIGHTPAR "UTF16)"
-#define STRING_UTF32_RIGHTPAR "UTF32)"
-#define STRING_UTF_RIGHTPAR "UTF)"
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+#define STRING_WEIRD_STARTWORD "[:<:]]"
+#define STRING_WEIRD_ENDWORD "[:>:]]"
+
+#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)"
+#define STRING_UTF8_RIGHTPAR "UTF8)"
+#define STRING_UTF16_RIGHTPAR "UTF16)"
+#define STRING_UTF32_RIGHTPAR "UTF32)"
+#define STRING_UTF_RIGHTPAR "UTF)"
+#define STRING_UCP_RIGHTPAR "UCP)"
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
+#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
+#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
+#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
#else /* SUPPORT_UTF */
@@ -1781,20 +1799,25 @@ only. */
#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
-#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
-#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
-#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
-#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
-#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
+#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET
+
+#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
+#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS
+#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS
+#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS
+#define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS
+#define STRING_NO_AUTO_POSSESS_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_A STR_U STR_T STR_O STR_UNDERSCORE STR_P STR_O STR_S STR_S STR_E STR_S STR_S 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
+#define STRING_LIMIT_MATCH_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_M STR_A STR_T STR_C STR_H STR_EQUALS_SIGN
+#define STRING_LIMIT_RECURSION_EQ STR_L STR_I STR_M STR_I STR_T STR_UNDERSCORE STR_R STR_E STR_C STR_U STR_R STR_S STR_I STR_O STR_N STR_EQUALS_SIGN
#endif /* SUPPORT_UTF */
@@ -1835,6 +1858,18 @@ only. */
#define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */
#define PT_WORD 8 /* Word - L plus N plus underscore */
#define PT_CLIST 9 /* Pseudo-property: match character list */
+#define PT_UCNC 10 /* Universal Character nameable character */
+#define PT_TABSIZE 11 /* Size of square table for autopossessify tests */
+
+/* The following special properties are used only in XCLASS items, when POSIX
+classes are specified and PCRE_UCP is set - in other words, for Unicode
+handling of these classes. They are not available via the \p or \P escapes like
+those in the above list, and so they do not take part in the autopossessifying
+table. */
+
+#define PT_PXGRAPH 11 /* [:graph:] - characters that mark the paper */
+#define PT_PXPRINT 12 /* [:print:] - [:graph:] plus non-control spaces */
+#define PT_PXPUNCT 13 /* [:punct:] - punctuation characters */
/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
contain characters with values greater than 255. */
@@ -1849,9 +1884,9 @@ contain characters with values greater than 255. */
#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
-0 for a data character. 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
+value such as \n. They must have non-zero values, as check_escape() returns 0
+for a data character. 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.
@@ -1874,12 +1909,31 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
ESC_E, ESC_Q, ESC_g, ESC_k,
ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu };
-/* 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. */
+/********************** Opcode definitions ******************/
+
+/****** NOTE NOTE NOTE ******
+
+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. Furthermore, values up to
+OP_DOLLM must not be changed without adjusting the table called autoposstab in
+pcre_compile.c
+
+Whenever this list is updated, the two macro definitions that follow must be
+updated to match. The possessification table called "opcode_possessify" in
+pcre_compile.c must also be updated, and also the tables called "coptable"
+and "poptable" in pcre_dfa_exec.c.
+
+****** NOTE NOTE NOTE ******/
+
+
+/* The values between FIRST_AUTOTAB_OP and LAST_AUTOTAB_RIGHT_OP, inclusive,
+are used in a table for deciding whether a repeated character type can be
+auto-possessified. */
+
+#define FIRST_AUTOTAB_OP OP_NOT_DIGIT
+#define LAST_AUTOTAB_LEFT_OP OP_EXTUNI
+#define LAST_AUTOTAB_RIGHT_OP OP_DOLLM
enum {
OP_END, /* 0 End of pattern */
@@ -1912,10 +1966,15 @@ enum {
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 */
+ /* Line end assertions */
+
+ OP_DOLL, /* 25 End of line - not multiline */
+ OP_DOLLM, /* 26 End of line - multiline */
+ OP_CIRC, /* 27 Start of line - not multiline */
+ OP_CIRCM, /* 28 Start of line - multiline */
+
+ /* Single characters; caseful must precede the caseless ones */
+
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 */
@@ -1924,7 +1983,7 @@ enum {
/* 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 ****/
+ /* Repeated 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 */
@@ -1942,7 +2001,7 @@ enum {
OP_POSQUERY, /* 44 Posesssified query, caseful */
OP_POSUPTO, /* 45 Possessified upto, caseful */
- /**** Single characters, caseless, must follow the caseful ones */
+ /* Repeated characters; caseless must follow the caseful ones */
OP_STARI, /* 46 */
OP_MINSTARI, /* 47 */
@@ -1960,8 +2019,8 @@ enum {
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 ****/
+ /* The negated ones must follow the non-negated ones, and match them */
+ /* Negated repeated 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 */
@@ -1979,7 +2038,7 @@ enum {
OP_NOTPOSQUERY, /* 70 */
OP_NOTPOSUPTO, /* 71 */
- /**** Negated single character, caseless; must follow the caseful ones ****/
+ /* Negated repeated character, caseless; must follow the caseful ones */
OP_NOTSTARI, /* 72 */
OP_NOTMINSTARI, /* 73 */
@@ -1997,7 +2056,7 @@ enum {
OP_NOTPOSQUERYI, /* 83 */
OP_NOTPOSUPTOI, /* 84 */
- /**** Character types ****/
+ /* Character types */
OP_TYPESTAR, /* 85 The maximizing and minimizing versions of */
OP_TYPEMINSTAR, /* 86 these six opcodes must come in pairs, with */
@@ -2028,89 +2087,96 @@ enum {
OP_CRRANGE, /* 104 These are different to the three sets above. */
OP_CRMINRANGE, /* 105 */
+ OP_CRPOSSTAR, /* 106 Possessified versions */
+ OP_CRPOSPLUS, /* 107 */
+ OP_CRPOSQUERY, /* 108 */
+ OP_CRPOSRANGE, /* 109 */
+
/* 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
+ OP_CLASS, /* 110 Match a character class, chars < 256 only */
+ OP_NCLASS, /* 111 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
+ OP_XCLASS, /* 112 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. */
+ OP_REF, /* 113 Match a back reference, casefully */
+ OP_REFI, /* 114 Match a back reference, caselessly */
+ OP_DNREF, /* 115 Match a duplicate name backref, casefully */
+ OP_DNREFI, /* 116 Match a duplicate name backref, caselessly */
+ OP_RECURSE, /* 117 Match a numbered subpattern (possibly recursive) */
+ OP_CALLOUT, /* 118 Call out to external function if provided */
+
+ OP_ALT, /* 119 Start of alternation */
+ OP_KET, /* 120 End of group that doesn't have an unbounded repeat */
+ OP_KETRMAX, /* 121 These two must remain together and in this */
+ OP_KETRMIN, /* 122 order. They are for groups the repeat for ever. */
+ OP_KETRPOS, /* 123 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 */
+ OP_REVERSE, /* 124 Move pointer back - used in lookbehind assertions */
+ OP_ASSERT, /* 125 Positive lookahead */
+ OP_ASSERT_NOT, /* 126 Negative lookahead */
+ OP_ASSERTBACK, /* 127 Positive lookbehind */
+ OP_ASSERTBACK_NOT, /* 128 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 */
+ OP_ONCE, /* 129 Atomic group, contains captures */
+ OP_ONCE_NC, /* 130 Atomic group containing no captures */
+ OP_BRA, /* 131 Start of non-capturing bracket */
+ OP_BRAPOS, /* 132 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 133 Start of capturing bracket */
+ OP_CBRAPOS, /* 134 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 135 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 */
+ OP_SBRA, /* 136 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 138 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 139 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 140 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_CREF, /* 141 Used to hold a capture number as condition */
+ OP_DNCREF, /* 142 Used to point to duplicate names as a condition */
+ OP_RREF, /* 143 Used to hold a recursion number as condition */
+ OP_DNRREF, /* 144 Used to point to duplicate names as a condition */
+ OP_DEF, /* 145 The DEFINE condition */
- OP_BRAZERO, /* 140 These two must remain together and in this */
- OP_BRAMINZERO, /* 141 order. */
- OP_BRAPOSZERO, /* 142 */
+ OP_BRAZERO, /* 146 These two must remain together and in this */
+ OP_BRAMINZERO, /* 147 order. */
+ OP_BRAPOSZERO, /* 148 */
/* 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 */
+ OP_MARK, /* 149 always has an argument */
+ OP_PRUNE, /* 150 */
+ OP_PRUNE_ARG, /* 151 same, but with argument */
+ OP_SKIP, /* 152 */
+ OP_SKIP_ARG, /* 153 same, but with argument */
+ OP_THEN, /* 154 */
+ OP_THEN_ARG, /* 155 same, but with argument */
+ OP_COMMIT, /* 156 */
/* 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 */
+ OP_FAIL, /* 157 */
+ OP_ACCEPT, /* 158 */
+ OP_ASSERT_ACCEPT, /* 159 Used inside assertions */
+ OP_CLOSE, /* 160 Used before OP_ACCEPT to close open captures */
/* This is used to skip a subpattern with a {0} quantifier */
- OP_SKIPZERO, /* 155 */
+ OP_SKIPZERO, /* 161 */
/* 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
@@ -2121,7 +2187,8 @@ enum {
/* *** 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. */
+called "opcode_possessify" in pcre_compile.c and "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
@@ -2134,7 +2201,7 @@ some cases doesn't actually use these names at all). */
"\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte", \
"notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v", \
"extuni", "\\Z", "\\z", \
- "^", "^", "$", "$", "char", "chari", "not", "noti", \
+ "$", "$", "^", "^", "char", "chari", "not", "noti", \
"*", "*?", "+", "+?", "?", "??", \
"{", "{", "{", \
"*+","++", "?+", "{", \
@@ -2150,7 +2217,8 @@ some cases doesn't actually use these names at all). */
"*", "*?", "+", "+?", "?", "??", "{", "{", "{", \
"*+","++", "?+", "{", \
"*", "*?", "+", "+?", "?", "??", "{", "{", \
- "class", "nclass", "xclass", "Ref", "Refi", \
+ "*+","++", "?+", "{", \
+ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
"Recurse", "Callout", \
"Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
"Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
@@ -2159,7 +2227,7 @@ some cases doesn't actually use these names at all). */
"Cond", \
"SBra", "SBraPos", "SCBra", "SCBraPos", \
"SCond", \
- "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def", \
+ "Cond ref", "Cond dnref", "Cond rec", "Cond dnrec", "Cond def", \
"Brazero", "Braminzero", "Braposzero", \
"*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
"*THEN", "*THEN", "*COMMIT", "*FAIL", \
@@ -2184,7 +2252,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */
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 */ \
+ 1, 1, 1, 1, 1, 1, /* \Z, \z, $, $M ^, ^M */ \
2, /* Char - the minimum length */ \
2, /* Chari - the minimum length */ \
2, /* not */ \
@@ -2215,11 +2283,14 @@ in UTF-8 mode. The code that uses this table must know about such things. */
/* Character class & ref repeats */ \
1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \
1+2*IMM2_SIZE, 1+2*IMM2_SIZE, /* CRRANGE, CRMINRANGE */ \
+ 1, 1, 1, 1+2*IMM2_SIZE, /* Possessive *+, ++, ?+, CRPOSRANGE */ \
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+2*IMM2_SIZE, /* DNREF */ \
+ 1+2*IMM2_SIZE, /* DNREFI */ \
1+LINK_SIZE, /* RECURSE */ \
2+2*LINK_SIZE, /* CALLOUT */ \
1+LINK_SIZE, /* Alt */ \
@@ -2244,8 +2315,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */
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+IMM2_SIZE, 1+2*IMM2_SIZE, /* CREF, DNCREF */ \
+ 1+IMM2_SIZE, 1+2*IMM2_SIZE, /* RREF, DNRREF */ \
1, /* DEF */ \
1, 1, 1, /* BRAZERO, BRAMINZERO, BRAPOSZERO */ \
3, 1, 3, /* MARK, PRUNE, PRUNE_ARG */ \
@@ -2254,8 +2325,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */
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. */
+/* A magic value for OP_RREF to indicate the "any recursion" condition. */
#define RREF_ANY 0xffff
@@ -2270,9 +2340,11 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9,
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, ERR75, ERR76, ERR77, ERRCOUNT };
+ ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79,
+ ERR80, ERR81, ERR82, ERR83, ERR84, ERRCOUNT };
/* JIT compiling modes. The function list is indexed by them. */
+
enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
JIT_NUMBER_OF_COMPILE_MODES };
@@ -2280,48 +2352,49 @@ enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE,
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
+be well.
+
+The size of the structure must be a multiple of 8 bytes. For the case of
+compiled-on-4 and run-on-8, we include an extra pointer that is always NULL so
+that there are an even number of pointers which therefore are a multiple of 8
+bytes.
+
+It is necessary to fork the struct for the 32 bit library, since it needs to
+use pcre_uint32 for first_char and req_char. We can't put an ifdef inside the
+typedef because pcretest needs access to the struct of the 8-, 16- and 32-bit
+variants.
+
+*** WARNING ***
+When new fields are added to these structures, remember to adjust the code in
+pcre_byte_order.c that is concerned with swapping the byte order of the fields
+when a compiled regex is reloaded on a host with different endianness.
+*** WARNING ***
+There is also similar byte-flipping code in pcretest.c, which is used for
+testing the byte-flipping features. It must also be kept in step.
+*** WARNING ***
*/
-#if defined COMPILE_PCRE8
-#define REAL_PCRE real_pcre
-#elif defined COMPILE_PCRE16
-#define REAL_PCRE real_pcre16
-#elif defined COMPILE_PCRE32
-#define REAL_PCRE real_pcre32
-#endif
-
-/* It is necessary to fork the struct for 32 bit, since it needs to use
- * pcre_uchar for first_char and req_char. Can't put an ifdef inside the
- * typedef since pcretest needs access to the struct of the 8-, 16-
- * and 32-bit variants. */
-
typedef struct real_pcre8_or_16 {
pcre_uint32 magic_number;
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint32 limit_match; /* Limit set from regex */
+ pcre_uint32 limit_recursion; /* Limit set from regex */
+ pcre_uint16 first_char; /* Starting character */
+ pcre_uint16 req_char; /* This character must be seen */
pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
pcre_uint16 top_bracket; /* Highest numbered group */
pcre_uint16 top_backref; /* Highest numbered back reference */
- 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 */
+ pcre_uint16 dummy1; /* To ensure size is a multiple of 8 */
+ pcre_uint16 dummy2; /* To ensure size is a multiple of 8 */
+ pcre_uint16 dummy3; /* To ensure size is a multiple of 8 */
const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- const pcre_uint8 *nullpad; /* NULL padding */
+ void *nullpad; /* NULL padding */
} real_pcre8_or_16;
typedef struct real_pcre8_or_16 real_pcre;
@@ -2331,22 +2404,31 @@ typedef struct real_pcre32 {
pcre_uint32 magic_number;
pcre_uint32 size; /* Total that was malloced */
pcre_uint32 options; /* Public options */
- pcre_uint16 flags; /* Private flags */
+ pcre_uint32 flags; /* Private flags */
+ pcre_uint32 limit_match; /* Limit set from regex */
+ pcre_uint32 limit_recursion; /* Limit set from regex */
+ pcre_uint32 first_char; /* Starting character */
+ pcre_uint32 req_char; /* This character must be seen */
pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */
pcre_uint16 top_bracket; /* Highest numbered group */
pcre_uint16 top_backref; /* Highest numbered back reference */
- pcre_uint32 first_char; /* Starting character */
- pcre_uint32 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 */
- pcre_uint16 dummy1; /* for later expansion */
- pcre_uint16 dummy2; /* for later expansion */
+ pcre_uint16 dummy; /* To ensure size is a multiple of 8 */
const pcre_uint8 *tables; /* Pointer to tables or NULL for std */
- void *nullpad; /* for later expansion */
+ void *nullpad; /* NULL padding */
} real_pcre32;
+#if defined COMPILE_PCRE8
+#define REAL_PCRE real_pcre
+#elif defined COMPILE_PCRE16
+#define REAL_PCRE real_pcre16
+#elif defined COMPILE_PCRE32
+#define REAL_PCRE real_pcre32
+#endif
+
/* Assert that the size of REAL_PCRE is divisible by 8 */
typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1];
@@ -2380,6 +2462,15 @@ typedef struct open_capitem {
pcre_uint16 flag; /* Set TRUE if recursive back ref */
} open_capitem;
+/* Structure for building a list of named groups during the first pass of
+compiling. */
+
+typedef struct named_group {
+ const pcre_uchar *name; /* Points to the name in the pattern */
+ int length; /* Length of the name */
+ pcre_uint32 number; /* Group number */
+} named_group;
+
/* Structure for passing "static" information around between the functions
doing the compiling, so that they are thread-safe. */
@@ -2392,24 +2483,29 @@ typedef struct compile_data {
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 */
+ open_capitem *open_caps; /* Chain of open capture items */
+ named_group *named_groups; /* Points to vector in pre-compile */
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 named_group_list_size; /* Number of entries in the list */
int workspace_size; /* Size of workspace */
- unsigned int bracount; /* Count of capturing parens as we compile */
+ unsigned int bracount; /* Count of capturing parens as we compile */
int final_bracount; /* Saved value after first pass */
int max_lookbehind; /* Maximum lookbehind (characters) */
int top_backref; /* Maximum back reference */
unsigned int backref_map; /* Bitmap of low back refs */
+ unsigned int namedrefcount; /* Number of backreferences by name */
+ int parens_depth; /* Depth of nested parentheses */
int assert_depth; /* Depth of nested assertions */
- int external_options; /* External (initial) options */
- int external_flags; /* External flag bits to be set */
+ pcre_uint32 external_options; /* External (initial) options */
+ pcre_uint32 external_flags; /* External flag bits to be set */
int req_varyopt; /* "After variable item" flag for reqbyte */
BOOL had_accept; /* (*ACCEPT) encountered */
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
BOOL check_lookbehind; /* Lookbehinds need later checking */
+ BOOL dupnames; /* Duplicate names exist */
int nltype; /* Newline type */
int nllen; /* Newline string length */
pcre_uchar nl[4]; /* Newline string when fixed length */
@@ -2431,6 +2527,7 @@ typedef struct recursion_info {
unsigned 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 */
+ int saved_capture_last; /* Last capture number */
PCRE_PUCHAR subject_position; /* Position at start of recursion */
} recursion_info;
@@ -2467,12 +2564,13 @@ typedef struct match_data {
int nllen; /* Newline string length */
int name_count; /* Number of names in name table */
int name_entry_size; /* Size of entry in names table */
+ unsigned int skip_arg_count; /* For counting SKIP_ARGs */
+ unsigned int ignore_skip_arg; /* For re-run when SKIP arg name not found */
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 */
@@ -2484,7 +2582,6 @@ typedef struct match_data {
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 */
@@ -2493,7 +2590,7 @@ typedef struct match_data {
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 */
+ pcre_int32 capture_last; /* Most recent capture number + overflow flag */
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 */
diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c
index 78fe75d57e..a318708b46 100644
--- a/src/3rdparty/pcre/pcre_jit_compile.c
+++ b/src/3rdparty/pcre/pcre_jit_compile.c
@@ -6,10 +6,10 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
The machine code generator part (this module) was written by Zoltan Herczeg
- Copyright (c) 2010-2012
+ Copyright (c) 2010-2013
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -65,6 +65,15 @@ system files. */
#error Unsupported architecture
#endif
+/* Defines for debugging purposes. */
+
+/* 1 - Use unoptimized capturing brackets.
+ 2 - Enable capture_last_ptr (includes option 1). */
+/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
+
+/* 1 - Always have a control head. */
+/* #define DEBUG_FORCE_CONTROL_HEAD 1 */
+
/* Allocate memory for the regex stack on the real machine stack.
Fast, but limited size. */
#define MACHINE_STACK_SIZE 32768
@@ -157,9 +166,11 @@ typedef struct jit_arguments {
int *offsets;
pcre_uchar *uchar_ptr;
pcre_uchar *mark_ptr;
+ void *callout_data;
/* Everything else after. */
- int offsetcount;
- int calllimit;
+ pcre_uint32 limit_match;
+ int real_offset_count;
+ int offset_count;
pcre_uint8 notbol;
pcre_uint8 noteol;
pcre_uint8 notempty;
@@ -171,6 +182,7 @@ typedef struct executable_functions {
PUBL(jit_callback) callback;
void *userdata;
pcre_uint32 top_bracket;
+ pcre_uint32 limit_match;
sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
} executable_functions;
@@ -179,21 +191,27 @@ typedef struct jump_list {
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 *quit;
struct stub_list *next;
} stub_list;
+enum frame_types {
+ no_frame = -1,
+ no_stack = -2
+};
+
+enum control_types {
+ type_mark = 0,
+ type_then_trap = 1
+};
+
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_matchingpath, and contains
-the aguments for compile_backtrackingpath. Must be the first member
+the arguments for compile_backtrackingpath. Must be the first member
of its descendants. */
typedef struct backtrack_common {
/* Concatenation stack. */
@@ -209,7 +227,7 @@ typedef struct backtrack_common {
typedef struct assert_backtrack {
backtrack_common common;
jump_list *condfailed;
- /* Less than 0 (-1) if a frame is not needed. */
+ /* Less than 0 if a frame is not needed. */
int framesize;
/* Points to our private memory word on the stack. */
int private_data_ptr;
@@ -230,7 +248,7 @@ typedef struct bracket_backtrack {
/* Both for OP_COND, OP_SCOND. */
jump_list *condfailed;
assert_backtrack *assert;
- /* For OP_ONCE. -1 if not needed. */
+ /* For OP_ONCE. Less than 0 if not needed. */
int framesize;
} u;
/* Points to our private memory word on the stack. */
@@ -265,31 +283,52 @@ typedef struct recurse_entry {
/* Collects the calls until the function is not created. */
jump_list *calls;
/* Points to the starting opcode. */
- int start;
+ sljit_sw start;
} recurse_entry;
typedef struct recurse_backtrack {
backtrack_common common;
+ BOOL inlined_pattern;
} recurse_backtrack;
+#define OP_THEN_TRAP OP_TABLE_LENGTH
+
+typedef struct then_trap_backtrack {
+ backtrack_common common;
+ /* If then_trap is not NULL, this structure contains the real
+ then_trap for the backtracking path. */
+ struct then_trap_backtrack *then_trap;
+ /* Points to the starting opcode. */
+ sljit_sw start;
+ /* Exit point for the then opcodes of this alternative. */
+ jump_list *quit;
+ /* Frame size of the current alternative. */
+ int framesize;
+} then_trap_backtrack;
+
#define MAX_RANGE_SIZE 6
typedef struct compiler_common {
+ /* The sljit ceneric compiler. */
struct sljit_compiler *compiler;
+ /* First byte code. */
pcre_uchar *start;
-
/* Maps private data offset to each opcode. */
- int *private_data_ptrs;
+ sljit_si *private_data_ptrs;
/* Tells whether the capturing bracket is optimized. */
pcre_uint8 *optimized_cbracket;
+ /* Tells whether the starting offset is a target of then. */
+ pcre_uint8 *then_offsets;
+ /* Current position where a THEN must jump. */
+ then_trap_backtrack *then_trap;
/* Starting offset of private data for capturing brackets. */
- int cbraptr;
- /* OVector starting point. Must be divisible by 2. */
+ int cbra_ptr;
+ /* Output vector starting point. Must be divisible by 2. */
int ovector_start;
/* Last known position of the requested byte. */
int req_char_ptr;
/* Head of the last recursion. */
- int recursive_head;
+ int recursive_head_ptr;
/* First inspected character for partial matching. */
int start_used_ptr;
/* Starting pointer for partial soft matches. */
@@ -298,36 +337,56 @@ typedef struct compiler_common {
int first_line_end;
/* Points to the marked string. */
int mark_ptr;
+ /* Recursive control verb management chain. */
+ int control_head_ptr;
+ /* Points to the last matched capture block index. */
+ int capture_last_ptr;
+ /* Points to the starting position of the current match. */
+ int start_ptr;
/* Flipped and lower case tables. */
const pcre_uint8 *fcc;
sljit_sw lcc;
/* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
int mode;
+ /* \K is found in the pattern. */
+ BOOL has_set_som;
+ /* (*SKIP:arg) is found in the pattern. */
+ BOOL has_skip_arg;
+ /* (*THEN) is found in the pattern. */
+ BOOL has_then;
+ /* Needs to know the start position anytime. */
+ BOOL needs_start_ptr;
+ /* Currently in recurse or negative assert. */
+ BOOL local_exit;
+ /* Currently in a positive assert. */
+ BOOL positive_assert;
/* Newline control. */
int nltype;
int newline;
int bsr_nltype;
/* Dollar endonly. */
int endonly;
- BOOL has_set_som;
/* Tables. */
sljit_sw ctypes;
int digits[2 + MAX_RANGE_SIZE];
/* Named capturing brackets. */
- sljit_uw name_table;
+ pcre_uchar *name_table;
sljit_sw name_count;
sljit_sw name_entry_size;
/* Labels and jump lists. */
struct sljit_label *partialmatchlabel;
- struct sljit_label *quitlabel;
- struct sljit_label *acceptlabel;
+ struct sljit_label *quit_label;
+ struct sljit_label *forced_quit_label;
+ struct sljit_label *accept_label;
stub_list *stubs;
recurse_entry *entries;
recurse_entry *currententry;
jump_list *partialmatch;
jump_list *quit;
+ jump_list *positive_assert_quit;
+ jump_list *forced_quit;
jump_list *accept;
jump_list *calllimit;
jump_list *stackalloc;
@@ -338,6 +397,7 @@ typedef struct compiler_common {
jump_list *vspace;
jump_list *casefulcmp;
jump_list *caselesscmp;
+ jump_list *reset_match;
BOOL jscript_compat;
#ifdef SUPPORT_UTF
BOOL utf;
@@ -390,12 +450,6 @@ typedef struct compare_context {
#endif
} compare_context;
-enum {
- frame_end = 0,
- frame_setstrbegin = -1,
- frame_setmark = -2
-};
-
/* Undefine sljit macros. */
#undef CMP
@@ -410,7 +464,7 @@ enum {
#define STACK_TOP SLJIT_SCRATCH_REG2
#define STACK_LIMIT SLJIT_SAVED_REG3
#define ARGUMENTS SLJIT_SAVED_EREG1
-#define CALL_COUNT SLJIT_SAVED_EREG2
+#define COUNT_MATCH SLJIT_SAVED_EREG2
#define RETURN_ADDR SLJIT_TEMPORARY_EREG1
/* Local space layout. */
@@ -421,14 +475,14 @@ enum {
#define POSSESSIVE0 (2 * sizeof(sljit_sw))
#define POSSESSIVE1 (3 * sizeof(sljit_sw))
/* Max limit of recursions. */
-#define CALL_LIMIT (4 * sizeof(sljit_sw))
+#define LIMIT_MATCH (4 * sizeof(sljit_sw))
/* 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 (common->ovector_start)
-#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_sw))
-#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_sw))
+#define OVECTOR(i) (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
+#define OVECTOR_PRIV(i) (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
#if defined COMPILE_PCRE8
@@ -459,6 +513,8 @@ the start pointers when the end of the capturing group has not yet reached. */
sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
#define JUMPHERE(jump) \
sljit_set_label((jump), sljit_emit_label(compiler))
+#define SET_LABEL(jump, label) \
+ sljit_set_label((jump), (label))
#define CMP(type, src1, src1w, src2, src2w) \
sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
#define CMPTO(type, src1, src1w, src2, src2w, label) \
@@ -479,11 +535,11 @@ return cc;
/* Functions whose might need modification for all new supported opcodes:
next_opcode
- get_private_data_length
+ check_opcode_types
set_private_data_ptrs
get_framesize
init_frame
- get_private_data_length_for_copy
+ get_private_data_copy_length
copy_private_data
compile_matchingpath
compile_backtrackingpath
@@ -507,6 +563,8 @@ switch(*cc)
case OP_WORDCHAR:
case OP_ANY:
case OP_ALLANY:
+ case OP_NOTPROP:
+ case OP_PROP:
case OP_ANYNL:
case OP_NOT_HSPACE:
case OP_HSPACE:
@@ -519,37 +577,66 @@ switch(*cc)
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_CRRANGE:
+ case OP_CRMINRANGE:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSPLUS:
+ case OP_CRPOSQUERY:
+ case OP_CRPOSRANGE:
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_REF:
+ case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_RECURSE:
+ case OP_CALLOUT:
+ case OP_ALT:
+ case OP_KET:
+ case OP_KETRMAX:
+ case OP_KETRMIN:
+ case OP_KETRPOS:
+ case OP_REVERSE:
+ case OP_ASSERT:
+ case OP_ASSERT_NOT:
+ case OP_ASSERTBACK:
+ case OP_ASSERTBACK_NOT:
+ case OP_ONCE:
+ case OP_ONCE_NC:
+ case OP_BRA:
+ case OP_BRAPOS:
+ case OP_CBRA:
+ case OP_CBRAPOS:
+ case OP_COND:
+ case OP_SBRA:
+ case OP_SBRAPOS:
+ case OP_SCBRA:
+ case OP_SCBRAPOS:
+ case OP_SCOND:
+ case OP_CREF:
+ case OP_DNCREF:
+ case OP_RREF:
+ case OP_DNRREF:
case OP_DEF:
case OP_BRAZERO:
case OP_BRAMINZERO:
case OP_BRAPOSZERO:
+ case OP_PRUNE:
+ case OP_SKIP:
+ case OP_THEN:
case OP_COMMIT:
case OP_FAIL:
case OP_ACCEPT:
case OP_ASSERT_ACCEPT:
+ case OP_CLOSE:
case OP_SKIPZERO:
- return cc + 1;
-
- case OP_ANYBYTE:
-#ifdef SUPPORT_UTF
- if (common->utf) return NULL;
-#endif
- return cc + 1;
+ return cc + PRIV(OP_lengths)[*cc];
case OP_CHAR:
case OP_CHARI:
@@ -561,222 +648,106 @@ switch(*cc)
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_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_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
case OP_NOTPOSUPTOI:
- cc += 2 + IMM2_SIZE;
+ cc += PRIV(OP_lengths)[*cc];
#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;
-
+ /* Special cases. */
+ 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_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;
+ return cc + PRIV(OP_lengths)[*cc] - 1;
- 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);
+ case OP_ANYBYTE:
+#ifdef SUPPORT_UTF
+ if (common->utf) return NULL;
+#endif
+ return cc + 1;
#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;
-
case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_SKIP_ARG:
+ case OP_THEN_ARG:
return cc + 1 + 2 + cc[1];
default:
+ /* All opcodes are supported now! */
+ SLJIT_ASSERT_STOP();
return NULL;
}
}
-#define CASE_ITERATOR_PRIVATE_DATA_1 \
- case OP_MINSTAR: \
- case OP_MINPLUS: \
- case OP_QUERY: \
- case OP_MINQUERY: \
- case OP_MINSTARI: \
- case OP_MINPLUSI: \
- case OP_QUERYI: \
- case OP_MINQUERYI: \
- case OP_NOTMINSTAR: \
- case OP_NOTMINPLUS: \
- case OP_NOTQUERY: \
- case OP_NOTMINQUERY: \
- case OP_NOTMINSTARI: \
- case OP_NOTMINPLUSI: \
- case OP_NOTQUERYI: \
- case OP_NOTMINQUERYI:
-
-#define CASE_ITERATOR_PRIVATE_DATA_2A \
- case OP_STAR: \
- case OP_PLUS: \
- case OP_STARI: \
- case OP_PLUSI: \
- case OP_NOTSTAR: \
- case OP_NOTPLUS: \
- case OP_NOTSTARI: \
- case OP_NOTPLUSI:
-
-#define CASE_ITERATOR_PRIVATE_DATA_2B \
- case OP_UPTO: \
- case OP_MINUPTO: \
- case OP_UPTOI: \
- case OP_MINUPTOI: \
- case OP_NOTUPTO: \
- case OP_NOTMINUPTO: \
- case OP_NOTUPTOI: \
- case OP_NOTMINUPTOI:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
- case OP_TYPEMINSTAR: \
- case OP_TYPEMINPLUS: \
- case OP_TYPEQUERY: \
- case OP_TYPEMINQUERY:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
- case OP_TYPESTAR: \
- case OP_TYPEPLUS:
-
-#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
- case OP_TYPEUPTO: \
- case OP_TYPEMINUPTO:
-
-static int get_class_iterator_size(pcre_uchar *cc)
+static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
{
-switch(*cc)
- {
- case OP_CRSTAR:
- case OP_CRPLUS:
- return 2;
-
- case OP_CRMINSTAR:
- case OP_CRMINPLUS:
- case OP_CRQUERY:
- case OP_CRMINQUERY:
- return 1;
-
- case OP_CRRANGE:
- case OP_CRMINRANGE:
- if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
- return 0;
- return 2;
-
- default:
- return 0;
- }
-}
-
-static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
-{
-int private_data_length = 0;
-pcre_uchar *alternative;
-pcre_uchar *name;
-pcre_uchar *end = NULL;
-int space, size, i;
-pcre_uint32 bracketlen;
+int count;
+pcre_uchar *slot;
/* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
while (cc < ccend)
{
- space = 0;
- size = 0;
- bracketlen = 0;
switch(*cc)
{
case OP_SET_SOM:
@@ -790,130 +761,67 @@ while (cc < ccend)
cc += 1 + IMM2_SIZE;
break;
- 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:
- private_data_length += sizeof(sljit_sw);
- bracketlen = 1 + LINK_SIZE;
- break;
-
case OP_CBRAPOS:
case OP_SCBRAPOS:
- private_data_length += sizeof(sljit_sw);
common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
- bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
+ cc += 1 + LINK_SIZE + IMM2_SIZE;
break;
case OP_COND:
case OP_SCOND:
- bracketlen = cc[1 + LINK_SIZE];
- if (bracketlen == OP_CREF)
- {
- bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
- common->optimized_cbracket[bracketlen] = 0;
- }
- else if (bracketlen == OP_NCREF)
- {
- bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
- name = (pcre_uchar *)common->name_table;
- alternative = name;
- for (i = 0; i < common->name_count; i++)
- {
- if (GET2(name, 0) == bracketlen) break;
- name += common->name_entry_size;
- }
- SLJIT_ASSERT(i != common->name_count);
-
- for (i = 0; i < common->name_count; i++)
- {
- if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
- common->optimized_cbracket[GET2(alternative, 0)] = 0;
- alternative += common->name_entry_size;
- }
- }
-
- if (*cc == OP_COND)
- {
- /* Might be a hidden SCOND. */
- alternative = cc + GET(cc, 1);
- if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
- private_data_length += sizeof(sljit_sw);
- }
- else
- private_data_length += sizeof(sljit_sw);
- bracketlen = 1 + LINK_SIZE;
- break;
-
- case OP_BRA:
- bracketlen = 1 + LINK_SIZE;
- break;
-
- case OP_CBRA:
- case OP_SCBRA:
- bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_1
- space = 1;
- size = -2;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2A
- space = 2;
- size = -2;
- break;
-
- CASE_ITERATOR_PRIVATE_DATA_2B
- space = 2;
- size = -(2 + IMM2_SIZE);
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- space = 1;
- size = 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
- if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
- space = 2;
- size = 1;
- break;
-
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
- if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
- space = 2;
- size = 1 + IMM2_SIZE;
+ /* Only AUTO_CALLOUT can insert this opcode. We do
+ not intend to support this case. */
+ if (cc[1 + LINK_SIZE] == OP_CALLOUT)
+ return FALSE;
+ cc += 1 + LINK_SIZE;
break;
- case OP_CLASS:
- case OP_NCLASS:
- size += 1 + 32 / sizeof(pcre_uchar);
- space = get_class_iterator_size(cc + size);
+ case OP_CREF:
+ common->optimized_cbracket[GET2(cc, 1)] = 0;
+ cc += 1 + IMM2_SIZE;
break;
-#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
- case OP_XCLASS:
- size = GET(cc, 1);
- space = get_class_iterator_size(cc + size);
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_DNCREF:
+ count = GET2(cc, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
+ while (count-- > 0)
+ {
+ common->optimized_cbracket[GET2(slot, 0)] = 0;
+ slot += common->name_entry_size;
+ }
+ cc += 1 + 2 * IMM2_SIZE;
break;
-#endif
case OP_RECURSE:
/* Set its value only once. */
- if (common->recursive_head == 0)
+ if (common->recursive_head_ptr == 0)
{
- common->recursive_head = common->ovector_start;
+ common->recursive_head_ptr = common->ovector_start;
common->ovector_start += sizeof(sljit_sw);
}
cc += 1 + LINK_SIZE;
break;
+ case OP_CALLOUT:
+ if (common->capture_last_ptr == 0)
+ {
+ common->capture_last_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+ cc += 2 + 2 * LINK_SIZE;
+ break;
+
+ case OP_THEN_ARG:
+ common->has_then = TRUE;
+ common->control_head_ptr = 1;
+ /* Fall through. */
+
+ case OP_PRUNE_ARG:
+ common->needs_start_ptr = TRUE;
+ /* Fall through. */
+
case OP_MARK:
if (common->mark_ptr == 0)
{
@@ -923,48 +831,201 @@ while (cc < ccend)
cc += 1 + 2 + cc[1];
break;
+ case OP_THEN:
+ common->has_then = TRUE;
+ common->control_head_ptr = 1;
+ /* Fall through. */
+
+ case OP_PRUNE:
+ case OP_SKIP:
+ common->needs_start_ptr = TRUE;
+ cc += 1;
+ break;
+
+ case OP_SKIP_ARG:
+ common->control_head_ptr = 1;
+ common->has_skip_arg = TRUE;
+ cc += 1 + 2 + cc[1];
+ break;
+
default:
cc = next_opcode(common, cc);
if (cc == NULL)
- return -1;
+ return FALSE;
break;
}
+ }
+return TRUE;
+}
- if (space > 0 && cc >= end)
- private_data_length += sizeof(sljit_sw) * space;
+static int get_class_iterator_size(pcre_uchar *cc)
+{
+switch(*cc)
+ {
+ case OP_CRSTAR:
+ case OP_CRPLUS:
+ return 2;
- if (size != 0)
+ case OP_CRMINSTAR:
+ case OP_CRMINPLUS:
+ case OP_CRQUERY:
+ case OP_CRMINQUERY:
+ return 1;
+
+ case OP_CRRANGE:
+ case OP_CRMINRANGE:
+ if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
+ return 0;
+ return 2;
+
+ default:
+ return 0;
+ }
+}
+
+static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
+{
+pcre_uchar *end = bracketend(begin);
+pcre_uchar *next;
+pcre_uchar *next_end;
+pcre_uchar *max_end;
+pcre_uchar type;
+sljit_sw length = end - begin;
+int min, max, i;
+
+/* Detect fixed iterations first. */
+if (end[-(1 + LINK_SIZE)] != OP_KET)
+ return FALSE;
+
+/* Already detected repeat. */
+if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
+ return TRUE;
+
+next = end;
+min = 1;
+while (1)
+ {
+ if (*next != *begin)
+ break;
+ next_end = bracketend(next);
+ if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
+ break;
+ next = next_end;
+ min++;
+ }
+
+if (min == 2)
+ return FALSE;
+
+max = 0;
+max_end = next;
+if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
+ {
+ type = *next;
+ while (1)
{
- if (size < 0)
- {
- cc += -size;
-#ifdef SUPPORT_UTF
- if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
-#endif
- }
- else
- cc += size;
+ if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
+ break;
+ next_end = bracketend(next + 2 + LINK_SIZE);
+ if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
+ break;
+ next = next_end;
+ max++;
}
- if (bracketlen != 0)
+ if (next[0] == type && next[1] == *begin && max >= 1)
{
- if (cc >= end)
+ next_end = bracketend(next + 1);
+ if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
{
- end = bracketend(cc);
- if (end[-1 - LINK_SIZE] == OP_KET)
- end = NULL;
+ for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
+ if (*next_end != OP_KET)
+ break;
+
+ if (i == max)
+ {
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
+ /* +2 the original and the last. */
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
+ if (min == 1)
+ return TRUE;
+ min--;
+ max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
+ }
}
- cc += bracketlen;
}
}
-return private_data_length;
+
+if (min >= 3)
+ {
+ common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
+ common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
+ common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
+ return TRUE;
+ }
+
+return FALSE;
}
-static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
+#define CASE_ITERATOR_PRIVATE_DATA_1 \
+ case OP_MINSTAR: \
+ case OP_MINPLUS: \
+ case OP_QUERY: \
+ case OP_MINQUERY: \
+ case OP_MINSTARI: \
+ case OP_MINPLUSI: \
+ case OP_QUERYI: \
+ case OP_MINQUERYI: \
+ case OP_NOTMINSTAR: \
+ case OP_NOTMINPLUS: \
+ case OP_NOTQUERY: \
+ case OP_NOTMINQUERY: \
+ case OP_NOTMINSTARI: \
+ case OP_NOTMINPLUSI: \
+ case OP_NOTQUERYI: \
+ case OP_NOTMINQUERYI:
+
+#define CASE_ITERATOR_PRIVATE_DATA_2A \
+ case OP_STAR: \
+ case OP_PLUS: \
+ case OP_STARI: \
+ case OP_PLUSI: \
+ case OP_NOTSTAR: \
+ case OP_NOTPLUS: \
+ case OP_NOTSTARI: \
+ case OP_NOTPLUSI:
+
+#define CASE_ITERATOR_PRIVATE_DATA_2B \
+ case OP_UPTO: \
+ case OP_MINUPTO: \
+ case OP_UPTOI: \
+ case OP_MINUPTOI: \
+ case OP_NOTUPTO: \
+ case OP_NOTMINUPTO: \
+ case OP_NOTUPTOI: \
+ case OP_NOTMINUPTOI:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
+ case OP_TYPEMINSTAR: \
+ case OP_TYPEMINPLUS: \
+ case OP_TYPEQUERY: \
+ case OP_TYPEMINQUERY:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
+ case OP_TYPESTAR: \
+ case OP_TYPEPLUS:
+
+#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
+ case OP_TYPEUPTO: \
+ case OP_TYPEMINUPTO:
+
+static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
{
pcre_uchar *cc = common->start;
pcre_uchar *alternative;
pcre_uchar *end = NULL;
+int private_data_ptr = *private_data_start;
int space, size, bracketlen;
while (cc < ccend)
@@ -972,8 +1033,30 @@ while (cc < ccend)
space = 0;
size = 0;
bracketlen = 0;
+ if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
+ return;
+
+ if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
+ if (detect_repeat(common, cc))
+ {
+ /* These brackets are converted to repeats, so no global
+ based single character repeat is allowed. */
+ if (cc >= end)
+ end = bracketend(cc);
+ }
+
switch(*cc)
{
+ case OP_KET:
+ if (common->private_data_ptrs[cc + 1 - common->start] != 0)
+ {
+ common->private_data_ptrs[cc - common->start] = private_data_ptr;
+ private_data_ptr += sizeof(sljit_sw);
+ cc += common->private_data_ptrs[cc + 1 - common->start];
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
@@ -1067,6 +1150,8 @@ while (cc < ccend)
break;
}
+ /* Character iterators, which are not inside a repeated bracket,
+ gets a private slot instead of allocating it on the stack. */
if (space > 0 && cc >= end)
{
common->private_data_ptrs[cc - common->start] = private_data_ptr;
@@ -1097,30 +1182,46 @@ while (cc < ccend)
cc += bracketlen;
}
}
+*private_data_start = private_data_ptr;
}
-/* Returns with -1 if no need for frame. */
-static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
+/* Returns with a frame_types (always < 0) if no need for frame. */
+static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
{
-pcre_uchar *ccend = bracketend(cc);
int length = 0;
-BOOL possessive = FALSE;
+int possessive = 0;
+BOOL stack_restore = FALSE;
BOOL setsom_found = recursive;
BOOL setmark_found = recursive;
+/* The last capture is a local variable even for recursions. */
+BOOL capture_last_found = FALSE;
+
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+SLJIT_ASSERT(common->control_head_ptr != 0);
+*needs_control_head = TRUE;
+#else
+*needs_control_head = FALSE;
+#endif
-if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+if (ccend == NULL)
{
- length = 3;
- possessive = TRUE;
+ ccend = bracketend(cc) - (1 + LINK_SIZE);
+ if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
+ {
+ possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
+ /* This is correct regardless of common->capture_last_ptr. */
+ capture_last_found = TRUE;
+ }
+ cc = next_opcode(common, cc);
}
-cc = next_opcode(common, cc);
SLJIT_ASSERT(cc != NULL);
while (cc < ccend)
switch(*cc)
{
case OP_SET_SOM:
SLJIT_ASSERT(common->has_set_som);
+ stack_restore = TRUE;
if (!setsom_found)
{
length += 2;
@@ -1130,16 +1231,22 @@ while (cc < ccend)
break;
case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_THEN_ARG:
SLJIT_ASSERT(common->mark_ptr != 0);
+ stack_restore = TRUE;
if (!setmark_found)
{
length += 2;
setmark_found = TRUE;
}
+ if (common->control_head_ptr != 0)
+ *needs_control_head = TRUE;
cc += 1 + 2 + cc[1];
break;
case OP_RECURSE:
+ stack_restore = TRUE;
if (common->has_set_som && !setsom_found)
{
length += 2;
@@ -1150,6 +1257,11 @@ while (cc < ccend)
length += 2;
setmark_found = TRUE;
}
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ length += 2;
+ capture_last_found = TRUE;
+ }
cc += 1 + LINK_SIZE;
break;
@@ -1157,31 +1269,105 @@ while (cc < ccend)
case OP_CBRAPOS:
case OP_SCBRA:
case OP_SCBRAPOS:
+ stack_restore = TRUE;
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ length += 2;
+ capture_last_found = TRUE;
+ }
length += 3;
cc += 1 + LINK_SIZE + IMM2_SIZE;
break;
default:
+ stack_restore = TRUE;
+ /* Fall through. */
+
+ 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_CHAR:
+ case OP_CHARI:
+ case OP_NOT:
+ case OP_NOTI:
+
+ case OP_EXACT:
+ case OP_POSSTAR:
+ case OP_POSPLUS:
+ case OP_POSQUERY:
+ case OP_POSUPTO:
+
+ case OP_EXACTI:
+ case OP_POSSTARI:
+ case OP_POSPLUSI:
+ case OP_POSQUERYI:
+ case OP_POSUPTOI:
+
+ case OP_NOTEXACT:
+ case OP_NOTPOSSTAR:
+ case OP_NOTPOSPLUS:
+ case OP_NOTPOSQUERY:
+ case OP_NOTPOSUPTO:
+
+ case OP_NOTEXACTI:
+ case OP_NOTPOSSTARI:
+ case OP_NOTPOSPLUSI:
+ case OP_NOTPOSQUERYI:
+ case OP_NOTPOSUPTOI:
+
+ case OP_TYPEEXACT:
+ case OP_TYPEPOSSTAR:
+ case OP_TYPEPOSPLUS:
+ case OP_TYPEPOSQUERY:
+ case OP_TYPEPOSUPTO:
+
+ case OP_CLASS:
+ case OP_NCLASS:
+ case OP_XCLASS:
+
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 (SLJIT_UNLIKELY(possessive == length))
+ return stack_restore ? no_frame : no_stack;
if (length > 0)
return length + 1;
-return -1;
+return stack_restore ? no_frame : no_stack;
}
-static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
+static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
{
DEFINE_COMPILER;
-pcre_uchar *ccend = bracketend(cc);
BOOL setsom_found = recursive;
BOOL setmark_found = recursive;
+/* The last capture is a local variable even for recursions. */
+BOOL capture_last_found = FALSE;
int offset;
/* >= 1 + shortest item size (2) */
@@ -1189,8 +1375,13 @@ 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);
+if (ccend == NULL)
+ {
+ ccend = bracketend(cc) - (1 + LINK_SIZE);
+ if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
+ cc = next_opcode(common, cc);
+ }
+
SLJIT_ASSERT(cc != NULL);
while (cc < ccend)
switch(*cc)
@@ -1200,7 +1391,7 @@ while (cc < ccend)
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);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
stackpos += (int)sizeof(sljit_sw);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
stackpos += (int)sizeof(sljit_sw);
@@ -1210,11 +1401,13 @@ while (cc < ccend)
break;
case OP_MARK:
+ case OP_PRUNE_ARG:
+ case OP_THEN_ARG:
SLJIT_ASSERT(common->mark_ptr != 0);
if (!setmark_found)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
stackpos += (int)sizeof(sljit_sw);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
stackpos += (int)sizeof(sljit_sw);
@@ -1227,7 +1420,7 @@ while (cc < ccend)
if (common->has_set_som && !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);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
stackpos += (int)sizeof(sljit_sw);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
stackpos += (int)sizeof(sljit_sw);
@@ -1236,12 +1429,21 @@ while (cc < ccend)
if (common->mark_ptr != 0 && !setmark_found)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
stackpos += (int)sizeof(sljit_sw);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
stackpos += (int)sizeof(sljit_sw);
setmark_found = TRUE;
}
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ capture_last_found = TRUE;
+ }
cc += 1 + LINK_SIZE;
break;
@@ -1249,6 +1451,15 @@ while (cc < ccend)
case OP_CBRAPOS:
case OP_SCBRA:
case OP_SCBRAPOS:
+ if (common->capture_last_ptr != 0 && !capture_last_found)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
+ stackpos += (int)sizeof(sljit_sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos += (int)sizeof(sljit_sw);
+ capture_last_found = TRUE;
+ }
offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
stackpos += (int)sizeof(sljit_sw);
@@ -1268,13 +1479,13 @@ while (cc < ccend)
break;
}
-OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
SLJIT_ASSERT(stackpos == STACK(stacktop));
}
-static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
+static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
{
-int private_data_length = 2;
+int private_data_length = needs_control_head ? 3 : 2;
int size;
pcre_uchar *alternative;
/* Calculate the sum of the private machine words. */
@@ -1283,6 +1494,12 @@ while (cc < ccend)
size = 0;
switch(*cc)
{
+ case OP_KET:
+ if (PRIVATE_DATA(cc) != 0)
+ private_data_length++;
+ cc += 1 + LINK_SIZE;
+ break;
+
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
@@ -1387,7 +1604,7 @@ return private_data_length;
}
static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
- BOOL save, int stackptr, int stacktop)
+ BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
{
DEFINE_COMPILER;
int srcw[2];
@@ -1408,7 +1625,7 @@ stacktop = STACK(stacktop - 1);
if (!save)
{
- stackptr += sizeof(sljit_sw);
+ stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
if (stackptr < stacktop)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
@@ -1424,15 +1641,21 @@ if (!save)
/* The tmp1next must be TRUE in either way. */
}
-while (status != end)
+do
{
count = 0;
switch(status)
{
case start:
- SLJIT_ASSERT(save && common->recursive_head != 0);
+ SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
count = 1;
- srcw[0] = common->recursive_head;
+ srcw[0] = common->recursive_head_ptr;
+ if (needs_control_head)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+ count = 2;
+ srcw[1] = common->control_head_ptr;
+ }
status = loop;
break;
@@ -1445,6 +1668,15 @@ while (status != end)
switch(*cc)
{
+ case OP_KET:
+ if (PRIVATE_DATA(cc) != 0)
+ {
+ count = 1;
+ srcw[0] = PRIVATE_DATA(cc);
+ }
+ cc += 1 + LINK_SIZE;
+ break;
+
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
@@ -1657,6 +1889,7 @@ while (status != end)
}
}
}
+while (status != end);
if (save)
{
@@ -1690,6 +1923,39 @@ if (save)
SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
}
+static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
+{
+pcre_uchar *end = bracketend(cc);
+BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
+
+/* Assert captures then. */
+if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
+ current_offset = NULL;
+/* Conditional block does not. */
+if (*cc == OP_COND || *cc == OP_SCOND)
+ has_alternatives = FALSE;
+
+cc = next_opcode(common, cc);
+if (has_alternatives)
+ current_offset = common->then_offsets + (cc - common->start);
+
+while (cc < end)
+ {
+ if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
+ cc = set_then_offsets(common, cc, current_offset);
+ else
+ {
+ if (*cc == OP_ALT && has_alternatives)
+ current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
+ if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
+ *current_offset = 1;
+ cc = next_opcode(common, cc);
+ }
+ }
+
+return end;
+}
+
#undef CASE_ITERATOR_PRIVATE_DATA_1
#undef CASE_ITERATOR_PRIVATE_DATA_2A
#undef CASE_ITERATOR_PRIVATE_DATA_2B
@@ -1708,7 +1974,7 @@ 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);
+ SET_LABEL(list->jump, label);
list = list->next;
}
}
@@ -1724,15 +1990,13 @@ if (list_item)
}
}
-static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
+static void add_stub(compiler_common *common, 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->quit = LABEL();
list_item->next = common->stubs;
@@ -1748,23 +2012,18 @@ 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;
- }
+ add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
JUMPTO(SLJIT_JUMP, list_item->quit);
list_item = list_item->next;
}
common->stubs = NULL;
}
-static SLJIT_INLINE void decrease_call_count(compiler_common *common)
+static SLJIT_INLINE void count_match(compiler_common *common)
{
DEFINE_COMPILER;
-OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
+OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
}
@@ -1781,7 +2040,7 @@ 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));
+add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
}
static SLJIT_INLINE void free_stack(compiler_common *common, int size)
@@ -1795,18 +2054,20 @@ 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. */
+SLJIT_ASSERT(length > 1);
/* TMP1 returns with begin - 1. */
OP2(SLJIT_SUB, SLJIT_SCRATCH_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++)
+ for (i = 1; i < length; i++)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
}
else
{
- GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);
+ GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
+ OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
loop = LABEL();
OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
@@ -1814,11 +2075,69 @@ else
}
}
+static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
+{
+DEFINE_COMPILER;
+struct sljit_label *loop;
+int i;
+
+SLJIT_ASSERT(length > 1);
+/* OVECTOR(1) contains the "string begin - 1" constant. */
+if (length > 2)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+if (length < 8)
+ {
+ for (i = 2; i < length; i++)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
+ }
+else
+ {
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
+ loop = LABEL();
+ OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, loop);
+ }
+
+OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
+if (common->control_head_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
+}
+
+static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
+{
+while (current != NULL)
+ {
+ switch (current[-2])
+ {
+ case type_then_trap:
+ break;
+
+ case type_mark:
+ if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
+ return current[-4];
+ break;
+
+ default:
+ SLJIT_ASSERT_STOP();
+ break;
+ }
+ current = (sljit_sw*)current[-1];
+ }
+return -1;
+}
+
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
{
DEFINE_COMPILER;
struct sljit_label *loop;
-struct sljit_jump *earlyexit;
+struct sljit_jump *early_quit;
/* At this point we can freely use all registers. */
OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
@@ -1827,14 +2146,14 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
if (common->mark_ptr != 0)
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
-OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
+OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
if (common->mark_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
/* Unlikely, but possible */
-earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
+early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
loop = LABEL();
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
@@ -1845,7 +2164,7 @@ OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT
OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
JUMPTO(SLJIT_C_NOT_ZERO, loop);
-JUMPHERE(earlyexit);
+JUMPHERE(early_quit);
/* Calculate the return value, which is the maximum ovector value. */
if (topbracket > 1)
@@ -1867,18 +2186,29 @@ else
static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
{
DEFINE_COMPILER;
+struct sljit_jump *jump;
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
-SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
+SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
+ && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
-OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
-CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
+OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
+CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
/* Store match begin and end. */
OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
+
+jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
+OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
+#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
+OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
+JUMPHERE(jump);
+
OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
@@ -2040,7 +2370,7 @@ return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
static void check_partial(compiler_common *common, BOOL force)
{
-/* Checks whether a partial matching is occured. Does not modify registers. */
+/* Checks whether a partial matching is occurred. Does not modify registers. */
DEFINE_COMPILER;
struct sljit_jump *jump = NULL;
@@ -2055,7 +2385,7 @@ else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
else
{
if (common->partialmatchlabel != NULL)
@@ -2068,35 +2398,34 @@ if (jump != NULL)
JUMPHERE(jump);
}
-static struct sljit_jump *check_str_end(compiler_common *common)
+static void check_str_end(compiler_common *common, jump_list **end_reached)
{
/* Does not affect registers. Usually used in a tight spot. */
DEFINE_COMPILER;
struct sljit_jump *jump;
-struct sljit_jump *nohit;
-struct sljit_jump *return_value;
if (common->mode == JIT_COMPILE)
- return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ {
+ add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ return;
+ }
jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
{
- nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
- JUMPHERE(nohit);
- return_value = JUMP(SLJIT_JUMP);
+ add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
+ add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
}
else
{
- return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
if (common->partialmatchlabel != NULL)
JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
else
add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
}
JUMPHERE(jump);
-return return_value;
}
static void detect_partial_match(compiler_common *common, jump_list **backtracks)
@@ -2115,7 +2444,7 @@ jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
{
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
}
else
@@ -2573,7 +2902,7 @@ DEFINE_COMPILER;
struct sljit_label *start;
struct sljit_jump *quit;
pcre_uint32 chars[MAX_N_CHARS * 2];
-pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
+pcre_uchar *cc = common->start + 1 + LINK_SIZE;
int location = 0;
pcre_int32 len, c, bit, caseless;
int must_stop;
@@ -2696,10 +3025,10 @@ if (firstline)
{
SLJIT_ASSERT(common->first_line_end != 0);
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
+ OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
}
else
- OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
+ OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
start = LABEL();
quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
@@ -2728,7 +3057,7 @@ JUMPHERE(quit);
if (firstline)
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
else
- OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
+ OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
return TRUE;
}
@@ -2877,16 +3206,24 @@ if (firstline)
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
}
+static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
+
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 *quit;
-struct sljit_jump *found;
+struct sljit_jump *found = NULL;
+jump_list *matches = NULL;
+pcre_uint8 inverted_start_bits[32];
+int i;
#ifndef COMPILE_PCRE8
struct sljit_jump *jump;
#endif
+for (i = 0; i < 32; ++i)
+ inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
+
if (firstline)
{
SLJIT_ASSERT(common->first_line_end != 0);
@@ -2901,17 +3238,21 @@ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
if (common->utf)
OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
#endif
+
+if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
+ {
#ifndef COMPILE_PCRE8
-jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
-JUMPHERE(jump);
+ 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);
+ 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)
@@ -2939,7 +3280,10 @@ if (common->utf)
#endif /* COMPILE_PCRE[8|16] */
#endif /* SUPPORT_UTF */
JUMPTO(SLJIT_JUMP, start);
-JUMPHERE(found);
+if (found != NULL)
+ JUMPHERE(found);
+if (matches != NULL)
+ set_jumps(matches, LABEL());
JUMPHERE(quit);
if (firstline)
@@ -3022,7 +3366,9 @@ GET_LOCAL_BASE(TMP3, 0, 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_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
+jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
+
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
@@ -3030,31 +3376,14 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
JUMPTO(SLJIT_JUMP, mainloop);
JUMPHERE(jump);
-jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
+jump = JUMP(SLJIT_C_SIG_LESS);
/* 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_sw));
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
-JUMPTO(SLJIT_JUMP, mainloop);
-
-JUMPHERE(jump);
-if (common->mark_ptr != 0)
- {
- jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
- JUMPTO(SLJIT_JUMP, mainloop);
-
- JUMPHERE(jump);
- }
-
-/* Unknown command. */
+OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
+OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
JUMPTO(SLJIT_JUMP, mainloop);
}
@@ -3063,6 +3392,7 @@ static void check_wordboundary(compiler_common *common)
{
DEFINE_COMPILER;
struct sljit_jump *skipread;
+jump_list *skipread_list = NULL;
#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
struct sljit_jump *jump;
#endif
@@ -3120,7 +3450,7 @@ else
JUMPHERE(skipread);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
-skipread = check_str_end(common);
+check_str_end(common, &skipread_list);
peek_char(common);
/* Testing char type. This is a code duplication. */
@@ -3161,7 +3491,7 @@ else
JUMPHERE(jump);
#endif /* COMPILE_PCRE8 */
}
-JUMPHERE(skipread);
+set_jumps(skipread_list, LABEL());
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);
@@ -3216,7 +3546,9 @@ switch(ranges[0])
}
return TRUE;
}
- if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
+ if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4])
+ && (ranges[2] | (ranges[4] - ranges[2])) == ranges[4]
+ && is_powerof2(ranges[4] - ranges[2]))
{
if (readch)
read_char(common);
@@ -3481,7 +3813,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
#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)
+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. */
pcre_uint32 c1, c2;
@@ -3577,7 +3909,7 @@ do
#endif
context->length -= IN_UCHARS(1);
-#if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
+#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
/* Unaligned read is supported. */
if (othercasebit != 0 && othercasechar == cc)
@@ -3594,27 +3926,18 @@ do
#if defined COMPILE_PCRE8
if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
-#elif defined COMPILE_PCRE16
+#else
if (context->ucharptr >= 2 || context->length == 0)
-#elif defined COMPILE_PCRE32
- if (1 /* context->ucharptr >= 1 || context->length == 0 */)
#endif
{
-#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
if (context->length >= 4)
OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#if defined COMPILE_PCRE8
else if (context->length >= 2)
OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
+#if defined COMPILE_PCRE8
else if (context->length >= 1)
OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#elif defined COMPILE_PCRE16
- else if (context->length >= 2)
- OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif /* COMPILE_PCRE[8|16] */
-#elif defined COMPILE_PCRE32
- OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
-#endif /* COMPILE_PCRE[8|16|32] */
+#endif /* COMPILE_PCRE8 */
context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
switch(context->ucharptr)
@@ -3625,7 +3948,6 @@ do
add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
break;
-#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
case 2 / sizeof(pcre_uchar):
if (context->oc.asushort != 0)
OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
@@ -3640,8 +3962,6 @@ do
break;
#endif
-#endif /* COMPILE_PCRE[8|16] */
-
default:
SLJIT_ASSERT_STOP();
break;
@@ -3651,8 +3971,8 @@ do
#else
- /* Unaligned read is unsupported. */
- if (context->length > 0)
+ /* Unaligned read is unsupported or in 32 bit mode. */
+ if (context->length >= 1)
OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
@@ -3705,14 +4025,15 @@ DEFINE_COMPILER;
jump_list *found = NULL;
jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
pcre_int32 c, charoffset;
-const pcre_uint32 *other_cases;
struct sljit_jump *jump = NULL;
pcre_uchar *ccbegin;
int compares, invertcmp, numberofcmps;
+
#ifdef SUPPORT_UCP
BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
BOOL charsaved = FALSE;
int typereg = TMP1, scriptreg = TMP1;
+const pcre_uint32 *other_cases;
pcre_int32 typeoffset;
#endif
@@ -3808,11 +4129,15 @@ while (*cc != XCL_END)
case PT_SPACE:
case PT_PXSPACE:
case PT_WORD:
+ case PT_PXGRAPH:
+ case PT_PXPRINT:
+ case PT_PXPUNCT:
needstype = TRUE;
needschar = TRUE;
break;
case PT_CLIST:
+ case PT_UCNC:
needschar = TRUE;
break;
@@ -3994,16 +4319,15 @@ while (*cc != XCL_END)
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);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
- if (*cc == PT_SPACE)
- JUMPHERE(jump);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
SET_TYPE_OFFSET(ucp_Zl);
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
@@ -4014,7 +4338,7 @@ while (*cc != XCL_END)
case PT_WORD:
OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- /* ... fall through */
+ /* Fall through. */
case PT_ALNUM:
SET_TYPE_OFFSET(ucp_Ll);
@@ -4078,6 +4402,84 @@ while (*cc != XCL_END)
}
jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
break;
+
+ case PT_UCNC:
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+
+ SET_CHAR_OFFSET(0xa0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ SET_CHAR_OFFSET(0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
+
+ case PT_PXGRAPH:
+ /* C and Z groups are the farthest two groups. */
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
+
+ jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
+
+ /* In case of ucp_Cf, we overwrite the result. */
+ SET_CHAR_OFFSET(0x2066);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+
+ JUMPHERE(jump);
+ jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
+ break;
+
+ case PT_PXPRINT:
+ /* C and Z groups are the farthest two groups. */
+ SET_TYPE_OFFSET(ucp_Ll);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
+ OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
+
+ jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
+
+ /* In case of ucp_Cf, we overwrite the result. */
+ SET_CHAR_OFFSET(0x2066);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
+
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
+ OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
+
+ JUMPHERE(jump);
+ jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
+ break;
+
+ case PT_PXPUNCT:
+ SET_TYPE_OFFSET(ucp_Sc);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
+
+ SET_CHAR_OFFSET(0);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
+ OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
+
+ SET_TYPE_OFFSET(ucp_Pc);
+ OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
+ OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
+ jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
+ break;
}
cc += 2;
}
@@ -4103,6 +4505,7 @@ int length;
unsigned int c, oc, bit;
compare_context context;
struct sljit_jump *jump[4];
+jump_list *end_list;
#ifdef SUPPORT_UTF
struct sljit_label *label;
#ifdef SUPPORT_UCP
@@ -4171,15 +4574,15 @@ switch(type)
if (common->nltype == NLTYPE_FIXED && common->newline > 255)
{
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
+ end_list = NULL;
if (common->mode != JIT_PARTIAL_HARD_COMPILE)
- jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
else
- jump[1] = check_str_end(common);
+ check_str_end(common, &end_list);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
- if (jump[1] != NULL)
- JUMPHERE(jump[1]);
+ set_jumps(end_list, LABEL());
JUMPHERE(jump[0]);
}
else
@@ -4238,19 +4641,20 @@ switch(type)
read_char(common);
jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
/* We don't need to handle soft partial matching case. */
+ end_list = NULL;
if (common->mode != JIT_PARTIAL_HARD_COMPILE)
- jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
else
- jump[1] = check_str_end(common);
+ check_str_end(common, &end_list);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
- jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
+ jump[1] = 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);
+ jump[2] = JUMP(SLJIT_JUMP);
JUMPHERE(jump[0]);
check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
+ set_jumps(end_list, LABEL());
JUMPHERE(jump[1]);
JUMPHERE(jump[2]);
- JUMPHERE(jump[3]);
return cc;
case OP_NOT_HSPACE:
@@ -4714,28 +5118,6 @@ if (context.length > 0)
return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
}
-static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
-{
-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 (backtracks == NULL)
- {
- /* OVECTOR(1) contains the "string begin - 1" constant. */
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
- OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
- OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
- return JUMP(SLJIT_C_NOT_ZERO);
- }
- add_jump(compiler, backtracks, 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_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
@@ -4768,24 +5150,65 @@ static void compile_backtrackingpath(compiler_common *, struct backtrack_common
#define BACKTRACK_AS(type) ((type *)backtrack)
-static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
+static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
{
+/* The OVECTOR offset goes to TMP2. */
DEFINE_COMPILER;
-int offset = GET2(cc, 1) << 1;
+int count = GET2(cc, 1 + IMM2_SIZE);
+pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
+unsigned int offset;
+jump_list *found = NULL;
+
+SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+
+count--;
+while (count-- > 0)
+ {
+ offset = GET2(slot, 0) << 1;
+ GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
+ add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
+ slot += common->name_entry_size;
+ }
+
+offset = GET2(slot, 0) << 1;
+GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
+if (backtracks != NULL && !common->jscript_compat)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
+
+set_jumps(found, LABEL());
+}
+
+static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
+{
+DEFINE_COMPILER;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
+int offset = 0;
struct sljit_jump *jump = NULL;
struct sljit_jump *partial;
struct sljit_jump *nopartial;
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
-/* OVECTOR(1) contains the "string begin - 1" constant. */
-if (withchecks && !common->jscript_compat)
- add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+if (ref)
+ {
+ offset = GET2(cc, 1) << 1;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
+ /* OVECTOR(1) contains the "string begin - 1" constant. */
+ if (withchecks && !common->jscript_compat)
+ add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ }
+else
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
#if defined SUPPORT_UTF && defined SUPPORT_UCP
if (common->utf && *cc == OP_REFI)
{
SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ if (ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ else
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+
if (withchecks)
jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
@@ -4810,7 +5233,11 @@ if (common->utf && *cc == OP_REFI)
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 (ref)
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
+ else
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
+
if (withchecks)
jump = JUMP(SLJIT_C_ZERO);
@@ -4847,14 +5274,15 @@ if (jump != NULL)
else
JUMPHERE(jump);
}
-return cc + 1 + IMM2_SIZE;
}
static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
{
DEFINE_COMPILER;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
backtrack_common *backtrack;
pcre_uchar type;
+int offset = 0;
struct sljit_label *label;
struct sljit_jump *zerolength;
struct sljit_jump *jump = NULL;
@@ -4864,7 +5292,13 @@ BOOL minimize;
PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
+if (ref)
+ offset = GET2(cc, 1) << 1;
+else
+ cc += IMM2_SIZE;
type = cc[1 + IMM2_SIZE];
+
+SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
minimize = (type & 0x1) != 0;
switch(type)
{
@@ -4902,25 +5336,52 @@ if (!minimize)
if (min == 0)
{
allocate_stack(common, 2);
+ if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
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_sw));
- zerolength = compile_ref_checks(common, ccbegin, NULL);
+ /* Handles both invalid and empty cases. Since the minimum repeat,
+ is zero the invalid case is basically the same as an empty case. */
+ if (ref)
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ else
+ {
+ compile_dnref_search(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
/* Restore if not zero length. */
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
}
else
{
allocate_stack(common, 1);
+ if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
- zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
+ if (ref)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ }
+ else
+ {
+ compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
}
if (min > 1 || max > 1)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
label = LABEL();
+ if (!ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
if (min > 1 || max > 1)
@@ -4951,28 +5412,56 @@ if (!minimize)
JUMPHERE(zerolength);
BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
- decrease_call_count(common);
+ count_match(common);
return cc;
}
-allocate_stack(common, 2);
+allocate_stack(common, ref ? 2 : 3);
+if (ref)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
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);
+ /* Handles both invalid and empty cases. Since the minimum repeat,
+ is zero the invalid case is basically the same as an empty case. */
+ if (ref)
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ else
+ {
+ compile_dnref_search(common, ccbegin, NULL);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ /* Length is non-zero, we can match real repeats. */
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
jump = JUMP(SLJIT_JUMP);
}
else
- zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
+ {
+ if (ref)
+ {
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
+ }
+ else
+ {
+ compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
+ zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
+ }
+ }
BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
if (max > 0)
add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
+if (!ref)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
@@ -4990,7 +5479,7 @@ if (jump != NULL)
JUMPHERE(jump);
JUMPHERE(zerolength);
-decrease_call_count(common);
+count_match(common);
return cc;
}
@@ -5000,9 +5489,21 @@ DEFINE_COMPILER;
backtrack_common *backtrack;
recurse_entry *entry = common->entries;
recurse_entry *prev = NULL;
-int start = GET(cc, 1);
+sljit_sw start = GET(cc, 1);
+pcre_uchar *start_cc;
+BOOL needs_control_head;
PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
+
+/* Inlining simple patterns. */
+if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
+ {
+ start_cc = common->start + start;
+ compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
+ BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
+ return cc + 1 + LINK_SIZE;
+ }
+
while (entry != NULL)
{
if (entry->start == start)
@@ -5051,10 +5552,111 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_
return cc + 1 + LINK_SIZE;
}
+static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
+{
+const pcre_uchar *begin = arguments->begin;
+int *offset_vector = arguments->offsets;
+int offset_count = arguments->offset_count;
+int i;
+
+if (PUBL(callout) == NULL)
+ return 0;
+
+callout_block->version = 2;
+callout_block->callout_data = arguments->callout_data;
+
+/* Offsets in subject. */
+callout_block->subject_length = arguments->end - arguments->begin;
+callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
+callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
+#if defined COMPILE_PCRE8
+callout_block->subject = (PCRE_SPTR)begin;
+#elif defined COMPILE_PCRE16
+callout_block->subject = (PCRE_SPTR16)begin;
+#elif defined COMPILE_PCRE32
+callout_block->subject = (PCRE_SPTR32)begin;
+#endif
+
+/* Convert and copy the JIT offset vector to the offset_vector array. */
+callout_block->capture_top = 0;
+callout_block->offset_vector = offset_vector;
+for (i = 2; i < offset_count; i += 2)
+ {
+ offset_vector[i] = jit_ovector[i] - begin;
+ offset_vector[i + 1] = jit_ovector[i + 1] - begin;
+ if (jit_ovector[i] >= begin)
+ callout_block->capture_top = i;
+ }
+
+callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
+if (offset_count > 0)
+ offset_vector[0] = -1;
+if (offset_count > 1)
+ offset_vector[1] = -1;
+return (*PUBL(callout))(callout_block);
+}
+
+/* Aligning to 8 byte. */
+#define CALLOUT_ARG_SIZE \
+ (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
+
+#define CALLOUT_ARG_OFFSET(arg) \
+ (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
+
+static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
+
+allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
+OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+SLJIT_ASSERT(common->capture_last_ptr != 0);
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
+
+/* These pointer sized fields temporarly stores internal variables. */
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
+
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
+OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
+
+/* Needed to save important temporary registers. */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
+OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
+GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
+sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
+OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
+
+/* Check return value. */
+OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
+if (common->forced_quit_label == NULL)
+ add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
+else
+ JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
+return cc + 2 + 2 * LINK_SIZE;
+}
+
+#undef CALLOUT_ARG_SIZE
+#undef CALLOUT_ARG_OFFSET
+
static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
{
DEFINE_COMPILER;
int framesize;
+int extrasize;
+BOOL needs_control_head;
int private_data_ptr;
backtrack_common altbacktrack;
pcre_uchar *ccbegin;
@@ -5064,13 +5666,20 @@ jump_list *tmp = NULL;
jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
jump_list **found;
/* Saving previous accept variables. */
-struct sljit_label *save_quitlabel = common->quitlabel;
-struct sljit_label *save_acceptlabel = common->acceptlabel;
+BOOL save_local_exit = common->local_exit;
+BOOL save_positive_assert = common->positive_assert;
+then_trap_backtrack *save_then_trap = common->then_trap;
+struct sljit_label *save_quit_label = common->quit_label;
+struct sljit_label *save_accept_label = common->accept_label;
jump_list *save_quit = common->quit;
+jump_list *save_positive_assert_quit = common->positive_assert_quit;
jump_list *save_accept = common->accept;
struct sljit_jump *jump;
struct sljit_jump *brajump = NULL;
+/* Assert captures then. */
+common->then_trap = NULL;
+
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
{
SLJIT_ASSERT(!conditional);
@@ -5079,7 +5688,7 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
}
private_data_ptr = PRIVATE_DATA(cc);
SLJIT_ASSERT(private_data_ptr != 0);
-framesize = get_framesize(common, cc, FALSE);
+framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
backtrack->framesize = framesize;
backtrack->private_data_ptr = private_data_ptr;
opcode = *cc;
@@ -5098,27 +5707,56 @@ if (bra == OP_BRAMINZERO)
if (framesize < 0)
{
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
- allocate_stack(common, 1);
+ extrasize = needs_control_head ? 2 : 1;
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
+ allocate_stack(common, extrasize);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ }
}
else
{
- allocate_stack(common, framesize + 2);
+ extrasize = needs_control_head ? 3 : 2;
+ allocate_stack(common, framesize + extrasize);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
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);
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
+ }
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
+ init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
}
memset(&altbacktrack, 0, sizeof(backtrack_common));
-common->quitlabel = NULL;
-common->quit = NULL;
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ /* Negative assert is stronger than positive assert. */
+ common->local_exit = TRUE;
+ common->quit_label = NULL;
+ common->quit = NULL;
+ common->positive_assert = FALSE;
+ }
+else
+ common->positive_assert = TRUE;
+common->positive_assert_quit = NULL;
+
while (1)
{
- common->acceptlabel = NULL;
+ common->accept_label = NULL;
common->accept = NULL;
altbacktrack.top = NULL;
altbacktrack.topbacktracks = NULL;
@@ -5130,45 +5768,64 @@ while (1)
compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
- common->quitlabel = save_quitlabel;
- common->acceptlabel = save_acceptlabel;
- common->quit = save_quit;
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+ common->positive_assert = save_positive_assert;
+ common->then_trap = save_then_trap;
+ common->accept_label = save_accept_label;
+ common->positive_assert_quit = save_positive_assert_quit;
common->accept = save_accept;
return NULL;
}
- common->acceptlabel = LABEL();
+ common->accept_label = LABEL();
if (common->accept != NULL)
- set_jumps(common->accept, common->acceptlabel);
+ set_jumps(common->accept, common->accept_label);
/* Reset stack. */
if (framesize < 0)
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- else {
+ {
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ else
+ free_stack(common, extrasize);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
+ }
+ else
+ {
if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
{
/* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
}
else
{
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
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);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
else if (bra == OP_BRAZERO)
{
if (framesize < 0)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
else
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
}
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
@@ -5185,9 +5842,16 @@ while (1)
compile_backtrackingpath(common, altbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
- common->quitlabel = save_quitlabel;
- common->acceptlabel = save_acceptlabel;
- common->quit = save_quit;
+ if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+ common->positive_assert = save_positive_assert;
+ common->then_trap = save_then_trap;
+ common->accept_label = save_accept_label;
+ common->positive_assert_quit = save_positive_assert_quit;
common->accept = save_accept;
return NULL;
}
@@ -5199,9 +5863,33 @@ while (1)
ccbegin = cc;
cc += GET(cc, 1);
}
+
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ SLJIT_ASSERT(common->positive_assert_quit == NULL);
+ /* Makes the check less complicated below. */
+ common->positive_assert_quit = common->quit;
+ }
+
/* None of them matched. */
-if (common->quit != NULL)
- set_jumps(common->quit, LABEL());
+if (common->positive_assert_quit != NULL)
+ {
+ jump = JUMP(SLJIT_JUMP);
+ set_jumps(common->positive_assert_quit, LABEL());
+ SLJIT_ASSERT(framesize != no_stack);
+ if (framesize < 0)
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
+ else
+ {
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
+ }
+ JUMPHERE(jump);
+ }
+
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
{
@@ -5213,21 +5901,25 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
{
/* The topmost item should be 0. */
if (bra == OP_BRAZERO)
+ {
+ if (extrasize == 2)
+ free_stack(common, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
else
- free_stack(common, 1);
+ free_stack(common, extrasize);
}
else
{
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
/* The topmost item should be 0. */
if (bra == OP_BRAZERO)
{
- free_stack(common, framesize + 1);
+ free_stack(common, framesize + extrasize - 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
}
else
- free_stack(common, framesize + 2);
+ free_stack(common, framesize + extrasize);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
}
jump = JUMP(SLJIT_JUMP);
@@ -5239,10 +5931,14 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
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);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
/* 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_sw));
+ if (extrasize == 2)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ }
else if (bra == OP_BRAMINZERO)
{
OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
@@ -5255,21 +5951,30 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
{
/* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
}
else
{
/* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
- 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 (extrasize == 2)
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ if (bra == OP_BRAMINZERO)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
+ }
}
}
if (bra == OP_BRAZERO)
{
backtrack->matchingpath = LABEL();
- sljit_set_label(jump, backtrack->matchingpath);
+ SET_LABEL(jump, backtrack->matchingpath);
}
else if (bra == OP_BRAMINZERO)
{
@@ -5291,22 +5996,26 @@ else
{
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
if (bra != OP_BRA)
+ {
+ if (extrasize == 2)
+ free_stack(common, 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
+ }
else
- free_stack(common, 1);
+ free_stack(common, extrasize);
}
else
{
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
/* The topmost item should be 0. */
if (bra != OP_BRA)
{
- free_stack(common, framesize + 1);
+ free_stack(common, framesize + extrasize - 1);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
}
else
- free_stack(common, framesize + 2);
+ free_stack(common, framesize + extrasize);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
}
@@ -5326,121 +6035,89 @@ else
}
}
-common->quitlabel = save_quitlabel;
-common->acceptlabel = save_acceptlabel;
-common->quit = save_quit;
+if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
+ {
+ common->local_exit = save_local_exit;
+ common->quit_label = save_quit_label;
+ common->quit = save_quit;
+ }
+common->positive_assert = save_positive_assert;
+common->then_trap = save_then_trap;
+common->accept_label = save_accept_label;
+common->positive_assert_quit = save_positive_assert_quit;
common->accept = save_accept;
return cc + 1 + LINK_SIZE;
}
-static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)
+static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
{
-int condition = FALSE;
-pcre_uchar *slotA = name_table;
-pcre_uchar *slotB;
-sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)];
-sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];
-sljit_sw no_capture;
-int i;
-
-locals += refno & 0xff;
-refno >>= 8;
-no_capture = locals[1];
+DEFINE_COMPILER;
+int stacksize;
-for (i = 0; i < name_count; i++)
+if (framesize < 0)
{
- if (GET2(slotA, 0) == refno) break;
- slotA += name_entry_size;
- }
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ else
+ {
+ stacksize = needs_control_head ? 1 : 0;
+ if (ket != OP_KET || has_alternatives)
+ stacksize++;
+ free_stack(common, stacksize);
+ }
-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. */
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
- slotB = slotA;
- while (slotB > name_table)
+ /* 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)
{
- 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;
+ /* Move the STR_PTR to the private_data_ptr. */
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
}
+ }
+else
+ {
+ stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
+ OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
- /* Scan up for duplicates */
- if (!condition)
+ if (ket == OP_KETRMAX)
{
- 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;
- }
+ /* TMP2 which is set here used by OP_KETRMAX below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
}
}
-return condition;
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
}
-static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)
+static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
{
-int condition = FALSE;
-pcre_uchar *slotA = name_table;
-pcre_uchar *slotB;
-sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)];
-sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];
-sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)];
-sljit_uw i;
+DEFINE_COMPILER;
-for (i = 0; i < name_count; i++)
+if (common->capture_last_ptr != 0)
{
- if (GET2(slotA, 0) == recno) break;
- slotA += name_entry_size;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
+ stacksize++;
}
-
-if (i < name_count)
+if (common->optimized_cbracket[offset >> 1] == 0)
{
- /* 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;
- }
- }
+ 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(stacksize), TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
+ 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);
+ stacksize += 2;
}
-return condition;
+return stacksize;
}
/*
@@ -5504,17 +6181,21 @@ backtrack_common *backtrack;
pcre_uchar opcode;
int private_data_ptr = 0;
int offset = 0;
-int stacksize;
+int i, stacksize;
+int repeat_ptr = 0, repeat_length = 0;
+int repeat_type = 0, repeat_count = 0;
pcre_uchar *ccbegin;
pcre_uchar *matchingpath;
+pcre_uchar *slot;
pcre_uchar bra = OP_BRA;
pcre_uchar ket;
assert_backtrack *assert;
BOOL has_alternatives;
+BOOL needs_control_head = FALSE;
struct sljit_jump *jump;
struct sljit_jump *skip;
-struct sljit_label *rmaxlabel = NULL;
-struct sljit_jump *braminzerojump = NULL;
+struct sljit_label *rmax_label = NULL;
+struct sljit_jump *braminzero = NULL;
PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
@@ -5527,35 +6208,36 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
opcode = *cc;
ccbegin = cc;
-matchingpath = ccbegin + 1 + LINK_SIZE;
+matchingpath = bracketend(cc) - 1 - LINK_SIZE;
+ket = *matchingpath;
+if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
+ {
+ repeat_ptr = PRIVATE_DATA(matchingpath);
+ repeat_length = PRIVATE_DATA(matchingpath + 1);
+ repeat_type = PRIVATE_DATA(matchingpath + 2);
+ repeat_count = PRIVATE_DATA(matchingpath + 3);
+ SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
+ if (repeat_type == OP_UPTO)
+ ket = OP_KETRMAX;
+ if (repeat_type == OP_MINUPTO)
+ ket = OP_KETRMIN;
+ }
if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
{
/* Drop this bracket_backtrack. */
parent->top = backtrack->prev;
- return bracketend(cc);
+ return matchingpath + 1 + LINK_SIZE + repeat_length;
}
-ket = *(bracketend(cc) - 1 - LINK_SIZE);
+matchingpath = ccbegin + 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 = (*matchingpath == OP_RREF) ? FALSE : TRUE;
- if (*matchingpath == OP_NRREF)
- {
- stacksize = GET2(matchingpath, 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 != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
- }
- }
+if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
+ has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE;
if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
opcode = OP_SCOND;
@@ -5586,12 +6268,12 @@ else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
SLJIT_ASSERT(private_data_ptr != 0);
BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
if (opcode == OP_ONCE)
- BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
}
/* Instructions before the first alternative. */
stacksize = 0;
-if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
stacksize++;
if (bra == OP_BRAZERO)
stacksize++;
@@ -5600,7 +6282,7 @@ if (stacksize > 0)
allocate_stack(common, stacksize);
stacksize = 0;
-if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
+if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
{
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
stacksize++;
@@ -5616,7 +6298,7 @@ if (bra == OP_BRAMINZERO)
if (ket != OP_KETRMIN)
{
free_stack(common, 1);
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
+ braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
}
else
{
@@ -5631,13 +6313,13 @@ if (bra == OP_BRAMINZERO)
if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
{
/* When we come from outside, private_data_ptr contains the previous STR_PTR. */
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
}
else
{
/* Except when the whole stack frame must be saved. */
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
+ braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
}
JUMPHERE(skip);
}
@@ -5650,77 +6332,106 @@ if (bra == OP_BRAMINZERO)
}
}
+if (repeat_type != 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
+ if (repeat_type == OP_EXACT)
+ rmax_label = LABEL();
+ }
+
if (ket == OP_KETRMIN)
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
if (ket == OP_KETRMAX)
{
- rmaxlabel = LABEL();
- if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
- BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
+ rmax_label = LABEL();
+ if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
}
/* Handling capturing brackets and alternatives. */
if (opcode == OP_ONCE)
{
+ stacksize = 0;
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ stacksize++;
+ }
+
if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
{
- /* Neither capturing brackets nor recursions are not found in the block. */
+ /* Neither capturing brackets nor recursions are found in the block. */
if (ket == OP_KETRMIN)
{
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- 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), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
+ stacksize += 2;
+ if (!needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
}
- else if (ket == OP_KETRMAX || has_alternatives)
+ else
{
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
- allocate_stack(common, 1);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
+ if (ket == OP_KETRMAX || has_alternatives)
+ stacksize++;
}
- else
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
+
+ if (stacksize > 0)
+ allocate_stack(common, stacksize);
+
+ stacksize = 0;
+ if (needs_control_head)
+ {
+ stacksize++;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
+ if (ket == OP_KETRMIN)
+ {
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
+ }
+ else if (ket == OP_KETRMAX || has_alternatives)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
}
else
{
- if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
+ if (ket != OP_KET || has_alternatives)
+ stacksize++;
+
+ stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
+ allocate_stack(common, stacksize);
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
+
+ stacksize = needs_control_head ? 1 : 0;
+ if (ket != OP_KET || has_alternatives)
{
- allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
- init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
+ stacksize++;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
}
else
{
- allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
- init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
}
+ init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
}
}
else if (opcode == OP_CBRA || opcode == OP_SCBRA)
{
/* Saving the previous values. */
- if (common->optimized_cbracket[offset >> 1] == 0)
- {
- 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, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
- }
- else
+ if (common->optimized_cbracket[offset >> 1] != 0)
{
SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
allocate_stack(common, 2);
@@ -5730,6 +6441,13 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA)
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, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
}
else if (opcode == OP_SBRA || opcode == OP_SCOND)
{
@@ -5756,47 +6474,73 @@ if (opcode == OP_COND || opcode == OP_SCOND)
CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
matchingpath += 1 + IMM2_SIZE;
}
- else if (*matchingpath == OP_NCREF)
+ else if (*matchingpath == OP_DNCREF)
{
SLJIT_ASSERT(has_alternatives);
- stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));
- GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
- OP1(SLJIT_MOV, SLJIT_SCRATCH_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, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
- JUMPHERE(jump);
- matchingpath += 1 + IMM2_SIZE;
+ i = GET2(matchingpath, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
+ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
+ OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
+ slot += common->name_entry_size;
+ i--;
+ while (i-- > 0)
+ {
+ OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
+ OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
+ slot += common->name_entry_size;
+ }
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
+ add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
+ matchingpath += 1 + 2 * IMM2_SIZE;
}
- else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
+ else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
{
/* Never has other case. */
BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
+ SLJIT_ASSERT(!has_alternatives);
- stacksize = GET2(matchingpath, 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 == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
-
- if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
+ if (*matchingpath == OP_RREF)
{
- SLJIT_ASSERT(!has_alternatives);
+ stacksize = GET2(matchingpath, 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 == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+
if (stacksize != 0)
matchingpath += 1 + IMM2_SIZE;
+ }
+ else
+ {
+ if (common->currententry == NULL || common->currententry->start == 0)
+ stacksize = 0;
else
{
+ stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
+ slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
+ i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
+ while (stacksize > 0)
+ {
+ if ((int)GET2(slot, 0) == i)
+ break;
+ slot += common->name_entry_size;
+ stacksize--;
+ }
+ }
+
+ if (stacksize != 0)
+ matchingpath += 1 + 2 * IMM2_SIZE;
+ }
+
+ /* The stacksize == 0 is a common "else" case. */
+ if (stacksize == 0)
+ {
if (*cc == OP_ALT)
{
matchingpath = cc + 1 + LINK_SIZE;
@@ -5805,24 +6549,6 @@ if (opcode == OP_COND || opcode == OP_SCOND)
else
matchingpath = cc;
}
- }
- else
- {
- SLJIT_ASSERT(has_alternatives);
-
- stacksize = GET2(matchingpath, 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_SCRATCH_REG1, 0, SLJIT_IMM, stacksize);
- GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
- OP1(SLJIT_MOV, SLJIT_SCRATCH_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, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
- matchingpath += 1 + IMM2_SIZE;
- }
}
else
{
@@ -5843,34 +6569,24 @@ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
return NULL;
if (opcode == OP_ONCE)
- {
- if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- /* 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 private_data_ptr. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw));
- 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));
- }
- }
- }
+ match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
stacksize = 0;
+if (repeat_type == OP_MINUPTO)
+ {
+ /* We need to preserve the counter. TMP2 will be used below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
+ stacksize++;
+ }
if (ket != OP_KET || bra != OP_BRA)
stacksize++;
+if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ if (common->optimized_cbracket[offset >> 1] == 0)
+ stacksize += 2;
+ }
if (has_alternatives && opcode != OP_ONCE)
stacksize++;
@@ -5878,17 +6594,25 @@ if (stacksize > 0)
allocate_stack(common, stacksize);
stacksize = 0;
-if (ket != OP_KET)
+if (repeat_type == OP_MINUPTO)
{
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
+ /* TMP2 was set above. */
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
stacksize++;
}
-else if (bra != OP_BRA)
+
+if (ket != OP_KET || bra != OP_BRA)
{
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ 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 (offset != 0)
+ stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
+
if (has_alternatives)
{
if (opcode != OP_ONCE)
@@ -5898,36 +6622,58 @@ if (has_alternatives)
}
/* Must be after the matchingpath label. */
-if (offset != 0)
+if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
{
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
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 (repeat_type != 0)
+ {
+ if (has_alternatives)
+ BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
+ /* Drop STR_PTR for greedy plus quantifier. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else if (opcode == OP_ONCE || opcode >= OP_SBRA)
{
if (has_alternatives)
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
/* Checking zero-length iteration. */
if (opcode != OP_ONCE)
{
- CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmax_label);
/* Drop STR_PTR for greedy plus quantifier. */
if (bra != OP_BRAZERO)
free_stack(common, 1);
}
else
/* TMP2 must contain the starting STR_PTR. */
- CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
}
else
- JUMPTO(SLJIT_JUMP, rmaxlabel);
+ JUMPTO(SLJIT_JUMP, rmax_label);
BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
}
+if (repeat_type == OP_EXACT)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
+ }
+else if (repeat_type == OP_UPTO)
+ {
+ /* We need to preserve the counter. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ }
+
if (bra == OP_BRAZERO)
BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
@@ -5935,9 +6681,9 @@ if (bra == OP_BRAMINZERO)
{
/* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
- if (braminzerojump != NULL)
+ if (braminzero != NULL)
{
- JUMPHERE(braminzerojump);
+ JUMPHERE(braminzero);
/* We need to release the end pointer to perform the
backtrack for the zero-length iteration. When
framesize is < 0, OP_ONCE will do the release itself. */
@@ -5953,13 +6699,17 @@ if (bra == OP_BRAMINZERO)
}
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
- decrease_call_count(common);
+ count_match(common);
/* Skip the other alternatives. */
while (*cc == OP_ALT)
cc += GET(cc, 1);
cc += 1 + LINK_SIZE;
-return cc;
+
+/* Temporarily encoding the needs_control_head in framesize. */
+if (opcode == OP_ONCE)
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
+return cc + repeat_length;
}
static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
@@ -5969,12 +6719,13 @@ backtrack_common *backtrack;
pcre_uchar opcode;
int private_data_ptr;
int cbraprivptr = 0;
+BOOL needs_control_head;
int framesize;
int stacksize;
int offset = 0;
BOOL zero = FALSE;
pcre_uchar *ccbegin = NULL;
-int stack;
+int stack; /* Also contains the offset of control head. */
struct sljit_label *loop = NULL;
struct jump_list *emptymatch = NULL;
@@ -6012,59 +6763,104 @@ switch(opcode)
break;
}
-framesize = get_framesize(common, cc, FALSE);
+framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
if (framesize < 0)
{
- stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
+ if (offset != 0)
+ {
+ stacksize = 2;
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ }
+ else
+ stacksize = 1;
+
+ if (needs_control_head)
+ stacksize++;
if (!zero)
stacksize++;
+
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
allocate_stack(common, stacksize);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ stack = 0;
+ if (offset != 0)
{
+ stack = 2;
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);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ if (common->capture_last_ptr != 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
+ stack = 3;
+ }
}
else
+ {
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ stack = 1;
+ }
+ if (needs_control_head)
+ stack++;
if (!zero)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
+ if (needs_control_head)
+ {
+ stack--;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
+ }
}
else
{
stacksize = framesize + 1;
if (!zero)
stacksize++;
- if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ if (needs_control_head)
+ stacksize++;
+ if (offset == 0)
stacksize++;
BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
- allocate_stack(common, stacksize);
+ allocate_stack(common, stacksize);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
+ if (needs_control_head)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
+
stack = 0;
if (!zero)
{
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
+ stack = 1;
+ }
+ if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
stack++;
}
- if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
+ if (offset == 0)
{
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);
+ init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
+ stack -= 1 + (offset == 0);
}
-if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+if (offset != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
loop = LABEL();
@@ -6080,13 +6876,16 @@ while (*cc != OP_KETRPOS)
if (framesize < 0)
{
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ if (framesize == no_frame)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ if (offset != 0)
{
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);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
}
else
@@ -6104,12 +6903,14 @@ while (*cc != OP_KETRPOS)
}
else
{
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ if (offset != 0)
{
OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
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);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
}
else
@@ -6132,6 +6933,10 @@ while (*cc != OP_KETRPOS)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
}
}
+
+ if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
+
JUMPTO(SLJIT_JUMP, loop);
flush_stubs(common);
@@ -6142,14 +6947,14 @@ while (*cc != OP_KETRPOS)
if (framesize < 0)
{
- if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
+ if (offset != 0)
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)
+ if (offset != 0)
{
/* Last alternative. */
if (*cc == OP_KETRPOS)
@@ -6168,6 +6973,8 @@ while (*cc != OP_KETRPOS)
ccbegin = cc + 1 + LINK_SIZE;
}
+/* We don't have to restore the control head in case of a failed match. */
+
backtrack->topbacktracks = NULL;
if (!zero)
{
@@ -6179,11 +6986,11 @@ if (!zero)
/* None of them matched. */
set_jumps(emptymatch, LABEL());
-decrease_call_count(common);
+count_match(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)
+static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end)
{
int class_len;
@@ -6219,7 +7026,7 @@ else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
}
else
{
- SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
+ SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
*type = *opcode;
cc++;
class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
@@ -6230,18 +7037,24 @@ else
if (end != NULL)
*end = cc + class_len;
}
+ else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
+ {
+ *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
+ 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);
+ SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
+ *max = GET2(cc, (class_len + IMM2_SIZE));
+ *min = GET2(cc, class_len);
- if (*arg2 == 0)
+ if (*min == 0)
{
- SLJIT_ASSERT(*arg1 != 0);
- *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
+ SLJIT_ASSERT(*max != 0);
+ *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
}
- if (*arg1 == *arg2)
+ if (*max == *min)
*opcode = OP_EXACT;
if (end != NULL)
@@ -6252,7 +7065,7 @@ else
if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
{
- *arg1 = GET2(cc, 0);
+ *max = GET2(cc, 0);
cc += IMM2_SIZE;
}
@@ -6281,7 +7094,7 @@ DEFINE_COMPILER;
backtrack_common *backtrack;
pcre_uchar opcode;
pcre_uchar type;
-int arg1 = -1, arg2 = -1;
+int max = -1, min = -1;
pcre_uchar* end;
jump_list *nomatch = NULL;
struct sljit_jump *jump = NULL;
@@ -6294,9 +7107,9 @@ int tmp_base, tmp_offset;
PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
-cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
+cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
-switch (type)
+switch(type)
{
case OP_NOT_DIGIT:
case OP_DIGIT:
@@ -6365,10 +7178,10 @@ switch(opcode)
{
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);
+ if (opcode == OP_CRRANGE && min > 0)
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
+ if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
+ jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
}
@@ -6395,7 +7208,7 @@ switch(opcode)
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
if (opcode <= OP_PLUS)
JUMPTO(SLJIT_JUMP, label);
- else if (opcode == OP_CRRANGE && arg1 == 0)
+ else if (opcode == OP_CRRANGE && max == 0)
{
OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
JUMPTO(SLJIT_JUMP, label);
@@ -6405,11 +7218,11 @@ switch(opcode)
OP1(SLJIT_MOV, TMP1, 0, base, offset1);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV, base, offset1, TMP1, 0);
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label);
}
set_jumps(nomatch, LABEL());
if (opcode == OP_CRRANGE)
- add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
+ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, min + 1));
OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
}
BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
@@ -6447,7 +7260,7 @@ switch(opcode)
break;
case OP_EXACT:
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
label = LABEL();
compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
@@ -6460,7 +7273,7 @@ switch(opcode)
if (opcode == OP_POSPLUS)
compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
if (opcode == OP_POSUPTO)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max);
OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
label = LABEL();
compile_char1_matchingpath(common, type, cc, &nomatch);
@@ -6484,12 +7297,40 @@ switch(opcode)
OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
break;
+ case OP_CRPOSRANGE:
+ /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
+ OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, label);
+
+ if (max != 0)
+ {
+ SLJIT_ASSERT(max - min > 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max - min);
+ }
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &nomatch);
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ if (max == 0)
+ JUMPTO(SLJIT_JUMP, label);
+ else
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_C_NOT_ZERO, label);
+ }
+ set_jumps(nomatch, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
+ break;
+
default:
SLJIT_ASSERT_STOP();
break;
}
-decrease_call_count(common);
+count_match(common);
return end;
}
@@ -6498,7 +7339,7 @@ static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common
DEFINE_COMPILER;
backtrack_common *backtrack;
-PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
if (*cc == OP_FAIL)
{
@@ -6509,30 +7350,30 @@ if (*cc == OP_FAIL)
if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
{
/* No need to check notempty conditions. */
- if (common->acceptlabel == NULL)
+ if (common->accept_label == NULL)
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
else
- JUMPTO(SLJIT_JUMP, common->acceptlabel);
+ JUMPTO(SLJIT_JUMP, common->accept_label);
return cc + 1;
}
-if (common->acceptlabel == NULL)
+if (common->accept_label == 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);
+ CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->accept_label);
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
add_jump(compiler, &backtrack->topbacktracks, 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)
+if (common->accept_label == 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);
+ CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
-if (common->acceptlabel == NULL)
+if (common->accept_label == 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);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
return cc + 1;
}
@@ -6556,10 +7397,86 @@ if (!optimized_cbracket)
return cc + 1 + IMM2_SIZE;
}
+static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+pcre_uchar opcode = *cc;
+pcre_uchar *ccend = cc + 1;
+
+if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
+ ccend += 2 + cc[1];
+
+PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
+
+if (opcode == OP_SKIP)
+ {
+ allocate_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
+ return ccend;
+ }
+
+if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ }
+
+return ccend;
+}
+
+static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
+
+static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
+{
+DEFINE_COMPILER;
+backtrack_common *backtrack;
+BOOL needs_control_head;
+int size;
+
+PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
+common->then_trap = BACKTRACK_AS(then_trap_backtrack);
+BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
+BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
+BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
+
+size = BACKTRACK_AS(then_trap_backtrack)->framesize;
+size = 3 + (size < 0 ? 0 : size);
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+allocate_stack(common, size);
+if (size > 3)
+ OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
+else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
+OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
+
+size = BACKTRACK_AS(then_trap_backtrack)->framesize;
+if (size >= 0)
+ init_frame(common, cc, ccend, size - 1, 0, FALSE);
+}
+
static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
{
DEFINE_COMPILER;
backtrack_common *backtrack;
+BOOL has_then_trap = FALSE;
+then_trap_backtrack *save_then_trap = NULL;
+
+SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
+
+if (common->has_then && common->then_offsets[cc - common->start] != 0)
+ {
+ SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
+ has_then_trap = TRUE;
+ save_then_trap = common->then_trap;
+ /* Tail item on backtrack. */
+ compile_then_trap_matchingpath(common, cc, ccend, parent);
+ }
while (cc < ccend)
{
@@ -6685,7 +7602,7 @@ while (cc < ccend)
case OP_CLASS:
case OP_NCLASS:
- if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
+ if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)
cc = compile_iterator_matchingpath(common, cc, parent);
else
cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
@@ -6693,7 +7610,7 @@ while (cc < ccend)
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
case OP_XCLASS:
- if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
+ if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
cc = compile_iterator_matchingpath(common, cc, parent);
else
cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
@@ -6702,16 +7619,35 @@ while (cc < ccend)
case OP_REF:
case OP_REFI:
- if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
+ if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
cc = compile_ref_iterator_matchingpath(common, cc, parent);
else
- cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ {
+ compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ cc += 1 + IMM2_SIZE;
+ }
+ break;
+
+ case OP_DNREF:
+ case OP_DNREFI:
+ if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
+ cc = compile_ref_iterator_matchingpath(common, cc, parent);
+ else
+ {
+ compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
+ compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
+ cc += 1 + 2 * IMM2_SIZE;
+ }
break;
case OP_RECURSE:
cc = compile_recurse_matchingpath(common, cc, parent);
break;
+ case OP_CALLOUT:
+ cc = compile_callout_matchingpath(common, cc, parent);
+ break;
+
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
@@ -6736,7 +7672,7 @@ while (cc < ccend)
}
BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
if (cc[1] > OP_ASSERTBACK_NOT)
- decrease_call_count(common);
+ count_match(common);
break;
case OP_ONCE:
@@ -6772,18 +7708,32 @@ while (cc < ccend)
PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
SLJIT_ASSERT(common->mark_ptr != 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
- allocate_stack(common, 1);
+ allocate_stack(common, common->has_skip_arg ? 5 : 1);
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ if (common->has_skip_arg)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
+ }
cc += 1 + 2 + cc[1];
break;
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ case OP_THEN:
+ case OP_THEN_ARG:
case OP_COMMIT:
- PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
- cc += 1;
+ cc = compile_control_verb_matchingpath(common, cc, parent);
break;
case OP_FAIL:
@@ -6807,6 +7757,15 @@ while (cc < ccend)
if (cc == NULL)
return;
}
+
+if (has_then_trap)
+ {
+ /* Head item on backtrack. */
+ PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
+ BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
+ BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
+ common->then_trap = save_then_trap;
+ }
SLJIT_ASSERT(cc == ccend);
}
@@ -6831,7 +7790,7 @@ DEFINE_COMPILER;
pcre_uchar *cc = current->cc;
pcre_uchar opcode;
pcre_uchar type;
-int arg1 = -1, arg2 = -1;
+int max = -1, min = -1;
struct sljit_label *label = NULL;
struct sljit_jump *jump = NULL;
jump_list *jumplist = NULL;
@@ -6840,7 +7799,7 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LO
int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
-cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
+cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL);
switch(opcode)
{
@@ -6859,7 +7818,7 @@ switch(opcode)
else
{
if (opcode == OP_UPTO)
- arg2 = 0;
+ min = 0;
if (opcode <= OP_PLUS)
{
OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
@@ -6869,7 +7828,7 @@ switch(opcode)
{
OP1(SLJIT_MOV, TMP1, 0, base, offset1);
OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
+ jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1);
OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
}
skip_char_back(common);
@@ -6914,12 +7873,12 @@ switch(opcode)
OP1(SLJIT_MOV, base, offset1, TMP1, 0);
if (opcode == OP_CRMINRANGE)
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label);
- if (opcode == OP_CRMINRANGE && arg1 == 0)
+ if (opcode == OP_CRMINRANGE && max == 0)
JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
else
- CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
+ CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
set_jumps(jumplist, LABEL());
if (private_data_ptr == 0)
@@ -6954,6 +7913,7 @@ switch(opcode)
case OP_EXACT:
case OP_POSPLUS:
+ case OP_CRPOSRANGE:
set_jumps(current->topbacktracks, LABEL());
break;
@@ -6968,15 +7928,18 @@ switch(opcode)
}
}
-static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
pcre_uchar *cc = current->cc;
+BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
pcre_uchar type;
-type = cc[1 + IMM2_SIZE];
+type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
+
if ((type & 0x1) == 0)
{
+ /* Maximize case. */
set_jumps(current->topbacktracks, LABEL());
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 1);
@@ -6987,14 +7950,18 @@ if ((type & 0x1) == 0)
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_backtrack)->matchingpath);
set_jumps(current->topbacktracks, LABEL());
-free_stack(common, 2);
+free_stack(common, ref ? 2 : 3);
}
-static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
+if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
+ compile_backtrackingpath(common, current->top);
set_jumps(current->topbacktracks, LABEL());
+if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
+ return;
if (common->has_set_som && common->mark_ptr != 0)
{
@@ -7082,11 +8049,10 @@ if (bra == OP_BRAZERO)
static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
-int opcode;
+int opcode, stacksize, count;
int offset = 0;
int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
-int stacksize;
-int count;
+int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
pcre_uchar *cc = current->cc;
pcre_uchar *ccbegin;
pcre_uchar *ccprev;
@@ -7096,10 +8062,12 @@ pcre_uchar bra = OP_BRA;
pcre_uchar ket;
assert_backtrack *assert;
BOOL has_alternatives;
+BOOL needs_control_head = FALSE;
struct sljit_jump *brazero = NULL;
struct sljit_jump *once = NULL;
struct sljit_jump *cond = NULL;
-struct sljit_label *rminlabel = NULL;
+struct sljit_label *rmin_label = NULL;
+struct sljit_label *exact_label = NULL;
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
{
@@ -7108,8 +8076,20 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
}
opcode = *cc;
+ccbegin = bracketend(cc) - 1 - LINK_SIZE;
+ket = *ccbegin;
+if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
+ {
+ repeat_ptr = PRIVATE_DATA(ccbegin);
+ repeat_type = PRIVATE_DATA(ccbegin + 2);
+ repeat_count = PRIVATE_DATA(ccbegin + 3);
+ SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
+ if (repeat_type == OP_UPTO)
+ ket = OP_KETRMAX;
+ if (repeat_type == OP_MINUPTO)
+ ket = OP_KETRMIN;
+ }
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))
@@ -7121,6 +8101,24 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN
if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
opcode = OP_ONCE;
+/* Decoding the needs_control_head in framesize. */
+if (opcode == OP_ONCE)
+ {
+ needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
+ CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
+ }
+
+if (ket != OP_KET && repeat_type != 0)
+ {
+ /* TMP1 is used in OP_KETRMIN below. */
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, 1);
+ if (repeat_type == OP_UPTO)
+ OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
+ }
+
if (ket == OP_KETRMAX)
{
if (bra == OP_BRAZERO)
@@ -7135,7 +8133,15 @@ 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)
+ if (repeat_type != 0)
+ {
+ /* TMP1 was set a few lines above. */
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
+ /* Drop STR_PTR for non-greedy plus quantifier. */
+ if (opcode != OP_ONCE)
+ free_stack(common, 1);
+ }
+ else if (opcode >= OP_SBRA || opcode == OP_ONCE)
{
/* Checking zero-length iteration. */
if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
@@ -7145,13 +8151,16 @@ else if (ket == OP_KETRMIN)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
}
+ /* Drop STR_PTR for non-greedy plus quantifier. */
if (opcode != OP_ONCE)
free_stack(common, 1);
}
else
JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
}
- rminlabel = LABEL();
+ rmin_label = LABEL();
+ if (repeat_type != 0)
+ OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
}
else if (bra == OP_BRAZERO)
{
@@ -7159,6 +8168,34 @@ else if (bra == OP_BRAZERO)
free_stack(common, 1);
brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
}
+else if (repeat_type == OP_EXACT)
+ {
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
+ exact_label = LABEL();
+ }
+
+if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ {
+ SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
+ 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), common->capture_last_ptr, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
+ free_stack(common, 3);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
+ }
+ else if (common->optimized_cbracket[offset >> 1] == 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
+ 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);
+ }
+ }
if (SLJIT_UNLIKELY(opcode == OP_ONCE))
{
@@ -7255,67 +8292,63 @@ if (has_alternatives)
current->top = NULL;
current->topbacktracks = NULL;
current->nextbacktracks = NULL;
+ /* Conditional blocks always have an additional alternative, even if it is empty. */
if (*cc == OP_ALT)
{
ccprev = cc + 1 + LINK_SIZE;
cc += GET(cc, 1);
if (opcode != OP_COND && opcode != OP_SCOND)
{
- if (private_data_ptr != 0 && opcode != OP_ONCE)
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ if (opcode != OP_ONCE)
+ {
+ if (private_data_ptr != 0)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ }
else
- OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
}
compile_matchingpath(common, ccprev, cc, current);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
return;
}
- /* Instructions after the current alternative is succesfully matched. */
+ /* Instructions after the current alternative is successfully matched. */
/* There is a similar code in compile_bracket_matchingpath. */
if (opcode == OP_ONCE)
- {
- if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
- {
- OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
- /* 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 private_data_ptr. */
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
- }
- }
- else
- {
- OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw));
- 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));
- }
- }
- }
+ match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
stacksize = 0;
- if (opcode != OP_ONCE)
+ if (repeat_type == OP_MINUPTO)
+ {
+ /* We need to preserve the counter. TMP2 will be used below. */
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
stacksize++;
+ }
if (ket != OP_KET || bra != OP_BRA)
stacksize++;
+ if (offset != 0)
+ {
+ if (common->capture_last_ptr != 0)
+ stacksize++;
+ if (common->optimized_cbracket[offset >> 1] == 0)
+ stacksize += 2;
+ }
+ if (opcode != OP_ONCE)
+ stacksize++;
- if (stacksize > 0) {
- if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->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_sw));
- }
- }
+ if (stacksize > 0)
+ allocate_stack(common, stacksize);
stacksize = 0;
+ if (repeat_type == OP_MINUPTO)
+ {
+ /* TMP2 was set above. */
+ OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
+ stacksize++;
+ }
+
if (ket != OP_KET || bra != OP_BRA)
{
if (ket != OP_KET)
@@ -7325,14 +8358,17 @@ if (has_alternatives)
stacksize++;
}
+ if (offset != 0)
+ stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
+
if (opcode != OP_ONCE)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
- if (offset != 0)
+ if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
{
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
+ /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
+ SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
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_backtrack)->alternative_matchingpath);
@@ -7357,7 +8393,6 @@ if (has_alternatives)
SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
assert = CURRENT_AS(bracket_backtrack)->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->private_data_ptr);
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
@@ -7374,23 +8409,19 @@ if (has_alternatives)
if (offset != 0)
{
/* Using both tmp register is better for instruction scheduling. */
- if (common->optimized_cbracket[offset >> 1] == 0)
+ if (common->optimized_cbracket[offset >> 1] != 0)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
+ free_stack(common, 2);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
- free_stack(common, 3);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
}
else
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
- free_stack(common, 2);
- 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);
+ free_stack(common, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
}
}
else if (opcode == OP_SBRA || opcode == OP_SCOND)
@@ -7401,17 +8432,19 @@ else if (opcode == OP_SBRA || opcode == OP_SCOND)
else if (opcode == OP_ONCE)
{
cc = ccbegin + GET(ccbegin, 1);
+ stacksize = needs_control_head ? 1 : 0;
+
if (CURRENT_AS(bracket_backtrack)->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_backtrack)->u.framesize + stacksize);
+ stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
}
else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
{
/* The STR_PTR must be released. */
- free_stack(common, 1);
+ stacksize++;
}
+ free_stack(common, stacksize);
JUMPHERE(once);
/* Restore previous private_data_ptr */
@@ -7426,11 +8459,18 @@ else if (opcode == OP_ONCE)
}
}
-if (ket == OP_KETRMAX)
+if (repeat_type == OP_EXACT)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
+ CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
+ }
+else if (ket == OP_KETRMAX)
{
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
if (bra != OP_BRAZERO)
free_stack(common, 1);
+
CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
if (bra == OP_BRAZERO)
{
@@ -7449,7 +8489,7 @@ else if (ket == OP_KETRMIN)
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);
+ CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
if (opcode == OP_ONCE)
free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
else if (bra == OP_BRAMINZERO)
@@ -7463,7 +8503,7 @@ else if (bra == OP_BRAZERO)
}
}
-static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
int offset;
@@ -7477,7 +8517,11 @@ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
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);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
+ if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
}
set_jumps(current->topbacktracks, LABEL());
free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
@@ -7498,7 +8542,7 @@ if (current->topbacktracks)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
}
-static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
assert_backtrack backtrack;
@@ -7522,9 +8566,103 @@ else
SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
}
+static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+pcre_uchar opcode = *current->cc;
+struct sljit_label *loop;
+struct sljit_jump *jump;
+
+if (opcode == OP_THEN || opcode == OP_THEN_ARG)
+ {
+ if (common->then_trap != NULL)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
+ jump = JUMP(SLJIT_JUMP);
+
+ loop = LABEL();
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
+ JUMPHERE(jump);
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
+ add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
+ return;
+ }
+ else if (common->positive_assert)
+ {
+ add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
+ return;
+ }
+ }
+
+if (common->local_exit)
+ {
+ if (common->quit_label == NULL)
+ add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+ else
+ JUMPTO(SLJIT_JUMP, common->quit_label);
+ return;
+ }
+
+if (opcode == OP_SKIP_ARG)
+ {
+ SLJIT_ASSERT(common->control_head_ptr != 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
+ sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
+
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
+ return;
+ }
+
+if (opcode == OP_SKIP)
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+else
+ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
+add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
+}
+
+static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+int size;
+
+if (CURRENT_AS(then_trap_backtrack)->then_trap)
+ {
+ common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
+ return;
+ }
+
+size = CURRENT_AS(then_trap_backtrack)->framesize;
+size = 3 + (size < 0 ? 0 : size);
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
+free_stack(common, size);
+jump = JUMP(SLJIT_JUMP);
+
+set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
+/* STACK_TOP is set by THEN. */
+if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+free_stack(common, 3);
+
+JUMPHERE(jump);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
+}
+
static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
{
DEFINE_COMPILER;
+then_trap_backtrack *save_then_trap = common->then_trap;
while (current)
{
@@ -7613,6 +8751,8 @@ while (current)
case OP_REF:
case OP_REFI:
+ case OP_DNREF:
+ case OP_DNREFI:
compile_ref_iterator_backtrackingpath(common, current);
break;
@@ -7658,31 +8798,52 @@ while (current)
break;
case OP_MARK:
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
- free_stack(common, 1);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
+ if (common->has_skip_arg)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
+ free_stack(common, common->has_skip_arg ? 5 : 1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
+ if (common->has_skip_arg)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
+ break;
+
+ case OP_THEN:
+ case OP_THEN_ARG:
+ case OP_PRUNE:
+ case OP_PRUNE_ARG:
+ case OP_SKIP:
+ case OP_SKIP_ARG:
+ compile_control_verb_backtrackingpath(common, current);
break;
case OP_COMMIT:
- OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
- if (common->quitlabel == NULL)
+ if (!common->local_exit)
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+ if (common->quit_label == NULL)
add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
else
- JUMPTO(SLJIT_JUMP, common->quitlabel);
+ JUMPTO(SLJIT_JUMP, common->quit_label);
break;
+ case OP_CALLOUT:
case OP_FAIL:
case OP_ACCEPT:
case OP_ASSERT_ACCEPT:
set_jumps(current->topbacktracks, LABEL());
break;
+ case OP_THEN_TRAP:
+ /* A virtual opcode for then traps. */
+ compile_then_trap_backtrackingpath(common, current);
+ break;
+
default:
SLJIT_ASSERT_STOP();
break;
}
current = current->prev;
}
+common->then_trap = save_then_trap;
}
static SLJIT_INLINE void compile_recurse(compiler_common *common)
@@ -7691,39 +8852,43 @@ 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 private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
-int framesize = get_framesize(common, cc, TRUE);
+BOOL needs_control_head;
+int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
+int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
int alternativesize;
-BOOL needsframe;
+BOOL needs_frame;
backtrack_common altbacktrack;
-struct sljit_label *save_quitlabel = common->quitlabel;
-jump_list *save_quit = common->quit;
struct sljit_jump *jump;
+/* Recurse captures then. */
+common->then_trap = NULL;
+
SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
-needsframe = framesize >= 0;
-if (!needsframe)
+needs_frame = framesize >= 0;
+if (!needs_frame)
framesize = 0;
alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
-SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
+SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
common->currententry->entry = LABEL();
set_jumps(common->currententry->calls, common->currententry->entry);
sljit_emit_fast_enter(compiler, TMP2, 0);
allocate_stack(common, private_data_size + framesize + alternativesize);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
-copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
-if (needsframe)
- init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
+copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
+if (needs_control_head)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
+if (needs_frame)
+ init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
if (alternativesize > 0)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
memset(&altbacktrack, 0, sizeof(backtrack_common));
-common->quitlabel = NULL;
-common->acceptlabel = NULL;
+common->quit_label = NULL;
+common->accept_label = NULL;
common->quit = NULL;
common->accept = NULL;
altbacktrack.cc = ccbegin;
@@ -7738,21 +8903,13 @@ while (1)
compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->quitlabel = save_quitlabel;
- common->quit = save_quit;
return;
- }
add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
compile_backtrackingpath(common, altbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- {
- common->quitlabel = save_quitlabel;
- common->quit = save_quit;
return;
- }
set_jumps(altbacktrack.topbacktracks, LABEL());
if (*cc != OP_ALT)
@@ -7761,16 +8918,29 @@ while (1)
altbacktrack.cc = cc + 1 + LINK_SIZE;
cc += GET(cc, 1);
}
-/* None of them matched. */
-if (common->quit != NULL)
- set_jumps(common->quit, LABEL());
+/* None of them matched. */
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
jump = JUMP(SLJIT_JUMP);
+if (common->quit != NULL)
+ {
+ set_jumps(common->quit, LABEL());
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
+ if (needs_frame)
+ {
+ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
+ OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
+ }
+ OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
+ common->quit = NULL;
+ add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
+ }
+
set_jumps(common->accept, LABEL());
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
-if (needsframe)
+OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
+if (needs_frame)
{
OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
@@ -7779,15 +8949,25 @@ if (needsframe)
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
JUMPHERE(jump);
-copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);
+if (common->quit != NULL)
+ set_jumps(common->quit, LABEL());
+copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
free_stack(common, private_data_size + framesize + alternativesize);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
-OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
+if (needs_control_head)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
+ }
+else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
+ OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
+ }
sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
-
-common->quitlabel = save_quitlabel;
-common->quit = save_quit;
}
#undef COMPILE_BACKTRACKINGPATH
@@ -7807,12 +8987,16 @@ pcre_uchar *ccend;
executable_functions *functions;
void *executable_func;
sljit_uw executable_size;
-struct sljit_label *mainloop = NULL;
-struct sljit_label *empty_match_found;
-struct sljit_label *empty_match_backtrack;
+struct sljit_label *mainloop_label = NULL;
+struct sljit_label *continue_match_label;
+struct sljit_label *empty_match_found_label;
+struct sljit_label *empty_match_backtrack_label;
+struct sljit_label *reset_match_label;
struct sljit_jump *jump;
+struct sljit_jump *minlength_check_failed = NULL;
struct sljit_jump *reqbyte_notfound = NULL;
struct sljit_jump *empty_match;
+struct sljit_label *quit_label;
SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
study = extra->study_data;
@@ -7863,7 +9047,7 @@ else
common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
common->ctypes = (sljit_sw)(tables + ctypes_offset);
common->digits[0] = -2;
-common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset);
+common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
common->name_count = re->name_count;
common->name_entry_size = re->name_entry_size;
common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
@@ -7877,15 +9061,22 @@ common->use_ucp = (re->options & PCRE_UCP) != 0;
ccend = bracketend(rootbacktrack.cc);
/* Calculate the local space size on the stack. */
-common->ovector_start = CALL_LIMIT + sizeof(sljit_sw);
+common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
if (!common->optimized_cbracket)
return;
+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
+memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+#else
memset(common->optimized_cbracket, 1, re->top_bracket + 1);
+#endif
SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
-private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
-if (private_data_size < 0)
+#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
+common->capture_last_ptr = common->ovector_start;
+common->ovector_start += sizeof(sljit_sw);
+#endif
+if (!check_opcode_types(common, rootbacktrack.cc, ccend))
{
SLJIT_FREE(common->optimized_cbracket);
return;
@@ -7904,7 +9095,12 @@ if (mode != JIT_COMPILE)
if (mode == JIT_PARTIAL_SOFT_COMPILE)
{
common->hit_start = common->ovector_start;
- common->ovector_start += sizeof(sljit_sw);
+ common->ovector_start += 2 * sizeof(sljit_sw);
+ }
+ else
+ {
+ SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
+ common->needs_start_ptr = TRUE;
}
}
if ((re->options & PCRE_FIRSTLINE) != 0)
@@ -7912,33 +9108,74 @@ if ((re->options & PCRE_FIRSTLINE) != 0)
common->first_line_end = common->ovector_start;
common->ovector_start += sizeof(sljit_sw);
}
+#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
+common->control_head_ptr = 1;
+#endif
+if (common->control_head_ptr != 0)
+ {
+ common->control_head_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+if (common->needs_start_ptr && common->has_set_som)
+ {
+ /* Saving the real start pointer is necessary. */
+ common->start_ptr = common->ovector_start;
+ common->ovector_start += sizeof(sljit_sw);
+ }
+else
+ common->needs_start_ptr = FALSE;
/* Aligning ovector to even number of sljit words. */
if ((common->ovector_start & sizeof(sljit_sw)) != 0)
common->ovector_start += sizeof(sljit_sw);
+if (common->start_ptr == 0)
+ common->start_ptr = OVECTOR(0);
+
+/* Capturing brackets cannot be optimized if callouts are allowed. */
+if (common->capture_last_ptr != 0)
+ memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
-common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
-private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);
-if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
+common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
+
+common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
+if (!common->private_data_ptrs)
{
SLJIT_FREE(common->optimized_cbracket);
return;
}
-common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
-if (!common->private_data_ptrs)
+memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
+
+private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
+set_private_data_ptrs(common, &private_data_size, ccend);
+if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
{
+ SLJIT_FREE(common->private_data_ptrs);
SLJIT_FREE(common->optimized_cbracket);
return;
}
-memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
-set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
+
+if (common->has_then)
+ {
+ common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
+ if (!common->then_offsets)
+ {
+ SLJIT_FREE(common->optimized_cbracket);
+ SLJIT_FREE(common->private_data_ptrs);
+ return;
+ }
+ memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
+ set_then_offsets(common, rootbacktrack.cc, NULL);
+ }
compiler = sljit_create_compiler();
if (!compiler)
{
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
+ if (common->has_then)
+ SLJIT_FREE(common->then_offsets);
return;
}
common->compiler = compiler;
@@ -7956,18 +9193,23 @@ 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_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
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);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0);
if (mode == JIT_PARTIAL_SOFT_COMPILE)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
+if (common->control_head_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 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);
+ mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
+ continue_match_label = LABEL();
/* Forward search if possible. */
if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
{
@@ -7981,20 +9223,39 @@ if ((re->options & PCRE_ANCHORED) == 0)
fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
}
}
+else
+ continue_match_label = LABEL();
+
+if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
+ {
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
+ OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
+ minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0);
+ }
if (common->req_char_ptr != 0)
reqbyte_notfound = search_requested_char(common, (pcre_uchar)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);
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
+OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH);
+if (common->capture_last_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
+
+if (common->needs_start_ptr)
+ {
+ SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
+ }
+else
+ SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
+
/* Copy the beginning of the string. */
if (mode == JIT_PARTIAL_SOFT_COMPILE)
{
- jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
JUMPHERE(jump);
}
else if (mode == JIT_PARTIAL_HARD_COMPILE)
@@ -8006,46 +9267,55 @@ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
+ if (common->has_then)
+ SLJIT_FREE(common->then_offsets);
return;
}
empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
-empty_match_found = LABEL();
+empty_match_found_label = LABEL();
-common->acceptlabel = LABEL();
+common->accept_label = LABEL();
if (common->accept != NULL)
- set_jumps(common->accept, common->acceptlabel);
+ set_jumps(common->accept, common->accept_label);
/* This means we have a match. Update the ovector. */
copy_ovector(common, re->top_bracket + 1);
-common->quitlabel = LABEL();
+common->quit_label = common->forced_quit_label = LABEL();
if (common->quit != NULL)
- set_jumps(common->quit, common->quitlabel);
+ set_jumps(common->quit, common->quit_label);
+if (common->forced_quit != NULL)
+ set_jumps(common->forced_quit, common->forced_quit_label);
+if (minlength_check_failed != NULL)
+ SET_LABEL(minlength_check_failed, common->forced_quit_label);
sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
if (mode != JIT_COMPILE)
{
common->partialmatchlabel = LABEL();
set_jumps(common->partialmatch, common->partialmatchlabel);
- return_with_partial_match(common, common->quitlabel);
+ return_with_partial_match(common, common->quit_label);
}
-empty_match_backtrack = LABEL();
+empty_match_backtrack_label = LABEL();
compile_backtrackingpath(common, rootbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
{
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
+ if (common->has_then)
+ SLJIT_FREE(common->then_offsets);
return;
}
SLJIT_ASSERT(rootbacktrack.prev == NULL);
+reset_match_label = LABEL();
if (mode == JIT_PARTIAL_SOFT_COMPILE)
{
/* Update hit_start only in the first time. */
- jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
+ jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
@@ -8053,35 +9323,20 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE)
}
/* Check we have remaining characters. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
+if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
+ {
+ SLJIT_ASSERT(common->first_line_end != 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
+ }
+
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
if ((re->options & PCRE_ANCHORED) == 0)
{
if ((re->options & PCRE_FIRSTLINE) == 0)
- {
- if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
- {
- OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
- CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
- }
- else
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
- }
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
else
- {
- SLJIT_ASSERT(common->first_line_end != 0);
- if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
- {
- OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
- OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
- OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
- JUMPTO(SLJIT_C_ZERO, mainloop);
- }
- else
- CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
- }
+ CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
}
/* No more remaining characters. */
@@ -8089,24 +9344,26 @@ if (reqbyte_notfound != NULL)
JUMPHERE(reqbyte_notfound);
if (mode == JIT_PARTIAL_SOFT_COMPILE)
- CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
+ CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
-JUMPTO(SLJIT_JUMP, common->quitlabel);
+JUMPTO(SLJIT_JUMP, common->quit_label);
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_backtrack);
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
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);
+CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
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_backtrack);
+CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
+JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
common->currententry = common->entries;
+common->local_exit = TRUE;
+quit_label = common->quit_label;
while (common->currententry != NULL)
{
/* Might add new entries. */
@@ -8116,11 +9373,15 @@ while (common->currententry != NULL)
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
+ if (common->has_then)
+ SLJIT_FREE(common->then_offsets);
return;
}
flush_stubs(common);
common->currententry = common->currententry->next;
}
+common->local_exit = FALSE;
+common->quit_label = quit_label;
/* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
/* This is a (really) rare case. */
@@ -8146,12 +9407,12 @@ sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
JUMPHERE(jump);
/* 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, common->quitlabel);
+JUMPTO(SLJIT_JUMP, common->quit_label);
/* Call limit reached. */
set_jumps(common->calllimit, LABEL());
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
-JUMPTO(SLJIT_JUMP, common->quitlabel);
+JUMPTO(SLJIT_JUMP, common->quit_label);
if (common->revertframes != NULL)
{
@@ -8188,6 +9449,14 @@ if (common->caselesscmp != NULL)
set_jumps(common->caselesscmp, LABEL());
do_caselesscmp(common);
}
+if (common->reset_match != NULL)
+ {
+ set_jumps(common->reset_match, LABEL());
+ do_reset_match(common, (re->top_bracket + 1) * 2);
+ CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
+ JUMPTO(SLJIT_JUMP, reset_match_label);
+ }
#ifdef SUPPORT_UTF
#ifndef COMPILE_PCRE32
if (common->utfreadchar != NULL)
@@ -8214,6 +9483,9 @@ if (common->getucd != NULL)
SLJIT_FREE(common->optimized_cbracket);
SLJIT_FREE(common->private_data_ptrs);
+if (common->has_then)
+ SLJIT_FREE(common->then_offsets);
+
executable_func = sljit_generate_code(compiler);
executable_size = sljit_get_generated_code_size(compiler);
sljit_free_compiler(compiler);
@@ -8244,6 +9516,7 @@ else
}
memset(functions, 0, sizeof(executable_functions));
functions->top_bracket = (re->top_bracket + 1) * 2;
+ functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
extra->executable_jit = functions;
extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
}
@@ -8272,7 +9545,7 @@ return convert_executable_func.call_executable_func(arguments);
int
PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
- int length, int start_offset, int options, int *offsets, int offsetcount)
+ int length, int start_offset, int options, int *offsets, int offset_count)
{
executable_functions *functions = (executable_functions *)extra_data->executable_jit;
union {
@@ -8280,7 +9553,7 @@ union {
jit_function call_executable_func;
} convert_executable_func;
jit_arguments arguments;
-int maxoffsetcount;
+int max_offset_count;
int retval;
int mode = JIT_COMPILE;
@@ -8298,25 +9571,29 @@ arguments.begin = subject;
arguments.end = subject + length;
arguments.mark_ptr = NULL;
/* JIT decreases this value less frequently than the interpreter. */
-arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
+arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
+if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
+ arguments.limit_match = functions->limit_match;
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;
+arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
+arguments.real_offset_count = offset_count;
-/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
+/* pcre_exec() rounds offset_count 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 = functions->top_bracket;
-if (offsetcount > maxoffsetcount)
- offsetcount = maxoffsetcount;
-arguments.offsetcount = offsetcount;
+if (offset_count != 2)
+ offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
+max_offset_count = functions->top_bracket;
+if (offset_count > max_offset_count)
+ offset_count = max_offset_count;
+arguments.offset_count = offset_count;
if (functions->callback)
arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
@@ -8331,7 +9608,7 @@ else
retval = convert_executable_func.call_executable_func(&arguments);
}
-if (retval * 2 > offsetcount)
+if (retval * 2 > offset_count)
retval = 0;
if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
*(extra_data->mark) = arguments.mark_ptr;
@@ -8343,17 +9620,17 @@ return retval;
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
PCRE_SPTR subject, int length, int start_offset, int options,
- int *offsets, int offsetcount, pcre_jit_stack *stack)
+ int *offsets, int offset_count, pcre_jit_stack *stack)
#elif defined COMPILE_PCRE16
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
PCRE_SPTR16 subject, int length, int start_offset, int options,
- int *offsets, int offsetcount, pcre16_jit_stack *stack)
+ int *offsets, int offset_count, pcre16_jit_stack *stack)
#elif defined COMPILE_PCRE32
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
PCRE_SPTR32 subject, int length, int start_offset, int options,
- int *offsets, int offsetcount, pcre32_jit_stack *stack)
+ int *offsets, int offset_count, pcre32_jit_stack *stack)
#endif
{
pcre_uchar *subject_ptr = (pcre_uchar *)subject;
@@ -8363,7 +9640,7 @@ union {
jit_function call_executable_func;
} convert_executable_func;
jit_arguments arguments;
-int maxoffsetcount;
+int max_offset_count;
int retval;
int mode = JIT_COMPILE;
@@ -8387,30 +9664,34 @@ arguments.begin = subject_ptr;
arguments.end = subject_ptr + length;
arguments.mark_ptr = NULL;
/* JIT decreases this value less frequently than the interpreter. */
-arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
+arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
+if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
+ arguments.limit_match = functions->limit_match;
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;
+arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
+arguments.real_offset_count = offset_count;
-/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
+/* pcre_exec() rounds offset_count 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 = functions->top_bracket;
-if (offsetcount > maxoffsetcount)
- offsetcount = maxoffsetcount;
-arguments.offsetcount = offsetcount;
+if (offset_count != 2)
+ offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
+max_offset_count = functions->top_bracket;
+if (offset_count > max_offset_count)
+ offset_count = max_offset_count;
+arguments.offset_count = offset_count;
convert_executable_func.executable_func = functions->executable_funcs[mode];
retval = convert_executable_func.call_executable_func(&arguments);
-if (retval * 2 > offsetcount)
+if (retval * 2 > offset_count)
retval = 0;
if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
*(extra_data->mark) = arguments.mark_ptr;
@@ -8504,6 +9785,20 @@ if (extra != NULL &&
}
}
+#if defined COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_free_unused_memory(void)
+#elif defined COMPILE_PCRE16
+PCRE_EXP_DECL void
+pcre16_jit_free_unused_memory(void)
+#elif defined COMPILE_PCRE32
+PCRE_EXP_DECL void
+pcre32_jit_free_unused_memory(void)
+#endif
+{
+sljit_free_unused_memory_exec();
+}
+
#else /* SUPPORT_JIT */
/* These are dummy functions to avoid linking errors when JIT support is not
@@ -8555,6 +9850,19 @@ pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void
(void)userdata;
}
+#if defined COMPILE_PCRE8
+PCRE_EXP_DECL void
+pcre_jit_free_unused_memory(void)
+#elif defined COMPILE_PCRE16
+PCRE_EXP_DECL void
+pcre16_jit_free_unused_memory(void)
+#elif defined COMPILE_PCRE32
+PCRE_EXP_DECL void
+pcre32_jit_free_unused_memory(void)
+#endif
+{
+}
+
#endif
/* End of pcre_jit_compile.c */
diff --git a/src/3rdparty/pcre/pcre_maketables.c b/src/3rdparty/pcre/pcre_maketables.c
index de1ea65cf6..17a2625fa0 100644
--- a/src/3rdparty/pcre/pcre_maketables.c
+++ b/src/3rdparty/pcre/pcre_maketables.c
@@ -98,13 +98,17 @@ for (i = 0; i < 256; i++) *p++ = tolower(i);
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. */
+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:].
+From release 8.34 is is also correct for Perl space, because Perl added VT at
+release 5.18.
+
+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++)
@@ -123,14 +127,15 @@ for (i = 0; i < 256; i++)
}
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. */
+/* Finally, the character type table. In this, we used to exclude VT from the
+white space chars, because Perl didn't recognize it as such for \s and for
+comments within regexes. However, Perl changed at release 5.18, so PCRE changed
+at release 8.34. */
for (i = 0; i < 256; i++)
{
int x = 0;
- if (i != CHAR_VT && isspace(i)) x += ctype_space;
+ if (isspace(i)) x += ctype_space;
if (isalpha(i)) x += ctype_letter;
if (isdigit(i)) x += ctype_digit;
if (isxdigit(i)) x += ctype_xdigit;
diff --git a/src/3rdparty/pcre/pcre_string_utils.c b/src/3rdparty/pcre/pcre_string_utils.c
index a9b4e77c00..2601ce385a 100644
--- a/src/3rdparty/pcre/pcre_string_utils.c
+++ b/src/3rdparty/pcre/pcre_string_utils.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -38,8 +38,8 @@ 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(). */
+/* This module contains internal functions for comparing and finding the length
+of strings for different data item sizes. */
#ifdef PCRE_HAVE_CONFIG_H
@@ -54,7 +54,7 @@ class. It is used by both pcre_exec() and pcre_def_exec(). */
* Compare string utilities *
*************************************************/
-/* The following two functions compares two strings. Basically an strcmp
+/* The following two functions compares two strings. Basically a strcmp
for non 8 bit characters.
Arguments:
diff --git a/src/3rdparty/pcre/pcre_study.c b/src/3rdparty/pcre/pcre_study.c
index 6040e4dbdc..0478a00c1a 100644
--- a/src/3rdparty/pcre/pcre_study.c
+++ b/src/3rdparty/pcre/pcre_study.c
@@ -66,8 +66,9 @@ string of that length that matches. In UTF8 mode, the result is in characters
rather than bytes.
Arguments:
+ re compiled pattern block
code pointer to start of group (the bracket)
- startcode pointer to start of the whole pattern
+ startcode pointer to start of the whole pattern's code
options the compiling options
int RECURSE depth
@@ -78,8 +79,8 @@ Returns: the minimum length
*/
static int
-find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
- int recurse_depth)
+find_minlength(const REAL_PCRE *re, 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. */
@@ -129,7 +130,7 @@ for (;;)
case OP_SBRAPOS:
case OP_ONCE:
case OP_ONCE_NC:
- d = find_minlength(cc, startcode, options, recurse_depth);
+ d = find_minlength(re, cc, startcode, options, recurse_depth);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
@@ -175,9 +176,9 @@ for (;;)
case OP_REVERSE:
case OP_CREF:
- case OP_NCREF:
+ case OP_DNCREF:
case OP_RREF:
- case OP_NRREF:
+ case OP_DNRREF:
case OP_DEF:
case OP_CALLOUT:
case OP_SOD:
@@ -341,6 +342,7 @@ for (;;)
{
case OP_CRPLUS:
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
branchlength++;
/* Fall through */
@@ -348,11 +350,14 @@ for (;;)
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
cc++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
branchlength += GET2(cc,1);
cc += 1 + 2 * IMM2_SIZE;
break;
@@ -375,7 +380,38 @@ for (;;)
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_DNREF: /* Duplicate named pattern back reference */
+ case OP_DNREFI:
+ if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
+ {
+ int count = GET2(cc, 1+IMM2_SIZE);
+ pcre_uchar *slot = (pcre_uchar *)re +
+ re->name_table_offset + GET2(cc, 1) * re->name_entry_size;
+ d = INT_MAX;
+ while (count-- > 0)
+ {
+ ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0));
+ if (cs == NULL) return -2;
+ do ce += GET(ce, 1); while (*ce == OP_ALT);
+ if (cc > cs && cc < ce)
+ {
+ d = 0;
+ had_recurse = TRUE;
+ break;
+ }
+ else
+ {
+ int dd = find_minlength(re, cs, startcode, options, recurse_depth);
+ if (dd < d) d = dd;
+ }
+ slot += re->name_entry_size;
+ }
+ }
+ else d = 0;
+ cc += 1 + 2*IMM2_SIZE;
+ goto REPEAT_BACK_REFERENCE;
+
+ case OP_REF: /* Single back reference */
case OP_REFI:
if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
{
@@ -389,7 +425,7 @@ for (;;)
}
else
{
- d = find_minlength(cs, startcode, options, recurse_depth);
+ d = find_minlength(re, cs, startcode, options, recurse_depth);
}
}
else d = 0;
@@ -397,24 +433,29 @@ for (;;)
/* Handle repeated back references */
+ REPEAT_BACK_REFERENCE:
switch (*cc)
{
case OP_CRSTAR:
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
min = 0;
cc++;
break;
case OP_CRPLUS:
case OP_CRMINPLUS:
+ case OP_CRPOSPLUS:
min = 1;
cc++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
min = GET2(cc, 1);
cc += 1 + 2 * IMM2_SIZE;
break;
@@ -437,7 +478,8 @@ for (;;)
had_recurse = TRUE;
else
{
- branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
+ branchlength += find_minlength(re, cs, startcode, options,
+ recurse_depth + 1);
}
cc += 1 + LINK_SIZE;
break;
@@ -778,6 +820,10 @@ do
case OP_COND:
case OP_CREF:
case OP_DEF:
+ case OP_DNCREF:
+ case OP_DNREF:
+ case OP_DNREFI:
+ case OP_DNRREF:
case OP_DOLL:
case OP_DOLLM:
case OP_END:
@@ -786,7 +832,6 @@ do
case OP_EXTUNI:
case OP_FAIL:
case OP_MARK:
- case OP_NCREF:
case OP_NOT:
case OP_NOTEXACT:
case OP_NOTEXACTI:
@@ -818,7 +863,6 @@ do
case OP_NOTUPTOI:
case OP_NOT_HSPACE:
case OP_NOT_VSPACE:
- case OP_NRREF:
case OP_PROP:
case OP_PRUNE:
case OP_PRUNE_ARG:
@@ -1183,24 +1227,16 @@ do
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. Luckily, the code value is the
- same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate
- bit. */
+ /* The cbit_space table has vertical tab as whitespace; we no longer
+ have to play fancy tricks because Perl added VT to its whitespace at
+ release 5.18. PCRE added it at release 8.34. */
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. Luckily, the code value is the same (0x0b) in ASCII
- and EBCDIC, so we can just adjust the appropriate bit. */
-
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:
@@ -1277,11 +1313,14 @@ do
case OP_CRMINSTAR:
case OP_CRQUERY:
case OP_CRMINQUERY:
+ case OP_CRPOSSTAR:
+ case OP_CRPOSQUERY:
tcode++;
break;
case OP_CRRANGE:
case OP_CRMINRANGE:
+ case OP_CRPOSRANGE:
if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
else try_next = FALSE;
break;
@@ -1346,6 +1385,7 @@ 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)
@@ -1422,7 +1462,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
/* Find the minimum length of subject string. */
-switch(min = find_minlength(code, code, re->options, 0))
+switch(min = find_minlength(re, 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;
diff --git a/src/3rdparty/pcre/pcre_tables.c b/src/3rdparty/pcre/pcre_tables.c
index a50b87371c..c5e1d8059b 100644
--- a/src/3rdparty/pcre/pcre_tables.c
+++ b/src/3rdparty/pcre/pcre_tables.c
@@ -346,6 +346,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#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_Xuc0 STR_X STR_u STR_c "\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"
@@ -493,6 +494,7 @@ const char PRIV(utt_names)[] =
STRING_Xan0
STRING_Xps0
STRING_Xsp0
+ STRING_Xuc0
STRING_Xwd0
STRING_Yi0
STRING_Z0
@@ -640,12 +642,13 @@ const ucp_type_table PRIV(utt)[] = {
{ 1011, PT_ALNUM, 0 },
{ 1015, PT_PXSPACE, 0 },
{ 1019, PT_SPACE, 0 },
- { 1023, PT_WORD, 0 },
- { 1027, PT_SC, ucp_Yi },
- { 1030, PT_GC, ucp_Z },
- { 1032, PT_PC, ucp_Zl },
- { 1035, PT_PC, ucp_Zp },
- { 1038, PT_PC, ucp_Zs }
+ { 1023, PT_UCNC, 0 },
+ { 1027, PT_WORD, 0 },
+ { 1031, PT_SC, ucp_Yi },
+ { 1034, PT_GC, ucp_Z },
+ { 1036, PT_PC, ucp_Zl },
+ { 1039, PT_PC, ucp_Zp },
+ { 1042, PT_PC, ucp_Zs }
};
const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
diff --git a/src/3rdparty/pcre/pcre_ucd.c b/src/3rdparty/pcre/pcre_ucd.c
index 003f04d3d7..33041821fc 100644
--- a/src/3rdparty/pcre/pcre_ucd.c
+++ b/src/3rdparty/pcre/pcre_ucd.c
@@ -20,7 +20,7 @@ needed. */
/* Unicode character database. */
/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 65696 bytes, block size: 128. */
+/* Total size: 65688 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
@@ -79,7 +79,7 @@ const pcre_uint32 PRIV(ucd_caseless_sets)[] = {
#ifndef PCRE_INCLUDED
-const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
+const ucd_record PRIV(ucd_records)[] = { /* 5016 bytes, record size 8 */
{ 9, 0, 2, 0, 0, }, /* 0 */
{ 9, 0, 1, 0, 0, }, /* 1 */
{ 9, 0, 0, 0, 0, }, /* 2 */
@@ -422,7 +422,7 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
{ 37, 21, 12, 0, 0, }, /* 339 */
{ 37, 17, 12, 0, 0, }, /* 340 */
{ 37, 12, 3, 0, 0, }, /* 341 */
- { 37, 29, 12, 0, 0, }, /* 342 */
+ { 37, 1, 2, 0, 0, }, /* 342 */
{ 37, 13, 12, 0, 0, }, /* 343 */
{ 37, 7, 12, 0, 0, }, /* 344 */
{ 37, 6, 12, 0, 0, }, /* 345 */
@@ -598,116 +598,115 @@ const ucd_record PRIV(ucd_records)[] = { /* 5024 bytes, record size 8 */
{ 83, 10, 5, 0, 0, }, /* 515 */
{ 83, 7, 12, 0, 0, }, /* 516 */
{ 83, 21, 12, 0, 0, }, /* 517 */
- { 83, 6, 12, 0, 0, }, /* 518 */
- { 83, 13, 12, 0, 0, }, /* 519 */
- { 67, 7, 12, 0, 0, }, /* 520 */
- { 67, 12, 3, 0, 0, }, /* 521 */
- { 67, 10, 5, 0, 0, }, /* 522 */
- { 67, 13, 12, 0, 0, }, /* 523 */
- { 67, 21, 12, 0, 0, }, /* 524 */
- { 38, 6, 12, 0, 0, }, /* 525 */
- { 91, 7, 12, 0, 0, }, /* 526 */
- { 91, 12, 3, 0, 0, }, /* 527 */
- { 91, 6, 12, 0, 0, }, /* 528 */
- { 91, 21, 12, 0, 0, }, /* 529 */
- { 86, 7, 12, 0, 0, }, /* 530 */
- { 86, 10, 5, 0, 0, }, /* 531 */
- { 86, 12, 3, 0, 0, }, /* 532 */
- { 86, 21, 12, 0, 0, }, /* 533 */
- { 86, 6, 12, 0, 0, }, /* 534 */
- { 86, 13, 12, 0, 0, }, /* 535 */
- { 23, 7, 9, 0, 0, }, /* 536 */
- { 23, 7, 10, 0, 0, }, /* 537 */
- { 9, 4, 2, 0, 0, }, /* 538 */
- { 9, 3, 12, 0, 0, }, /* 539 */
- { 25, 25, 12, 0, 0, }, /* 540 */
- { 0, 24, 12, 0, 0, }, /* 541 */
- { 9, 6, 3, 0, 0, }, /* 542 */
- { 35, 7, 12, 0, 0, }, /* 543 */
- { 19, 14, 12, 0, 0, }, /* 544 */
- { 19, 15, 12, 0, 0, }, /* 545 */
- { 19, 26, 12, 0, 0, }, /* 546 */
- { 70, 7, 12, 0, 0, }, /* 547 */
- { 66, 7, 12, 0, 0, }, /* 548 */
- { 41, 7, 12, 0, 0, }, /* 549 */
- { 41, 15, 12, 0, 0, }, /* 550 */
- { 18, 7, 12, 0, 0, }, /* 551 */
- { 18, 14, 12, 0, 0, }, /* 552 */
- { 59, 7, 12, 0, 0, }, /* 553 */
- { 59, 21, 12, 0, 0, }, /* 554 */
- { 42, 7, 12, 0, 0, }, /* 555 */
- { 42, 21, 12, 0, 0, }, /* 556 */
- { 42, 14, 12, 0, 0, }, /* 557 */
- { 13, 9, 12, 0, 40, }, /* 558 */
- { 13, 5, 12, 0, -40, }, /* 559 */
- { 46, 7, 12, 0, 0, }, /* 560 */
- { 44, 7, 12, 0, 0, }, /* 561 */
- { 44, 13, 12, 0, 0, }, /* 562 */
- { 11, 7, 12, 0, 0, }, /* 563 */
- { 80, 7, 12, 0, 0, }, /* 564 */
- { 80, 21, 12, 0, 0, }, /* 565 */
- { 80, 15, 12, 0, 0, }, /* 566 */
- { 65, 7, 12, 0, 0, }, /* 567 */
- { 65, 15, 12, 0, 0, }, /* 568 */
- { 65, 21, 12, 0, 0, }, /* 569 */
- { 71, 7, 12, 0, 0, }, /* 570 */
- { 71, 21, 12, 0, 0, }, /* 571 */
- { 97, 7, 12, 0, 0, }, /* 572 */
- { 96, 7, 12, 0, 0, }, /* 573 */
- { 30, 7, 12, 0, 0, }, /* 574 */
- { 30, 12, 3, 0, 0, }, /* 575 */
- { 30, 15, 12, 0, 0, }, /* 576 */
- { 30, 21, 12, 0, 0, }, /* 577 */
- { 87, 7, 12, 0, 0, }, /* 578 */
- { 87, 15, 12, 0, 0, }, /* 579 */
- { 87, 21, 12, 0, 0, }, /* 580 */
- { 77, 7, 12, 0, 0, }, /* 581 */
- { 77, 21, 12, 0, 0, }, /* 582 */
- { 82, 7, 12, 0, 0, }, /* 583 */
- { 82, 15, 12, 0, 0, }, /* 584 */
- { 81, 7, 12, 0, 0, }, /* 585 */
- { 81, 15, 12, 0, 0, }, /* 586 */
- { 88, 7, 12, 0, 0, }, /* 587 */
- { 0, 15, 12, 0, 0, }, /* 588 */
- { 93, 10, 5, 0, 0, }, /* 589 */
- { 93, 12, 3, 0, 0, }, /* 590 */
- { 93, 7, 12, 0, 0, }, /* 591 */
- { 93, 21, 12, 0, 0, }, /* 592 */
- { 93, 15, 12, 0, 0, }, /* 593 */
- { 93, 13, 12, 0, 0, }, /* 594 */
- { 84, 12, 3, 0, 0, }, /* 595 */
- { 84, 10, 5, 0, 0, }, /* 596 */
- { 84, 7, 12, 0, 0, }, /* 597 */
- { 84, 21, 12, 0, 0, }, /* 598 */
- { 84, 1, 2, 0, 0, }, /* 599 */
- { 100, 7, 12, 0, 0, }, /* 600 */
- { 100, 13, 12, 0, 0, }, /* 601 */
- { 95, 12, 3, 0, 0, }, /* 602 */
- { 95, 7, 12, 0, 0, }, /* 603 */
- { 95, 10, 5, 0, 0, }, /* 604 */
- { 95, 13, 12, 0, 0, }, /* 605 */
- { 95, 21, 12, 0, 0, }, /* 606 */
- { 99, 12, 3, 0, 0, }, /* 607 */
- { 99, 10, 5, 0, 0, }, /* 608 */
- { 99, 7, 12, 0, 0, }, /* 609 */
- { 99, 21, 12, 0, 0, }, /* 610 */
- { 99, 13, 12, 0, 0, }, /* 611 */
- { 101, 7, 12, 0, 0, }, /* 612 */
- { 101, 12, 3, 0, 0, }, /* 613 */
- { 101, 10, 5, 0, 0, }, /* 614 */
- { 101, 13, 12, 0, 0, }, /* 615 */
- { 62, 7, 12, 0, 0, }, /* 616 */
- { 62, 14, 12, 0, 0, }, /* 617 */
- { 62, 21, 12, 0, 0, }, /* 618 */
- { 79, 7, 12, 0, 0, }, /* 619 */
- { 98, 7, 12, 0, 0, }, /* 620 */
- { 98, 10, 5, 0, 0, }, /* 621 */
- { 98, 12, 3, 0, 0, }, /* 622 */
- { 98, 6, 12, 0, 0, }, /* 623 */
- { 9, 10, 3, 0, 0, }, /* 624 */
- { 19, 12, 3, 0, 0, }, /* 625 */
- { 9, 26, 11, 0, 0, }, /* 626 */
- { 26, 26, 12, 0, 0, }, /* 627 */
+ { 83, 13, 12, 0, 0, }, /* 518 */
+ { 67, 7, 12, 0, 0, }, /* 519 */
+ { 67, 12, 3, 0, 0, }, /* 520 */
+ { 67, 10, 5, 0, 0, }, /* 521 */
+ { 67, 13, 12, 0, 0, }, /* 522 */
+ { 67, 21, 12, 0, 0, }, /* 523 */
+ { 38, 6, 12, 0, 0, }, /* 524 */
+ { 91, 7, 12, 0, 0, }, /* 525 */
+ { 91, 12, 3, 0, 0, }, /* 526 */
+ { 91, 6, 12, 0, 0, }, /* 527 */
+ { 91, 21, 12, 0, 0, }, /* 528 */
+ { 86, 7, 12, 0, 0, }, /* 529 */
+ { 86, 10, 5, 0, 0, }, /* 530 */
+ { 86, 12, 3, 0, 0, }, /* 531 */
+ { 86, 21, 12, 0, 0, }, /* 532 */
+ { 86, 6, 12, 0, 0, }, /* 533 */
+ { 86, 13, 12, 0, 0, }, /* 534 */
+ { 23, 7, 9, 0, 0, }, /* 535 */
+ { 23, 7, 10, 0, 0, }, /* 536 */
+ { 9, 4, 2, 0, 0, }, /* 537 */
+ { 9, 3, 12, 0, 0, }, /* 538 */
+ { 25, 25, 12, 0, 0, }, /* 539 */
+ { 0, 24, 12, 0, 0, }, /* 540 */
+ { 9, 6, 3, 0, 0, }, /* 541 */
+ { 35, 7, 12, 0, 0, }, /* 542 */
+ { 19, 14, 12, 0, 0, }, /* 543 */
+ { 19, 15, 12, 0, 0, }, /* 544 */
+ { 19, 26, 12, 0, 0, }, /* 545 */
+ { 70, 7, 12, 0, 0, }, /* 546 */
+ { 66, 7, 12, 0, 0, }, /* 547 */
+ { 41, 7, 12, 0, 0, }, /* 548 */
+ { 41, 15, 12, 0, 0, }, /* 549 */
+ { 18, 7, 12, 0, 0, }, /* 550 */
+ { 18, 14, 12, 0, 0, }, /* 551 */
+ { 59, 7, 12, 0, 0, }, /* 552 */
+ { 59, 21, 12, 0, 0, }, /* 553 */
+ { 42, 7, 12, 0, 0, }, /* 554 */
+ { 42, 21, 12, 0, 0, }, /* 555 */
+ { 42, 14, 12, 0, 0, }, /* 556 */
+ { 13, 9, 12, 0, 40, }, /* 557 */
+ { 13, 5, 12, 0, -40, }, /* 558 */
+ { 46, 7, 12, 0, 0, }, /* 559 */
+ { 44, 7, 12, 0, 0, }, /* 560 */
+ { 44, 13, 12, 0, 0, }, /* 561 */
+ { 11, 7, 12, 0, 0, }, /* 562 */
+ { 80, 7, 12, 0, 0, }, /* 563 */
+ { 80, 21, 12, 0, 0, }, /* 564 */
+ { 80, 15, 12, 0, 0, }, /* 565 */
+ { 65, 7, 12, 0, 0, }, /* 566 */
+ { 65, 15, 12, 0, 0, }, /* 567 */
+ { 65, 21, 12, 0, 0, }, /* 568 */
+ { 71, 7, 12, 0, 0, }, /* 569 */
+ { 71, 21, 12, 0, 0, }, /* 570 */
+ { 97, 7, 12, 0, 0, }, /* 571 */
+ { 96, 7, 12, 0, 0, }, /* 572 */
+ { 30, 7, 12, 0, 0, }, /* 573 */
+ { 30, 12, 3, 0, 0, }, /* 574 */
+ { 30, 15, 12, 0, 0, }, /* 575 */
+ { 30, 21, 12, 0, 0, }, /* 576 */
+ { 87, 7, 12, 0, 0, }, /* 577 */
+ { 87, 15, 12, 0, 0, }, /* 578 */
+ { 87, 21, 12, 0, 0, }, /* 579 */
+ { 77, 7, 12, 0, 0, }, /* 580 */
+ { 77, 21, 12, 0, 0, }, /* 581 */
+ { 82, 7, 12, 0, 0, }, /* 582 */
+ { 82, 15, 12, 0, 0, }, /* 583 */
+ { 81, 7, 12, 0, 0, }, /* 584 */
+ { 81, 15, 12, 0, 0, }, /* 585 */
+ { 88, 7, 12, 0, 0, }, /* 586 */
+ { 0, 15, 12, 0, 0, }, /* 587 */
+ { 93, 10, 5, 0, 0, }, /* 588 */
+ { 93, 12, 3, 0, 0, }, /* 589 */
+ { 93, 7, 12, 0, 0, }, /* 590 */
+ { 93, 21, 12, 0, 0, }, /* 591 */
+ { 93, 15, 12, 0, 0, }, /* 592 */
+ { 93, 13, 12, 0, 0, }, /* 593 */
+ { 84, 12, 3, 0, 0, }, /* 594 */
+ { 84, 10, 5, 0, 0, }, /* 595 */
+ { 84, 7, 12, 0, 0, }, /* 596 */
+ { 84, 21, 12, 0, 0, }, /* 597 */
+ { 84, 1, 2, 0, 0, }, /* 598 */
+ { 100, 7, 12, 0, 0, }, /* 599 */
+ { 100, 13, 12, 0, 0, }, /* 600 */
+ { 95, 12, 3, 0, 0, }, /* 601 */
+ { 95, 7, 12, 0, 0, }, /* 602 */
+ { 95, 10, 5, 0, 0, }, /* 603 */
+ { 95, 13, 12, 0, 0, }, /* 604 */
+ { 95, 21, 12, 0, 0, }, /* 605 */
+ { 99, 12, 3, 0, 0, }, /* 606 */
+ { 99, 10, 5, 0, 0, }, /* 607 */
+ { 99, 7, 12, 0, 0, }, /* 608 */
+ { 99, 21, 12, 0, 0, }, /* 609 */
+ { 99, 13, 12, 0, 0, }, /* 610 */
+ { 101, 7, 12, 0, 0, }, /* 611 */
+ { 101, 12, 3, 0, 0, }, /* 612 */
+ { 101, 10, 5, 0, 0, }, /* 613 */
+ { 101, 13, 12, 0, 0, }, /* 614 */
+ { 62, 7, 12, 0, 0, }, /* 615 */
+ { 62, 14, 12, 0, 0, }, /* 616 */
+ { 62, 21, 12, 0, 0, }, /* 617 */
+ { 79, 7, 12, 0, 0, }, /* 618 */
+ { 98, 7, 12, 0, 0, }, /* 619 */
+ { 98, 10, 5, 0, 0, }, /* 620 */
+ { 98, 12, 3, 0, 0, }, /* 621 */
+ { 98, 6, 12, 0, 0, }, /* 622 */
+ { 9, 10, 3, 0, 0, }, /* 623 */
+ { 19, 12, 3, 0, 0, }, /* 624 */
+ { 9, 26, 11, 0, 0, }, /* 625 */
+ { 26, 26, 12, 0, 0, }, /* 626 */
};
const pcre_uint8 PRIV(ucd_stage1)[] = { /* 8704 bytes */
@@ -1380,7 +1379,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 12 */
185,185,185,185,185,109,186,186,186,187,187,188, 4,187,189,189,
-190,190,190,190,190,190,190,190,190,190,190, 4,109,109,187, 4,
+190,190,190,190,190,190,190,190,190,190,190, 4,185,109,187, 4,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
102,191,191,191,191,191,191,191,191,191,191,104,104,104,104,104,
@@ -1760,7 +1759,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 50 */
360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
-360,360,360,360,360,360,360,361,361,362,362,362,109,109,363,363,
+360,360,360,360,360,360,360,361,361,362,362,361,109,109,363,363,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,364,
@@ -1885,7 +1884,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
4, 4, 4, 4, 4, 4, 4, 4, 4, 21, 25, 4, 4, 4, 4, 15,
15, 4, 4, 4, 8, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3,
- 22, 22, 22, 22, 22,426,426,426,426,426, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22,426, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
23,101,109,109, 23, 23, 23, 23, 23, 23, 8, 8, 8, 6, 7,101,
/* block 63 */
@@ -1929,7 +1928,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
/* block 67 */
- 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
8, 8, 19, 19, 19, 19, 19, 19, 19, 6, 7, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
@@ -2353,30 +2352,30 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,516,
516,516,516,514,515,515,514,514,514,514,515,515,514,515,515,515,
-515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,518,
-519,519,519,519,519,519,519,519,519,519,109,109,109,109,517,517,
+515,517,517,517,517,517,517,517,517,517,517,517,517,517,109,102,
+518,518,518,518,518,518,518,518,518,518,109,109,109,109,517,517,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 110 */
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,521,521,521,521,521,521,522,
-522,521,521,522,522,521,521,109,109,109,109,109,109,109,109,109,
-520,520,520,521,520,520,520,520,520,520,520,520,521,522,109,109,
-523,523,523,523,523,523,523,523,523,523,109,109,524,524,524,524,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
+519,519,519,519,519,519,519,519,519,520,520,520,520,520,520,521,
+521,520,520,521,521,520,520,109,109,109,109,109,109,109,109,109,
+519,519,519,520,519,519,519,519,519,519,519,519,520,521,109,109,
+522,522,522,522,522,522,522,522,522,522,109,109,523,523,523,523,
295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,
-525,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109,
+524,295,295,295,295,295,295,301,301,301,295,296,109,109,109,109,
/* block 111 */
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,
-527,526,527,527,527,526,526,527,527,526,526,526,526,526,527,527,
-526,527,526,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,526,526,528,529,529,
-530,530,530,530,530,530,530,530,530,530,530,531,532,532,531,531,
-533,533,530,534,534,531,532,109,109,109,109,109,109,109,109,109,
+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,
+526,525,526,526,526,525,525,526,526,525,525,525,525,525,526,526,
+525,526,525,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,525,525,527,528,528,
+529,529,529,529,529,529,529,529,529,529,529,530,531,531,530,530,
+532,532,529,533,533,530,531,109,109,109,109,109,109,109,109,109,
/* block 112 */
109,308,308,308,308,308,308,109,109,308,308,308,308,308,308,109,
@@ -2393,85 +2392,85 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
-530,530,530,531,531,532,531,531,532,531,531,533,531,532,109,109,
-535,535,535,535,535,535,535,535,535,535,109,109,109,109,109,109,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,530,530,531,530,530,531,530,530,532,530,531,109,109,
+534,534,534,534,534,534,534,534,534,534,109,109,109,109,109,109,
/* block 114 */
-536,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,536,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,536,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,536,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,
-536,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 115 */
-537,537,537,537,537,537,537,537,537,537,537,537,536,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,536,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,536,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,
-536,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,536,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
/* block 116 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,536,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,536,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,
-536,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,536,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 117 */
-537,537,537,537,537,537,537,537,536,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,536,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,
-536,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,536,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,536,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
/* block 118 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-537,537,537,537,536,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,
-536,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,536,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,536,537,537,537,537,537,537,537,
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 119 */
-537,537,537,537,536,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,
-536,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,536,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,536,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,536,537,537,537,537,537,537,537,537,537,537,537,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
/* block 120 */
-537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,537,
-536,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,536,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,536,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,536,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,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+535,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,535,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,535,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
/* block 121 */
-537,537,537,537,537,537,537,537,536,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,109,109,109,109,109,109,109,109,109,109,109,109,
+536,536,536,536,536,536,536,536,535,536,536,536,536,536,536,536,
+536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,536,
+536,536,536,536,109,109,109,109,109,109,109,109,109,109,109,109,
306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,306,
306,306,306,306,306,306,306,109,109,109,109,307,307,307,307,307,
307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,
@@ -2479,6 +2478,16 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
307,307,307,307,307,307,307,307,307,307,307,307,109,109,109,109,
/* block 122 */
+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 123 */
538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
@@ -2488,16 +2497,6 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-/* block 123 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-
/* block 124 */
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,
@@ -2521,7 +2520,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 126 */
33, 33, 33, 33, 33, 33, 33,109,109,109,109,109,109,109,109,109,
109,109,109,178,178,178,178,178,109,109,109,109,109,184,181,184,
-184,184,184,184,184,184,184,184,184,540,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,539,184,184,184,184,184,184,
184,184,184,184,184,184,184,109,184,184,184,184,184,109,184,109,
184,184,109,184,184,109,184,184,184,184,184,184,184,184,184,184,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
@@ -2532,8 +2531,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
-191,191,541,541,541,541,541,541,541,541,541,541,541,541,541,541,
-541,541,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+191,191,540,540,540,540,540,540,540,540,540,540,540,540,540,540,
+540,540,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
@@ -2600,7 +2599,7 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
/* block 134 */
469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,469,
-469,469,469,469,469,469,469,469,469,469,469,469,469,469,542,542,
+469,469,469,469,469,469,469,469,469,469,469,469,469,469,541,541,
472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,
472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,109,
109,109,472,472,472,472,472,472,109,109,472,472,472,472,472,472,
@@ -2609,37 +2608,37 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
426,426,426,426,426,426,426,426,426, 22, 22, 22, 19, 19,109,109,
/* block 135 */
-543,543,543,543,543,543,543,543,543,543,543,543,109,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,109,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,543,543,109,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,109,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,109,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,109,542,542,109,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 136 */
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,109,109,109,109,109,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,542,
+542,542,542,542,542,542,542,542,542,542,542,109,109,109,109,109,
/* block 137 */
4, 4, 4,109,109,109,109, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23,109,109,109, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,
-544,544,544,544,544,545,545,545,545,546,546,546,546,546,546,546,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+543,543,543,543,543,544,544,544,544,545,545,545,545,545,545,545,
/* block 138 */
-546,546,546,546,546,546,546,546,546,546,545,109,109,109,109,109,
+545,545,545,545,545,545,545,545,545,545,544,109,109,109,109,109,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2649,49 +2648,49 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,104,109,109,
/* block 139 */
+546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
+546,546,546,546,546,546,546,546,546,546,546,546,546,109,109,109,
547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
-547,547,547,547,547,547,547,547,547,547,547,547,547,109,109,109,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
-548,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 140 */
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,
-549,549,549,549,549,549,549,549,549,549,549,549,549,549,549,109,
-550,550,550,550,109,109,109,109,109,109,109,109,109,109,109,109,
-551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,
-551,552,551,551,551,551,551,551,551,551,552,109,109,109,109,109,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,109,
+549,549,549,549,109,109,109,109,109,109,109,109,109,109,109,109,
+550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,550,
+550,551,550,550,550,550,550,550,550,550,551,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 141 */
-553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,
-553,553,553,553,553,553,553,553,553,553,553,553,553,553,109,554,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,555,
-555,555,555,555,109,109,109,109,555,555,555,555,555,555,555,555,
-556,557,557,557,557,557,109,109,109,109,109,109,109,109,109,109,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,109,553,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,109,109,109,109,554,554,554,554,554,554,554,554,
+555,556,556,556,556,556,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 142 */
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,
+557,557,557,557,557,557,557,557,558,558,558,558,558,558,558,558,
558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,
-558,558,558,558,558,558,558,558,559,559,559,559,559,559,559,559,
559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
-560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,
/* block 143 */
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,561,
-561,561,561,561,561,561,561,561,561,561,561,561,561,561,109,109,
-562,562,562,562,562,562,562,562,562,562,109,109,109,109,109,109,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,
+560,560,560,560,560,560,560,560,560,560,560,560,560,560,109,109,
+561,561,561,561,561,561,561,561,561,561,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2699,61 +2698,61 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 144 */
-563,563,563,563,563,563,109,109,563,109,563,563,563,563,563,563,
+562,562,562,562,562,562,109,109,562,109,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,
+562,562,562,562,562,562,109,562,562,109,109,109,562,109,109,562,
563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,109,563,563,109,109,109,563,109,109,563,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,109,565,566,566,566,566,566,566,566,566,
+563,563,563,563,563,563,109,564,565,565,565,565,565,565,565,565,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 145 */
-567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,
-567,567,567,567,567,567,568,568,568,568,568,568,109,109,109,569,
-570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,570,
-570,570,570,570,570,570,570,570,570,570,109,109,109,109,109,571,
+566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,566,
+566,566,566,566,566,566,567,567,567,567,567,567,109,109,109,568,
+569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+569,569,569,569,569,569,569,569,569,569,109,109,109,109,109,570,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 146 */
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
+571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-573,573,573,573,573,573,573,573,109,109,109,109,109,109,573,573,
+572,572,572,572,572,572,572,572,109,109,109,109,109,109,572,572,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 147 */
-574,575,575,575,109,575,575,109,109,109,109,109,575,575,575,575,
-574,574,574,574,109,574,574,574,109,574,574,574,574,574,574,574,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
-574,574,574,574,109,109,109,109,575,575,575,109,109,109,109,575,
-576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,109,
-577,577,577,577,577,577,577,577,577,109,109,109,109,109,109,109,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,579,579,580,
+573,574,574,574,109,574,574,109,109,109,109,109,574,574,574,574,
+573,573,573,573,109,573,573,573,109,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,109,109,109,109,574,574,574,109,109,109,109,574,
+575,575,575,575,575,575,575,575,109,109,109,109,109,109,109,109,
+576,576,576,576,576,576,576,576,576,109,109,109,109,109,109,109,
+577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
+577,577,577,577,577,577,577,577,577,577,577,577,577,578,578,579,
/* block 148 */
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,109,109,109,582,582,582,582,582,582,582,
-583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
-583,583,583,583,583,583,109,109,584,584,584,584,584,584,584,584,
-585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
-585,585,585,109,109,109,109,109,586,586,586,586,586,586,586,586,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,109,109,109,581,581,581,581,581,581,581,
+582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,
+582,582,582,582,582,582,109,109,583,583,583,583,583,583,583,583,
+584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+584,584,584,109,109,109,109,109,585,585,585,585,585,585,585,585,
/* block 149 */
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
-587,587,587,587,587,587,587,587,587,109,109,109,109,109,109,109,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2765,103 +2764,103 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,
-588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,109,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,109,
/* block 151 */
-589,590,589,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,
-591,591,591,591,591,591,591,591,590,590,590,590,590,590,590,590,
-590,590,590,590,590,590,590,592,592,592,592,592,592,592,109,109,
-109,109,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
-593,593,593,593,593,593,594,594,594,594,594,594,594,594,594,594,
+588,589,588,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,591,591,591,591,591,591,591,109,109,
+109,109,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
+592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 152 */
-595,595,596,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,
-596,596,596,595,595,595,595,596,596,595,595,598,598,599,598,598,
-598,598,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,
-600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,109,
-601,601,601,601,601,601,601,601,601,601,109,109,109,109,109,109,
+594,594,595,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,
+595,595,595,594,594,594,594,595,595,594,594,597,597,598,597,597,
+597,597,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,599,
+599,599,599,599,599,599,599,599,599,109,109,109,109,109,109,109,
+600,600,600,600,600,600,600,600,600,600,109,109,109,109,109,109,
/* block 153 */
-602,602,602,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,603,
-603,603,603,603,603,603,603,602,602,602,602,602,604,602,602,602,
-602,602,602,602,602,109,605,605,605,605,605,605,605,605,605,605,
-606,606,606,606,109,109,109,109,109,109,109,109,109,109,109,109,
+601,601,601,602,602,602,602,602,602,602,602,602,602,602,602,602,
+602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,
+602,602,602,602,602,602,602,601,601,601,601,601,603,601,601,601,
+601,601,601,601,601,109,604,604,604,604,604,604,604,604,604,604,
+605,605,605,605,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 154 */
-607,607,608,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,
-609,609,609,608,608,608,607,607,607,607,607,607,607,607,607,608,
-608,609,609,609,609,610,610,610,610,109,109,109,109,109,109,109,
-611,611,611,611,611,611,611,611,611,611,109,109,109,109,109,109,
+606,606,607,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,608,
+608,608,608,607,607,607,606,606,606,606,606,606,606,606,606,607,
+607,608,608,608,608,609,609,609,609,109,109,109,109,109,109,109,
+610,610,610,610,610,610,610,610,610,610,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 155 */
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,612,
-612,612,612,612,612,612,612,612,612,612,612,613,614,613,614,614,
-613,613,613,613,613,613,614,613,109,109,109,109,109,109,109,109,
-615,615,615,615,615,615,615,615,615,615,109,109,109,109,109,109,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,
+611,611,611,611,611,611,611,611,611,611,611,612,613,612,613,613,
+612,612,612,612,612,612,613,612,109,109,109,109,109,109,109,109,
+614,614,614,614,614,614,614,614,614,614,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 156 */
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
/* block 157 */
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,
+615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+
+/* block 158 */
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,616,616,616,616,616,616,616,616,616,616,616,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-
-/* block 158 */
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,109,
-618,618,618,618,109,109,109,109,109,109,109,109,109,109,109,109,
+616,616,616,109,109,109,109,109,109,109,109,109,109,109,109,109,
+617,617,617,617,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 159 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
/* block 160 */
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
-619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,109,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,
+618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2889,18 +2888,18 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 163 */
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,619,619,109,109,109,109,109,109,109,109,109,109,109,
+619,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,
-620,620,620,620,620,109,109,109,109,109,109,109,109,109,109,109,
-620,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,
-621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,109,
+620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,109,
/* block 164 */
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,622,
-622,622,622,623,623,623,623,623,623,623,623,623,623,623,623,623,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,621,
+621,621,621,622,622,622,622,622,622,622,622,622,622,622,622,622,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -2935,8 +2934,8 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
- 19, 19, 19, 19, 19,624,395,104,104,104, 19, 19, 19,395,624,624,
-624,624,624, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104,
+ 19, 19, 19, 19, 19,623,395,104,104,104, 19, 19, 19,395,623,623,
+623,623,623, 22, 22, 22, 22, 22, 22, 22, 22,104,104,104,104,104,
/* block 168 */
104,104,104, 19, 19,104,104,104,104,104,104,104, 19, 19, 19, 19,
@@ -2949,11 +2948,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
/* block 169 */
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,546,
-546,546,625,625,625,546,109,109,109,109,109,109,109,109,109,109,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+545,545,624,624,624,545,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
@@ -3105,11 +3104,11 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,626,626,626,626,626,626,626,626,626,626,
-626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,
+109,109,109,109,109,109,625,625,625,625,625,625,625,625,625,625,
+625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,
/* block 185 */
-627, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,
+626, 19, 19,109,109,109,109,109,109,109,109,109,109,109,109,109,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,109,109,109,109,109,
@@ -3279,14 +3278,14 @@ const pcre_uint16 PRIV(ucd_stage2)[] = { /* 51968 bytes, block = 128 */
426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
/* block 202 */
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,109,109,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
+538,538,538,538,538,538,538,538,538,538,538,538,538,538,109,109,
};
diff --git a/src/3rdparty/pcre/pcre_valid_utf8.c b/src/3rdparty/pcre/pcre_valid_utf8.c
index e5b533467d..1cf0a14710 100644
--- a/src/3rdparty/pcre/pcre_valid_utf8.c
+++ b/src/3rdparty/pcre/pcre_valid_utf8.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -92,7 +92,7 @@ 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
-PCRE_UTF8_ERR22 Non-character
+PCRE_UTF8_ERR22 Unused (was non-character)
Arguments:
string points to the string
@@ -118,7 +118,6 @@ if (length < 0)
for (p = string; length-- > 0; p++)
{
register pcre_uchar ab, c, d;
- pcre_uint32 v = 0;
c = *p;
if (c < 128) continue; /* ASCII character */
@@ -187,7 +186,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 2;
return PCRE_UTF8_ERR14;
}
- v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f);
break;
/* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
@@ -215,7 +213,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 3;
return PCRE_UTF8_ERR13;
}
- v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f);
break;
/* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
@@ -290,14 +287,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - ab;
return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
}
-
- /* Reject non-characters. The pointer p is currently at the last byte of the
- character. */
- if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef))
- {
- *erroroffset = (int)(p - string) - ab;
- return PCRE_UTF8_ERR22;
- }
}
#else /* Not SUPPORT_UTF */
diff --git a/src/3rdparty/pcre/pcre_xclass.c b/src/3rdparty/pcre/pcre_xclass.c
index 595cafb2aa..dce8580a3d 100644
--- a/src/3rdparty/pcre/pcre_xclass.c
+++ b/src/3rdparty/pcre/pcre_xclass.c
@@ -6,7 +6,7 @@
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
+ Copyright (c) 1997-2013 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -128,55 +128,120 @@ while ((t = *data++) != XCL_END)
else /* XCL_PROP & XCL_NOTPROP */
{
const ucd_record *prop = GET_UCD(c);
+ BOOL isprop = t == XCL_PROP;
switch(*data)
{
case PT_ANY:
- if (t == XCL_PROP) return !negated;
+ if (isprop) return !negated;
break;
case PT_LAMP:
if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
- prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
+ prop->chartype == ucp_Lt) == isprop) return !negated;
break;
case PT_GC:
- if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
+ if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)
return !negated;
break;
case PT_PC:
- if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
+ if ((data[1] == prop->chartype) == isprop) return !negated;
break;
case PT_SC:
- if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
+ if ((data[1] == prop->script) == isprop) return !negated;
break;
case PT_ALNUM:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
- PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
+ PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
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;
+ /* Perl space used to exclude VT, but from Perl 5.18 it is included,
+ which means that Perl space and POSIX space are now identical. PCRE
+ was changed at release 8.34. */
+ case PT_SPACE: /* Perl space */
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;
+ switch(c)
+ {
+ HSPACE_CASES:
+ VSPACE_CASES:
+ if (isprop) return !negated;
+ break;
+
+ default:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)
+ return !negated;
+ break;
+ }
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))
+ == isprop)
+ return !negated;
+ break;
+
+ case PT_UCNC:
+ if (c < 0xa0)
+ {
+ if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
+ c == CHAR_GRAVE_ACCENT) == isprop)
+ return !negated;
+ }
+ else
+ {
+ if ((c < 0xd800 || c > 0xdfff) == isprop)
+ return !negated;
+ }
+ break;
+
+ /* The following three properties can occur only in an XCLASS, as there
+ is no \p or \P coding for them. */
+
+ /* Graphic character. Implement this as not Z (space or separator) and
+ not C (other), except for Cf (format) with a few exceptions. This seems
+ to be what Perl does. The exceptional characters are:
+
+ U+061C Arabic Letter Mark
+ U+180E Mongolian Vowel Separator
+ U+2066 - U+2069 Various "isolate"s
+ */
+
+ case PT_PXGRAPH:
+ if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Printable character: same as graphic, with the addition of Zs, i.e.
+ not Zl and not Zp, and U+180E. */
+
+ case PT_PXPRINT:
+ if ((prop->chartype != ucp_Zl &&
+ prop->chartype != ucp_Zp &&
+ (PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
+ (prop->chartype == ucp_Cf &&
+ c != 0x061c && (c < 0x2066 || c > 0x2069))
+ )) == isprop)
+ return !negated;
+ break;
+
+ /* Punctuation: all Unicode punctuation, plus ASCII characters that
+ Unicode treats as symbols rather than punctuation, for Perl
+ compatibility (these are $+<=>^`|~). */
+
+ case PT_PXPUNCT:
+ if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
+ (c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
return !negated;
break;
diff --git a/src/3rdparty/pcre/sljit/sljitConfig.h b/src/3rdparty/pcre/sljit/sljitConfig.h
index 68bc59d089..4f0fe4463a 100644
--- a/src/3rdparty/pcre/sljit/sljitConfig.h
+++ b/src/3rdparty/pcre/sljit/sljitConfig.h
@@ -48,6 +48,7 @@
/* #define SLJIT_CONFIG_PPC_64 1 */
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_SPARC_32 1 */
+/* #define SLJIT_CONFIG_TILEGX 1 */
/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
diff --git a/src/3rdparty/pcre/sljit/sljitConfigInternal.h b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
index bc945fbcab..af455df063 100644
--- a/src/3rdparty/pcre/sljit/sljitConfigInternal.h
+++ b/src/3rdparty/pcre/sljit/sljitConfigInternal.h
@@ -63,6 +63,7 @@
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
|| (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
|| (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
#error "An architecture must be selected"
@@ -76,6 +77,7 @@
+ (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_TILEGX && SLJIT_CONFIG_TILEGX) \
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
@@ -104,10 +106,12 @@
#define SLJIT_CONFIG_PPC_64 1
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
#define SLJIT_CONFIG_PPC_32 1
-#elif defined(__mips__)
+#elif defined(__mips__) && !defined(_LP64)
#define SLJIT_CONFIG_MIPS_32 1
#elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1
+#elif defined(__tilegx__)
+#define SLJIT_CONFIG_TILEGX 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
@@ -173,9 +177,13 @@
#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
#ifndef SLJIT_INLINE
-/* Inline functions. */
+/* Inline functions. Some old compilers do not support them. */
+#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510
+#define SLJIT_INLINE
+#else
#define SLJIT_INLINE __inline
#endif
+#endif /* !SLJIT_INLINE */
#ifndef SLJIT_CONST
/* Const variables. */
@@ -266,7 +274,9 @@ typedef signed int sljit_si;
#define SLJIT_WORD_SHIFT 0
typedef unsigned long int sljit_uw;
typedef long int sljit_sw;
-#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
#define SLJIT_32BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 2
typedef unsigned int sljit_uw;
@@ -311,7 +321,7 @@ typedef double sljit_d;
/* ABI (Application Binary Interface) types. */
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#if defined(__GNUC__)
+#if defined(__GNUC__) && !defined(__APPLE__)
#define SLJIT_CALL __attribute__ ((fastcall))
#define SLJIT_X86_32_FASTCALL 1
@@ -420,6 +430,7 @@ typedef double sljit_d;
#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);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
#endif
diff --git a/src/3rdparty/pcre/sljit/sljitExecAllocator.c b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
index 75a38991d5..f24ed33797 100644
--- a/src/3rdparty/pcre/sljit/sljitExecAllocator.c
+++ b/src/3rdparty/pcre/sljit/sljitExecAllocator.c
@@ -287,3 +287,26 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
allocator_release_lock();
}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
+{
+ struct free_block* free_block;
+ struct free_block* next_free_block;
+
+ allocator_grab_lock();
+
+ free_block = free_blocks;
+ while (free_block) {
+ next_free_block = free_block->next;
+ if (!free_block->header.prev_size &&
+ AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
+ total_size -= free_block->size;
+ sljit_remove_free_block(free_block);
+ free_chunk(free_block, free_block->size + sizeof(struct block_header));
+ }
+ free_block = next_free_block;
+ }
+
+ SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+ allocator_release_lock();
+}
diff --git a/src/3rdparty/pcre/sljit/sljitLir.c b/src/3rdparty/pcre/sljit/sljitLir.c
index 6979841070..53d208a69d 100644
--- a/src/3rdparty/pcre/sljit/sljitLir.c
+++ b/src/3rdparty/pcre/sljit/sljitLir.c
@@ -170,6 +170,14 @@
# define FCSR_FCC 33
#endif
+#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+# define IS_JAL 0x04
+# define IS_COND 0x08
+
+# define PATCH_B 0x10
+# define PATCH_J 0x20
+#endif
+
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
# define IS_MOVABLE 0x04
# define IS_COND 0x08
@@ -652,14 +660,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
}
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"
+ (char*)"unused", (char*)"s1", (char*)"s2", (char*)"s3",
+ (char*)"se1", (char*)"se2", (char*)"p1", (char*)"p2",
+ (char*)"p3", (char*)"pe1", (char*)"pe2", (char*)"lc"
};
static char* freg_names[] = {
- (char*)"<noreg>", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3",
- (char*)"float_r4", (char*)"float_r5", (char*)"float_r6"
+ (char*)"unused", (char*)"f1", (char*)"f2", (char*)"f3",
+ (char*)"f4", (char*)"f5", (char*)"f6"
};
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -736,17 +744,17 @@ static SLJIT_CONST char* op_names[] = {
};
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_unordered", (char*)"c_float_ordered",
+ (char*)"equal", (char*)"not_equal",
+ (char*)"less", (char*)"greater_equal",
+ (char*)"greater", (char*)"less_equal",
+ (char*)"sig_less", (char*)"sig_greater_equal",
+ (char*)"sig_greater", (char*)"sig_less_equal",
+ (char*)"overflow", (char*)"not_overflow",
+ (char*)"mul_overflow", (char*)"mul_not_overflow",
+ (char*)"float_equal", (char*)"float_not_equal",
+ (char*)"float_less", (char*)"float_greater_equal",
+ (char*)"float_greater", (char*)"float_less_equal",
+ (char*)"float_unordered", (char*)"float_ordered",
(char*)"jump", (char*)"fast_call",
(char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
};
@@ -993,6 +1001,12 @@ static SLJIT_INLINE void check_sljit_get_register_index(sljit_si reg)
SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS);
}
+static SLJIT_INLINE void check_sljit_get_float_register_index(sljit_si reg)
+{
+ SLJIT_UNUSED_ARG(reg);
+ SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_FLOAT_REGISTERS);
+}
+
static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
@@ -1104,7 +1118,7 @@ static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler,
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]);
+ fprintf(compiler->verbose, " jump%s.%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
#endif
}
@@ -1127,7 +1141,7 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s
#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]);
+ 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);
@@ -1156,7 +1170,7 @@ static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler,
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
+ fprintf(compiler->verbose, " %scmp%s.%s ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
sljit_verbose_fparam(src1, src1w);
fprintf(compiler->verbose, ", ");
@@ -1187,7 +1201,7 @@ static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler,
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " ijump<%s> ", jump_names[type]);
+ fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
sljit_verbose_param(src, srcw);
fprintf(compiler->verbose, "\n");
}
@@ -1223,14 +1237,14 @@ static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compil
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i",
+ fprintf(compiler->verbose, " %sflags.%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i",
op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
sljit_verbose_param(dst, dstw);
if (src != SLJIT_UNUSED) {
fprintf(compiler->verbose, ", ");
sljit_verbose_param(src, srcw);
}
- fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
+ fprintf(compiler->verbose, ", %s\n", jump_names[type]);
}
#endif
}
@@ -1339,6 +1353,8 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi
# include "sljitNativeMIPS_common.c"
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
# include "sljitNativeSPARC_common.c"
+#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+# include "sljitNativeTILEGX.c"
#endif
#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
diff --git a/src/3rdparty/pcre/sljit/sljitLir.h b/src/3rdparty/pcre/sljit/sljitLir.h
index 3171d1557c..920689d2ec 100644
--- a/src/3rdparty/pcre/sljit/sljitLir.h
+++ b/src/3rdparty/pcre/sljit/sljitLir.h
@@ -77,7 +77,7 @@
#endif
/* The following header file defines useful macros for fine tuning
-sljit based code generators. They are listed in the begining
+sljit based code generators. They are listed in the beginning
of sljitConfigInternal.h */
#include "sljitConfigInternal.h"
@@ -161,12 +161,14 @@ of sljitConfigInternal.h */
/* Floating point operations are performed on double or
single precision values. */
-#define SLJIT_FLOAT_REG1 1
-#define SLJIT_FLOAT_REG2 2
-#define SLJIT_FLOAT_REG3 3
-#define SLJIT_FLOAT_REG4 4
-#define SLJIT_FLOAT_REG5 5
-#define SLJIT_FLOAT_REG6 6
+#define SLJIT_FLOAT_REG1 1
+#define SLJIT_FLOAT_REG2 2
+#define SLJIT_FLOAT_REG3 3
+#define SLJIT_FLOAT_REG4 4
+#define SLJIT_FLOAT_REG5 5
+#define SLJIT_FLOAT_REG6 6
+
+#define SLJIT_NO_FLOAT_REGISTERS 6
/* --------------------------------------------------------------------- */
/* Main structures and functions */
@@ -281,6 +283,11 @@ struct sljit_compiler {
sljit_sw cache_argw;
#endif
+#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+ sljit_si cache_arg;
+ sljit_sw cache_argw;
+#endif
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
FILE* verbose;
#endif
@@ -306,7 +313,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
/* Free everything except the compiled machine code. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
-/* Returns the current error code. If an error is occured, future sljit
+/* Returns the current error code. If an error is occurred, future sljit
calls which uses the same compiler argument returns early with the same
error code. Thus there is no need for checking the error after every
call, it is enough to do it before the code is compiled. Removing
@@ -447,7 +454,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
sequences. This information could help to improve those code
generators which focuses only a few architectures.
- x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full adress space on x86-32)
+ x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
[reg+(reg<<imm)] is supported
[imm], -2^32+1 <= imm <= 2^32-1 is supported
Write-back is not supported
@@ -698,12 +705,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
/* The following function is a helper function for sljit_emit_op_custom.
It returns with the real machine register index of any SLJIT_SCRATCH
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. */
+ Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
+/* The following function is a helper function for sljit_emit_op_custom.
+ It returns with the real machine register index of any SLJIT_FLOAT register.
+ Note: the index is divided by 2 on ARM 32 bit architectures. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si 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
@@ -896,7 +907,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
/* --------------------------------------------------------------------- */
#define SLJIT_MAJOR_VERSION 0
-#define SLJIT_MINOR_VERSION 90
+#define SLJIT_MINOR_VERSION 91
/* Get the human readable name of the platform. Can be useful on platforms
like ARM, where ARM and Thumb2 functions can be mixed, and
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
index 0a60dc2a67..74ec83177d 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_Thumb2.c
@@ -418,9 +418,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
- SLJIT_CACHE_FLUSH(code, code_ptr);
compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = compiler->size * sizeof(sljit_uh);
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
/* Set thumb mode flag. */
return (void*)((sljit_uw)code | 0x1);
}
@@ -1526,6 +1526,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
diff --git a/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
index 23a45a4c6a..e3ca3d9bb1 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeARM_v5.c
@@ -405,7 +405,6 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw
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);
@@ -431,7 +430,6 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw
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);
@@ -787,9 +785,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(code_ptr - code <= (sljit_si)size);
- SLJIT_CACHE_FLUSH(code, code_ptr);
compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = size * sizeof(sljit_uw);
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
return code;
}
@@ -1991,6 +1989,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
diff --git a/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
index 9559ec32de..ede1c0bafe 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeMIPS_common.c
@@ -30,7 +30,7 @@
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
{
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
- return "MIPS" SLJIT_CPUINFO;
+ return "MIPS(32)" SLJIT_CPUINFO;
#else
return "MIPS III" SLJIT_CPUINFO;
#endif
@@ -398,7 +398,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
}
compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = compiler->size * sizeof(sljit_ins);
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
#ifndef __GNUC__
SLJIT_CACHE_FLUSH(code, code_ptr);
#else
@@ -1099,6 +1099,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg << 1;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
diff --git a/src/3rdparty/pcre/sljit/sljitNativePPC_common.c b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
index f7c75a7906..67e6898a17 100644
--- a/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
+++ b/src/3rdparty/pcre/sljit/sljitNativePPC_common.c
@@ -402,9 +402,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
- SLJIT_CACHE_FLUSH(code, code_ptr);
compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = compiler->size * sizeof(sljit_ins);
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -1507,6 +1507,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
diff --git a/src/3rdparty/pcre/sljit/sljitNativeSPARC_common.c b/src/3rdparty/pcre/sljit/sljitNativeSPARC_common.c
index c6522be2a7..e5571ee6dd 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeSPARC_common.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeSPARC_common.c
@@ -35,6 +35,30 @@ typedef sljit_ui sljit_ins;
static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
{
+#if defined(__SUNPRO_C) && __SUNPRO_C < 0x590
+ __asm (
+ /* if (from == to) return */
+ "cmp %i0, %i1\n"
+ "be .leave\n"
+ "nop\n"
+
+ /* loop until from >= to */
+ ".mainloop:\n"
+ "flush %i0\n"
+ "add %i0, 8, %i0\n"
+ "cmp %i0, %i1\n"
+ "bcs .mainloop\n"
+ "nop\n"
+
+ /* The comparison was done above. */
+ "bne .leave\n"
+ /* nop is not necessary here, since the
+ sub operation has no side effect. */
+ "sub %i0, 4, %i0\n"
+ "flush %i0\n"
+ ".leave:"
+ );
+#else
if (SLJIT_UNLIKELY(from == to))
return;
@@ -49,12 +73,13 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
if (from == to) {
/* Flush the last word. */
- to --;
+ from --;
__asm__ volatile (
"flush %0\n"
- : : "r"(to)
+ : : "r"(from)
);
}
+#endif
}
/* TMP_REG2 is not used by getput_arg */
@@ -344,7 +369,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = compiler->size * sizeof(sljit_ins);
+ compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
SLJIT_CACHE_FLUSH(code, code_ptr);
return code;
}
@@ -896,6 +921,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg << 1;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
index 03a595bd85..2866e8f2a1 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_32.c
@@ -149,7 +149,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
if (saveds > 3)
locals_offset += (saveds - 3) * sizeof(sljit_uw);
compiler->locals_offset = locals_offset;
+#if defined(__APPLE__)
+ saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+ local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
+#else
local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
+#endif
compiler->local_size = local_size;
#ifdef _WIN32
@@ -197,7 +202,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
if (saveds > 3)
locals_offset += (saveds - 3) * sizeof(sljit_uw);
compiler->locals_offset = locals_offset;
+#if defined(__APPLE__)
+ saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
+ compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
+#else
compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
+#endif
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
index ab98a03d2c..ceb3d675b7 100644
--- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
+++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c
@@ -206,6 +206,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
#define OR_r_rm 0x0b
#define OR_EAX_i32 0x0d
#define OR_rm_r 0x09
+#define OR_rm8_r8 0x08
#define POP_r 0x58
#define POP_rm 0x8f
#define POPF 0x9d
@@ -267,75 +268,54 @@ static sljit_si cpu_has_sse2 = -1;
#endif
static sljit_si cpu_has_cmov = -1;
-#if defined(_MSC_VER) && (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-#if _MSC_VER >= 1400
+#if defined(_MSC_VER) && _MSC_VER >= 1400
#include <intrin.h>
-#else
-#error "MSVC does not support inline assembly in 64 bit mode"
#endif
-#endif /* _MSC_VER && SLJIT_CONFIG_X86_64 */
static void get_cpu_features(void)
{
sljit_ui features;
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+
+ int CPUInfo[4];
+ __cpuid(CPUInfo, 1);
+ features = (sljit_ui)CPUInfo[3];
+
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
/* AT&T syntax. */
__asm__ (
- "pushl %%ebx\n"
"movl $0x1, %%eax\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ /* On x86-32, there is no red zone, so this
+ should work (no need for a local variable). */
+ "push %%ebx\n"
+#endif
"cpuid\n"
- "popl %%ebx\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ "pop %%ebx\n"
+#endif
"movl %%edx, %0\n"
: "=g" (features)
:
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
: "%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_DETECT_SSE2 is not implemented for this C compiler"
+ : "%rax", "%rbx", "%rcx", "%rdx"
#endif
-
-#else /* SLJIT_CONFIG_X86_32 */
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
- /* AT&T syntax. */
- __asm__ (
- "pushq %%rbx\n"
- "movl $0x1, %%eax\n"
- "cpuid\n"
- "popq %%rbx\n"
- "movl %%edx, %0\n"
- : "=g" (features)
- :
- : "%rax", "%rcx", "%rdx"
);
-#elif defined(_MSC_VER) && _MSC_VER >= 1400
- int CPUInfo[4];
- __cpuid(CPUInfo, 1);
- features = (sljit_ui)CPUInfo[3];
-#else
+#else /* _MSC_VER && _MSC_VER >= 1400 */
+
+ /* Intel syntax. */
__asm {
mov eax, 1
- push rbx
cpuid
- pop rbx
mov features, edx
}
-#endif
-#endif /* SLJIT_CONFIG_X86_32 */
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
cpu_has_sse2 = (features >> 26) & 0x1;
@@ -570,7 +550,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* 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;
+ compiler->executable_size = code_ptr - code;
return (void*)code;
}
@@ -650,9 +630,10 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size)
This function touches all 4k pages belongs to the requested stack space,
which size is passed in local_size. This is necessary on Windows where
the stack can only grow in 4k steps. However, this function just burn
- CPU cycles if the stack is large enough, but you don't know it in advance.
- I think this is a bad design even if it has some reasons. */
- alloca(local_size);
+ CPU cycles if the stack is large enough. However, you don't know it in
+ advance, so it must always be called. I think this is a bad design in
+ general even if it has some reasons. */
+ *(sljit_si*)alloca(local_size) = 0;
}
#endif
@@ -1785,7 +1766,7 @@ static sljit_si emit_mul(struct sljit_compiler *compiler,
return SLJIT_SUCCESS;
}
-static sljit_si emit_lea_binary(struct sljit_compiler *compiler,
+static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags,
sljit_si dst, sljit_sw dstw,
sljit_si src1, sljit_sw src1w,
sljit_si src2, sljit_sw src2w)
@@ -1794,10 +1775,12 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler,
sljit_si 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;
+ if (!keep_flags) {
+ if (dst == src1 && dstw == src1w)
+ return SLJIT_ERR_UNSUPPORTED;
+ if (dst == src2 && dstw == src2w)
+ return SLJIT_ERR_UNSUPPORTED;
+ }
dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
@@ -2153,7 +2136,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *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)
+ if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
return compiler->error;
}
else
@@ -2173,7 +2156,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
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)
+ if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
return compiler->error;
}
else
@@ -2231,6 +2214,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
return reg_map[reg];
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
+{
+ check_sljit_get_float_register_index(reg);
+ return reg;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size)
{
@@ -2637,6 +2626,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
cond_set = get_jump_code(type) + 0x10;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && dst <= TMP_REGISTER && dst == src) {
+ inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3);
+ FAIL_IF(!inst);
+ INC_SIZE(4 + 3);
+ /* Set low register to conditional flag. */
+ *inst++ = (reg_map[TMP_REGISTER] <= 7) ? REX : REX_B;
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | reg_lmap[TMP_REGISTER];
+ *inst++ = REX | (reg_map[TMP_REGISTER] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B);
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (reg_lmap[TMP_REGISTER] << 3) | reg_lmap[dst];
+ return SLJIT_SUCCESS;
+ }
+
reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
@@ -2717,6 +2721,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
return SLJIT_SUCCESS;
}
+ if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && dst <= TMP_REGISTER && dst == src && reg_map[dst] <= 4) {
+ SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] == 0, scratch_reg1_must_be_eax);
+ if (dst != SLJIT_SCRATCH_REG1) {
+ inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
+ FAIL_IF(!inst);
+ INC_SIZE(1 + 3 + 2 + 1);
+ /* Set low register to conditional flag. */
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER];
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 0 /* eax */;
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];
+ *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER];
+ }
+ else {
+ inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);
+ FAIL_IF(!inst);
+ INC_SIZE(2 + 3 + 2 + 2);
+ /* Set low register to conditional flag. */
+ *inst++ = XCHG_r_rm;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REGISTER];
+ *inst++ = GROUP_0F;
+ *inst++ = cond_set;
+ *inst++ = MOD_REG | 1 /* ecx */;
+ *inst++ = OR_rm8_r8;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;
+ *inst++ = XCHG_r_rm;
+ *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REGISTER];
+ }
+ return SLJIT_SUCCESS;
+ }
+
/* Set TMP_REGISTER to the bit. */
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
FAIL_IF(!inst);
@@ -2761,16 +2798,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co
if (NOT_HALFWORD(offset)) {
FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
- SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
+ SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
return compiler->error;
#else
- return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
+ return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
#endif
}
#endif
if (offset != 0)
- return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
+ return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0);
}
diff --git a/src/3rdparty/pcre/ucp.h b/src/3rdparty/pcre/ucp.h
index 21039106e5..d8b34bfcc5 100644
--- a/src/3rdparty/pcre/ucp.h
+++ b/src/3rdparty/pcre/ucp.h
@@ -11,7 +11,10 @@ should always be at the end of each enum, for backwards compatibility.
IMPORTANT: Note also that the specific numeric values of the enums have to be
the same as the values that are generated by the maint/MultiStage2.py script,
-where the equivalent property descriptive names are listed in vectors. */
+where the equivalent property descriptive names are listed in vectors.
+
+ALSO: The specific values of the first two enums are assumed for the table
+called catposstab in pcre_compile.c. */
/* These are the general character categories. */
diff --git a/src/3rdparty/sqlite/shell.c b/src/3rdparty/sqlite/shell.c
index 1be2871fed..480ec5b455 100644
--- a/src/3rdparty/sqlite/shell.c
+++ b/src/3rdparty/sqlite/shell.c
@@ -53,7 +53,6 @@
# include <readline/history.h>
#endif
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
-# define readline(p) local_getline(p,stdin,0)
# define add_history(X)
# define read_history(X)
# define write_history(X)
@@ -65,13 +64,18 @@
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#undef popen
-#define popen(a,b) _popen((a),(b))
+#define popen _popen
#undef pclose
-#define pclose(x) _pclose(x)
+#define pclose _pclose
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty(int);
+
+/* popen and pclose are not C89 functions and so are sometimes omitted from
+** the <stdio.h> header */
+extern FILE *popen(const char*,const char*);
+extern int pclose(FILE*);
#endif
#if defined(_WIN32_WCE)
@@ -82,21 +86,38 @@ extern int isatty(int);
#define isatty(x) 1
#endif
-/* True if the timer is enabled */
-static int enableTimer = 0;
-
/* ctype macros that work with signed characters */
#define IsSpace(X) isspace((unsigned char)X)
#define IsDigit(X) isdigit((unsigned char)X)
#define ToLower(X) (char)tolower((unsigned char)X)
+
+/* True if the timer is enabled */
+static int enableTimer = 0;
+
+/* Return the current wall-clock time */
+static sqlite3_int64 timeOfDay(void){
+ static sqlite3_vfs *clockVfs = 0;
+ sqlite3_int64 t;
+ if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
+ if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
+ clockVfs->xCurrentTimeInt64(clockVfs, &t);
+ }else{
+ double r;
+ clockVfs->xCurrentTime(clockVfs, &r);
+ t = (sqlite3_int64)(r*86400000.0);
+ }
+ return t;
+}
+
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
&& !defined(__minux)
#include <sys/time.h>
#include <sys/resource.h>
/* Saved resource information for the beginning of an operation */
-static struct rusage sBegin;
+static struct rusage sBegin; /* CPU time at start */
+static sqlite3_int64 iBegin; /* Wall-clock time at start */
/*
** Begin timing an operation
@@ -104,6 +125,7 @@ static struct rusage sBegin;
static void beginTimer(void){
if( enableTimer ){
getrusage(RUSAGE_SELF, &sBegin);
+ iBegin = timeOfDay();
}
}
@@ -119,8 +141,10 @@ static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
static void endTimer(void){
if( enableTimer ){
struct rusage sEnd;
+ sqlite3_int64 iEnd = timeOfDay();
getrusage(RUSAGE_SELF, &sEnd);
- printf("CPU Time: user %f sys %f\n",
+ printf("Run Time: real %.3f user %f sys %f\n",
+ (iEnd - iBegin)*0.001,
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
}
@@ -138,6 +162,7 @@ static void endTimer(void){
static HANDLE hProcess;
static FILETIME ftKernelBegin;
static FILETIME ftUserBegin;
+static sqlite3_int64 ftWallBegin;
typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
static GETPROCTIMES getProcessTimesAddr = NULL;
@@ -175,6 +200,7 @@ static void beginTimer(void){
if( enableTimer && getProcessTimesAddr ){
FILETIME ftCreation, ftExit;
getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
+ ftWallBegin = timeOfDay();
}
}
@@ -191,8 +217,10 @@ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
static void endTimer(void){
if( enableTimer && getProcessTimesAddr){
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
+ sqlite3_int64 ftWallEnd = timeOfDay();
getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
- printf("CPU Time: user %f sys %f\n",
+ printf("Run Time: real %.3f user %f sys %f\n",
+ (ftWallEnd - ftWallBegin)*0.001,
timeDiff(&ftUserBegin, &ftUserEnd),
timeDiff(&ftKernelBegin, &ftKernelEnd));
}
@@ -332,23 +360,13 @@ static void shellstaticFunc(
** to the text. NULL is returned at end of file, or if malloc()
** fails.
**
-** The interface is like "readline" but no command-line editing
-** is done.
+** If zLine is not NULL then it is a malloced buffer returned from
+** a previous call to this routine that may be reused.
*/
-static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
- char *zLine;
- int nLine;
- int n;
- int inQuote = 0;
+static char *local_getline(char *zLine, FILE *in){
+ int nLine = zLine==0 ? 0 : 100;
+ int n = 0;
- if( zPrompt && *zPrompt ){
- printf("%s",zPrompt);
- fflush(stdout);
- }
- nLine = 100;
- zLine = malloc( nLine );
- if( zLine==0 ) return 0;
- n = 0;
while( 1 ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
@@ -363,42 +381,48 @@ static char *local_getline(char *zPrompt, FILE *in, int csvFlag){
zLine[n] = 0;
break;
}
- while( zLine[n] ){
- if( zLine[n]=='"' ) inQuote = !inQuote;
- n++;
- }
- if( n>0 && zLine[n-1]=='\n' && (!inQuote || !csvFlag) ){
+ while( zLine[n] ) n++;
+ if( n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
- zLine = realloc( zLine, n+1 );
return zLine;
}
/*
** Retrieve a single line of input text.
**
-** zPrior is a string of prior text retrieved. If not the empty
-** string, then issue a continuation prompt.
+** If in==0 then read from standard input and prompt before each line.
+** If isContinuation is true, then a continuation prompt is appropriate.
+** If isContinuation is zero, then the main prompt should be used.
+**
+** If zPrior is not NULL then it is a buffer from a prior call to this
+** routine that can be reused.
+**
+** The result is stored in space obtained from malloc() and must either
+** be freed by the caller or else passed back into this routine via the
+** zPrior argument for reuse.
*/
-static char *one_input_line(const char *zPrior, FILE *in){
+static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
char *zPrompt;
char *zResult;
if( in!=0 ){
- return local_getline(0, in, 0);
- }
- if( zPrior && zPrior[0] ){
- zPrompt = continuePrompt;
+ zResult = local_getline(zPrior, in);
}else{
- zPrompt = mainPrompt;
- }
- zResult = readline(zPrompt);
+ zPrompt = isContinuation ? continuePrompt : mainPrompt;
#if defined(HAVE_READLINE) && HAVE_READLINE==1
- if( zResult && *zResult ) add_history(zResult);
+ free(zPrior);
+ zResult = readline(zPrompt);
+ if( zResult && *zResult ) add_history(zResult);
+#else
+ printf("%s", zPrompt);
+ fflush(stdout);
+ zResult = local_getline(zPrior, stdin);
#endif
+ }
return zResult;
}
@@ -436,9 +460,13 @@ struct callback_data {
** .explain ON */
char outfile[FILENAME_MAX]; /* Filename for *out */
const char *zDbFilename; /* name of the database file */
+ char *zFreeOnClose; /* Filename to free when closing */
const char *zVfs; /* Name of VFS to use */
sqlite3_stmt *pStmt; /* Current statement if any. */
FILE *pLog; /* Write log output here */
+ int *aiIndent; /* Array of indents used in MODE_Explain */
+ int nIndent; /* Size of array aiIndent[] */
+ int iIndent; /* Index of current op in aiIndent[] */
};
/*
@@ -554,7 +582,7 @@ static void output_c_string(FILE *out, const char *z){
}else if( c=='\r' ){
fputc('\\', out);
fputc('r', out);
- }else if( !isprint(c) ){
+ }else if( !isprint(c&0xff) ){
fprintf(out, "\\%03o", c&0xff);
}else{
fputc(c, out);
@@ -740,10 +768,15 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
}else{
w = 10;
}
- if( p->mode==MODE_Explain && azArg[i] &&
- strlen30(azArg[i])>w ){
+ if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
w = strlen30(azArg[i]);
}
+ if( i==1 && p->aiIndent && p->pStmt ){
+ if( p->iIndent<p->nIndent ){
+ fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
+ }
+ p->iIndent++;
+ }
if( w<0 ){
fprintf(p->out,"%*.*s%s",-w,-w,
azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
@@ -974,7 +1007,7 @@ static int run_table_dump_query(
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
- p->nErr++;
+ if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
return rc;
}
rc = sqlite3_step(pSelect);
@@ -1001,7 +1034,7 @@ static int run_table_dump_query(
rc = sqlite3_finalize(pSelect);
if( rc!=SQLITE_OK ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
- p->nErr++;
+ if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
}
return rc;
}
@@ -1109,12 +1142,109 @@ static int display_stats(
fprintf(pArg->out, "Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
+ iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+ fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
}
return 0;
}
/*
+** Parameter azArray points to a zero-terminated array of strings. zStr
+** points to a single nul-terminated string. Return non-zero if zStr
+** is equal, according to strcmp(), to any of the strings in the array.
+** Otherwise, return zero.
+*/
+static int str_in_array(const char *zStr, const char **azArray){
+ int i;
+ for(i=0; azArray[i]; i++){
+ if( 0==strcmp(zStr, azArray[i]) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** If compiled statement pSql appears to be an EXPLAIN statement, allocate
+** and populate the callback_data.aiIndent[] array with the number of
+** spaces each opcode should be indented before it is output.
+**
+** The indenting rules are:
+**
+** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
+** all opcodes that occur between the p2 jump destination and the opcode
+** itself by 2 spaces.
+**
+** * For each "Goto", if the jump destination is earlier in the program
+** and ends on one of:
+** Yield SeekGt SeekLt RowSetRead
+** then indent all opcodes between the earlier instruction
+** and "Goto" by 2 spaces.
+*/
+static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
+ const char *zSql; /* The text of the SQL statement */
+ const char *z; /* Used to check if this is an EXPLAIN */
+ int *abYield = 0; /* True if op is an OP_Yield */
+ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
+ int iOp; /* Index of operation in p->aiIndent[] */
+
+ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
+ const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 };
+ const char *azGoto[] = { "Goto", 0 };
+
+ /* Try to figure out if this is really an EXPLAIN statement. If this
+ ** cannot be verified, return early. */
+ zSql = sqlite3_sql(pSql);
+ if( zSql==0 ) return;
+ for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
+ if( sqlite3_strnicmp(z, "explain", 7) ) return;
+
+ for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
+ int i;
+ int iAddr = sqlite3_column_int(pSql, 0);
+ const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
+
+ /* Set p2 to the P2 field of the current opcode. Then, assuming that
+ ** p2 is an instruction address, set variable p2op to the index of that
+ ** instruction in the aiIndent[] array. p2 and p2op may be different if
+ ** the current instruction is part of a sub-program generated by an
+ ** SQL trigger or foreign key. */
+ int p2 = sqlite3_column_int(pSql, 3);
+ int p2op = (p2 + (iOp-iAddr));
+
+ /* Grow the p->aiIndent array as required */
+ if( iOp>=nAlloc ){
+ nAlloc += 100;
+ p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
+ abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
+ }
+ abYield[iOp] = str_in_array(zOp, azYield);
+ p->aiIndent[iOp] = 0;
+ p->nIndent = iOp+1;
+
+ if( str_in_array(zOp, azNext) ){
+ for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
+ }
+ if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
+ for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
+ }
+ }
+
+ p->iIndent = 0;
+ sqlite3_free(abYield);
+ sqlite3_reset(pSql);
+}
+
+/*
+** Free the array allocated by explain_data_prepare().
+*/
+static void explain_data_delete(struct callback_data *p){
+ sqlite3_free(p->aiIndent);
+ p->aiIndent = 0;
+ p->nIndent = 0;
+ p->iIndent = 0;
+}
+
+/*
** Execute a statement or set of statements. Print
** any result rows/columns depending on the current mode
** set via the supplied callback.
@@ -1175,6 +1305,12 @@ static int shell_exec(
}
}
+ /* If the shell is currently in ".explain" mode, gather the extra
+ ** data required to add indents to the output.*/
+ if( pArg && pArg->mode==MODE_Explain ){
+ explain_data_prepare(pArg, pStmt);
+ }
+
/* perform the first step. this will tell us if we
** have a result set or not and how wide it is.
*/
@@ -1192,7 +1328,7 @@ static int shell_exec(
char **azCols = (char **)pData; /* Names of result columns */
char **azVals = &azCols[nCol]; /* Results */
int *aiTypes = (int *)&azVals[nCol]; /* Result types */
- int i;
+ int i, x;
assert(sizeof(int) <= sizeof(char *));
/* save off ptrs to column names */
for(i=0; i<nCol; i++){
@@ -1201,8 +1337,12 @@ static int shell_exec(
do{
/* extract the data and data types */
for(i=0; i<nCol; i++){
- azVals[i] = (char *)sqlite3_column_text(pStmt, i);
- aiTypes[i] = sqlite3_column_type(pStmt, i);
+ aiTypes[i] = x = sqlite3_column_type(pStmt, i);
+ if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
+ azVals[i] = "";
+ }else{
+ azVals[i] = (char*)sqlite3_column_text(pStmt, i);
+ }
if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
rc = SQLITE_NOMEM;
break; /* from for */
@@ -1228,6 +1368,8 @@ static int shell_exec(
}
}
+ explain_data_delete(pArg);
+
/* print usage stats if stats on */
if( pArg && pArg->statsOn ){
display_stats(db, pArg, 0);
@@ -1278,7 +1420,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
if( strcmp(zTable, "sqlite_sequence")==0 ){
zPrepStmt = "DELETE FROM sqlite_sequence;\n";
- }else if( strcmp(zTable, "sqlite_stat1")==0 ){
+ }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
fprintf(p->out, "ANALYZE sqlite_master;\n");
}else if( strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
@@ -1431,6 +1573,7 @@ static char zHelp[] =
" tabs Tab-separated values\n"
" tcl TCL list elements\n"
".nullvalue STRING Use STRING in place of NULL values\n"
+ ".open ?FILENAME? Close existing database and reopen FILENAME\n"
".output FILENAME Send output to FILENAME\n"
".output stdout Send output to the screen\n"
".print STRING... Print literal STRING\n"
@@ -1464,7 +1607,7 @@ static int process_input(struct callback_data *p, FILE *in);
** Make sure the database is open. If it is not, then open it. If
** the database fails to open, print an error message and exit.
*/
-static void open_db(struct callback_data *p){
+static void open_db(struct callback_data *p, int keepAlive){
if( p->db==0 ){
sqlite3_initialize();
sqlite3_open(p->zDbFilename, &p->db);
@@ -1476,6 +1619,7 @@ static void open_db(struct callback_data *p){
if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
p->zDbFilename, sqlite3_errmsg(db));
+ if( keepAlive ) return;
exit(1);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
@@ -1490,6 +1634,7 @@ static void open_db(struct callback_data *p){
** \t -> tab
** \n -> newline
** \r -> carriage return
+** \" -> "
** \NNN -> ascii character NNN in octal
** \\ -> backslash
*/
@@ -1505,6 +1650,8 @@ static void resolve_backslashes(char *z){
c = '\t';
}else if( c=='r' ){
c = '\r';
+ }else if( c=='\\' ){
+ c = '\\';
}else if( c>='0' && c<='7' ){
c -= '0';
if( z[i+1]>='0' && z[i+1]<='7' ){
@@ -1523,21 +1670,14 @@ static void resolve_backslashes(char *z){
}
/*
-** Interpret zArg as a boolean value. Return either 0 or 1.
-*/
-static int booleanValue(char *zArg){
- int i;
- for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
- if( i>0 && zArg[i]==0 ) return atoi(zArg);
- if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
- return 1;
- }
- if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
- return 0;
- }
- fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
- zArg);
- return 0;
+** Return the value of a hexadecimal digit. Return -1 if the input
+** is not a hex digit.
+*/
+static int hexDigitValue(char c){
+ if( c>='0' && c<='9' ) return c - '0';
+ if( c>='a' && c<='f' ) return c - 'a' + 10;
+ if( c>='A' && c<='F' ) return c - 'A' + 10;
+ return -1;
}
/*
@@ -1564,11 +1704,20 @@ static sqlite3_int64 integerValue(const char *zArg){
}else if( zArg[0]=='+' ){
zArg++;
}
- while( isdigit(zArg[0]) ){
- v = v*10 + zArg[0] - '0';
- zArg++;
+ if( zArg[0]=='0' && zArg[1]=='x' ){
+ int x;
+ zArg += 2;
+ while( (x = hexDigitValue(zArg[0]))>=0 ){
+ v = (v<<4) + x;
+ zArg++;
+ }
+ }else{
+ while( IsDigit(zArg[0]) ){
+ v = v*10 + zArg[0] - '0';
+ zArg++;
+ }
}
- for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++){
+ for(i=0; i<ArraySize(aMult); i++){
if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
v *= aMult[i].iMult;
break;
@@ -1578,6 +1727,29 @@ static sqlite3_int64 integerValue(const char *zArg){
}
/*
+** Interpret zArg as either an integer or a boolean value. Return 1 or 0
+** for TRUE and FALSE. Return the integer value if appropriate.
+*/
+static int booleanValue(char *zArg){
+ int i;
+ if( zArg[0]=='0' && zArg[1]=='x' ){
+ for(i=2; hexDigitValue(zArg[i])>=0; i++){}
+ }else{
+ for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
+ }
+ if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
+ if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
+ return 1;
+ }
+ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
+ return 0;
+ }
+ fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
+ zArg);
+ return 0;
+}
+
+/*
** Close an output file, assuming it is not stderr or stdout
*/
static void output_file_close(FILE *f){
@@ -1624,6 +1796,105 @@ static void test_breakpoint(void){
}
/*
+** An object used to read a CSV file
+*/
+typedef struct CSVReader CSVReader;
+struct CSVReader {
+ const char *zFile; /* Name of the input file */
+ FILE *in; /* Read the CSV text from this input stream */
+ char *z; /* Accumulated text for a field */
+ int n; /* Number of bytes in z */
+ int nAlloc; /* Space allocated for z[] */
+ int nLine; /* Current line number */
+ int cTerm; /* Character that terminated the most recent field */
+ int cSeparator; /* The separator character. (Usually ",") */
+};
+
+/* Append a single byte to z[] */
+static void csv_append_char(CSVReader *p, int c){
+ if( p->n+1>=p->nAlloc ){
+ p->nAlloc += p->nAlloc + 100;
+ p->z = sqlite3_realloc(p->z, p->nAlloc);
+ if( p->z==0 ){
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ }
+ p->z[p->n++] = (char)c;
+}
+
+/* Read a single field of CSV text. Compatible with rfc4180 and extended
+** with the option of having a separator other than ",".
+**
+** + Input comes from p->in.
+** + Store results in p->z of length p->n. Space to hold p->z comes
+** from sqlite3_malloc().
+** + Use p->cSep as the separator. The default is ",".
+** + Keep track of the line number in p->nLine.
+** + Store the character that terminates the field in p->cTerm. Store
+** EOF on end-of-file.
+** + Report syntax errors on stderr
+*/
+static char *csv_read_one_field(CSVReader *p){
+ int c, pc;
+ int cSep = p->cSeparator;
+ p->n = 0;
+ c = fgetc(p->in);
+ if( c==EOF || seenInterrupt ){
+ p->cTerm = EOF;
+ return 0;
+ }
+ if( c=='"' ){
+ int startLine = p->nLine;
+ int cQuote = c;
+ pc = 0;
+ while( 1 ){
+ c = fgetc(p->in);
+ if( c=='\n' ) p->nLine++;
+ if( c==cQuote ){
+ if( pc==cQuote ){
+ pc = 0;
+ continue;
+ }
+ }
+ if( (c==cSep && pc==cQuote)
+ || (c=='\n' && pc==cQuote)
+ || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
+ || (c==EOF && pc==cQuote)
+ ){
+ do{ p->n--; }while( p->z[p->n]!=cQuote );
+ p->cTerm = c;
+ break;
+ }
+ if( pc==cQuote && c!='\r' ){
+ fprintf(stderr, "%s:%d: unescaped %c character\n",
+ p->zFile, p->nLine, cQuote);
+ }
+ if( c==EOF ){
+ fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
+ p->zFile, startLine, cQuote);
+ p->cTerm = EOF;
+ break;
+ }
+ csv_append_char(p, c);
+ pc = c;
+ }
+ }else{
+ while( c!=EOF && c!=cSep && c!='\n' ){
+ csv_append_char(p, c);
+ c = fgetc(p->in);
+ }
+ if( c=='\n' ){
+ p->nLine++;
+ if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
+ }
+ p->cTerm = c;
+ }
+ if( p->z ) p->z[p->n] = 0;
+ return p->z;
+}
+
+/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
@@ -1644,7 +1915,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( zLine[i]=='\'' || zLine[i]=='"' ){
int delim = zLine[i++];
azArg[nArg++] = &zLine[i];
- while( zLine[i] && zLine[i]!=delim ){ i++; }
+ while( zLine[i] && zLine[i]!=delim ){
+ if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
+ i++;
+ }
if( zLine[i]==delim ){
zLine[i++] = 0;
}
@@ -1665,7 +1939,6 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
const char *zDestFile = 0;
const char *zDb = 0;
- const char *zKey = 0;
sqlite3 *pDest;
sqlite3_backup *pBackup;
int j;
@@ -1673,9 +1946,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
const char *z = azArg[j];
if( z[0]=='-' ){
while( z[0]=='-' ) z++;
- if( strcmp(z,"key")==0 && j<nArg-1 ){
- zKey = azArg[++j];
- }else
+ /* No options to process at this time */
{
fprintf(stderr, "unknown option: %s\n", azArg[j]);
return 1;
@@ -1701,12 +1972,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_close(pDest);
return 1;
}
-#ifdef SQLITE_HAS_CODEC
- sqlite3_key(pDest, zKey, (int)strlen(zKey));
-#else
- (void)zKey;
-#endif
- open_db(p);
+ open_db(p, 0);
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
if( pBackup==0 ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
@@ -1738,7 +2004,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data;
char *zErrMsg = 0;
- open_db(p);
+ open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 1;
data.mode = MODE_Column;
@@ -1755,7 +2021,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
- open_db(p);
+ open_db(p, 0);
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
@@ -1808,7 +2074,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
- if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc);
+ if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
}else
@@ -1830,7 +2096,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
*/
p->mode = MODE_Explain;
p->showHeader = 1;
- memset(p->colWidth,0,ArraySize(p->colWidth));
+ memset(p->colWidth,0,sizeof(p->colWidth));
p->colWidth[0] = 4; /* addr */
p->colWidth[1] = 13; /* opcode */
p->colWidth[2] = 4; /* P1 */
@@ -1861,48 +2127,98 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
char *zTable = azArg[2]; /* Insert data into this table */
- char *zFile = azArg[1]; /* The file from which to extract data */
+ char *zFile = azArg[1]; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */
int nByte; /* Number of bytes in an SQL string */
int i, j; /* Loop counters */
+ int needCommit; /* True to COMMIT or ROLLBACK at end */
int nSep; /* Number of bytes in p->separator[] */
char *zSql; /* An SQL statement */
- char *zLine; /* A single line of input from the file */
- char **azCol; /* zLine[] broken up into columns */
- char *zCommit; /* How to commit changes */
- FILE *in; /* The input file */
- int lineno = 0; /* Line number of input file */
+ CSVReader sCsv; /* Reader context */
+ int (*xCloser)(FILE*); /* Procedure to close th3 connection */
- open_db(p);
+ seenInterrupt = 0;
+ memset(&sCsv, 0, sizeof(sCsv));
+ open_db(p, 0);
nSep = strlen30(p->separator);
if( nSep==0 ){
fprintf(stderr, "Error: non-null separator required for import\n");
return 1;
}
+ if( nSep>1 ){
+ fprintf(stderr, "Error: multi-character separators not allowed"
+ " for import\n");
+ return 1;
+ }
+ sCsv.zFile = zFile;
+ sCsv.nLine = 1;
+ if( sCsv.zFile[0]=='|' ){
+ sCsv.in = popen(sCsv.zFile+1, "r");
+ sCsv.zFile = "<pipe>";
+ xCloser = pclose;
+ }else{
+ sCsv.in = fopen(sCsv.zFile, "rb");
+ xCloser = fclose;
+ }
+ if( sCsv.in==0 ){
+ fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
+ return 1;
+ }
+ sCsv.cSeparator = p->separator[0];
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
+ xCloser(sCsv.in);
return 1;
}
nByte = strlen30(zSql);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
+ if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
+ char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
+ char cSep = '(';
+ while( csv_read_one_field(&sCsv) ){
+ zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCsv.z);
+ cSep = ',';
+ if( sCsv.cTerm!=sCsv.cSeparator ) break;
+ }
+ if( cSep=='(' ){
+ sqlite3_free(zCreate);
+ sqlite3_free(sCsv.z);
+ xCloser(sCsv.in);
+ fprintf(stderr,"%s: empty file\n", sCsv.zFile);
+ return 1;
+ }
+ zCreate = sqlite3_mprintf("%z\n)", zCreate);
+ rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
+ sqlite3_free(zCreate);
+ if( rc ){
+ fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
+ sqlite3_errmsg(db));
+ sqlite3_free(sCsv.z);
+ xCloser(sCsv.in);
+ return 1;
+ }
+ rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
+ }
sqlite3_free(zSql);
if( rc ){
if (pStmt) sqlite3_finalize(pStmt);
fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
+ xCloser(sCsv.in);
return 1;
}
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */
- zSql = malloc( nByte + 20 + nCol*2 );
+ zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
if( zSql==0 ){
fprintf(stderr, "Error: out of memory\n");
+ xCloser(sCsv.in);
return 1;
}
- sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
+ sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
j = strlen30(zSql);
for(i=1; i<nCol; i++){
zSql[j++] = ',';
@@ -1911,85 +2227,58 @@ static int do_meta_command(char *zLine, struct callback_data *p){
zSql[j++] = ')';
zSql[j] = 0;
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
- free(zSql);
+ sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
if (pStmt) sqlite3_finalize(pStmt);
+ xCloser(sCsv.in);
return 1;
}
- in = fopen(zFile, "rb");
- if( in==0 ){
- fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
- sqlite3_finalize(pStmt);
- return 1;
- }
- azCol = malloc( sizeof(azCol[0])*(nCol+1) );
- if( azCol==0 ){
- fprintf(stderr, "Error: out of memory\n");
- fclose(in);
- sqlite3_finalize(pStmt);
- return 1;
- }
- sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
- zCommit = "COMMIT";
- while( (zLine = local_getline(0, in, 1))!=0 ){
- char *z, c;
- int inQuote = 0;
- lineno++;
- azCol[0] = zLine;
- for(i=0, z=zLine; (c = *z)!=0; z++){
- if( c=='"' ) inQuote = !inQuote;
- if( c=='\n' ) lineno++;
- if( !inQuote && c==p->separator[0] && strncmp(z,p->separator,nSep)==0 ){
- *z = 0;
+ needCommit = sqlite3_get_autocommit(db);
+ if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
+ do{
+ int startLine = sCsv.nLine;
+ for(i=0; i<nCol; i++){
+ char *z = csv_read_one_field(&sCsv);
+ if( z==0 && i==0 ) break;
+ sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
+ if( i<nCol-1 && sCsv.cTerm!=sCsv.cSeparator ){
+ fprintf(stderr, "%s:%d: expected %d columns but found %d - "
+ "filling the rest with NULL\n",
+ sCsv.zFile, startLine, nCol, i+1);
i++;
- if( i<nCol ){
- azCol[i] = &z[nSep];
- z += nSep-1;
- }
+ while( i<nCol ){ sqlite3_bind_null(pStmt, i); i++; }
}
- } /* end for */
- *z = 0;
- if( i+1!=nCol ){
- fprintf(stderr,
- "Error: %s line %d: expected %d columns of data but found %d\n",
- zFile, lineno, nCol, i+1);
- zCommit = "ROLLBACK";
- free(zLine);
- rc = 1;
- break; /* from while */
}
- for(i=0; i<nCol; i++){
- if( azCol[i][0]=='"' ){
- int k;
- for(z=azCol[i], j=1, k=0; z[j]; j++){
- if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
- z[k++] = z[j];
- }
- z[k] = 0;
+ if( sCsv.cTerm==sCsv.cSeparator ){
+ do{
+ csv_read_one_field(&sCsv);
+ i++;
+ }while( sCsv.cTerm==sCsv.cSeparator );
+ fprintf(stderr, "%s:%d: expected %d columns but found %d - "
+ "extras ignored\n",
+ sCsv.zFile, startLine, nCol, i);
+ }
+ if( i>=nCol ){
+ sqlite3_step(pStmt);
+ rc = sqlite3_reset(pStmt);
+ if( rc!=SQLITE_OK ){
+ fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCsv.zFile, startLine,
+ sqlite3_errmsg(db));
}
- sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
- }
- sqlite3_step(pStmt);
- rc = sqlite3_reset(pStmt);
- free(zLine);
- if( rc!=SQLITE_OK ){
- fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
- zCommit = "ROLLBACK";
- rc = 1;
- break; /* from while */
}
- } /* end while */
- free(azCol);
- fclose(in);
+ }while( sCsv.cTerm!=EOF );
+
+ xCloser(sCsv.in);
+ sqlite3_free(sCsv.z);
sqlite3_finalize(pStmt);
- sqlite3_exec(p->db, zCommit, 0, 0, 0);
+ if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
}else
if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
struct callback_data data;
char *zErrMsg = 0;
- open_db(p);
+ open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.mode = MODE_List;
@@ -2055,7 +2344,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
char *zErrMsg = 0;
zFile = azArg[1];
zProc = nArg>=3 ? azArg[2] : 0;
- open_db(p);
+ open_db(p, 0);
rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
if( rc!=SQLITE_OK ){
fprintf(stderr, "Error: %s\n", zErrMsg);
@@ -2121,6 +2410,26 @@ static int do_meta_command(char *zLine, struct callback_data *p){
"%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
}else
+ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
+ sqlite3 *savedDb = p->db;
+ const char *zSavedFilename = p->zDbFilename;
+ char *zNewFilename = 0;
+ p->db = 0;
+ if( nArg>=2 ){
+ p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
+ }
+ open_db(p, 1);
+ if( p->db!=0 ){
+ sqlite3_close(savedDb);
+ sqlite3_free(p->zFreeOnClose);
+ p->zFreeOnClose = zNewFilename;
+ }else{
+ sqlite3_free(zNewFilename);
+ p->db = savedDb;
+ p->zDbFilename = zSavedFilename;
+ }
+ }else
+
if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
if( p->outfile[0]=='|' ){
pclose(p->out);
@@ -2204,7 +2513,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
sqlite3_close(pSrc);
return 1;
}
- open_db(p);
+ open_db(p, 0);
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
if( pBackup==0 ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
@@ -2234,7 +2543,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
struct callback_data data;
char *zErrMsg = 0;
- open_db(p);
+ open_db(p, 0);
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.mode = MODE_Semi;
@@ -2305,6 +2614,29 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}else
+#ifdef SQLITE_DEBUG
+ /* Undocumented commands for internal testing. Subject to change
+ ** without notice. */
+ if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
+ if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
+ int i, v;
+ for(i=1; i<nArg; i++){
+ v = booleanValue(azArg[i]);
+ fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
+ }
+ }
+ if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
+ int i; sqlite3_int64 v;
+ for(i=1; i<nArg; i++){
+ char zBuf[200];
+ v = integerValue(azArg[i]);
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
+ fprintf(p->out, "%s", zBuf);
+ }
+ }
+ }else
+#endif
+
if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
sqlite3_snprintf(sizeof(p->separator), p->separator,
"%.*s", (int)sizeof(p->separator)-1, azArg[1]);
@@ -2342,7 +2674,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
int nRow, nAlloc;
char *zSql = 0;
int ii;
- open_db(p);
+ open_db(p, 0);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ) return rc;
zSql = sqlite3_mprintf(
@@ -2442,7 +2774,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
int testctrl = -1;
int rc = 0;
int i, n;
- open_db(p);
+ open_db(p, 0);
/* convert testctrl text option to value. allow any unique prefix
** of the option name, or a numerical value. */
@@ -2458,7 +2790,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
}
}
- if( testctrl<0 ) testctrl = atoi(azArg[1]);
+ if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
}else{
@@ -2492,7 +2824,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
- unsigned int opt = (unsigned int)integerValue(azArg[2]);
+ unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
} else {
@@ -2505,7 +2837,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
if( nArg==3 ){
- int opt = atoi(azArg[2]);
+ int opt = booleanValue(azArg[2]);
rc = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
} else {
@@ -2541,8 +2873,8 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
- open_db(p);
- sqlite3_busy_timeout(p->db, atoi(azArg[1]));
+ open_db(p, 0);
+ sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
}else
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
@@ -2552,7 +2884,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
- open_db(p);
+ open_db(p, 0);
output_file_close(p->traceOut);
p->traceOut = output_file_open(azArg[1]);
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
@@ -2592,7 +2924,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
int j;
assert( nArg<=ArraySize(azArg) );
for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
- p->colWidth[j-1] = atoi(azArg[j]);
+ p->colWidth[j-1] = (int)integerValue(azArg[j]);
}
}else
@@ -2609,7 +2941,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
-static int _contains_semicolon(const char *z, int N){
+static int line_contains_semicolon(const char *z, int N){
int i;
for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
return 0;
@@ -2644,7 +2976,7 @@ static int _all_whitespace(const char *z){
** than a semi-colon. The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
-static int _is_command_terminator(const char *zLine){
+static int line_is_command_terminator(const char *zLine){
while( IsSpace(zLine[0]) ){ zLine++; };
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
return 1; /* Oracle */
@@ -2660,7 +2992,7 @@ static int _is_command_terminator(const char *zLine){
** Return true if zSql is a complete SQL statement. Return false if it
** ends in the middle of a string literal or C-style comment.
*/
-static int _is_complete(char *zSql, int nSql){
+static int line_is_complete(char *zSql, int nSql){
int rc;
if( zSql==0 ) return 1;
zSql[nSql] = ';';
@@ -2680,20 +3012,21 @@ static int _is_complete(char *zSql, int nSql){
** Return the number of errors.
*/
static int process_input(struct callback_data *p, FILE *in){
- char *zLine = 0;
- char *zSql = 0;
- int nSql = 0;
- int nSqlPrior = 0;
- char *zErrMsg;
- int rc;
- int errCnt = 0;
- int lineno = 0;
- int startline = 0;
+ char *zLine = 0; /* A single input line */
+ char *zSql = 0; /* Accumulated SQL text */
+ int nLine; /* Length of current line */
+ int nSql = 0; /* Bytes of zSql[] used */
+ int nAlloc = 0; /* Allocated zSql[] space */
+ int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
+ char *zErrMsg; /* Error message returned */
+ int rc; /* Error code */
+ int errCnt = 0; /* Number of errors seen */
+ int lineno = 0; /* Current line number */
+ int startline = 0; /* Line number for start of current input */
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
- free(zLine);
- zLine = one_input_line(zSql, in);
+ zLine = one_input_line(in, zLine, nSql>0);
if( zLine==0 ){
/* End of input */
if( stdin_is_interactive ) printf("\n");
@@ -2704,7 +3037,7 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0;
}
lineno++;
- if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
+ if( nSql==0 && _all_whitespace(zLine) ) continue;
if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p);
@@ -2715,38 +3048,35 @@ static int process_input(struct callback_data *p, FILE *in){
}
continue;
}
- if( _is_command_terminator(zLine) && _is_complete(zSql, nSql) ){
+ if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
memcpy(zLine,";",2);
}
+ nLine = strlen30(zLine);
+ if( nSql+nLine+2>=nAlloc ){
+ nAlloc = nSql+nLine+100;
+ zSql = realloc(zSql, nAlloc);
+ if( zSql==0 ){
+ fprintf(stderr, "Error: out of memory\n");
+ exit(1);
+ }
+ }
nSqlPrior = nSql;
- if( zSql==0 ){
+ if( nSql==0 ){
int i;
for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
- if( zLine[i]!=0 ){
- nSql = strlen30(zLine);
- zSql = malloc( nSql+3 );
- if( zSql==0 ){
- fprintf(stderr, "Error: out of memory\n");
- exit(1);
- }
- memcpy(zSql, zLine, nSql+1);
- startline = lineno;
- }
+ assert( nAlloc>0 && zSql!=0 );
+ memcpy(zSql, zLine+i, nLine+1-i);
+ startline = lineno;
+ nSql = nLine-i;
}else{
- int len = strlen30(zLine);
- zSql = realloc( zSql, nSql + len + 4 );
- if( zSql==0 ){
- fprintf(stderr,"Error: out of memory\n");
- exit(1);
- }
zSql[nSql++] = '\n';
- memcpy(&zSql[nSql], zLine, len+1);
- nSql += len;
+ memcpy(zSql+nSql, zLine, nLine+1);
+ nSql += nLine;
}
- if( zSql && _contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
+ if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
&& sqlite3_complete(zSql) ){
p->cnt = 0;
- open_db(p);
+ open_db(p, 0);
BEGIN_TIMER;
rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
END_TIMER;
@@ -2767,16 +3097,12 @@ static int process_input(struct callback_data *p, FILE *in){
}
errCnt++;
}
- free(zSql);
- zSql = 0;
nSql = 0;
- }else if( zSql && _all_whitespace(zSql) ){
- free(zSql);
- zSql = 0;
+ }else if( nSql && _all_whitespace(zSql) ){
nSql = 0;
}
}
- if( zSql ){
+ if( nSql ){
if( !_all_whitespace(zSql) ){
fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
}
@@ -3024,7 +3350,6 @@ int main(int argc, char **argv){
stdin_is_interactive = 0;
}else if( strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
- int j, c;
const char *zSize;
sqlite3_int64 szHeap;
@@ -3078,7 +3403,7 @@ int main(int argc, char **argv){
** to the sqlite command-line tool.
*/
if( access(data.zDbFilename, 0)==0 ){
- open_db(&data);
+ open_db(&data, 0);
}
/* Process the initialization file if there is one. If no -init option
@@ -3158,7 +3483,7 @@ int main(int argc, char **argv){
rc = do_meta_command(z, &data);
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
}else{
- open_db(&data);
+ open_db(&data, 0);
rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
if( zErrMsg!=0 ){
fprintf(stderr,"Error: %s\n", zErrMsg);
@@ -3182,7 +3507,7 @@ int main(int argc, char **argv){
rc = do_meta_command(zFirstCmd, &data);
if( rc==2 ) rc = 0;
}else{
- open_db(&data);
+ open_db(&data, 0);
rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
if( zErrMsg!=0 ){
fprintf(stderr,"Error: %s\n", zErrMsg);
@@ -3229,5 +3554,6 @@ int main(int argc, char **argv){
if( data.db ){
sqlite3_close(data.db);
}
+ sqlite3_free(data.zFreeOnClose);
return rc;
}
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 03fa649610..9c73927982 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.7.17. By combining all the individual C code files into this
+** version 3.8.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -25,549 +25,6 @@
#ifndef SQLITE_API
# define SQLITE_API
#endif
-/************** Begin file sqliteInt.h ***************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Internal interface definitions for SQLite.
-**
-*/
-#ifndef _SQLITEINT_H_
-#define _SQLITEINT_H_
-
-/*
-** These #defines should enable >2GB file support on POSIX if the
-** underlying operating system supports it. If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
-** system #includes. Hence, this block of code must be the very first
-** code in all source files.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: Red Hat 7.2) but you want your code to work
-** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
-** Include the configuration header output by 'configure' if we're using the
-** autoconf-based build
-*/
-#ifdef _HAVE_SQLITE_CONFIG_H
-#include "config.h"
-#endif
-
-/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
-/************** Begin file sqliteLimit.h *************************************/
-/*
-** 2007 May 7
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file defines various limits of what SQLite can process.
-*/
-
-/*
-** The maximum length of a TEXT or BLOB in bytes. This also
-** limits the size of a row in a table or index.
-**
-** The hard limit is the ability of a 32-bit signed integer
-** to count the size: 2^31-1 or 2147483647.
-*/
-#ifndef SQLITE_MAX_LENGTH
-# define SQLITE_MAX_LENGTH 1000000000
-#endif
-
-/*
-** This is the maximum number of
-**
-** * Columns in a table
-** * Columns in an index
-** * Columns in a view
-** * Terms in the SET clause of an UPDATE statement
-** * Terms in the result set of a SELECT statement
-** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement.
-** * Terms in the VALUES clause of an INSERT statement
-**
-** The hard upper limit here is 32676. Most database people will
-** tell you that in a well-normalized database, you usually should
-** not have more than a dozen or so columns in any table. And if
-** that is the case, there is no point in having more than a few
-** dozen values in any of the other situations described above.
-*/
-#ifndef SQLITE_MAX_COLUMN
-# define SQLITE_MAX_COLUMN 2000
-#endif
-
-/*
-** The maximum length of a single SQL statement in bytes.
-**
-** It used to be the case that setting this value to zero would
-** turn the limit off. That is no longer true. It is not possible
-** to turn this limit off.
-*/
-#ifndef SQLITE_MAX_SQL_LENGTH
-# define SQLITE_MAX_SQL_LENGTH 1000000000
-#endif
-
-/*
-** The maximum depth of an expression tree. This is limited to
-** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
-** want to place more severe limits on the complexity of an
-** expression.
-**
-** A value of 0 used to mean that the limit was not enforced.
-** But that is no longer true. The limit is now strictly enforced
-** at all times.
-*/
-#ifndef SQLITE_MAX_EXPR_DEPTH
-# define SQLITE_MAX_EXPR_DEPTH 1000
-#endif
-
-/*
-** The maximum number of terms in a compound SELECT statement.
-** The code generator for compound SELECT statements does one
-** level of recursion for each term. A stack overflow can result
-** if the number of terms is too large. In practice, most SQL
-** never has more than 3 or 4 terms. Use a value of 0 to disable
-** any limit on the number of terms in a compount SELECT.
-*/
-#ifndef SQLITE_MAX_COMPOUND_SELECT
-# define SQLITE_MAX_COMPOUND_SELECT 500
-#endif
-
-/*
-** The maximum number of opcodes in a VDBE program.
-** Not currently enforced.
-*/
-#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
-#endif
-
-/*
-** The maximum number of arguments to an SQL function.
-*/
-#ifndef SQLITE_MAX_FUNCTION_ARG
-# define SQLITE_MAX_FUNCTION_ARG 127
-#endif
-
-/*
-** The maximum number of in-memory pages to use for the main database
-** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
-*/
-#ifndef SQLITE_DEFAULT_CACHE_SIZE
-# define SQLITE_DEFAULT_CACHE_SIZE 2000
-#endif
-#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
-# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
-#endif
-
-/*
-** The default number of frames to accumulate in the log file before
-** checkpointing the database in WAL mode.
-*/
-#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
-# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000
-#endif
-
-/*
-** The maximum number of attached databases. This must be between 0
-** and 62. The upper bound on 62 is because a 64-bit integer bitmap
-** is used internally to track attached databases.
-*/
-#ifndef SQLITE_MAX_ATTACHED
-# define SQLITE_MAX_ATTACHED 10
-#endif
-
-
-/*
-** The maximum value of a ?nnn wildcard that the parser will accept.
-*/
-#ifndef SQLITE_MAX_VARIABLE_NUMBER
-# define SQLITE_MAX_VARIABLE_NUMBER 999
-#endif
-
-/* Maximum page size. The upper bound on this value is 65536. This a limit
-** imposed by the use of 16-bit offsets within each page.
-**
-** Earlier versions of SQLite allowed the user to change this value at
-** compile time. This is no longer permitted, on the grounds that it creates
-** a library that is technically incompatible with an SQLite library
-** compiled with a different limit. If a process operating on a database
-** with a page-size of 65536 bytes crashes, then an instance of SQLite
-** compiled with the default page-size limit will not be able to rollback
-** the aborted transaction. This could lead to database corruption.
-*/
-#ifdef SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_MAX_PAGE_SIZE
-#endif
-#define SQLITE_MAX_PAGE_SIZE 65536
-
-
-/*
-** The default size of a database page.
-*/
-#ifndef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE 1024
-#endif
-#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_DEFAULT_PAGE_SIZE
-# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-/*
-** Ordinarily, if no value is explicitly provided, SQLite creates databases
-** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain
-** device characteristics (sector-size and atomic write() support),
-** SQLite may choose a larger value. This constant is the maximum value
-** SQLite will choose on its own.
-*/
-#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192
-#endif
-#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
-# undef SQLITE_MAX_DEFAULT_PAGE_SIZE
-# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
-#endif
-
-
-/*
-** Maximum number of pages in one database file.
-**
-** This is really just the default value for the max_page_count pragma.
-** This value can be lowered (or raised) at run-time using that the
-** max_page_count macro.
-*/
-#ifndef SQLITE_MAX_PAGE_COUNT
-# define SQLITE_MAX_PAGE_COUNT 1073741823
-#endif
-
-/*
-** Maximum length (in bytes) of the pattern in a LIKE or GLOB
-** operator.
-*/
-#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
-# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
-#endif
-
-/*
-** Maximum depth of recursion for triggers.
-**
-** A value of 1 means that a trigger program will not be able to itself
-** fire any triggers. A value of 0 means that no trigger programs at all
-** may be executed.
-*/
-#ifndef SQLITE_MAX_TRIGGER_DEPTH
-# define SQLITE_MAX_TRIGGER_DEPTH 1000
-#endif
-
-/************** End of sqliteLimit.h *****************************************/
-/************** Continuing where we left off in sqliteInt.h ******************/
-
-/* Disable nuisance warnings on Borland compilers */
-#if defined(__BORLANDC__)
-#pragma warn -rch /* unreachable code */
-#pragma warn -ccc /* Condition is always true or false */
-#pragma warn -aus /* Assigned value is never used */
-#pragma warn -csu /* Comparing signed and unsigned */
-#pragma warn -spa /* Suspicious pointer arithmetic */
-#endif
-
-/* Needed for various definitions... */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
-# define _BSD_SOURCE
-#endif
-
-/*
-** Include standard header files as necessary
-*/
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-/*
-** The following macros are used to cast pointers to integers and
-** integers to pointers. The way you do this varies from one compiler
-** to the next, so we have developed the following set of #if statements
-** to generate appropriate macros for a wide range of compilers.
-**
-** The correct "ANSI" way to do this is to use the intptr_t type.
-** Unfortunately, that typedef is not available on all compilers, or
-** if it is available, it requires an #include of specific headers
-** that vary from one machine to the next.
-**
-** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
-** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
-** So we have to define the macros in different ways depending on the
-** compiler.
-*/
-#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
-# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
-#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
-# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
-# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
-#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
-# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
-#else /* Generates a warning - but it always works */
-# define SQLITE_INT_TO_PTR(X) ((void*)(X))
-# define SQLITE_PTR_TO_INT(X) ((int)(X))
-#endif
-
-/*
-** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
-** 0 means mutexes are permanently disable and the library is never
-** threadsafe. 1 means the library is serialized which is the highest
-** level of threadsafety. 2 means the libary is multithreaded - multiple
-** threads can use SQLite as long as no two threads try to use the same
-** database connection at the same time.
-**
-** Older versions of SQLite used an optional THREADSAFE macro.
-** We support that for legacy.
-*/
-#if !defined(SQLITE_THREADSAFE)
-# if defined(THREADSAFE)
-# define SQLITE_THREADSAFE THREADSAFE
-# else
-# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
-# endif
-#endif
-
-/*
-** Powersafe overwrite is on by default. But can be turned off using
-** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
-*/
-#ifndef SQLITE_POWERSAFE_OVERWRITE
-# define SQLITE_POWERSAFE_OVERWRITE 1
-#endif
-
-/*
-** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
-** It determines whether or not the features related to
-** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
-** be overridden at runtime using the sqlite3_config() API.
-*/
-#if !defined(SQLITE_DEFAULT_MEMSTATUS)
-# define SQLITE_DEFAULT_MEMSTATUS 1
-#endif
-
-/*
-** Exactly one of the following macros must be defined in order to
-** specify which memory allocation subsystem to use.
-**
-** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
-** SQLITE_WIN32_MALLOC // Use Win32 native heap API
-** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails
-** SQLITE_MEMDEBUG // Debugging version of system malloc()
-**
-** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
-** assert() macro is enabled, each call into the Win32 native heap subsystem
-** will cause HeapValidate to be called. If heap validation should fail, an
-** assertion will be triggered.
-**
-** (Historical note: There used to be several other options, but we've
-** pared it down to just these three.)
-**
-** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
-** the default.
-*/
-#if defined(SQLITE_SYSTEM_MALLOC) \
- + defined(SQLITE_WIN32_MALLOC) \
- + defined(SQLITE_ZERO_MALLOC) \
- + defined(SQLITE_MEMDEBUG)>1
-# error "Two or more of the following compile-time configuration options\
- are defined but at most one is allowed:\
- SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
- SQLITE_ZERO_MALLOC"
-#endif
-#if defined(SQLITE_SYSTEM_MALLOC) \
- + defined(SQLITE_WIN32_MALLOC) \
- + defined(SQLITE_ZERO_MALLOC) \
- + defined(SQLITE_MEMDEBUG)==0
-# define SQLITE_SYSTEM_MALLOC 1
-#endif
-
-/*
-** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
-** sizes of memory allocations below this value where possible.
-*/
-#if !defined(SQLITE_MALLOC_SOFT_LIMIT)
-# define SQLITE_MALLOC_SOFT_LIMIT 1024
-#endif
-
-/*
-** We need to define _XOPEN_SOURCE as follows in order to enable
-** recursive mutexes on most Unix systems. But Mac OS X is different.
-** The _XOPEN_SOURCE define causes problems for Mac OS X we are told,
-** so it is omitted there. See ticket #2673.
-**
-** Later we learn that _XOPEN_SOURCE is poorly or incorrectly
-** implemented on some systems. So we avoid defining it at all
-** if it is already defined or if it is unneeded because we are
-** not doing a threadsafe build. Ticket #2681.
-**
-** See also ticket #2741.
-*/
-#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) \
- && !defined(__APPLE__) && SQLITE_THREADSAFE
-# define _XOPEN_SOURCE 500 /* Needed to enable pthread recursive mutexes */
-#endif
-
-/*
-** The TCL headers are only needed when compiling the TCL bindings.
-*/
-#if defined(SQLITE_TCL) || defined(TCLSH)
-# include <tcl.h>
-#endif
-
-/*
-** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
-** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
-** make it true by defining or undefining NDEBUG.
-**
-** Setting NDEBUG makes the code smaller and run faster by disabling the
-** number assert() statements in the code. So we want the default action
-** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
-** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
-** feature.
-*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
-# define NDEBUG 1
-#endif
-#if defined(NDEBUG) && defined(SQLITE_DEBUG)
-# undef NDEBUG
-#endif
-
-/*
-** The testcase() macro is used to aid in coverage testing. When
-** doing coverage testing, the condition inside the argument to
-** testcase() must be evaluated both true and false in order to
-** get full branch coverage. The testcase() macro is inserted
-** to help ensure adequate test coverage in places where simple
-** condition/decision coverage is inadequate. For example, testcase()
-** can be used to make sure boundary values are tested. For
-** bitmask tests, testcase() can be used to make sure each bit
-** is significant and used at least once. On switch statements
-** where multiple cases go to the same block of code, testcase()
-** can insure that all cases are evaluated.
-**
-*/
-#ifdef SQLITE_COVERAGE_TEST
-SQLITE_PRIVATE void sqlite3Coverage(int);
-# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
-#else
-# define testcase(X)
-#endif
-
-/*
-** The TESTONLY macro is used to enclose variable declarations or
-** other bits of code that are needed to support the arguments
-** within testcase() and assert() macros.
-*/
-#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
-# define TESTONLY(X) X
-#else
-# define TESTONLY(X)
-#endif
-
-/*
-** Sometimes we need a small amount of code such as a variable initialization
-** to setup for a later assert() statement. We do not want this code to
-** appear when assert() is disabled. The following macro is therefore
-** used to contain that setup code. The "VVA" acronym stands for
-** "Verification, Validation, and Accreditation". In other words, the
-** code within VVA_ONLY() will only run during verification processes.
-*/
-#ifndef NDEBUG
-# define VVA_ONLY(X) X
-#else
-# define VVA_ONLY(X)
-#endif
-
-/*
-** The ALWAYS and NEVER macros surround boolean expressions which
-** are intended to always be true or false, respectively. Such
-** expressions could be omitted from the code completely. But they
-** are included in a few cases in order to enhance the resilience
-** of SQLite to unexpected behavior - to make the code "self-healing"
-** or "ductile" rather than being "brittle" and crashing at the first
-** hint of unplanned behavior.
-**
-** In other words, ALWAYS and NEVER are added for defensive code.
-**
-** When doing coverage testing ALWAYS and NEVER are hard-coded to
-** be true and false so that the unreachable code then specify will
-** not be counted as untested code.
-*/
-#if defined(SQLITE_COVERAGE_TEST)
-# define ALWAYS(X) (1)
-# define NEVER(X) (0)
-#elif !defined(NDEBUG)
-# define ALWAYS(X) ((X)?1:(assert(0),0))
-# define NEVER(X) ((X)?(assert(0),1):0)
-#else
-# define ALWAYS(X) (X)
-# define NEVER(X) (X)
-#endif
-
-/*
-** Return true (non-zero) if the input is a integer that is too large
-** to fit in 32-bits. This macro is used inside of various testcase()
-** macros to verify that we have tested SQLite for large-file support.
-*/
-#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
-
-/*
-** The macro unlikely() is a hint that surrounds a boolean
-** expression that is usually false. Macro likely() surrounds
-** a boolean expression that is usually true. GCC is able to
-** use these hints to generate better code, sometimes.
-*/
-#if defined(__GNUC__) && 0
-# define likely(X) __builtin_expect((X),1)
-# define unlikely(X) __builtin_expect((X),0)
-#else
-# define likely(X) !!(X)
-# define unlikely(X) !!(X)
-#endif
-
-/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
** 2001 September 15
@@ -678,9 +135,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.7.17"
-#define SQLITE_VERSION_NUMBER 3007017
-#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
+#define SQLITE_VERSION "3.8.2"
+#define SQLITE_VERSION_NUMBER 3008002
+#define SQLITE_SOURCE_ID "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -941,7 +398,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** <ul>
** <li> The application must insure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
+** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** <li> The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
@@ -1018,7 +475,7 @@ SQLITE_API int sqlite3_exec(
** [sqlite3_extended_result_codes()] API.
**
** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
+** One may expect the number of extended result codes will increase
** over time. Software that uses extended result codes should expect
** to see new result codes in future releases of SQLite.
**
@@ -1049,11 +506,15 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
+#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
+#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -1068,8 +529,10 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
+#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -1478,6 +941,14 @@ struct sqlite3_io_methods {
** can be queried by passing in a pointer to a negative number. This
** file-control is used internally to implement [PRAGMA mmap_size].
**
+** <li>[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -1497,6 +968,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
/*
** CAPI3REF: Mutex Handle
@@ -1941,7 +1413,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
** that causes the corresponding memory allocation to fail.
**
-** The xInit method initializes the memory allocator. (For example,
+** The xInit method initializes the memory allocator. For example,
** it might allocate any require mutexes or initialize internal data
** structures. The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
@@ -2183,27 +1655,27 @@ struct sqlite3_mem_methods {
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd> This option takes a single argument of type int. If non-zero, then
+** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
-** is globally disabled. If URI handling is globally enabled, all filenames
+** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
-** connection is opened. If it is globally disabled, filenames are
+** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
-** database connection is opened. By default, URI handling is globally
+** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
-** [SQLITE_USE_URI] symbol defined.
+** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd> This option takes a single integer argument which is interpreted as
+** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
-** full table scans in the query optimizer. The default setting is determined
+** full table scans in the query optimizer. ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
-** malfunction when the optimization is enabled. Providing the ability to
+** when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
@@ -2232,17 +1704,24 @@ struct sqlite3_mem_methods {
**
** [[SQLITE_CONFIG_MMAP_SIZE]]
** <dt>SQLITE_CONFIG_MMAP_SIZE
-** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
+** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
-** The default setting can be overridden by each database connection using
+** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
-** [SQLITE_FCNTL_MMAP_SIZE] file control. The maximum allowed mmap size
+** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
-** [SQLITE_MAX_MMAP_SIZE] compile-time option.
-** If either argument to this option is negative, then that argument is
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
+** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
+** <dd>^This option is only available if SQLite is compiled for Windows
+** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
+** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -2267,6 +1746,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2343,19 +1823,21 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
@@ -3128,9 +2610,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the
-** callback function X. ^The parameter N is the number of
+** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X. ^If N is less than one then the progress
+** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
@@ -3664,7 +3147,6 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
-** the
** </li>
** </ol>
*/
@@ -4326,19 +3808,19 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
**
** <tr><td> NULL <td> INTEGER <td> Result is 0
** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
+** <tr><td> NULL <td> TEXT <td> Result is a NULL pointer
+** <tr><td> NULL <td> BLOB <td> Result is a NULL pointer
** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
+** <tr><td> FLOAT <td> INTEGER <td> [CAST] to INTEGER
** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
+** <tr><td> FLOAT <td> BLOB <td> [CAST] to BLOB
+** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
+** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
** </table>
** </blockquote>)^
@@ -4394,7 +3876,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
@@ -4750,41 +4232,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
**
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
+** some circumstances the associated metadata may be preserved. An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function. ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory
+** allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular. The destructor X in
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
@@ -5089,6 +4579,11 @@ SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
+SQLITE_API int sqlite3_key_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The key */
+);
/*
** Change the key on an open database. If the current database is not
@@ -5102,6 +4597,11 @@ SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
+SQLITE_API int sqlite3_rekey_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The new key */
+);
/*
** Specify the activation key for a SEE database. Unless
@@ -5353,12 +4853,13 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
+** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
@@ -5371,6 +4872,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
@@ -5452,8 +4954,8 @@ SQLITE_API int sqlite3_release_memory(int);
**
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D. Unlike the
-** [sqlite3_release_memory()] interface, this interface is effect even
-** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
** omitted.
**
** See also: [sqlite3_release_memory()]
@@ -5687,11 +5189,24 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
-** See also: [sqlite3_reset_auto_extension()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
*/
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+
+/*
** CAPI3REF: Reset Automatic Extension Loading
**
** ^This interface disables all automatic extensions previously
@@ -5815,10 +5330,22 @@ struct sqlite3_module {
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5843,7 +5370,9 @@ struct sqlite3_index_info {
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
+ double estimatedCost; /* Estimated cost of using this index */
+ /* Fields below are only available in SQLite 3.8.2 and later */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
};
/*
@@ -6047,6 +5576,9 @@ typedef struct sqlite3_blob sqlite3_blob;
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
+** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
+** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
+**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
@@ -6570,7 +6102,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
-#define SQLITE_TESTCTRL_LAST 19
+#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
+#define SQLITE_TESTCTRL_LAST 20
/*
** CAPI3REF: SQLite Runtime Status
@@ -6803,6 +6336,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^ ^The highwater mark is always 0.
+** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@@ -6815,7 +6354,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
@@ -6869,11 +6409,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@@ -7752,7 +7302,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#if 0
} /* End of the 'extern "C"' block */
#endif
-#endif
+#endif /* _SQLITE3_H_ */
/*
** 2010 August 30
@@ -7816,7 +7366,533 @@ struct sqlite3_rtree_geometry {
/************** End of sqlite3.h *********************************************/
+/************** Begin file sqliteInt.h ***************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Internal interface definitions for SQLite.
+**
+*/
+#ifndef _SQLITEINT_H_
+#define _SQLITEINT_H_
+
+/*
+** These #defines should enable >2GB file support on POSIX if the
+** underlying operating system supports it. If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
+** system #includes. Hence, this block of code must be the very first
+** code in all source files.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line. This is necessary if you are compiling
+** on a recent machine (ex: Red Hat 7.2) but you want your code to work
+** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
+** without this option, LFS is enable. But LFS does not exist in the kernel
+** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
+** Include the configuration header output by 'configure' if we're using the
+** autoconf-based build
+*/
+#ifdef _HAVE_SQLITE_CONFIG_H
+#include "config.h"
+#endif
+
+/************** Include sqliteLimit.h in the middle of sqliteInt.h ***********/
+/************** Begin file sqliteLimit.h *************************************/
+/*
+** 2007 May 7
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file defines various limits of what SQLite can process.
+*/
+
+/*
+** The maximum length of a TEXT or BLOB in bytes. This also
+** limits the size of a row in a table or index.
+**
+** The hard limit is the ability of a 32-bit signed integer
+** to count the size: 2^31-1 or 2147483647.
+*/
+#ifndef SQLITE_MAX_LENGTH
+# define SQLITE_MAX_LENGTH 1000000000
+#endif
+
+/*
+** This is the maximum number of
+**
+** * Columns in a table
+** * Columns in an index
+** * Columns in a view
+** * Terms in the SET clause of an UPDATE statement
+** * Terms in the result set of a SELECT statement
+** * Terms in the GROUP BY or ORDER BY clauses of a SELECT statement.
+** * Terms in the VALUES clause of an INSERT statement
+**
+** The hard upper limit here is 32676. Most database people will
+** tell you that in a well-normalized database, you usually should
+** not have more than a dozen or so columns in any table. And if
+** that is the case, there is no point in having more than a few
+** dozen values in any of the other situations described above.
+*/
+#ifndef SQLITE_MAX_COLUMN
+# define SQLITE_MAX_COLUMN 2000
+#endif
+
+/*
+** The maximum length of a single SQL statement in bytes.
+**
+** It used to be the case that setting this value to zero would
+** turn the limit off. That is no longer true. It is not possible
+** to turn this limit off.
+*/
+#ifndef SQLITE_MAX_SQL_LENGTH
+# define SQLITE_MAX_SQL_LENGTH 1000000000
+#endif
+
+/*
+** The maximum depth of an expression tree. This is limited to
+** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might
+** want to place more severe limits on the complexity of an
+** expression.
+**
+** A value of 0 used to mean that the limit was not enforced.
+** But that is no longer true. The limit is now strictly enforced
+** at all times.
+*/
+#ifndef SQLITE_MAX_EXPR_DEPTH
+# define SQLITE_MAX_EXPR_DEPTH 1000
+#endif
+
+/*
+** The maximum number of terms in a compound SELECT statement.
+** The code generator for compound SELECT statements does one
+** level of recursion for each term. A stack overflow can result
+** if the number of terms is too large. In practice, most SQL
+** never has more than 3 or 4 terms. Use a value of 0 to disable
+** any limit on the number of terms in a compount SELECT.
+*/
+#ifndef SQLITE_MAX_COMPOUND_SELECT
+# define SQLITE_MAX_COMPOUND_SELECT 500
+#endif
+
+/*
+** The maximum number of opcodes in a VDBE program.
+** Not currently enforced.
+*/
+#ifndef SQLITE_MAX_VDBE_OP
+# define SQLITE_MAX_VDBE_OP 25000
+#endif
+
+/*
+** The maximum number of arguments to an SQL function.
+*/
+#ifndef SQLITE_MAX_FUNCTION_ARG
+# define SQLITE_MAX_FUNCTION_ARG 127
+#endif
+
+/*
+** The maximum number of in-memory pages to use for the main database
+** table and for temporary tables. The SQLITE_DEFAULT_CACHE_SIZE
+*/
+#ifndef SQLITE_DEFAULT_CACHE_SIZE
+# define SQLITE_DEFAULT_CACHE_SIZE 2000
+#endif
+#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
+# define SQLITE_DEFAULT_TEMP_CACHE_SIZE 500
+#endif
+
+/*
+** The default number of frames to accumulate in the log file before
+** checkpointing the database in WAL mode.
+*/
+#ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
+# define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT 1000
+#endif
+
+/*
+** The maximum number of attached databases. This must be between 0
+** and 62. The upper bound on 62 is because a 64-bit integer bitmap
+** is used internally to track attached databases.
+*/
+#ifndef SQLITE_MAX_ATTACHED
+# define SQLITE_MAX_ATTACHED 10
+#endif
+
+
+/*
+** The maximum value of a ?nnn wildcard that the parser will accept.
+*/
+#ifndef SQLITE_MAX_VARIABLE_NUMBER
+# define SQLITE_MAX_VARIABLE_NUMBER 999
+#endif
+
+/* Maximum page size. The upper bound on this value is 65536. This a limit
+** imposed by the use of 16-bit offsets within each page.
+**
+** Earlier versions of SQLite allowed the user to change this value at
+** compile time. This is no longer permitted, on the grounds that it creates
+** a library that is technically incompatible with an SQLite library
+** compiled with a different limit. If a process operating on a database
+** with a page-size of 65536 bytes crashes, then an instance of SQLite
+** compiled with the default page-size limit will not be able to rollback
+** the aborted transaction. This could lead to database corruption.
+*/
+#ifdef SQLITE_MAX_PAGE_SIZE
+# undef SQLITE_MAX_PAGE_SIZE
+#endif
+#define SQLITE_MAX_PAGE_SIZE 65536
+
+
+/*
+** The default size of a database page.
+*/
+#ifndef SQLITE_DEFAULT_PAGE_SIZE
+# define SQLITE_DEFAULT_PAGE_SIZE 1024
+#endif
+#if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
+# undef SQLITE_DEFAULT_PAGE_SIZE
+# define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
+#endif
+
+/*
+** Ordinarily, if no value is explicitly provided, SQLite creates databases
+** with page size SQLITE_DEFAULT_PAGE_SIZE. However, based on certain
+** device characteristics (sector-size and atomic write() support),
+** SQLite may choose a larger value. This constant is the maximum value
+** SQLite will choose on its own.
+*/
+#ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE
+# define SQLITE_MAX_DEFAULT_PAGE_SIZE 8192
+#endif
+#if SQLITE_MAX_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
+# undef SQLITE_MAX_DEFAULT_PAGE_SIZE
+# define SQLITE_MAX_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
+#endif
+
+
+/*
+** Maximum number of pages in one database file.
+**
+** This is really just the default value for the max_page_count pragma.
+** This value can be lowered (or raised) at run-time using that the
+** max_page_count macro.
+*/
+#ifndef SQLITE_MAX_PAGE_COUNT
+# define SQLITE_MAX_PAGE_COUNT 1073741823
+#endif
+
+/*
+** Maximum length (in bytes) of the pattern in a LIKE or GLOB
+** operator.
+*/
+#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
+# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
+#endif
+
+/*
+** Maximum depth of recursion for triggers.
+**
+** A value of 1 means that a trigger program will not be able to itself
+** fire any triggers. A value of 0 means that no trigger programs at all
+** may be executed.
+*/
+#ifndef SQLITE_MAX_TRIGGER_DEPTH
+# define SQLITE_MAX_TRIGGER_DEPTH 1000
+#endif
+
+/************** End of sqliteLimit.h *****************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
+
+/* Disable nuisance warnings on Borland compilers */
+#if defined(__BORLANDC__)
+#pragma warn -rch /* unreachable code */
+#pragma warn -ccc /* Condition is always true or false */
+#pragma warn -aus /* Assigned value is never used */
+#pragma warn -csu /* Comparing signed and unsigned */
+#pragma warn -spa /* Suspicious pointer arithmetic */
+#endif
+
+/* Needed for various definitions... */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
+# define _BSD_SOURCE
+#endif
+
+/*
+** Include standard header files as necessary
+*/
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+/*
+** The following macros are used to cast pointers to integers and
+** integers to pointers. The way you do this varies from one compiler
+** to the next, so we have developed the following set of #if statements
+** to generate appropriate macros for a wide range of compilers.
+**
+** The correct "ANSI" way to do this is to use the intptr_t type.
+** Unfortunately, that typedef is not available on all compilers, or
+** if it is available, it requires an #include of specific headers
+** that vary from one machine to the next.
+**
+** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
+** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
+** So we have to define the macros in different ways depending on the
+** compiler.
+*/
+#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */
+# define SQLITE_INT_TO_PTR(X) ((void*)(__PTRDIFF_TYPE__)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(__PTRDIFF_TYPE__)(X))
+#elif !defined(__GNUC__) /* Works for compilers other than LLVM */
+# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
+# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
+#elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */
+# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
+#else /* Generates a warning - but it always works */
+# define SQLITE_INT_TO_PTR(X) ((void*)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(X))
+#endif
+
+/*
+** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
+** 0 means mutexes are permanently disable and the library is never
+** threadsafe. 1 means the library is serialized which is the highest
+** level of threadsafety. 2 means the library is multithreaded - multiple
+** threads can use SQLite as long as no two threads try to use the same
+** database connection at the same time.
+**
+** Older versions of SQLite used an optional THREADSAFE macro.
+** We support that for legacy.
+*/
+#if !defined(SQLITE_THREADSAFE)
+# if defined(THREADSAFE)
+# define SQLITE_THREADSAFE THREADSAFE
+# else
+# define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
+# endif
+#endif
+
+/*
+** Powersafe overwrite is on by default. But can be turned off using
+** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
+*/
+#ifndef SQLITE_POWERSAFE_OVERWRITE
+# define SQLITE_POWERSAFE_OVERWRITE 1
+#endif
+
+/*
+** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
+** It determines whether or not the features related to
+** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
+** be overridden at runtime using the sqlite3_config() API.
+*/
+#if !defined(SQLITE_DEFAULT_MEMSTATUS)
+# define SQLITE_DEFAULT_MEMSTATUS 1
+#endif
+
+/*
+** Exactly one of the following macros must be defined in order to
+** specify which memory allocation subsystem to use.
+**
+** SQLITE_SYSTEM_MALLOC // Use normal system malloc()
+** SQLITE_WIN32_MALLOC // Use Win32 native heap API
+** SQLITE_ZERO_MALLOC // Use a stub allocator that always fails
+** SQLITE_MEMDEBUG // Debugging version of system malloc()
+**
+** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
+** assert() macro is enabled, each call into the Win32 native heap subsystem
+** will cause HeapValidate to be called. If heap validation should fail, an
+** assertion will be triggered.
+**
+** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
+** the default.
+*/
+#if defined(SQLITE_SYSTEM_MALLOC) \
+ + defined(SQLITE_WIN32_MALLOC) \
+ + defined(SQLITE_ZERO_MALLOC) \
+ + defined(SQLITE_MEMDEBUG)>1
+# error "Two or more of the following compile-time configuration options\
+ are defined but at most one is allowed:\
+ SQLITE_SYSTEM_MALLOC, SQLITE_WIN32_MALLOC, SQLITE_MEMDEBUG,\
+ SQLITE_ZERO_MALLOC"
+#endif
+#if defined(SQLITE_SYSTEM_MALLOC) \
+ + defined(SQLITE_WIN32_MALLOC) \
+ + defined(SQLITE_ZERO_MALLOC) \
+ + defined(SQLITE_MEMDEBUG)==0
+# define SQLITE_SYSTEM_MALLOC 1
+#endif
+
+/*
+** If SQLITE_MALLOC_SOFT_LIMIT is not zero, then try to keep the
+** sizes of memory allocations below this value where possible.
+*/
+#if !defined(SQLITE_MALLOC_SOFT_LIMIT)
+# define SQLITE_MALLOC_SOFT_LIMIT 1024
+#endif
+
+/*
+** We need to define _XOPEN_SOURCE as follows in order to enable
+** recursive mutexes on most Unix systems and fchmod() on OpenBSD.
+** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit
+** it.
+*/
+#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
+# define _XOPEN_SOURCE 600
+#endif
+
+/*
+** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
+** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
+** make it true by defining or undefining NDEBUG.
+**
+** Setting NDEBUG makes the code smaller and faster by disabling the
+** assert() statements in the code. So we want the default action
+** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
+** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
+** feature.
+*/
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+# define NDEBUG 1
+#endif
+#if defined(NDEBUG) && defined(SQLITE_DEBUG)
+# undef NDEBUG
+#endif
+
+/*
+** Enable SQLITE_ENABLE_EXPLAIN_COMMENTS if SQLITE_DEBUG is turned on.
+*/
+#if !defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) && defined(SQLITE_DEBUG)
+# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1
+#endif
+
+/*
+** The testcase() macro is used to aid in coverage testing. When
+** doing coverage testing, the condition inside the argument to
+** testcase() must be evaluated both true and false in order to
+** get full branch coverage. The testcase() macro is inserted
+** to help ensure adequate test coverage in places where simple
+** condition/decision coverage is inadequate. For example, testcase()
+** can be used to make sure boundary values are tested. For
+** bitmask tests, testcase() can be used to make sure each bit
+** is significant and used at least once. On switch statements
+** where multiple cases go to the same block of code, testcase()
+** can insure that all cases are evaluated.
+**
+*/
+#ifdef SQLITE_COVERAGE_TEST
+SQLITE_PRIVATE void sqlite3Coverage(int);
+# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
+#else
+# define testcase(X)
+#endif
+
+/*
+** The TESTONLY macro is used to enclose variable declarations or
+** other bits of code that are needed to support the arguments
+** within testcase() and assert() macros.
+*/
+#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST)
+# define TESTONLY(X) X
+#else
+# define TESTONLY(X)
+#endif
+
+/*
+** Sometimes we need a small amount of code such as a variable initialization
+** to setup for a later assert() statement. We do not want this code to
+** appear when assert() is disabled. The following macro is therefore
+** used to contain that setup code. The "VVA" acronym stands for
+** "Verification, Validation, and Accreditation". In other words, the
+** code within VVA_ONLY() will only run during verification processes.
+*/
+#ifndef NDEBUG
+# define VVA_ONLY(X) X
+#else
+# define VVA_ONLY(X)
+#endif
+
+/*
+** The ALWAYS and NEVER macros surround boolean expressions which
+** are intended to always be true or false, respectively. Such
+** expressions could be omitted from the code completely. But they
+** are included in a few cases in order to enhance the resilience
+** of SQLite to unexpected behavior - to make the code "self-healing"
+** or "ductile" rather than being "brittle" and crashing at the first
+** hint of unplanned behavior.
+**
+** In other words, ALWAYS and NEVER are added for defensive code.
+**
+** When doing coverage testing ALWAYS and NEVER are hard-coded to
+** be true and false so that the unreachable code they specify will
+** not be counted as untested code.
+*/
+#if defined(SQLITE_COVERAGE_TEST)
+# define ALWAYS(X) (1)
+# define NEVER(X) (0)
+#elif !defined(NDEBUG)
+# define ALWAYS(X) ((X)?1:(assert(0),0))
+# define NEVER(X) ((X)?(assert(0),1):0)
+#else
+# define ALWAYS(X) (X)
+# define NEVER(X) (X)
+#endif
+
+/*
+** Return true (non-zero) if the input is a integer that is too large
+** to fit in 32-bits. This macro is used inside of various testcase()
+** macros to verify that we have tested SQLite for large-file support.
+*/
+#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
+
+/*
+** The macro unlikely() is a hint that surrounds a boolean
+** expression that is usually false. Macro likely() surrounds
+** a boolean expression that is usually true. These hints could,
+** in theory, be used by the compiler to generate better code, but
+** currently they are just comments for human readers.
+*/
+#define likely(X) (X)
+#define unlikely(X) (X)
+
/************** Include hash.h in the middle of sqliteInt.h ******************/
/************** Begin file hash.h ********************************************/
/*
@@ -7944,137 +8020,137 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_LP 22
#define TK_RP 23
#define TK_AS 24
-#define TK_COMMA 25
-#define TK_ID 26
-#define TK_INDEXED 27
-#define TK_ABORT 28
-#define TK_ACTION 29
-#define TK_AFTER 30
-#define TK_ANALYZE 31
-#define TK_ASC 32
-#define TK_ATTACH 33
-#define TK_BEFORE 34
-#define TK_BY 35
-#define TK_CASCADE 36
-#define TK_CAST 37
-#define TK_COLUMNKW 38
-#define TK_CONFLICT 39
-#define TK_DATABASE 40
-#define TK_DESC 41
-#define TK_DETACH 42
-#define TK_EACH 43
-#define TK_FAIL 44
-#define TK_FOR 45
-#define TK_IGNORE 46
-#define TK_INITIALLY 47
-#define TK_INSTEAD 48
-#define TK_LIKE_KW 49
-#define TK_MATCH 50
-#define TK_NO 51
-#define TK_KEY 52
-#define TK_OF 53
-#define TK_OFFSET 54
-#define TK_PRAGMA 55
-#define TK_RAISE 56
-#define TK_REPLACE 57
-#define TK_RESTRICT 58
-#define TK_ROW 59
-#define TK_TRIGGER 60
-#define TK_VACUUM 61
-#define TK_VIEW 62
-#define TK_VIRTUAL 63
-#define TK_REINDEX 64
-#define TK_RENAME 65
-#define TK_CTIME_KW 66
-#define TK_ANY 67
-#define TK_OR 68
-#define TK_AND 69
-#define TK_IS 70
-#define TK_BETWEEN 71
-#define TK_IN 72
-#define TK_ISNULL 73
-#define TK_NOTNULL 74
-#define TK_NE 75
-#define TK_EQ 76
-#define TK_GT 77
-#define TK_LE 78
-#define TK_LT 79
-#define TK_GE 80
-#define TK_ESCAPE 81
-#define TK_BITAND 82
-#define TK_BITOR 83
-#define TK_LSHIFT 84
-#define TK_RSHIFT 85
-#define TK_PLUS 86
-#define TK_MINUS 87
-#define TK_STAR 88
-#define TK_SLASH 89
-#define TK_REM 90
-#define TK_CONCAT 91
-#define TK_COLLATE 92
-#define TK_BITNOT 93
-#define TK_STRING 94
-#define TK_JOIN_KW 95
-#define TK_CONSTRAINT 96
-#define TK_DEFAULT 97
-#define TK_NULL 98
-#define TK_PRIMARY 99
-#define TK_UNIQUE 100
-#define TK_CHECK 101
-#define TK_REFERENCES 102
-#define TK_AUTOINCR 103
-#define TK_ON 104
-#define TK_INSERT 105
-#define TK_DELETE 106
-#define TK_UPDATE 107
-#define TK_SET 108
-#define TK_DEFERRABLE 109
-#define TK_FOREIGN 110
-#define TK_DROP 111
-#define TK_UNION 112
-#define TK_ALL 113
-#define TK_EXCEPT 114
-#define TK_INTERSECT 115
-#define TK_SELECT 116
-#define TK_DISTINCT 117
-#define TK_DOT 118
-#define TK_FROM 119
-#define TK_JOIN 120
-#define TK_USING 121
-#define TK_ORDER 122
-#define TK_GROUP 123
-#define TK_HAVING 124
-#define TK_LIMIT 125
-#define TK_WHERE 126
-#define TK_INTO 127
-#define TK_VALUES 128
-#define TK_INTEGER 129
-#define TK_FLOAT 130
-#define TK_BLOB 131
-#define TK_REGISTER 132
-#define TK_VARIABLE 133
-#define TK_CASE 134
-#define TK_WHEN 135
-#define TK_THEN 136
-#define TK_ELSE 137
-#define TK_INDEX 138
-#define TK_ALTER 139
-#define TK_ADD 140
-#define TK_TO_TEXT 141
-#define TK_TO_BLOB 142
-#define TK_TO_NUMERIC 143
-#define TK_TO_INT 144
-#define TK_TO_REAL 145
-#define TK_ISNOT 146
-#define TK_END_OF_FILE 147
-#define TK_ILLEGAL 148
-#define TK_SPACE 149
-#define TK_UNCLOSED_STRING 150
-#define TK_FUNCTION 151
-#define TK_COLUMN 152
-#define TK_AGG_FUNCTION 153
-#define TK_AGG_COLUMN 154
-#define TK_CONST_FUNC 155
+#define TK_WITHOUT 25
+#define TK_COMMA 26
+#define TK_ID 27
+#define TK_INDEXED 28
+#define TK_ABORT 29
+#define TK_ACTION 30
+#define TK_AFTER 31
+#define TK_ANALYZE 32
+#define TK_ASC 33
+#define TK_ATTACH 34
+#define TK_BEFORE 35
+#define TK_BY 36
+#define TK_CASCADE 37
+#define TK_CAST 38
+#define TK_COLUMNKW 39
+#define TK_CONFLICT 40
+#define TK_DATABASE 41
+#define TK_DESC 42
+#define TK_DETACH 43
+#define TK_EACH 44
+#define TK_FAIL 45
+#define TK_FOR 46
+#define TK_IGNORE 47
+#define TK_INITIALLY 48
+#define TK_INSTEAD 49
+#define TK_LIKE_KW 50
+#define TK_MATCH 51
+#define TK_NO 52
+#define TK_KEY 53
+#define TK_OF 54
+#define TK_OFFSET 55
+#define TK_PRAGMA 56
+#define TK_RAISE 57
+#define TK_REPLACE 58
+#define TK_RESTRICT 59
+#define TK_ROW 60
+#define TK_TRIGGER 61
+#define TK_VACUUM 62
+#define TK_VIEW 63
+#define TK_VIRTUAL 64
+#define TK_REINDEX 65
+#define TK_RENAME 66
+#define TK_CTIME_KW 67
+#define TK_ANY 68
+#define TK_OR 69
+#define TK_AND 70
+#define TK_IS 71
+#define TK_BETWEEN 72
+#define TK_IN 73
+#define TK_ISNULL 74
+#define TK_NOTNULL 75
+#define TK_NE 76
+#define TK_EQ 77
+#define TK_GT 78
+#define TK_LE 79
+#define TK_LT 80
+#define TK_GE 81
+#define TK_ESCAPE 82
+#define TK_BITAND 83
+#define TK_BITOR 84
+#define TK_LSHIFT 85
+#define TK_RSHIFT 86
+#define TK_PLUS 87
+#define TK_MINUS 88
+#define TK_STAR 89
+#define TK_SLASH 90
+#define TK_REM 91
+#define TK_CONCAT 92
+#define TK_COLLATE 93
+#define TK_BITNOT 94
+#define TK_STRING 95
+#define TK_JOIN_KW 96
+#define TK_CONSTRAINT 97
+#define TK_DEFAULT 98
+#define TK_NULL 99
+#define TK_PRIMARY 100
+#define TK_UNIQUE 101
+#define TK_CHECK 102
+#define TK_REFERENCES 103
+#define TK_AUTOINCR 104
+#define TK_ON 105
+#define TK_INSERT 106
+#define TK_DELETE 107
+#define TK_UPDATE 108
+#define TK_SET 109
+#define TK_DEFERRABLE 110
+#define TK_FOREIGN 111
+#define TK_DROP 112
+#define TK_UNION 113
+#define TK_ALL 114
+#define TK_EXCEPT 115
+#define TK_INTERSECT 116
+#define TK_SELECT 117
+#define TK_DISTINCT 118
+#define TK_DOT 119
+#define TK_FROM 120
+#define TK_JOIN 121
+#define TK_USING 122
+#define TK_ORDER 123
+#define TK_GROUP 124
+#define TK_HAVING 125
+#define TK_LIMIT 126
+#define TK_WHERE 127
+#define TK_INTO 128
+#define TK_VALUES 129
+#define TK_INTEGER 130
+#define TK_FLOAT 131
+#define TK_BLOB 132
+#define TK_REGISTER 133
+#define TK_VARIABLE 134
+#define TK_CASE 135
+#define TK_WHEN 136
+#define TK_THEN 137
+#define TK_ELSE 138
+#define TK_INDEX 139
+#define TK_ALTER 140
+#define TK_ADD 141
+#define TK_TO_TEXT 142
+#define TK_TO_BLOB 143
+#define TK_TO_NUMERIC 144
+#define TK_TO_INT 145
+#define TK_TO_REAL 146
+#define TK_ISNOT 147
+#define TK_END_OF_FILE 148
+#define TK_ILLEGAL 149
+#define TK_SPACE 150
+#define TK_UNCLOSED_STRING 151
+#define TK_FUNCTION 152
+#define TK_COLUMN 153
+#define TK_AGG_FUNCTION 154
+#define TK_AGG_COLUMN 155
#define TK_UMINUS 156
#define TK_UPLUS 157
@@ -8154,6 +8230,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#endif
/*
+** Macros to compute minimum and maximum of two numbers.
+*/
+#define MIN(A,B) ((A)<(B)?(A):(B))
+#define MAX(A,B) ((A)>(B)?(A):(B))
+
+/*
** Check to see if this machine uses EBCDIC. (Yes, believe it or
** not, there are still machines out there that use EBCDIC.)
*/
@@ -8237,6 +8319,31 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
#endif
/*
+** Estimated quantities used for query planning are stored as 16-bit
+** logarithms. For quantity X, the value stored is 10*log2(X). This
+** gives a possible range of values of approximately 1.0e986 to 1e-986.
+** But the allowed values are "grainy". Not every value is representable.
+** For example, quantities 16 and 17 are both represented by a LogEst
+** of 40. However, since LogEst quantatites are suppose to be estimates,
+** not exact values, this imprecision is not a problem.
+**
+** "LogEst" is short for "Logarithimic Estimate".
+**
+** Examples:
+** 1 -> 0 20 -> 43 10000 -> 132
+** 2 -> 10 25 -> 46 25000 -> 146
+** 3 -> 16 100 -> 66 1000000 -> 199
+** 4 -> 20 1000 -> 99 1048576 -> 200
+** 10 -> 33 1024 -> 100 4294967296 -> 320
+**
+** The LogEst can be negative to indicate fractional values.
+** Examples:
+**
+** 0.5 -> -10 0.1 -> -33 0.0625 -> -40
+*/
+typedef INT16_TYPE LogEst;
+
+/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
@@ -8335,6 +8442,20 @@ SQLITE_PRIVATE const int sqlite3one;
#endif
/*
+** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
+** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also
+** define SQLITE_ENABLE_STAT3_OR_STAT4
+*/
+#ifdef SQLITE_ENABLE_STAT4
+# undef SQLITE_ENABLE_STAT3
+# define SQLITE_ENABLE_STAT3_OR_STAT4 1
+#elif SQLITE_ENABLE_STAT3
+# define SQLITE_ENABLE_STAT3_OR_STAT4 1
+#elif SQLITE_ENABLE_STAT3_OR_STAT4
+# undef SQLITE_ENABLE_STAT3_OR_STAT4
+#endif
+
+/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**
@@ -8478,9 +8599,7 @@ typedef struct UnpackedRecord UnpackedRecord;
typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
-typedef struct WherePlan WherePlan;
typedef struct WhereInfo WhereInfo;
-typedef struct WhereLevel WhereLevel;
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
@@ -8555,7 +8674,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int,int);
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
@@ -8669,8 +8788,8 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
+SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
+SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
@@ -8779,7 +8898,6 @@ typedef struct Vdbe Vdbe;
** The names of the following types declared in vdbeInt.h are required
** for the VdbeOp definition.
*/
-typedef struct VdbeFunc VdbeFunc;
typedef struct Mem Mem;
typedef struct SubProgram SubProgram;
@@ -8803,7 +8921,6 @@ struct VdbeOp {
i64 *pI64; /* Used when p4type is P4_INT64 */
double *pReal; /* Used when p4type is P4_REAL */
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
- VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
Mem *pMem; /* Used when p4type is P4_MEM */
VTable *pVtab; /* Used when p4type is P4_VTAB */
@@ -8812,7 +8929,7 @@ struct VdbeOp {
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
int (*xAdvance)(BtCursor *, int *);
} p4;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
@@ -8857,7 +8974,6 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
-#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
@@ -8869,15 +8985,11 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-/* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
-** is made. That copy is freed when the Vdbe is finalized. But if the
-** argument is P4_KEYINFO_HANDOFF, the passed in pointer is used. It still
-** gets freed when the Vdbe is finalized so it still should be obtained
-** from a single sqliteMalloc(). But no copy is made and the calling
-** function should *not* try to free the KeyInfo.
-*/
-#define P4_KEYINFO_HANDOFF (-16)
-#define P4_KEYINFO_STATIC (-17)
+/* Error message codes for OP_Halt */
+#define P5_ConstraintNotNull 1
+#define P5_ConstraintUnique 2
+#define P5_ConstraintCheck 3
+#define P5_ConstraintFK 4
/*
** The Vdbe.aColName array contains 5n Mem structures, where n is the
@@ -8914,156 +9026,158 @@ typedef struct VdbeOpList VdbeOpList;
/************** Begin file opcodes.h *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodeh.awk script for details */
-#define OP_Goto 1
-#define OP_Gosub 2
-#define OP_Return 3
-#define OP_Yield 4
-#define OP_HaltIfNull 5
-#define OP_Halt 6
-#define OP_Integer 7
-#define OP_Int64 8
-#define OP_Real 130 /* same as TK_FLOAT */
-#define OP_String8 94 /* same as TK_STRING */
-#define OP_String 9
-#define OP_Null 10
-#define OP_Blob 11
-#define OP_Variable 12
-#define OP_Move 13
-#define OP_Copy 14
-#define OP_SCopy 15
-#define OP_ResultRow 16
-#define OP_Concat 91 /* same as TK_CONCAT */
-#define OP_Add 86 /* same as TK_PLUS */
-#define OP_Subtract 87 /* same as TK_MINUS */
-#define OP_Multiply 88 /* same as TK_STAR */
-#define OP_Divide 89 /* same as TK_SLASH */
-#define OP_Remainder 90 /* same as TK_REM */
-#define OP_CollSeq 17
-#define OP_Function 18
-#define OP_BitAnd 82 /* same as TK_BITAND */
-#define OP_BitOr 83 /* same as TK_BITOR */
-#define OP_ShiftLeft 84 /* same as TK_LSHIFT */
-#define OP_ShiftRight 85 /* same as TK_RSHIFT */
-#define OP_AddImm 20
-#define OP_MustBeInt 21
-#define OP_RealAffinity 22
-#define OP_ToText 141 /* same as TK_TO_TEXT */
-#define OP_ToBlob 142 /* same as TK_TO_BLOB */
-#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
-#define OP_ToInt 144 /* same as TK_TO_INT */
-#define OP_ToReal 145 /* same as TK_TO_REAL */
-#define OP_Eq 76 /* same as TK_EQ */
-#define OP_Ne 75 /* same as TK_NE */
-#define OP_Lt 79 /* same as TK_LT */
-#define OP_Le 78 /* same as TK_LE */
-#define OP_Gt 77 /* same as TK_GT */
-#define OP_Ge 80 /* same as TK_GE */
-#define OP_Permutation 23
-#define OP_Compare 24
-#define OP_Jump 25
-#define OP_And 69 /* same as TK_AND */
-#define OP_Or 68 /* same as TK_OR */
-#define OP_Not 19 /* same as TK_NOT */
-#define OP_BitNot 93 /* same as TK_BITNOT */
-#define OP_Once 26
-#define OP_If 27
-#define OP_IfNot 28
-#define OP_IsNull 73 /* same as TK_ISNULL */
-#define OP_NotNull 74 /* same as TK_NOTNULL */
-#define OP_Column 29
-#define OP_Affinity 30
-#define OP_MakeRecord 31
-#define OP_Count 32
-#define OP_Savepoint 33
-#define OP_AutoCommit 34
-#define OP_Transaction 35
-#define OP_ReadCookie 36
-#define OP_SetCookie 37
-#define OP_VerifyCookie 38
-#define OP_OpenRead 39
-#define OP_OpenWrite 40
-#define OP_OpenAutoindex 41
-#define OP_OpenEphemeral 42
-#define OP_SorterOpen 43
-#define OP_OpenPseudo 44
-#define OP_Close 45
-#define OP_SeekLt 46
-#define OP_SeekLe 47
-#define OP_SeekGe 48
-#define OP_SeekGt 49
-#define OP_Seek 50
-#define OP_NotFound 51
-#define OP_Found 52
-#define OP_IsUnique 53
-#define OP_NotExists 54
-#define OP_Sequence 55
-#define OP_NewRowid 56
-#define OP_Insert 57
-#define OP_InsertInt 58
-#define OP_Delete 59
-#define OP_ResetCount 60
-#define OP_SorterCompare 61
-#define OP_SorterData 62
-#define OP_RowKey 63
-#define OP_RowData 64
-#define OP_Rowid 65
-#define OP_NullRow 66
-#define OP_Last 67
-#define OP_SorterSort 70
-#define OP_Sort 71
-#define OP_Rewind 72
-#define OP_SorterNext 81
-#define OP_Prev 92
-#define OP_Next 95
-#define OP_SorterInsert 96
-#define OP_IdxInsert 97
-#define OP_IdxDelete 98
-#define OP_IdxRowid 99
-#define OP_IdxLT 100
-#define OP_IdxGE 101
-#define OP_Destroy 102
-#define OP_Clear 103
-#define OP_CreateIndex 104
-#define OP_CreateTable 105
-#define OP_ParseSchema 106
-#define OP_LoadAnalysis 107
-#define OP_DropTable 108
-#define OP_DropIndex 109
-#define OP_DropTrigger 110
-#define OP_IntegrityCk 111
-#define OP_RowSetAdd 112
-#define OP_RowSetRead 113
-#define OP_RowSetTest 114
-#define OP_Program 115
-#define OP_Param 116
-#define OP_FkCounter 117
-#define OP_FkIfZero 118
-#define OP_MemMax 119
-#define OP_IfPos 120
-#define OP_IfNeg 121
-#define OP_IfZero 122
-#define OP_AggStep 123
-#define OP_AggFinal 124
-#define OP_Checkpoint 125
-#define OP_JournalMode 126
-#define OP_Vacuum 127
-#define OP_IncrVacuum 128
-#define OP_Expire 129
-#define OP_TableLock 131
-#define OP_VBegin 132
-#define OP_VCreate 133
-#define OP_VDestroy 134
-#define OP_VOpen 135
-#define OP_VFilter 136
-#define OP_VColumn 137
-#define OP_VNext 138
-#define OP_VRename 139
-#define OP_VUpdate 140
-#define OP_Pagecount 146
-#define OP_MaxPgcnt 147
-#define OP_Trace 148
-#define OP_Noop 149
-#define OP_Explain 150
+#define OP_Function 1 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Savepoint 2
+#define OP_AutoCommit 3
+#define OP_Transaction 4
+#define OP_SorterNext 5
+#define OP_PrevIfOpen 6
+#define OP_NextIfOpen 7
+#define OP_Prev 8
+#define OP_Next 9
+#define OP_AggStep 10 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_Checkpoint 11
+#define OP_JournalMode 12
+#define OP_Vacuum 13
+#define OP_VFilter 14 /* synopsis: iPlan=r[P3] zPlan='P4' */
+#define OP_VUpdate 15 /* synopsis: data=r[P3@P2] */
+#define OP_Goto 16
+#define OP_Gosub 17
+#define OP_Return 18
+#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
+#define OP_Yield 20
+#define OP_HaltIfNull 21 /* synopsis: if r[P3] null then halt */
+#define OP_Halt 22
+#define OP_Integer 23 /* synopsis: r[P2]=P1 */
+#define OP_Int64 24 /* synopsis: r[P2]=P4 */
+#define OP_String 25 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 26 /* synopsis: r[P2..P3]=NULL */
+#define OP_Blob 27 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 28 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 29 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 30 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_SCopy 31 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 32 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 33
+#define OP_AddImm 34 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_MustBeInt 35
+#define OP_RealAffinity 36
+#define OP_Permutation 37
+#define OP_Compare 38
+#define OP_Jump 39
+#define OP_Once 40
+#define OP_If 41
+#define OP_IfNot 42
+#define OP_Column 43 /* synopsis: r[P3]=PX */
+#define OP_Affinity 44 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 45 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 46 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 47
+#define OP_SetCookie 48
+#define OP_VerifyCookie 49
+#define OP_OpenRead 50 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 51 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 52 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 53 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 54
+#define OP_OpenPseudo 55 /* synopsis: content in r[P2@P3] */
+#define OP_Close 56
+#define OP_SeekLt 57 /* synopsis: key=r[P3@P4] */
+#define OP_SeekLe 58 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGe 59 /* synopsis: key=r[P3@P4] */
+#define OP_SeekGt 60 /* synopsis: key=r[P3@P4] */
+#define OP_Seek 61 /* synopsis: intkey=r[P2] */
+#define OP_NoConflict 62 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 63 /* synopsis: key=r[P3@P4] */
+#define OP_Found 64 /* synopsis: key=r[P3@P4] */
+#define OP_NotExists 65 /* synopsis: intkey=r[P3] */
+#define OP_Sequence 66 /* synopsis: r[P2]=rowid */
+#define OP_NewRowid 67 /* synopsis: r[P2]=rowid */
+#define OP_Insert 68 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_Or 69 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 70 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_InsertInt 71 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 72
+#define OP_ResetCount 73
+#define OP_IsNull 74 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 75 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 76 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+#define OP_Eq 77 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+#define OP_Gt 78 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+#define OP_Le 79 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+#define OP_Lt 80 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
+#define OP_Ge 81 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
+#define OP_SorterCompare 82 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */
+#define OP_BitAnd 83 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 84 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 85 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 86 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 87 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 88 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 89 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 90 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 91 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 92 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_SorterData 93 /* synopsis: r[P2]=data */
+#define OP_BitNot 94 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_String8 95 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_RowKey 96 /* synopsis: r[P2]=key */
+#define OP_RowData 97 /* synopsis: r[P2]=data */
+#define OP_Rowid 98 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 99
+#define OP_Last 100
+#define OP_SorterSort 101
+#define OP_Sort 102
+#define OP_Rewind 103
+#define OP_SorterInsert 104
+#define OP_IdxInsert 105 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 106 /* synopsis: key=r[P2@P3] */
+#define OP_IdxRowid 107 /* synopsis: r[P2]=rowid */
+#define OP_IdxLT 108 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 109 /* synopsis: key=r[P3@P4] */
+#define OP_Destroy 110
+#define OP_Clear 111
+#define OP_CreateIndex 112 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 113 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_ParseSchema 114
+#define OP_LoadAnalysis 115
+#define OP_DropTable 116
+#define OP_DropIndex 117
+#define OP_DropTrigger 118
+#define OP_IntegrityCk 119
+#define OP_RowSetAdd 120 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetRead 121 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 122 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 123
+#define OP_Param 124
+#define OP_FkCounter 125 /* synopsis: fkctr[P1]+=P2 */
+#define OP_FkIfZero 126 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_MemMax 127 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_IfPos 128 /* synopsis: if r[P1]>0 goto P2 */
+#define OP_IfNeg 129 /* synopsis: if r[P1]<0 goto P2 */
+#define OP_IfZero 130 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
+#define OP_Real 131 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_AggFinal 132 /* synopsis: accum=r[P1] N=P2 */
+#define OP_IncrVacuum 133
+#define OP_Expire 134
+#define OP_TableLock 135 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 136
+#define OP_VCreate 137
+#define OP_VDestroy 138
+#define OP_VOpen 139
+#define OP_VColumn 140 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VNext 141
+#define OP_ToText 142 /* same as TK_TO_TEXT */
+#define OP_ToBlob 143 /* same as TK_TO_BLOB */
+#define OP_ToNumeric 144 /* same as TK_TO_NUMERIC */
+#define OP_ToInt 145 /* same as TK_TO_INT */
+#define OP_ToReal 146 /* same as TK_TO_REAL */
+#define OP_VRename 147
+#define OP_Pagecount 148
+#define OP_MaxPgcnt 149
+#define OP_Trace 150
+#define OP_Noop 151
+#define OP_Explain 152
/* Properties such as "out2" or "jump" that are specified in
@@ -9078,25 +9192,26 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
#define OPFLG_INITIALIZER {\
-/* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
-/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
-/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
-/* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
-/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
-/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
-/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
-/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
-/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
-/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
-/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
-/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
-/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
+/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
+/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\
+/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x04, 0x10, 0x00, 0x02,\
+/* 24 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x20,\
+/* 32 */ 0x00, 0x00, 0x04, 0x05, 0x04, 0x00, 0x00, 0x01,\
+/* 40 */ 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x02,\
+/* 48 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 56 */ 0x00, 0x11, 0x11, 0x11, 0x11, 0x08, 0x11, 0x11,\
+/* 64 */ 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c, 0x4c, 0x00,\
+/* 72 */ 0x00, 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15,\
+/* 80 */ 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
+/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02,\
+/* 96 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,\
+/* 104 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
+/* 112 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 120 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
+/* 128 */ 0x05, 0x05, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00,\
+/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x04,\
+/* 144 */ 0x04, 0x04, 0x04, 0x00, 0x02, 0x02, 0x00, 0x00,\
+/* 152 */ 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -9121,6 +9236,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
+SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*);
@@ -9133,7 +9249,6 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int);
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*);
#endif
SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*);
@@ -9145,7 +9260,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
#ifndef SQLITE_OMIT_TRACE
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
@@ -9159,15 +9274,27 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *,
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
-
-#ifndef NDEBUG
+/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
+** each VDBE opcode.
+**
+** Use the SQLITE_ENABLE_MODULE_COMMENTS macro to see some extra no-op
+** comments in VDBE programs that show key decision points in the code
+** generator.
+*/
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...);
# define VdbeComment(X) sqlite3VdbeComment X
SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeNoopComment(X) sqlite3VdbeNoopComment X
+# ifdef SQLITE_ENABLE_MODULE_COMMENTS
+# define VdbeModuleComment(X) sqlite3VdbeNoopComment X
+# else
+# define VdbeModuleComment(X)
+# endif
#else
# define VdbeComment(X)
# define VdbeNoopComment(X)
+# define VdbeModuleComment(X)
#endif
#endif
@@ -9259,8 +9386,20 @@ typedef struct PgHdr DbPage;
/*
** Flags that make up the mask passed to sqlite3PagerAcquire().
*/
-#define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */
-#define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */
+#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
+#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
+
+/*
+** Flags for sqlite3PagerSetFlags()
+*/
+#define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */
+#define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */
+#define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */
+#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */
+#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */
+#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */
+#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */
+#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */
/*
** The remainder of this file contains the declarations of the functions
@@ -9288,7 +9427,7 @@ SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int,int);
+SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
@@ -9917,7 +10056,6 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
struct Db {
char *zName; /* Name of this database */
Btree *pBt; /* The B*Tree structure for this database file */
- u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 safety_level; /* How aggressive at syncing data to disk */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
};
@@ -10063,9 +10201,10 @@ struct sqlite3 {
u8 busy; /* TRUE if currently initializing */
u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */
} init;
- int activeVdbeCnt; /* Number of VDBEs currently executing */
- int writeVdbeCnt; /* Number of active VDBEs that are writing */
- int vdbeExecCnt; /* Number of nested calls to VdbeExec() */
+ int nVdbeActive; /* Number of VDBEs currently running */
+ int nVdbeRead; /* Number of active VDBEs that read or write */
+ int nVdbeWrite; /* Number of active VDBEs that read and write */
+ int nVdbeExec; /* Number of nested calls to VdbeExec() */
int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */
void (*xTrace)(void*,const char*); /* Trace function */
@@ -10086,8 +10225,6 @@ struct sqlite3 {
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*);
void *pCollNeededArg;
sqlite3_value *pErr; /* Most recent error message */
- char *zErrMsg; /* Most recent error message (UTF-8 encoded) */
- char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */
union {
volatile int isInterrupted; /* True if sqlite3_interrupt has been called */
double notUsed1; /* Spacer */
@@ -10101,7 +10238,7 @@ struct sqlite3 {
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int (*xProgress)(void *); /* The progress callback */
void *pProgressArg; /* Argument to the progress callback */
- int nProgressOps; /* Number of opcodes for progress callback */
+ unsigned nProgressOps; /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nVTrans; /* Allocated size of aVTrans */
@@ -10119,6 +10256,7 @@ struct sqlite3 {
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
i64 nDeferredCons; /* Net deferred constraints this transaction. */
+ i64 nDeferredImmCons; /* Net deferred immediate constraints */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -10150,30 +10288,35 @@ struct sqlite3 {
*/
#define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
#define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */
-#define SQLITE_FullColNames 0x00000004 /* Show full column names on SELECT */
-#define SQLITE_ShortColNames 0x00000008 /* Show short columns names */
-#define SQLITE_CountRows 0x00000010 /* Count rows changed by INSERT, */
+#define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */
+#define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */
+#define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */
+#define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
+#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
+#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
-#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
+#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
/* result set is empty */
-#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
-#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
-#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
-#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */
-#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
-#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
-#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
-#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
-#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
-#define SQLITE_RecoveryMode 0x00008000 /* Ignore schema errors */
-#define SQLITE_ReverseOrder 0x00010000 /* Reverse unordered SELECTs */
-#define SQLITE_RecTriggers 0x00020000 /* Enable recursive triggers */
-#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
-#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
-#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
-#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
+#define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */
+#define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */
+#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */
+#define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */
+#define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */
+#define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */
+#define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */
+#define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */
+#define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */
+#define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */
+#define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */
+#define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */
+#define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */
+#define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */
+#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
+#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
+
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -10190,6 +10333,9 @@ struct sqlite3 {
#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
#define SQLITE_Transitive 0x0200 /* Transitive constraints */
+#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
+#define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */
+#define SQLITE_AdjustOutEst 0x1000 /* Adjust output estimates using WHERE */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -10204,6 +10350,13 @@ struct sqlite3 {
#endif
/*
+** Return true if it OK to factor constant expressions into the initialization
+** code. The argument is a Parse object for the code generator.
+*/
+#define ConstFactorOk(P) \
+ ((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst))
+
+/*
** Possible values for the sqlite.magic field.
** The numbers are obtained at random and have no special meaning, other
** than being distinct from one another.
@@ -10223,8 +10376,7 @@ struct sqlite3 {
*/
struct FuncDef {
i16 nArg; /* Number of arguments. -1 means unlimited */
- u8 iPrefEnc; /* Preferred text encoding (SQLITE_UTF8, 16LE, 16BE) */
- u8 flags; /* Some combination of SQLITE_FUNC_* */
+ u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */
void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
@@ -10260,14 +10412,17 @@ struct FuncDestructor {
** values must correspond to OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG. There
** are assert() statements in the code to verify this.
*/
-#define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */
-#define SQLITE_FUNC_CASE 0x02 /* Case-sensitive LIKE-type function */
-#define SQLITE_FUNC_EPHEM 0x04 /* Ephemeral. Delete with VDBE */
-#define SQLITE_FUNC_NEEDCOLL 0x08 /* sqlite3GetFuncCollSeq() might be called */
-#define SQLITE_FUNC_COUNT 0x10 /* Built-in count(*) aggregate */
-#define SQLITE_FUNC_COALESCE 0x20 /* Built-in coalesce() or ifnull() function */
-#define SQLITE_FUNC_LENGTH 0x40 /* Built-in length() function */
-#define SQLITE_FUNC_TYPEOF 0x80 /* Built-in typeof() function */
+#define SQLITE_FUNC_ENCMASK 0x003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
+#define SQLITE_FUNC_LIKE 0x004 /* Candidate for the LIKE optimization */
+#define SQLITE_FUNC_CASE 0x008 /* Case-sensitive LIKE-type function */
+#define SQLITE_FUNC_EPHEM 0x010 /* Ephemeral. Delete with VDBE */
+#define SQLITE_FUNC_NEEDCOLL 0x020 /* sqlite3GetFuncCollSeq() might be called */
+#define SQLITE_FUNC_LENGTH 0x040 /* Built-in length() function */
+#define SQLITE_FUNC_TYPEOF 0x080 /* Built-in typeof() function */
+#define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */
+#define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
+#define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
+#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -10280,6 +10435,9 @@ struct FuncDestructor {
** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
+** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
+**
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
** Used to create an aggregate function definition implemented by
** the C functions xStep and xFinal. The first four parameters
@@ -10295,18 +10453,22 @@ struct FuncDestructor {
** parameter.
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL), \
+ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
+#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
- {nArg, SQLITE_UTF8, (bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
+ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0}
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
+ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
pArg, 0, xFunc, 0, 0, #zName, 0, 0}
#define LIKEFUNC(zName, nArg, arg, flags) \
- {nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
+ {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
+ (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0}
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
- {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
+ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
/*
@@ -10318,6 +10480,7 @@ struct FuncDestructor {
struct Savepoint {
char *zName; /* Savepoint name (nul-terminated) */
i64 nDeferredCons; /* Number of deferred fk violations */
+ i64 nDeferredImmCons; /* Number of deferred imm fk. */
Savepoint *pNext; /* Parent savepoint (if any) */
};
@@ -10354,7 +10517,8 @@ struct Column {
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
- u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
+ u8 szEst; /* Estimated size of this column. INT==1 */
+ u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
@@ -10518,6 +10682,7 @@ struct Table {
i16 iPKey; /* If not negative, use aCol[iPKey] as the primary key */
i16 nCol; /* Number of columns in this table */
u16 nRef; /* Number of pointers to this Table */
+ LogEst szTabRow; /* Estimated size of each table row in bytes */
u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
@@ -10541,6 +10706,7 @@ struct Table {
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
#define TF_Virtual 0x10 /* Is a virtual table */
+#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
/*
@@ -10556,6 +10722,9 @@ struct Table {
# define IsHiddenColumn(X) 0
#endif
+/* Does the table have a rowid */
+#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
+
/*
** Each foreign key constraint is an instance of the following structure.
**
@@ -10570,26 +10739,35 @@ struct Table {
** );
**
** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
+** Equivalent names:
+**
+** from-table == child-table
+** to-table == parent-table
**
** Each REFERENCES clause generates an instance of the following structure
** which is attached to the from-table. The to-table need not exist when
** the from-table is created. The existence of the to-table is not checked.
+**
+** The list of all parents for child Table X is held at X.pFKey.
+**
+** A list of all children for a table named Z (which might not even exist)
+** is held in Schema.fkeyHash with a hash key of Z.
*/
struct FKey {
Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */
- FKey *pNextFrom; /* Next foreign key in pFrom */
+ FKey *pNextFrom; /* Next FKey with the same in pFrom. Next parent of pFrom */
char *zTo; /* Name of table that the key points to (aka: Parent) */
- FKey *pNextTo; /* Next foreign key on table named zTo */
- FKey *pPrevTo; /* Previous foreign key on table named zTo */
+ FKey *pNextTo; /* Next with the same zTo. Next child of zTo. */
+ FKey *pPrevTo; /* Previous with the same zTo */
int nCol; /* Number of columns in this key */
/* EV: R-30323-21917 */
- u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
- u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
- Trigger *apTrigger[2]; /* Triggers for aAction[] actions */
- struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
- int iFrom; /* Index of column in pFrom */
- char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
- } aCol[1]; /* One entry for each of nCol column s */
+ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
+ u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */
+ Trigger *apTrigger[2];/* Triggers for aAction[] actions */
+ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
+ int iFrom; /* Index of column in pFrom */
+ char *zCol; /* Name of column in zTo. If NULL use PRIMARY KEY */
+ } aCol[1]; /* One entry for each of nCol columns */
};
/*
@@ -10629,19 +10807,25 @@ struct FKey {
#define OE_SetDflt 8 /* Set the foreign key value to its default */
#define OE_Cascade 9 /* Cascade the changes */
-#define OE_Default 99 /* Do whatever the default action is */
+#define OE_Default 10 /* Do whatever the default action is */
/*
** An instance of the following structure is passed as the first
** argument to sqlite3VdbeKeyCompare and is used to control the
** comparison of the two index keys.
+**
+** Note that aSortOrder[] and aColl[] have nField+1 slots. There
+** are nField slots for the columns of an index then one extra slot
+** for the rowid at the end.
*/
struct KeyInfo {
- sqlite3 *db; /* The database connection */
+ u32 nRef; /* Number of references to this KeyInfo object */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
- u16 nField; /* Number of entries in aColl[] */
- u8 *aSortOrder; /* Sort order for each column. May be NULL */
+ u16 nField; /* Number of key columns in the index */
+ u16 nXField; /* Number of columns beyond the key columns */
+ sqlite3 *db; /* The database connection */
+ u8 *aSortOrder; /* Sort order for each column. */
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
};
@@ -10663,7 +10847,6 @@ struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
u8 flags; /* Boolean settings. UNPACKED_... below */
- i64 rowid; /* Used by UNPACKED_PREFIX_SEARCH */
Mem *aMem; /* Values */
};
@@ -10672,7 +10855,6 @@ struct UnpackedRecord {
*/
#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
-#define UNPACKED_PREFIX_SEARCH 0x04 /* Ignore final (rowid) field */
/*
** Each SQL index is represented in memory by an
@@ -10702,7 +10884,7 @@ struct UnpackedRecord {
*/
struct Index {
char *zName; /* Name of this index */
- int *aiColumn; /* Which columns are used by this index. 1st is 0 */
+ i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */
Table *pTable; /* The SQL table being indexed */
char *zColAff; /* String defining the affinity of each column */
@@ -10710,14 +10892,22 @@ struct Index {
Schema *pSchema; /* Schema containing this index */
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
char **azColl; /* Array of collation sequence names for index */
+ Expr *pPartIdxWhere; /* WHERE clause for partial indices */
+ KeyInfo *pKeyInfo; /* A KeyInfo object suitable for this index */
int tnum; /* DB Page containing root of this index */
- u16 nColumn; /* Number of columns in table used by this index */
+ LogEst szIdxRow; /* Estimated average row size in bytes */
+ u16 nKeyCol; /* Number of columns forming the key */
+ u16 nColumn; /* Number of columns stored in the index */
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
unsigned bUnordered:1; /* Use this index for == or IN queries only */
-#ifdef SQLITE_ENABLE_STAT3
+ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
+ unsigned isResized:1; /* True if resizeIndexObject() has been called */
+ unsigned isCovering:1; /* True if this is a covering index */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
- tRowcnt avgEq; /* Average nEq value for key values not in aSample */
+ int nSampleCol; /* Size of IndexSample.anEq[] and so on */
+ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
IndexSample *aSample; /* Samples of the left-most key */
#endif
};
@@ -10728,16 +10918,11 @@ struct Index {
** analyze.c source file for additional information.
*/
struct IndexSample {
- union {
- char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
- double r; /* Value if eType is SQLITE_FLOAT */
- i64 i; /* Value if eType is SQLITE_INTEGER */
- } u;
- u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
- int nByte; /* Size in byte of text or blob. */
- tRowcnt nEq; /* Est. number of rows where the key equals this sample */
- tRowcnt nLt; /* Est. number of rows where key is less than this sample */
- tRowcnt nDLt; /* Est. number of distinct keys less than this sample */
+ void *p; /* Pointer to sampled record */
+ int n; /* Size of record in bytes */
+ tRowcnt *anEq; /* Est. number of rows where the key equals this sample */
+ tRowcnt *anLt; /* Est. number of rows where key is less than this sample */
+ tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */
};
/*
@@ -10878,7 +11063,7 @@ typedef int ynVar;
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
- u16 flags; /* Various flags. EP_* See below */
+ u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
int iValue; /* Non-negative integer value if EP_IntValue */
@@ -10892,8 +11077,8 @@ struct Expr {
Expr *pLeft; /* Left subnode */
Expr *pRight; /* Right subnode */
union {
- ExprList *pList; /* Function arguments or in "<expr> IN (<expr-list)" */
- Select *pSelect; /* Used for sub-selects and "<expr> IN (<select>)" */
+ ExprList *pList; /* op = IN, EXISTS, SELECT, CASE, FUNCTION, BETWEEN */
+ Select *pSelect; /* EP_xIsSelect and op = IN, EXISTS, SELECT */
} x;
/* If the EP_Reduced flag is set in the Expr.flags mask, then no
@@ -10906,12 +11091,12 @@ struct Expr {
#endif
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
- ** TK_TRIGGER: 1 -> new, 0 -> old */
+ ** TK_TRIGGER: 1 -> new, 0 -> old
+ ** EP_Unlikely: 1000 times likelihood */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
** TK_VARIABLE: variable number (always >= 1). */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 flags2; /* Second set of flags. EP2_... */
u8 op2; /* TK_REGISTER: original value of Expr.op
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
@@ -10922,51 +11107,47 @@ struct Expr {
/*
** The following are the meanings of bits in the Expr.flags field.
*/
-#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
-#define EP_Agg 0x0002 /* Contains one or more aggregate functions */
-#define EP_Resolved 0x0004 /* IDs have been resolved to COLUMNs */
-#define EP_Error 0x0008 /* Expression contains one or more errors */
-#define EP_Distinct 0x0010 /* Aggregate function with DISTINCT keyword */
-#define EP_VarSelect 0x0020 /* pSelect is correlated, not constant */
-#define EP_DblQuoted 0x0040 /* token.z was originally in "..." */
-#define EP_InfixFunc 0x0080 /* True for an infix function: LIKE, GLOB, etc */
-#define EP_Collate 0x0100 /* Tree contains a TK_COLLATE opeartor */
-#define EP_FixedDest 0x0200 /* Result needed in a specific register */
-#define EP_IntValue 0x0400 /* Integer value contained in u.iValue */
-#define EP_xIsSelect 0x0800 /* x.pSelect is valid (otherwise x.pList is) */
-#define EP_Hint 0x1000 /* Not used */
-#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
-#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
+#define EP_FromJoin 0x000001 /* Originated in ON or USING clause of a join */
+#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
+#define EP_Resolved 0x000004 /* IDs have been resolved to COLUMNs */
+#define EP_Error 0x000008 /* Expression contains one or more errors */
+#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
+#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
+#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
+#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
+#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */
+ /* unused 0x000200 */
+#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
+#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
+#define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */
+#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
+#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+#define EP_Static 0x008000 /* Held in memory not obtained from malloc() */
+#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
+#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
+#define EP_Constant 0x080000 /* Node is a constant */
/*
-** The following are the meanings of bits in the Expr.flags2 field.
+** These macros can be used to test, set, or clear bits in the
+** Expr.flags field.
*/
-#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
+#define ExprSetProperty(E,P) (E)->flags|=(P)
+#define ExprClearProperty(E,P) (E)->flags&=~(P)
-/*
-** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
-** flag on an expression structure. This flag is used for VV&A only. The
-** routine is implemented as a macro that only works when in debugging mode,
-** so as not to burden production code.
+/* The ExprSetVVAProperty() macro is used for Verification, Validation,
+** and Accreditation only. It works like ExprSetProperty() during VVA
+** processes but is a no-op for delivery.
*/
#ifdef SQLITE_DEBUG
-# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+# define ExprSetVVAProperty(E,P) (E)->flags|=(P)
#else
-# define ExprSetIrreducible(X)
+# define ExprSetVVAProperty(E,P)
#endif
/*
-** These macros can be used to test, set, or clear bits in the
-** Expr.flags field.
-*/
-#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
-#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
-#define ExprSetProperty(E,P) (E)->flags|=(P)
-#define ExprClearProperty(E,P) (E)->flags&=~(P)
-
-/*
** Macros to determine the number of bytes required by a normal Expr
** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
@@ -11007,8 +11188,14 @@ struct ExprList {
u8 sortOrder; /* 1 for DESC or 0 for ASC */
unsigned done :1; /* A flag to indicate when processing is finished */
unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
- u16 iOrderByCol; /* For ORDER BY, column number in result set */
- u16 iAlias; /* Index into Parse.aAlias[] for zName */
+ unsigned reusable :1; /* Constant expression is reusable */
+ union {
+ struct {
+ u16 iOrderByCol; /* For ORDER BY, column number in result set */
+ u16 iAlias; /* Index into Parse.aAlias[] for zName */
+ } x;
+ int iConstExprReg; /* Register in which Expr value is cached */
+ } u;
} *a; /* Alloc a power of two greater or equal to nExpr */
};
@@ -11061,6 +11248,11 @@ typedef u64 Bitmask;
#define BMS ((int)(sizeof(Bitmask)*8))
/*
+** A bit in a Bitmask
+*/
+#define MASKBIT(n) (((Bitmask)1)<<(n))
+
+/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
@@ -11080,8 +11272,8 @@ typedef u64 Bitmask;
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
- i16 nSrc; /* Number of tables or subqueries in the FROM clause */
- i16 nAlloc; /* Number of entries allocated in a[] below */
+ u8 nSrc; /* Number of tables or subqueries in the FROM clause */
+ u8 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
@@ -11120,79 +11312,6 @@ struct SrcList {
/*
-** A WherePlan object holds information that describes a lookup
-** strategy.
-**
-** This object is intended to be opaque outside of the where.c module.
-** It is included here only so that that compiler will know how big it
-** is. None of the fields in this object should be used outside of
-** the where.c module.
-**
-** Within the union, pIdx is only used when wsFlags&WHERE_INDEXED is true.
-** pTerm is only used when wsFlags&WHERE_MULTI_OR is true. And pVtabIdx
-** is only used when wsFlags&WHERE_VIRTUALTABLE is true. It is never the
-** case that more than one of these conditions is true.
-*/
-struct WherePlan {
- u32 wsFlags; /* WHERE_* flags that describe the strategy */
- u16 nEq; /* Number of == constraints */
- u16 nOBSat; /* Number of ORDER BY terms satisfied */
- double nRow; /* Estimated number of rows (for EQP) */
- union {
- Index *pIdx; /* Index when WHERE_INDEXED is true */
- struct WhereTerm *pTerm; /* WHERE clause term for OR-search */
- sqlite3_index_info *pVtabIdx; /* Virtual table index to use */
- } u;
-};
-
-/*
-** For each nested loop in a WHERE clause implementation, the WhereInfo
-** structure contains a single instance of this structure. This structure
-** is intended to be private to the where.c module and should not be
-** access or modified by other modules.
-**
-** The pIdxInfo field is used to help pick the best index on a
-** virtual table. The pIdxInfo pointer contains indexing
-** information for the i-th table in the FROM clause before reordering.
-** All the pIdxInfo pointers are freed by whereInfoFree() in where.c.
-** All other information in the i-th WhereLevel object for the i-th table
-** after FROM clause ordering.
-*/
-struct WhereLevel {
- WherePlan plan; /* query plan for this element of the FROM clause */
- int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
- int iTabCur; /* The VDBE cursor used to access the table */
- int iIdxCur; /* The VDBE cursor used to access pIdx */
- int addrBrk; /* Jump here to break out of the loop */
- int addrNxt; /* Jump here to start the next IN combination */
- int addrCont; /* Jump here to continue with the next loop cycle */
- int addrFirst; /* First instruction of interior of the loop */
- u8 iFrom; /* Which entry in the FROM clause */
- u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
- int p1, p2; /* Operands of the opcode used to ends the loop */
- union { /* Information that depends on plan.wsFlags */
- struct {
- int nIn; /* Number of entries in aInLoop[] */
- struct InLoop {
- int iCur; /* The VDBE cursor used by this IN operator */
- int addrInTop; /* Top of the IN loop */
- u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
- } *aInLoop; /* Information about each nested IN operator */
- } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
- Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
- } u;
- double rOptCost; /* "Optimal" cost for this level */
-
- /* The following field is really not part of the current level. But
- ** we need a place to cache virtual table index information for each
- ** virtual table in the FROM clause and the WhereLevel structure is
- ** a convenient place since there is one WhereLevel for each FROM clause
- ** element.
- */
- sqlite3_index_info *pIdxInfo; /* Index info for n-th source table */
-};
-
-/*
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
** and the WhereInfo.wctrlFlags member.
*/
@@ -11205,33 +11324,12 @@ struct WhereLevel {
#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
+#define WHERE_GROUPBY 0x0100 /* pOrderBy is really a GROUP BY */
+#define WHERE_DISTINCTBY 0x0200 /* pOrderby is really a DISTINCT clause */
+#define WHERE_WANT_DISTINCT 0x0400 /* All output needs to be distinct */
-/*
-** The WHERE clause processing routine has two halves. The
-** first part does the start of the WHERE loop and the second
-** half does the tail of the WHERE loop. An instance of
-** this structure is returned by the first half and passed
-** into the second half to give some continuity.
+/* Allowed return values from sqlite3WhereIsDistinct()
*/
-struct WhereInfo {
- Parse *pParse; /* Parsing and code generating context */
- SrcList *pTabList; /* List of tables in the join */
- u16 nOBSat; /* Number of ORDER BY terms satisfied by indices */
- u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
- u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
- u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
- u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
- int iTop; /* The very beginning of the WHERE loop */
- int iContinue; /* Jump here to continue with next record */
- int iBreak; /* Jump here to break out of the loop */
- int nLevel; /* Number of nested loop */
- struct WhereClause *pWC; /* Decomposition of the WHERE clause */
- double savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
- double nRowOut; /* Estimated number of output rows */
- WhereLevel a[1]; /* Information about each nest loop in WHERE */
-};
-
-/* Allowed values for WhereInfo.eDistinct and DistinctCtx.eTnctType */
#define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */
#define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */
#define WHERE_DISTINCT_ORDERED 2 /* All duplicates are adjacent */
@@ -11261,7 +11359,7 @@ struct WhereInfo {
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
- ExprList *pEList; /* Optional list of named expressions */
+ ExprList *pEList; /* Optional list of result-set columns */
AggInfo *pAggInfo; /* Information about aggregates at this level */
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
@@ -11276,8 +11374,7 @@ struct NameContext {
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
-#define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
- ** if no other resolution is available */
+#define NC_PartIdx 0x10 /* True if resolving a partial index WHERE */
/*
** An instance of the following structure contains all information
@@ -11305,7 +11402,7 @@ struct Select {
u16 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
int addrOpenEphm[3]; /* OP_OpenEphem opcodes related to this select */
- double nSelectRow; /* Estimated number of result rows */
+ u64 nSelectRow; /* Estimated number of result rows */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -11332,6 +11429,7 @@ struct Select {
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
#define SF_Materialize 0x0100 /* Force materialization of views */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
+#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
/*
@@ -11453,6 +11551,7 @@ struct Parse {
u8 iColCache; /* Next entry in aColCache[] to replace */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
u8 mayAbort; /* True if statement may throw an ABORT exception */
+ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
@@ -11462,6 +11561,7 @@ struct Parse {
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int ckBase; /* Base register of data during check constraints */
+ int iPartIdxTab; /* Table corresponding to a partial index */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
struct yColCache {
@@ -11472,6 +11572,7 @@ struct Parse {
int iReg; /* Reg with value of this column. 0 means none. */
int lru; /* Least recently used entry has the smallest value */
} aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
+ ExprList *pConstExpr;/* Constant expressions */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
@@ -11489,7 +11590,9 @@ struct Parse {
/* Information used while coding trigger programs. */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
- double nQueryLoop; /* Estimated number of iterations of a query */
+ int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
+ int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */
+ u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
@@ -11501,6 +11604,7 @@ struct Parse {
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
+ u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
@@ -11514,7 +11618,6 @@ struct Parse {
#endif
char **azVar; /* Pointers to names of parameters */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
- int *aAlias; /* Register used to hold aliased result */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
@@ -11661,6 +11764,7 @@ typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
Schema *pSchema; /* Fix items to this schema */
+ int bVarOnly; /* Check for variable references only */
const char *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name of the container - used for error messages */
@@ -11677,10 +11781,11 @@ struct StrAccum {
int nChar; /* Length of the string so far */
int nAlloc; /* Amount of space allocated in zText */
int mxAlloc; /* Maximum allowed string length */
- u8 mallocFailed; /* Becomes true if any memory allocation fails */
u8 useMalloc; /* 0: none, 1: sqlite3DbMalloc, 2: sqlite3_malloc */
- u8 tooBig; /* Becomes true if string size exceeds limits */
+ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
};
+#define STRACCUM_NOMEM 1
+#define STRACCUM_TOOBIG 2
/*
** A pointer to this structure is used to communicate information
@@ -11705,6 +11810,7 @@ struct Sqlite3Config {
int bOpenUri; /* True to interpret filenames as URIs */
int bUseCis; /* Use covering indices for full-scans */
int mxStrlen; /* Maximum string length */
+ int neverCorrupt; /* Database is always well-formed */
int szLookaside; /* Default lookaside buffer size */
int nLookaside; /* Default lookaside buffer count */
sqlite3_mem_methods m; /* Low-level memory allocation interface */
@@ -11742,6 +11848,24 @@ struct Sqlite3Config {
};
/*
+** This macro is used inside of assert() statements to indicate that
+** the assert is only valid on a well-formed database. Instead of:
+**
+** assert( X );
+**
+** One writes:
+**
+** assert( X || CORRUPT_DB );
+**
+** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate
+** that the database is definitely corrupt, only that it might be corrupt.
+** For most test cases, CORRUPT_DB is set to false using a special
+** sqlite3_test_control(). This enables assert() statements to prove
+** things that are always true for well-formed databases.
+*/
+#define CORRUPT_DB (sqlite3Config.neverCorrupt==0)
+
+/*
** Context pointer passed down through the tree-walk.
*/
struct Walker {
@@ -11981,6 +12105,8 @@ SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int);
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*);
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*);
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
@@ -11989,7 +12115,7 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
-SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
+SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
@@ -12042,8 +12168,9 @@ SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
- Token*, int, int);
+ Expr*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
@@ -12059,6 +12186,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
+SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*);
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
@@ -12069,11 +12202,13 @@ SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int);
+SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
+#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
+#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
@@ -12085,8 +12220,9 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
@@ -12111,17 +12247,19 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
-SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
-SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
-SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
- int*,int,int,int,int,int*);
-SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
-SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
+SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
+SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
+SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
+ u8,u8,int,int*);
+SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
+SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, int);
+SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
+SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*);
+SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
@@ -12191,7 +12329,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int)
#endif
SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
-SQLITE_PRIVATE int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
+SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*);
SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*);
SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
@@ -12203,6 +12341,12 @@ SQLITE_PRIVATE int sqlite3Atoi(const char*);
SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar);
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
+SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
+SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
+#endif
+SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
/*
** Routines to read and write variable-length integers. These used to
@@ -12288,9 +12432,6 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
-#ifdef SQLITE_ENABLE_STAT3
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
-#endif
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
@@ -12316,12 +12457,13 @@ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
-SQLITE_PRIVATE char sqlite3AffinityType(const char*);
+SQLITE_PRIVATE char sqlite3AffinityType(const char*, u8*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
@@ -12335,7 +12477,13 @@ SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
SQLITE_PRIVATE void sqlite3SchemaClear(void *);
SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*);
+#endif
SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
@@ -12355,6 +12503,12 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
+SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
+#endif
+
/*
** The interface to the LEMON-generated parser
*/
@@ -12396,13 +12550,14 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*);
#else
SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*);
SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p);
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*);
SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
+SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
@@ -12417,8 +12572,10 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
+SQLITE_PRIVATE void sqlite3ParserReset(Parse*);
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
@@ -12437,18 +12594,18 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int);
+SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int);
SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*);
-SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int);
+SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int);
SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int);
SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*);
SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *);
#else
- #define sqlite3FkActions(a,b,c,d)
- #define sqlite3FkCheck(a,b,c,d)
+ #define sqlite3FkActions(a,b,c,d,e,f)
+ #define sqlite3FkCheck(a,b,c,d,e,f)
#define sqlite3FkDropTable(a,b,c)
- #define sqlite3FkOldmask(a,b) 0
- #define sqlite3FkRequired(a,b,c,d) 0
+ #define sqlite3FkOldmask(a,b) 0
+ #define sqlite3FkRequired(a,b,c,d) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
@@ -12735,6 +12892,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0x7ffffffe, /* mxStrlen */
+ 0, /* neverCorrupt */
128, /* szLookaside */
500, /* nLookaside */
{0,0,0,0,0,0,0,0}, /* m */
@@ -12770,7 +12928,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
#endif
};
-
/*
** Hash table for global functions - functions common to all
** database connections. After initialization, this table is
@@ -12937,7 +13094,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_ENABLE_RTREE
"ENABLE_RTREE",
#endif
-#ifdef SQLITE_ENABLE_STAT3
+#if defined(SQLITE_ENABLE_STAT4)
+ "ENABLE_STAT4",
+#elif defined(SQLITE_ENABLE_STAT3)
"ENABLE_STAT3",
#endif
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
@@ -13165,6 +13324,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_SOUNDEX
"SOUNDEX",
#endif
+#ifdef SQLITE_SYSTEM_MALLOC
+ "SYSTEM_MALLOC",
+#endif
#ifdef SQLITE_TCL
"TCL",
#endif
@@ -13180,6 +13342,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_USE_ALLOCA
"USE_ALLOCA",
#endif
+#ifdef SQLITE_WIN32_MALLOC
+ "WIN32_MALLOC",
+#endif
#ifdef SQLITE_ZERO_MALLOC
"ZERO_MALLOC"
#endif
@@ -13279,7 +13444,7 @@ typedef struct VdbeOp Op;
/*
** Boolean values
*/
-typedef unsigned char Bool;
+typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
@@ -13287,12 +13452,18 @@ typedef struct VdbeSorter VdbeSorter;
/* Opaque type used by the explainer */
typedef struct Explain Explain;
+/* Elements of the linked list at Vdbe.pAuxData */
+typedef struct AuxData AuxData;
+
/*
** A cursor is a pointer into a single BTree within a database file.
** The cursor can seek to a BTree entry with a particular key, or
** loop over all entries of the Btree. You can also insert new BTree
** entries or retrieve the key or data from the entry that the cursor
** is currently pointing to.
+**
+** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
+** A pseudo-table is a single-row table implemented by registers.
**
** Every cursor that the virtual machine has open is represented by an
** instance of the following structure.
@@ -13301,31 +13472,24 @@ struct VdbeCursor {
BtCursor *pCursor; /* The cursor structure of the backend */
Btree *pBt; /* Separate file holding temporary table */
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
- int iDb; /* Index of cursor database in db->aDb[] (or -1) */
+ int seekResult; /* Result of previous sqlite3BtreeMoveto() */
int pseudoTableReg; /* Register holding pseudotable content. */
- int nField; /* Number of fields in the header */
- Bool zeroed; /* True if zeroed out and ready for reuse */
- Bool rowidIsValid; /* True if lastRowid is valid */
- Bool atFirst; /* True if pointing to first entry */
- Bool useRandomRowid; /* Generate new record numbers semi-randomly */
- Bool nullRow; /* True if pointing to a row with no data */
- Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
- Bool isTable; /* True if a table requiring integer keys */
- Bool isIndex; /* True if an index containing keys only - no data */
- Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */
- Bool isSorter; /* True if a new-style sorter */
- Bool multiPseudo; /* Multi-register pseudo-cursor */
+ i16 nField; /* Number of fields in the header */
+ u16 nHdrParsed; /* Number of header fields parsed so far */
+ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
+ u8 nullRow; /* True if pointing to a row with no data */
+ u8 rowidIsValid; /* True if lastRowid is valid */
+ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
+ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
+ Bool isTable:1; /* True if a table requiring integer keys */
+ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
+ Bool multiPseudo:1; /* Multi-register pseudo-cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
- const sqlite3_module *pModule; /* Module for cursor pVtabCursor */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
- i64 lastRowid; /* Last rowid from a Next or NextIdx operation */
+ i64 lastRowid; /* Rowid being deleted by OP_Delete */
VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */
- /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists or
- ** OP_IsUnique opcode on this cursor. */
- int seekResult;
-
/* Cached information about the header for the data record that the
** cursor is currently pointing to. Only valid if cacheStatus matches
** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
@@ -13336,10 +13500,14 @@ struct VdbeCursor {
** be NULL.
*/
u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
- int payloadSize; /* Total number of bytes in the record */
- u32 *aType; /* Type values for all entries in the record */
- u32 *aOffset; /* Cached offsets to the start of each columns data */
- u8 *aRow; /* Data for the current row, if all on one page */
+ u32 payloadSize; /* Total number of bytes in the record */
+ u32 szRow; /* Byte available in aRow */
+ u32 iHdrOffset; /* Offset to next unparsed byte of the header */
+ const u8 *aRow; /* Data for the current row, if all on one page */
+ u32 aType[1]; /* Type values for all entries in the record */
+ /* 2*nField extra array elements allocated for aType[], beyond the one
+ ** static element declared in the structure. nField total array slots for
+ ** aType[] and nField+1 array slots for aOffset[] */
};
typedef struct VdbeCursor VdbeCursor;
@@ -13473,23 +13641,19 @@ struct Mem {
#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
#endif
-
-/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
-** additional information about auxiliary information bound to arguments
-** of the function. This is used to implement the sqlite3_get_auxdata()
-** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
-** that can be associated with a constant argument to a function. This
-** allows functions such as "regexp" to compile their constant regular
-** expression argument once and reused the compiled code for multiple
-** invocations.
+/*
+** Each auxilliary data pointer stored by a user defined function
+** implementation calling sqlite3_set_auxdata() is stored in an instance
+** of this structure. All such structures associated with a single VM
+** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
+** when the VM is halted (if not before).
*/
-struct VdbeFunc {
- FuncDef *pFunc; /* The definition of the function */
- int nAux; /* Number of entries allocated for apAux[] */
- struct AuxData {
- void *pAux; /* Aux data for the i-th argument */
- void (*xDelete)(void *); /* Destructor for the aux data */
- } apAux[1]; /* One slot for each function argument */
+struct AuxData {
+ int iOp; /* Instruction number of OP_Function opcode */
+ int iArg; /* Index of function argument. */
+ void *pAux; /* Aux data pointer */
+ void (*xDelete)(void *); /* Destructor for the aux data */
+ AuxData *pNext; /* Next element in list */
};
/*
@@ -13507,12 +13671,14 @@ struct VdbeFunc {
*/
struct sqlite3_context {
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
- VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
Mem s; /* The return value is stored here */
Mem *pMem; /* Memory cell used to store aggregate context */
CollSeq *pColl; /* Collating sequence */
+ Vdbe *pVdbe; /* The VM that owns this context */
+ int iOp; /* Instruction number of OP_Function */
int isError; /* Error code returned by the function. */
- int skipFlag; /* Skip skip accumulator loading if true */
+ u8 skipFlag; /* Skip skip accumulator loading if true */
+ u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */
};
/*
@@ -13580,24 +13746,24 @@ struct Vdbe {
bft expired:1; /* True if the VM needs to be recompiled */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
- bft readOnly:1; /* True for read-only statements */
+ bft readOnly:1; /* True for statements that do not write */
+ bft bIsReader:1; /* True for statements that read */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
int nChange; /* Number of db changes made since last reset */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
int iStatement; /* Statement number (or 0 if has not opened stmt) */
- int aCounter[3]; /* Counters used by sqlite3_stmt_status() */
+ u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
+ i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
+ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
char *zSql; /* Text of the SQL statement that generated this */
void *pFree; /* Free this when deleting the vdbe */
-#ifdef SQLITE_DEBUG
- FILE *trace; /* Write an execution trace here, if not NULL */
-#endif
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
Explain *pExplain; /* The explainer */
char *zExplain; /* Explanation of data structures */
@@ -13609,6 +13775,7 @@ struct Vdbe {
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
int nOnceFlag; /* Size of array aOnceFlag[] */
u8 *aOnceFlag; /* Flags for OP_Once */
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
};
/*
@@ -13632,7 +13799,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
@@ -13665,7 +13832,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
#define VdbeMemRelease(X) \
@@ -13686,7 +13853,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*);
@@ -13953,6 +14120,16 @@ SQLITE_API int sqlite3_db_status(
break;
}
+ /* Set *pCurrent to non-zero if there are unresolved deferred foreign
+ ** key constraints. Set *pCurrent to zero if all foreign key constraints
+ ** have been satisfied. The *pHighwater is always set to zero.
+ */
+ case SQLITE_DBSTATUS_DEFERRED_FKS: {
+ *pHighwater = 0;
+ *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
+ break;
+ }
+
default: {
rc = SQLITE_ERROR;
}
@@ -14258,8 +14435,8 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){
** Return the number of errors.
*/
static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
- sqlite3 *db = sqlite3_context_db_handle(context);
- if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
+ p->iJD = sqlite3StmtCurrentTime(context);
+ if( p->iJD>0 ){
p->validJD = 1;
return 0;
}else{
@@ -14394,6 +14571,10 @@ struct tm *__cdecl localtime(const time_t *t);
**
** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
** routine will always fail.
+**
+** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
+** library function localtime_r() is used to assist in the calculation of
+** local time.
*/
static int osLocaltime(time_t *t, struct tm *pTm){
int rc;
@@ -14450,6 +14631,11 @@ static sqlite3_int64 localtimeOffset(
x = *p;
computeYMD_HMS(&x);
if( x.Y<1971 || x.Y>=2038 ){
+ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
+ ** works for years between 1970 and 2037. For dates outside this range,
+ ** SQLite attempts to map the year into an equivalent year within this
+ ** range, do the calculation, then map the year back.
+ */
x.Y = 2000;
x.M = 1;
x.D = 1;
@@ -15046,8 +15232,8 @@ static void currentTimeFunc(
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
- db = sqlite3_context_db_handle(context);
- if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
+ iT = sqlite3StmtCurrentTime(context);
+ if( iT<=0 ) return;
t = iT/1000 - 10000*(sqlite3_int64)21086676;
#ifdef HAVE_GMTIME_R
pTm = gmtime_r(&t, &sNow);
@@ -15675,16 +15861,6 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
** macros.
*/
#ifdef SQLITE_SYSTEM_MALLOC
-
-/*
-** The MSVCRT has malloc_usable_size() but it is called _msize().
-** The use of _msize() is automatic, but can be disabled by compiling
-** with -DSQLITE_WITHOUT_MSIZE
-*/
-#if defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
-# define SQLITE_MALLOCSIZE _msize
-#endif
-
#if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC)
/*
@@ -15707,22 +15883,48 @@ static malloc_zone_t* _sqliteZone_;
** Use standard C library malloc and free on non-Apple systems.
** Also used by Apple systems if SQLITE_WITHOUT_ZONEMALLOC is defined.
*/
-#define SQLITE_MALLOC(x) malloc(x)
-#define SQLITE_FREE(x) free(x)
-#define SQLITE_REALLOC(x,y) realloc((x),(y))
+#define SQLITE_MALLOC(x) malloc(x)
+#define SQLITE_FREE(x) free(x)
+#define SQLITE_REALLOC(x,y) realloc((x),(y))
-#if (defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)) \
- || (defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE))
-# include <malloc.h> /* Needed for malloc_usable_size on linux */
-#endif
-#ifdef HAVE_MALLOC_USABLE_SIZE
-# ifndef SQLITE_MALLOCSIZE
-# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
-# endif
-#else
-# undef SQLITE_MALLOCSIZE
+/*
+** The malloc.h header file is needed for malloc_usable_size() function
+** on some systems (e.g. Linux).
+*/
+#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)
+# define SQLITE_USE_MALLOC_H
+# define SQLITE_USE_MALLOC_USABLE_SIZE
+/*
+** The MSVCRT has malloc_usable_size(), but it is called _msize(). The
+** use of _msize() is automatic, but can be disabled by compiling with
+** -DSQLITE_WITHOUT_MSIZE. Using the _msize() function also requires
+** the malloc.h header file.
+*/
+#elif defined(_MSC_VER) && !defined(SQLITE_WITHOUT_MSIZE)
+# define SQLITE_USE_MALLOC_H
+# define SQLITE_USE_MSIZE
#endif
+/*
+** Include the malloc.h header file, if necessary. Also set define macro
+** SQLITE_MALLOCSIZE to the appropriate function name, which is _msize()
+** for MSVC and malloc_usable_size() for most other systems (e.g. Linux).
+** The memory size function can always be overridden manually by defining
+** the macro SQLITE_MALLOCSIZE to the desired function name.
+*/
+#if defined(SQLITE_USE_MALLOC_H)
+# include <malloc.h>
+# if defined(SQLITE_USE_MALLOC_USABLE_SIZE)
+# if !defined(SQLITE_MALLOCSIZE)
+# define SQLITE_MALLOCSIZE(x) malloc_usable_size(x)
+# endif
+# elif defined(SQLITE_USE_MSIZE)
+# if !defined(SQLITE_MALLOCSIZE)
+# define SQLITE_MALLOCSIZE _msize
+# endif
+# endif
+#endif /* defined(SQLITE_USE_MALLOC_H) */
+
#endif /* __APPLE__ or not __APPLE__ */
/*
@@ -16086,7 +16288,7 @@ static int sqlite3MemSize(void *p){
return 0;
}
pHdr = sqlite3MemsysGetHeader(p);
- return pHdr->iSize;
+ return (int)pHdr->iSize;
}
/*
@@ -16128,7 +16330,7 @@ static void randomFill(char *pBuf, int nByte){
x = SQLITE_PTR_TO_INT(pBuf);
y = nByte | 1;
while( nByte >= 4 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
+ x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(int*)pBuf = r;
@@ -16136,7 +16338,7 @@ static void randomFill(char *pBuf, int nByte){
nByte -= 4;
}
while( nByte-- > 0 ){
- x = (x>>1) ^ (-(x&1) & 0xd0000001);
+ x = (x>>1) ^ (-(int)(x&1) & 0xd0000001);
y = y*1103515245 + 12345;
r = x ^ y;
*(pBuf++) = r & 0xff;
@@ -16231,9 +16433,9 @@ static void sqlite3MemFree(void *pPrior){
}
z = (char*)pBt;
z -= pHdr->nTitle;
- adjustStats(pHdr->iSize, -1);
+ adjustStats((int)pHdr->iSize, -1);
randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) +
- pHdr->iSize + sizeof(int) + pHdr->nTitle);
+ (int)pHdr->iSize + sizeof(int) + pHdr->nTitle);
free(z);
sqlite3_mutex_leave(mem.mutex);
}
@@ -16255,9 +16457,9 @@ static void *sqlite3MemRealloc(void *pPrior, int nByte){
pOldHdr = sqlite3MemsysGetHeader(pPrior);
pNew = sqlite3MemMalloc(nByte);
if( pNew ){
- memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
+ memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize));
if( nByte>pOldHdr->iSize ){
- randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize);
+ randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize);
}
sqlite3MemFree(pPrior);
}
@@ -16372,7 +16574,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSync(){
for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){
void **pBt = (void**)pHdr;
pBt -= pHdr->nBacktraceSlots;
- mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
+ mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]);
}
}
@@ -17256,13 +17458,13 @@ static SQLITE_WSD struct Mem5Global {
} mem5;
/*
-** Access the static variable through a macro for SQLITE_OMIT_WSD
+** Access the static variable through a macro for SQLITE_OMIT_WSD.
*/
#define mem5 GLOBAL(struct Mem5Global, mem5)
/*
** Assuming mem5.zPool is divided up into an array of Mem5Link
-** structures, return a pointer to the idx-th such lik.
+** structures, return a pointer to the idx-th such link.
*/
#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.szAtom]))
@@ -17328,7 +17530,7 @@ static void memsys5Leave(void){
static int memsys5Size(void *p){
int iSize = 0;
if( p ){
- int i = ((u8 *)p-mem5.zPool)/mem5.szAtom;
+ int i = (int)(((u8 *)p-mem5.zPool)/mem5.szAtom);
assert( i>=0 && i<mem5.nBlock );
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
}
@@ -17336,29 +17538,10 @@ static int memsys5Size(void *p){
}
/*
-** Find the first entry on the freelist iLogsize. Unlink that
-** entry and return its index.
-*/
-static int memsys5UnlinkFirst(int iLogsize){
- int i;
- int iFirst;
-
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- i = iFirst = mem5.aiFreelist[iLogsize];
- assert( iFirst>=0 );
- while( i>0 ){
- if( i<iFirst ) iFirst = i;
- i = MEM5LINK(i)->next;
- }
- memsys5Unlink(iFirst, iLogsize);
- return iFirst;
-}
-
-/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable. Return NULL if nBytes==0.
**
-** The caller guarantees that nByte positive.
+** The caller guarantees that nByte is positive.
**
** The caller has obtained a mutex prior to invoking this
** routine so there is never any chance that two or more
@@ -17399,7 +17582,8 @@ static void *memsys5MallocUnsafe(int nByte){
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
return 0;
}
- i = memsys5UnlinkFirst(iBin);
+ i = mem5.aiFreelist[iBin];
+ memsys5Unlink(i, iBin);
while( iBin>iLogsize ){
int newSize;
@@ -17433,7 +17617,7 @@ static void memsys5FreeUnsafe(void *pOld){
/* Set iBlock to the index of the block pointed to by pOld in
** the array of mem5.szAtom byte blocks pointed to by mem5.zPool.
*/
- iBlock = ((u8 *)pOld-mem5.zPool)/mem5.szAtom;
+ iBlock = (int)(((u8 *)pOld-mem5.zPool)/mem5.szAtom);
/* Check that the pointer pOld points to a valid, non-free block. */
assert( iBlock>=0 && iBlock<mem5.nBlock );
@@ -17480,7 +17664,7 @@ static void memsys5FreeUnsafe(void *pOld){
}
/*
-** Allocate nBytes of memory
+** Allocate nBytes of memory.
*/
static void *memsys5Malloc(int nBytes){
sqlite3_int64 *p = 0;
@@ -18494,7 +18678,7 @@ struct sqlite3_mutex {
}
return osType==2;
}
-#endif /* SQLITE_OS_WINCE */
+#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */
#endif
#ifdef SQLITE_DEBUG
@@ -18532,7 +18716,7 @@ static int winMutex_isInit = 0;
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
-static long winMutex_lock = 0;
+static LONG winMutex_lock = 0;
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
@@ -19253,6 +19437,7 @@ SQLITE_API void sqlite3_free(void *p){
*/
SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
assert( db==0 || sqlite3_mutex_held(db->mutex) );
+ if( p==0 ) return;
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite3DbMallocSize(db, p);
@@ -19912,7 +20097,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
nOut = precision + 10;
zOut = zExtra = sqlite3Malloc( nOut );
if( zOut==0 ){
- pAccum->mallocFailed = 1;
+ pAccum->accError = STRACCUM_NOMEM;
return;
}
}
@@ -19966,13 +20151,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
else prefix = 0;
}
if( xtype==etGENERIC && precision>0 ) precision--;
-#if 0
- /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
- for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
-#else
- /* It makes more sense to use 0.5 */
for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
-#endif
if( xtype==etFLOAT ) realvalue += rounder;
/* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
exp = 0;
@@ -20027,10 +20206,10 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}else{
e2 = exp;
}
- if( e2+precision+width > etBUFSIZE - 15 ){
- bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
+ if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
+ bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
if( bufpt==0 ){
- pAccum->mallocFailed = 1;
+ pAccum->accError = STRACCUM_NOMEM;
return;
}
}
@@ -20165,7 +20344,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
- pAccum->mallocFailed = 1;
+ pAccum->accError = STRACCUM_NOMEM;
return;
}
}else{
@@ -20243,22 +20422,20 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
- if( p->tooBig | p->mallocFailed ){
- testcase(p->tooBig);
- testcase(p->mallocFailed);
+ if( p->accError ){
+ testcase(p->accError==STRACCUM_TOOBIG);
+ testcase(p->accError==STRACCUM_NOMEM);
return;
}
assert( p->zText!=0 || p->nChar==0 );
- if( N<0 ){
+ if( N<=0 ){
+ if( N==0 || z[0]==0 ) return;
N = sqlite3Strlen30(z);
}
- if( N==0 || NEVER(z==0) ){
- return;
- }
if( p->nChar+N >= p->nAlloc ){
char *zNew;
if( !p->useMalloc ){
- p->tooBig = 1;
+ p->accError = STRACCUM_TOOBIG;
N = p->nAlloc - p->nChar - 1;
if( N<=0 ){
return;
@@ -20269,7 +20446,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
- p->tooBig = 1;
+ p->accError = STRACCUM_TOOBIG;
return;
}else{
p->nAlloc = (int)szNew;
@@ -20283,7 +20460,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
- p->mallocFailed = 1;
+ p->accError = STRACCUM_NOMEM;
sqlite3StrAccumReset(p);
return;
}
@@ -20311,7 +20488,7 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
- p->mallocFailed = 1;
+ p->accError = STRACCUM_NOMEM;
}
}
}
@@ -20342,8 +20519,7 @@ SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx)
p->nAlloc = n;
p->mxAlloc = mx;
p->useMalloc = 1;
- p->tooBig = 0;
- p->mallocFailed = 0;
+ p->accError = 0;
}
/*
@@ -20360,7 +20536,7 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
acc.db = db;
sqlite3VXPrintf(&acc, 1, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
- if( acc.mallocFailed ){
+ if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
}
return z;
@@ -20557,24 +20733,11 @@ static SQLITE_WSD struct sqlite3PrngType {
} sqlite3Prng;
/*
-** Get a single 8-bit random value from the RC4 PRNG. The Mutex
-** must be held while executing this routine.
-**
-** Why not just use a library random generator like lrand48() for this?
-** Because the OP_NewRowid opcode in the VDBE depends on having a very
-** good source of random numbers. The lrand48() library function may
-** well be good enough. But maybe not. Or maybe lrand48() has some
-** subtle problems on some systems that could cause problems. It is hard
-** to know. To minimize the risk of problems due to bad lrand48()
-** implementations, SQLite uses this random number generator based
-** on RC4, which we know works very well.
-**
-** (Later): Actually, OP_NewRowid does not depend on a good source of
-** randomness any more. But we will leave this code in all the same.
+** Return N random bytes.
*/
-static u8 randomByte(void){
+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
unsigned char t;
-
+ unsigned char *zBuf = pBuf;
/* The "wsdPrng" macro will resolve to the pseudo-random number generator
** state vector. If writable static data is unsupported on the target,
@@ -20589,6 +20752,10 @@ static u8 randomByte(void){
# define wsdPrng sqlite3Prng
#endif
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+ sqlite3_mutex_enter(mutex);
+#endif
/* Initialize the state of the random number generator once,
** the first time this routine is called. The seed value does
@@ -20617,28 +20784,14 @@ static u8 randomByte(void){
wsdPrng.isInit = 1;
}
- /* Generate and return single random byte
- */
- wsdPrng.i++;
- t = wsdPrng.s[wsdPrng.i];
- wsdPrng.j += t;
- wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
- wsdPrng.s[wsdPrng.j] = t;
- t += wsdPrng.s[wsdPrng.i];
- return wsdPrng.s[t];
-}
-
-/*
-** Return N random bytes.
-*/
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
- unsigned char *zBuf = pBuf;
-#if SQLITE_THREADSAFE
- sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
-#endif
- sqlite3_mutex_enter(mutex);
while( N-- ){
- *(zBuf++) = randomByte();
+ wsdPrng.i++;
+ t = wsdPrng.s[wsdPrng.i];
+ wsdPrng.j += t;
+ wsdPrng.s[wsdPrng.i] = wsdPrng.s[wsdPrng.j];
+ wsdPrng.s[wsdPrng.j] = t;
+ t += wsdPrng.s[wsdPrng.i];
+ *(zBuf++) = wsdPrng.s[t];
}
sqlite3_mutex_leave(mutex);
}
@@ -21126,32 +21279,6 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e
}
/*
-** Convert a UTF-8 string to the UTF-16 encoding specified by parameter
-** enc. A pointer to the new string is returned, and the value of *pnOut
-** is set to the length of the returned string in bytes. The call should
-** arrange to call sqlite3DbFree() on the returned pointer when it is
-** no longer required.
-**
-** If a malloc failure occurs, NULL is returned and the db.mallocFailed
-** flag set.
-*/
-#ifdef SQLITE_ENABLE_STAT3
-SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
- Mem m;
- memset(&m, 0, sizeof(m));
- m.db = db;
- sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
- if( sqlite3VdbeMemTranslate(&m, enc) ){
- assert( db->mallocFailed );
- return 0;
- }
- assert( m.z==m.zMalloc );
- *pnOut = m.n;
- return m.z;
-}
-#endif
-
-/*
** zIn is a UTF-16 encoded unicode string at least nChar characters long.
** Return the number of bytes in the first nChar unicode characters
** in pZ. nChar must be non-negative.
@@ -21426,7 +21553,8 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
case '[': quote = ']'; break; /* For MS SqlServer compatibility */
default: return -1;
}
- for(i=1, j=0; ALWAYS(z[i]); i++){
+ for(i=1, j=0;; i++){
+ assert( z[i] );
if( z[i]==quote ){
if( z[i+1]==quote ){
z[j++] = quote;
@@ -21697,12 +21825,12 @@ static int compare2pow63(const char *zNum, int incr){
** If the zNum value is representable as a 64-bit twos-complement
** integer, then write that value into *pNum and return 0.
**
-** If zNum is exactly 9223372036854665808, return 2. This special
-** case is broken out because while 9223372036854665808 cannot be a
-** signed 64-bit integer, its negative -9223372036854665808 can be.
+** If zNum is exactly 9223372036854775808, return 2. This special
+** case is broken out because while 9223372036854775808 cannot be a
+** signed 64-bit integer, its negative -9223372036854775808 can be.
**
** If zNum is too big for a 64-bit integer and is not
-** 9223372036854665808 or if zNum contains any non-numeric text,
+** 9223372036854775808 or if zNum contains any non-numeric text,
** then return 1.
**
** length is the number of bytes in the string (bytes, not characters).
@@ -21744,7 +21872,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
u = u*10 + c - '0';
}
if( u>LARGEST_INT64 ){
- *pNum = SMALLEST_INT64;
+ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
@@ -21775,7 +21903,6 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
- assert( (*pNum)==SMALLEST_INT64 );
return neg ? 0 : 2;
}
}
@@ -22441,6 +22568,85 @@ SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
}
#endif
+/*
+** Find (an approximate) sum of two LogEst values. This computation is
+** not a simple "+" operator because LogEst is stored as a logarithmic
+** value.
+**
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){
+ static const unsigned char x[] = {
+ 10, 10, /* 0,1 */
+ 9, 9, /* 2,3 */
+ 8, 8, /* 4,5 */
+ 7, 7, 7, /* 6,7,8 */
+ 6, 6, 6, /* 9,10,11 */
+ 5, 5, 5, /* 12-14 */
+ 4, 4, 4, 4, /* 15-18 */
+ 3, 3, 3, 3, 3, 3, /* 19-24 */
+ 2, 2, 2, 2, 2, 2, 2, /* 25-31 */
+ };
+ if( a>=b ){
+ if( a>b+49 ) return a;
+ if( a>b+31 ) return a+1;
+ return a+x[a-b];
+ }else{
+ if( b>a+49 ) return b;
+ if( b>a+31 ) return b+1;
+ return b+x[b-a];
+ }
+}
+
+/*
+** Convert an integer into a LogEst. In other words, compute a
+** good approximatation for 10*log2(x).
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){
+ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 };
+ LogEst y = 40;
+ if( x<8 ){
+ if( x<2 ) return 0;
+ while( x<8 ){ y -= 10; x <<= 1; }
+ }else{
+ while( x>255 ){ y += 40; x >>= 4; }
+ while( x>15 ){ y += 10; x >>= 1; }
+ }
+ return a[x&7] + y - 10;
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Convert a double into a LogEst
+** In other words, compute an approximation for 10*log2(x).
+*/
+SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
+ u64 a;
+ LogEst e;
+ assert( sizeof(x)==8 && sizeof(a)==8 );
+ if( x<=1 ) return 0;
+ if( x<=2000000000 ) return sqlite3LogEst((u64)x);
+ memcpy(&a, &x, 8);
+ e = (a>>52) - 1022;
+ return e*10;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** Convert a LogEst into an integer.
+*/
+SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
+ u64 n;
+ if( x<10 ) return 1;
+ n = x%10;
+ x /= 10;
+ if( n>=5 ) n -= 2;
+ else if( n>=1 ) n -= 1;
+ if( x>=3 ){
+ return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
+ }
+ return (n+8)>>(3-x);
+}
+
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -22728,159 +22934,166 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the mkopcodec.awk script for details. */
-#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)
+# define OpHelp(X) "\0" X
+#else
+# define OpHelp(X)
+#endif
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
static const char *const azName[] = { "?",
- /* 1 */ "Goto",
- /* 2 */ "Gosub",
- /* 3 */ "Return",
- /* 4 */ "Yield",
- /* 5 */ "HaltIfNull",
- /* 6 */ "Halt",
- /* 7 */ "Integer",
- /* 8 */ "Int64",
- /* 9 */ "String",
- /* 10 */ "Null",
- /* 11 */ "Blob",
- /* 12 */ "Variable",
- /* 13 */ "Move",
- /* 14 */ "Copy",
- /* 15 */ "SCopy",
- /* 16 */ "ResultRow",
- /* 17 */ "CollSeq",
- /* 18 */ "Function",
- /* 19 */ "Not",
- /* 20 */ "AddImm",
- /* 21 */ "MustBeInt",
- /* 22 */ "RealAffinity",
- /* 23 */ "Permutation",
- /* 24 */ "Compare",
- /* 25 */ "Jump",
- /* 26 */ "Once",
- /* 27 */ "If",
- /* 28 */ "IfNot",
- /* 29 */ "Column",
- /* 30 */ "Affinity",
- /* 31 */ "MakeRecord",
- /* 32 */ "Count",
- /* 33 */ "Savepoint",
- /* 34 */ "AutoCommit",
- /* 35 */ "Transaction",
- /* 36 */ "ReadCookie",
- /* 37 */ "SetCookie",
- /* 38 */ "VerifyCookie",
- /* 39 */ "OpenRead",
- /* 40 */ "OpenWrite",
- /* 41 */ "OpenAutoindex",
- /* 42 */ "OpenEphemeral",
- /* 43 */ "SorterOpen",
- /* 44 */ "OpenPseudo",
- /* 45 */ "Close",
- /* 46 */ "SeekLt",
- /* 47 */ "SeekLe",
- /* 48 */ "SeekGe",
- /* 49 */ "SeekGt",
- /* 50 */ "Seek",
- /* 51 */ "NotFound",
- /* 52 */ "Found",
- /* 53 */ "IsUnique",
- /* 54 */ "NotExists",
- /* 55 */ "Sequence",
- /* 56 */ "NewRowid",
- /* 57 */ "Insert",
- /* 58 */ "InsertInt",
- /* 59 */ "Delete",
- /* 60 */ "ResetCount",
- /* 61 */ "SorterCompare",
- /* 62 */ "SorterData",
- /* 63 */ "RowKey",
- /* 64 */ "RowData",
- /* 65 */ "Rowid",
- /* 66 */ "NullRow",
- /* 67 */ "Last",
- /* 68 */ "Or",
- /* 69 */ "And",
- /* 70 */ "SorterSort",
- /* 71 */ "Sort",
- /* 72 */ "Rewind",
- /* 73 */ "IsNull",
- /* 74 */ "NotNull",
- /* 75 */ "Ne",
- /* 76 */ "Eq",
- /* 77 */ "Gt",
- /* 78 */ "Le",
- /* 79 */ "Lt",
- /* 80 */ "Ge",
- /* 81 */ "SorterNext",
- /* 82 */ "BitAnd",
- /* 83 */ "BitOr",
- /* 84 */ "ShiftLeft",
- /* 85 */ "ShiftRight",
- /* 86 */ "Add",
- /* 87 */ "Subtract",
- /* 88 */ "Multiply",
- /* 89 */ "Divide",
- /* 90 */ "Remainder",
- /* 91 */ "Concat",
- /* 92 */ "Prev",
- /* 93 */ "BitNot",
- /* 94 */ "String8",
- /* 95 */ "Next",
- /* 96 */ "SorterInsert",
- /* 97 */ "IdxInsert",
- /* 98 */ "IdxDelete",
- /* 99 */ "IdxRowid",
- /* 100 */ "IdxLT",
- /* 101 */ "IdxGE",
- /* 102 */ "Destroy",
- /* 103 */ "Clear",
- /* 104 */ "CreateIndex",
- /* 105 */ "CreateTable",
- /* 106 */ "ParseSchema",
- /* 107 */ "LoadAnalysis",
- /* 108 */ "DropTable",
- /* 109 */ "DropIndex",
- /* 110 */ "DropTrigger",
- /* 111 */ "IntegrityCk",
- /* 112 */ "RowSetAdd",
- /* 113 */ "RowSetRead",
- /* 114 */ "RowSetTest",
- /* 115 */ "Program",
- /* 116 */ "Param",
- /* 117 */ "FkCounter",
- /* 118 */ "FkIfZero",
- /* 119 */ "MemMax",
- /* 120 */ "IfPos",
- /* 121 */ "IfNeg",
- /* 122 */ "IfZero",
- /* 123 */ "AggStep",
- /* 124 */ "AggFinal",
- /* 125 */ "Checkpoint",
- /* 126 */ "JournalMode",
- /* 127 */ "Vacuum",
- /* 128 */ "IncrVacuum",
- /* 129 */ "Expire",
- /* 130 */ "Real",
- /* 131 */ "TableLock",
- /* 132 */ "VBegin",
- /* 133 */ "VCreate",
- /* 134 */ "VDestroy",
- /* 135 */ "VOpen",
- /* 136 */ "VFilter",
- /* 137 */ "VColumn",
- /* 138 */ "VNext",
- /* 139 */ "VRename",
- /* 140 */ "VUpdate",
- /* 141 */ "ToText",
- /* 142 */ "ToBlob",
- /* 143 */ "ToNumeric",
- /* 144 */ "ToInt",
- /* 145 */ "ToReal",
- /* 146 */ "Pagecount",
- /* 147 */ "MaxPgcnt",
- /* 148 */ "Trace",
- /* 149 */ "Noop",
- /* 150 */ "Explain",
+ /* 1 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 2 */ "Savepoint" OpHelp(""),
+ /* 3 */ "AutoCommit" OpHelp(""),
+ /* 4 */ "Transaction" OpHelp(""),
+ /* 5 */ "SorterNext" OpHelp(""),
+ /* 6 */ "PrevIfOpen" OpHelp(""),
+ /* 7 */ "NextIfOpen" OpHelp(""),
+ /* 8 */ "Prev" OpHelp(""),
+ /* 9 */ "Next" OpHelp(""),
+ /* 10 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 11 */ "Checkpoint" OpHelp(""),
+ /* 12 */ "JournalMode" OpHelp(""),
+ /* 13 */ "Vacuum" OpHelp(""),
+ /* 14 */ "VFilter" OpHelp("iPlan=r[P3] zPlan='P4'"),
+ /* 15 */ "VUpdate" OpHelp("data=r[P3@P2]"),
+ /* 16 */ "Goto" OpHelp(""),
+ /* 17 */ "Gosub" OpHelp(""),
+ /* 18 */ "Return" OpHelp(""),
+ /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
+ /* 20 */ "Yield" OpHelp(""),
+ /* 21 */ "HaltIfNull" OpHelp("if r[P3] null then halt"),
+ /* 22 */ "Halt" OpHelp(""),
+ /* 23 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 24 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 25 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 26 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 27 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 28 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 29 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 30 */ "Copy" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 31 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 32 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 33 */ "CollSeq" OpHelp(""),
+ /* 34 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 35 */ "MustBeInt" OpHelp(""),
+ /* 36 */ "RealAffinity" OpHelp(""),
+ /* 37 */ "Permutation" OpHelp(""),
+ /* 38 */ "Compare" OpHelp(""),
+ /* 39 */ "Jump" OpHelp(""),
+ /* 40 */ "Once" OpHelp(""),
+ /* 41 */ "If" OpHelp(""),
+ /* 42 */ "IfNot" OpHelp(""),
+ /* 43 */ "Column" OpHelp("r[P3]=PX"),
+ /* 44 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 45 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 46 */ "Count" OpHelp("r[P2]=count()"),
+ /* 47 */ "ReadCookie" OpHelp(""),
+ /* 48 */ "SetCookie" OpHelp(""),
+ /* 49 */ "VerifyCookie" OpHelp(""),
+ /* 50 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 51 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 52 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 53 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 54 */ "SorterOpen" OpHelp(""),
+ /* 55 */ "OpenPseudo" OpHelp("content in r[P2@P3]"),
+ /* 56 */ "Close" OpHelp(""),
+ /* 57 */ "SeekLt" OpHelp("key=r[P3@P4]"),
+ /* 58 */ "SeekLe" OpHelp("key=r[P3@P4]"),
+ /* 59 */ "SeekGe" OpHelp("key=r[P3@P4]"),
+ /* 60 */ "SeekGt" OpHelp("key=r[P3@P4]"),
+ /* 61 */ "Seek" OpHelp("intkey=r[P2]"),
+ /* 62 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 63 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 64 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 65 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 66 */ "Sequence" OpHelp("r[P2]=rowid"),
+ /* 67 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 68 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 69 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 70 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 71 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 72 */ "Delete" OpHelp(""),
+ /* 73 */ "ResetCount" OpHelp(""),
+ /* 74 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 75 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 76 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
+ /* 77 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
+ /* 78 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
+ /* 79 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
+ /* 80 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
+ /* 81 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
+ /* 82 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"),
+ /* 83 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 84 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 85 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 86 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 87 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 88 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 89 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 90 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 91 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 92 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 93 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 94 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 95 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 96 */ "RowKey" OpHelp("r[P2]=key"),
+ /* 97 */ "RowData" OpHelp("r[P2]=data"),
+ /* 98 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 99 */ "NullRow" OpHelp(""),
+ /* 100 */ "Last" OpHelp(""),
+ /* 101 */ "SorterSort" OpHelp(""),
+ /* 102 */ "Sort" OpHelp(""),
+ /* 103 */ "Rewind" OpHelp(""),
+ /* 104 */ "SorterInsert" OpHelp(""),
+ /* 105 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 106 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 107 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 108 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 109 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 110 */ "Destroy" OpHelp(""),
+ /* 111 */ "Clear" OpHelp(""),
+ /* 112 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 113 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 114 */ "ParseSchema" OpHelp(""),
+ /* 115 */ "LoadAnalysis" OpHelp(""),
+ /* 116 */ "DropTable" OpHelp(""),
+ /* 117 */ "DropIndex" OpHelp(""),
+ /* 118 */ "DropTrigger" OpHelp(""),
+ /* 119 */ "IntegrityCk" OpHelp(""),
+ /* 120 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 121 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 122 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 123 */ "Program" OpHelp(""),
+ /* 124 */ "Param" OpHelp(""),
+ /* 125 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 126 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 127 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 128 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
+ /* 129 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"),
+ /* 130 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
+ /* 131 */ "Real" OpHelp("r[P2]=P4"),
+ /* 132 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 133 */ "IncrVacuum" OpHelp(""),
+ /* 134 */ "Expire" OpHelp(""),
+ /* 135 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 136 */ "VBegin" OpHelp(""),
+ /* 137 */ "VCreate" OpHelp(""),
+ /* 138 */ "VDestroy" OpHelp(""),
+ /* 139 */ "VOpen" OpHelp(""),
+ /* 140 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 141 */ "VNext" OpHelp(""),
+ /* 142 */ "ToText" OpHelp(""),
+ /* 143 */ "ToBlob" OpHelp(""),
+ /* 144 */ "ToNumeric" OpHelp(""),
+ /* 145 */ "ToInt" OpHelp(""),
+ /* 146 */ "ToReal" OpHelp(""),
+ /* 147 */ "VRename" OpHelp(""),
+ /* 148 */ "Pagecount" OpHelp(""),
+ /* 149 */ "MaxPgcnt" OpHelp(""),
+ /* 150 */ "Trace" OpHelp(""),
+ /* 151 */ "Noop" OpHelp(""),
+ /* 152 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -22935,13 +23148,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
*/
#if SQLITE_OS_UNIX /* This file is used on unix only */
-/* Use posix_fallocate() if it is available
-*/
-#if !defined(HAVE_POSIX_FALLOCATE) \
- && (_XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L)
-# define HAVE_POSIX_FALLOCATE 1
-#endif
-
/*
** There are various methods for file locking used for concurrency
** control:
@@ -23114,11 +23320,13 @@ struct unixFile {
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
+#if SQLITE_MAX_MMAP_SIZE>0
int nFetchOut; /* Number of outstanding xFetch refs */
sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */
sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
void *pMapRegion; /* Memory mapped region */
+#endif
#ifdef __QNXNTO__
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
@@ -23553,6 +23761,7 @@ static struct unix_syscall {
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
{ "mmap", (sqlite3_syscall_ptr)mmap, 0 },
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent)
@@ -23565,6 +23774,7 @@ static struct unix_syscall {
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
#endif
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
+#endif
}; /* End of the overrideable system calls */
@@ -23652,6 +23862,15 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
}
/*
+** Do not accept any file descriptor less than this value, in order to avoid
+** opening database file using file descriptors that are commonly used for
+** standard input, output, and error.
+*/
+#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR
+# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3
+#endif
+
+/*
** Invoke open(). Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
@@ -23671,13 +23890,23 @@ static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){
static int robust_open(const char *z, int f, mode_t m){
int fd;
mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS;
- do{
+ while(1){
#if defined(O_CLOEXEC)
fd = osOpen(z,f|O_CLOEXEC,m2);
#else
fd = osOpen(z,f,m2);
#endif
- }while( fd<0 && errno==EINTR );
+ if( fd<0 ){
+ if( errno==EINTR ) continue;
+ break;
+ }
+ if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
+ osClose(fd);
+ sqlite3_log(SQLITE_WARNING,
+ "attempt to open \"%s\" as file descriptor %d", z, fd);
+ fd = -1;
+ if( osOpen("/dev/null", f, m)<0 ) break;
+ }
if( fd>=0 ){
if( m!=0 ){
struct stat statbuf;
@@ -24971,12 +25200,16 @@ end_unlock:
** the requested locking level, this routine is a no-op.
*/
static int unixUnlock(sqlite3_file *id, int eFileLock){
+#if SQLITE_MAX_MMAP_SIZE>0
assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 );
+#endif
return posixUnlock(id, eFileLock, 0);
}
+#if SQLITE_MAX_MMAP_SIZE>0
static int unixMapfile(unixFile *pFd, i64 nByte);
static void unixUnmapfile(unixFile *pFd);
+#endif
/*
** This function performs the parts of the "close file" operation
@@ -24990,7 +25223,9 @@ static void unixUnmapfile(unixFile *pFd);
*/
static int closeUnixFile(sqlite3_file *id){
unixFile *pFile = (unixFile*)id;
+#if SQLITE_MAX_MMAP_SIZE>0
unixUnmapfile(pFile);
+#endif
if( pFile->h>=0 ){
robust_close(pFile, pFile->h, __LINE__);
pFile->h = -1;
@@ -26195,6 +26430,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
#endif
TIMER_START;
assert( cnt==(cnt&0x1ffff) );
+ assert( id->h>2 );
cnt &= 0x1ffff;
do{
#if defined(USE_PREAD)
@@ -26309,6 +26545,7 @@ static int seekAndWriteFd(
int rc = 0; /* Value returned by system call */
assert( nBuf==(nBuf&0x1ffff) );
+ assert( fd>2 );
nBuf &= 0x1ffff;
TIMER_START;
@@ -26694,6 +26931,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
}
#endif
+#if SQLITE_MAX_MMAP_SIZE>0
/* If the file was just truncated to a size smaller than the currently
** mapped region, reduce the effective mapping size as well. SQLite will
** use read() and write() to access data beyond this point from now on.
@@ -26701,6 +26939,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
if( nByte<pFile->mmapSize ){
pFile->mmapSize = nByte;
}
+#endif
return SQLITE_OK;
}
@@ -26790,6 +27029,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
}
}
+#if SQLITE_MAX_MMAP_SIZE>0
if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){
int rc;
if( pFile->szChunk<=0 ){
@@ -26802,6 +27042,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
rc = unixMapfile(pFile, nByte);
return rc;
}
+#endif
return SQLITE_OK;
}
@@ -26870,18 +27111,24 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
+#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
+ int rc = SQLITE_OK;
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
*(i64*)pArg = pFile->mmapSizeMax;
- if( newLimit>=0 ){
+ if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
- if( newLimit<pFile->mmapSize ) pFile->mmapSize = newLimit;
+ if( pFile->mmapSize>0 ){
+ unixUnmapfile(pFile);
+ rc = unixMapfile(pFile, -1);
+ }
}
- return SQLITE_OK;
+ return rc;
}
+#endif
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
@@ -27144,7 +27391,7 @@ static int unixShmSystemLock(
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
- mask = (1<<(ofst+n)) - (1<<ofst);
+ mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d ok", ofst));
@@ -27692,22 +27939,20 @@ static int unixShmUnmap(
# define unixShmUnmap 0
#endif /* #ifndef SQLITE_OMIT_WAL */
+#if SQLITE_MAX_MMAP_SIZE>0
/*
** If it is currently memory mapped, unmap file pFd.
*/
static void unixUnmapfile(unixFile *pFd){
assert( pFd->nFetchOut==0 );
-#if SQLITE_MAX_MMAP_SIZE>0
if( pFd->pMapRegion ){
osMunmap(pFd->pMapRegion, pFd->mmapSizeActual);
pFd->pMapRegion = 0;
pFd->mmapSize = 0;
pFd->mmapSizeActual = 0;
}
-#endif
}
-#if SQLITE_MAX_MMAP_SIZE>0
/*
** Return the system page size.
*/
@@ -27720,9 +27965,7 @@ static int unixGetPagesize(void){
return (int)sysconf(_SC_PAGESIZE);
#endif
}
-#endif /* SQLITE_MAX_MMAP_SIZE>0 */
-#if SQLITE_MAX_MMAP_SIZE>0
/*
** Attempt to set the size of the memory mapping maintained by file
** descriptor pFd to nNew bytes. Any existing mapping is discarded.
@@ -27807,7 +28050,6 @@ static void unixRemapfile(
pFd->pMapRegion = (void *)pNew;
pFd->mmapSize = pFd->mmapSizeActual = nNew;
}
-#endif
/*
** Memory map or remap the file opened by file-descriptor pFd (if the file
@@ -27826,7 +28068,6 @@ static void unixRemapfile(
** code otherwise.
*/
static int unixMapfile(unixFile *pFd, i64 nByte){
-#if SQLITE_MAX_MMAP_SIZE>0
i64 nMap = nByte;
int rc;
@@ -27852,10 +28093,10 @@ static int unixMapfile(unixFile *pFd, i64 nByte){
unixUnmapfile(pFd);
}
}
-#endif
return SQLITE_OK;
}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
/*
** If possible, return a pointer to a mapping of file fd starting at offset
@@ -27904,6 +28145,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
UNUSED_PARAMETER(iOff);
+#if SQLITE_MAX_MMAP_SIZE>0
/* If p==0 (unmap the entire file) then there must be no outstanding
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
** then there must be at least one outstanding. */
@@ -27919,6 +28161,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
}
assert( pFd->nFetchOut>=0 );
+#endif
return SQLITE_OK;
}
@@ -28250,7 +28493,9 @@ static int fillInUnixFile(
pNew->pVfs = pVfs;
pNew->zPath = zFilename;
pNew->ctrlFlags = (u8)ctrlFlags;
+#if SQLITE_MAX_MMAP_SIZE>0
pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+#endif
if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0),
"psow", SQLITE_POWERSAFE_OVERWRITE) ){
pNew->ctrlFlags |= UNIXFILE_PSOW;
@@ -28407,6 +28652,7 @@ static const char *unixTempFileDir(void){
static const char *azDirs[] = {
0,
0,
+ 0,
"/var/tmp",
"/usr/tmp",
"/tmp",
@@ -28417,7 +28663,8 @@ static const char *unixTempFileDir(void){
const char *zDir = 0;
azDirs[0] = sqlite3_temp_directory;
- if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+ if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR");
+ if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR");
for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
if( zDir==0 ) continue;
if( osStat(zDir, &buf) ) continue;
@@ -30530,6 +30777,7 @@ SQLITE_API int sqlite3_os_end(void){
#ifdef __CYGWIN__
# include <sys/cygwin.h>
+# include <errno.h> /* amalgamator: keep */
#endif
/*
@@ -30750,7 +30998,7 @@ SQLITE_API int sqlite3_open_file_count = 0;
** available in Windows platforms based on the NT kernel.
*/
#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
-# error "WAL mode requires support from the Windows NT kernel, compile\
+# error "WAL mode requires support from the Windows NT kernel, compile\
with SQLITE_OMIT_WAL."
#endif
@@ -30758,7 +31006,7 @@ SQLITE_API int sqlite3_open_file_count = 0;
** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
# define SQLITE_WIN32_HAS_ANSI
#endif
@@ -30766,11 +31014,126 @@ SQLITE_API int sqlite3_open_file_count = 0;
** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions
** based on the sub-platform)?
*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
+#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \
+ !defined(SQLITE_WIN32_NO_WIDE)
# define SQLITE_WIN32_HAS_WIDE
#endif
/*
+** Make sure at least one set of Win32 APIs is available.
+*/
+#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
+# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
+ must be defined."
+#endif
+
+/*
+** Define the required Windows SDK version constants if they are not
+** already available.
+*/
+#ifndef NTDDI_WIN8
+# define NTDDI_WIN8 0x06020000
+#endif
+
+#ifndef NTDDI_WINBLUE
+# define NTDDI_WINBLUE 0x06030000
+#endif
+
+/*
+** Check if the GetVersionEx[AW] functions should be considered deprecated
+** and avoid using them in that case. It should be noted here that if the
+** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero
+** (whether via this block or via being manually specified), that implies
+** the underlying operating system will always be based on the Windows NT
+** Kernel.
+*/
+#ifndef SQLITE_WIN32_GETVERSIONEX
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
+# define SQLITE_WIN32_GETVERSIONEX 0
+# else
+# define SQLITE_WIN32_GETVERSIONEX 1
+# endif
+#endif
+
+/*
+** This constant should already be defined (in the "WinDef.h" SDK file).
+*/
+#ifndef MAX_PATH
+# define MAX_PATH (260)
+#endif
+
+/*
+** Maximum pathname length (in chars) for Win32. This should normally be
+** MAX_PATH.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_CHARS
+# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH)
+#endif
+
+/*
+** This constant should already be defined (in the "WinNT.h" SDK file).
+*/
+#ifndef UNICODE_STRING_MAX_CHARS
+# define UNICODE_STRING_MAX_CHARS (32767)
+#endif
+
+/*
+** Maximum pathname length (in chars) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS.
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_CHARS
+# define SQLITE_WINNT_MAX_PATH_CHARS (UNICODE_STRING_MAX_CHARS)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in
+** characters, so we allocate 4 bytes per character assuming worst-case of
+** 4-bytes-per-character for UTF8.
+*/
+#ifndef SQLITE_WIN32_MAX_PATH_BYTES
+# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4)
+#endif
+
+/*
+** Maximum pathname length (in bytes) for WinNT. This should normally be
+** UNICODE_STRING_MAX_CHARS * sizeof(WCHAR).
+*/
+#ifndef SQLITE_WINNT_MAX_PATH_BYTES
+# define SQLITE_WINNT_MAX_PATH_BYTES \
+ (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
+#endif
+
+/*
+** Maximum error message length (in chars) for WinRT.
+*/
+#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS
+# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024)
+#endif
+
+/*
+** Returns non-zero if the character should be treated as a directory
+** separator.
+*/
+#ifndef winIsDirSep
+# define winIsDirSep(a) (((a) == '/') || ((a) == '\\'))
+#endif
+
+/*
+** This macro is used when a local variable is set to a value that is
+** [sometimes] not used by the code (e.g. via conditional compilation).
+*/
+#ifndef UNUSED_VARIABLE_VALUE
+# define UNUSED_VARIABLE_VALUE(x) (void)(x)
+#endif
+
+/*
+** Returns the character that should be used as the directory separator.
+*/
+#ifndef winGetDirSep
+# define winGetDirSep() '\\'
+#endif
+
+/*
** Do we need to manually define the Win32 file mapping APIs for use with WAL
** mode (e.g. these APIs are available in the Windows CE SDK; however, they
** are not present in the header file)?
@@ -30806,13 +31169,6 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
/*
-** Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_FILE_ATTRIBUTES
@@ -30828,7 +31184,7 @@ WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
#endif
#ifndef SQLITE_OMIT_WAL
-/* Forward references */
+/* Forward references to structures used for WAL */
typedef struct winShm winShm; /* A connection to shared-memory */
typedef struct winShmNode winShmNode; /* A region of shared-memory */
#endif
@@ -30958,6 +31314,7 @@ struct winFile {
# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
+
/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
@@ -30965,30 +31322,41 @@ struct winFile {
typedef struct winMemData winMemData;
struct winMemData {
#ifndef NDEBUG
- u32 magic; /* Magic number to detect structure corruption. */
+ u32 magic1; /* Magic number to detect structure corruption. */
#endif
HANDLE hHeap; /* The handle to our heap. */
BOOL bOwned; /* Do we own the heap (i.e. destroy it on shutdown)? */
+#ifndef NDEBUG
+ u32 magic2; /* Magic number to detect structure corruption. */
+#endif
};
#ifndef NDEBUG
-#define WINMEM_MAGIC 0x42b2830b
+#define WINMEM_MAGIC1 0x42b2830b
+#define WINMEM_MAGIC2 0xbd4d7cf4
#endif
static struct winMemData win_mem_data = {
#ifndef NDEBUG
- WINMEM_MAGIC,
+ WINMEM_MAGIC1,
#endif
NULL, FALSE
+#ifndef NDEBUG
+ ,WINMEM_MAGIC2
+#endif
};
#ifndef NDEBUG
-#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
+#define winMemAssertMagic1() assert( win_mem_data.magic1==WINMEM_MAGIC1 )
+#define winMemAssertMagic2() assert( win_mem_data.magic2==WINMEM_MAGIC2 )
+#define winMemAssertMagic() winMemAssertMagic1(); winMemAssertMagic2();
#else
#define winMemAssertMagic()
#endif
-#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetDataPtr() &win_mem_data
+#define winMemGetHeap() win_mem_data.hHeap
+#define winMemGetOwned() win_mem_data.bOwned
static void *winMemMalloc(int nBytes);
static void winMemFree(void *pPrior);
@@ -31015,7 +31383,8 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite3_os_type = 0;
-#else
+#elif !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+ defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_HAS_WIDE)
static int sqlite3_os_type = 0;
#endif
@@ -31321,7 +31690,8 @@ static struct win_syscall {
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-#if defined(SQLITE_WIN32_HAS_ANSI)
+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+ SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
@@ -31330,10 +31700,20 @@ static struct win_syscall {
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+ defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+ { "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
+#else
+ { "GetVersionExW", (SYSCALL)0, 0 },
+#endif
+
+#define osGetVersionExW ((BOOL(WINAPI*)( \
+ LPOSVERSIONINFOW))aSyscall[35].pCurrent)
+
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
- SIZE_T))aSyscall[35].pCurrent)
+ SIZE_T))aSyscall[36].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
@@ -31342,7 +31722,7 @@ static struct win_syscall {
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
- SIZE_T))aSyscall[36].pCurrent)
+ SIZE_T))aSyscall[37].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
@@ -31350,21 +31730,21 @@ static struct win_syscall {
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[37].pCurrent)
+#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[38].pCurrent)
+#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
- SIZE_T))aSyscall[39].pCurrent)
+ SIZE_T))aSyscall[40].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[40].pCurrent)
+ LPCVOID))aSyscall[41].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
@@ -31373,7 +31753,15 @@ static struct win_syscall {
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
- LPCVOID))aSyscall[41].pCurrent)
+ LPCVOID))aSyscall[42].pCurrent)
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ { "HeapCompact", (SYSCALL)HeapCompact, 0 },
+#else
+ { "HeapCompact", (SYSCALL)0, 0 },
+#endif
+
+#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
@@ -31381,7 +31769,7 @@ static struct win_syscall {
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[42].pCurrent)
+#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
!defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -31390,7 +31778,7 @@ static struct win_syscall {
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[43].pCurrent)
+#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
@@ -31398,7 +31786,7 @@ static struct win_syscall {
{ "LocalFree", (SYSCALL)0, 0 },
#endif
-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[44].pCurrent)
+#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
@@ -31408,7 +31796,7 @@ static struct win_syscall {
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[45].pCurrent)
+ DWORD))aSyscall[47].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -31419,7 +31807,7 @@ static struct win_syscall {
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[46].pCurrent)
+ LPOVERLAPPED))aSyscall[48].pCurrent)
#endif
#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
@@ -31429,26 +31817,26 @@ static struct win_syscall {
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- SIZE_T))aSyscall[47].pCurrent)
+ SIZE_T))aSyscall[49].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
- int))aSyscall[48].pCurrent)
+ int))aSyscall[50].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
- LARGE_INTEGER*))aSyscall[49].pCurrent)
+ LARGE_INTEGER*))aSyscall[51].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[50].pCurrent)
+ LPOVERLAPPED))aSyscall[52].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[51].pCurrent)
+#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
@@ -31457,7 +31845,7 @@ static struct win_syscall {
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
- DWORD))aSyscall[52].pCurrent)
+ DWORD))aSyscall[54].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
@@ -31465,12 +31853,12 @@ static struct win_syscall {
{ "Sleep", (SYSCALL)0, 0 },
#endif
-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[53].pCurrent)
+#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
- LPFILETIME))aSyscall[54].pCurrent)
+ LPFILETIME))aSyscall[56].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
@@ -31480,7 +31868,7 @@ static struct win_syscall {
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- DWORD))aSyscall[55].pCurrent)
+ DWORD))aSyscall[57].pCurrent)
#endif
#if !SQLITE_OS_WINCE
@@ -31490,7 +31878,7 @@ static struct win_syscall {
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
- LPOVERLAPPED))aSyscall[56].pCurrent)
+ LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
@@ -31498,17 +31886,17 @@ static struct win_syscall {
{ "UnmapViewOfFile", (SYSCALL)0, 0 },
#endif
-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[57].pCurrent)
+#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
- LPCSTR,LPBOOL))aSyscall[58].pCurrent)
+ LPCSTR,LPBOOL))aSyscall[60].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
- LPOVERLAPPED))aSyscall[59].pCurrent)
+ LPOVERLAPPED))aSyscall[61].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
@@ -31517,7 +31905,7 @@ static struct win_syscall {
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
- DWORD,DWORD))aSyscall[60].pCurrent)
+ DWORD,DWORD))aSyscall[62].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
@@ -31526,7 +31914,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
- DWORD))aSyscall[61].pCurrent)
+ DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
@@ -31535,7 +31923,7 @@ static struct win_syscall {
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
- BOOL))aSyscall[62].pCurrent)
+ BOOL))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
@@ -31544,7 +31932,7 @@ static struct win_syscall {
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
- PLARGE_INTEGER,DWORD))aSyscall[63].pCurrent)
+ PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
@@ -31553,7 +31941,7 @@ static struct win_syscall {
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
- FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[64].pCurrent)
+ FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
@@ -31562,7 +31950,7 @@ static struct win_syscall {
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
- SIZE_T))aSyscall[65].pCurrent)
+ SIZE_T))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
@@ -31571,7 +31959,7 @@ static struct win_syscall {
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
- LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[66].pCurrent)
+ LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
@@ -31580,7 +31968,7 @@ static struct win_syscall {
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
- DWORD))aSyscall[67].pCurrent)
+ DWORD))aSyscall[69].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
@@ -31588,7 +31976,7 @@ static struct win_syscall {
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[68].pCurrent)
+#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
@@ -31597,7 +31985,7 @@ static struct win_syscall {
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
- LPSYSTEM_INFO))aSyscall[69].pCurrent)
+ LPSYSTEM_INFO))aSyscall[71].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
@@ -31605,7 +31993,7 @@ static struct win_syscall {
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[70].pCurrent)
+#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
@@ -31613,11 +32001,11 @@ static struct win_syscall {
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[71].pCurrent)
+#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[72].pCurrent)
+#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
@@ -31626,7 +32014,7 @@ static struct win_syscall {
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
- LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[73].pCurrent)
+ LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
}; /* End of the overrideable system calls */
@@ -31713,6 +32101,94 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
return 0;
}
+#ifdef SQLITE_WIN32_MALLOC
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** compact it. Upon success, SQLITE_OK will be returned. Upon failure, one
+** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned. The
+** "pnLargest" argument, if non-zero, will be used to return the size of the
+** largest committed free block in the heap, in bytes.
+*/
+SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
+ int rc = SQLITE_OK;
+ UINT nLargest = 0;
+ HANDLE hHeap;
+
+ winMemAssertMagic();
+ hHeap = winMemGetHeap();
+ assert( hHeap!=0 );
+ assert( hHeap!=INVALID_HANDLE_VALUE );
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+#endif
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+ if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
+ DWORD lastErrno = osGetLastError();
+ if( lastErrno==NO_ERROR ){
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOMEM;
+ }else{
+ sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+ osGetLastError(), (void*)hHeap);
+ rc = SQLITE_ERROR;
+ }
+ }
+#else
+ sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
+ (void*)hHeap);
+ rc = SQLITE_NOTFOUND;
+#endif
+ if( pnLargest ) *pnLargest = nLargest;
+ return rc;
+}
+
+/*
+** If a Win32 native heap has been configured, this function will attempt to
+** destroy and recreate it. If the Win32 native heap is not isolated and/or
+** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+** be returned and no changes will be made to the Win32 native heap.
+*/
+SQLITE_API int sqlite3_win32_reset_heap(){
+ int rc;
+ MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
+ MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
+ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
+ MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+ sqlite3_mutex_enter(pMaster);
+ sqlite3_mutex_enter(pMem);
+ winMemAssertMagic();
+ if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
+ /*
+ ** At this point, there should be no outstanding memory allocations on
+ ** the heap. Also, since both the master and memsys locks are currently
+ ** being held by us, no other function (i.e. from another thread) should
+ ** be able to even access the heap. Attempt to destroy and recreate our
+ ** isolated Win32 native heap now.
+ */
+ assert( winMemGetHeap()!=NULL );
+ assert( winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ winMemShutdown(winMemGetDataPtr());
+ assert( winMemGetHeap()==NULL );
+ assert( !winMemGetOwned() );
+ assert( sqlite3_memory_used()==0 );
+ rc = winMemInit(winMemGetDataPtr());
+ assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
+ assert( rc!=SQLITE_OK || winMemGetOwned() );
+ assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
+ }else{
+ /*
+ ** The Win32 native heap cannot be modified because it may be in use.
+ */
+ rc = SQLITE_BUSY;
+ }
+ sqlite3_mutex_leave(pMem);
+ sqlite3_mutex_leave(pMaster);
+ return rc;
+}
+#endif /* SQLITE_WIN32_MALLOC */
+
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
@@ -31782,16 +32258,25 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
-# define isNT() (1)
+
+#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
+# define osIsNT() (1)
+#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+# define osIsNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
-# define isNT() (0)
+# define osIsNT() (0)
#else
- static int isNT(void){
+ static int osIsNT(void){
if( sqlite3_os_type==0 ){
+#if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8
+ OSVERSIONINFOW sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ osGetVersionExW(&sInfo);
+#else
OSVERSIONINFOA sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
osGetVersionExA(&sInfo);
+#endif
sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
}
return sqlite3_os_type==2;
@@ -31811,12 +32296,12 @@ static void *winMemMalloc(int nBytes){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
assert( nBytes>=0 );
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
nBytes, osGetLastError(), (void*)hHeap);
}
return p;
@@ -31833,11 +32318,11 @@ static void winMemFree(void *pPrior){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
}
}
@@ -31854,7 +32339,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
@@ -31863,7 +32348,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){
p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
}
if( !p ){
- sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
(void*)hHeap);
}
@@ -31882,12 +32367,12 @@ static int winMemSize(void *p){
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
- assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
#endif
if( !p ) return 0;
n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
if( n==(SIZE_T)-1 ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
p, osGetLastError(), (void*)hHeap);
return 0;
}
@@ -31908,18 +32393,25 @@ static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
- assert( pWinMemData->magic==WINMEM_MAGIC );
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
+ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
+ DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
+ if( dwMaximumSize==0 ){
+ dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
+ }else if( dwInitialSize>dwMaximumSize ){
+ dwInitialSize = dwMaximumSize;
+ }
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE,
- SQLITE_WIN32_HEAP_MAX_SIZE);
+ dwInitialSize, dwMaximumSize);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
- osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
+ "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+ osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+ dwMaximumSize);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
@@ -31929,7 +32421,7 @@ static int winMemInit(void *pAppData){
pWinMemData->hHeap = osGetProcessHeap();
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to GetProcessHeap (%d)", osGetLastError());
+ "failed to GetProcessHeap (%lu)", osGetLastError());
return SQLITE_NOMEM;
}
pWinMemData->bOwned = FALSE;
@@ -31950,6 +32442,9 @@ static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
+ assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+ assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
@@ -31957,7 +32452,7 @@ static void winMemShutdown(void *pAppData){
#endif
if( pWinMemData->bOwned ){
if( !osHeapDestroy(pWinMemData->hHeap) ){
- sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
+ sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
osGetLastError(), (void*)pWinMemData->hHeap);
}
pWinMemData->bOwned = FALSE;
@@ -31998,7 +32493,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
**
** Space to hold the returned string is obtained from malloc.
*/
-static LPWSTR utf8ToUnicode(const char *zFilename){
+static LPWSTR winUtf8ToUnicode(const char *zFilename){
int nChar;
LPWSTR zWideFilename;
@@ -32023,7 +32518,7 @@ static LPWSTR utf8ToUnicode(const char *zFilename){
** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is
** obtained from sqlite3_malloc().
*/
-static char *unicodeToUtf8(LPCWSTR zWideFilename){
+static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
@@ -32051,7 +32546,7 @@ static char *unicodeToUtf8(LPCWSTR zWideFilename){
** Space to hold the returned string is obtained
** from sqlite3_malloc.
*/
-static LPWSTR mbcsToUnicode(const char *zFilename){
+static LPWSTR winMbcsToUnicode(const char *zFilename){
int nByte;
LPWSTR zMbcsFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -32081,7 +32576,7 @@ static LPWSTR mbcsToUnicode(const char *zFilename){
** Space to hold the returned string is obtained from
** sqlite3_malloc().
*/
-static char *unicodeToMbcs(LPCWSTR zWideFilename){
+static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
int nByte;
char *zFilename;
int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
@@ -32111,11 +32606,11 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
char *zFilenameUtf8;
LPWSTR zTmpWide;
- zTmpWide = mbcsToUnicode(zFilename);
+ zTmpWide = winMbcsToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameUtf8 = unicodeToUtf8(zTmpWide);
+ zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameUtf8;
}
@@ -32128,11 +32623,11 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
char *zFilenameMbcs;
LPWSTR zTmpWide;
- zTmpWide = utf8ToUnicode(zFilename);
+ zTmpWide = winUtf8ToUnicode(zFilename);
if( zTmpWide==0 ){
return 0;
}
- zFilenameMbcs = unicodeToMbcs(zTmpWide);
+ zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
sqlite3_free(zTmpWide);
return zFilenameMbcs;
}
@@ -32162,7 +32657,7 @@ SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
if( ppDirectory ){
char *zValueUtf8 = 0;
if( zValue && zValue[0] ){
- zValueUtf8 = unicodeToUtf8(zValue);
+ zValueUtf8 = winUnicodeToUtf8(zValue);
if ( zValueUtf8==0 ){
return SQLITE_NOMEM;
}
@@ -32175,11 +32670,11 @@ SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
}
/*
-** The return value of getLastErrorMsg
+** The return value of winGetLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
** otherwise (if the message was truncated).
*/
-static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
+static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
/* FormatMessage returns 0 on failure. Otherwise it
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
@@ -32187,16 +32682,16 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
DWORD dwLen = 0;
char *zOut = 0;
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
- WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
+ WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
zTempWide,
- MAX_PATH,
+ SQLITE_WIN32_MAX_ERRMSG_CHARS,
0);
#else
LPWSTR zTempWide = NULL;
@@ -32213,7 +32708,7 @@ static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
- zOut = unicodeToUtf8(zTempWide);
+ zOut = winUnicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
/* free the system buffer allocated by FormatMessage */
@@ -32281,7 +32776,7 @@ static int winLogErrorAtLine(
int i; /* Loop counter */
zMsg[0] = 0;
- getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
+ winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
assert( errcode!=SQLITE_OK );
if( zPath==0 ) zPath = "";
for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
@@ -32306,17 +32801,17 @@ static int winLogErrorAtLine(
#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
#endif
-static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY;
-static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
+static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
+static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
/*
** If a ReadFile() or WriteFile() error occurs, invoke this routine
** to see if it should be retried. Return TRUE to retry. Return FALSE
** to give up with an error.
*/
-static int retryIoerr(int *pnRetry, DWORD *pError){
+static int winRetryIoerr(int *pnRetry, DWORD *pError){
DWORD e = osGetLastError();
- if( *pnRetry>=win32IoerrRetry ){
+ if( *pnRetry>=winIoerrRetry ){
if( pError ){
*pError = e;
}
@@ -32325,7 +32820,7 @@ static int retryIoerr(int *pnRetry, DWORD *pError){
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
- sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
+ sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
@@ -32338,11 +32833,11 @@ static int retryIoerr(int *pnRetry, DWORD *pError){
/*
** Log a I/O error retry episode.
*/
-static void logIoerr(int nRetry){
+static void winLogIoerr(int nRetry){
if( nRetry ){
sqlite3_log(SQLITE_IOERR,
"delayed %dms for lock/sharing conflict",
- win32IoerrRetryDelay*nRetry*(nRetry+1)/2
+ winIoerrRetryDelay*nRetry*(nRetry+1)/2
);
}
}
@@ -32407,7 +32902,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
BOOL bLogged = FALSE;
BOOL bInit = TRUE;
- zName = utf8ToUnicode(zFilename);
+ zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
return SQLITE_IOERR_NOMEM;
@@ -32427,10 +32922,9 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
if (!pFile->hMutex){
pFile->lastErrno = osGetLastError();
- winLogError(SQLITE_IOERR, pFile->lastErrno,
- "winceCreateLock1", zFilename);
sqlite3_free(zName);
- return SQLITE_IOERR;
+ return winLogError(SQLITE_IOERR, pFile->lastErrno,
+ "winceCreateLock1", zFilename);
}
/* Acquire the mutex before continuing */
@@ -32680,7 +33174,7 @@ static BOOL winLockFile(
return winceLockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -32711,7 +33205,7 @@ static BOOL winUnlockFile(
return winceUnlockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
- if( isNT() ){
+ if( osIsNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
@@ -32741,7 +33235,7 @@ static BOOL winUnlockFile(
** argument to offset iOffset within the file. If successful, return 0.
** Otherwise, set pFile->lastErrno and return non-zero.
*/
-static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
+static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
LONG upperBits; /* Most sig. 32 bits of new offset */
LONG lowerBits; /* Least sig. 32 bits of new offset */
@@ -32766,7 +33260,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
&& ((lastErrno = osGetLastError())!=NO_ERROR)) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
@@ -32787,7 +33281,7 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
if(!bRet){
pFile->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
- "seekWinFile", pFile->zPath);
+ "winSeekFile", pFile->zPath);
OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
return 1;
}
@@ -32798,7 +33292,8 @@ static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
}
#if SQLITE_MAX_MMAP_SIZE>0
-/* Forward references to VFS methods */
+/* Forward references to VFS helper methods used for memory mapped files */
+static int winMapfile(winFile*, sqlite3_int64);
static int winUnmapfile(winFile*);
#endif
@@ -32825,8 +33320,7 @@ static int winClose(sqlite3_file *id){
OSTRACE(("CLOSE file=%p\n", pFile->h));
#if SQLITE_MAX_MMAP_SIZE>0
- rc = winUnmapfile(pFile);
- if( rc!=SQLITE_OK ) return rc;
+ winUnmapfile(pFile);
#endif
do{
@@ -32902,7 +33396,7 @@ static int winRead(
#endif
#if SQLITE_OS_WINCE
- if( seekWinFile(pFile, offset) ){
+ if( winSeekFile(pFile, offset) ){
OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
return SQLITE_FULL;
}
@@ -32915,13 +33409,13 @@ static int winRead(
osGetLastError()!=ERROR_HANDLE_EOF ){
#endif
DWORD lastErrno;
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
pFile->lastErrno = lastErrno;
OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
- "winRead", pFile->zPath);
+ "winRead", pFile->zPath);
}
- logIoerr(nRetry);
+ winLogIoerr(nRetry);
if( nRead<(DWORD)amt ){
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[nRead], 0, amt-nRead);
@@ -32974,7 +33468,7 @@ static int winWrite(
#endif
#if SQLITE_OS_WINCE
- rc = seekWinFile(pFile, offset);
+ rc = winSeekFile(pFile, offset);
if( rc==0 ){
#else
{
@@ -32999,7 +33493,7 @@ static int winWrite(
#else
if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
#endif
- if( retryIoerr(&nRetry, &lastErrno) ) continue;
+ if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
break;
}
assert( nWrite==0 || nWrite<=(DWORD)nRem );
@@ -33025,13 +33519,14 @@ static int winWrite(
if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
|| ( pFile->lastErrno==ERROR_DISK_FULL )){
OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
- return SQLITE_FULL;
+ return winLogError(SQLITE_FULL, pFile->lastErrno,
+ "winWrite1", pFile->zPath);
}
OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
- "winWrite", pFile->zPath);
+ "winWrite2", pFile->zPath);
}else{
- logIoerr(nRetry);
+ winLogIoerr(nRetry);
}
OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
@@ -33060,7 +33555,7 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
}
/* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
- if( seekWinFile(pFile, nByte) ){
+ if( winSeekFile(pFile, nByte) ){
rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
"winTruncate1", pFile->zPath);
}else if( 0==osSetEndOfFile(pFile->h) &&
@@ -33141,6 +33636,7 @@ static int winSync(sqlite3_file *id, int flags){
** no-op
*/
#ifdef SQLITE_NO_SYNC
+ OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
#else
rc = osFlushFileBuffers(pFile->h);
@@ -33152,7 +33648,7 @@ static int winSync(sqlite3_file *id, int flags){
pFile->lastErrno = osGetLastError();
OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
- "winSync", pFile->zPath);
+ "winSync", pFile->zPath);
}
#endif
}
@@ -33193,7 +33689,7 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
&& ((lastErrno = osGetLastError())!=NO_ERROR) ){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
- "winFileSize", pFile->zPath);
+ "winFileSize", pFile->zPath);
}
}
#endif
@@ -33238,10 +33734,10 @@ static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
-static int getReadLock(winFile *pFile){
+static int winGetReadLock(winFile *pFile){
int res;
OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
@@ -33273,11 +33769,11 @@ static int getReadLock(winFile *pFile){
/*
** Undo a readlock
*/
-static int unlockReadLock(winFile *pFile){
+static int winUnlockReadLock(winFile *pFile){
int res;
DWORD lastErrno;
OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
- if( isNT() ){
+ if( osIsNT() ){
res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -33288,7 +33784,7 @@ static int unlockReadLock(winFile *pFile){
if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
- "unlockReadLock", pFile->zPath);
+ "winUnlockReadLock", pFile->zPath);
}
OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res)));
return res;
@@ -33379,7 +33875,7 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==SHARED_LOCK && res ){
assert( pFile->locktype==NO_LOCK );
- res = getReadLock(pFile);
+ res = winGetReadLock(pFile);
if( res ){
newLocktype = SHARED_LOCK;
}else{
@@ -33410,14 +33906,14 @@ static int winLock(sqlite3_file *id, int locktype){
*/
if( locktype==EXCLUSIVE_LOCK && res ){
assert( pFile->locktype>=SHARED_LOCK );
- res = unlockReadLock(pFile);
+ res = winUnlockReadLock(pFile);
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
if( res ){
newLocktype = EXCLUSIVE_LOCK;
}else{
lastErrno = osGetLastError();
- getReadLock(pFile);
+ winGetReadLock(pFile);
}
}
@@ -33434,10 +33930,10 @@ static int winLock(sqlite3_file *id, int locktype){
if( res ){
rc = SQLITE_OK;
}else{
- OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
- pFile->h, locktype, newLocktype));
pFile->lastErrno = lastErrno;
rc = SQLITE_BUSY;
+ OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
+ pFile->h, locktype, newLocktype));
}
pFile->locktype = (u8)newLocktype;
OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
@@ -33497,18 +33993,18 @@ static int winUnlock(sqlite3_file *id, int locktype){
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
- if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
+ if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
/* This should never happen. We should always be able to
** reacquire the read lock */
rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
- "winUnlock", pFile->zPath);
+ "winUnlock", pFile->zPath);
}
}
if( type>=RESERVED_LOCK ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
- unlockReadLock(pFile);
+ winUnlockReadLock(pFile);
}
if( type>=PENDING_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
@@ -33535,8 +34031,10 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
}
}
-/* Forward declaration */
-static int getTempname(int nBuf, char *zBuf);
+/* Forward references to VFS helper methods used for temporary files */
+static int winGetTempname(sqlite3_vfs *, char **);
+static int winIsDir(const void *);
+static BOOL winIsDriveLetterAndColon(const char *);
/*
** Control and query of the open file handle.
@@ -33596,37 +34094,44 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
case SQLITE_FCNTL_WIN32_AV_RETRY: {
int *a = (int*)pArg;
if( a[0]>0 ){
- win32IoerrRetry = a[0];
+ winIoerrRetry = a[0];
}else{
- a[0] = win32IoerrRetry;
+ a[0] = winIoerrRetry;
}
if( a[1]>0 ){
- win32IoerrRetryDelay = a[1];
+ winIoerrRetryDelay = a[1];
}else{
- a[1] = win32IoerrRetryDelay;
+ a[1] = winIoerrRetryDelay;
}
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
- char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
- if( zTFile ){
- getTempname(pFile->pVfs->mxPathname, zTFile);
+ char *zTFile = 0;
+ int rc = winGetTempname(pFile->pVfs, &zTFile);
+ if( rc==SQLITE_OK ){
*(char**)pArg = zTFile;
}
- OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
- return SQLITE_OK;
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+ return rc;
}
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
+ int rc = SQLITE_OK;
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
*(i64*)pArg = pFile->mmapSizeMax;
- if( newLimit>=0 ) pFile->mmapSizeMax = newLimit;
- OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
- return SQLITE_OK;
+ if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+ pFile->mmapSizeMax = newLimit;
+ if( pFile->mmapSize>0 ){
+ winUnmapfile(pFile);
+ rc = winMapfile(pFile, -1);
+ }
+ }
+ OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+ return rc;
}
#endif
}
@@ -33831,7 +34336,6 @@ static int winDelete(sqlite3_vfs *,const char*,int);
static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
winShmNode **pp;
winShmNode *p;
- BOOL bRc;
assert( winShmMutexHeld() );
OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
osGetCurrentProcessId(), deleteFlag));
@@ -33839,14 +34343,16 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
while( (p = *pp)!=0 ){
if( p->nRef==0 ){
int i;
- if( p->mutex ) sqlite3_mutex_free(p->mutex);
+ if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
for(i=0; i<p->nRegion; i++){
- bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
+ BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
bRc = osCloseHandle(p->aRegion[i].hMap);
OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+ UNUSED_VARIABLE_VALUE(bRc);
}
if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
SimulateIOErrorBenign(1);
@@ -33941,7 +34447,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winOpenShm", pDbFd->zPath);
+ "winOpenShm", pDbFd->zPath);
}
}
if( rc==SQLITE_OK ){
@@ -34201,7 +34707,7 @@ static int winShmMap(
rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap1", pDbFd->zPath);
+ "winShmMap1", pDbFd->zPath);
goto shmpage_out;
}
@@ -34216,7 +34722,7 @@ static int winShmMap(
rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
if( rc!=SQLITE_OK ){
rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
- "winShmMap2", pDbFd->zPath);
+ "winShmMap2", pDbFd->zPath);
goto shmpage_out;
}
}
@@ -34270,7 +34776,7 @@ static int winShmMap(
if( !pMap ){
pShmNode->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
- "winShmMap3", pDbFd->zPath);
+ "winShmMap3", pDbFd->zPath);
if( hMap ) osCloseHandle(hMap);
goto shmpage_out;
}
@@ -34318,7 +34824,7 @@ static int winUnmapfile(winFile *pFile){
"rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
pFile->pMapRegion));
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
- "winUnmap1", pFile->zPath);
+ "winUnmapfile1", pFile->zPath);
}
pFile->pMapRegion = 0;
pFile->mmapSize = 0;
@@ -34330,7 +34836,7 @@ static int winUnmapfile(winFile *pFile){
OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
osGetCurrentProcessId(), pFile, pFile->hMap));
return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
- "winUnmap2", pFile->zPath);
+ "winUnmapfile2", pFile->zPath);
}
pFile->hMap = NULL;
}
@@ -34405,27 +34911,28 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
if( pFd->hMap==NULL ){
pFd->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
- "winMapfile", pFd->zPath);
+ "winMapfile1", pFd->zPath);
/* Log the error, but continue normal operation using xRead/xWrite */
- OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
- osGetCurrentProcessId(), pFd));
+ OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return SQLITE_OK;
}
assert( (nMap % winSysInfo.dwPageSize)==0 );
+ assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
#if SQLITE_OS_WINRT
- pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
+ pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
#else
- assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
#endif
if( pNew==NULL ){
osCloseHandle(pFd->hMap);
pFd->hMap = NULL;
pFd->lastErrno = osGetLastError();
- winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
- "winMapfile", pFd->zPath);
- OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
- osGetCurrentProcessId(), pFd));
+ rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+ "winMapfile2", pFd->zPath);
+ /* Log the error, but continue normal operation using xRead/xWrite */
+ OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
+ osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
return SQLITE_OK;
}
pFd->pMapRegion = pNew;
@@ -34564,16 +35071,37 @@ static const sqlite3_io_methods winIoMethod = {
** sqlite3_vfs object.
*/
+#if defined(__CYGWIN__)
+/*
+** Convert a filename from whatever the underlying operating system
+** supports for filenames into UTF-8. Space to hold the result is
+** obtained from malloc and must be freed by the calling function.
+*/
+static char *winConvertToUtf8Filename(const void *zFilename){
+ char *zConverted = 0;
+ if( osIsNT() ){
+ zConverted = winUnicodeToUtf8(zFilename);
+ }
+#ifdef SQLITE_WIN32_HAS_ANSI
+ else{
+ zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+ }
+#endif
+ /* caller will handle out of memory */
+ return zConverted;
+}
+#endif
+
/*
** Convert a UTF-8 filename into whatever form the underlying
** operating system wants filenames in. Space to hold the result
** is obtained from malloc and must be freed by the calling
** function.
*/
-static void *convertUtf8Filename(const char *zFilename){
+static void *winConvertFromUtf8Filename(const char *zFilename){
void *zConverted = 0;
- if( isNT() ){
- zConverted = utf8ToUnicode(zFilename);
+ if( osIsNT() ){
+ zConverted = winUtf8ToUnicode(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
@@ -34585,17 +35113,39 @@ static void *convertUtf8Filename(const char *zFilename){
}
/*
-** Create a temporary file name in zBuf. zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
+** This function returns non-zero if the specified UTF-8 string buffer
+** ends with a directory separator character or one was successfully
+** added to it.
+*/
+static int winMakeEndInDirSep(int nBuf, char *zBuf){
+ if( zBuf ){
+ int nLen = sqlite3Strlen30(zBuf);
+ if( nLen>0 ){
+ if( winIsDirSep(zBuf[nLen-1]) ){
+ return 1;
+ }else if( nLen+1<nBuf ){
+ zBuf[nLen] = winGetDirSep();
+ zBuf[nLen+1] = '\0';
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Create a temporary file name and store the resulting pointer into pzBuf.
+** The pointer returned in pzBuf must be freed via sqlite3_free().
*/
-static int getTempname(int nBuf, char *zBuf){
+static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
- int nTempPath;
- char zTempPath[MAX_PATH+2];
+ int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
+ int nMax, nBuf, nDir, nLen;
+ char *zBuf;
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
@@ -34603,21 +35153,140 @@ static int getTempname(int nBuf, char *zBuf){
*/
SimulateIOError( return SQLITE_IOERR );
- memset(zTempPath, 0, MAX_PATH+2);
+ /* Allocate a temporary buffer to store the fully qualified file
+ ** name for the temporary file. If this fails, we cannot continue.
+ */
+ nMax = pVfs->mxPathname; nBuf = nMax + 2;
+ zBuf = sqlite3MallocZero( nBuf );
+ if( !zBuf ){
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ /* Figure out the effective temporary directory. First, check if one
+ ** has been explicitly set by the application; otherwise, use the one
+ ** configured by the operating system.
+ */
+ nDir = nMax - (nPre + 15);
+ assert( nDir>0 );
if( sqlite3_temp_directory ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
+ int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
+ if( nDirLen>0 ){
+ if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
+ nDirLen++;
+ }
+ if( nDirLen>nDir ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
+ }
}
-#if !SQLITE_OS_WINRT
- else if( isNT() ){
+#if defined(__CYGWIN__)
+ else{
+ static const char *azDirs[] = {
+ 0, /* getenv("SQLITE_TMPDIR") */
+ 0, /* getenv("TMPDIR") */
+ 0, /* getenv("TMP") */
+ 0, /* getenv("TEMP") */
+ 0, /* getenv("USERPROFILE") */
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ ".",
+ 0 /* List terminator */
+ };
+ unsigned int i;
+ const char *zDir = 0;
+
+ if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
+ if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+ if( !azDirs[2] ) azDirs[2] = getenv("TMP");
+ if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
+ if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+ void *zConverted;
+ if( zDir==0 ) continue;
+ /* If the path starts with a drive letter followed by the colon
+ ** character, assume it is already a native Win32 path; otherwise,
+ ** it must be converted to a native Win32 path via the Cygwin API
+ ** prior to using it.
+ */
+ if( winIsDriveLetterAndColon(zDir) ){
+ zConverted = winConvertFromUtf8Filename(zDir);
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( winIsDir(zConverted) ){
+ sqlite3_snprintf(nMax, zBuf, "%s", zDir);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }else{
+ zConverted = sqlite3MallocZero( nMax+1 );
+ if( !zConverted ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+ zConverted, nMax+1)<0 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
+ return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
+ "winGetTempname2", zDir);
+ }
+ if( winIsDir(zConverted) ){
+ /* At this point, we know the candidate directory exists and should
+ ** be used. However, we may need to convert the string containing
+ ** its name into UTF-8 (i.e. if it is UTF-16 right now).
+ */
+ char *zUtf8 = winConvertToUtf8Filename(zConverted);
+ if( !zUtf8 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zConverted);
+ break;
+ }
+ sqlite3_free(zConverted);
+ }
+ }
+ }
+#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+ else if( osIsNT() ){
char *zMulti;
- WCHAR zWidePath[MAX_PATH];
- osGetTempPathW(MAX_PATH-30, zWidePath);
- zMulti = unicodeToUtf8(zWidePath);
+ LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
+ if( !zWidePath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathW(nMax, zWidePath)==0 ){
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname2", 0);
+ }
+ zMulti = winUnicodeToUtf8(zWidePath);
if( zMulti ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
+ sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
sqlite3_free(zMulti);
+ sqlite3_free(zWidePath);
}else{
+ sqlite3_free(zWidePath);
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
@@ -34625,36 +35294,62 @@ static int getTempname(int nBuf, char *zBuf){
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
- char zMbcsPath[MAX_PATH];
- osGetTempPathA(MAX_PATH-30, zMbcsPath);
+ char *zMbcsPath = sqlite3MallocZero( nMax );
+ if( !zMbcsPath ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( osGetTempPathA(nMax, zMbcsPath)==0 ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+ return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+ "winGetTempname3", 0);
+ }
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
}
-#endif
-#endif
+#endif /* SQLITE_WIN32_HAS_ANSI */
+#endif /* !SQLITE_OS_WINRT */
- /* Check that the output buffer is large enough for the temporary file
- ** name. If it is not, return SQLITE_ERROR.
+ /*
+ ** Check to make sure the temporary directory ends with an appropriate
+ ** separator. If it does not and there is not enough space left to add
+ ** one, fail.
*/
- nTempPath = sqlite3Strlen30(zTempPath);
+ if( !winMakeEndInDirSep(nDir+1, zBuf) ){
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
+ }
- if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
+ /*
+ ** Check that the output buffer is large enough for the temporary file
+ ** name in the following format:
+ **
+ ** "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
+ **
+ ** If not, return SQLITE_ERROR. The number 17 is used here in order to
+ ** account for the space used by the 15 character random suffix and the
+ ** two trailing NUL characters. The final directory separator character
+ ** has already added if it was not already present.
+ */
+ nLen = sqlite3Strlen30(zBuf);
+ if( (nLen + nPre + 17) > nBuf ){
+ sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
- return SQLITE_ERROR;
+ return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
}
- for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
- zTempPath[i] = 0;
+ sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
- sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
- "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
- zTempPath);
j = sqlite3Strlen30(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
@@ -34662,6 +35357,7 @@ static int getTempname(int nBuf, char *zBuf){
}
zBuf[j] = 0;
zBuf[j+1] = 0;
+ *pzBuf = zBuf;
OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
return SQLITE_OK;
@@ -34677,13 +35373,13 @@ static int winIsDir(const void *zConverted){
int rc = 0;
DWORD lastErrno;
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( !rc ){
return 0; /* Invalid name? */
}
@@ -34700,14 +35396,14 @@ static int winIsDir(const void *zConverted){
** Open a file.
*/
static int winOpen(
- sqlite3_vfs *pVfs, /* Not used */
+ sqlite3_vfs *pVfs, /* Used to get maximum path name length */
const char *zName, /* Name of the file (UTF-8) */
sqlite3_file *id, /* Write the SQLite file handle here */
int flags, /* Open mode flags */
int *pOutFlags /* Status return flags */
){
HANDLE h;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
DWORD dwDesiredAccess;
DWORD dwShareMode;
DWORD dwCreationDisposition;
@@ -34723,7 +35419,7 @@ static int winOpen(
/* If argument zPath is a NULL pointer, this function is required to open
** a temporary file. Use this buffer to store the file name in.
*/
- char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */
+ char *zTmpname = 0; /* For temporary filename, if necessary. */
int rc = SQLITE_OK; /* Function Return Code */
#if !defined(NDEBUG) || SQLITE_OS_WINCE
@@ -34778,7 +35474,7 @@ static int winOpen(
pFile->h = INVALID_HANDLE_VALUE;
#if SQLITE_OS_WINRT
- if( !sqlite3_temp_directory ){
+ if( !zUtf8Name && !sqlite3_temp_directory ){
sqlite3_log(SQLITE_ERROR,
"sqlite3_temp_directory variable should be set for WinRT");
}
@@ -34788,9 +35484,8 @@ static int winOpen(
** temporary file name to use
*/
if( !zUtf8Name ){
- assert(isDelete && !isOpenJournal);
- memset(zTmpname, 0, MAX_PATH+2);
- rc = getTempname(MAX_PATH+2, zTmpname);
+ assert( isDelete && !isOpenJournal );
+ rc = winGetTempname(pVfs, &zTmpname);
if( rc!=SQLITE_OK ){
OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
return rc;
@@ -34803,17 +35498,19 @@ static int winOpen(
** sqlite3_uri_parameter().
*/
assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
- zUtf8Name[strlen(zUtf8Name)+1]==0 );
+ zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
- zConverted = convertUtf8Filename(zUtf8Name);
+ zConverted = winConvertFromUtf8Filename(zUtf8Name);
if( zConverted==0 ){
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
return SQLITE_IOERR_NOMEM;
}
if( winIsDir(zConverted) ){
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
return SQLITE_CANTOPEN_ISDIR;
}
@@ -34860,7 +35557,7 @@ static int winOpen(
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
@@ -34875,7 +35572,7 @@ static int winOpen(
dwShareMode,
dwCreationDisposition,
&extendedParameters))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#else
@@ -34885,7 +35582,7 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#endif
@@ -34898,12 +35595,12 @@ static int winOpen(
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
- retryIoerr(&cnt, &lastErrno) ){
+ winRetryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
- logIoerr(cnt);
+ winLogIoerr(cnt);
OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
@@ -34912,6 +35609,7 @@ static int winOpen(
pFile->lastErrno = lastErrno;
winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
if( isReadWrite && !isExclusive ){
return winOpen(pVfs, zName, id,
((flags|SQLITE_OPEN_READONLY) &
@@ -34940,6 +35638,7 @@ static int winOpen(
){
osCloseHandle(h);
sqlite3_free(zConverted);
+ sqlite3_free(zTmpname);
OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
return rc;
}
@@ -34951,6 +35650,7 @@ static int winOpen(
sqlite3_free(zConverted);
}
+ sqlite3_free(zTmpname);
pFile->pMethod = &winIoMethod;
pFile->pVfs = pVfs;
pFile->h = h;
@@ -34994,7 +35694,7 @@ static int winDelete(
int cnt = 0;
int rc;
DWORD attr;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
@@ -35002,11 +35702,12 @@ static int winDelete(
SimulateIOError(return SQLITE_IOERR_DELETE);
OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
- zConverted = convertUtf8Filename(zFilename);
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
+ OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
@@ -35045,7 +35746,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -35073,7 +35774,7 @@ static int winDelete(
rc = SQLITE_OK; /* Deleted OK. */
break;
}
- if ( !retryIoerr(&cnt, &lastErrno) ){
+ if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
@@ -35081,10 +35782,9 @@ static int winDelete(
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
- rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
- "winDelete", zFilename);
+ rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt);
}
sqlite3_free(zConverted);
OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
@@ -35102,7 +35802,7 @@ static int winAccess(
){
DWORD attr;
int rc = 0;
- DWORD lastErrno;
+ DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
@@ -35110,18 +35810,18 @@ static int winAccess(
OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
zFilename, flags, pResOut));
- zConverted = convertUtf8Filename(zFilename);
+ zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
- &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+ &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( rc ){
/* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
** as if it does not exist.
@@ -35134,11 +35834,11 @@ static int winAccess(
attr = sAttrData.dwFileAttributes;
}
}else{
- logIoerr(cnt);
+ winLogIoerr(cnt);
if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
- winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
- return SQLITE_IOERR_ACCESS;
+ return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
+ zFilename);
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
@@ -35168,6 +35868,15 @@ static int winAccess(
return SQLITE_OK;
}
+/*
+** Returns non-zero if the specified path name starts with a drive letter
+** followed by a colon character.
+*/
+static BOOL winIsDriveLetterAndColon(
+ const char *zPathname
+){
+ return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+}
/*
** Returns non-zero if the specified path name should be used verbatim. If
@@ -35185,7 +35894,7 @@ static BOOL winIsVerbatimPathname(
** the final two cases; therefore, we return the safer return value of TRUE
** so that callers of this function will simply use it verbatim.
*/
- if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
+ if ( winIsDirSep(zPathname[0]) ){
return TRUE;
}
@@ -35195,7 +35904,7 @@ static BOOL winIsVerbatimPathname(
** attempt to treat it as a relative path name (i.e. they should simply use
** it verbatim).
*/
- if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
+ if ( winIsDriveLetterAndColon(zPathname) ){
return TRUE;
}
@@ -35221,7 +35930,6 @@ static int winFullPathname(
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
- assert( pVfs->mxPathname>=MAX_PATH );
assert( nFull>=pVfs->mxPathname );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
@@ -35230,14 +35938,48 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
- char zOut[MAX_PATH+1];
- memset(zOut, 0, MAX_PATH+1);
- cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
- MAX_PATH+1);
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zOut);
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+ CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname1", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
+ }
}else{
- cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+ zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
+ return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+ "winFullPathname2", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
+ }
}
return SQLITE_OK;
#endif
@@ -35253,8 +35995,8 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
@@ -35269,7 +36011,7 @@ static int winFullPathname(
/* If this path name begins with "/X:", where "X" is any alphabetic
** character, discard the initial "/" from the pathname.
*/
- if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
+ if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
zRelative++;
}
@@ -35286,22 +36028,21 @@ static int winFullPathname(
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
- sqlite3_data_directory, zRelative);
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
- zConverted = convertUtf8Filename(zRelative);
+ zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
- if( isNT() ){
+ if( osIsNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW1", zConverted);
sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname1", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -35311,14 +36052,13 @@ static int winFullPathname(
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameW2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname2", zRelative);
}
sqlite3_free(zConverted);
- zOut = unicodeToUtf8(zTemp);
+ zOut = winUnicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -35326,10 +36066,9 @@ static int winFullPathname(
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA1", zConverted);
sqlite3_free(zConverted);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname3", zRelative);
}
nByte += 3;
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
@@ -35339,11 +36078,10 @@ static int winFullPathname(
}
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
- winLogError(SQLITE_ERROR, osGetLastError(),
- "GetFullPathNameA2", zConverted);
sqlite3_free(zConverted);
sqlite3_free(zTemp);
- return SQLITE_CANTOPEN_FULLPATH;
+ return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+ "winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
@@ -35371,12 +36109,12 @@ static int winFullPathname(
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
- void *zConverted = convertUtf8Filename(zFilename);
+ void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
return 0;
}
- if( isNT() ){
+ if( osIsNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
@@ -35393,7 +36131,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
- getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
+ winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
UNUSED_PARAMETER(pVfs);
@@ -35569,7 +36307,7 @@ static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
*/
static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
UNUSED_PARAMETER(pVfs);
- return getLastErrorMsg(osGetLastError(), nBuf, zBuf);
+ return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
}
/*
@@ -35579,7 +36317,7 @@ SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
- MAX_PATH, /* mxPathname */
+ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
0, /* pNext */
"win32", /* zName */
0, /* pAppData */
@@ -35600,10 +36338,36 @@ SQLITE_API int sqlite3_os_init(void){
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ static sqlite3_vfs winLongPathVfs = {
+ 3, /* iVersion */
+ sizeof(winFile), /* szOsFile */
+ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
+ 0, /* pNext */
+ "win32-longpath", /* zName */
+ 0, /* pAppData */
+ winOpen, /* xOpen */
+ winDelete, /* xDelete */
+ winAccess, /* xAccess */
+ winFullPathname, /* xFullPathname */
+ winDlOpen, /* xDlOpen */
+ winDlError, /* xDlError */
+ winDlSym, /* xDlSym */
+ winDlClose, /* xDlClose */
+ winRandomness, /* xRandomness */
+ winSleep, /* xSleep */
+ winCurrentTime, /* xCurrentTime */
+ winGetLastError, /* xGetLastError */
+ winCurrentTimeInt64, /* xCurrentTimeInt64 */
+ winSetSystemCall, /* xSetSystemCall */
+ winGetSystemCall, /* xGetSystemCall */
+ winNextSystemCall, /* xNextSystemCall */
+ };
+#endif
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==74 );
+ assert( ArraySize(aSyscall)==76 );
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
@@ -35616,6 +36380,11 @@ SQLITE_API int sqlite3_os_init(void){
assert( winSysInfo.dwPageSize>0 );
sqlite3_vfs_register(&winVfs, 1);
+
+#if defined(SQLITE_WIN32_HAS_WIDE)
+ sqlite3_vfs_register(&winLongPathVfs, 0);
+#endif
+
return SQLITE_OK;
}
@@ -37226,7 +37995,7 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
int sz; /* Bytes of memory required to allocate the new cache */
/*
- ** The seperateCache variable is true if each PCache has its own private
+ ** The separateCache variable is true if each PCache has its own private
** PGroup. In other words, separateCache is true for mode (1) where no
** mutexing is required.
**
@@ -37429,6 +38198,7 @@ static sqlite3_pcache_page *pcache1Fetch(
if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
goto fetch_out;
}
+ assert( pCache->nHash>0 && pCache->apHash );
/* Step 4. Try to recycle a page. */
if( pCache->bPurgeable && pGroup->pLruTail && (
@@ -38790,6 +39560,13 @@ struct PagerSavepoint {
};
/*
+** Bits of the Pager.doNotSpill flag. See further description below.
+*/
+#define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */
+#define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */
+#define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */
+
+/*
** A open page cache is an instance of struct Pager. A description of
** some of the more important member variables follows:
**
@@ -38855,19 +39632,21 @@ struct PagerSavepoint {
** journal file from being successfully finalized, the setMaster flag
** is cleared anyway (and the pager will move to ERROR state).
**
-** doNotSpill, doNotSyncSpill
+** doNotSpill
**
-** These two boolean variables control the behavior of cache-spills
-** (calls made by the pcache module to the pagerStress() routine to
-** write cached data to the file-system in order to free up memory).
+** This variables control the behavior of cache-spills (calls made by
+** the pcache module to the pagerStress() routine to write cached data
+** to the file-system in order to free up memory).
**
-** When doNotSpill is non-zero, writing to the database from pagerStress()
-** is disabled altogether. This is done in a very obscure case that
+** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
+** writing to the database from pagerStress() is disabled altogether.
+** The SPILLFLAG_ROLLBACK case is done in a very obscure case that
** comes up during savepoint rollback that requires the pcache module
** to allocate a new page to prevent the journal file from being written
-** while it is being traversed by code in pager_playback().
+** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF
+** case is a user preference.
**
-** If doNotSyncSpill is non-zero, writing to the database from pagerStress()
+** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
** is permitted, but syncing the journal file is not. This flag is set
** by sqlite3PagerWrite() when the file-system sector-size is larger than
** the database page-size in order to prevent a journal sync from happening
@@ -38971,7 +39750,6 @@ struct Pager {
u8 changeCountDone; /* Set after incrementing the change-counter */
u8 setMaster; /* True if a m-j name has been written to jrnl */
u8 doNotSpill; /* Do not spill the cache when non-zero */
- u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */
u8 subjInMemory; /* True to use in-memory sub-journals */
Pgno dbSize; /* Number of pages in the database */
Pgno dbOrigSize; /* dbSize before the current transaction */
@@ -39350,13 +40128,17 @@ static char *print_pager_state(Pager *p){
** PagerSavepoint.pInSavepoint.
*/
static int subjRequiresPage(PgHdr *pPg){
- Pgno pgno = pPg->pgno;
Pager *pPager = pPg->pPager;
+ PagerSavepoint *p;
+ Pgno pgno;
int i;
- for(i=0; i<pPager->nSavepoint; i++){
- PagerSavepoint *p = &pPager->aSavepoint[i];
- if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
- return 1;
+ if( pPager->nSavepoint ){
+ pgno = pPg->pgno;
+ for(i=0; i<pPager->nSavepoint; i++){
+ p = &pPager->aSavepoint[i];
+ if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
+ return 1;
+ }
}
}
return 0;
@@ -40148,6 +40930,7 @@ static void pager_unlock(Pager *pPager){
pPager->changeCountDone = pPager->tempFile;
pPager->eState = PAGER_OPEN;
pPager->errCode = SQLITE_OK;
+ if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
}
pPager->journalOff = 0;
@@ -40630,11 +41413,11 @@ static int pager_playback_one_page(
** requiring a journal-sync before it is written.
*/
assert( isSavepnt );
- assert( pPager->doNotSpill==0 );
- pPager->doNotSpill++;
+ assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
+ pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
- assert( pPager->doNotSpill==1 );
- pPager->doNotSpill--;
+ assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
+ pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
if( rc!=SQLITE_OK ) return rc;
pPg->flags &= ~PGHDR_NEED_READ;
sqlite3PcacheMakeDirty(pPg);
@@ -41201,12 +41984,6 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
assert( pPager->eState>=PAGER_READER && !MEMDB );
assert( isOpen(pPager->fd) );
- if( NEVER(!isOpen(pPager->fd)) ){
- assert( pPager->tempFile );
- memset(pPg->pData, 0, pPager->pageSize);
- return SQLITE_OK;
- }
-
#ifndef SQLITE_OMIT_WAL
if( iFrame ){
/* Try to pull the page from the write-ahead log. */
@@ -41714,10 +42491,10 @@ SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
static void pagerFixMaplimit(Pager *pPager){
#if SQLITE_MAX_MMAP_SIZE>0
sqlite3_file *fd = pPager->fd;
- if( isOpen(fd) ){
+ if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
sqlite3_int64 sz;
- pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->szMmap>0;
sz = pPager->szMmap;
+ pPager->bUseFetch = (sz>0);
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
}
#endif
@@ -41739,9 +42516,12 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
}
/*
-** Adjust the robustness of the database to damage due to OS crashes
-** or power failures by changing the number of syncs()s when writing
-** the rollback journal. There are three levels:
+** Adjust settings of the pager to those specified in the pgFlags parameter.
+**
+** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
+** of the database to damage due to OS crashes or power failures by
+** changing the number of syncs()s when writing the journals.
+** There are three levels:
**
** OFF sqlite3OsSync() is never called. This is the default
** for temporary and transient files.
@@ -41782,22 +42562,21 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** and FULL=3.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
+SQLITE_PRIVATE void sqlite3PagerSetFlags(
Pager *pPager, /* The pager to set safety level for */
- int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
- int bFullFsync, /* PRAGMA fullfsync */
- int bCkptFullFsync /* PRAGMA checkpoint_fullfsync */
+ unsigned pgFlags /* Various flags */
){
+ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
assert( level>=1 && level<=3 );
pPager->noSync = (level==1 || pPager->tempFile) ?1:0;
pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
if( pPager->noSync ){
pPager->syncFlags = 0;
pPager->ckptSyncFlags = 0;
- }else if( bFullFsync ){
+ }else if( pgFlags & PAGER_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_FULL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
- }else if( bCkptFullFsync ){
+ }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_NORMAL;
pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
}else{
@@ -41808,6 +42587,11 @@ SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(
if( pPager->fullSync ){
pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
}
+ if( pgFlags & PAGER_CACHESPILL ){
+ pPager->doNotSpill &= ~SPILLFLAG_OFF;
+ }else{
+ pPager->doNotSpill |= SPILLFLAG_OFF;
+ }
}
#endif
@@ -42550,7 +43334,8 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
*/
assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
if( rc==SQLITE_OK
- && (pList->pDirty ? pPager->dbSize : pList->pgno+1)>pPager->dbHintSize
+ && pPager->dbHintSize<pPager->dbSize
+ && (pList->pDirty || pList->pgno>pPager->dbHintSize)
){
sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
@@ -42707,13 +43492,14 @@ static int pagerStress(void *p, PgHdr *pPg){
assert( pPg->pPager==pPager );
assert( pPg->flags&PGHDR_DIRTY );
- /* The doNotSyncSpill flag is set during times when doing a sync of
+ /* The doNotSpill NOSYNC bit is set during times when doing a sync of
** journal (and adding a new header) is not allowed. This occurs
** during calls to sqlite3PagerWrite() while trying to journal multiple
** pages belonging to the same sector.
**
- ** The doNotSpill flag inhibits all cache spilling regardless of whether
- ** or not a sync is required. This is set during a rollback.
+ ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
+ ** regardless of whether or not a sync is required. This is set during
+ ** a rollback or by user request, respectively.
**
** Spilling is also prohibited when in an error state since that could
** lead to database corruption. In the current implementaton it
@@ -42723,8 +43509,13 @@ static int pagerStress(void *p, PgHdr *pPg){
** test for the error state as a safeguard against future changes.
*/
if( NEVER(pPager->errCode) ) return SQLITE_OK;
- if( pPager->doNotSpill ) return SQLITE_OK;
- if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){
+ testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
+ testcase( pPager->doNotSpill & SPILLFLAG_OFF );
+ testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
+ if( pPager->doNotSpill
+ && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
+ || (pPg->flags & PGHDR_NEED_SYNC)!=0)
+ ){
return SQLITE_OK;
}
@@ -43515,7 +44306,7 @@ static void pagerUnlockIfUnused(Pager *pPager){
** page is initialized to all zeros.
**
** If noContent is true, it means that we do not care about the contents
-** of the page. This occurs in two seperate scenarios:
+** of the page. This occurs in two scenarios:
**
** a) When reading a free-list leaf page from the database, and
**
@@ -43546,19 +44337,19 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
Pager *pPager, /* The pager open on the database file */
Pgno pgno, /* Page number to fetch */
DbPage **ppPage, /* Write a pointer to the page here */
- int flags /* PAGER_ACQUIRE_XXX flags */
+ int flags /* PAGER_GET_XXX flags */
){
int rc = SQLITE_OK;
PgHdr *pPg = 0;
u32 iFrame = 0; /* Frame to read from WAL file */
- const int noContent = (flags & PAGER_ACQUIRE_NOCONTENT);
+ const int noContent = (flags & PAGER_GET_NOCONTENT);
/* It is acceptable to use a read-only (mmap) page for any page except
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
** flag was specified by the caller. And so long as the db is not a
** temporary or in-memory database. */
const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
- && (pPager->eState==PAGER_READER || (flags & PAGER_ACQUIRE_READONLY))
+ && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
#ifdef SQLITE_HAS_CODEC
&& pPager->xCodec==0
#endif
@@ -44078,13 +44869,13 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
int ii; /* Loop counter */
int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
- /* Set the doNotSyncSpill flag to 1. This is because we cannot allow
+ /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
** a journal header to be written between the pages journaled by
** this function.
*/
assert( !MEMDB );
- assert( pPager->doNotSyncSpill==0 );
- pPager->doNotSyncSpill++;
+ assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
+ pPager->doNotSpill |= SPILLFLAG_NOSYNC;
/* This trick assumes that both the page-size and sector-size are
** an integer power of 2. It sets variable pg1 to the identifier
@@ -44143,8 +44934,8 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
}
}
- assert( pPager->doNotSyncSpill==1 );
- pPager->doNotSyncSpill--;
+ assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
+ pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
}else{
rc = pager_write(pDbPage);
}
@@ -44925,7 +45716,27 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
return pPager->pCodec;
}
-#endif
+
+/*
+** This function is called by the wal module when writing page content
+** into the log file.
+**
+** This function returns a pointer to a buffer containing the encrypted
+** page content. If a malloc fails, this function may return NULL.
+*/
+SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
+ void *aData = 0;
+ CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
+ return aData;
+}
+
+/*
+** Return the current pager state
+*/
+SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
+ return pPager->eState;
+}
+#endif /* SQLITE_HAS_CODEC */
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
@@ -45480,21 +46291,6 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
}
#endif
-#ifdef SQLITE_HAS_CODEC
-/*
-** This function is called by the wal module when writing page content
-** into the log file.
-**
-** This function returns a pointer to a buffer containing the encrypted
-** page content. If a malloc fails, this function may return NULL.
-*/
-SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
- void *aData = 0;
- CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
- return aData;
-}
-#endif /* SQLITE_HAS_CODEC */
-
#endif /* SQLITE_OMIT_DISKIO */
/************** End of pager.c ***********************************************/
@@ -47963,7 +48759,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
pWal->writeLock = 0;
- rc = SQLITE_BUSY;
+ rc = SQLITE_BUSY_SNAPSHOT;
}
return rc;
@@ -48672,13 +49468,13 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
**
** OFFSET SIZE DESCRIPTION
** 0 16 Header string: "SQLite format 3\000"
-** 16 2 Page size in bytes.
+** 16 2 Page size in bytes. (1 means 65536)
** 18 1 File format write version
** 19 1 File format read version
** 20 1 Bytes of unused space at the end of each page
-** 21 1 Max embedded payload fraction
-** 22 1 Min embedded payload fraction
-** 23 1 Min leaf payload fraction
+** 21 1 Max embedded payload fraction (must be 64)
+** 22 1 Min embedded payload fraction (must be 32)
+** 23 1 Min leaf payload fraction (must be 32)
** 24 4 File change counter
** 28 4 Reserved for future use
** 32 4 First freelist page
@@ -48692,9 +49488,10 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
** 56 4 1=UTF-8 2=UTF16le 3=UTF16be
** 60 4 User version
** 64 4 Incremental vacuum mode
-** 68 4 unused
-** 72 4 unused
-** 76 4 unused
+** 68 4 Application-ID
+** 72 20 unused
+** 92 4 The version-valid-for number
+** 96 4 SQLITE_VERSION_NUMBER
**
** All of the integer values are big-endian (most significant byte first).
**
@@ -49135,14 +49932,19 @@ struct BtCursor {
/*
** Potential values for BtCursor.eState.
**
-** CURSOR_VALID:
-** Cursor points to a valid entry. getPayload() etc. may be called.
-**
** CURSOR_INVALID:
** Cursor does not point to a valid entry. This can happen (for example)
** because the table is empty or because BtreeCursorFirst() has not been
** called.
**
+** CURSOR_VALID:
+** Cursor points to a valid entry. getPayload() etc. may be called.
+**
+** CURSOR_SKIPNEXT:
+** Cursor is valid except that the Cursor.skipNext field is non-zero
+** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious()
+** operation should be a no-op.
+**
** CURSOR_REQUIRESEEK:
** The table that this cursor was opened on still exists, but has been
** modified since the cursor was last used. The cursor position is saved
@@ -49159,8 +49961,9 @@ struct BtCursor {
*/
#define CURSOR_INVALID 0
#define CURSOR_VALID 1
-#define CURSOR_REQUIRESEEK 2
-#define CURSOR_FAULT 3
+#define CURSOR_SKIPNEXT 2
+#define CURSOR_REQUIRESEEK 3
+#define CURSOR_FAULT 4
/*
** The database page the PENDING_BYTE occupies. This page is never used.
@@ -50234,7 +51037,7 @@ static int btreeMoveto(
){
int rc; /* Status code */
UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
+ char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
char *pFree = 0;
if( pKey ){
@@ -50244,6 +51047,10 @@ static int btreeMoveto(
);
if( pIdxKey==0 ) return SQLITE_NOMEM;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
+ if( pIdxKey->nField==0 ){
+ sqlite3DbFree(pCur->pKeyInfo->db, pFree);
+ return SQLITE_CORRUPT_BKPT;
+ }
}else{
pIdxKey = 0;
}
@@ -50274,6 +51081,9 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
sqlite3_free(pCur->pKey);
pCur->pKey = 0;
assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
+ if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
+ pCur->eState = CURSOR_SKIPNEXT;
+ }
}
return rc;
}
@@ -50299,7 +51109,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
*pHasMoved = 1;
return rc;
}
- if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){
+ if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
*pHasMoved = 1;
}else{
*pHasMoved = 0;
@@ -50487,7 +51297,8 @@ static void btreeParseCellPtr(
assert( n==4-4*pPage->leaf );
if( pPage->intKey ){
if( pPage->hasData ){
- n += getVarint32(&pCell[n], nPayload);
+ assert( n==0 );
+ n = getVarint32(pCell, nPayload);
}else{
nPayload = 0;
}
@@ -50765,7 +51576,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
}else if( gap+2<=top ){
/* Search the freelist looking for a free slot big enough to satisfy
** the request. The allocation is made from the first free slot in
- ** the list that is large enough to accomadate it.
+ ** the list that is large enough to accommodate it.
*/
int pc, addr;
for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
@@ -51131,15 +51942,12 @@ static int btreeGetPage(
BtShared *pBt, /* The btree */
Pgno pgno, /* Number of the page to fetch */
MemPage **ppPage, /* Return the page in this parameter */
- int noContent, /* Do not load page content if true */
- int bReadonly /* True if a read-only (mmap) page is ok */
+ int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
){
int rc;
DbPage *pDbPage;
- int flags = (noContent ? PAGER_ACQUIRE_NOCONTENT : 0)
- | (bReadonly ? PAGER_ACQUIRE_READONLY : 0);
- assert( noContent==0 || bReadonly==0 );
+ assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY );
assert( sqlite3_mutex_held(pBt->mutex) );
rc = sqlite3PagerAcquire(pBt->pPager, pgno, (DbPage**)&pDbPage, flags);
if( rc ) return rc;
@@ -51187,15 +51995,16 @@ static int getAndInitPage(
BtShared *pBt, /* The database file */
Pgno pgno, /* Number of the page to get */
MemPage **ppPage, /* Write the page pointer here */
- int bReadonly /* True if a read-only (mmap) page is ok */
+ int bReadonly /* PAGER_GET_READONLY or 0 */
){
int rc;
assert( sqlite3_mutex_held(pBt->mutex) );
+ assert( bReadonly==PAGER_GET_READONLY || bReadonly==0 );
if( pgno>btreePagecount(pBt) ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = btreeGetPage(pBt, pgno, ppPage, 0, bReadonly);
+ rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
if( rc==SQLITE_OK ){
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
@@ -51600,6 +52409,18 @@ static int removeFromSharingList(BtShared *pBt){
static void allocateTempSpace(BtShared *pBt){
if( !pBt->pTmpSpace ){
pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
+
+ /* One of the uses of pBt->pTmpSpace is to format cells before
+ ** inserting them into a leaf page (function fillInCell()). If
+ ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
+ ** by the various routines that manipulate binary cells. Which
+ ** can mean that fillInCell() only initializes the first 2 or 3
+ ** bytes of pTmpSpace, but that the first 4 bytes are copied from
+ ** it into a database page. This is not actually a problem, but it
+ ** does cause a valgrind error when the 1 or 2 bytes of unitialized
+ ** data is passed to system call write(). So to avoid this error,
+ ** zero the first 4 bytes of temp space here. */
+ if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
}
}
@@ -51715,17 +52536,14 @@ SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){
** probability of damage to near zero but with a write performance reduction.
*/
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
-SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(
+SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
Btree *p, /* The btree to set the safety level on */
- int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
- int fullSync, /* PRAGMA fullfsync. */
- int ckptFullSync /* PRAGMA checkpoint_fullfync */
+ unsigned pgFlags /* Various PAGER_* flags */
){
BtShared *pBt = p->pBt;
assert( sqlite3_mutex_held(p->db->mutex) );
- assert( level>=1 && level<=3 );
sqlite3BtreeEnter(p);
- sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync, ckptFullSync);
+ sqlite3PagerSetFlags(pBt->pPager, pgFlags);
sqlite3BtreeLeave(p);
return SQLITE_OK;
}
@@ -51931,7 +52749,7 @@ static int lockBtree(BtShared *pBt){
assert( pBt->pPage1==0 );
rc = sqlite3PagerSharedLock(pBt->pPager);
if( rc!=SQLITE_OK ) return rc;
- rc = btreeGetPage(pBt, 1, &pPage1, 0, 0);
+ rc = btreeGetPage(pBt, 1, &pPage1, 0);
if( rc!=SQLITE_OK ) return rc;
/* Do some checking to help insure the file we opened really is
@@ -52218,7 +53036,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
goto trans_begun;
}
- assert( IfNotOmitAV(pBt->bDoTruncate)==0 );
+ assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
/* Write transactions are not possible on a read-only database */
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 && wrflag ){
@@ -52513,7 +53331,7 @@ static int relocatePage(
** iPtrPage.
*/
if( eType!=PTRMAP_ROOTPAGE ){
- rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0, 0);
+ rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -52597,7 +53415,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
u8 eMode = BTALLOC_ANY; /* Mode parameter for allocateBtreePage() */
Pgno iNear = 0; /* nearby parameter for allocateBtreePage() */
- rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0, 0);
+ rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -52708,7 +53526,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){
/*
** This routine is called prior to sqlite3PagerCommit when a transaction
-** is commited for an auto-vacuum database.
+** is committed for an auto-vacuum database.
**
** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
** the database file should be truncated to during the commit process.
@@ -52823,12 +53641,13 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
*/
static void btreeEndTransaction(Btree *p){
BtShared *pBt = p->pBt;
+ sqlite3 *db = p->db;
assert( sqlite3BtreeHoldsMutex(p) );
#ifndef SQLITE_OMIT_AUTOVACUUM
pBt->bDoTruncate = 0;
#endif
- if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){
+ if( p->inTrans>TRANS_NONE && db->nVdbeRead>1 ){
/* If there are other active statements that belong to this database
** handle, downgrade to a read-only transaction. The other statements
** may still be reading from the database. */
@@ -52995,7 +53814,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
/* The rollback may have destroyed the pPage1->aData value. So
** call btreeGetPage() on page 1 again to make
** sure pPage1->aData is set correctly. */
- if( btreeGetPage(pBt, 1, &pPage1, 0, 0)==SQLITE_OK ){
+ if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){
int nPage = get4byte(28+(u8*)pPage1->aData);
testcase( nPage==0 );
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
@@ -53430,7 +54249,7 @@ static int getOverflowPage(
assert( next==0 || rc==SQLITE_DONE );
if( rc==SQLITE_OK ){
- rc = btreeGetPage(pBt, ovfl, &pPage, 0, (ppPage==0));
+ rc = btreeGetPage(pBt, ovfl, &pPage, (ppPage==0) ? PAGER_GET_READONLY : 0);
assert( rc==SQLITE_OK || pPage==0 );
if( rc==SQLITE_OK ){
next = get4byte(pPage->aData);
@@ -53652,7 +54471,7 @@ static int accessPayload(
{
DbPage *pDbPage;
rc = sqlite3PagerAcquire(pBt->pPager, nextPage, &pDbPage,
- (eOp==0 ? PAGER_ACQUIRE_READONLY : 0)
+ (eOp==0 ? PAGER_GET_READONLY : 0)
);
if( rc==SQLITE_OK ){
aPayload = sqlite3PagerGetData(pDbPage);
@@ -53744,7 +54563,7 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p
*/
static const unsigned char *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
- int *pAmt, /* Write the number of available bytes here */
+ u32 *pAmt, /* Write the number of available bytes here */
int skipKey /* read beginning at data if this is true */
){
unsigned char *aPayload;
@@ -53757,7 +54576,7 @@ static const unsigned char *fetchPayload(
assert( cursorHoldsMutex(pCur) );
pPage = pCur->apPage[pCur->iPage];
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
- if( NEVER(pCur->info.nSize==0) ){
+ if( pCur->info.nSize==0 ){
btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
&pCur->info);
}
@@ -53794,7 +54613,7 @@ static const unsigned char *fetchPayload(
** These routines is used to get quick access to key and data
** in the common case where no overflow pages are used.
*/
-SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
+SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
const void *p = 0;
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
@@ -53803,7 +54622,7 @@ SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
}
return p;
}
-SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
+SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
const void *p = 0;
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
@@ -53836,7 +54655,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){
return SQLITE_CORRUPT_BKPT;
}
- rc = getAndInitPage(pBt, newPgno, &pNewPage, (pCur->wrFlag==0));
+ rc = getAndInitPage(pBt, newPgno, &pNewPage,
+ pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
if( rc ) return rc;
pCur->apPage[i+1] = pNewPage;
pCur->aiIdx[i+1] = 0;
@@ -53953,7 +54773,8 @@ static int moveToRoot(BtCursor *pCur){
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}else{
- rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0], pCur->wrFlag==0);
+ rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
+ pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
return rc;
@@ -54183,10 +55004,10 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
}
assert( pCur->apPage[0]->intKey || pIdxKey );
for(;;){
- int lwr, upr, idx;
+ int lwr, upr, idx, c;
Pgno chldPg;
MemPage *pPage = pCur->apPage[pCur->iPage];
- int c;
+ u8 *pCell; /* Pointer to current cell in pPage */
/* pPage->nCell must be greater than zero. If this is the root-page
** the cursor would have been INVALID above and this for(;;) loop
@@ -54198,35 +55019,47 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( pPage->intKey==(pIdxKey==0) );
lwr = 0;
upr = pPage->nCell-1;
- if( biasRight ){
- pCur->aiIdx[pCur->iPage] = (u16)(idx = upr);
- }else{
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2);
- }
- for(;;){
- u8 *pCell; /* Pointer to current cell in pPage */
-
- assert( idx==pCur->aiIdx[pCur->iPage] );
- pCur->info.nSize = 0;
- pCell = findCell(pPage, idx) + pPage->childPtrSize;
- if( pPage->intKey ){
+ assert( biasRight==0 || biasRight==1 );
+ idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( pPage->intKey ){
+ for(;;){
i64 nCellKey;
+ pCell = findCell(pPage, idx) + pPage->childPtrSize;
if( pPage->hasData ){
- u32 dummy;
- pCell += getVarint32(pCell, dummy);
+ while( 0x80 <= *(pCell++) ){
+ if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
+ }
}
getVarint(pCell, (u64*)&nCellKey);
- if( nCellKey==intKey ){
- c = 0;
- }else if( nCellKey<intKey ){
- c = -1;
+ if( nCellKey<intKey ){
+ lwr = idx+1;
+ if( lwr>upr ){ c = -1; break; }
+ }else if( nCellKey>intKey ){
+ upr = idx-1;
+ if( lwr>upr ){ c = +1; break; }
}else{
- assert( nCellKey>intKey );
- c = +1;
+ assert( nCellKey==intKey );
+ pCur->validNKey = 1;
+ pCur->info.nKey = nCellKey;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( !pPage->leaf ){
+ lwr = idx;
+ goto moveto_next_layer;
+ }else{
+ *pRes = 0;
+ rc = SQLITE_OK;
+ goto moveto_finish;
+ }
}
- pCur->validNKey = 1;
- pCur->info.nKey = nCellKey;
- }else{
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
+ }
+ }else{
+ for(;;){
+ int nCell;
+ pCell = findCell(pPage, idx) + pPage->childPtrSize;
+
/* The maximum supported page-size is 65536 bytes. This means that
** the maximum number of record bytes stored on an index B-Tree
** page is less than 16384 bytes and may be stored as a 2-byte
@@ -54235,7 +55068,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** stored entirely within the b-tree page by inspecting the first
** 2 bytes of the cell.
*/
- int nCell = pCell[0];
+ nCell = pCell[0];
if( nCell<=pPage->max1bytePayload
/* && (pCell+nCell)<pPage->aDataEnd */
){
@@ -54266,6 +55099,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
rc = SQLITE_NOMEM;
goto moveto_finish;
}
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
if( rc ){
sqlite3_free(pCellKey);
@@ -54274,49 +55108,44 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
- }
- if( c==0 ){
- if( pPage->intKey && !pPage->leaf ){
- lwr = idx;
- break;
+ if( c<0 ){
+ lwr = idx+1;
+ }else if( c>0 ){
+ upr = idx-1;
}else{
+ assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
goto moveto_finish;
}
+ if( lwr>upr ) break;
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
}
- if( c<0 ){
- lwr = idx+1;
- }else{
- upr = idx-1;
- }
- if( lwr>upr ){
- break;
- }
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
}
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- chldPg = 0;
- }else if( lwr>=pPage->nCell ){
- chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- }else{
- chldPg = get4byte(findCell(pPage, lwr));
- }
- if( chldPg==0 ){
assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
}
+moveto_next_layer:
+ if( lwr>=pPage->nCell ){
+ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ }else{
+ chldPg = get4byte(findCell(pPage, lwr));
+ }
pCur->aiIdx[pCur->iPage] = (u16)lwr;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
rc = moveToChild(pCur, chldPg);
- if( rc ) goto moveto_finish;
+ if( rc ) break;
}
moveto_finish:
+ pCur->info.nSize = 0;
+ pCur->validNKey = 0;
return rc;
}
@@ -54348,21 +55177,29 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
assert( pRes!=0 );
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext>0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+ if( pCur->eState!=CURSOR_VALID ){
+ rc = restoreCursorPosition(pCur);
+ if( rc!=SQLITE_OK ){
+ *pRes = 0;
+ return rc;
+ }
+ if( CURSOR_INVALID==pCur->eState ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ if( pCur->skipNext ){
+ assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ pCur->eState = CURSOR_VALID;
+ if( pCur->skipNext>0 ){
+ pCur->skipNext = 0;
+ *pRes = 0;
+ return SQLITE_OK;
+ }
+ pCur->skipNext = 0;
+ }
}
- pCur->skipNext = 0;
pPage = pCur->apPage[pCur->iPage];
idx = ++pCur->aiIdx[pCur->iPage];
@@ -54380,7 +55217,10 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
if( idx>=pPage->nCell ){
if( !pPage->leaf ){
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
- if( rc ) return rc;
+ if( rc ){
+ *pRes = 0;
+ return rc;
+ }
rc = moveToLeftmost(pCur);
*pRes = 0;
return rc;
@@ -54422,21 +55262,32 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
MemPage *pPage;
assert( cursorHoldsMutex(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc!=SQLITE_OK ){
- return rc;
- }
+ assert( pRes!=0 );
+ assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->atLast = 0;
- if( CURSOR_INVALID==pCur->eState ){
- *pRes = 1;
- return SQLITE_OK;
- }
- if( pCur->skipNext<0 ){
- pCur->skipNext = 0;
- *pRes = 0;
- return SQLITE_OK;
+ if( pCur->eState!=CURSOR_VALID ){
+ if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
+ rc = btreeRestoreCursorPosition(pCur);
+ if( rc!=SQLITE_OK ){
+ *pRes = 0;
+ return rc;
+ }
+ }
+ if( CURSOR_INVALID==pCur->eState ){
+ *pRes = 1;
+ return SQLITE_OK;
+ }
+ if( pCur->skipNext ){
+ assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_SKIPNEXT );
+ pCur->eState = CURSOR_VALID;
+ if( pCur->skipNext<0 ){
+ pCur->skipNext = 0;
+ *pRes = 0;
+ return SQLITE_OK;
+ }
+ pCur->skipNext = 0;
+ }
}
- pCur->skipNext = 0;
pPage = pCur->apPage[pCur->iPage];
assert( pPage->isInit );
@@ -54444,6 +55295,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
int idx = pCur->aiIdx[pCur->iPage];
rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
if( rc ){
+ *pRes = 0;
return rc;
}
rc = moveToRightmost(pCur);
@@ -54567,7 +55419,7 @@ static int allocateBtreePage(
if( iTrunk>mxPage ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
+ rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
@@ -54631,7 +55483,7 @@ static int allocateBtreePage(
goto end_allocate_page;
}
testcase( iNewTrunk==mxPage );
- rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0, 0);
+ rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
}
@@ -54710,8 +55562,8 @@ static int allocateBtreePage(
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
}
put4byte(&aData[4], k-1);
- noContent = !btreeGetHasContent(pBt, *pPgno);
- rc = btreeGetPage(pBt, *pPgno, ppPage, noContent, 0);
+ noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
+ rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
@@ -54743,7 +55595,7 @@ static int allocateBtreePage(
** here are confined to those pages that lie between the end of the
** database image and the end of the database file.
*/
- int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate));
+ int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc ) return rc;
@@ -54759,7 +55611,7 @@ static int allocateBtreePage(
MemPage *pPg = 0;
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent, 0);
+ rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg->pDbPage);
releasePage(pPg);
@@ -54773,7 +55625,7 @@ static int allocateBtreePage(
*pPgno = pBt->nPage;
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
- rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent, 0);
+ rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
if( rc ) return rc;
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){
@@ -54841,7 +55693,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
/* If the secure_delete option is enabled, then
** always fully overwrite deleted information with zeros.
*/
- if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0, 0))!=0) )
+ if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) )
|| ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0)
){
goto freepage_out;
@@ -54868,7 +55720,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
u32 nLeaf; /* Initial number of leaf cells on trunk page */
iTrunk = get4byte(&pPage1->aData[32]);
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0, 0);
+ rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
if( rc!=SQLITE_OK ){
goto freepage_out;
}
@@ -54914,7 +55766,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
** first trunk in the free-list is full. Either way, the page being freed
** will become the new first trunk page in the free-list.
*/
- if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0, 0)) ){
+ if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){
goto freepage_out;
}
rc = sqlite3PagerWrite(pPage->pDbPage);
@@ -56813,7 +57665,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
}
/* Move the page currently at pgnoRoot to pgnoMove. */
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
+ rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -56834,7 +57686,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){
if( rc!=SQLITE_OK ){
return rc;
}
- rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0, 0);
+ rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -57012,7 +57864,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
return SQLITE_LOCKED_SHAREDCACHE;
}
- rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0, 0);
+ rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
if( rc ) return rc;
rc = sqlite3BtreeClearTable(p, iTable, 0);
if( rc ){
@@ -57047,7 +57899,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
*/
MemPage *pMove;
releasePage(pPage);
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
+ rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -57057,7 +57909,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
return rc;
}
pMove = 0;
- rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0, 0);
+ rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0);
freePage(pMove, &rc);
releasePage(pMove);
if( rc!=SQLITE_OK ){
@@ -57272,7 +58124,7 @@ static void checkAppendMsg(
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
- if( pCheck->errMsg.mallocFailed ){
+ if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
pCheck->mallocFailed = 1;
}
}
@@ -57469,7 +58321,7 @@ static int checkTreePage(
usableSize = pBt->usableSize;
if( iPage==0 ) return 0;
if( checkRef(pCheck, iPage, zParentContext) ) return 0;
- if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0, 0))!=0 ){
+ if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
checkAppendMsg(pCheck, zContext,
"unable to get the page. error code=%d", rc);
return 0;
@@ -58051,12 +58903,6 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
** API functions and the related features.
*/
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
/*
** Structure allocated for each backup operation.
*/
@@ -58138,6 +58984,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
rc = SQLITE_ERROR;
}
sqlite3DbFree(pErrorDb, pParse->zErrMsg);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(pErrorDb, pParse);
}
if( rc ){
@@ -58434,7 +59281,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
rc = sqlite3PagerAcquire(pSrcPager, iSrcPg, &pSrcPg,
- PAGER_ACQUIRE_READONLY);
+ PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
@@ -59093,15 +59940,8 @@ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
-** If the double is too large, return 0x8000000000000000.
-**
-** Most systems appear to do this simply by assigning
-** variables and without the extra range tests. But
-** there are reports that windows throws an expection
-** if the floating point value is out of range. (See ticket #2880.)
-** Because we do not completely understand the problem, we will
-** take the conservative approach and always do range tests
-** before attempting the conversion.
+** If the double is out of range of a 64-bit signed integer then
+** return the closest available 64-bit signed integer.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
@@ -59118,14 +59958,10 @@ static i64 doubleToInt64(double r){
static const i64 maxInt = LARGEST_INT64;
static const i64 minInt = SMALLEST_INT64;
- if( r<(double)minInt ){
- return minInt;
- }else if( r>(double)maxInt ){
- /* minInt is correct here - not maxInt. It turns out that assigning
- ** a very large positive number to an integer results in a very large
- ** negative integer. This makes no sense, but it is what x86 hardware
- ** does so for compatibility we will do the same in software. */
+ if( r<=(double)minInt ){
return minInt;
+ }else if( r>=(double)maxInt ){
+ return maxInt;
}else{
return (i64)r;
}
@@ -59207,17 +60043,11 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
**
** The second and third terms in the following conditional enforces
** the second condition under the assumption that addition overflow causes
- ** values to wrap around. On x86 hardware, the third term is always
- ** true and could be omitted. But we leave it in because other
- ** architectures might behave differently.
+ ** values to wrap around.
*/
if( pMem->r==(double)pMem->u.i
&& pMem->u.i>SMALLEST_INT64
-#if defined(__i486__) || defined(__x86_64__)
- && ALWAYS(pMem->u.i<LARGEST_INT64)
-#else
&& pMem->u.i<LARGEST_INT64
-#endif
){
pMem->flags |= MEM_Int;
}
@@ -59589,34 +60419,29 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
** if both values are integers.
*/
if( combined_flags&(MEM_Int|MEM_Real) ){
- if( !(f1&(MEM_Int|MEM_Real)) ){
- return 1;
- }
- if( !(f2&(MEM_Int|MEM_Real)) ){
- return -1;
- }
- if( (f1 & f2 & MEM_Int)==0 ){
- double r1, r2;
- if( (f1&MEM_Real)==0 ){
- r1 = (double)pMem1->u.i;
- }else{
- r1 = pMem1->r;
- }
- if( (f2&MEM_Real)==0 ){
- r2 = (double)pMem2->u.i;
- }else{
- r2 = pMem2->r;
- }
- if( r1<r2 ) return -1;
- if( r1>r2 ) return 1;
- return 0;
- }else{
- assert( f1&MEM_Int );
- assert( f2&MEM_Int );
+ double r1, r2;
+ if( (f1 & f2 & MEM_Int)!=0 ){
if( pMem1->u.i < pMem2->u.i ) return -1;
if( pMem1->u.i > pMem2->u.i ) return 1;
return 0;
}
+ if( (f1&MEM_Real)!=0 ){
+ r1 = pMem1->r;
+ }else if( (f1&MEM_Int)!=0 ){
+ r1 = (double)pMem1->u.i;
+ }else{
+ return 1;
+ }
+ if( (f2&MEM_Real)!=0 ){
+ r2 = pMem2->r;
+ }else if( (f2&MEM_Int)!=0 ){
+ r2 = (double)pMem2->u.i;
+ }else{
+ return -1;
+ }
+ if( r1<r2 ) return -1;
+ if( r1>r2 ) return 1;
+ return 0;
}
/* If one value is a string and the other is a blob, the string is less.
@@ -59691,13 +60516,13 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
*/
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
- int offset, /* Offset from the start of data to return bytes from. */
- int amt, /* Number of bytes to return. */
+ u32 offset, /* Offset from the start of data to return bytes from. */
+ u32 amt, /* Number of bytes to return. */
int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
char *zData; /* Data from the btree layer */
- int available = 0; /* Number of bytes available on the local btree page */
+ u32 available = 0; /* Number of bytes available on the local btree page */
int rc = SQLITE_OK; /* Return code */
assert( sqlite3BtreeCursorIsValid(pCur) );
@@ -59712,7 +60537,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
}
assert( zData!=0 );
- if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){
+ if( offset+amt<=available ){
sqlite3VdbeMemRelease(pMem);
pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
@@ -59731,7 +60556,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
sqlite3VdbeMemRelease(pMem);
}
}
- pMem->n = amt;
+ pMem->n = (int)amt;
return rc;
}
@@ -59796,43 +60621,101 @@ SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
}
/*
-** Create a new sqlite3_value object, containing the value of pExpr.
+** Context object passed by sqlite3Stat4ProbeSetValue() through to
+** valueNew(). See comments above valueNew() for details.
+*/
+struct ValueNewStat4Ctx {
+ Parse *pParse;
+ Index *pIdx;
+ UnpackedRecord **ppRec;
+ int iVal;
+};
+
+/*
+** Allocate and return a pointer to a new sqlite3_value object. If
+** the second argument to this function is NULL, the object is allocated
+** by calling sqlite3ValueNew().
**
-** This only works for very simple expressions that consist of one constant
-** token (i.e. "5", "5.1", "'a string'"). If the expression can
-** be converted directly into a value, then the value is allocated and
-** a pointer written to *ppVal. The caller is responsible for deallocating
-** the value by passing it to sqlite3ValueFree() later on. If the expression
-** cannot be converted to a value, then *ppVal is set to NULL.
+** Otherwise, if the second argument is non-zero, then this function is
+** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
+** already been allocated, allocate the UnpackedRecord structure that
+** that function will return to its caller here. Then return a pointer
+** an sqlite3_value within the UnpackedRecord.a[] array.
*/
-SQLITE_PRIVATE int sqlite3ValueFromExpr(
- sqlite3 *db, /* The database connection */
- Expr *pExpr, /* The expression to evaluate */
- u8 enc, /* Encoding to use */
- u8 affinity, /* Affinity to use */
- sqlite3_value **ppVal /* Write the new value here */
+static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( p ){
+ UnpackedRecord *pRec = p->ppRec[0];
+
+ if( pRec==0 ){
+ Index *pIdx = p->pIdx; /* Index being probed */
+ int nByte; /* Bytes of space to allocate */
+ int i; /* Counter variable */
+ int nCol = pIdx->nColumn; /* Number of index columns including rowid */
+
+ nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord));
+ pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
+ if( pRec ){
+ pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
+ if( pRec->pKeyInfo ){
+ assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
+ assert( pRec->pKeyInfo->enc==ENC(db) );
+ pRec->flags = UNPACKED_PREFIX_MATCH;
+ pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
+ for(i=0; i<nCol; i++){
+ pRec->aMem[i].flags = MEM_Null;
+ pRec->aMem[i].type = SQLITE_NULL;
+ pRec->aMem[i].db = db;
+ }
+ }else{
+ sqlite3DbFree(db, pRec);
+ pRec = 0;
+ }
+ }
+ if( pRec==0 ) return 0;
+ p->ppRec[0] = pRec;
+ }
+
+ pRec->nField = p->iVal+1;
+ return &pRec->aMem[p->iVal];
+ }
+#else
+ UNUSED_PARAMETER(p);
+#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
+ return sqlite3ValueNew(db);
+}
+
+/*
+** Extract a value from the supplied expression in the manner described
+** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
+** using valueNew().
+**
+** If pCtx is NULL and an error occurs after the sqlite3_value object
+** has been allocated, it is freed before returning. Or, if pCtx is not
+** NULL, it is assumed that the caller will free any allocated object
+** in all cases.
+*/
+static int valueFromExpr(
+ sqlite3 *db, /* The database connection */
+ Expr *pExpr, /* The expression to evaluate */
+ u8 enc, /* Encoding to use */
+ u8 affinity, /* Affinity to use */
+ sqlite3_value **ppVal, /* Write the new value here */
+ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
){
int op;
char *zVal = 0;
sqlite3_value *pVal = 0;
int negInt = 1;
const char *zNeg = "";
+ int rc = SQLITE_OK;
if( !pExpr ){
*ppVal = 0;
return SQLITE_OK;
}
op = pExpr->op;
-
- /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
- ** The ifdef here is to enable us to achieve 100% branch test coverage even
- ** when SQLITE_ENABLE_STAT3 is omitted.
- */
-#ifdef SQLITE_ENABLE_STAT3
- if( op==TK_REGISTER ) op = pExpr->op2;
-#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
-#endif
/* Handle negative integers in a single step. This is needed in the
** case when the value is -9223372036854775808.
@@ -59846,7 +60729,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
}
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
if( ExprHasProperty(pExpr, EP_IntValue) ){
sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt);
@@ -59863,11 +60746,13 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
}
if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str;
if( enc!=SQLITE_UTF8 ){
- sqlite3VdbeChangeEncoding(pVal, enc);
+ rc = sqlite3VdbeChangeEncoding(pVal, enc);
}
}else if( op==TK_UMINUS ) {
/* This branch happens for multiple negative signs. Ex: -(-5) */
- if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){
+ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal)
+ && pVal!=0
+ ){
sqlite3VdbeMemNumerify(pVal);
if( pVal->u.i==SMALLEST_INT64 ){
pVal->flags &= MEM_Int;
@@ -59880,7 +60765,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
sqlite3ValueApplyAffinity(pVal, affinity, enc);
}
}else if( op==TK_NULL ){
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
@@ -59888,7 +60773,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
int nVal;
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
assert( pExpr->u.zToken[1]=='\'' );
- pVal = sqlite3ValueNew(db);
+ pVal = valueNew(db, pCtx);
if( !pVal ) goto no_mem;
zVal = &pExpr->u.zToken[2];
nVal = sqlite3Strlen30(zVal)-1;
@@ -59902,17 +60787,201 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
sqlite3VdbeMemStoreType(pVal);
}
*ppVal = pVal;
- return SQLITE_OK;
+ return rc;
no_mem:
db->mallocFailed = 1;
sqlite3DbFree(db, zVal);
- sqlite3ValueFree(pVal);
- *ppVal = 0;
+ assert( *ppVal==0 );
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pCtx==0 ) sqlite3ValueFree(pVal);
+#else
+ assert( pCtx==0 ); sqlite3ValueFree(pVal);
+#endif
return SQLITE_NOMEM;
}
/*
+** Create a new sqlite3_value object, containing the value of pExpr.
+**
+** This only works for very simple expressions that consist of one constant
+** token (i.e. "5", "5.1", "'a string'"). If the expression can
+** be converted directly into a value, then the value is allocated and
+** a pointer written to *ppVal. The caller is responsible for deallocating
+** the value by passing it to sqlite3ValueFree() later on. If the expression
+** cannot be converted to a value, then *ppVal is set to NULL.
+*/
+SQLITE_PRIVATE int sqlite3ValueFromExpr(
+ sqlite3 *db, /* The database connection */
+ Expr *pExpr, /* The expression to evaluate */
+ u8 enc, /* Encoding to use */
+ u8 affinity, /* Affinity to use */
+ sqlite3_value **ppVal /* Write the new value here */
+){
+ return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
+}
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+/*
+** The implementation of the sqlite_record() function. This function accepts
+** a single argument of any type. The return value is a formatted database
+** record (a blob) containing the argument value.
+**
+** This is used to convert the value stored in the 'sample' column of the
+** sqlite_stat3 table to the record format SQLite uses internally.
+*/
+static void recordFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ const int file_format = 1;
+ int iSerial; /* Serial type */
+ int nSerial; /* Bytes of space for iSerial as varint */
+ int nVal; /* Bytes of space required for argv[0] */
+ int nRet;
+ sqlite3 *db;
+ u8 *aRet;
+
+ UNUSED_PARAMETER( argc );
+ iSerial = sqlite3VdbeSerialType(argv[0], file_format);
+ nSerial = sqlite3VarintLen(iSerial);
+ nVal = sqlite3VdbeSerialTypeLen(iSerial);
+ db = sqlite3_context_db_handle(context);
+
+ nRet = 1 + nSerial + nVal;
+ aRet = sqlite3DbMallocRaw(db, nRet);
+ if( aRet==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ aRet[0] = nSerial+1;
+ sqlite3PutVarint(&aRet[1], iSerial);
+ sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format);
+ sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
+ sqlite3DbFree(db, aRet);
+ }
+}
+
+/*
+** Register built-in functions used to help read ANALYZE data.
+*/
+SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){
+ static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = {
+ FUNCTION(sqlite_record, 1, 0, 0, recordFunc),
+ };
+ int i;
+ FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+ FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
+ for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
+ sqlite3FuncDefInsert(pHash, &aFunc[i]);
+ }
+}
+
+/*
+** This function is used to allocate and populate UnpackedRecord
+** structures intended to be compared against sample index keys stored
+** in the sqlite_stat4 table.
+**
+** A single call to this function attempts to populates field iVal (leftmost
+** is 0 etc.) of the unpacked record with a value extracted from expression
+** pExpr. Extraction of values is possible if:
+**
+** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
+**
+** * The expression is a bound variable, and this is a reprepare, or
+**
+** * The sqlite3ValueFromExpr() function is able to extract a value
+** from the expression (i.e. the expression is a literal value).
+**
+** If a value can be extracted, the affinity passed as the 5th argument
+** is applied to it before it is copied into the UnpackedRecord. Output
+** parameter *pbOk is set to true if a value is extracted, or false
+** otherwise.
+**
+** When this function is called, *ppRec must either point to an object
+** allocated by an earlier call to this function, or must be NULL. If it
+** is NULL and a value can be successfully extracted, a new UnpackedRecord
+** is allocated (and *ppRec set to point to it) before returning.
+**
+** Unless an error is encountered, SQLITE_OK is returned. It is not an
+** error if a value cannot be extracted from pExpr. If an error does
+** occur, an SQLite error code is returned.
+*/
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
+ Parse *pParse, /* Parse context */
+ Index *pIdx, /* Index being probed */
+ UnpackedRecord **ppRec, /* IN/OUT: Probe record */
+ Expr *pExpr, /* The expression to extract a value from */
+ u8 affinity, /* Affinity to use */
+ int iVal, /* Array element to populate */
+ int *pbOk /* OUT: True if value was extracted */
+){
+ int rc = SQLITE_OK;
+ sqlite3_value *pVal = 0;
+ sqlite3 *db = pParse->db;
+
+
+ struct ValueNewStat4Ctx alloc;
+ alloc.pParse = pParse;
+ alloc.pIdx = pIdx;
+ alloc.ppRec = ppRec;
+ alloc.iVal = iVal;
+
+ /* Skip over any TK_COLLATE nodes */
+ pExpr = sqlite3ExprSkipCollate(pExpr);
+
+ if( !pExpr ){
+ pVal = valueNew(db, &alloc);
+ if( pVal ){
+ sqlite3VdbeMemSetNull((Mem*)pVal);
+ }
+ }else if( pExpr->op==TK_VARIABLE
+ || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
+ ){
+ Vdbe *v;
+ int iBindVar = pExpr->iColumn;
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
+ if( (v = pParse->pReprepare)!=0 ){
+ pVal = valueNew(db, &alloc);
+ if( pVal ){
+ rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
+ if( rc==SQLITE_OK ){
+ sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
+ }
+ pVal->db = pParse->db;
+ sqlite3VdbeMemStoreType((Mem*)pVal);
+ }
+ }
+ }else{
+ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc);
+ }
+ *pbOk = (pVal!=0);
+
+ assert( pVal==0 || pVal->db==db );
+ return rc;
+}
+
+/*
+** Unless it is NULL, the argument must be an UnpackedRecord object returned
+** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
+** the object.
+*/
+SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
+ if( pRec ){
+ int i;
+ int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
+ Mem *aMem = pRec->aMem;
+ sqlite3 *db = aMem[0].db;
+ for(i=0; i<nCol; i++){
+ sqlite3DbFree(db, aMem[i].zMalloc);
+ }
+ sqlite3KeyInfoUnref(pRec->pKeyInfo);
+ sqlite3DbFree(db, pRec);
+ }
+}
+#endif /* ifdef SQLITE_ENABLE_STAT4 */
+
+/*
** Change the string value of an sqlite3_value object
*/
SQLITE_PRIVATE void sqlite3ValueSetStr(
@@ -60030,15 +61099,6 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pB->isPrepareV2 = pA->isPrepareV2;
}
-#ifdef SQLITE_DEBUG
-/*
-** Turn tracing on or off
-*/
-SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
- p->trace = trace;
-}
-#endif
-
/*
** Resize the Vdbe.aOp array so that it is at least one op larger than
** it was.
@@ -60059,6 +61119,17 @@ static int growOpArray(Vdbe *p){
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
+#ifdef SQLITE_DEBUG
+/* This routine is just a convenient place to set a breakpoint that will
+** fire after each opcode is inserted and displayed using
+** "PRAGMA vdbe_addoptrace=on".
+*/
+static void test_addop_breakpoint(void){
+ static int n = 0;
+ n++;
+}
+#endif
+
/*
** Add a new instruction to the list of instructions current in the
** VDBE. Return the address of the new instruction.
@@ -60096,10 +61167,13 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
pOp->p3 = p3;
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOp->zComment = 0;
+#endif
+#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
+ test_addop_breakpoint();
}
#endif
#ifdef VDBE_PROFILE
@@ -60202,8 +61276,8 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
- assert( j>=0 && j<p->nLabel );
- if( p->aLabel ){
+ assert( j<p->nLabel );
+ if( j>=0 && p->aLabel ){
p->aLabel[j] = p->nOp;
}
}
@@ -60355,32 +61429,66 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
Op *pOp;
int *aLabel = p->aLabel;
p->readOnly = 1;
+ p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode;
- pOp->opflags = sqlite3OpcodeProperty[opcode];
- if( opcode==OP_Function || opcode==OP_AggStep ){
- if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
- }else if( (opcode==OP_Transaction && pOp->p2!=0) || opcode==OP_Vacuum ){
- p->readOnly = 0;
+ /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
+ ** cases from this switch! */
+ switch( opcode ){
+ case OP_Function:
+ case OP_AggStep: {
+ if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
+ break;
+ }
+ case OP_Transaction: {
+ if( pOp->p2!=0 ) p->readOnly = 0;
+ /* fall thru */
+ }
+ case OP_AutoCommit:
+ case OP_Savepoint: {
+ p->bIsReader = 1;
+ break;
+ }
+#ifndef SQLITE_OMIT_WAL
+ case OP_Checkpoint:
+#endif
+ case OP_Vacuum:
+ case OP_JournalMode: {
+ p->readOnly = 0;
+ p->bIsReader = 1;
+ break;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( opcode==OP_VUpdate ){
- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
- }else if( opcode==OP_VFilter ){
- int n;
- assert( p->nOp - i >= 3 );
- assert( pOp[-1].opcode==OP_Integer );
- n = pOp[-1].p1;
- if( n>nMaxArgs ) nMaxArgs = n;
+ case OP_VUpdate: {
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+ break;
+ }
+ case OP_VFilter: {
+ int n;
+ assert( p->nOp - i >= 3 );
+ assert( pOp[-1].opcode==OP_Integer );
+ n = pOp[-1].p1;
+ if( n>nMaxArgs ) nMaxArgs = n;
+ break;
+ }
#endif
- }else if( opcode==OP_Next || opcode==OP_SorterNext ){
- pOp->p4.xAdvance = sqlite3BtreeNext;
- pOp->p4type = P4_ADVANCE;
- }else if( opcode==OP_Prev ){
- pOp->p4.xAdvance = sqlite3BtreePrevious;
- pOp->p4type = P4_ADVANCE;
+ case OP_Next:
+ case OP_NextIfOpen:
+ case OP_SorterNext: {
+ pOp->p4.xAdvance = sqlite3BtreeNext;
+ pOp->p4type = P4_ADVANCE;
+ break;
+ }
+ case OP_Prev:
+ case OP_PrevIfOpen: {
+ pOp->p4.xAdvance = sqlite3BtreePrevious;
+ pOp->p4type = P4_ADVANCE;
+ break;
+ }
}
+ pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( -1-pOp->p2<p->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
@@ -60388,8 +61496,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
}
sqlite3DbFree(p->db, p->aLabel);
p->aLabel = 0;
-
*pMaxFuncArgs = nMaxArgs;
+ assert( p->bIsReader!=0 || p->btreeMask==0 );
}
/*
@@ -60443,7 +61551,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp)
VdbeOp *pOut = &p->aOp[i+addr];
pOut->opcode = pIn->opcode;
pOut->p1 = pIn->p1;
- if( p2<0 && (sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP)!=0 ){
+ if( p2<0 ){
+ assert( sqlite3OpcodeProperty[pOut->opcode] & OPFLG_JUMP );
pOut->p2 = addr + ADDR(p2);
}else{
pOut->p2 = p2;
@@ -60452,8 +61561,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp)
pOut->p4type = P4_NOTUSED;
pOut->p4.p = 0;
pOut->p5 = 0;
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOut->zComment = 0;
+#endif
+#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
}
@@ -60515,8 +61626,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- assert( addr>=0 || p->db->mallocFailed );
- if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
+ if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
}
@@ -60525,7 +61635,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
** the FuncDef is not ephermal, then do nothing.
*/
static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
- if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){
+ if( ALWAYS(pDef) && (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){
sqlite3DbFree(db, pDef);
}
}
@@ -60542,21 +61652,16 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
- case P4_KEYINFO:
- case P4_INTARRAY:
- case P4_KEYINFO_HANDOFF: {
+ case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
}
- case P4_MPRINTF: {
- if( db->pnBytesFreed==0 ) sqlite3_free(p4);
+ case P4_KEYINFO: {
+ if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
break;
}
- case P4_VDBEFUNC: {
- VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
- freeEphemeralFunction(db, pVdbeFunc->pFunc);
- if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
- sqlite3DbFree(db, pVdbeFunc);
+ case P4_MPRINTF: {
+ if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
case P4_FUNCDEF: {
@@ -60591,7 +61696,7 @@ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
Op *pOp;
for(pOp=aOp; pOp<&aOp[nOp]; pOp++){
freeP4(db, pOp->p4type, pOp->p4.p);
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
sqlite3DbFree(db, pOp->zComment);
#endif
}
@@ -60619,6 +61724,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
freeP4(db, pOp->p4type, pOp->p4.p);
memset(pOp, 0, sizeof(pOp[0]));
pOp->opcode = OP_Noop;
+ if( addr==p->nOp-1 ) p->nOp--;
}
}
@@ -60632,14 +61738,6 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
** the string is made into memory obtained from sqlite3_malloc().
** A value of n==0 means copy bytes of zP4 up to and including the
** first null byte. If n>0 then copy n+1 bytes of zP4.
-**
-** If n==P4_KEYINFO it means that zP4 is a pointer to a KeyInfo structure.
-** A copy is made of the KeyInfo structure into memory obtained from
-** sqlite3_malloc, to be freed when the Vdbe is finalized.
-** n==P4_KEYINFO_HANDOFF indicates that zP4 points to a KeyInfo structure
-** stored in memory that the caller has obtained from sqlite3_malloc. The
-** caller should not free the allocation, it will be freed when the Vdbe is
-** finalized.
**
** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points
** to a string or structure that is guaranteed to exist for the lifetime of
@@ -60654,7 +61752,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
db = p->db;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->aOp==0 || db->mallocFailed ){
- if ( n!=P4_KEYINFO && n!=P4_VTAB ) {
+ if( n!=P4_VTAB ){
freeP4(db, n, (void*)*(char**)&zP4);
}
return;
@@ -60677,26 +61775,6 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
pOp->p4.p = 0;
pOp->p4type = P4_NOTUSED;
}else if( n==P4_KEYINFO ){
- KeyInfo *pKeyInfo;
- int nField, nByte;
-
- nField = ((KeyInfo*)zP4)->nField;
- nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
- pKeyInfo = sqlite3DbMallocRaw(0, nByte);
- pOp->p4.pKeyInfo = pKeyInfo;
- if( pKeyInfo ){
- u8 *aSortOrder;
- memcpy((char*)pKeyInfo, zP4, nByte - nField);
- aSortOrder = pKeyInfo->aSortOrder;
- assert( aSortOrder!=0 );
- pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
- memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
- pOp->p4type = P4_KEYINFO;
- }else{
- p->db->mallocFailed = 1;
- pOp->p4type = P4_NOTUSED;
- }
- }else if( n==P4_KEYINFO_HANDOFF ){
pOp->p4.p = (void*)zP4;
pOp->p4type = P4_KEYINFO;
}else if( n==P4_VTAB ){
@@ -60714,7 +61792,19 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
}
}
-#ifndef NDEBUG
+/*
+** Set the P4 on the most recently added opcode to the KeyInfo for the
+** index given.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ assert( pIdx!=0 );
+ sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
+ P4_KEYINFO);
+}
+
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** Change the comment on the most recently coded instruction. Or
** insert a No-op and add the comment to that new instruction. This
@@ -60789,6 +61879,81 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
}
}
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
+/*
+** Return an integer value for one of the parameters to the opcode pOp
+** determined by character c.
+*/
+static int translateP(char c, const Op *pOp){
+ if( c=='1' ) return pOp->p1;
+ if( c=='2' ) return pOp->p2;
+ if( c=='3' ) return pOp->p3;
+ if( c=='4' ) return pOp->p4.i;
+ return pOp->p5;
+}
+
+/*
+** Compute a string for the "comment" field of a VDBE opcode listing
+*/
+static int displayComment(
+ const Op *pOp, /* The opcode to be commented */
+ const char *zP4, /* Previously obtained value for P4 */
+ char *zTemp, /* Write result here */
+ int nTemp /* Space available in zTemp[] */
+){
+ const char *zOpName;
+ const char *zSynopsis;
+ int nOpName;
+ int ii, jj;
+ zOpName = sqlite3OpcodeName(pOp->opcode);
+ nOpName = sqlite3Strlen30(zOpName);
+ if( zOpName[nOpName+1] ){
+ int seenCom = 0;
+ char c;
+ zSynopsis = zOpName += nOpName + 1;
+ for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
+ if( c=='P' ){
+ c = zSynopsis[++ii];
+ if( c=='4' ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4);
+ }else if( c=='X' ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment);
+ seenCom = 1;
+ }else{
+ int v1 = translateP(c, pOp);
+ int v2;
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
+ if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
+ ii += 3;
+ jj += sqlite3Strlen30(zTemp+jj);
+ v2 = translateP(zSynopsis[ii], pOp);
+ if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
+ ii += 4;
+ }
+ }
+ jj += sqlite3Strlen30(zTemp+jj);
+ }else{
+ zTemp[jj++] = c;
+ }
+ }
+ if( !seenCom && jj<nTemp-5 && pOp->zComment ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
+ jj += sqlite3Strlen30(zTemp+jj);
+ }
+ if( jj<nTemp ) zTemp[jj] = 0;
+ }else if( pOp->zComment ){
+ sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
+ jj = sqlite3Strlen30(zTemp);
+ }else{
+ zTemp[0] = 0;
+ jj = 0;
+ }
+ return jj;
+}
+#endif /* SQLITE_DEBUG */
+
+
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
|| defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
/*
@@ -60799,17 +61964,20 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
char *zP4 = zTemp;
assert( nTemp>=20 );
switch( pOp->p4type ){
- case P4_KEYINFO_STATIC:
case P4_KEYINFO: {
int i, j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
- sqlite3_snprintf(nTemp, zTemp, "keyinfo(%d", pKeyInfo->nField);
+ sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
i = sqlite3Strlen30(zTemp);
for(j=0; j<pKeyInfo->nField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "nil";
int n = sqlite3Strlen30(zColl);
+ if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
+ zColl = "B";
+ n = 1;
+ }
if( i+n>nTemp-6 ){
memcpy(&zTemp[i],",...",4);
break;
@@ -60828,7 +61996,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
}
case P4_COLLSEQ: {
CollSeq *pColl = pOp->p4.pColl;
- sqlite3_snprintf(nTemp, zTemp, "collseq(%.20s)", pColl->zName);
+ sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
break;
}
case P4_FUNCDEF: {
@@ -60982,16 +62150,18 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
char *zP4;
char zPtr[50];
- static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-4s %.2X %s\n";
+ char zCom[100];
+ static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
- fprintf(pOut, zFormat1, pc,
- sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
-#ifdef SQLITE_DEBUG
- pOp->zComment ? pOp->zComment : ""
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ displayComment(pOp, zP4, zCom, sizeof(zCom));
#else
- ""
+ zCom[0] = 0
#endif
+ fprintf(pOut, zFormat1, pc,
+ sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
+ zCom
);
fflush(pOut);
}
@@ -61137,7 +62307,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
}else{
- char *z;
+ char *zP4;
Op *pOp;
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
@@ -61160,7 +62330,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
pMem++;
pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
+ pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
pMem->type = SQLITE_TEXT;
@@ -61207,9 +62377,9 @@ SQLITE_PRIVATE int sqlite3VdbeList(
return SQLITE_ERROR;
}
pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
- z = displayP4(pOp, pMem->z, 32);
- if( z!=pMem->z ){
- sqlite3VdbeMemSetStr(pMem, z, -1, SQLITE_UTF8, 0);
+ zP4 = displayP4(pOp, pMem->z, 32);
+ if( zP4!=pMem->z ){
+ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
}else{
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
@@ -61230,19 +62400,19 @@ SQLITE_PRIVATE int sqlite3VdbeList(
pMem->enc = SQLITE_UTF8;
pMem++;
-#ifdef SQLITE_DEBUG
- if( pOp->zComment ){
- pMem->flags = MEM_Str|MEM_Term;
- pMem->z = pOp->zComment;
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem->type = SQLITE_TEXT;
- }else
-#endif
- {
- pMem->flags = MEM_Null; /* Comment */
- pMem->type = SQLITE_NULL;
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ if( sqlite3VdbeMemGrow(pMem, 500, 0) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
}
+ pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->type = SQLITE_TEXT;
+ pMem->enc = SQLITE_UTF8;
+#else
+ pMem->flags = MEM_Null; /* Comment */
+ pMem->type = SQLITE_NULL;
+#endif
}
p->nResColumn = 8 - 4*(p->explain-1);
@@ -61259,15 +62429,17 @@ SQLITE_PRIVATE int sqlite3VdbeList(
** Print the SQL that was used to generate a VDBE program.
*/
SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){
- int nOp = p->nOp;
- VdbeOp *pOp;
- if( nOp<1 ) return;
- pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
- const char *z = pOp->p4.z;
- while( sqlite3Isspace(*z) ) z++;
- printf("SQL: [%s]\n", z);
+ const char *z = 0;
+ if( p->zSql ){
+ z = p->zSql;
+ }else if( p->nOp>=1 ){
+ const VdbeOp *pOp = &p->aOp[0];
+ if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
+ z = pOp->p4.z;
+ while( sqlite3Isspace(*z) ) z++;
+ }
}
+ if( z ) printf("SQL: [%s]\n", z);
}
#endif
@@ -61525,7 +62697,7 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pCx->pVtabCursor ){
sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
- const sqlite3_module *pModule = pCx->pModule;
+ const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
p->inVtabMethod = 1;
pModule->xClose(pVtabCursor);
p->inVtabMethod = 0;
@@ -61588,6 +62760,10 @@ static void closeAllCursors(Vdbe *p){
p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel);
}
+
+ /* Delete any auxdata allocations made by the VM */
+ sqlite3VdbeDeleteAuxData(p, -1, 0);
+ assert( p->pAuxData==0 );
}
/*
@@ -61696,7 +62872,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** required, as an xSync() callback may add an attached database
** to the transaction.
*/
- rc = sqlite3VtabSync(db, &p->zErrMsg);
+ rc = sqlite3VtabSync(db, p);
/* This loop determines (a) if the commit hook should be invoked and
** (b) how many database files have open write transactions, not
@@ -61915,7 +63091,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
}
/*
-** This routine checks that the sqlite3.activeVdbeCnt count variable
+** This routine checks that the sqlite3.nVdbeActive count variable
** matches the number of vdbe's in the list sqlite3.pVdbe that are
** currently active. An assertion fails if the two counts do not match.
** This is an internal self-check only - it is not an essential processing
@@ -61928,16 +63104,19 @@ static void checkActiveVdbeCnt(sqlite3 *db){
Vdbe *p;
int cnt = 0;
int nWrite = 0;
+ int nRead = 0;
p = db->pVdbe;
while( p ){
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
cnt++;
if( p->readOnly==0 ) nWrite++;
+ if( p->bIsReader ) nRead++;
}
p = p->pNext;
}
- assert( cnt==db->activeVdbeCnt );
- assert( nWrite==db->writeVdbeCnt );
+ assert( cnt==db->nVdbeActive );
+ assert( nWrite==db->nVdbeWrite );
+ assert( nRead==db->nVdbeRead );
}
#else
#define checkActiveVdbeCnt(x)
@@ -61948,7 +63127,7 @@ static void checkActiveVdbeCnt(sqlite3 *db){
** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or
** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement
** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the
-** statement transaction is commtted.
+** statement transaction is committed.
**
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
** Otherwise SQLITE_OK.
@@ -62002,6 +63181,7 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
** the statement transaction was opened. */
if( eOp==SAVEPOINT_ROLLBACK ){
db->nDeferredCons = p->nStmtDefCons;
+ db->nDeferredImmCons = p->nStmtDefImmCons;
}
}
return rc;
@@ -62020,10 +63200,12 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
sqlite3 *db = p->db;
- if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
+ if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
+ || (!deferred && p->nFkConstraint>0)
+ ){
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
p->errorAction = OE_Abort;
- sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
+ sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
return SQLITE_ERROR;
}
return SQLITE_OK;
@@ -62073,8 +63255,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
}
checkActiveVdbeCnt(db);
- /* No commit or rollback needed if the program never started */
- if( p->pc>=0 ){
+ /* No commit or rollback needed if the program never started or if the
+ ** SQL statement does not read or write a database file. */
+ if( p->pc>=0 && p->bIsReader ){
int mrc; /* Primary error code from p->rc */
int eStatementOp = 0;
int isSpecialError; /* Set to true if a 'special' error */
@@ -62127,7 +63310,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
*/
if( !sqlite3VtabInSync(db)
&& db->autoCommit
- && db->writeVdbeCnt==(p->readOnly==0)
+ && db->nVdbeWrite==(p->readOnly==0)
){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
rc = sqlite3VdbeCheckFk(p, 1);
@@ -62152,6 +63335,8 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3RollbackAll(db, SQLITE_OK);
}else{
db->nDeferredCons = 0;
+ db->nDeferredImmCons = 0;
+ db->flags &= ~SQLITE_DeferFKs;
sqlite3CommitInternalChanges(db);
}
}else{
@@ -62208,11 +63393,12 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
/* We have successfully halted and closed the VM. Record this fact. */
if( p->pc>=0 ){
- db->activeVdbeCnt--;
- if( !p->readOnly ){
- db->writeVdbeCnt--;
- }
- assert( db->activeVdbeCnt>=db->writeVdbeCnt );
+ db->nVdbeActive--;
+ if( !p->readOnly ) db->nVdbeWrite--;
+ if( p->bIsReader ) db->nVdbeRead--;
+ assert( db->nVdbeActive>=db->nVdbeRead );
+ assert( db->nVdbeRead>=db->nVdbeWrite );
+ assert( db->nVdbeWrite>=0 );
}
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
@@ -62228,7 +63414,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
sqlite3ConnectionUnlocked(db);
}
- assert( db->activeVdbeCnt>0 || db->autoCommit==0 || db->nStatement==0 );
+ assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 );
return (p->rc==SQLITE_BUSY ? SQLITE_BUSY : SQLITE_OK);
}
@@ -62357,6 +63543,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
}
}
#endif
+ p->iCurrentTime = 0;
p->magic = VDBE_MAGIC_INIT;
return p->rc & db->errMask;
}
@@ -62376,20 +63563,35 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
}
/*
-** Call the destructor for each auxdata entry in pVdbeFunc for which
-** the corresponding bit in mask is clear. Auxdata entries beyond 31
-** are always destroyed. To destroy all auxdata entries, call this
-** routine with mask==0.
+** If parameter iOp is less than zero, then invoke the destructor for
+** all auxiliary data pointers currently cached by the VM passed as
+** the first argument.
+**
+** Or, if iOp is greater than or equal to zero, then the destructor is
+** only invoked for those auxiliary data pointers created by the user
+** function invoked by the OP_Function opcode at instruction iOp of
+** VM pVdbe, and only then if:
+**
+** * the associated function parameter is the 32nd or later (counting
+** from left to right), or
+**
+** * the corresponding bit in argument mask is clear (where the first
+** function parameter corrsponds to bit 0 etc.).
*/
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
- int i;
- for(i=0; i<pVdbeFunc->nAux; i++){
- struct AuxData *pAux = &pVdbeFunc->apAux[i];
- if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
+ AuxData **pp = &pVdbe->pAuxData;
+ while( *pp ){
+ AuxData *pAux = *pp;
+ if( (iOp<0)
+ || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
+ ){
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
- pAux->pAux = 0;
+ *pp = pAux->pNext;
+ sqlite3DbFree(pVdbe->db, pAux);
+ }else{
+ pp= &pAux->pNext;
}
}
}
@@ -62479,7 +63681,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
#endif
p->deferredMoveto = 0;
p->cacheStatus = CACHE_STALE;
- }else if( ALWAYS(p->pCursor) ){
+ }else if( p->pCursor ){
int hasMoved;
int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
if( rc ) return rc;
@@ -62787,15 +63989,12 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
return 0;
}
default: {
+ static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
u32 len = (serial_type-12)/2;
pMem->z = (char *)buf;
pMem->n = len;
pMem->xDel = 0;
- if( serial_type&0x01 ){
- pMem->flags = MEM_Str | MEM_Ephem;
- }else{
- pMem->flags = MEM_Blob | MEM_Ephem;
- }
+ pMem->flags = aFlag[serial_type&1];
return len;
}
}
@@ -62908,11 +64107,10 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
- int d1; /* Offset into aKey[] of next data element */
+ u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
u32 szHdr1; /* Number of bytes in header */
int i = 0;
- int nField;
int rc = 0;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
KeyInfo *pKeyInfo;
@@ -62935,14 +64133,27 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
- nField = pKeyInfo->nField;
+ assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
assert( pKeyInfo->aSortOrder!=0 );
- while( idx1<szHdr1 && i<pPKey2->nField ){
+ assert( pKeyInfo->nField>0 );
+ assert( idx1<=szHdr1 || CORRUPT_DB );
+ do{
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += getVarint32( aKey1+idx1, serial_type1 );
- if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
+
+ /* Verify that there is enough key space remaining to avoid
+ ** a buffer overread. The "d1+serial_type1+2" subexpression will
+ ** always be greater than or equal to the amount of required key space.
+ ** Use that approximation to avoid the more expensive call to
+ ** sqlite3VdbeSerialTypeLen() in the common case.
+ */
+ if( d1+serial_type1+2>(u32)nKey1
+ && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
+ ){
+ break;
+ }
/* Extract the values to be compared.
*/
@@ -62950,32 +64161,16 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
/* Do the comparison
*/
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
- i<nField ? pKeyInfo->aColl[i] : 0);
+ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
if( rc!=0 ){
assert( mem1.zMalloc==0 ); /* See comment below */
-
- /* Invert the result if we are using DESC sort order. */
- if( i<nField && pKeyInfo->aSortOrder[i] ){
- rc = -rc;
+ if( pKeyInfo->aSortOrder[i] ){
+ rc = -rc; /* Invert the result for DESC sort order. */
}
-
- /* If the PREFIX_SEARCH flag is set and all fields except the final
- ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
- ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
- ** This is used by the OP_IsUnique opcode.
- */
- if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
- assert( idx1==szHdr1 && rc );
- assert( mem1.flags & MEM_Int );
- pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
- pPKey2->rowid = mem1.u.i;
- }
-
return rc;
}
i++;
- }
+ }while( idx1<szHdr1 && i<pPKey2->nField );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
@@ -63033,7 +64228,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
/* Read in the complete content of the index entry */
memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
if( rc ){
return rc;
}
@@ -63111,7 +64306,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
return SQLITE_CORRUPT_BKPT;
}
memset(&m, 0, sizeof(m));
- rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m);
+ rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m);
if( rc ){
return rc;
}
@@ -63171,7 +64366,7 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
@@ -63202,6 +64397,21 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
}
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
+** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
+** in memory obtained from sqlite3DbMalloc).
+*/
+SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
+ sqlite3 *db = p->db;
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
+ sqlite3_free(pVtab->zErrMsg);
+ pVtab->zErrMsg = 0;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
@@ -63415,12 +64625,14 @@ SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
+ pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_ERROR;
+ pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
@@ -63484,6 +64696,7 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
}
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
+ pCtx->fErrorOrAux = 1;
if( pCtx->s.flags & MEM_Null ){
sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1,
SQLITE_UTF8, SQLITE_STATIC);
@@ -63494,6 +64707,7 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
+ pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1,
SQLITE_UTF8, SQLITE_STATIC);
}
@@ -63503,6 +64717,7 @@ SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
sqlite3VdbeMemSetNull(&pCtx->s);
pCtx->isError = SQLITE_NOMEM;
+ pCtx->fErrorOrAux = 1;
pCtx->s.db->mallocFailed = 1;
}
@@ -63586,11 +64801,13 @@ static int sqlite3Step(Vdbe *p){
** reset the interrupt flag. This prevents a call to sqlite3_interrupt
** from interrupting a statement that has not yet started.
*/
- if( db->activeVdbeCnt==0 ){
+ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
}
- assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 );
+ assert( db->nVdbeWrite>0 || db->autoCommit==0
+ || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
+ );
#ifndef SQLITE_OMIT_TRACE
if( db->xProfile && !db->init.busy ){
@@ -63598,8 +64815,9 @@ static int sqlite3Step(Vdbe *p){
}
#endif
- db->activeVdbeCnt++;
- if( p->readOnly==0 ) db->writeVdbeCnt++;
+ db->nVdbeActive++;
+ if( p->readOnly==0 ) db->nVdbeWrite++;
+ if( p->bIsReader ) db->nVdbeRead++;
p->pc = 0;
}
#ifndef SQLITE_OMIT_EXPLAIN
@@ -63608,9 +64826,9 @@ static int sqlite3Step(Vdbe *p){
}else
#endif /* SQLITE_OMIT_EXPLAIN */
{
- db->vdbeExecCnt++;
+ db->nVdbeExec++;
rc = sqlite3VdbeExec(p);
- db->vdbeExecCnt--;
+ db->nVdbeExec--;
}
#ifndef SQLITE_OMIT_TRACE
@@ -63706,6 +64924,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
return rc;
}
+
/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
@@ -63731,6 +64950,19 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
}
/*
+** Return the current time for a statement
+*/
+SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
+ Vdbe *v = p->pVdbe;
+ int rc;
+ if( v->iCurrentTime==0 ){
+ rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime);
+ if( rc ) v->iCurrentTime = 0;
+ }
+ return v->iCurrentTime;
+}
+
+/*
** The following is the implementation of an SQL function that always
** fails with an error message stating that the function is used in the
** wrong context. The sqlite3_overload_function() API might construct
@@ -63785,14 +65017,14 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
- VdbeFunc *pVdbeFunc;
+ AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
- return 0;
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
- return pVdbeFunc->apAux[iArg].pAux;
+
+ return (pAuxData ? pAuxData->pAux : 0);
}
/*
@@ -63806,29 +65038,30 @@ SQLITE_API void sqlite3_set_auxdata(
void *pAux,
void (*xDelete)(void*)
){
- struct AuxData *pAuxData;
- VdbeFunc *pVdbeFunc;
- if( iArg<0 ) goto failed;
+ AuxData *pAuxData;
+ Vdbe *pVdbe = pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
- pVdbeFunc = pCtx->pVdbeFunc;
- if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
- int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
- int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
- pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
- if( !pVdbeFunc ){
- goto failed;
- }
- pCtx->pVdbeFunc = pVdbeFunc;
- memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
- pVdbeFunc->nAux = iArg+1;
- pVdbeFunc->pFunc = pCtx->pFunc;
- }
+ if( iArg<0 ) goto failed;
- pAuxData = &pVdbeFunc->apAux[iArg];
- if( pAuxData->pAux && pAuxData->xDelete ){
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
+ }
+ if( pAuxData==0 ){
+ pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
+ if( !pAuxData ) goto failed;
+ pAuxData->iOp = pCtx->iOp;
+ pAuxData->iArg = iArg;
+ pAuxData->pNext = pVdbe->pAuxData;
+ pVdbe->pAuxData = pAuxData;
+ if( pCtx->fErrorOrAux==0 ){
+ pCtx->isError = 0;
+ pCtx->fErrorOrAux = 1;
+ }
+ }else if( pAuxData->xDelete ){
pAuxData->xDelete(pAuxData->pAux);
}
+
pAuxData->pAux = pAux;
pAuxData->xDelete = xDelete;
return;
@@ -64017,13 +65250,6 @@ SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
return iType;
}
-/* The following function is experimental and subject to change or
-** removal */
-/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){
-** return sqlite3_value_numeric_type( columnMem(pStmt,i) );
-**}
-*/
-
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string. If N is out of range, return 0.
@@ -64500,9 +65726,9 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
*/
SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
- int v = pVdbe->aCounter[op-1];
- if( resetFlag ) pVdbe->aCounter[op-1] = 0;
- return v;
+ u32 v = pVdbe->aCounter[op];
+ if( resetFlag ) pVdbe->aCounter[op] = 0;
+ return (int)v;
}
/************** End of vdbeapi.c *********************************************/
@@ -64554,9 +65780,9 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
/*
** This function returns a pointer to a nul-terminated string in memory
-** obtained from sqlite3DbMalloc(). If sqlite3.vdbeExecCnt is 1, then the
+** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the
** string contains a copy of zRawSql but with host parameters expanded to
-** their current bindings. Or, if sqlite3.vdbeExecCnt is greater than 1,
+** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1,
** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text.
**
@@ -64594,7 +65820,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
sqlite3StrAccumInit(&out, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
out.db = db;
- if( db->vdbeExecCnt>1 ){
+ if( db->nVdbeExec>1 ){
while( *zRawSql ){
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
@@ -65015,9 +66241,8 @@ static VdbeCursor *allocateCursor(
int nByte;
VdbeCursor *pCx = 0;
nByte =
- ROUND8(sizeof(VdbeCursor)) +
- (isBtreeCursor?sqlite3BtreeCursorSize():0) +
- 2*nField*sizeof(u32);
+ ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
+ (isBtreeCursor?sqlite3BtreeCursorSize():0);
assert( iCur<p->nCursor );
if( p->apCsr[iCur] ){
@@ -65029,12 +66254,9 @@ static VdbeCursor *allocateCursor(
memset(pCx, 0, sizeof(VdbeCursor));
pCx->iDb = iDb;
pCx->nField = nField;
- if( nField ){
- pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))];
- }
if( isBtreeCursor ){
pCx->pCursor = (BtCursor*)
- &pMem->z[ROUND8(sizeof(VdbeCursor))+2*nField*sizeof(u32)];
+ &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
sqlite3BtreeCursorZero(pCx->pCursor);
}
}
@@ -65220,37 +66442,36 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
/*
** Print the value of a register for tracing purposes:
*/
-static void memTracePrint(FILE *out, Mem *p){
+static void memTracePrint(Mem *p){
if( p->flags & MEM_Invalid ){
- fprintf(out, " undefined");
+ printf(" undefined");
}else if( p->flags & MEM_Null ){
- fprintf(out, " NULL");
+ printf(" NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
- fprintf(out, " si:%lld", p->u.i);
+ printf(" si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
- fprintf(out, " i:%lld", p->u.i);
+ printf(" i:%lld", p->u.i);
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( p->flags & MEM_Real ){
- fprintf(out, " r:%g", p->r);
+ printf(" r:%g", p->r);
#endif
}else if( p->flags & MEM_RowSet ){
- fprintf(out, " (rowset)");
+ printf(" (rowset)");
}else{
char zBuf[200];
sqlite3VdbeMemPrettyPrint(p, zBuf);
- fprintf(out, " ");
- fprintf(out, "%s", zBuf);
+ printf(" %s", zBuf);
}
}
-static void registerTrace(FILE *out, int iReg, Mem *p){
- fprintf(out, "REG[%d] = ", iReg);
- memTracePrint(out, p);
- fprintf(out, "\n");
+static void registerTrace(int iReg, Mem *p){
+ printf("REG[%d] = ", iReg);
+ memTracePrint(p);
+ printf("\n");
}
#endif
#ifdef SQLITE_DEBUG
-# define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
+# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
#else
# define REGISTER_TRACE(R,M)
#endif
@@ -65389,19 +66610,6 @@ static int checkSavepointCount(sqlite3 *db){
}
#endif
-/*
-** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
-** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored
-** in memory obtained from sqlite3DbMalloc).
-*/
-static void importVtabErrMsg(Vdbe *p, sqlite3_vtab *pVtab){
- sqlite3 *db = p->db;
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
- sqlite3_free(pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
-}
-
/*
** Execute as much of a VDBE program as we can then return.
@@ -65444,16 +66652,16 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
+ int iCompare = 0; /* Result of last OP_Compare operation */
+ unsigned nVmStep = 0; /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- int checkProgress; /* True if progress callbacks are enabled */
- int nProgressOps = 0; /* Opcodes executed since progress callback. */
+ unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
#endif
Mem *aMem = p->aMem; /* Copy of p->aMem */
Mem *pIn1 = 0; /* 1st input operand */
Mem *pIn2 = 0; /* 2nd input operand */
Mem *pIn3 = 0; /* 3rd input operand */
Mem *pOut = 0; /* Output operand */
- int iCompare = 0; /* Result of last OP_Compare operation */
int *aPermute = 0; /* Permutation of columns for OP_Compare */
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
@@ -65472,29 +66680,33 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
struct OP_Yield_stack_vars {
int pcDest;
} aa;
+ struct OP_Halt_stack_vars {
+ const char *zType;
+ const char *zLogFmt;
+ } ab;
struct OP_Null_stack_vars {
int cnt;
u16 nullFlag;
- } ab;
+ } ac;
struct OP_Variable_stack_vars {
Mem *pVar; /* Value being transferred */
- } ac;
+ } ad;
struct OP_Move_stack_vars {
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
- } ad;
+ } ae;
struct OP_Copy_stack_vars {
int n;
- } ae;
+ } af;
struct OP_ResultRow_stack_vars {
Mem *pMem;
int i;
- } af;
+ } ag;
struct OP_Concat_stack_vars {
i64 nByte;
- } ag;
+ } ah;
struct OP_Remainder_stack_vars {
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
@@ -65502,26 +66714,26 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
- } ah;
+ } ai;
struct OP_Function_stack_vars {
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
- } ai;
+ } aj;
struct OP_ShiftRight_stack_vars {
i64 iA;
u64 uA;
i64 iB;
u8 op;
- } aj;
+ } ak;
struct OP_Ge_stack_vars {
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
- } ak;
+ } al;
struct OP_Compare_stack_vars {
int n;
int i;
@@ -65531,43 +66743,38 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
- } al;
+ } am;
struct OP_Or_stack_vars {
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- } am;
+ } an;
struct OP_IfNot_stack_vars {
int c;
- } an;
+ } ao;
struct OP_Column_stack_vars {
- u32 payloadSize; /* Number of bytes in the record */
i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
int p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
BtCursor *pCrsr; /* The BTree cursor */
u32 *aType; /* aType[i] holds the numeric type of the i-th column */
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
int len; /* The length of the serialized data for the column */
int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
Mem *pDest; /* Where to write the extracted value */
Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
+ const u8 *zData; /* Part of the record being decoded */
+ const u8 *zHdr; /* Next unparsed byte of the header */
+ const u8 *zEndHdr; /* Pointer to first byte after the header */
u32 offset; /* Offset into the data */
u32 szField; /* Number of bytes in the content of a field */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
+ u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
- } ao;
+ } ap;
struct OP_Affinity_stack_vars {
const char *zAffinity; /* The affinity to be applied */
char cAff; /* A single character of affinity */
- } ap;
+ } aq;
struct OP_MakeRecord_stack_vars {
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
@@ -65584,11 +66791,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] */
int len; /* Length of a field */
- } aq;
+ } ar;
struct OP_Count_stack_vars {
i64 nEntry;
BtCursor *pCrsr;
- } ar;
+ } as;
struct OP_Savepoint_stack_vars {
int p1; /* Value of P1 operand */
char *zName; /* Name of savepoint */
@@ -65598,28 +66805,28 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
Savepoint *pTmp;
int iSavepoint;
int ii;
- } as;
+ } at;
struct OP_AutoCommit_stack_vars {
int desiredAutoCommit;
int iRollback;
int turnOnAC;
- } at;
+ } au;
struct OP_Transaction_stack_vars {
Btree *pBt;
- } au;
+ } av;
struct OP_ReadCookie_stack_vars {
int iMeta;
int iDb;
int iCookie;
- } av;
+ } aw;
struct OP_SetCookie_stack_vars {
Db *pDb;
- } aw;
+ } ax;
struct OP_VerifyCookie_stack_vars {
int iMeta;
int iGen;
Btree *pBt;
- } ax;
+ } ay;
struct OP_OpenWrite_stack_vars {
int nField;
KeyInfo *pKeyInfo;
@@ -65629,16 +66836,17 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
- } ay;
+ } az;
struct OP_OpenEphemeral_stack_vars {
VdbeCursor *pCx;
- } az;
+ KeyInfo *pKeyInfo;
+ } ba;
struct OP_SorterOpen_stack_vars {
VdbeCursor *pCx;
- } ba;
+ } bb;
struct OP_OpenPseudo_stack_vars {
VdbeCursor *pCx;
- } bb;
+ } bc;
struct OP_SeekGt_stack_vars {
int res;
int oc;
@@ -65646,27 +66854,19 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
- } bc;
+ } bd;
struct OP_Seek_stack_vars {
VdbeCursor *pC;
- } bd;
+ } be;
struct OP_Found_stack_vars {
int alreadyExists;
+ int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
- } be;
- struct OP_IsUnique_stack_vars {
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
} bf;
struct OP_NotExists_stack_vars {
VdbeCursor *pC;
@@ -65700,6 +66900,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
struct OP_SorterCompare_stack_vars {
VdbeCursor *pC;
int res;
+ int nIgnore;
} bk;
struct OP_SorterData_stack_vars {
VdbeCursor *pC;
@@ -65729,7 +66930,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
BtCursor *pCrsr;
int res;
} bq;
- struct OP_Next_stack_vars {
+ struct OP_SorterNext_stack_vars {
VdbeCursor *pC;
int res;
} br;
@@ -65899,24 +67100,49 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
goto no_mem;
}
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+ assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK;
+ p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
CHECK_FOR_INTERRUPT;
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- checkProgress = db->xProgress!=0;
+ if( db->xProgress ){
+ assert( 0 < db->nProgressOps );
+ nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
+ if( nProgressLimit==0 ){
+ nProgressLimit = db->nProgressOps;
+ }else{
+ nProgressLimit %= (unsigned)db->nProgressOps;
+ }
+ }
#endif
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
- if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
+ if( p->pc==0
+ && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0
+ ){
int i;
- printf("VDBE Program Listing:\n");
+ int once = 1;
sqlite3VdbePrintSql(p);
- for(i=0; i<p->nOp; i++){
- sqlite3VdbePrintOp(stdout, i, &aOp[i]);
+ if( p->db->flags & SQLITE_VdbeListing ){
+ printf("VDBE Program Listing:\n");
+ for(i=0; i<p->nOp; i++){
+ sqlite3VdbePrintOp(stdout, i, &aOp[i]);
+ }
+ }
+ if( p->db->flags & SQLITE_VdbeEQP ){
+ for(i=0; i<p->nOp; i++){
+ if( aOp[i].opcode==OP_Explain ){
+ if( once ) printf("VDBE Query Plan:\n");
+ printf("%s\n", aOp[i].p4.z);
+ once = 0;
+ }
+ }
}
+ if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n");
}
sqlite3EndBenignMalloc();
#endif
@@ -65927,17 +67153,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
origPc = pc;
start = sqlite3Hwtime();
#endif
+ nVmStep++;
pOp = &aOp[pc];
/* Only allow tracing if SQLITE_DEBUG is defined.
*/
#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( pc==0 ){
- printf("VDBE Execution Trace:\n");
- sqlite3VdbePrintSql(p);
- }
- sqlite3VdbePrintOp(p->trace, pc, pOp);
+ if( db->flags & SQLITE_VdbeTrace ){
+ sqlite3VdbePrintOp(stdout, pc, pOp);
}
#endif
@@ -65954,27 +67177,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
#endif
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
- /* Call the progress callback if it is configured and the required number
- ** of VDBE ops have been executed (either since this invocation of
- ** sqlite3VdbeExec() or since last time the progress callback was called).
- ** If the progress callback returns non-zero, exit the virtual machine with
- ** a return code SQLITE_ABORT.
- */
- if( checkProgress ){
- if( db->nProgressOps==nProgressOps ){
- int prc;
- prc = db->xProgress(db->pProgressArg);
- if( prc!=0 ){
- rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
- }
- nProgressOps = 0;
- }
- nProgressOps++;
- }
-#endif
-
/* On any opcode with the "out2-prerelease" tag, free any
** external allocations out of mem[p2] and set mem[p2] to be
** an undefined integer. Opcodes will either fill in the integer
@@ -65983,7 +67185,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
@@ -65994,30 +67196,30 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
#ifdef SQLITE_DEBUG
if( (pOp->opflags & OPFLG_IN1)!=0 ){
assert( pOp->p1>0 );
- assert( pOp->p1<=p->nMem );
+ assert( pOp->p1<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (pOp->opflags & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
assert( pOp->p2>0 );
- assert( pOp->p2<=p->nMem );
+ assert( pOp->p2<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_OUT3)!=0 ){
assert( pOp->p3>0 );
- assert( pOp->p3<=p->nMem );
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
memAboutToChange(p, &aMem[pOp->p3]);
}
#endif
@@ -66067,8 +67269,37 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** the program.
*/
case OP_Goto: { /* jump */
- CHECK_FOR_INTERRUPT;
pc = pOp->p2 - 1;
+
+ /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
+ ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
+ ** completion. Check to see if sqlite3_interrupt() has been called
+ ** or if the progress callback needs to be invoked.
+ **
+ ** This code uses unstructured "goto" statements and does not look clean.
+ ** But that is not due to sloppy coding habits. The code is written this
+ ** way for performance, to avoid having to run the interrupt and progress
+ ** checks on every opcode. This helps sqlite3_step() to run about 1.5%
+ ** faster according to "valgrind --tool=cachegrind" */
+check_for_interrupt:
+ CHECK_FOR_INTERRUPT;
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ /* Call the progress callback if it is configured and the required number
+ ** of VDBE ops have been executed (either since this invocation of
+ ** sqlite3VdbeExec() or since last time the progress callback was called).
+ ** If the progress callback returns non-zero, exit the virtual machine with
+ ** a return code SQLITE_ABORT.
+ */
+ if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
+ assert( db->nProgressOps!=0 );
+ nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
+ if( db->xProgress(db->pProgressArg) ){
+ rc = SQLITE_INTERRUPT;
+ goto vdbe_error_halt;
+ }
+ }
+#endif
+
break;
}
@@ -66078,7 +67309,7 @@ case OP_Goto: { /* jump */
** and then jump to address P2.
*/
case OP_Gosub: { /* jump */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
assert( (pIn1->flags & MEM_Dyn)==0 );
memAboutToChange(p, pIn1);
@@ -66118,11 +67349,13 @@ case OP_Yield: { /* in1 */
break;
}
-/* Opcode: HaltIfNull P1 P2 P3 P4 *
+/* Opcode: HaltIfNull P1 P2 P3 P4 P5
+** Synopsis: if r[P3] null then halt
**
** Check the value in register P3. If it is NULL then Halt using
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
** value in register P3 is not NULL, then this routine is a no-op.
+** The P5 parameter should be 1.
*/
case OP_HaltIfNull: { /* in3 */
pIn3 = &aMem[pOp->p3];
@@ -66130,7 +67363,7 @@ case OP_HaltIfNull: { /* in3 */
/* Fall through into OP_Halt */
}
-/* Opcode: Halt P1 P2 * P4 *
+/* Opcode: Halt P1 P2 * P4 P5
**
** Exit immediately. All open cursors, etc are closed
** automatically.
@@ -66145,11 +67378,27 @@ case OP_HaltIfNull: { /* in3 */
**
** If P4 is not null then it is an error message string.
**
+** P5 is a value between 0 and 4, inclusive, that modifies the P4 string.
+**
+** 0: (no change)
+** 1: NOT NULL contraint failed: P4
+** 2: UNIQUE constraint failed: P4
+** 3: CHECK constraint failed: P4
+** 4: FOREIGN KEY constraint failed: P4
+**
+** If P5 is not zero and P4 is NULL, then everything after the ":" is
+** omitted.
+**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** every program. So a jump past the last instruction of the program
** is the same as executing Halt.
*/
case OP_Halt: {
+#if 0 /* local variables moved into u.ab */
+ const char *zType;
+ const char *zLogFmt;
+#endif /* local variables moved into u.ab */
+
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
VdbeFrame *pFrame = p->pFrame;
@@ -66159,7 +67408,7 @@ case OP_Halt: {
pc = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
@@ -66170,18 +67419,33 @@ case OP_Halt: {
aMem = p->aMem;
break;
}
-
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pc;
- if( pOp->p4.z ){
- assert( p->rc!=SQLITE_OK );
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pc, p->zSql, pOp->p4.z);
- }else if( p->rc ){
- testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(pOp->p1, "constraint failed at %d in [%s]", pc, p->zSql);
+ if( p->rc ){
+ if( pOp->p5 ){
+ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
+ "FOREIGN KEY" };
+ assert( pOp->p5>=1 && pOp->p5<=4 );
+ testcase( pOp->p5==1 );
+ testcase( pOp->p5==2 );
+ testcase( pOp->p5==3 );
+ testcase( pOp->p5==4 );
+ u.ab.zType = azType[pOp->p5-1];
+ }else{
+ u.ab.zType = 0;
+ }
+ assert( u.ab.zType!=0 || pOp->p4.z!=0 );
+ u.ab.zLogFmt = "abort at %d in [%s]: %s";
+ if( u.ab.zType && pOp->p4.z ){
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
+ u.ab.zType, pOp->p4.z);
+ }else if( pOp->p4.z ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
+ }else{
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType);
+ }
+ sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -66189,13 +67453,14 @@ case OP_Halt: {
p->rc = rc = SQLITE_BUSY;
}else{
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
- assert( rc==SQLITE_OK || db->nDeferredCons>0 );
+ assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
goto vdbe_return;
}
/* Opcode: Integer P1 P2 * * *
+** Synopsis: r[P2]=P1
**
** The 32-bit integer value P1 is written into register P2.
*/
@@ -66205,6 +67470,7 @@ case OP_Integer: { /* out2-prerelease */
}
/* Opcode: Int64 * P2 * P4 *
+** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit integer value.
** Write that value into register P2.
@@ -66217,6 +67483,7 @@ case OP_Int64: { /* out2-prerelease */
#ifndef SQLITE_OMIT_FLOATING_POINT
/* Opcode: Real * P2 * P4 *
+** Synopsis: r[P2]=P4
**
** P4 is a pointer to a 64-bit floating point value.
** Write that value into register P2.
@@ -66230,6 +67497,7 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
#endif
/* Opcode: String8 * P2 * P4 *
+** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
** into an OP_String before it is executed for the first time.
@@ -66264,6 +67532,7 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
}
/* Opcode: String P1 P2 * P4 *
+** Synopsis: r[P2]='P4' (len=P1)
**
** The string value P4 of length P1 (bytes) is stored in register P2.
*/
@@ -66278,6 +67547,7 @@ case OP_String: { /* out2-prerelease */
}
/* Opcode: Null P1 P2 P3 * *
+** Synopsis: r[P2..P3]=NULL
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and every register in between P2 and P3. If P3
@@ -66289,25 +67559,26 @@ case OP_String: { /* out2-prerelease */
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ab */
+#if 0 /* local variables moved into u.ac */
int cnt;
u16 nullFlag;
-#endif /* local variables moved into u.ab */
- u.ab.cnt = pOp->p3-pOp->p2;
- assert( pOp->p3<=p->nMem );
- pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
- while( u.ab.cnt>0 ){
+#endif /* local variables moved into u.ac */
+ u.ac.cnt = pOp->p3-pOp->p2;
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
+ pOut->flags = u.ac.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+ while( u.ac.cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
- pOut->flags = u.ab.nullFlag;
- u.ab.cnt--;
+ pOut->flags = u.ac.nullFlag;
+ u.ac.cnt--;
}
break;
}
/* Opcode: Blob P1 P2 * P4
+** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
** blob in register P2.
@@ -66321,6 +67592,7 @@ case OP_Blob: { /* out2-prerelease */
}
/* Opcode: Variable P1 P2 * P4 *
+** Synopsis: r[P2]=parameter(P1,P4)
**
** Transfer the values of bound parameter P1 into register P2
**
@@ -66328,22 +67600,23 @@ case OP_Blob: { /* out2-prerelease */
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ac */
+#if 0 /* local variables moved into u.ad */
Mem *pVar; /* Value being transferred */
-#endif /* local variables moved into u.ac */
+#endif /* local variables moved into u.ad */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
- u.ac.pVar = &p->aVar[pOp->p1 - 1];
- if( sqlite3VdbeMemTooBig(u.ac.pVar) ){
+ u.ad.pVar = &p->aVar[pOp->p1 - 1];
+ if( sqlite3VdbeMemTooBig(u.ad.pVar) ){
goto too_big;
}
- sqlite3VdbeMemShallowCopy(pOut, u.ac.pVar, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pOut, u.ad.pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Move the values in register P1..P1+P3 over into
** registers P2..P2+P3. Registers P1..P1+P3 are
@@ -66351,43 +67624,44 @@ case OP_Variable: { /* out2-prerelease */
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
-#if 0 /* local variables moved into u.ad */
+#if 0 /* local variables moved into u.ae */
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
-#endif /* local variables moved into u.ad */
+#endif /* local variables moved into u.ae */
+
+ u.ae.n = pOp->p3;
+ u.ae.p1 = pOp->p1;
+ u.ae.p2 = pOp->p2;
+ assert( u.ae.n>=0 && u.ae.p1>0 && u.ae.p2>0 );
+ assert( u.ae.p1+u.ae.n<=u.ae.p2 || u.ae.p2+u.ae.n<=u.ae.p1 );
- u.ad.n = pOp->p3 + 1;
- u.ad.p1 = pOp->p1;
- u.ad.p2 = pOp->p2;
- assert( u.ad.n>0 && u.ad.p1>0 && u.ad.p2>0 );
- assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 );
-
- pIn1 = &aMem[u.ad.p1];
- pOut = &aMem[u.ad.p2];
- while( u.ad.n-- ){
- assert( pOut<=&aMem[p->nMem] );
- assert( pIn1<=&aMem[p->nMem] );
+ pIn1 = &aMem[u.ae.p1];
+ pOut = &aMem[u.ae.p2];
+ do{
+ assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
+ assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
- u.ad.zMalloc = pOut->zMalloc;
+ u.ae.zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[u.ad.p1] && pOut->pScopyFrom<&aMem[u.ad.p1+pOp->p3] ){
- pOut->pScopyFrom += u.ad.p1 - pOp->p2;
+ if( pOut->pScopyFrom>=&aMem[u.ae.p1] && pOut->pScopyFrom<&aMem[u.ae.p1+pOp->p3] ){
+ pOut->pScopyFrom += u.ae.p1 - pOp->p2;
}
#endif
- pIn1->zMalloc = u.ad.zMalloc;
- REGISTER_TRACE(u.ad.p2++, pOut);
+ pIn1->zMalloc = u.ae.zMalloc;
+ REGISTER_TRACE(u.ae.p2++, pOut);
pIn1++;
pOut++;
- }
+ }while( u.ae.n-- );
break;
}
/* Opcode: Copy P1 P2 P3 * *
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
@@ -66395,11 +67669,11 @@ case OP_Move: {
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: {
-#if 0 /* local variables moved into u.ae */
+#if 0 /* local variables moved into u.af */
int n;
-#endif /* local variables moved into u.ae */
+#endif /* local variables moved into u.af */
- u.ae.n = pOp->p3;
+ u.af.n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
@@ -66409,8 +67683,8 @@ case OP_Copy: {
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
- REGISTER_TRACE(pOp->p2+pOp->p3-u.ae.n, pOut);
- if( (u.ae.n--)==0 ) break;
+ REGISTER_TRACE(pOp->p2+pOp->p3-u.af.n, pOut);
+ if( (u.af.n--)==0 ) break;
pOut++;
pIn1++;
}
@@ -66418,6 +67692,7 @@ case OP_Copy: {
}
/* Opcode: SCopy P1 P2 * * *
+** Synopsis: r[P2]=r[P1]
**
** Make a shallow copy of register P1 into register P2.
**
@@ -66429,7 +67704,7 @@ case OP_Copy: {
** during the lifetime of the copy. Use OP_Copy to make a complete
** copy.
*/
-case OP_SCopy: { /* in1, out2 */
+case OP_SCopy: { /* out2 */
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
@@ -66437,11 +67712,11 @@ case OP_SCopy: { /* in1, out2 */
#ifdef SQLITE_DEBUG
if( pOut->pScopyFrom==0 ) pOut->pScopyFrom = pIn1;
#endif
- REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: ResultRow P1 P2 * * *
+** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
@@ -66450,13 +67725,25 @@ case OP_SCopy: { /* in1, out2 */
** row.
*/
case OP_ResultRow: {
-#if 0 /* local variables moved into u.af */
+#if 0 /* local variables moved into u.ag */
Mem *pMem;
int i;
-#endif /* local variables moved into u.af */
+#endif /* local variables moved into u.ag */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
- assert( pOp->p1+pOp->p2<=p->nMem+1 );
+ assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
+
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ /* Run the progress counter just before returning.
+ */
+ if( db->xProgress!=0
+ && nVmStep>=nProgressLimit
+ && db->xProgress(db->pProgressArg)!=0
+ ){
+ rc = SQLITE_INTERRUPT;
+ goto vdbe_error_halt;
+ }
+#endif
/* If this statement has violated immediate foreign key constraints, do
** not return the number of rows modified. And do not RELEASE the statement
@@ -66495,15 +67782,15 @@ case OP_ResultRow: {
** and have an assigned type. The results are de-ephemeralized as
** a side effect.
*/
- u.af.pMem = p->pResultSet = &aMem[pOp->p1];
- for(u.af.i=0; u.af.i<pOp->p2; u.af.i++){
- assert( memIsValid(&u.af.pMem[u.af.i]) );
- Deephemeralize(&u.af.pMem[u.af.i]);
- assert( (u.af.pMem[u.af.i].flags & MEM_Ephem)==0
- || (u.af.pMem[u.af.i].flags & (MEM_Str|MEM_Blob))==0 );
- sqlite3VdbeMemNulTerminate(&u.af.pMem[u.af.i]);
- sqlite3VdbeMemStoreType(&u.af.pMem[u.af.i]);
- REGISTER_TRACE(pOp->p1+u.af.i, &u.af.pMem[u.af.i]);
+ u.ag.pMem = p->pResultSet = &aMem[pOp->p1];
+ for(u.ag.i=0; u.ag.i<pOp->p2; u.ag.i++){
+ assert( memIsValid(&u.ag.pMem[u.ag.i]) );
+ Deephemeralize(&u.ag.pMem[u.ag.i]);
+ assert( (u.ag.pMem[u.ag.i].flags & MEM_Ephem)==0
+ || (u.ag.pMem[u.ag.i].flags & (MEM_Str|MEM_Blob))==0 );
+ sqlite3VdbeMemNulTerminate(&u.ag.pMem[u.ag.i]);
+ sqlite3VdbeMemStoreType(&u.ag.pMem[u.ag.i]);
+ REGISTER_TRACE(pOp->p1+u.ag.i, &u.ag.pMem[u.ag.i]);
}
if( db->mallocFailed ) goto no_mem;
@@ -66515,6 +67802,7 @@ case OP_ResultRow: {
}
/* Opcode: Concat P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]+r[P1]
**
** Add the text in register P1 onto the end of the text in
** register P2 and store the result in register P3.
@@ -66527,9 +67815,9 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ag */
+#if 0 /* local variables moved into u.ah */
i64 nByte;
-#endif /* local variables moved into u.ag */
+#endif /* local variables moved into u.ah */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
@@ -66542,34 +67830,36 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
- u.ag.nByte = pIn1->n + pIn2->n;
- if( u.ag.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ah.nByte = pIn1->n + pIn2->n;
+ if( u.ah.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ag.nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ah.nByte+2, pOut==pIn2) ){
goto no_mem;
}
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[u.ag.nByte] = 0;
- pOut->z[u.ag.nByte+1] = 0;
+ pOut->z[u.ah.nByte]=0;
+ pOut->z[u.ah.nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)u.ag.nByte;
+ pOut->n = (int)u.ah.nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Add P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]+r[P2]
**
** Add the value in register P1 to the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Multiply P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]*r[P2]
**
**
** Multiply the value in register P1 by the value in register P2
@@ -66577,12 +67867,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]-r[P1]
**
** Subtract the value in register P1 from the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Divide P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]/r[P1]
**
** Divide the value in register P1 by the value in register P2
** and store the result in register P3 (P3=P2/P1). If the value in
@@ -66590,10 +67882,11 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]%r[P1]
**
-** Compute the remainder after integer division of the value in
-** register P1 by the value in register P2 and store the result in P3.
-** If the value in register P2 is zero the result is NULL.
+** Compute the remainder after integer register P2 is divided by
+** register P1 and store the result in register P3.
+** If the value in register P1 is zero the result is NULL.
** If either operand is NULL, the result is NULL.
*/
case OP_Add: /* same as TK_PLUS, in1, in2, out3 */
@@ -66601,79 +67894,79 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
-#if 0 /* local variables moved into u.ah */
+#if 0 /* local variables moved into u.ai */
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
-#endif /* local variables moved into u.ah */
+#endif /* local variables moved into u.ai */
pIn1 = &aMem[pOp->p1];
applyNumericAffinity(pIn1);
pIn2 = &aMem[pOp->p2];
applyNumericAffinity(pIn2);
pOut = &aMem[pOp->p3];
- u.ah.flags = pIn1->flags | pIn2->flags;
- if( (u.ah.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ u.ai.flags = pIn1->flags | pIn2->flags;
+ if( (u.ai.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- u.ah.iA = pIn1->u.i;
- u.ah.iB = pIn2->u.i;
- u.ah.bIntint = 1;
+ u.ai.iA = pIn1->u.i;
+ u.ai.iB = pIn2->u.i;
+ u.ai.bIntint = 1;
switch( pOp->opcode ){
- case OP_Add: if( sqlite3AddInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Subtract: if( sqlite3SubInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
- case OP_Multiply: if( sqlite3MulInt64(&u.ah.iB,u.ah.iA) ) goto fp_math; break;
+ case OP_Add: if( sqlite3AddInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
+ case OP_Subtract: if( sqlite3SubInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
+ case OP_Multiply: if( sqlite3MulInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
case OP_Divide: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 && u.ah.iB==SMALLEST_INT64 ) goto fp_math;
- u.ah.iB /= u.ah.iA;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 && u.ai.iB==SMALLEST_INT64 ) goto fp_math;
+ u.ai.iB /= u.ai.iA;
break;
}
default: {
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.iB %= u.ah.iA;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 ) u.ai.iA = 1;
+ u.ai.iB %= u.ai.iA;
break;
}
}
- pOut->u.i = u.ah.iB;
+ pOut->u.i = u.ai.iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- u.ah.bIntint = 0;
+ u.ai.bIntint = 0;
fp_math:
- u.ah.rA = sqlite3VdbeRealValue(pIn1);
- u.ah.rB = sqlite3VdbeRealValue(pIn2);
+ u.ai.rA = sqlite3VdbeRealValue(pIn1);
+ u.ai.rB = sqlite3VdbeRealValue(pIn2);
switch( pOp->opcode ){
- case OP_Add: u.ah.rB += u.ah.rA; break;
- case OP_Subtract: u.ah.rB -= u.ah.rA; break;
- case OP_Multiply: u.ah.rB *= u.ah.rA; break;
+ case OP_Add: u.ai.rB += u.ai.rA; break;
+ case OP_Subtract: u.ai.rB -= u.ai.rA; break;
+ case OP_Multiply: u.ai.rB *= u.ai.rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( u.ah.rA==(double)0 ) goto arithmetic_result_is_null;
- u.ah.rB /= u.ah.rA;
+ if( u.ai.rA==(double)0 ) goto arithmetic_result_is_null;
+ u.ai.rB /= u.ai.rA;
break;
}
default: {
- u.ah.iA = (i64)u.ah.rA;
- u.ah.iB = (i64)u.ah.rB;
- if( u.ah.iA==0 ) goto arithmetic_result_is_null;
- if( u.ah.iA==-1 ) u.ah.iA = 1;
- u.ah.rB = (double)(u.ah.iB % u.ah.iA);
+ u.ai.iA = (i64)u.ai.rA;
+ u.ai.iB = (i64)u.ai.rB;
+ if( u.ai.iA==0 ) goto arithmetic_result_is_null;
+ if( u.ai.iA==-1 ) u.ai.iA = 1;
+ u.ai.rB = (double)(u.ai.iB % u.ai.iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
- pOut->u.i = u.ah.rB;
+ pOut->u.i = u.ai.rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
- if( sqlite3IsNaN(u.ah.rB) ){
+ if( sqlite3IsNaN(u.ai.rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = u.ah.rB;
+ pOut->r = u.ai.rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (u.ah.flags & MEM_Real)==0 && !u.ah.bIntint ){
+ if( (u.ai.flags & MEM_Real)==0 && !u.ai.bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
@@ -66709,6 +68002,7 @@ case OP_CollSeq: {
}
/* Opcode: Function P1 P2 P3 P4 P5
+** Synopsis: r[P3]=func(r[P2@P5])
**
** Invoke a user function (P4 is a pointer to a Function structure that
** defines the function) with P5 arguments taken from register P2 and
@@ -66725,92 +68019,81 @@ case OP_CollSeq: {
** See also: AggStep and AggFinal
*/
case OP_Function: {
-#if 0 /* local variables moved into u.ai */
+#if 0 /* local variables moved into u.aj */
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
-#endif /* local variables moved into u.ai */
+#endif /* local variables moved into u.aj */
- u.ai.n = pOp->p5;
- u.ai.apVal = p->apArg;
- assert( u.ai.apVal || u.ai.n==0 );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
+ u.aj.n = pOp->p5;
+ u.aj.apVal = p->apArg;
+ assert( u.aj.apVal || u.aj.n==0 );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
- assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n );
- u.ai.pArg = &aMem[pOp->p2];
- for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){
- assert( memIsValid(u.ai.pArg) );
- u.ai.apVal[u.ai.i] = u.ai.pArg;
- Deephemeralize(u.ai.pArg);
- sqlite3VdbeMemStoreType(u.ai.pArg);
- REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
- }
-
- assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
- if( pOp->p4type==P4_FUNCDEF ){
- u.ai.ctx.pFunc = pOp->p4.pFunc;
- u.ai.ctx.pVdbeFunc = 0;
- }else{
- u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
- u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
+ assert( u.aj.n==0 || (pOp->p2>0 && pOp->p2+u.aj.n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.aj.n );
+ u.aj.pArg = &aMem[pOp->p2];
+ for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++, u.aj.pArg++){
+ assert( memIsValid(u.aj.pArg) );
+ u.aj.apVal[u.aj.i] = u.aj.pArg;
+ Deephemeralize(u.aj.pArg);
+ sqlite3VdbeMemStoreType(u.aj.pArg);
+ REGISTER_TRACE(pOp->p2+u.aj.i, u.aj.pArg);
}
- u.ai.ctx.s.flags = MEM_Null;
- u.ai.ctx.s.db = db;
- u.ai.ctx.s.xDel = 0;
- u.ai.ctx.s.zMalloc = 0;
+ assert( pOp->p4type==P4_FUNCDEF );
+ u.aj.ctx.pFunc = pOp->p4.pFunc;
+ u.aj.ctx.iOp = pc;
+ u.aj.ctx.pVdbe = p;
/* The output cell may already have a buffer allocated. Move
- ** the pointer to u.ai.ctx.s so in case the user-function can use
+ ** the pointer to u.aj.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
- sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
- MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
+ memcpy(&u.aj.ctx.s, pOut, sizeof(Mem));
+ pOut->flags = MEM_Null;
+ pOut->xDel = 0;
+ pOut->zMalloc = 0;
+ MemSetTypeFlag(&u.aj.ctx.s, MEM_Null);
- u.ai.ctx.isError = 0;
- if( u.ai.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ u.aj.ctx.fErrorOrAux = 0;
+ if( u.aj.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- u.ai.ctx.pColl = pOp[-1].p4.pColl;
+ u.aj.ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
- (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
+ (*u.aj.ctx.pFunc->xFunc)(&u.aj.ctx, u.aj.n, u.aj.apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
- /* If any auxiliary data functions have been called by this user function,
- ** immediately call the destructor for any non-static values.
- */
- if( u.ai.ctx.pVdbeFunc ){
- sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
- pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
- pOp->p4type = P4_VDBEFUNC;
- }
-
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite3_result_XXX() function
** to return a value. The following call releases any resources
** associated with such a value.
*/
- sqlite3VdbeMemRelease(&u.ai.ctx.s);
+ sqlite3VdbeMemRelease(&u.aj.ctx.s);
goto no_mem;
}
/* If the function returned an error, throw an exception */
- if( u.ai.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ai.ctx.s));
- rc = u.ai.ctx.isError;
+ if( u.aj.ctx.fErrorOrAux ){
+ if( u.aj.ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.aj.ctx.s));
+ rc = u.aj.ctx.isError;
+ }
+ sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&u.ai.ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &u.ai.ctx.s);
+ sqlite3VdbeChangeEncoding(&u.aj.ctx.s, encoding);
+ assert( pOut->flags==MEM_Null );
+ memcpy(pOut, &u.aj.ctx.s, sizeof(Mem));
if( sqlite3VdbeMemTooBig(pOut) ){
goto too_big;
}
@@ -66829,18 +68112,21 @@ case OP_Function: {
}
/* Opcode: BitAnd P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]&r[P2]
**
** Take the bit-wise AND of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: BitOr P1 P2 P3 * *
+** Synopsis: r[P3]=r[P1]|r[P2]
**
** Take the bit-wise OR of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftLeft P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]<<r[P1]
**
** Shift the integer value in register P2 to the left by the
** number of bits specified by the integer in register P1.
@@ -66848,6 +68134,7 @@ case OP_Function: {
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftRight P1 P2 P3 * *
+** Synopsis: r[P3]=r[P2]>>r[P1]
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
@@ -66858,12 +68145,12 @@ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0 /* local variables moved into u.aj */
+#if 0 /* local variables moved into u.ak */
i64 iA;
u64 uA;
i64 iB;
u8 op;
-#endif /* local variables moved into u.aj */
+#endif /* local variables moved into u.ak */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
@@ -66872,43 +68159,44 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
sqlite3VdbeMemSetNull(pOut);
break;
}
- u.aj.iA = sqlite3VdbeIntValue(pIn2);
- u.aj.iB = sqlite3VdbeIntValue(pIn1);
- u.aj.op = pOp->opcode;
- if( u.aj.op==OP_BitAnd ){
- u.aj.iA &= u.aj.iB;
- }else if( u.aj.op==OP_BitOr ){
- u.aj.iA |= u.aj.iB;
- }else if( u.aj.iB!=0 ){
- assert( u.aj.op==OP_ShiftRight || u.aj.op==OP_ShiftLeft );
+ u.ak.iA = sqlite3VdbeIntValue(pIn2);
+ u.ak.iB = sqlite3VdbeIntValue(pIn1);
+ u.ak.op = pOp->opcode;
+ if( u.ak.op==OP_BitAnd ){
+ u.ak.iA &= u.ak.iB;
+ }else if( u.ak.op==OP_BitOr ){
+ u.ak.iA |= u.ak.iB;
+ }else if( u.ak.iB!=0 ){
+ assert( u.ak.op==OP_ShiftRight || u.ak.op==OP_ShiftLeft );
/* If shifting by a negative amount, shift in the other direction */
- if( u.aj.iB<0 ){
+ if( u.ak.iB<0 ){
assert( OP_ShiftRight==OP_ShiftLeft+1 );
- u.aj.op = 2*OP_ShiftLeft + 1 - u.aj.op;
- u.aj.iB = u.aj.iB>(-64) ? -u.aj.iB : 64;
+ u.ak.op = 2*OP_ShiftLeft + 1 - u.ak.op;
+ u.ak.iB = u.ak.iB>(-64) ? -u.ak.iB : 64;
}
- if( u.aj.iB>=64 ){
- u.aj.iA = (u.aj.iA>=0 || u.aj.op==OP_ShiftLeft) ? 0 : -1;
+ if( u.ak.iB>=64 ){
+ u.ak.iA = (u.ak.iA>=0 || u.ak.op==OP_ShiftLeft) ? 0 : -1;
}else{
- memcpy(&u.aj.uA, &u.aj.iA, sizeof(u.aj.uA));
- if( u.aj.op==OP_ShiftLeft ){
- u.aj.uA <<= u.aj.iB;
+ memcpy(&u.ak.uA, &u.ak.iA, sizeof(u.ak.uA));
+ if( u.ak.op==OP_ShiftLeft ){
+ u.ak.uA <<= u.ak.iB;
}else{
- u.aj.uA >>= u.aj.iB;
+ u.ak.uA >>= u.ak.iB;
/* Sign-extend on a right shift of a negative number */
- if( u.aj.iA<0 ) u.aj.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.aj.iB);
+ if( u.ak.iA<0 ) u.ak.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ak.iB);
}
- memcpy(&u.aj.iA, &u.aj.uA, sizeof(u.aj.iA));
+ memcpy(&u.ak.iA, &u.ak.uA, sizeof(u.ak.iA));
}
}
- pOut->u.i = u.aj.iA;
+ pOut->u.i = u.ak.iA;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
/* Opcode: AddImm P1 P2 * * *
+** Synopsis: r[P1]=r[P1]+P2
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
@@ -66932,17 +68220,19 @@ case OP_AddImm: { /* in1 */
*/
case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
- applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
if( (pIn1->flags & MEM_Int)==0 ){
- if( pOp->p2==0 ){
- rc = SQLITE_MISMATCH;
- goto abort_due_to_error;
- }else{
- pc = pOp->p2 - 1;
+ applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
+ if( (pIn1->flags & MEM_Int)==0 ){
+ if( pOp->p2==0 ){
+ rc = SQLITE_MISMATCH;
+ goto abort_due_to_error;
+ }else{
+ pc = pOp->p2 - 1;
+ break;
+ }
}
- }else{
- MemSetTypeFlag(pIn1, MEM_Int);
}
+ MemSetTypeFlag(pIn1, MEM_Int);
break;
}
@@ -67067,6 +68357,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
/* Opcode: Lt P1 P2 P3 P4 P5
+** Synopsis: if r[P1]<r[P3] goto P2
**
** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
** jump to address P2.
@@ -67101,6 +68392,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** bit set.
*/
/* Opcode: Ne P1 P2 P3 P4 P5
+** Synopsis: if r[P1]!=r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are not equal. See the Lt opcode for
@@ -67113,6 +68405,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Eq P1 P2 P3 P4 P5
+** Synopsis: if r[P1]==r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the operands in registers P1 and P3 are equal.
@@ -67125,18 +68418,21 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */
** the SQLITE_NULLEQ flag were omitted from P5.
*/
/* Opcode: Le P1 P2 P3 P4 P5
+** Synopsis: if r[P1]<=r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is less than or equal to the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Gt P1 P2 P3 P4 P5
+** Synopsis: if r[P1]>r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Ge P1 P2 P3 P4 P5
+** Synopsis: if r[P1]>=r[P3] goto P2
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than or equal to the content of
@@ -67148,18 +68444,18 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
-#if 0 /* local variables moved into u.ak */
+#if 0 /* local variables moved into u.al */
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
-#endif /* local variables moved into u.ak */
+#endif /* local variables moved into u.al */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
- u.ak.flags1 = pIn1->flags;
- u.ak.flags3 = pIn3->flags;
- if( (u.ak.flags1 | u.ak.flags3)&MEM_Null ){
+ u.al.flags1 = pIn1->flags;
+ u.al.flags3 = pIn3->flags;
+ if( (u.al.flags1 | u.al.flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
@@ -67167,65 +68463,65 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
- assert( (u.ak.flags1 & MEM_Cleared)==0 );
- if( (u.ak.flags1&MEM_Null)!=0
- && (u.ak.flags3&MEM_Null)!=0
- && (u.ak.flags3&MEM_Cleared)==0
+ assert( (u.al.flags1 & MEM_Cleared)==0 );
+ if( (u.al.flags1&MEM_Null)!=0
+ && (u.al.flags3&MEM_Null)!=0
+ && (u.al.flags3&MEM_Cleared)==0
){
- u.ak.res = 0; /* Results are equal */
+ u.al.res = 0; /* Results are equal */
}else{
- u.ak.res = 1; /* Results are not equal */
+ u.al.res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
- if( pOp->p5 & SQLITE_STOREP2 ){
+ if( pOp->p5 & SQLITE_JUMPIFNULL ){
+ pc = pOp->p2-1;
+ }else if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
- }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
}
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
- u.ak.affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( u.ak.affinity ){
- applyAffinity(pIn1, u.ak.affinity, encoding);
- applyAffinity(pIn3, u.ak.affinity, encoding);
+ u.al.affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( u.al.affinity ){
+ applyAffinity(pIn1, u.al.affinity, encoding);
+ applyAffinity(pIn3, u.al.affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
ExpandBlob(pIn1);
ExpandBlob(pIn3);
- u.ak.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ u.al.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
switch( pOp->opcode ){
- case OP_Eq: u.ak.res = u.ak.res==0; break;
- case OP_Ne: u.ak.res = u.ak.res!=0; break;
- case OP_Lt: u.ak.res = u.ak.res<0; break;
- case OP_Le: u.ak.res = u.ak.res<=0; break;
- case OP_Gt: u.ak.res = u.ak.res>0; break;
- default: u.ak.res = u.ak.res>=0; break;
+ case OP_Eq: u.al.res = u.al.res==0; break;
+ case OP_Ne: u.al.res = u.al.res!=0; break;
+ case OP_Lt: u.al.res = u.al.res<0; break;
+ case OP_Le: u.al.res = u.al.res<=0; break;
+ case OP_Gt: u.al.res = u.al.res>0; break;
+ default: u.al.res = u.al.res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.ak.res;
+ pOut->u.i = u.al.res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.ak.res ){
+ }else if( u.al.res ){
pc = pOp->p2-1;
}
/* Undo any changes made by applyAffinity() to the input registers. */
- pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.ak.flags1&MEM_TypeMask);
- pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.ak.flags3&MEM_TypeMask);
+ pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.al.flags1&MEM_TypeMask);
+ pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.al.flags3&MEM_TypeMask);
break;
}
@@ -67265,7 +68561,7 @@ case OP_Permutation: {
** and strings are less than blobs.
*/
case OP_Compare: {
-#if 0 /* local variables moved into u.al */
+#if 0 /* local variables moved into u.am */
int n;
int i;
int p1;
@@ -67274,38 +68570,38 @@ case OP_Compare: {
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
-#endif /* local variables moved into u.al */
+#endif /* local variables moved into u.am */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
- u.al.n = pOp->p3;
- u.al.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.al.n>0 );
- assert( u.al.pKeyInfo!=0 );
- u.al.p1 = pOp->p1;
- u.al.p2 = pOp->p2;
+ u.am.n = pOp->p3;
+ u.am.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.am.n>0 );
+ assert( u.am.pKeyInfo!=0 );
+ u.am.p1 = pOp->p1;
+ u.am.p2 = pOp->p2;
#if SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
- for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
- assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 );
- assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 );
+ for(k=0; k<u.am.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
+ assert( u.am.p1>0 && u.am.p1+mx<=(p->nMem-p->nCursor)+1 );
+ assert( u.am.p2>0 && u.am.p2+mx<=(p->nMem-p->nCursor)+1 );
}else{
- assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 );
- assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 );
+ assert( u.am.p1>0 && u.am.p1+u.am.n<=(p->nMem-p->nCursor)+1 );
+ assert( u.am.p2>0 && u.am.p2+u.am.n<=(p->nMem-p->nCursor)+1 );
}
#endif /* SQLITE_DEBUG */
- for(u.al.i=0; u.al.i<u.al.n; u.al.i++){
- u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i;
- assert( memIsValid(&aMem[u.al.p1+u.al.idx]) );
- assert( memIsValid(&aMem[u.al.p2+u.al.idx]) );
- REGISTER_TRACE(u.al.p1+u.al.idx, &aMem[u.al.p1+u.al.idx]);
- REGISTER_TRACE(u.al.p2+u.al.idx, &aMem[u.al.p2+u.al.idx]);
- assert( u.al.i<u.al.pKeyInfo->nField );
- u.al.pColl = u.al.pKeyInfo->aColl[u.al.i];
- u.al.bRev = u.al.pKeyInfo->aSortOrder[u.al.i];
- iCompare = sqlite3MemCompare(&aMem[u.al.p1+u.al.idx], &aMem[u.al.p2+u.al.idx], u.al.pColl);
+ for(u.am.i=0; u.am.i<u.am.n; u.am.i++){
+ u.am.idx = aPermute ? aPermute[u.am.i] : u.am.i;
+ assert( memIsValid(&aMem[u.am.p1+u.am.idx]) );
+ assert( memIsValid(&aMem[u.am.p2+u.am.idx]) );
+ REGISTER_TRACE(u.am.p1+u.am.idx, &aMem[u.am.p1+u.am.idx]);
+ REGISTER_TRACE(u.am.p2+u.am.idx, &aMem[u.am.p2+u.am.idx]);
+ assert( u.am.i<u.am.pKeyInfo->nField );
+ u.am.pColl = u.am.pKeyInfo->aColl[u.am.i];
+ u.am.bRev = u.am.pKeyInfo->aSortOrder[u.am.i];
+ iCompare = sqlite3MemCompare(&aMem[u.am.p1+u.am.idx], &aMem[u.am.p2+u.am.idx], u.am.pColl);
if( iCompare ){
- if( u.al.bRev ) iCompare = -iCompare;
+ if( u.am.bRev ) iCompare = -iCompare;
break;
}
}
@@ -67331,6 +68627,7 @@ case OP_Jump: { /* jump */
}
/* Opcode: And P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] && r[P2])
**
** Take the logical AND of the values in registers P1 and P2 and
** write the result into register P3.
@@ -67340,6 +68637,7 @@ case OP_Jump: { /* jump */
** a NULL output.
*/
/* Opcode: Or P1 P2 P3 * *
+** Synopsis: r[P3]=(r[P1] || r[P2])
**
** Take the logical OR of the values in register P1 and P2 and
** store the answer in register P3.
@@ -67350,41 +68648,42 @@ case OP_Jump: { /* jump */
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
-#if 0 /* local variables moved into u.am */
+#if 0 /* local variables moved into u.an */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.am */
+#endif /* local variables moved into u.an */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.am.v1 = 2;
+ u.an.v1 = 2;
}else{
- u.am.v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ u.an.v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
- u.am.v2 = 2;
+ u.an.v2 = 2;
}else{
- u.am.v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ u.an.v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- u.am.v1 = and_logic[u.am.v1*3+u.am.v2];
+ u.an.v1 = and_logic[u.an.v1*3+u.an.v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- u.am.v1 = or_logic[u.am.v1*3+u.am.v2];
+ u.an.v1 = or_logic[u.an.v1*3+u.an.v2];
}
pOut = &aMem[pOp->p3];
- if( u.am.v1==2 ){
+ if( u.an.v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = u.am.v1;
+ pOut->u.i = u.an.v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
}
/* Opcode: Not P1 P2 * * *
+** Synopsis: r[P2]= !r[P1]
**
** Interpret the value in register P1 as a boolean value. Store the
** boolean complement in register P2. If the value in register P1 is
@@ -67402,6 +68701,7 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */
}
/* Opcode: BitNot P1 P2 * * *
+** Synopsis: r[P1]= ~r[P1]
**
** Interpret the content of register P1 as an integer. Store the
** ones-complement of the P1 value into register P2. If P1 holds
@@ -67447,27 +68747,28 @@ case OP_Once: { /* jump */
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
-#if 0 /* local variables moved into u.an */
+#if 0 /* local variables moved into u.ao */
int c;
-#endif /* local variables moved into u.an */
+#endif /* local variables moved into u.ao */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.an.c = pOp->p3;
+ u.ao.c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- u.an.c = sqlite3VdbeIntValue(pIn1)!=0;
+ u.ao.c = sqlite3VdbeIntValue(pIn1)!=0;
#else
- u.an.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+ u.ao.c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
- if( pOp->opcode==OP_IfNot ) u.an.c = !u.an.c;
+ if( pOp->opcode==OP_IfNot ) u.ao.c = !u.ao.c;
}
- if( u.an.c ){
+ if( u.ao.c ){
pc = pOp->p2-1;
}
break;
}
/* Opcode: IsNull P1 P2 * * *
+** Synopsis: if r[P1]==NULL goto P2
**
** Jump to P2 if the value in register P1 is NULL.
*/
@@ -67480,6 +68781,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
}
/* Opcode: NotNull P1 P2 * * *
+** Synopsis: if r[P1]!=NULL goto P2
**
** Jump to P2 if the value in register P1 is not NULL.
*/
@@ -67492,6 +68794,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
}
/* Opcode: Column P1 P2 P3 P4 P5
+** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
@@ -67516,155 +68819,105 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
-#if 0 /* local variables moved into u.ao */
- u32 payloadSize; /* Number of bytes in the record */
+#if 0 /* local variables moved into u.ap */
i64 payloadSize64; /* Number of bytes in the record */
- int p1; /* P1 value of the opcode */
int p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
- char *zRec; /* Pointer to complete record-data */
BtCursor *pCrsr; /* The BTree cursor */
u32 *aType; /* aType[i] holds the numeric type of the i-th column */
u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int nField; /* number of fields in the record */
int len; /* The length of the serialized data for the column */
int i; /* Loop counter */
- char *zData; /* Part of the record being decoded */
Mem *pDest; /* Where to write the extracted value */
Mem sMem; /* For storing the record being decoded */
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
+ const u8 *zData; /* Part of the record being decoded */
+ const u8 *zHdr; /* Next unparsed byte of the header */
+ const u8 *zEndHdr; /* Pointer to first byte after the header */
u32 offset; /* Offset into the data */
u32 szField; /* Number of bytes in the content of a field */
- int szHdr; /* Size of the header size field at start of record */
- int avail; /* Number of bytes of available data */
+ u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
-#endif /* local variables moved into u.ao */
-
-
- u.ao.p1 = pOp->p1;
- u.ao.p2 = pOp->p2;
- u.ao.pC = 0;
- memset(&u.ao.sMem, 0, sizeof(u.ao.sMem));
- assert( u.ao.p1<p->nCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- u.ao.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.ao.pDest);
- u.ao.zRec = 0;
+#endif /* local variables moved into u.ap */
- /* This block sets the variable u.ao.payloadSize to be the total number of
- ** bytes in the record.
- **
- ** u.ao.zRec is set to be the complete text of the record if it is available.
- ** The complete record text is always available for pseudo-tables
- ** If the record is stored in a cursor, the complete record text
- ** might be available in the u.ao.pC->aRow cache. Or it might not be.
- ** If the data is unavailable, u.ao.zRec is set to NULL.
- **
- ** We also compute the number of columns in the record. For cursors,
- ** the number of columns is stored in the VdbeCursor.nField element.
- */
- u.ao.pC = p->apCsr[u.ao.p1];
- assert( u.ao.pC!=0 );
+ u.ap.p2 = pOp->p2;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ u.ap.pDest = &aMem[pOp->p3];
+ memAboutToChange(p, u.ap.pDest);
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ u.ap.pC = p->apCsr[pOp->p1];
+ assert( u.ap.pC!=0 );
+ assert( u.ap.p2<u.ap.pC->nField );
+ u.ap.aType = u.ap.pC->aType;
+ u.ap.aOffset = u.ap.aType + u.ap.pC->nField;
#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( u.ao.pC->pVtabCursor==0 );
-#endif
- u.ao.pCrsr = u.ao.pC->pCursor;
- if( u.ao.pCrsr!=0 ){
- /* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(u.ao.pC);
- if( rc ) goto abort_due_to_error;
- if( u.ao.pC->nullRow ){
- u.ao.payloadSize = 0;
- }else if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.payloadSize = u.ao.pC->payloadSize;
- u.ao.zRec = (char*)u.ao.pC->aRow;
- }else if( u.ao.pC->isIndex ){
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ao.pCrsr, &u.ao.payloadSize64);
- assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for u.ao.payloadSize64 to be
- ** larger than 32 bits. */
- assert( (u.ao.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ao.payloadSize64 );
- u.ao.payloadSize = (u32)u.ao.payloadSize64;
- }else{
- assert( sqlite3BtreeCursorIsValid(u.ao.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ao.pCrsr, &u.ao.payloadSize);
- assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- }
- }else if( ALWAYS(u.ao.pC->pseudoTableReg>0) ){
- u.ao.pReg = &aMem[u.ao.pC->pseudoTableReg];
- if( u.ao.pC->multiPseudo ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, u.ao.pReg+u.ao.p2, MEM_Ephem);
- Deephemeralize(u.ao.pDest);
- goto op_column_out;
- }
- assert( u.ao.pReg->flags & MEM_Blob );
- assert( memIsValid(u.ao.pReg) );
- u.ao.payloadSize = u.ao.pReg->n;
- u.ao.zRec = u.ao.pReg->z;
- u.ao.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr;
- assert( u.ao.payloadSize==0 || u.ao.zRec!=0 );
- }else{
- /* Consider the row to be NULL */
- u.ao.payloadSize = 0;
- }
-
- /* If u.ao.payloadSize is 0, then just store a NULL. This can happen because of
- ** nullRow or because of a corrupt database. */
- if( u.ao.payloadSize==0 ){
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
- goto op_column_out;
- }
- assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
- if( u.ao.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
- goto too_big;
- }
-
- u.ao.nField = u.ao.pC->nField;
- assert( u.ao.p2<u.ao.nField );
-
- /* Read and parse the table header. Store the results of the parse
- ** into the record header cache fields of the cursor.
- */
- u.ao.aType = u.ao.pC->aType;
- if( u.ao.pC->cacheStatus==p->cacheCtr ){
- u.ao.aOffset = u.ao.pC->aOffset;
- }else{
- assert(u.ao.aType);
- u.ao.avail = 0;
- u.ao.pC->aOffset = u.ao.aOffset = &u.ao.aType[u.ao.nField];
- u.ao.pC->payloadSize = u.ao.payloadSize;
- u.ao.pC->cacheStatus = p->cacheCtr;
-
- /* Figure out how many bytes are in the header */
- if( u.ao.zRec ){
- u.ao.zData = u.ao.zRec;
- }else{
- if( u.ao.pC->isIndex ){
- u.ao.zData = (char*)sqlite3BtreeKeyFetch(u.ao.pCrsr, &u.ao.avail);
+ assert( u.ap.pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
+#endif
+ u.ap.pCrsr = u.ap.pC->pCursor;
+ assert( u.ap.pCrsr!=0 || u.ap.pC->pseudoTableReg>0 ); /* u.ap.pCrsr NULL on PseudoTables */
+ assert( u.ap.pCrsr!=0 || u.ap.pC->nullRow ); /* u.ap.pC->nullRow on PseudoTables */
+
+ /* If the cursor cache is stale, bring it up-to-date */
+ rc = sqlite3VdbeCursorMoveto(u.ap.pC);
+ if( rc ) goto abort_due_to_error;
+ if( u.ap.pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
+ if( u.ap.pC->nullRow ){
+ if( u.ap.pCrsr==0 ){
+ assert( u.ap.pC->pseudoTableReg>0 );
+ u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg];
+ if( u.ap.pC->multiPseudo ){
+ sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem);
+ Deephemeralize(u.ap.pDest);
+ goto op_column_out;
+ }
+ assert( u.ap.pReg->flags & MEM_Blob );
+ assert( memIsValid(u.ap.pReg) );
+ u.ap.pC->payloadSize = u.ap.pC->szRow = u.ap.avail = u.ap.pReg->n;
+ u.ap.pC->aRow = (u8*)u.ap.pReg->z;
}else{
- u.ao.zData = (char*)sqlite3BtreeDataFetch(u.ao.pCrsr, &u.ao.avail);
+ MemSetTypeFlag(u.ap.pDest, MEM_Null);
+ goto op_column_out;
}
- /* If KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the u.ao.pC->aRow cache. That will save us from
- ** having to make additional calls to fetch the content portion of
- ** the record.
- */
- assert( u.ao.avail>=0 );
- if( u.ao.payloadSize <= (u32)u.ao.avail ){
- u.ao.zRec = u.ao.zData;
- u.ao.pC->aRow = (u8*)u.ao.zData;
+ }else{
+ assert( u.ap.pCrsr );
+ if( u.ap.pC->isTable==0 ){
+ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ap.pCrsr, &u.ap.payloadSize64);
+ assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
+ /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
+ ** payload size, so it is impossible for u.ap.payloadSize64 to be
+ ** larger than 32 bits. */
+ assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 );
+ u.ap.pC->aRow = sqlite3BtreeKeyFetch(u.ap.pCrsr, &u.ap.avail);
+ u.ap.pC->payloadSize = (u32)u.ap.payloadSize64;
+ }else{
+ assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.pC->payloadSize);
+ assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
+ u.ap.pC->aRow = sqlite3BtreeDataFetch(u.ap.pCrsr, &u.ap.avail);
+ }
+ assert( u.ap.avail<=65536 ); /* Maximum page size is 64KiB */
+ if( u.ap.pC->payloadSize <= (u32)u.ap.avail ){
+ u.ap.pC->szRow = u.ap.pC->payloadSize;
}else{
- u.ao.pC->aRow = 0;
+ u.ap.pC->szRow = u.ap.avail;
}
+ if( u.ap.pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ goto too_big;
+ }
+ }
+ u.ap.pC->cacheStatus = p->cacheCtr;
+ u.ap.pC->iHdrOffset = getVarint32(u.ap.pC->aRow, u.ap.offset);
+ u.ap.pC->nHdrParsed = 0;
+ u.ap.aOffset[0] = u.ap.offset;
+ if( u.ap.avail<u.ap.offset ){
+ /* u.ap.pC->aRow does not have to hold the entire row, but it does at least
+ ** need to cover the header of the record. If u.ap.pC->aRow does not contain
+ ** the complete header, then set it to zero, forcing the header to be
+ ** dynamically allocated. */
+ u.ap.pC->aRow = 0;
+ u.ap.pC->szRow = 0;
}
- /* The following assert is true in all cases except when
- ** the database file has been corrupted externally.
- ** assert( u.ao.zRec!=0 || u.ao.avail>=u.ao.payloadSize || u.ao.avail>=9 ); */
- u.ao.szHdr = getVarint32((u8*)u.ao.zData, u.ao.offset);
/* Make sure a corrupt database has not given us an oversize header.
** Do this now to avoid an oversize memory allocation.
@@ -67675,161 +68928,155 @@ case OP_Column: {
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
- if( u.ao.offset > 98307 ){
+ if( u.ap.offset > 98307 || u.ap.offset > u.ap.pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
- goto op_column_out;
+ goto op_column_error;
}
+ }
- /* Compute in u.ao.len the number of bytes of data we need to read in order
- ** to get u.ao.nField type values. u.ao.offset is an upper bound on this. But
- ** u.ao.nField might be significantly less than the true number of columns
- ** in the table, and in that case, 5*u.ao.nField+3 might be smaller than u.ao.offset.
- ** We want to minimize u.ao.len in order to limit the size of the memory
- ** allocation, especially if a corrupt database file has caused u.ao.offset
- ** to be oversized. Offset is limited to 98307 above. But 98307 might
- ** still exceed Robson memory allocation limits on some configurations.
- ** On systems that cannot tolerate large memory allocations, u.ao.nField*5+3
- ** will likely be much smaller since u.ao.nField will likely be less than
- ** 20 or so. This insures that Robson memory allocation limits are
- ** not exceeded even for corrupt database files.
- */
- u.ao.len = u.ao.nField*5 + 3;
- if( u.ao.len > (int)u.ao.offset ) u.ao.len = (int)u.ao.offset;
-
- /* The KeyFetch() or DataFetch() above are fast and will get the entire
- ** record header in most cases. But they will fail to get the complete
- ** record header if the record header does not fit on a single page
- ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
- ** acquire the complete header text.
+ /* Make sure at least the first u.ap.p2+1 entries of the header have been
+ ** parsed and valid information is in u.ap.aOffset[] and u.ap.aType[].
+ */
+ if( u.ap.pC->nHdrParsed<=u.ap.p2 ){
+ /* If there is more header available for parsing in the record, try
+ ** to extract additional fields up through the u.ap.p2+1-th field
*/
- if( !u.ao.zRec && u.ao.avail<u.ao.len ){
- u.ao.sMem.flags = 0;
- u.ao.sMem.db = 0;
- rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, 0, u.ao.len, u.ao.pC->isIndex, &u.ao.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
+ if( u.ap.pC->iHdrOffset<u.ap.aOffset[0] ){
+ /* Make sure u.ap.zData points to enough of the record to cover the header. */
+ if( u.ap.pC->aRow==0 ){
+ memset(&u.ap.sMem, 0, sizeof(u.ap.sMem));
+ rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, 0, u.ap.aOffset[0],
+ !u.ap.pC->isTable, &u.ap.sMem);
+ if( rc!=SQLITE_OK ){
+ goto op_column_error;
+ }
+ u.ap.zData = (u8*)u.ap.sMem.z;
+ }else{
+ u.ap.zData = u.ap.pC->aRow;
}
- u.ao.zData = u.ao.sMem.z;
- }
- u.ao.zEndHdr = (u8 *)&u.ao.zData[u.ao.len];
- u.ao.zIdx = (u8 *)&u.ao.zData[u.ao.szHdr];
- /* Scan the header and use it to fill in the u.ao.aType[] and u.ao.aOffset[]
- ** arrays. u.ao.aType[u.ao.i] will contain the type integer for the u.ao.i-th
- ** column and u.ao.aOffset[u.ao.i] will contain the u.ao.offset from the beginning
- ** of the record to the start of the data for the u.ao.i-th column
- */
- for(u.ao.i=0; u.ao.i<u.ao.nField; u.ao.i++){
- if( u.ao.zIdx<u.ao.zEndHdr ){
- u.ao.aOffset[u.ao.i] = u.ao.offset;
- if( u.ao.zIdx[0]<0x80 ){
- u.ao.t = u.ao.zIdx[0];
- u.ao.zIdx++;
+ /* Fill in u.ap.aType[u.ap.i] and u.ap.aOffset[u.ap.i] values through the u.ap.p2-th field. */
+ u.ap.i = u.ap.pC->nHdrParsed;
+ u.ap.offset = u.ap.aOffset[u.ap.i];
+ u.ap.zHdr = u.ap.zData + u.ap.pC->iHdrOffset;
+ u.ap.zEndHdr = u.ap.zData + u.ap.aOffset[0];
+ assert( u.ap.i<=u.ap.p2 && u.ap.zHdr<u.ap.zEndHdr );
+ do{
+ if( u.ap.zHdr[0]<0x80 ){
+ u.ap.t = u.ap.zHdr[0];
+ u.ap.zHdr++;
}else{
- u.ao.zIdx += sqlite3GetVarint32(u.ao.zIdx, &u.ao.t);
+ u.ap.zHdr += sqlite3GetVarint32(u.ap.zHdr, &u.ap.t);
}
- u.ao.aType[u.ao.i] = u.ao.t;
- u.ao.szField = sqlite3VdbeSerialTypeLen(u.ao.t);
- u.ao.offset += u.ao.szField;
- if( u.ao.offset<u.ao.szField ){ /* True if u.ao.offset overflows */
- u.ao.zIdx = &u.ao.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
+ u.ap.aType[u.ap.i] = u.ap.t;
+ u.ap.szField = sqlite3VdbeSerialTypeLen(u.ap.t);
+ u.ap.offset += u.ap.szField;
+ if( u.ap.offset<u.ap.szField ){ /* True if u.ap.offset overflows */
+ u.ap.zHdr = &u.ap.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
break;
}
- }else{
- /* If u.ao.i is less that u.ao.nField, then there are fewer fields in this
- ** record than SetNumColumns indicated there are columns in the
- ** table. Set the u.ao.offset for any extra columns not present in
- ** the record to 0. This tells code below to store the default value
- ** for the column instead of deserializing a value from the record.
- */
- u.ao.aOffset[u.ao.i] = 0;
+ u.ap.i++;
+ u.ap.aOffset[u.ap.i] = u.ap.offset;
+ }while( u.ap.i<=u.ap.p2 && u.ap.zHdr<u.ap.zEndHdr );
+ u.ap.pC->nHdrParsed = u.ap.i;
+ u.ap.pC->iHdrOffset = (u32)(u.ap.zHdr - u.ap.zData);
+ if( u.ap.pC->aRow==0 ){
+ sqlite3VdbeMemRelease(&u.ap.sMem);
+ u.ap.sMem.flags = MEM_Null;
+ }
+
+ /* If we have read more header data than was contained in the header,
+ ** or if the end of the last field appears to be past the end of the
+ ** record, or if the end of the last field appears to be before the end
+ ** of the record (when all fields present), then we must be dealing
+ ** with a corrupt database.
+ */
+ if( (u.ap.zHdr > u.ap.zEndHdr)
+ || (u.ap.offset > u.ap.pC->payloadSize)
+ || (u.ap.zHdr==u.ap.zEndHdr && u.ap.offset!=u.ap.pC->payloadSize)
+ ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto op_column_error;
}
}
- sqlite3VdbeMemRelease(&u.ao.sMem);
- u.ao.sMem.flags = MEM_Null;
- /* If we have read more header data than was contained in the header,
- ** or if the end of the last field appears to be past the end of the
- ** record, or if the end of the last field appears to be before the end
- ** of the record (when all fields present), then we must be dealing
- ** with a corrupt database.
+ /* If after trying to extra new entries from the header, nHdrParsed is
+ ** still not up to u.ap.p2, that means that the record has fewer than u.ap.p2
+ ** columns. So the result will be either the default value or a NULL.
*/
- if( (u.ao.zIdx > u.ao.zEndHdr) || (u.ao.offset > u.ao.payloadSize)
- || (u.ao.zIdx==u.ao.zEndHdr && u.ao.offset!=u.ao.payloadSize) ){
- rc = SQLITE_CORRUPT_BKPT;
+ if( u.ap.pC->nHdrParsed<=u.ap.p2 ){
+ if( pOp->p4type==P4_MEM ){
+ sqlite3VdbeMemShallowCopy(u.ap.pDest, pOp->p4.pMem, MEM_Static);
+ }else{
+ MemSetTypeFlag(u.ap.pDest, MEM_Null);
+ }
goto op_column_out;
}
}
- /* Get the column information. If u.ao.aOffset[u.ao.p2] is non-zero, then
- ** deserialize the value from the record. If u.ao.aOffset[u.ao.p2] is zero,
- ** then there are not enough fields in the record to satisfy the
- ** request. In this case, set the value NULL or to P4 if P4 is
- ** a pointer to a Mem object.
+ /* Extract the content for the u.ap.p2+1-th column. Control can only
+ ** reach this point if u.ap.aOffset[u.ap.p2], u.ap.aOffset[u.ap.p2+1], and u.ap.aType[u.ap.p2] are
+ ** all valid.
*/
- if( u.ao.aOffset[u.ao.p2] ){
- assert( rc==SQLITE_OK );
- if( u.ao.zRec ){
- /* This is the common case where the whole row fits on a single page */
- VdbeMemRelease(u.ao.pDest);
- sqlite3VdbeSerialGet((u8 *)&u.ao.zRec[u.ao.aOffset[u.ao.p2]], u.ao.aType[u.ao.p2], u.ao.pDest);
+ assert( u.ap.p2<u.ap.pC->nHdrParsed );
+ assert( rc==SQLITE_OK );
+ if( u.ap.pC->szRow>=u.ap.aOffset[u.ap.p2+1] ){
+ /* This is the common case where the desired content fits on the original
+ ** page - where the content is not on an overflow page */
+ VdbeMemRelease(u.ap.pDest);
+ sqlite3VdbeSerialGet(u.ap.pC->aRow+u.ap.aOffset[u.ap.p2], u.ap.aType[u.ap.p2], u.ap.pDest);
+ }else{
+ /* This branch happens only when content is on overflow pages */
+ u.ap.t = u.ap.aType[u.ap.p2];
+ if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
+ && ((u.ap.t>=12 && (u.ap.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
+ || (u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.t))==0
+ ){
+ /* Content is irrelevant for the typeof() function and for
+ ** the length(X) function if X is a blob. So we might as well use
+ ** bogus content rather than reading content from disk. NULL works
+ ** for text and blob and whatever is in the u.ap.payloadSize64 variable
+ ** will work for everything else. Content is also irrelevant if
+ ** the content length is 0. */
+ u.ap.zData = u.ap.t<=13 ? (u8*)&u.ap.payloadSize64 : 0;
+ u.ap.sMem.zMalloc = 0;
}else{
- /* This branch happens only when the row overflows onto multiple pages */
- u.ao.t = u.ao.aType[u.ao.p2];
- if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
- && ((u.ao.t>=12 && (u.ao.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)
- ){
- /* Content is irrelevant for the typeof() function and for
- ** the length(X) function if X is a blob. So we might as well use
- ** bogus content rather than reading content from disk. NULL works
- ** for text and blob and whatever is in the u.ao.payloadSize64 variable
- ** will work for everything else. */
- u.ao.zData = u.ao.t<12 ? (char*)&u.ao.payloadSize64 : 0;
- }else{
- u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.t);
- sqlite3VdbeMemMove(&u.ao.sMem, u.ao.pDest);
- rc = sqlite3VdbeMemFromBtree(u.ao.pCrsr, u.ao.aOffset[u.ao.p2], u.ao.len, u.ao.pC->isIndex,
- &u.ao.sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
- }
- u.ao.zData = u.ao.sMem.z;
+ memset(&u.ap.sMem, 0, sizeof(u.ap.sMem));
+ sqlite3VdbeMemMove(&u.ap.sMem, u.ap.pDest);
+ rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, u.ap.aOffset[u.ap.p2], u.ap.len, !u.ap.pC->isTable,
+ &u.ap.sMem);
+ if( rc!=SQLITE_OK ){
+ goto op_column_error;
}
- sqlite3VdbeSerialGet((u8*)u.ao.zData, u.ao.t, u.ao.pDest);
+ u.ap.zData = (u8*)u.ap.sMem.z;
}
- u.ao.pDest->enc = encoding;
- }else{
- if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(u.ao.pDest, pOp->p4.pMem, MEM_Static);
- }else{
- MemSetTypeFlag(u.ao.pDest, MEM_Null);
+ sqlite3VdbeSerialGet(u.ap.zData, u.ap.t, u.ap.pDest);
+ /* If we dynamically allocated space to hold the data (in the
+ ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
+ ** dynamically allocated space over to the u.ap.pDest structure.
+ ** This prevents a memory copy. */
+ if( u.ap.sMem.zMalloc ){
+ assert( u.ap.sMem.z==u.ap.sMem.zMalloc );
+ assert( !(u.ap.pDest->flags & MEM_Dyn) );
+ assert( !(u.ap.pDest->flags & (MEM_Blob|MEM_Str)) || u.ap.pDest->z==u.ap.sMem.z );
+ u.ap.pDest->flags &= ~(MEM_Ephem|MEM_Static);
+ u.ap.pDest->flags |= MEM_Term;
+ u.ap.pDest->z = u.ap.sMem.z;
+ u.ap.pDest->zMalloc = u.ap.sMem.zMalloc;
}
}
-
- /* If we dynamically allocated space to hold the data (in the
- ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the u.ao.pDest structure.
- ** This prevents a memory copy.
- */
- if( u.ao.sMem.zMalloc ){
- assert( u.ao.sMem.z==u.ao.sMem.zMalloc );
- assert( !(u.ao.pDest->flags & MEM_Dyn) );
- assert( !(u.ao.pDest->flags & (MEM_Blob|MEM_Str)) || u.ao.pDest->z==u.ao.sMem.z );
- u.ao.pDest->flags &= ~(MEM_Ephem|MEM_Static);
- u.ao.pDest->flags |= MEM_Term;
- u.ao.pDest->z = u.ao.sMem.z;
- u.ao.pDest->zMalloc = u.ao.sMem.zMalloc;
- }
-
- rc = sqlite3VdbeMemMakeWriteable(u.ao.pDest);
+ u.ap.pDest->enc = encoding;
op_column_out:
- UPDATE_MAX_BLOBSIZE(u.ao.pDest);
- REGISTER_TRACE(pOp->p3, u.ao.pDest);
+ rc = sqlite3VdbeMemMakeWriteable(u.ap.pDest);
+op_column_error:
+ UPDATE_MAX_BLOBSIZE(u.ap.pDest);
+ REGISTER_TRACE(pOp->p3, u.ap.pDest);
break;
}
/* Opcode: Affinity P1 P2 * P4 *
+** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
@@ -67838,26 +69085,27 @@ op_column_out:
** memory cell in the range.
*/
case OP_Affinity: {
-#if 0 /* local variables moved into u.ap */
+#if 0 /* local variables moved into u.aq */
const char *zAffinity; /* The affinity to be applied */
char cAff; /* A single character of affinity */
-#endif /* local variables moved into u.ap */
+#endif /* local variables moved into u.aq */
- u.ap.zAffinity = pOp->p4.z;
- assert( u.ap.zAffinity!=0 );
- assert( u.ap.zAffinity[pOp->p2]==0 );
+ u.aq.zAffinity = pOp->p4.z;
+ assert( u.aq.zAffinity!=0 );
+ assert( u.aq.zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){
- assert( pIn1 <= &p->aMem[p->nMem] );
+ while( (u.aq.cAff = *(u.aq.zAffinity++))!=0 ){
+ assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
ExpandBlob(pIn1);
- applyAffinity(pIn1, u.ap.cAff, encoding);
+ applyAffinity(pIn1, u.aq.cAff, encoding);
pIn1++;
}
break;
}
/* Opcode: MakeRecord P1 P2 P3 P4 *
+** Synopsis: r[P3]=mkrec(r[P1@P2])
**
** Convert P2 registers beginning with P1 into the [record format]
** use as a data record in a database table or as a key
@@ -67873,7 +69121,7 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
-#if 0 /* local variables moved into u.aq */
+#if 0 /* local variables moved into u.ar */
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
@@ -67889,7 +69137,7 @@ case OP_MakeRecord: {
int file_format; /* File format to use for encoding */
int i; /* Space used in zNewRecord[] */
int len; /* Length of a field */
-#endif /* local variables moved into u.aq */
+#endif /* local variables moved into u.ar */
/* Assuming the record contains N fields, the record format looks
** like this:
@@ -67906,16 +69154,16 @@ case OP_MakeRecord: {
** hdr-size field is also a varint which is the offset from the beginning
** of the record to data0.
*/
- u.aq.nData = 0; /* Number of bytes of data space */
- u.aq.nHdr = 0; /* Number of bytes of header space */
- u.aq.nZero = 0; /* Number of zero bytes at the end of the record */
- u.aq.nField = pOp->p1;
- u.aq.zAffinity = pOp->p4.z;
- assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 );
- u.aq.pData0 = &aMem[u.aq.nField];
- u.aq.nField = pOp->p2;
- u.aq.pLast = &u.aq.pData0[u.aq.nField-1];
- u.aq.file_format = p->minWriteFileFormat;
+ u.ar.nData = 0; /* Number of bytes of data space */
+ u.ar.nHdr = 0; /* Number of bytes of header space */
+ u.ar.nZero = 0; /* Number of zero bytes at the end of the record */
+ u.ar.nField = pOp->p1;
+ u.ar.zAffinity = pOp->p4.z;
+ assert( u.ar.nField>0 && pOp->p2>0 && pOp->p2+u.ar.nField<=(p->nMem-p->nCursor)+1 );
+ u.ar.pData0 = &aMem[u.ar.nField];
+ u.ar.nField = pOp->p2;
+ u.ar.pLast = &u.ar.pData0[u.ar.nField-1];
+ u.ar.file_format = p->minWriteFileFormat;
/* Identify the output register */
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
@@ -67925,34 +69173,34 @@ case OP_MakeRecord: {
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- assert( memIsValid(u.aq.pRec) );
- if( u.aq.zAffinity ){
- applyAffinity(u.aq.pRec, u.aq.zAffinity[u.aq.pRec-u.aq.pData0], encoding);
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
+ assert( memIsValid(u.ar.pRec) );
+ if( u.ar.zAffinity ){
+ applyAffinity(u.ar.pRec, u.ar.zAffinity[u.ar.pRec-u.ar.pData0], encoding);
}
- if( u.aq.pRec->flags&MEM_Zero && u.aq.pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(u.aq.pRec);
+ if( u.ar.pRec->flags&MEM_Zero && u.ar.pRec->n>0 ){
+ sqlite3VdbeMemExpandBlob(u.ar.pRec);
}
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.len = sqlite3VdbeSerialTypeLen(u.aq.serial_type);
- u.aq.nData += u.aq.len;
- u.aq.nHdr += sqlite3VarintLen(u.aq.serial_type);
- if( u.aq.pRec->flags & MEM_Zero ){
+ u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
+ u.ar.len = sqlite3VdbeSerialTypeLen(u.ar.serial_type);
+ u.ar.nData += u.ar.len;
+ u.ar.nHdr += sqlite3VarintLen(u.ar.serial_type);
+ if( u.ar.pRec->flags & MEM_Zero ){
/* Only pure zero-filled BLOBs can be input to this Opcode.
** We do not allow blobs with a prefix and a zero-filled tail. */
- u.aq.nZero += u.aq.pRec->u.nZero;
- }else if( u.aq.len ){
- u.aq.nZero = 0;
+ u.ar.nZero += u.ar.pRec->u.nZero;
+ }else if( u.ar.len ){
+ u.ar.nZero = 0;
}
}
/* Add the initial header varint and total the size */
- u.aq.nHdr += u.aq.nVarint = sqlite3VarintLen(u.aq.nHdr);
- if( u.aq.nVarint<sqlite3VarintLen(u.aq.nHdr) ){
- u.aq.nHdr++;
+ u.ar.nHdr += u.ar.nVarint = sqlite3VarintLen(u.ar.nHdr);
+ if( u.ar.nVarint<sqlite3VarintLen(u.ar.nHdr) ){
+ u.ar.nHdr++;
}
- u.aq.nByte = u.aq.nHdr+u.aq.nData-u.aq.nZero;
- if( u.aq.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ar.nByte = u.ar.nHdr+u.ar.nData-u.ar.nZero;
+ if( u.ar.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
@@ -67961,28 +69209,28 @@ case OP_MakeRecord: {
** be one of the input registers (because the following call to
** sqlite3VdbeMemGrow() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemGrow(pOut, (int)u.aq.nByte, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ar.nByte, 0) ){
goto no_mem;
}
- u.aq.zNewRecord = (u8 *)pOut->z;
+ u.ar.zNewRecord = (u8 *)pOut->z;
/* Write the record */
- u.aq.i = putVarint32(u.aq.zNewRecord, u.aq.nHdr);
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){
- u.aq.serial_type = sqlite3VdbeSerialType(u.aq.pRec, u.aq.file_format);
- u.aq.i += putVarint32(&u.aq.zNewRecord[u.aq.i], u.aq.serial_type); /* serial type */
+ u.ar.i = putVarint32(u.ar.zNewRecord, u.ar.nHdr);
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
+ u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
+ u.ar.i += putVarint32(&u.ar.zNewRecord[u.ar.i], u.ar.serial_type); /* serial type */
}
- for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */
- u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format);
+ for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ /* serial data */
+ u.ar.i += sqlite3VdbeSerialPut(&u.ar.zNewRecord[u.ar.i], (int)(u.ar.nByte-u.ar.i), u.ar.pRec,u.ar.file_format);
}
- assert( u.aq.i==u.aq.nByte );
+ assert( u.ar.i==u.ar.nByte );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut->n = (int)u.aq.nByte;
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
+ pOut->n = (int)u.ar.nByte;
pOut->flags = MEM_Blob | MEM_Dyn;
pOut->xDel = 0;
- if( u.aq.nZero ){
- pOut->u.nZero = u.aq.nZero;
+ if( u.ar.nZero ){
+ pOut->u.nZero = u.ar.nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
@@ -67992,24 +69240,22 @@ case OP_MakeRecord: {
}
/* Opcode: Count P1 P2 * * *
+** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
** opened by cursor P1 in register P2
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ar */
+#if 0 /* local variables moved into u.as */
i64 nEntry;
BtCursor *pCrsr;
-#endif /* local variables moved into u.ar */
+#endif /* local variables moved into u.as */
- u.ar.pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( ALWAYS(u.ar.pCrsr) ){
- rc = sqlite3BtreeCount(u.ar.pCrsr, &u.ar.nEntry);
- }else{
- u.ar.nEntry = 0;
- }
- pOut->u.i = u.ar.nEntry;
+ u.as.pCrsr = p->apCsr[pOp->p1]->pCursor;
+ assert( u.as.pCrsr );
+ rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry);
+ pOut->u.i = u.as.nEntry;
break;
}
#endif
@@ -68021,7 +69267,7 @@ case OP_Count: { /* out2-prerelease */
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
-#if 0 /* local variables moved into u.as */
+#if 0 /* local variables moved into u.at */
int p1; /* Value of P1 operand */
char *zName; /* Name of savepoint */
int nName;
@@ -68030,21 +69276,22 @@ case OP_Savepoint: {
Savepoint *pTmp;
int iSavepoint;
int ii;
-#endif /* local variables moved into u.as */
+#endif /* local variables moved into u.at */
- u.as.p1 = pOp->p1;
- u.as.zName = pOp->p4.z;
+ u.at.p1 = pOp->p1;
+ u.at.zName = pOp->p4.z;
- /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
+ /* Assert that the u.at.p1 parameter is valid. Also that if there is no open
** transaction, then there cannot be any savepoints.
*/
assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
+ assert( u.at.p1==SAVEPOINT_BEGIN||u.at.p1==SAVEPOINT_RELEASE||u.at.p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
+ assert( p->bIsReader );
- if( u.as.p1==SAVEPOINT_BEGIN ){
- if( db->writeVdbeCnt>0 ){
+ if( u.at.p1==SAVEPOINT_BEGIN ){
+ if( db->nVdbeWrite>0 ){
/* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
@@ -68052,7 +69299,7 @@ case OP_Savepoint: {
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- u.as.nName = sqlite3Strlen30(u.as.zName);
+ u.at.nName = sqlite3Strlen30(u.at.zName);
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* This call is Ok even if this savepoint is actually a transaction
@@ -68066,10 +69313,10 @@ case OP_Savepoint: {
#endif
/* Create a new savepoint structure. */
- u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
- if( u.as.pNew ){
- u.as.pNew->zName = (char *)&u.as.pNew[1];
- memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);
+ u.at.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.at.nName+1);
+ if( u.at.pNew ){
+ u.at.pNew->zName = (char *)&u.at.pNew[1];
+ memcpy(u.at.pNew->zName, u.at.zName, u.at.nName+1);
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
@@ -68081,27 +69328,28 @@ case OP_Savepoint: {
}
/* Link the new savepoint into the database handle's list. */
- u.as.pNew->pNext = db->pSavepoint;
- db->pSavepoint = u.as.pNew;
- u.as.pNew->nDeferredCons = db->nDeferredCons;
+ u.at.pNew->pNext = db->pSavepoint;
+ db->pSavepoint = u.at.pNew;
+ u.at.pNew->nDeferredCons = db->nDeferredCons;
+ u.at.pNew->nDeferredImmCons = db->nDeferredImmCons;
}
}
}else{
- u.as.iSavepoint = 0;
+ u.at.iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
** an error is returned to the user. */
for(
- u.as.pSavepoint = db->pSavepoint;
- u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
- u.as.pSavepoint = u.as.pSavepoint->pNext
+ u.at.pSavepoint = db->pSavepoint;
+ u.at.pSavepoint && sqlite3StrICmp(u.at.pSavepoint->zName, u.at.zName);
+ u.at.pSavepoint = u.at.pSavepoint->pNext
){
- u.as.iSavepoint++;
+ u.at.iSavepoint++;
}
- if( !u.as.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
+ if( !u.at.pSavepoint ){
+ sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.at.zName);
rc = SQLITE_ERROR;
- }else if( db->writeVdbeCnt>0 && u.as.p1==SAVEPOINT_RELEASE ){
+ }else if( db->nVdbeWrite>0 && u.at.p1==SAVEPOINT_RELEASE ){
/* It is not possible to release (commit) a savepoint if there are
** active write statements.
*/
@@ -68115,8 +69363,8 @@ case OP_Savepoint: {
** and this is a RELEASE command, then the current transaction
** is committed.
*/
- int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
+ int isTransaction = u.at.pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && u.at.p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
@@ -68130,19 +69378,19 @@ case OP_Savepoint: {
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
- u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
- if( u.as.p1==SAVEPOINT_ROLLBACK ){
- for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
- sqlite3BtreeTripAllCursors(db->aDb[u.as.ii].pBt, SQLITE_ABORT);
+ u.at.iSavepoint = db->nSavepoint - u.at.iSavepoint - 1;
+ if( u.at.p1==SAVEPOINT_ROLLBACK ){
+ for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){
+ sqlite3BtreeTripAllCursors(db->aDb[u.at.ii].pBt, SQLITE_ABORT);
}
}
- for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
+ for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){
+ rc = sqlite3BtreeSavepoint(db->aDb[u.at.ii].pBt, u.at.p1, u.at.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( u.at.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
@@ -68151,10 +69399,10 @@ case OP_Savepoint: {
/* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=u.as.pSavepoint ){
- u.as.pTmp = db->pSavepoint;
- db->pSavepoint = u.as.pTmp->pNext;
- sqlite3DbFree(db, u.as.pTmp);
+ while( db->pSavepoint!=u.at.pSavepoint ){
+ u.at.pTmp = db->pSavepoint;
+ db->pSavepoint = u.at.pTmp->pNext;
+ sqlite3DbFree(db, u.at.pTmp);
db->nSavepoint--;
}
@@ -68162,19 +69410,20 @@ case OP_Savepoint: {
** too. If it is a ROLLBACK TO, then set the number of deferred
** constraint violations present in the database to the value stored
** when the savepoint was created. */
- if( u.as.p1==SAVEPOINT_RELEASE ){
- assert( u.as.pSavepoint==db->pSavepoint );
- db->pSavepoint = u.as.pSavepoint->pNext;
- sqlite3DbFree(db, u.as.pSavepoint);
+ if( u.at.p1==SAVEPOINT_RELEASE ){
+ assert( u.at.pSavepoint==db->pSavepoint );
+ db->pSavepoint = u.at.pSavepoint->pNext;
+ sqlite3DbFree(db, u.at.pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
}else{
- db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
+ db->nDeferredCons = u.at.pSavepoint->nDeferredCons;
+ db->nDeferredImmCons = u.at.pSavepoint->nDeferredImmCons;
}
if( !isTransaction ){
- rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
+ rc = sqlite3VtabSavepoint(db, u.at.p1, u.at.iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
@@ -68193,21 +69442,22 @@ case OP_Savepoint: {
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
-#if 0 /* local variables moved into u.at */
+#if 0 /* local variables moved into u.au */
int desiredAutoCommit;
int iRollback;
int turnOnAC;
-#endif /* local variables moved into u.at */
+#endif /* local variables moved into u.au */
- u.at.desiredAutoCommit = pOp->p1;
- u.at.iRollback = pOp->p2;
- u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
- assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
- assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
- assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
+ u.au.desiredAutoCommit = pOp->p1;
+ u.au.iRollback = pOp->p2;
+ u.au.turnOnAC = u.au.desiredAutoCommit && !db->autoCommit;
+ assert( u.au.desiredAutoCommit==1 || u.au.desiredAutoCommit==0 );
+ assert( u.au.desiredAutoCommit==1 || u.au.iRollback==0 );
+ assert( db->nVdbeActive>0 ); /* At least this one VM is active */
+ assert( p->bIsReader );
#if 0
- if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){
+ if( u.au.turnOnAC && u.au.iRollback && db->nVdbeActive>1 ){
/* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first.
@@ -68217,25 +69467,25 @@ case OP_AutoCommit: {
rc = SQLITE_BUSY;
}else
#endif
- if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>0 ){
+ if( u.au.turnOnAC && !u.au.iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
** return an error indicating that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( u.at.desiredAutoCommit!=db->autoCommit ){
- if( u.at.iRollback ){
- assert( u.at.desiredAutoCommit==1 );
+ }else if( u.au.desiredAutoCommit!=db->autoCommit ){
+ if( u.au.iRollback ){
+ assert( u.au.desiredAutoCommit==1 );
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
- db->autoCommit = (u8)u.at.desiredAutoCommit;
+ db->autoCommit = (u8)u.au.desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
+ db->autoCommit = (u8)(1-u.au.desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -68250,8 +69500,8 @@ case OP_AutoCommit: {
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (u.at.iRollback)?"cannot rollback - no transaction is active":
+ (!u.au.desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (u.au.iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
@@ -68275,8 +69525,8 @@ case OP_AutoCommit: {
** other process can start another write transaction while this transaction is
** underway. Starting a write transaction also creates a rollback journal. A
** write transaction must be started before any changes can be made to the
-** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained
-** on the file.
+** database. If P2 is greater than or equal to 2 then an EXCLUSIVE lock is
+** also obtained on the file.
**
** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
** true (this flag is set if the Vdbe may modify more than one row and may
@@ -68291,16 +69541,22 @@ case OP_AutoCommit: {
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
-#if 0 /* local variables moved into u.au */
+#if 0 /* local variables moved into u.av */
Btree *pBt;
-#endif /* local variables moved into u.au */
+#endif /* local variables moved into u.av */
+ assert( p->bIsReader );
+ assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.au.pBt = db->aDb[pOp->p1].pBt;
+ if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
+ rc = SQLITE_READONLY;
+ goto abort_due_to_error;
+ }
+ u.av.pBt = db->aDb[pOp->p1].pBt;
- if( u.au.pBt ){
- rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
+ if( u.av.pBt ){
+ rc = sqlite3BtreeBeginTrans(u.av.pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
@@ -68311,9 +69567,9 @@ case OP_Transaction: {
}
if( pOp->p2 && p->usesStmtJournal
- && (db->autoCommit==0 || db->activeVdbeCnt>1)
+ && (db->autoCommit==0 || db->nVdbeRead>1)
){
- assert( sqlite3BtreeIsInTrans(u.au.pBt) );
+ assert( sqlite3BtreeIsInTrans(u.av.pBt) );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
db->nStatement++;
@@ -68322,13 +69578,14 @@ case OP_Transaction: {
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginStmt(u.au.pBt, p->iStatement);
+ rc = sqlite3BtreeBeginStmt(u.av.pBt, p->iStatement);
}
/* Store the current value of the database handles deferred constraint
** counter. If the statement transaction needs to be rolled back,
** the value of this counter needs to be restored too. */
p->nStmtDefCons = db->nDeferredCons;
+ p->nStmtDefImmCons = db->nDeferredImmCons;
}
}
break;
@@ -68347,21 +69604,22 @@ case OP_Transaction: {
** executing this instruction.
*/
case OP_ReadCookie: { /* out2-prerelease */
-#if 0 /* local variables moved into u.av */
+#if 0 /* local variables moved into u.aw */
int iMeta;
int iDb;
int iCookie;
-#endif /* local variables moved into u.av */
+#endif /* local variables moved into u.aw */
- u.av.iDb = pOp->p1;
- u.av.iCookie = pOp->p3;
+ assert( p->bIsReader );
+ u.aw.iDb = pOp->p1;
+ u.aw.iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META );
- assert( u.av.iDb>=0 && u.av.iDb<db->nDb );
- assert( db->aDb[u.av.iDb].pBt!=0 );
- assert( (p->btreeMask & (((yDbMask)1)<<u.av.iDb))!=0 );
+ assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb );
+ assert( db->aDb[u.aw.iDb].pBt!=0 );
+ assert( (p->btreeMask & (((yDbMask)1)<<u.aw.iDb))!=0 );
- sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
- pOut->u.i = u.av.iMeta;
+ sqlite3BtreeGetMeta(db->aDb[u.aw.iDb].pBt, u.aw.iCookie, (u32 *)&u.aw.iMeta);
+ pOut->u.i = u.aw.iMeta;
break;
}
@@ -68376,26 +69634,27 @@ case OP_ReadCookie: { /* out2-prerelease */
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
-#if 0 /* local variables moved into u.aw */
+#if 0 /* local variables moved into u.ax */
Db *pDb;
-#endif /* local variables moved into u.aw */
+#endif /* local variables moved into u.ax */
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- u.aw.pDb = &db->aDb[pOp->p1];
- assert( u.aw.pDb->pBt!=0 );
+ assert( p->readOnly==0 );
+ u.ax.pDb = &db->aDb[pOp->p1];
+ assert( u.ax.pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
pIn3 = &aMem[pOp->p3];
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+ rc = sqlite3BtreeUpdateMeta(u.ax.pDb->pBt, pOp->p2, (int)pIn3->u.i);
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
- u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+ u.ax.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
+ u.ax.pDb->pSchema->file_format = (u8)pIn3->u.i;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -68425,23 +69684,24 @@ case OP_SetCookie: { /* in3 */
** invoked.
*/
case OP_VerifyCookie: {
-#if 0 /* local variables moved into u.ax */
+#if 0 /* local variables moved into u.ay */
int iMeta;
int iGen;
Btree *pBt;
-#endif /* local variables moved into u.ax */
+#endif /* local variables moved into u.ay */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
- u.ax.pBt = db->aDb[pOp->p1].pBt;
- if( u.ax.pBt ){
- sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
- u.ax.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+ assert( p->bIsReader );
+ u.ay.pBt = db->aDb[pOp->p1].pBt;
+ if( u.ay.pBt ){
+ sqlite3BtreeGetMeta(u.ay.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ay.iMeta);
+ u.ay.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
}else{
- u.ax.iGen = u.ax.iMeta = 0;
+ u.ay.iGen = u.ay.iMeta = 0;
}
- if( u.ax.iMeta!=pOp->p2 || u.ax.iGen!=pOp->p3 ){
+ if( u.ay.iMeta!=pOp->p2 || u.ay.iGen!=pOp->p3 ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
/* If the schema-cookie from the database file matches the cookie
@@ -68457,7 +69717,7 @@ case OP_VerifyCookie: {
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
+ if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ay.iMeta ){
sqlite3ResetOneSchema(db, pOp->p1);
}
@@ -68468,6 +69728,7 @@ case OP_VerifyCookie: {
}
/* Opcode: OpenRead P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
**
** Open a read-only cursor for the database table whose root page is
** P2 in a database file. The database file is determined by P3.
@@ -68498,6 +69759,7 @@ case OP_VerifyCookie: {
** See also OpenWrite.
*/
/* Opcode: OpenWrite P1 P2 P3 P4 P5
+** Synopsis: root=P2 iDb=P3
**
** Open a read/write cursor named P1 on the table or index whose root
** page is P2. Or if P5!=0 use the content of register P2 to find the
@@ -68518,7 +69780,7 @@ case OP_VerifyCookie: {
*/
case OP_OpenRead:
case OP_OpenWrite: {
-#if 0 /* local variables moved into u.ay */
+#if 0 /* local variables moved into u.az */
int nField;
KeyInfo *pKeyInfo;
int p2;
@@ -68527,82 +69789,87 @@ case OP_OpenWrite: {
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
-#endif /* local variables moved into u.ay */
+#endif /* local variables moved into u.az */
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
+ assert( p->bIsReader );
+ assert( pOp->opcode==OP_OpenRead || p->readOnly==0 );
if( p->expired ){
rc = SQLITE_ABORT;
break;
}
- u.ay.nField = 0;
- u.ay.pKeyInfo = 0;
- u.ay.p2 = pOp->p2;
- u.ay.iDb = pOp->p3;
- assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<u.ay.iDb))!=0 );
- u.ay.pDb = &db->aDb[u.ay.iDb];
- u.ay.pX = u.ay.pDb->pBt;
- assert( u.ay.pX!=0 );
+ u.az.nField = 0;
+ u.az.pKeyInfo = 0;
+ u.az.p2 = pOp->p2;
+ u.az.iDb = pOp->p3;
+ assert( u.az.iDb>=0 && u.az.iDb<db->nDb );
+ assert( (p->btreeMask & (((yDbMask)1)<<u.az.iDb))!=0 );
+ u.az.pDb = &db->aDb[u.az.iDb];
+ u.az.pX = u.az.pDb->pBt;
+ assert( u.az.pX!=0 );
if( pOp->opcode==OP_OpenWrite ){
- u.ay.wrFlag = 1;
- assert( sqlite3SchemaMutexHeld(db, u.ay.iDb, 0) );
- if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
+ u.az.wrFlag = 1;
+ assert( sqlite3SchemaMutexHeld(db, u.az.iDb, 0) );
+ if( u.az.pDb->pSchema->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = u.az.pDb->pSchema->file_format;
}
}else{
- u.ay.wrFlag = 0;
+ u.az.wrFlag = 0;
}
if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( u.ay.p2>0 );
- assert( u.ay.p2<=p->nMem );
- pIn2 = &aMem[u.ay.p2];
+ assert( u.az.p2>0 );
+ assert( u.az.p2<=(p->nMem-p->nCursor) );
+ pIn2 = &aMem[u.az.p2];
assert( memIsValid(pIn2) );
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite3VdbeMemIntegerify(pIn2);
- u.ay.p2 = (int)pIn2->u.i;
- /* The u.ay.p2 value always comes from a prior OP_CreateTable opcode and
- ** that opcode will always set the u.ay.p2 value to 2 or more or else fail.
+ u.az.p2 = (int)pIn2->u.i;
+ /* The u.az.p2 value always comes from a prior OP_CreateTable opcode and
+ ** that opcode will always set the u.az.p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- if( NEVER(u.ay.p2<2) ) {
+ if( NEVER(u.az.p2<2) ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
if( pOp->p4type==P4_KEYINFO ){
- u.ay.pKeyInfo = pOp->p4.pKeyInfo;
- u.ay.pKeyInfo->enc = ENC(p->db);
- u.ay.nField = u.ay.pKeyInfo->nField+1;
+ u.az.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.az.pKeyInfo->enc==ENC(db) );
+ assert( u.az.pKeyInfo->db==db );
+ u.az.nField = u.az.pKeyInfo->nField+u.az.pKeyInfo->nXField;
}else if( pOp->p4type==P4_INT32 ){
- u.ay.nField = pOp->p4.i;
+ u.az.nField = pOp->p4.i;
}
assert( pOp->p1>=0 );
- u.ay.pCur = allocateCursor(p, pOp->p1, u.ay.nField, u.ay.iDb, 1);
- if( u.ay.pCur==0 ) goto no_mem;
- u.ay.pCur->nullRow = 1;
- u.ay.pCur->isOrdered = 1;
- rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
- u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
+ assert( u.az.nField>=0 );
+ testcase( u.az.nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */
+ u.az.pCur = allocateCursor(p, pOp->p1, u.az.nField, u.az.iDb, 1);
+ if( u.az.pCur==0 ) goto no_mem;
+ u.az.pCur->nullRow = 1;
+ u.az.pCur->isOrdered = 1;
+ rc = sqlite3BtreeCursor(u.az.pX, u.az.p2, u.az.wrFlag, u.az.pKeyInfo, u.az.pCur->pCursor);
+ u.az.pCur->pKeyInfo = u.az.pKeyInfo;
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
- sqlite3BtreeCursorHints(u.ay.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
+ sqlite3BtreeCursorHints(u.az.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
/* Since it performs no memory allocation or IO, the only value that
** sqlite3BtreeCursor() may return is SQLITE_OK. */
assert( rc==SQLITE_OK );
- /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of
+ /* Set the VdbeCursor.isTable variable. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has
** since moved into the btree layer. */
- u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
- u.ay.pCur->isIndex = !u.ay.pCur->isTable;
+ u.az.pCur->isTable = pOp->p4type!=P4_KEYINFO;
break;
}
/* Opcode: OpenEphemeral P1 P2 * P4 P5
+** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if
@@ -68614,18 +69881,13 @@ case OP_OpenWrite: {
** if P4 is not 0. If P4 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
-** This opcode was once called OpenTemp. But that created
-** confusion because the term "temp table", might refer either
-** to a TEMP table at the SQL level, or to a table opened by
-** this opcode. Then this opcode was call OpenVirtual. But
-** that created confusion with the whole virtual-table idea.
-**
** The P5 parameter can be a mask of the BTREE_* flags defined
** in btree.h. These flags control aspects of the operation of
** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are
** added automatically.
*/
/* Opcode: OpenAutoindex P1 P2 * P4 *
+** Synopsis: nColumn=P2
**
** This opcode works the same as OP_OpenEphemeral. It has a
** different name to distinguish its use. Tables created using
@@ -68634,24 +69896,26 @@ case OP_OpenWrite: {
*/
case OP_OpenAutoindex:
case OP_OpenEphemeral: {
-#if 0 /* local variables moved into u.az */
+#if 0 /* local variables moved into u.ba */
VdbeCursor *pCx;
-#endif /* local variables moved into u.az */
+ KeyInfo *pKeyInfo;
+#endif /* local variables moved into u.ba */
+
static const int vfsFlags =
SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TRANSIENT_DB;
-
assert( pOp->p1>=0 );
- u.az.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.az.pCx==0 ) goto no_mem;
- u.az.pCx->nullRow = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.az.pCx->pBt,
+ assert( pOp->p2>=0 );
+ u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( u.ba.pCx==0 ) goto no_mem;
+ u.ba.pCx->nullRow = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ba.pCx->pBt,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(u.ba.pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -68659,49 +69923,51 @@ case OP_OpenEphemeral: {
** opening it. If a transient table is required, just use the
** automatically created table with root-page 1 (an BLOB_INTKEY table).
*/
- if( pOp->p4.pKeyInfo ){
+ if( (u.ba.pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+ rc = sqlite3BtreeCreateTable(u.ba.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
- u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.az.pCx->pKeyInfo->enc = ENC(p->db);
+ assert( u.ba.pKeyInfo->db==db );
+ assert( u.ba.pKeyInfo->enc==ENC(db) );
+ u.ba.pCx->pKeyInfo = u.ba.pKeyInfo;
+ rc = sqlite3BtreeCursor(u.ba.pCx->pBt, pgno, 1, u.ba.pKeyInfo, u.ba.pCx->pCursor);
}
- u.az.pCx->isTable = 0;
+ u.ba.pCx->isTable = 0;
}else{
- rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
- u.az.pCx->isTable = 1;
+ rc = sqlite3BtreeCursor(u.ba.pCx->pBt, MASTER_ROOT, 1, 0, u.ba.pCx->pCursor);
+ u.ba.pCx->isTable = 1;
}
}
- u.az.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
- u.az.pCx->isIndex = !u.az.pCx->isTable;
+ u.ba.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
-/* Opcode: SorterOpen P1 P2 * P4 *
+/* Opcode: SorterOpen P1 * * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
-#if 0 /* local variables moved into u.ba */
+#if 0 /* local variables moved into u.bb */
VdbeCursor *pCx;
-#endif /* local variables moved into u.ba */
+#endif /* local variables moved into u.bb */
- u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.ba.pCx==0 ) goto no_mem;
- u.ba.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- u.ba.pCx->pKeyInfo->enc = ENC(p->db);
- u.ba.pCx->isSorter = 1;
- rc = sqlite3VdbeSorterInit(db, u.ba.pCx);
+ assert( pOp->p1>=0 );
+ assert( pOp->p2>=0 );
+ u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( u.bb.pCx==0 ) goto no_mem;
+ u.bb.pCx->pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.bb.pCx->pKeyInfo->db==db );
+ assert( u.bb.pCx->pKeyInfo->enc==ENC(db) );
+ rc = sqlite3VdbeSorterInit(db, u.bb.pCx);
break;
}
/* Opcode: OpenPseudo P1 P2 P3 * P5
+** Synopsis: content in r[P2@P3]
**
** Open a new cursor that points to a fake table that contains a single
** row of data. The content of that one row in the content of memory
@@ -68718,18 +69984,18 @@ case OP_SorterOpen: {
** the pseudo-table.
*/
case OP_OpenPseudo: {
-#if 0 /* local variables moved into u.bb */
+#if 0 /* local variables moved into u.bc */
VdbeCursor *pCx;
-#endif /* local variables moved into u.bb */
+#endif /* local variables moved into u.bc */
assert( pOp->p1>=0 );
- u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
- if( u.bb.pCx==0 ) goto no_mem;
- u.bb.pCx->nullRow = 1;
- u.bb.pCx->pseudoTableReg = pOp->p2;
- u.bb.pCx->isTable = 1;
- u.bb.pCx->isIndex = 0;
- u.bb.pCx->multiPseudo = pOp->p5;
+ assert( pOp->p3>=0 );
+ u.bc.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
+ if( u.bc.pCx==0 ) goto no_mem;
+ u.bc.pCx->nullRow = 1;
+ u.bc.pCx->pseudoTableReg = pOp->p2;
+ u.bc.pCx->isTable = 1;
+ u.bc.pCx->multiPseudo = pOp->p5;
break;
}
@@ -68746,6 +70012,7 @@ case OP_Close: {
}
/* Opcode: SeekGe P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as the key. If cursor P1 refers
@@ -68759,6 +70026,7 @@ case OP_Close: {
** See also: Found, NotFound, Distinct, SeekLt, SeekGt, SeekLe
*/
/* Opcode: SeekGt P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
@@ -68772,6 +70040,7 @@ case OP_Close: {
** See also: Found, NotFound, Distinct, SeekLt, SeekGe, SeekLe
*/
/* Opcode: SeekLt P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
@@ -68785,6 +70054,7 @@ case OP_Close: {
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLe
*/
/* Opcode: SeekLe P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If cursor P1 refers to an SQL table (B-Tree that uses integer keys),
** use the value in register P3 as a key. If cursor P1 refers
@@ -68801,157 +70071,143 @@ case OP_SeekLt: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */
-#if 0 /* local variables moved into u.bc */
+#if 0 /* local variables moved into u.bd */
int res;
int oc;
VdbeCursor *pC;
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
-#endif /* local variables moved into u.bc */
+#endif /* local variables moved into u.bd */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2!=0 );
- u.bc.pC = p->apCsr[pOp->p1];
- assert( u.bc.pC!=0 );
- assert( u.bc.pC->pseudoTableReg==0 );
+ u.bd.pC = p->apCsr[pOp->p1];
+ assert( u.bd.pC!=0 );
+ assert( u.bd.pC->pseudoTableReg==0 );
assert( OP_SeekLe == OP_SeekLt+1 );
assert( OP_SeekGe == OP_SeekLt+2 );
assert( OP_SeekGt == OP_SeekLt+3 );
- assert( u.bc.pC->isOrdered );
- if( ALWAYS(u.bc.pC->pCursor!=0) ){
- u.bc.oc = pOp->opcode;
- u.bc.pC->nullRow = 0;
- if( u.bc.pC->isTable ){
- /* The input value in P3 might be of any type: integer, real, string,
- ** blob, or NULL. But it needs to be an integer before we can do
- ** the seek, so covert it. */
- pIn3 = &aMem[pOp->p3];
- applyNumericAffinity(pIn3);
- u.bc.iKey = sqlite3VdbeIntValue(pIn3);
- u.bc.pC->rowidIsValid = 0;
-
- /* If the P3 value could not be converted into an integer without
- ** loss of information, then special processing is required... */
- if( (pIn3->flags & MEM_Int)==0 ){
- if( (pIn3->flags & MEM_Real)==0 ){
- /* If the P3 value cannot be converted into any kind of a number,
- ** then the seek is not possible, so jump to P2 */
- pc = pOp->p2 - 1;
- break;
- }
- /* If we reach this point, then the P3 value must be a floating
- ** point number. */
- assert( (pIn3->flags & MEM_Real)!=0 );
-
- if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
- /* The P3 value is too large in magnitude to be expressed as an
- ** integer. */
- u.bc.res = 1;
- if( pIn3->r<0 ){
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }else{
- if( u.bc.oc<=OP_SeekLe ){ assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- if( u.bc.res ){
- pc = pOp->p2 - 1;
- }
- break;
- }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
- /* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
- }else{
- /* Use the floor() function to convert real->int */
- assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
- if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
- }
+ assert( u.bd.pC->isOrdered );
+ assert( u.bd.pC->pCursor!=0 );
+ u.bd.oc = pOp->opcode;
+ u.bd.pC->nullRow = 0;
+ if( u.bd.pC->isTable ){
+ /* The input value in P3 might be of any type: integer, real, string,
+ ** blob, or NULL. But it needs to be an integer before we can do
+ ** the seek, so covert it. */
+ pIn3 = &aMem[pOp->p3];
+ applyNumericAffinity(pIn3);
+ u.bd.iKey = sqlite3VdbeIntValue(pIn3);
+ u.bd.pC->rowidIsValid = 0;
+
+ /* If the P3 value could not be converted into an integer without
+ ** loss of information, then special processing is required... */
+ if( (pIn3->flags & MEM_Int)==0 ){
+ if( (pIn3->flags & MEM_Real)==0 ){
+ /* If the P3 value cannot be converted into any kind of a number,
+ ** then the seek is not possible, so jump to P2 */
+ pc = pOp->p2 - 1;
+ break;
}
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
+
+ /* If the approximation u.bd.iKey is larger than the actual real search
+ ** term, substitute >= for > and < for <=. e.g. if the search term
+ ** is 4.9 and the integer approximation 5:
+ **
+ ** (x > 4.9) -> (x >= 5)
+ ** (x <= 4.9) -> (x < 5)
+ */
+ if( pIn3->r<(double)u.bd.iKey ){
+ assert( OP_SeekGe==(OP_SeekGt-1) );
+ assert( OP_SeekLt==(OP_SeekLe-1) );
+ assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
+ if( (u.bd.oc & 0x0001)==(OP_SeekGt & 0x0001) ) u.bd.oc--;
}
- if( u.bc.res==0 ){
- u.bc.pC->rowidIsValid = 1;
- u.bc.pC->lastRowid = u.bc.iKey;
+
+ /* If the approximation u.bd.iKey is smaller than the actual real search
+ ** term, substitute <= for < and > for >=. */
+ else if( pIn3->r>(double)u.bd.iKey ){
+ assert( OP_SeekLe==(OP_SeekLt+1) );
+ assert( OP_SeekGt==(OP_SeekGe+1) );
+ assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
+ if( (u.bd.oc & 0x0001)==(OP_SeekLt & 0x0001) ) u.bd.oc++;
}
- }else{
- u.bc.nField = pOp->p4.i;
- assert( pOp->p4type==P4_INT32 );
- assert( u.bc.nField>0 );
- u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
- u.bc.r.nField = (u16)u.bc.nField;
-
- /* The next line of code computes as follows, only faster:
- ** if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
- ** u.bc.r.flags = UNPACKED_INCRKEY;
- ** }else{
- ** u.bc.r.flags = 0;
- ** }
- */
- u.bc.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bc.oc - OP_SeekLt)));
- assert( u.bc.oc!=OP_SeekGt || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekLe || u.bc.r.flags==UNPACKED_INCRKEY );
- assert( u.bc.oc!=OP_SeekGe || u.bc.r.flags==0 );
- assert( u.bc.oc!=OP_SeekLt || u.bc.r.flags==0 );
+ }
+ rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( u.bd.res==0 ){
+ u.bd.pC->rowidIsValid = 1;
+ u.bd.pC->lastRowid = u.bd.iKey;
+ }
+ }else{
+ u.bd.nField = pOp->p4.i;
+ assert( pOp->p4type==P4_INT32 );
+ assert( u.bd.nField>0 );
+ u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
+ u.bd.r.nField = (u16)u.bd.nField;
+
+ /* The next line of code computes as follows, only faster:
+ ** if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){
+ ** u.bd.r.flags = UNPACKED_INCRKEY;
+ ** }else{
+ ** u.bd.r.flags = 0;
+ ** }
+ */
+ u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt)));
+ assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY );
+ assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY );
+ assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 );
+ assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 );
- u.bc.r.aMem = &aMem[pOp->p3];
+ u.bd.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bc.r.nField; i++) assert( memIsValid(&u.bc.r.aMem[i]) ); }
+ { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
#endif
- ExpandBlob(u.bc.r.aMem);
- rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- u.bc.pC->rowidIsValid = 0;
+ ExpandBlob(u.bd.r.aMem);
+ rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
}
- u.bc.pC->deferredMoveto = 0;
- u.bc.pC->cacheStatus = CACHE_STALE;
+ u.bd.pC->rowidIsValid = 0;
+ }
+ u.bd.pC->deferredMoveto = 0;
+ u.bd.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
- sqlite3_search_count++;
+ sqlite3_search_count++;
#endif
- if( u.bc.oc>=OP_SeekGe ){ assert( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt );
- if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- u.bc.res = 0;
- }
+ if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
+ if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){
+ rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ u.bd.pC->rowidIsValid = 0;
}else{
- assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
- if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bc.pC->rowidIsValid = 0;
- }else{
- /* u.bc.res might be negative because the table is empty. Check to
- ** see if this is the case.
- */
- u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
- }
- }
- assert( pOp->p2>0 );
- if( u.bc.res ){
- pc = pOp->p2 - 1;
+ u.bd.res = 0;
}
}else{
- /* This happens when attempting to open the sqlite3_master table
- ** for read access returns SQLITE_EMPTY. In this case always
- ** take the jump (since there are no records in the table).
- */
+ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
+ if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){
+ rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res);
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ u.bd.pC->rowidIsValid = 0;
+ }else{
+ /* u.bd.res might be negative because the table is empty. Check to
+ ** see if this is the case.
+ */
+ u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor);
+ }
+ }
+ assert( pOp->p2>0 );
+ if( u.bd.res ){
pc = pOp->p2 - 1;
}
break;
}
/* Opcode: Seek P1 P2 * * *
+** Synopsis: intkey=r[P2]
**
** P1 is an open table cursor and P2 is a rowid integer. Arrange
** for P1 to move so that it points to the rowid given by P2.
@@ -68961,26 +70217,26 @@ case OP_SeekGt: { /* jump, in3 */
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
-#if 0 /* local variables moved into u.bd */
+#if 0 /* local variables moved into u.be */
VdbeCursor *pC;
-#endif /* local variables moved into u.bd */
+#endif /* local variables moved into u.be */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bd.pC = p->apCsr[pOp->p1];
- assert( u.bd.pC!=0 );
- if( ALWAYS(u.bd.pC->pCursor!=0) ){
- assert( u.bd.pC->isTable );
- u.bd.pC->nullRow = 0;
- pIn2 = &aMem[pOp->p2];
- u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- u.bd.pC->rowidIsValid = 0;
- u.bd.pC->deferredMoveto = 1;
- }
+ u.be.pC = p->apCsr[pOp->p1];
+ assert( u.be.pC!=0 );
+ assert( u.be.pC->pCursor!=0 );
+ assert( u.be.pC->isTable );
+ u.be.pC->nullRow = 0;
+ pIn2 = &aMem[pOp->p2];
+ u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+ u.be.pC->rowidIsValid = 0;
+ u.be.pC->deferredMoveto = 1;
break;
}
/* Opcode: Found P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
** P4>0 then register P3 is the first of P4 registers that form an unpacked
@@ -68989,8 +70245,11 @@ case OP_Seek: { /* in2 */
** Cursor P1 is on an index btree. If the record identified by P3 and P4
** is a prefix of any entry in P1 then a jump is made to P2 and
** P1 is left pointing at the matching entry.
+**
+** See also: NotFound, NoConflict, NotExists. SeekGe
*/
/* Opcode: NotFound P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
**
** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
** P4>0 then register P3 is the first of P4 registers that form an unpacked
@@ -69002,173 +70261,122 @@ case OP_Seek: { /* in2 */
** falls through to the next instruction and P1 is left pointing at the
** matching entry.
**
-** See also: Found, NotExists, IsUnique
+** See also: Found, NotExists, NoConflict
*/
+/* Opcode: NoConflict P1 P2 P3 P4 *
+** Synopsis: key=r[P3@P4]
+**
+** If P4==0 then register P3 holds a blob constructed by MakeRecord. If
+** P4>0 then register P3 is the first of P4 registers that form an unpacked
+** record.
+**
+** Cursor P1 is on an index btree. If the record identified by P3 and P4
+** contains any NULL value, jump immediately to P2. If all terms of the
+** record are not-NULL then a check is done to determine if any row in the
+** P1 index btree has a matching key prefix. If there are no matches, jump
+** immediately to P2. If there is a match, fall through and leave the P1
+** cursor pointing to the matching row.
+**
+** This opcode is similar to OP_NotFound with the exceptions that the
+** branch is always taken if any part of the search key input is NULL.
+**
+** See also: NotFound, Found, NotExists
+*/
+case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.be */
+#if 0 /* local variables moved into u.bf */
int alreadyExists;
+ int ii;
VdbeCursor *pC;
int res;
char *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
-#endif /* local variables moved into u.be */
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
+#endif /* local variables moved into u.bf */
#ifdef SQLITE_TEST
- sqlite3_found_count++;
+ if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
#endif
- u.be.alreadyExists = 0;
+ u.bf.alreadyExists = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p4type==P4_INT32 );
- u.be.pC = p->apCsr[pOp->p1];
- assert( u.be.pC!=0 );
+ u.bf.pC = p->apCsr[pOp->p1];
+ assert( u.bf.pC!=0 );
pIn3 = &aMem[pOp->p3];
- if( ALWAYS(u.be.pC->pCursor!=0) ){
-
- assert( u.be.pC->isTable==0 );
- if( pOp->p4.i>0 ){
- u.be.r.pKeyInfo = u.be.pC->pKeyInfo;
- u.be.r.nField = (u16)pOp->p4.i;
- u.be.r.aMem = pIn3;
+ assert( u.bf.pC->pCursor!=0 );
+ assert( u.bf.pC->isTable==0 );
+ if( pOp->p4.i>0 ){
+ u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo;
+ u.bf.r.nField = (u16)pOp->p4.i;
+ u.bf.r.aMem = pIn3;
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.be.r.nField; i++) assert( memIsValid(&u.be.r.aMem[i]) ); }
-#endif
- u.be.r.flags = UNPACKED_PREFIX_MATCH;
- u.be.pIdxKey = &u.be.r;
- }else{
- u.be.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- u.be.pC->pKeyInfo, u.be.aTempRec, sizeof(u.be.aTempRec), &u.be.pFree
- );
- if( u.be.pIdxKey==0 ) goto no_mem;
- assert( pIn3->flags & MEM_Blob );
- assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
- sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, u.be.pIdxKey);
- u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
- }
- rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
- if( pOp->p4.i==0 ){
- sqlite3DbFree(db, u.be.pFree);
+ {
+ int i;
+ for(i=0; i<u.bf.r.nField; i++){
+ assert( memIsValid(&u.bf.r.aMem[i]) );
+ if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]);
+ }
}
- if( rc!=SQLITE_OK ){
- break;
+#endif
+ u.bf.r.flags = UNPACKED_PREFIX_MATCH;
+ u.bf.pIdxKey = &u.bf.r;
+ }else{
+ u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+ u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree
+ );
+ if( u.bf.pIdxKey==0 ) goto no_mem;
+ assert( pIn3->flags & MEM_Blob );
+ assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
+ sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey);
+ u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
+ }
+ if( pOp->opcode==OP_NoConflict ){
+ /* For the OP_NoConflict opcode, take the jump if any of the
+ ** input fields are NULL, since any key with a NULL will not
+ ** conflict */
+ for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){
+ if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){
+ pc = pOp->p2 - 1;
+ break;
+ }
}
- u.be.alreadyExists = (u.be.res==0);
- u.be.pC->deferredMoveto = 0;
- u.be.pC->cacheStatus = CACHE_STALE;
}
- if( pOp->opcode==OP_Found ){
- if( u.be.alreadyExists ) pc = pOp->p2 - 1;
- }else{
- if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
+ rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res);
+ if( pOp->p4.i==0 ){
+ sqlite3DbFree(db, u.bf.pFree);
}
- break;
-}
-
-/* Opcode: IsUnique P1 P2 P3 P4 *
-**
-** Cursor P1 is open on an index b-tree - that is to say, a btree which
-** no data and where the key are records generated by OP_MakeRecord with
-** the list field being the integer ROWID of the entry that the index
-** entry refers to.
-**
-** The P3 register contains an integer record number. Call this record
-** number R. Register P4 is the first in a set of N contiguous registers
-** that make up an unpacked index key that can be used with cursor P1.
-** The value of N can be inferred from the cursor. N includes the rowid
-** value appended to the end of the index record. This rowid value may
-** or may not be the same as R.
-**
-** If any of the N registers beginning with register P4 contains a NULL
-** value, jump immediately to P2.
-**
-** Otherwise, this instruction checks if cursor P1 contains an entry
-** where the first (N-1) fields match but the rowid value at the end
-** of the index entry is not R. If there is no such entry, control jumps
-** to instruction P2. Otherwise, the rowid of the conflicting index
-** entry is copied to register P3 and control falls through to the next
-** instruction.
-**
-** See also: NotFound, NotExists, Found
-*/
-case OP_IsUnique: { /* jump, in3 */
-#if 0 /* local variables moved into u.bf */
- u16 ii;
- VdbeCursor *pCx;
- BtCursor *pCrsr;
- u16 nField;
- Mem *aMx;
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
-#endif /* local variables moved into u.bf */
-
- pIn3 = &aMem[pOp->p3];
- u.bf.aMx = &aMem[pOp->p4.i];
- /* Assert that the values of parameters P1 and P4 are in range. */
- assert( pOp->p4type==P4_INT32 );
- assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
-
- /* Find the index cursor. */
- u.bf.pCx = p->apCsr[pOp->p1];
- assert( u.bf.pCx->deferredMoveto==0 );
- u.bf.pCx->seekResult = 0;
- u.bf.pCx->cacheStatus = CACHE_STALE;
- u.bf.pCrsr = u.bf.pCx->pCursor;
-
- /* If any of the values are NULL, take the jump. */
- u.bf.nField = u.bf.pCx->pKeyInfo->nField;
- for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){
- if( u.bf.aMx[u.bf.ii].flags & MEM_Null ){
- pc = pOp->p2 - 1;
- u.bf.pCrsr = 0;
- break;
- }
+ if( rc!=SQLITE_OK ){
+ break;
}
- assert( (u.bf.aMx[u.bf.nField].flags & MEM_Null)==0 );
-
- if( u.bf.pCrsr!=0 ){
- /* Populate the index search key. */
- u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
- u.bf.r.nField = u.bf.nField + 1;
- u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
- u.bf.r.aMem = u.bf.aMx;
-#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bf.r.nField; i++) assert( memIsValid(&u.bf.r.aMem[i]) ); }
-#endif
-
- /* Extract the value of u.bf.R from register P3. */
- sqlite3VdbeMemIntegerify(pIn3);
- u.bf.R = pIn3->u.i;
-
- /* Search the B-Tree index. If no conflicting record is found, jump
- ** to P2. Otherwise, copy the rowid of the conflicting record to
- ** register P3 and fall through to the next instruction. */
- rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
- if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
- pc = pOp->p2 - 1;
- }else{
- pIn3->u.i = u.bf.r.rowid;
- }
+ u.bf.pC->seekResult = u.bf.res;
+ u.bf.alreadyExists = (u.bf.res==0);
+ u.bf.pC->nullRow = 1-u.bf.alreadyExists;
+ u.bf.pC->deferredMoveto = 0;
+ u.bf.pC->cacheStatus = CACHE_STALE;
+ if( pOp->opcode==OP_Found ){
+ if( u.bf.alreadyExists ) pc = pOp->p2 - 1;
+ }else{
+ if( !u.bf.alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
/* Opcode: NotExists P1 P2 P3 * *
+** Synopsis: intkey=r[P3]
**
-** Use the content of register P3 as an integer key. If a record
-** with that key does not exist in table of P1, then jump to P2.
-** If the record does exist, then fall through. The cursor is left
-** pointing to the record if it exists.
+** P1 is the index of a cursor open on an SQL table btree (with integer
+** keys). P3 is an integer rowid. If P1 does not contain a record with
+** rowid P3 then jump immediately to P2. If P1 does contain a record
+** with rowid P3 then leave the cursor pointing at that record and fall
+** through to the next instruction.
**
-** The difference between this operation and NotFound is that this
-** operation assumes the key is an integer and that P1 is a table whereas
-** NotFound assumes key is a blob constructed from MakeRecord and
-** P1 is an index.
+** The OP_NotFound opcode performs the same operation on index btrees
+** (with arbitrary multi-value keys).
**
-** See also: Found, NotFound, IsUnique
+** See also: Found, NotFound, NoConflict
*/
case OP_NotExists: { /* jump, in3 */
#if 0 /* local variables moved into u.bg */
@@ -69186,32 +70394,25 @@ case OP_NotExists: { /* jump, in3 */
assert( u.bg.pC->isTable );
assert( u.bg.pC->pseudoTableReg==0 );
u.bg.pCrsr = u.bg.pC->pCursor;
- if( ALWAYS(u.bg.pCrsr!=0) ){
- u.bg.res = 0;
- u.bg.iKey = pIn3->u.i;
- rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
- u.bg.pC->lastRowid = pIn3->u.i;
- u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
- u.bg.pC->nullRow = 0;
- u.bg.pC->cacheStatus = CACHE_STALE;
- u.bg.pC->deferredMoveto = 0;
- if( u.bg.res!=0 ){
- pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
- }
- u.bg.pC->seekResult = u.bg.res;
- }else{
- /* This happens when an attempt to open a read cursor on the
- ** sqlite_master table returns SQLITE_EMPTY.
- */
+ assert( u.bg.pCrsr!=0 );
+ u.bg.res = 0;
+ u.bg.iKey = pIn3->u.i;
+ rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
+ u.bg.pC->lastRowid = pIn3->u.i;
+ u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
+ u.bg.pC->nullRow = 0;
+ u.bg.pC->cacheStatus = CACHE_STALE;
+ u.bg.pC->deferredMoveto = 0;
+ if( u.bg.res!=0 ){
pc = pOp->p2 - 1;
assert( u.bg.pC->rowidIsValid==0 );
- u.bg.pC->seekResult = 0;
}
+ u.bg.pC->seekResult = u.bg.res;
break;
}
/* Opcode: Sequence P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Find the next available sequence number for cursor P1.
** Write the sequence number into register P2.
@@ -69227,6 +70428,7 @@ case OP_Sequence: { /* out2-prerelease */
/* Opcode: NewRowid P1 P2 P3 * *
+** Synopsis: r[P2]=rowid
**
** Get a new integer record number (a.k.a "rowid") used as the key to a table.
** The record number is not previously used as a key in the database
@@ -69315,7 +70517,7 @@ case OP_NewRowid: { /* out2-prerelease */
u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
}else{
/* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=p->nMem );
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
u.bh.pMem = &aMem[pOp->p3];
memAboutToChange(p, u.bh.pMem);
}
@@ -69378,6 +70580,7 @@ case OP_NewRowid: { /* out2-prerelease */
}
/* Opcode: Insert P1 P2 P3 P4 P5
+** Synopsis: intkey=r[P3] data=r[P2]
**
** Write an entry into the table of cursor P1. A new entry is
** created if it doesn't already exist or the data for an existing
@@ -69417,6 +70620,7 @@ case OP_NewRowid: { /* out2-prerelease */
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
+** Synopsis: intkey=P3 data=r[P2]
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
@@ -69473,7 +70677,7 @@ case OP_InsertInt: {
sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
- pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
+ (pOp->p5 & OPFLAG_APPEND)!=0, u.bi.seekResult
);
u.bi.pC->rowidIsValid = 0;
u.bi.pC->deferredMoveto = 0;
@@ -69517,20 +70721,11 @@ case OP_Delete: {
VdbeCursor *pC;
#endif /* local variables moved into u.bj */
- u.bj.iKey = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bj.pC = p->apCsr[pOp->p1];
assert( u.bj.pC!=0 );
assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
-
- /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
- ** row being deleted.
- */
- if( db->xUpdateCallback && pOp->p4.z ){
- assert( u.bj.pC->isTable );
- assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- u.bj.iKey = u.bj.pC->lastRowid;
- }
+ u.bj.iKey = u.bj.pC->lastRowid; /* Only used for the update hook */
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
** OP_Column on the same table without any intervening operations that
@@ -69548,10 +70743,9 @@ case OP_Delete: {
u.bj.pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[u.bj.pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
+ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && u.bj.pC->isTable ){
+ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
+ db->aDb[u.bj.pC->iDb].zName, pOp->p4.z, u.bj.iKey);
assert( u.bj.pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
@@ -69570,23 +70764,34 @@ case OP_ResetCount: {
break;
}
-/* Opcode: SorterCompare P1 P2 P3
+/* Opcode: SorterCompare P1 P2 P3 P4
+** Synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2
+**
+** P1 is a sorter cursor. This instruction compares a prefix of the
+** the record blob in register P3 against a prefix of the entry that
+** the sorter cursor currently points to. The final P4 fields of both
+** the P3 and sorter record are ignored.
+**
+** If either P3 or the sorter contains a NULL in one of their significant
+** fields (not counting the P4 fields at the end which are ignored) then
+** the comparison is assumed to be equal.
**
-** P1 is a sorter cursor. This instruction compares the record blob in
-** register P3 with the entry that the sorter cursor currently points to.
-** If, excluding the rowid fields at the end, the two records are a match,
-** fall through to the next instruction. Otherwise, jump to instruction P2.
+** Fall through to next instruction if the two records compare equal to
+** each other. Jump to P2 if they are different.
*/
case OP_SorterCompare: {
#if 0 /* local variables moved into u.bk */
VdbeCursor *pC;
int res;
+ int nIgnore;
#endif /* local variables moved into u.bk */
u.bk.pC = p->apCsr[pOp->p1];
assert( isSorter(u.bk.pC) );
+ assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
- rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, &u.bk.res);
+ u.bk.nIgnore = pOp->p4.i;
+ rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, u.bk.nIgnore, &u.bk.res);
if( u.bk.res ){
pc = pOp->p2-1;
}
@@ -69594,6 +70799,7 @@ case OP_SorterCompare: {
};
/* Opcode: SorterData P1 P2 * * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the current sorter data for sorter cursor P1.
*/
@@ -69604,12 +70810,13 @@ case OP_SorterData: {
pOut = &aMem[pOp->p2];
u.bl.pC = p->apCsr[pOp->p1];
- assert( u.bl.pC->isSorter );
+ assert( isSorter(u.bl.pC) );
rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
break;
}
/* Opcode: RowData P1 P2 * * *
+** Synopsis: r[P2]=data
**
** Write into register P2 the complete row data for cursor P1.
** There is no interpretation of the data.
@@ -69620,6 +70827,7 @@ case OP_SorterData: {
** of a real table, not a pseudo-table.
*/
/* Opcode: RowKey P1 P2 * * *
+** Synopsis: r[P2]=key
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.
@@ -69644,9 +70852,9 @@ case OP_RowData: {
/* Note that RowKey and RowData are really exactly the same instruction */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bm.pC = p->apCsr[pOp->p1];
- assert( u.bm.pC->isSorter==0 );
+ assert( isSorter(u.bm.pC)==0 );
assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData );
- assert( u.bm.pC->isIndex || pOp->opcode==OP_RowData );
+ assert( u.bm.pC->isTable==0 || pOp->opcode==OP_RowData );
assert( u.bm.pC!=0 );
assert( u.bm.pC->nullRow==0 );
assert( u.bm.pC->pseudoTableReg==0 );
@@ -69663,7 +70871,7 @@ case OP_RowData: {
rc = sqlite3VdbeCursorMoveto(u.bm.pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
- if( u.bm.pC->isIndex ){
+ if( u.bm.pC->isTable==0 ){
assert( !u.bm.pC->isTable );
VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
@@ -69683,17 +70891,19 @@ case OP_RowData: {
}
pOut->n = u.bm.n;
MemSetTypeFlag(pOut, MEM_Blob);
- if( u.bm.pC->isIndex ){
+ if( u.bm.pC->isTable==0 ){
rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
}else{
rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
+ REGISTER_TRACE(pOp->p2, pOut);
break;
}
/* Opcode: Rowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
@@ -69725,7 +70935,7 @@ case OP_Rowid: { /* out2-prerelease */
u.bn.pModule = u.bn.pVtab->pModule;
assert( u.bn.pModule->xRowid );
rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
- importVtabErrMsg(p, u.bn.pVtab);
+ sqlite3VtabImportErrmsg(p, u.bn.pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( u.bn.pC->pCursor!=0 );
@@ -69758,6 +70968,7 @@ case OP_NullRow: {
assert( u.bo.pC!=0 );
u.bo.pC->nullRow = 1;
u.bo.pC->rowidIsValid = 0;
+ u.bo.pC->cacheStatus = CACHE_STALE;
assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor );
if( u.bo.pC->pCursor ){
sqlite3BtreeClearCursor(u.bo.pC->pCursor);
@@ -69785,9 +70996,8 @@ case OP_Last: { /* jump */
assert( u.bp.pC!=0 );
u.bp.pCrsr = u.bp.pC->pCursor;
u.bp.res = 0;
- if( ALWAYS(u.bp.pCrsr!=0) ){
- rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
- }
+ assert( u.bp.pCrsr!=0 );
+ rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
u.bp.pC->nullRow = (u8)u.bp.res;
u.bp.pC->deferredMoveto = 0;
u.bp.pC->rowidIsValid = 0;
@@ -69817,7 +71027,7 @@ case OP_Sort: { /* jump */
sqlite3_sort_count++;
sqlite3_search_count--;
#endif
- p->aCounter[SQLITE_STMTSTATUS_SORT-1]++;
+ p->aCounter[SQLITE_STMTSTATUS_SORT]++;
/* Fall through into OP_Rewind */
}
/* Opcode: Rewind P1 P2 * * *
@@ -69838,7 +71048,7 @@ case OP_Rewind: { /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bq.pC = p->apCsr[pOp->p1];
assert( u.bq.pC!=0 );
- assert( u.bq.pC->isSorter==(pOp->opcode==OP_SorterSort) );
+ assert( isSorter(u.bq.pC)==(pOp->opcode==OP_SorterSort) );
u.bq.res = 1;
if( isSorter(u.bq.pC) ){
rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res);
@@ -69846,7 +71056,6 @@ case OP_Rewind: { /* jump */
u.bq.pCrsr = u.bq.pC->pCursor;
assert( u.bq.pCrsr );
rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res);
- u.bq.pC->atFirst = u.bq.res==0 ?1:0;
u.bq.pC->deferredMoveto = 0;
u.bq.pC->cacheStatus = CACHE_STALE;
u.bq.pC->rowidIsValid = 0;
@@ -69859,14 +71068,15 @@ case OP_Rewind: { /* jump */
break;
}
-/* Opcode: Next P1 P2 * P4 P5
+/* Opcode: Next P1 P2 * * P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
** to the following instruction. But if the cursor advance was successful,
** jump immediately to P2.
**
-** The P1 cursor must be for a real table, not a pseudo-table.
+** The P1 cursor must be for a real table, not a pseudo-table. P1 must have
+** been opened prior to this opcode or the program will segfault.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreeNext().
@@ -69874,7 +71084,12 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
-** See also: Prev
+** See also: Prev, NextIfOpen
+*/
+/* Opcode: NextIfOpen P1 P2 * * P5
+**
+** This opcode works just like OP_Next except that if cursor P1 is not
+** open it behaves a no-op.
*/
/* Opcode: Prev P1 P2 * * P5
**
@@ -69883,7 +71098,8 @@ case OP_Rewind: { /* jump */
** to the following instruction. But if the cursor backup was successful,
** jump immediately to P2.
**
-** The P1 cursor must be for a real table, not a pseudo-table.
+** The P1 cursor must be for a real table, not a pseudo-table. If P1 is
+** not open then the behavior is undefined.
**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreePrevious().
@@ -69891,47 +71107,56 @@ case OP_Rewind: { /* jump */
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
-case OP_SorterNext: /* jump */
-case OP_Prev: /* jump */
-case OP_Next: { /* jump */
+/* Opcode: PrevIfOpen P1 P2 * * P5
+**
+** This opcode works just like OP_Prev except that if cursor P1 is not
+** open it behaves a no-op.
+*/
+case OP_SorterNext: { /* jump */
#if 0 /* local variables moved into u.br */
VdbeCursor *pC;
int res;
#endif /* local variables moved into u.br */
- CHECK_FOR_INTERRUPT;
+ u.br.pC = p->apCsr[pOp->p1];
+ assert( isSorter(u.br.pC) );
+ rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
+ goto next_tail;
+case OP_PrevIfOpen: /* jump */
+case OP_NextIfOpen: /* jump */
+ if( p->apCsr[pOp->p1]==0 ) break;
+ /* Fall through */
+case OP_Prev: /* jump */
+case OP_Next: /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( pOp->p5<=ArraySize(p->aCounter) );
+ assert( pOp->p5<ArraySize(p->aCounter) );
u.br.pC = p->apCsr[pOp->p1];
- if( u.br.pC==0 ){
- break; /* See ticket #2273 */
- }
- assert( u.br.pC->isSorter==(pOp->opcode==OP_SorterNext) );
- if( isSorter(u.br.pC) ){
- assert( pOp->opcode==OP_SorterNext );
- rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
- }else{
- u.br.res = 1;
- assert( u.br.pC->deferredMoveto==0 );
- assert( u.br.pC->pCursor );
- assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
- assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
- rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
- }
- u.br.pC->nullRow = (u8)u.br.res;
+ assert( u.br.pC!=0 );
+ assert( u.br.pC->deferredMoveto==0 );
+ assert( u.br.pC->pCursor );
+ assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
+ assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+ assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
+ assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
+ rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
+next_tail:
u.br.pC->cacheStatus = CACHE_STALE;
if( u.br.res==0 ){
+ u.br.pC->nullRow = 0;
pc = pOp->p2 - 1;
- if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
+ p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
+ }else{
+ u.br.pC->nullRow = 1;
}
u.br.pC->rowidIsValid = 0;
- break;
+ goto check_for_interrupt;
}
/* Opcode: IdxInsert P1 P2 P3 * P5
+** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
@@ -69955,31 +71180,32 @@ case OP_IdxInsert: { /* in2 */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bs.pC = p->apCsr[pOp->p1];
assert( u.bs.pC!=0 );
- assert( u.bs.pC->isSorter==(pOp->opcode==OP_SorterInsert) );
+ assert( isSorter(u.bs.pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
u.bs.pCrsr = u.bs.pC->pCursor;
- if( ALWAYS(u.bs.pCrsr!=0) ){
- assert( u.bs.pC->isTable==0 );
- rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- if( isSorter(u.bs.pC) ){
- rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
- }else{
- u.bs.nKey = pIn2->n;
- u.bs.zKey = pIn2->z;
- rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
- );
- assert( u.bs.pC->deferredMoveto==0 );
- u.bs.pC->cacheStatus = CACHE_STALE;
- }
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ assert( u.bs.pCrsr!=0 );
+ assert( u.bs.pC->isTable==0 );
+ rc = ExpandBlob(pIn2);
+ if( rc==SQLITE_OK ){
+ if( isSorter(u.bs.pC) ){
+ rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
+ }else{
+ u.bs.nKey = pIn2->n;
+ u.bs.zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
+ );
+ assert( u.bs.pC->deferredMoveto==0 );
+ u.bs.pC->cacheStatus = CACHE_STALE;
}
}
break;
}
/* Opcode: IdxDelete P1 P2 P3 * *
+** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
@@ -69994,30 +71220,31 @@ case OP_IdxDelete: {
#endif /* local variables moved into u.bt */
assert( pOp->p3>0 );
- assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
+ assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
u.bt.pC = p->apCsr[pOp->p1];
assert( u.bt.pC!=0 );
u.bt.pCrsr = u.bt.pC->pCursor;
- if( ALWAYS(u.bt.pCrsr!=0) ){
- u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
- u.bt.r.nField = (u16)pOp->p3;
- u.bt.r.flags = 0;
- u.bt.r.aMem = &aMem[pOp->p2];
+ assert( u.bt.pCrsr!=0 );
+ assert( pOp->p5==0 );
+ u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
+ u.bt.r.nField = (u16)pOp->p3;
+ u.bt.r.flags = UNPACKED_PREFIX_MATCH;
+ u.bt.r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
+ { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
#endif
- rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
- if( rc==SQLITE_OK && u.bt.res==0 ){
- rc = sqlite3BtreeDelete(u.bt.pCrsr);
- }
- assert( u.bt.pC->deferredMoveto==0 );
- u.bt.pC->cacheStatus = CACHE_STALE;
+ rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
+ if( rc==SQLITE_OK && u.bt.res==0 ){
+ rc = sqlite3BtreeDelete(u.bt.pCrsr);
}
+ assert( u.bt.pC->deferredMoveto==0 );
+ u.bt.pC->cacheStatus = CACHE_STALE;
break;
}
/* Opcode: IdxRowid P1 P2 * * *
+** Synopsis: r[P2]=rowid
**
** Write into register P2 an integer which is the last entry in the record at
** the end of the index key pointed to by cursor P1. This integer should be
@@ -70036,25 +71263,25 @@ case OP_IdxRowid: { /* out2-prerelease */
u.bu.pC = p->apCsr[pOp->p1];
assert( u.bu.pC!=0 );
u.bu.pCrsr = u.bu.pC->pCursor;
+ assert( u.bu.pCrsr!=0 );
pOut->flags = MEM_Null;
- if( ALWAYS(u.bu.pCrsr!=0) ){
- rc = sqlite3VdbeCursorMoveto(u.bu.pC);
- if( NEVER(rc) ) goto abort_due_to_error;
- assert( u.bu.pC->deferredMoveto==0 );
- assert( u.bu.pC->isTable==0 );
- if( !u.bu.pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- pOut->u.i = u.bu.rowid;
- pOut->flags = MEM_Int;
+ rc = sqlite3VdbeCursorMoveto(u.bu.pC);
+ if( NEVER(rc) ) goto abort_due_to_error;
+ assert( u.bu.pC->deferredMoveto==0 );
+ assert( u.bu.pC->isTable==0 );
+ if( !u.bu.pC->nullRow ){
+ rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
}
+ pOut->u.i = u.bu.rowid;
+ pOut->flags = MEM_Int;
}
break;
}
/* Opcode: IdxGE P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index
@@ -70069,6 +71296,7 @@ case OP_IdxRowid: { /* out2-prerelease */
** the result is false whereas it would be true with IdxGT.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
** key that omits the ROWID. Compare this key value against the index
@@ -70092,31 +71320,30 @@ case OP_IdxGE: { /* jump */
u.bv.pC = p->apCsr[pOp->p1];
assert( u.bv.pC!=0 );
assert( u.bv.pC->isOrdered );
- if( ALWAYS(u.bv.pC->pCursor!=0) ){
- assert( u.bv.pC->deferredMoveto==0 );
- assert( pOp->p5==0 || pOp->p5==1 );
- assert( pOp->p4type==P4_INT32 );
- u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
- u.bv.r.nField = (u16)pOp->p4.i;
- if( pOp->p5 ){
- u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
- }else{
- u.bv.r.flags = UNPACKED_PREFIX_MATCH;
- }
- u.bv.r.aMem = &aMem[pOp->p3];
+ assert( u.bv.pC->pCursor!=0);
+ assert( u.bv.pC->deferredMoveto==0 );
+ assert( pOp->p5==0 || pOp->p5==1 );
+ assert( pOp->p4type==P4_INT32 );
+ u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
+ u.bv.r.nField = (u16)pOp->p4.i;
+ if( pOp->p5 ){
+ u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
+ }else{
+ u.bv.r.flags = UNPACKED_PREFIX_MATCH;
+ }
+ u.bv.r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
+ { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
#endif
- rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
- if( pOp->opcode==OP_IdxLT ){
- u.bv.res = -u.bv.res;
- }else{
- assert( pOp->opcode==OP_IdxGE );
- u.bv.res++;
- }
- if( u.bv.res>0 ){
- pc = pOp->p2 - 1 ;
- }
+ rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
+ if( pOp->opcode==OP_IdxLT ){
+ u.bv.res = -u.bv.res;
+ }else{
+ assert( pOp->opcode==OP_IdxGE );
+ u.bv.res++;
+ }
+ if( u.bv.res>0 ){
+ pc = pOp->p2 - 1 ;
}
break;
}
@@ -70149,15 +71376,18 @@ case OP_Destroy: { /* out2-prerelease */
int iDb;
#endif /* local variables moved into u.bw */
+ assert( p->readOnly==0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
u.bw.iCnt = 0;
for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){
- if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0 ){
+ if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->bIsReader
+ && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0
+ ){
u.bw.iCnt++;
}
}
#else
- u.bw.iCnt = db->activeVdbeCnt;
+ u.bw.iCnt = db->nVdbeRead;
#endif
pOut->flags = MEM_Null;
if( u.bw.iCnt>1 ){
@@ -70206,6 +71436,8 @@ case OP_Clear: {
#endif /* local variables moved into u.bx */
u.bx.nChange = 0;
+ assert( p->readOnly==0 );
+ assert( pOp->p1!=1 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
@@ -70222,6 +71454,7 @@ case OP_Clear: {
}
/* Opcode: CreateTable P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** Allocate a new table in the main database file if P1==0 or in the
** auxiliary database file if P1==1 or in an attached database if
@@ -70235,6 +71468,7 @@ case OP_Clear: {
** See also: CreateIndex
*/
/* Opcode: CreateIndex P1 P2 * * *
+** Synopsis: r[P2]=root iDb=P1
**
** Allocate a new index in the main database file if P1==0 or in the
** auxiliary database file if P1==1 or in an attached database if
@@ -70254,6 +71488,7 @@ case OP_CreateTable: { /* out2-prerelease */
u.by.pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+ assert( p->readOnly==0 );
u.by.pDb = &db->aDb[pOp->p1];
assert( u.by.pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
@@ -70406,11 +71641,12 @@ case OP_IntegrityCk: {
Mem *pnErr; /* Register keeping track of errors remaining */
#endif /* local variables moved into u.ca */
+ assert( p->bIsReader );
u.ca.nRoot = pOp->p2;
assert( u.ca.nRoot>0 );
u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
if( u.ca.aRoot==0 ) goto no_mem;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
u.ca.pnErr = &aMem[pOp->p3];
assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
@@ -70440,6 +71676,7 @@ case OP_IntegrityCk: {
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
+** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
@@ -70459,6 +71696,7 @@ case OP_RowSetAdd: { /* in1, in2 */
}
/* Opcode: RowSetRead P1 P2 P3 * *
+** Synopsis: r[P3]=rowset(P1)
**
** Extract the smallest value from boolean index P1 and put that value into
** register P3. Or, if boolean index P1 is initially empty, leave P3
@@ -70468,7 +71706,7 @@ case OP_RowSetRead: { /* jump, in1, out3 */
#if 0 /* local variables moved into u.cb */
i64 val;
#endif /* local variables moved into u.cb */
- CHECK_FOR_INTERRUPT;
+
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_RowSet)==0
|| sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
@@ -70480,10 +71718,11 @@ case OP_RowSetRead: { /* jump, in1, out3 */
/* A value was pulled from the index */
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
}
- break;
+ goto check_for_interrupt;
}
/* Opcode: RowSetTest P1 P2 P3 P4
+** Synopsis: if r[P3] in rowset(P1) goto P2
**
** Register P3 is assumed to hold a 64-bit integer value. If register P1
** contains a RowSet object and that RowSet object contains
@@ -70693,6 +71932,7 @@ case OP_Param: { /* out2-prerelease */
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Opcode: FkCounter P1 P2 * * *
+** Synopsis: fkctr[P1]+=P2
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented
@@ -70700,7 +71940,9 @@ case OP_Param: { /* out2-prerelease */
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
- if( pOp->p1 ){
+ if( db->flags & SQLITE_DeferFKs ){
+ db->nDeferredImmCons += pOp->p2;
+ }else if( pOp->p1 ){
db->nDeferredCons += pOp->p2;
}else{
p->nFkConstraint += pOp->p2;
@@ -70709,6 +71951,7 @@ case OP_FkCounter: {
}
/* Opcode: FkIfZero P1 P2 * * *
+** Synopsis: if fkctr[P1]==0 goto P2
**
** This opcode tests if a foreign key constraint-counter is currently zero.
** If so, jump to instruction P2. Otherwise, fall through to the next
@@ -70721,9 +71964,9 @@ case OP_FkCounter: {
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
- if( db->nDeferredCons==0 ) pc = pOp->p2-1;
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}else{
- if( p->nFkConstraint==0 ) pc = pOp->p2-1;
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}
break;
}
@@ -70731,6 +71974,7 @@ case OP_FkIfZero: { /* jump */
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Opcode: MemMax P1 P2 * * *
+** Synopsis: r[P1]=max(r[P1],r[P2])
**
** P1 is a register in the root frame of this VM (the root frame is
** different from the current frame if this instruction is being executed
@@ -70763,6 +72007,7 @@ case OP_MemMax: { /* in2 */
#endif /* SQLITE_OMIT_AUTOINCREMENT */
/* Opcode: IfPos P1 P2 * * *
+** Synopsis: if r[P1]>0 goto P2
**
** If the value of register P1 is 1 or greater, jump to P2.
**
@@ -70779,6 +72024,7 @@ case OP_IfPos: { /* jump, in1 */
}
/* Opcode: IfNeg P1 P2 * * *
+** Synopsis: if r[P1]<0 goto P2
**
** If the value of register P1 is less than zero, jump to P2.
**
@@ -70795,6 +72041,7 @@ case OP_IfNeg: { /* jump, in1 */
}
/* Opcode: IfZero P1 P2 P3 * *
+** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2
**
** The register P1 must contain an integer. Add literal P3 to the
** value in register P1. If the result is exactly 0, jump to P2.
@@ -70813,6 +72060,7 @@ case OP_IfZero: { /* jump, in1 */
}
/* Opcode: AggStep * P2 P3 P4 P5
+** Synopsis: accum=r[P3] step(r[P2@P5])
**
** Execute the step function for an aggregate. The
** function has P5 arguments. P4 is a pointer to the FuncDef
@@ -70844,7 +72092,7 @@ case OP_AggStep: {
sqlite3VdbeMemStoreType(u.cg.pRec);
}
u.cg.ctx.pFunc = pOp->p4.pFunc;
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
u.cg.pMem->n++;
u.cg.ctx.s.flags = MEM_Null;
@@ -70855,7 +72103,7 @@ case OP_AggStep: {
u.cg.ctx.isError = 0;
u.cg.ctx.pColl = 0;
u.cg.ctx.skipFlag = 0;
- if( u.cg.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ if( u.cg.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
@@ -70878,6 +72126,7 @@ case OP_AggStep: {
}
/* Opcode: AggFinal P1 P2 * P4 *
+** Synopsis: accum=r[P1] N=P2
**
** Execute the finalizer function for an aggregate. P1 is
** the memory location that is the accumulator for the aggregate.
@@ -70893,7 +72142,7 @@ case OP_AggFinal: {
#if 0 /* local variables moved into u.ch */
Mem *pMem;
#endif /* local variables moved into u.ch */
- assert( pOp->p1>0 && pOp->p1<=p->nMem );
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
u.ch.pMem = &aMem[pOp->p1];
assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
@@ -70927,6 +72176,7 @@ case OP_Checkpoint: {
Mem *pMem; /* Write results here */
#endif /* local variables moved into u.ci */
+ assert( p->readOnly==0 );
u.ci.aRes[0] = 0;
u.ci.aRes[1] = u.ci.aRes[2] = -1;
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
@@ -70978,6 +72228,7 @@ case OP_JournalMode: { /* out2-prerelease */
|| u.cj.eNew==PAGER_JOURNALMODE_QUERY
);
assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( p->readOnly==0 );
u.cj.pBt = db->aDb[pOp->p1].pBt;
u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
@@ -71001,7 +72252,7 @@ case OP_JournalMode: { /* out2-prerelease */
if( (u.cj.eNew!=u.cj.eOld)
&& (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
){
- if( !db->autoCommit || db->activeVdbeCnt>1 ){
+ if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR;
sqlite3SetString(&p->zErrMsg, db,
"cannot change %s wal mode from within a transaction",
@@ -71060,6 +72311,7 @@ case OP_JournalMode: { /* out2-prerelease */
** a transaction.
*/
case OP_Vacuum: {
+ assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db);
break;
}
@@ -71079,6 +72331,7 @@ case OP_IncrVacuum: { /* jump */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
+ assert( p->readOnly==0 );
u.ck.pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
if( rc==SQLITE_DONE ){
@@ -71109,6 +72362,7 @@ case OP_Expire: {
#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
+** Synopsis: iDb=P1 root=P2 write=P3
**
** Obtain a lock on a particular table. This instruction is only used when
** the shared-cache feature is enabled.
@@ -71155,7 +72409,7 @@ case OP_VBegin: {
#endif /* local variables moved into u.cl */
u.cl.pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, u.cl.pVTab);
- if( u.cl.pVTab ) importVtabErrMsg(p, u.cl.pVTab->pVtab);
+ if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -71201,13 +72455,14 @@ case OP_VOpen: {
sqlite3_module *pModule;
#endif /* local variables moved into u.cm */
+ assert( p->bIsReader );
u.cm.pCur = 0;
u.cm.pVtabCursor = 0;
u.cm.pVtab = pOp->p4.pVtab->pVtab;
u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
assert(u.cm.pVtab && u.cm.pModule);
rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
- importVtabErrMsg(p, u.cm.pVtab);
+ sqlite3VtabImportErrmsg(p, u.cm.pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
u.cm.pVtabCursor->pVtab = u.cm.pVtab;
@@ -71216,7 +72471,6 @@ case OP_VOpen: {
u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
if( u.cm.pCur ){
u.cm.pCur->pVtabCursor = u.cm.pVtabCursor;
- u.cm.pCur->pModule = u.cm.pVtabCursor->pVtab->pModule;
}else{
db->mallocFailed = 1;
u.cm.pModule->xClose(u.cm.pVtabCursor);
@@ -71228,6 +72482,7 @@ case OP_VOpen: {
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VFilter P1 P2 P3 P4 *
+** Synopsis: iPlan=r[P3] zPlan='P4'
**
** P1 is a cursor opened using VOpen. P2 is an address to jump to if
** the filtered result set is empty.
@@ -71287,7 +72542,7 @@ case OP_VFilter: { /* jump */
p->inVtabMethod = 1;
rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
p->inVtabMethod = 0;
- importVtabErrMsg(p, u.cn.pVtab);
+ sqlite3VtabImportErrmsg(p, u.cn.pVtab);
if( rc==SQLITE_OK ){
u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
}
@@ -71304,6 +72559,7 @@ case OP_VFilter: { /* jump */
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VColumn P1 P2 P3 * *
+** Synopsis: r[P3]=vcolumn(P2)
**
** Store the value of the P2-th column of
** the row of the virtual-table that the
@@ -71319,7 +72575,7 @@ case OP_VColumn: {
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur->pVtabCursor );
- assert( pOp->p3>0 && pOp->p3<=p->nMem );
+ assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
u.co.pDest = &aMem[pOp->p3];
memAboutToChange(p, u.co.pDest);
if( pCur->nullRow ){
@@ -71340,7 +72596,7 @@ case OP_VColumn: {
MemSetTypeFlag(&u.co.sContext.s, MEM_Null);
rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
- importVtabErrMsg(p, u.co.pVtab);
+ sqlite3VtabImportErrmsg(p, u.co.pVtab);
if( u.co.sContext.isError ){
rc = u.co.sContext.isError;
}
@@ -71395,7 +72651,7 @@ case OP_VNext: { /* jump */
p->inVtabMethod = 1;
rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
p->inVtabMethod = 0;
- importVtabErrMsg(p, u.cp.pVtab);
+ sqlite3VtabImportErrmsg(p, u.cp.pVtab);
if( rc==SQLITE_OK ){
u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
}
@@ -71404,7 +72660,7 @@ case OP_VNext: { /* jump */
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
}
- break;
+ goto check_for_interrupt;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -71425,6 +72681,7 @@ case OP_VRename: {
u.cq.pName = &aMem[pOp->p1];
assert( u.cq.pVtab->pModule->xRename );
assert( memIsValid(u.cq.pName) );
+ assert( p->readOnly==0 );
REGISTER_TRACE(pOp->p1, u.cq.pName);
assert( u.cq.pName->flags & MEM_Str );
testcase( u.cq.pName->enc==SQLITE_UTF8 );
@@ -71433,7 +72690,7 @@ case OP_VRename: {
rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
if( rc==SQLITE_OK ){
rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
- importVtabErrMsg(p, u.cq.pVtab);
+ sqlite3VtabImportErrmsg(p, u.cq.pVtab);
p->expired = 0;
}
break;
@@ -71442,6 +72699,7 @@ case OP_VRename: {
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate P1 P2 P3 P4 *
+** Synopsis: data=r[P3@P2]
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
** This opcode invokes the corresponding xUpdate method. P2 values
@@ -71478,6 +72736,7 @@ case OP_VUpdate: {
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
);
+ assert( p->readOnly==0 );
u.cr.pVtab = pOp->p4.pVtab->pVtab;
u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
u.cr.nArg = pOp->p2;
@@ -71496,7 +72755,7 @@ case OP_VUpdate: {
db->vtabOnConflict = pOp->p5;
rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
db->vtabOnConflict = vtabOnConflict;
- importVtabErrMsg(p, u.cr.pVtab);
+ sqlite3VtabImportErrmsg(p, u.cr.pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
db->lastRowid = lastRowid = u.cr.rowid;
@@ -71572,6 +72831,16 @@ case OP_Trace: {
db->xTrace(db->pTraceArg, u.cs.z);
sqlite3DbFree(db, u.cs.z);
}
+#ifdef SQLITE_USE_FCNTL_TRACE
+ u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( u.cs.zTrace ){
+ int i;
+ for(i=0; i<db->nDb; i++){
+ if( ((1<<i) & p->btreeMask)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, u.cs.zTrace);
+ }
+ }
+#endif /* SQLITE_USE_FCNTL_TRACE */
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
&& (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
@@ -71629,13 +72898,13 @@ default: { /* This is really OP_Noop and OP_Explain */
assert( pc>=-1 && pc<p->nOp );
#ifdef SQLITE_DEBUG
- if( p->trace ){
- if( rc!=0 ) fprintf(p->trace,"rc=%d\n",rc);
+ if( db->flags & SQLITE_VdbeTrace ){
+ if( rc!=0 ) printf("rc=%d\n",rc);
if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
- registerTrace(p->trace, pOp->p2, &aMem[pOp->p2]);
+ registerTrace(pOp->p2, &aMem[pOp->p2]);
}
if( pOp->opflags & OPFLG_OUT3 ){
- registerTrace(p->trace, pOp->p3, &aMem[pOp->p3]);
+ registerTrace(pOp->p3, &aMem[pOp->p3]);
}
}
#endif /* SQLITE_DEBUG */
@@ -71663,6 +72932,8 @@ vdbe_error_halt:
** top. */
vdbe_return:
db->lastRowid = lastRowid;
+ testcase( nVmStep>0 );
+ p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
return rc;
@@ -71770,7 +73041,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
rc = sqlite3_step(p->pStmt);
if( rc==SQLITE_ROW ){
- u32 type = v->apCsr[0]->aType[p->iCol];
+ VdbeCursor *pC = v->apCsr[0];
+ u32 type = pC->aType[p->iCol];
if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
@@ -71779,9 +73051,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
sqlite3_finalize(p->pStmt);
p->pStmt = 0;
}else{
- p->iOffset = v->apCsr[0]->aOffset[p->iCol];
+ p->iOffset = pC->aType[p->iCol + pC->nField];
p->nByte = sqlite3VdbeSerialTypeLen(type);
- p->pCsr = v->apCsr[0]->pCursor;
+ p->pCsr = pC->pCursor;
sqlite3BtreeEnterCursor(p->pCsr);
sqlite3BtreeCacheOverflow(p->pCsr);
sqlite3BtreeLeaveCursor(p->pCsr);
@@ -71884,6 +73156,10 @@ SQLITE_API int sqlite3_blob_open(
pTab = 0;
sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
}
+ if( pTab && !HasRowid(pTab) ){
+ pTab = 0;
+ sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable);
+ }
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
@@ -71941,7 +73217,7 @@ SQLITE_API int sqlite3_blob_open(
#endif
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int j;
- for(j=0; j<pIdx->nColumn; j++){
+ for(j=0; j<pIdx->nKeyCol; j++){
if( pIdx->aiColumn[j]==iCol ){
zFault = "indexed";
}
@@ -72030,6 +73306,7 @@ blob_open_out:
}
sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
@@ -72230,7 +73507,7 @@ typedef struct FileWriter FileWriter;
** other key value. If the keys are equal (only possible with two EOF
** values), it doesn't matter which index is stored.
**
-** The (N/4) elements of aTree[] that preceed the final (N/2) described
+** The (N/4) elements of aTree[] that precede the final (N/2) described
** above contains the index of the smallest of each block of 4 iterators.
** And so on. So that aTree[1] contains the index of the iterator that
** currently points to the smallest key value. aTree[0] is unused.
@@ -72562,7 +73839,7 @@ static int vdbeSorterIterInit(
*/
static void vdbeSorterCompare(
const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */
- int bOmitRowid, /* Ignore rowid field at end of keys */
+ int nIgnore, /* Ignore the last nIgnore fields */
const void *pKey1, int nKey1, /* Left side of comparison */
const void *pKey2, int nKey2, /* Right side of comparison */
int *pRes /* OUT: Result of comparison */
@@ -72576,8 +73853,8 @@ static void vdbeSorterCompare(
sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
}
- if( bOmitRowid ){
- r2->nField = pKeyInfo->nField;
+ if( nIgnore ){
+ r2->nField = pKeyInfo->nField - nIgnore;
assert( r2->nField>0 );
for(i=0; i<r2->nField; i++){
if( r2->aMem[i].flags & MEM_Null ){
@@ -73203,13 +74480,14 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
const VdbeCursor *pCsr, /* Sorter cursor */
Mem *pVal, /* Value to compare to current sorter key */
+ int nIgnore, /* Ignore this many fields at the end */
int *pRes /* OUT: Result of comparison */
){
VdbeSorter *pSorter = pCsr->pSorter;
void *pKey; int nKey; /* Sorter key to compare pVal with */
pKey = vdbeSorterRowkey(pSorter, &nKey);
- vdbeSorterCompare(pCsr, 1, pVal->z, pVal->n, pKey, nKey, pRes);
+ vdbeSorterCompare(pCsr, nIgnore, pVal->z, pVal->n, pKey, nKey, pRes);
return SQLITE_OK;
}
@@ -73505,12 +74783,6 @@ typedef struct FileChunk FileChunk;
*/
#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
-/* Macro to find the minimum of two numeric values.
-*/
-#ifndef MIN
-# define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
/*
** The rollback journal is composed of a linked list of these structures.
*/
@@ -73780,7 +75052,7 @@ SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
+ && !ExprHasProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -73947,7 +75219,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** column reference is so that the column reference will be recognized as
** usable by indices within the WHERE clause processing logic.
**
-** Hack: The TK_AS operator is inhibited if zType[0]=='G'. This means
+** The TK_AS operator is inhibited if zType[0]=='G'. This means
** that in a GROUP BY clause, the expression is evaluated twice. Hence:
**
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY x
@@ -73957,8 +75229,9 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
** SELECT random()%5 AS x, count(*) FROM tab GROUP BY random()%5
**
** The result of random()%5 in the GROUP BY clause is probably different
-** from the result in the result-set. We might fix this someday. Or
-** then again, we might not...
+** from the result in the result-set. On the other hand Standard SQL does
+** not allow the GROUP BY clause to contain references to result-set columns.
+** So this should never come up in well-formed queries.
**
** If the reference is followed by a COLLATE operator, then make sure
** the COLLATE operator is preserved. For example:
@@ -73998,10 +75271,11 @@ static void resolveAlias(
incrAggFunctionDepth(pDup, nSubquery);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
- if( pEList->a[iCol].iAlias==0 ){
- pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
+ ExprSetProperty(pDup, EP_Skip);
+ if( pEList->a[iCol].u.x.iAlias==0 ){
+ pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias);
}
- pDup->iTable = pEList->a[iCol].iAlias;
+ pDup->iTable = pEList->a[iCol].u.x.iAlias;
}
if( pExpr->op==TK_COLLATE ){
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
@@ -74020,7 +75294,7 @@ static void resolveAlias(
if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
- pExpr->flags2 |= EP2_MallocedToken;
+ pExpr->flags |= EP_MemToken;
}
sqlite3DbFree(db, pDup);
}
@@ -74116,27 +75390,38 @@ static int lookupName(
struct SrcList_item *pMatch = 0; /* The matching pSrcList item */
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
- int isTrigger = 0;
+ int isTrigger = 0; /* True if resolved to a trigger column */
+ Table *pTab = 0; /* Table hold the row */
+ Column *pCol; /* A column of pTab */
assert( pNC ); /* the name context cannot be NULL. */
assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
/* Translate the schema name in zDb into a pointer to the corresponding
** schema. If not found, pSchema will remain NULL and nothing will match
** resulting in an appropriate error message toward the end of this routine
*/
if( zDb ){
- for(i=0; i<db->nDb; i++){
- assert( db->aDb[i].zName );
- if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
- pSchema = db->aDb[i].pSchema;
- break;
+ testcase( pNC->ncFlags & NC_PartIdx );
+ testcase( pNC->ncFlags & NC_IsCheck );
+ if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
+ /* Silently ignore database qualifiers inside CHECK constraints and partial
+ ** indices. Do not raise errors because that might break legacy and
+ ** because it does not hurt anything to just ignore the database name. */
+ zDb = 0;
+ }else{
+ for(i=0; i<db->nDb; i++){
+ assert( db->aDb[i].zName );
+ if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
+ pSchema = db->aDb[i].pSchema;
+ break;
+ }
}
}
}
@@ -74148,9 +75433,6 @@ static int lookupName(
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
- Table *pTab;
- Column *pCol;
-
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 );
@@ -74210,9 +75492,8 @@ static int lookupName(
/* If we have not already resolved the name, then maybe
** it is a new.* or old.* trigger argument reference
*/
- if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){
+ if( zDb==0 && zTab!=0 && cntTab==0 && pParse->pTriggerTab!=0 ){
int op = pParse->eTriggerOp;
- Table *pTab = 0;
assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
pExpr->iTable = 1;
@@ -74226,8 +75507,7 @@ static int lookupName(
int iCol;
pSchema = pTab->pSchema;
cntTab++;
- for(iCol=0; iCol<pTab->nCol; iCol++){
- Column *pCol = &pTab->aCol[iCol];
+ for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
@@ -74235,8 +75515,10 @@ static int lookupName(
break;
}
}
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) ){
- iCol = -1; /* IMP: R-44911-55124 */
+ if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
+ /* IMP: R-24309-18625 */
+ /* IMP: R-44911-55124 */
+ iCol = -1;
}
if( iCol<pTab->nCol ){
cnt++;
@@ -74262,7 +75544,8 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
+ assert( pTab!=0 || cntTab==0 );
+ if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -74279,10 +75562,16 @@ static int lookupName(
** forms the result set entry ("a+b" in the example) and return immediately.
** Note that the expression in the result set should have already been
** resolved by the time the WHERE clause is resolved.
+ **
+ ** The ability to use an output result-set column in the WHERE, GROUP BY,
+ ** or HAVING clauses, or as part of a larger expression in the ORDRE BY
+ ** clause is not standard SQL. This is a (goofy) SQLite extension, that
+ ** is supported for backwards compatibility only. TO DO: Issue a warning
+ ** on sqlite3_log() whenever the capability is used.
*/
if( (pEList = pNC->pEList)!=0
&& zTab==0
- && ((pNC->ncFlags & NC_AsMaybe)==0 || cnt==0)
+ && cnt==0
){
for(j=0; j<pEList->nExpr; j++){
char *zAs = pEList->a[j].zName;
@@ -74415,6 +75704,52 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
}
/*
+** Report an error that an expression is not valid for a partial index WHERE
+** clause.
+*/
+static void notValidPartIdxWhere(
+ Parse *pParse, /* Leave error message here */
+ NameContext *pNC, /* The name context */
+ const char *zMsg /* Type of error */
+){
+ if( (pNC->ncFlags & NC_PartIdx)!=0 ){
+ sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
+ zMsg);
+ }
+}
+
+#ifndef SQLITE_OMIT_CHECK
+/*
+** Report an error that an expression is not valid for a CHECK constraint.
+*/
+static void notValidCheckConstraint(
+ Parse *pParse, /* Leave error message here */
+ NameContext *pNC, /* The name context */
+ const char *zMsg /* Type of error */
+){
+ if( (pNC->ncFlags & NC_IsCheck)!=0 ){
+ sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
+ }
+}
+#else
+# define notValidCheckConstraint(P,N,M)
+#endif
+
+/*
+** Expression p should encode a floating point value between 1.0 and 0.0.
+** Return 1024 times this value. Or return -1 if p is not a floating point
+** value between 1.0 and 0.0.
+*/
+static int exprProbability(Expr *p){
+ double r = -1.0;
+ if( p->op!=TK_FLOAT ) return -1;
+ sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
+ assert( r>=0.0 );
+ if( r>1.0 ) return -1;
+ return (int)(r*1000.0);
+}
+
+/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
@@ -74434,7 +75769,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pParse = pNC->pParse;
assert( pParse==pWalker->pParse );
- if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return WRC_Prune;
+ if( ExprHasProperty(pExpr, EP_Resolved) ) return WRC_Prune;
ExprSetProperty(pExpr, EP_Resolved);
#ifndef NDEBUG
if( pNC->pSrcList && pNC->pSrcList->nAlloc>0 ){
@@ -74498,7 +75833,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
/* Resolve function names
*/
- case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pList = pExpr->x.pList; /* The argument list */
int n = pList ? pList->nExpr : 0; /* Number of arguments */
@@ -74511,8 +75845,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
- testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ notValidPartIdxWhere(pParse, pNC, "functions");
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
@@ -74525,6 +75859,23 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
}else{
is_agg = pDef->xFunc==0;
+ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+ ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
+ if( n==2 ){
+ pExpr->iTable = exprProbability(pList->a[1].pExpr);
+ if( pExpr->iTable<0 ){
+ sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
+ "constant between 0.0 and 1.0");
+ pNC->nErr++;
+ }
+ }else{
+ /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
+ ** likelihood(X, 0.0625).
+ ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
+ ** likelihood(X,0.0625). */
+ pExpr->iTable = 62; /* TUNING: Default 2nd arg to unlikely() is 0.0625 */
+ }
+ }
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pDef ){
@@ -74538,6 +75889,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pExpr->op = TK_NULL;
return WRC_Prune;
}
+ if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
}
#endif
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
@@ -74578,11 +75930,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
-#ifndef SQLITE_OMIT_CHECK
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
- }
-#endif
+ notValidCheckConstraint(pParse, pNC, "subqueries");
+ notValidPartIdxWhere(pParse, pNC, "subqueries");
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
@@ -74591,14 +75940,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
break;
}
-#ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: {
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
- sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
- }
+ notValidCheckConstraint(pParse, pNC, "parameters");
+ notValidPartIdxWhere(pParse, pNC, "parameters");
break;
}
-#endif
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
@@ -74689,7 +76035,7 @@ static int resolveOrderByTermToExprList(
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
- if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
+ if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
return i+1;
}
}
@@ -74795,7 +76141,7 @@ static int resolveCompoundOrderBy(
pItem->pExpr->pLeft = pNew;
}
sqlite3ExprDelete(db, pE);
- pItem->iOrderByCol = (u16)iCol;
+ pItem->u.x.iOrderByCol = (u16)iCol;
pItem->done = 1;
}else{
moreToDo = 1;
@@ -74816,8 +76162,8 @@ static int resolveCompoundOrderBy(
/*
** Check every term in the ORDER BY or GROUP BY clause pOrderBy of
** the SELECT statement pSelect. If any term is reference to a
-** result set expression (as determined by the ExprList.a.iCol field)
-** then convert that term into a copy of the corresponding result set
+** result set expression (as determined by the ExprList.a.u.x.iOrderByCol
+** field) then convert that term into a copy of the corresponding result set
** column.
**
** If any errors are detected, add an error message to pParse and
@@ -74844,12 +76190,12 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
pEList = pSelect->pEList;
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
- if( pItem->iOrderByCol ){
- if( pItem->iOrderByCol>pEList->nExpr ){
+ if( pItem->u.x.iOrderByCol ){
+ if( pItem->u.x.iOrderByCol>pEList->nExpr ){
resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
return 1;
}
- resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0);
+ resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
}
}
return 0;
@@ -74864,7 +76210,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
** If the order-by term is an integer I between 1 and N (where N is the
** number of columns in the result set of the SELECT) then the expression
** in the resolution is a copy of the I-th result-set expression. If
-** the order-by term is an identify that corresponds to the AS-name of
+** the order-by term is an identifier that corresponds to the AS-name of
** a result-set expression, then the term resolves to a copy of the
** result-set expression. Otherwise, the expression is resolved in
** the usual way - using sqlite3ResolveExprNames().
@@ -74890,16 +76236,19 @@ static int resolveOrderGroupBy(
pParse = pNC->pParse;
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
Expr *pE = pItem->pExpr;
- iCol = resolveAsName(pParse, pSelect->pEList, pE);
- if( iCol>0 ){
- /* If an AS-name match is found, mark this ORDER BY column as being
- ** a copy of the iCol-th result-set column. The subsequent call to
- ** sqlite3ResolveOrderGroupBy() will convert the expression to a
- ** copy of the iCol-th result-set expression. */
- pItem->iOrderByCol = (u16)iCol;
- continue;
+ Expr *pE2 = sqlite3ExprSkipCollate(pE);
+ if( zType[0]!='G' ){
+ iCol = resolveAsName(pParse, pSelect->pEList, pE2);
+ if( iCol>0 ){
+ /* If an AS-name match is found, mark this ORDER BY column as being
+ ** a copy of the iCol-th result-set column. The subsequent call to
+ ** sqlite3ResolveOrderGroupBy() will convert the expression to a
+ ** copy of the iCol-th result-set expression. */
+ pItem->u.x.iOrderByCol = (u16)iCol;
+ continue;
+ }
}
- if( sqlite3ExprIsInteger(sqlite3ExprSkipCollate(pE), &iCol) ){
+ if( sqlite3ExprIsInteger(pE2, &iCol) ){
/* The ORDER BY term is an integer constant. Again, set the column
** number so that sqlite3ResolveOrderGroupBy() will convert the
** order-by term to a copy of the result-set expression */
@@ -74907,18 +76256,18 @@ static int resolveOrderGroupBy(
resolveOutOfRangeError(pParse, zType, i+1, nResult);
return 1;
}
- pItem->iOrderByCol = (u16)iCol;
+ pItem->u.x.iOrderByCol = (u16)iCol;
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
- pItem->iOrderByCol = 0;
+ pItem->u.x.iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
- if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
- pItem->iOrderByCol = j+1;
+ if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
+ pItem->u.x.iOrderByCol = j+1;
}
}
}
@@ -75042,7 +76391,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
return WRC_Abort;
}
- /* Add the expression list to the name-context before parsing the
+ /* Add the output column list to the name-context before parsing the
** other expressions in the SELECT statement. This is so that
** expressions in the WHERE clause (etc.) can refer to expressions by
** aliases in the result set.
@@ -75051,10 +76400,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** re-evaluated for each reference to it.
*/
sNC.pEList = p->pEList;
- sNC.ncFlags |= NC_AsMaybe;
if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort;
- sNC.ncFlags &= ~NC_AsMaybe;
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
@@ -75224,6 +76571,48 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
sqlite3WalkSelect(&w, p);
}
+/*
+** Resolve names in expressions that can only reference a single table:
+**
+** * CHECK constraints
+** * WHERE clauses on partial indices
+**
+** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
+** is set to -1 and the Expr.iColumn value is set to the column number.
+**
+** Any errors cause an error message to be set in pParse.
+*/
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* The table being referenced */
+ int type, /* NC_IsCheck or NC_PartIdx */
+ Expr *pExpr, /* Expression to resolve. May be NULL. */
+ ExprList *pList /* Expression list to resolve. May be NUL. */
+){
+ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
+ NameContext sNC; /* Name context for pParse->pNewTable */
+ int i; /* Loop counter */
+
+ assert( type==NC_IsCheck || type==NC_PartIdx );
+ memset(&sNC, 0, sizeof(sNC));
+ memset(&sSrc, 0, sizeof(sSrc));
+ sSrc.nSrc = 1;
+ sSrc.a[0].zName = pTab->zName;
+ sSrc.a[0].pTab = pTab;
+ sSrc.a[0].iCursor = -1;
+ sNC.pParse = pParse;
+ sNC.pSrcList = &sSrc;
+ sNC.ncFlags = type;
+ if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
+ if( pList ){
+ for(i=0; i<pList->nExpr; i++){
+ if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
+ return;
+ }
+ }
+ }
+}
+
/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
@@ -75268,7 +76657,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- return sqlite3AffinityType(pExpr->u.zToken);
+ return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
@@ -75297,7 +76686,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr *pExpr, Toke
Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
if( pNew ){
pNew->pLeft = pExpr;
- pNew->flags |= EP_Collate;
+ pNew->flags |= EP_Collate|EP_Skip;
pExpr = pNew;
}
}
@@ -75312,13 +76701,21 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
}
/*
-** Skip over any TK_COLLATE and/or TK_AS operators at the root of
-** an expression.
+** Skip over any TK_COLLATE or TK_AS operators and any unlikely()
+** or likelihood() function at the root of an expression.
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
- while( pExpr && (pExpr->op==TK_COLLATE || pExpr->op==TK_AS) ){
- pExpr = pExpr->pLeft;
- }
+ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
+ if( ExprHasProperty(pExpr, EP_Unlikely) ){
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
+ assert( pExpr->x.pList->nExpr>0 );
+ assert( pExpr->op==TK_FUNCTION );
+ pExpr = pExpr->x.pList->a[0].pExpr;
+ }else{
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_AS );
+ pExpr = pExpr->pLeft;
+ }
+ }
return pExpr;
}
@@ -75341,8 +76738,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
p = p->pLeft;
continue;
}
- assert( op!=TK_REGISTER || p->op2!=TK_COLLATE );
- if( op==TK_COLLATE ){
+ if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
}
@@ -75824,7 +77220,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
const char *z;
if( pExpr==0 ) return;
- assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
@@ -75894,12 +77290,12 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
+ /* The Expr.x union is never used at the same time as Expr.pRight */
+ assert( p->x.pList==0 || p->pRight==0 );
sqlite3ExprDelete(db, p->pLeft);
sqlite3ExprDelete(db, p->pRight);
- if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
- sqlite3DbFree(db, p->u.zToken);
- }
+ if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@@ -75959,16 +77355,19 @@ static int exprStructSize(Expr *p){
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
+ assert( EXPR_FULLSIZE<=0xfff );
+ assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
}else{
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_FromJoin) );
- assert( (p->flags2 & EP2_MallocedToken)==0 );
- assert( (p->flags2 & EP2_Irreducible)==0 );
- if( p->pLeft || p->pRight || p->x.pList ){
+ assert( !ExprHasProperty(p, EP_MemToken) );
+ assert( !ExprHasProperty(p, EP_NoReduce) );
+ if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
+ assert( p->pRight==0 );
nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
}
}
@@ -76062,7 +77461,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
@@ -76082,7 +77481,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
+ if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
@@ -76092,8 +77491,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
- pNew->flags2 = 0;
- if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ if( !ExprHasProperty(p, EP_TokenOnly) ){
pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
@@ -76147,8 +77545,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
- pItem->iOrderByCol = pOldItem->iOrderByCol;
- pItem->iAlias = pOldItem->iAlias;
+ pItem->bSpanIsTab = pOldItem->bSpanIsTab;
+ pItem->u = pOldItem->u;
}
return pNew;
}
@@ -76402,16 +77800,19 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* If pWalker->u.i is 3 then any term of the expression that comes from
** the ON or USING clauses of a join disqualifies the expression
** from being considered constant. */
- if( pWalker->u.i==3 && ExprHasAnyProperty(pExpr, EP_FromJoin) ){
+ if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
pWalker->u.i = 0;
return WRC_Abort;
}
switch( pExpr->op ){
/* Consider functions to be constant if all their arguments are constant
- ** and pWalker->u.i==2 */
+ ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
+ ** flag. */
case TK_FUNCTION:
- if( pWalker->u.i==2 ) return 0;
+ if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
+ return WRC_Continue;
+ }
/* Fall through */
case TK_ID:
case TK_COLUMN:
@@ -76505,6 +77906,7 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
case TK_UMINUS: {
int v;
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
+ assert( v!=(-2147483647-1) );
*pValue = -v;
rc = 1;
}
@@ -76748,8 +78150,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */
- int iCol; /* Index of column <column> */
- int iDb; /* Database idx for pTab */
+ i16 iCol; /* Index of column <column> */
+ i16 iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
@@ -76757,7 +78159,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
pExpr = p->pEList->a[0].pExpr;
- iCol = pExpr->iColumn;
+ iCol = (i16)pExpr->iColumn;
/* Code an OP_VerifyCookie and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -76795,16 +78197,11 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
&& sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
- && (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
+ && (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
){
- int iAddr;
- char *pKey;
-
- pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx);
- iAddr = sqlite3CodeOnce(pParse);
-
- sqlite3VdbeAddOp4(v, OP_OpenRead, iTab, pIdx->tnum, iDb,
- pKey,P4_KEYINFO_HANDOFF);
+ int iAddr = sqlite3CodeOnce(pParse);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
@@ -76823,16 +78220,16 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
/* Could not found an existing table or index to use as the RHS b-tree.
** We will have to generate an ephemeral table to do the job.
*/
- double savedNQueryLoop = pParse->nQueryLoop;
+ u32 savedNQueryLoop = pParse->nQueryLoop;
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
if( prNotFound ){
*prNotFound = rMayHaveNull = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
}else{
- testcase( pParse->nQueryLoop>(double)1 );
- pParse->nQueryLoop = (double)1;
- if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){
+ testcase( pParse->nQueryLoop>0 );
+ pParse->nQueryLoop = 0;
+ if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
eType = IN_INDEX_ROWID;
}
}
@@ -76873,7 +78270,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
**
** If rMayHaveNull is zero, that means that the subquery is being used
** for membership testing only. There is no need to initialize any
-** registers to indicate the presense or absence of NULLs on the RHS.
+** registers to indicate the presence or absence of NULLs on the RHS.
**
** For a SELECT or EXISTS operator, return the register that holds the
** result. For IN operators or if an error occurs, the return value is 0.
@@ -76901,7 +78298,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** If all of the above are false, then we can run this code just once
** save the results, and reuse the same result on subsequent invocations.
*/
- if( !ExprHasAnyProperty(pExpr, EP_VarSelect) ){
+ if( !ExprHasProperty(pExpr, EP_VarSelect) ){
testAddr = sqlite3CodeOnce(pParse);
}
@@ -76918,10 +78315,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
switch( pExpr->op ){
case TK_IN: {
char affinity; /* Affinity of the LHS of the IN */
- KeyInfo keyInfo; /* Keyinfo for the generated table */
- static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
int addr; /* Address of OP_OpenEphemeral instruction */
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
+ KeyInfo *pKeyInfo = 0; /* Key information */
if( rMayHaveNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
@@ -76945,9 +78341,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
pExpr->iTable = pParse->nTab++;
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
- memset(&keyInfo, 0, sizeof(keyInfo));
- keyInfo.nField = 1;
- keyInfo.aSortOrder = &sortOrder;
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
@@ -76963,14 +78357,18 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
dest.affSdst = (u8)affinity;
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
pExpr->x.pSelect->iLimit = 0;
+ testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
+ sqlite3KeyInfoUnref(pKeyInfo);
return 0;
}
pEList = pExpr->x.pSelect->pEList;
- if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
- keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
- pEList->a[0].pExpr);
- }
+ assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+ assert( pEList!=0 );
+ assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
+ pEList->a[0].pExpr);
}else if( ALWAYS(pExpr->x.pList!=0) ){
/* Case 2: expr IN (exprlist)
**
@@ -76987,8 +78385,10 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
if( !affinity ){
affinity = SQLITE_AFF_NONE;
}
- keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- keyInfo.aSortOrder = &sortOrder;
+ if( pKeyInfo ){
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
+ }
/* Loop through each expression in <exprlist>. */
r1 = sqlite3GetTempReg(pParse);
@@ -77027,8 +78427,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempReg(pParse, r2);
}
- if( !isRowid ){
- sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
+ if( pKeyInfo ){
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
}
break;
}
@@ -77069,7 +78469,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
return 0;
}
rReg = dest.iSDParm;
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
break;
}
}
@@ -77429,15 +78829,19 @@ static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
Vdbe *v, /* The VDBE under construction */
Table *pTab, /* The table containing the value */
- int iTabCur, /* The cursor for this table */
+ int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
- int regOut /* Extract the valud into this register */
+ int regOut /* Extract the value into this register */
){
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- sqlite3VdbeAddOp3(v, op, iTabCur, iCol, regOut);
+ int x = iCol;
+ if( !HasRowid(pTab) ){
+ x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+ }
+ sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
}
if( iCol>=0 ){
sqlite3ColumnDefault(v, pTab, iCol, regOut);
@@ -77542,6 +78946,16 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
#endif /* SQLITE_DEBUG || SQLITE_COVERAGE_TEST */
/*
+** Convert an expression node to a TK_REGISTER
+*/
+static void exprToRegister(Expr *p, int iReg){
+ p->op2 = p->op;
+ p->op = TK_REGISTER;
+ p->iTable = iReg;
+ ExprClearProperty(p, EP_Skip);
+}
+
+/*
** Generate code into the current Vdbe to evaluate the given
** expression. Attempt to store the results in register "target".
** Return the register where results are stored.
@@ -77560,6 +78974,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
int regFree2 = 0; /* If non-zero free this temporary register */
int r1, r2, r3, r4; /* Various register numbers */
sqlite3 *db = pParse->db; /* The database connection */
+ Expr tempX; /* Temporary expression node */
assert( target>0 && target<=pParse->nMem );
if( v==0 ){
@@ -77588,15 +79003,20 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
- if( pExpr->iTable<0 ){
- /* This only happens when coding check constraints */
- assert( pParse->ckBase>0 );
- inReg = pExpr->iColumn + pParse->ckBase;
- }else{
- inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
- pExpr->iColumn, pExpr->iTable, target,
- pExpr->op2);
+ int iTab = pExpr->iTable;
+ if( iTab<0 ){
+ if( pParse->ckBase>0 ){
+ /* Generating CHECK constraints or inserting into partial index */
+ inReg = pExpr->iColumn + pParse->ckBase;
+ break;
+ }else{
+ /* Deleting from a partial index */
+ iTab = pParse->iPartIdxTab;
+ }
}
+ inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+ pExpr->iColumn, iTab, target,
+ pExpr->op2);
break;
}
case TK_INTEGER: {
@@ -77661,7 +79081,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
int aff, to_op;
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
assert( !ExprHasProperty(pExpr, EP_IntValue) );
- aff = sqlite3AffinityType(pExpr->u.zToken);
+ aff = sqlite3AffinityType(pExpr->u.zToken, 0);
to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
@@ -77774,8 +79194,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
codeReal(v, pLeft->u.zToken, 1, target);
#endif
}else{
- regFree1 = r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, r1);
+ tempX.op = TK_INTEGER;
+ tempX.flags = EP_IntValue|EP_TokenOnly;
+ tempX.u.iValue = 0;
+ r1 = sqlite3ExprCodeTemp(pParse, &tempX, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
@@ -77820,7 +79242,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
break;
}
- case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
int nFarg; /* Number of function arguments */
@@ -77833,9 +79254,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
CollSeq *pColl = 0; /* A collating sequence */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- testcase( op==TK_CONST_FUNC );
- testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
@@ -77854,7 +79273,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** IFNULL() functions. This avoids unnecessary evalation of
** arguments past the first non-NULL argument.
*/
- if( pDef->flags & SQLITE_FUNC_COALESCE ){
+ if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
int endCoalesce = sqlite3VdbeMakeLabel(v);
assert( nFarg>=2 );
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
@@ -77869,16 +79288,37 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
break;
}
+ /* The UNLIKELY() function is a no-op. The result is the value
+ ** of the first argument.
+ */
+ if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
+ assert( nFarg>=1 );
+ sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
+ break;
+ }
+ for(i=0; i<nFarg; i++){
+ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
+ constMask |= (1<<i);
+ }
+ if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
+ pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
+ }
+ }
if( pFarg ){
- r1 = sqlite3GetTempRange(pParse, nFarg);
+ if( constMask ){
+ r1 = pParse->nMem+1;
+ pParse->nMem += nFarg;
+ }else{
+ r1 = sqlite3GetTempRange(pParse, nFarg);
+ }
/* For length() and typeof() functions with a column argument,
** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG
** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data
** loading.
*/
- if( (pDef->flags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
+ if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){
u8 exprOp;
assert( nFarg==1 );
assert( pFarg->a[0].pExpr!=0 );
@@ -77886,13 +79326,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){
assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG );
assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG );
- testcase( pDef->flags==SQLITE_FUNC_LENGTH );
- pFarg->a[0].pExpr->op2 = pDef->flags;
+ testcase( pDef->funcFlags & OPFLAG_LENGTHARG );
+ pFarg->a[0].pExpr->op2 =
+ pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG);
}
}
sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */
- sqlite3ExprCodeExprList(pParse, pFarg, r1, 1);
+ sqlite3ExprCodeExprList(pParse, pFarg, r1,
+ SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */
}else{
r1 = 0;
@@ -77916,22 +79358,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
}
#endif
- for(i=0; i<nFarg; i++){
- if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
- constMask |= (1<<i);
- }
- if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
- pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
- }
- }
- if( pDef->flags & SQLITE_FUNC_NEEDCOLL ){
+ if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
if( !pColl ) pColl = db->pDfltColl;
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target,
(char*)pDef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nFarg);
- if( nFarg ){
+ if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
break;
@@ -78065,9 +79499,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** WHEN x=eN THEN rN ELSE y END
**
** X (if it exists) is in pExpr->pLeft.
- ** Y is in pExpr->pRight. The Y is also optional. If there is no
- ** ELSE clause and no other term matches, then the result of the
- ** exprssion is NULL.
+ ** Y is in the last element of pExpr->x.pList if pExpr->x.pList->nExpr is
+ ** odd. The Y is also optional. If the number of elements in x.pList
+ ** is even, then Y is omitted and the "otherwise" result is NULL.
** Ei is in pExpr->pList->a[i*2] and Ri is pExpr->pList->a[i*2+1].
**
** The result of the expression is the Ri for the first matching Ei,
@@ -78082,27 +79516,23 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
ExprList *pEList; /* List of WHEN terms */
struct ExprList_item *aListelem; /* Array of WHEN terms */
Expr opCompare; /* The X==Ei expression */
- Expr cacheX; /* Cached expression X */
Expr *pX; /* The X expression */
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; )
assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
- assert((pExpr->x.pList->nExpr % 2) == 0);
assert(pExpr->x.pList->nExpr > 0);
pEList = pExpr->x.pList;
aListelem = pEList->a;
nExpr = pEList->nExpr;
endLabel = sqlite3VdbeMakeLabel(v);
if( (pX = pExpr->pLeft)!=0 ){
- cacheX = *pX;
+ tempX = *pX;
testcase( pX->op==TK_COLUMN );
- testcase( pX->op==TK_REGISTER );
- cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
+ exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, &regFree1));
testcase( regFree1==0 );
- cacheX.op = TK_REGISTER;
opCompare.op = TK_EQ;
- opCompare.pLeft = &cacheX;
+ opCompare.pLeft = &tempX;
pTest = &opCompare;
/* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001:
** The value in regFree1 might get SCopy-ed into the file result.
@@ -78110,7 +79540,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** purposes and possibly overwritten. */
regFree1 = 0;
}
- for(i=0; i<nExpr; i=i+2){
+ for(i=0; i<nExpr-1; i=i+2){
sqlite3ExprCachePush(pParse);
if( pX ){
assert( pTest!=0 );
@@ -78122,15 +79552,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
- testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel);
sqlite3ExprCachePop(pParse, 1);
sqlite3VdbeResolveLabel(v, nextCase);
}
- if( pExpr->pRight ){
+ if( (nExpr&1)!=0 ){
sqlite3ExprCachePush(pParse);
- sqlite3ExprCode(pParse, pExpr->pRight, target);
+ sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
sqlite3ExprCachePop(pParse, 1);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -78161,7 +79590,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
}else{
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
- pExpr->affinity, pExpr->u.zToken, 0);
+ pExpr->affinity, pExpr->u.zToken, 0, 0);
}
break;
@@ -78174,6 +79603,28 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
/*
+** Factor out the code of the given expression to initialization time.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeAtInit(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The expression to code when the VDBE initializes */
+ int regDest, /* Store the value in this register */
+ u8 reusable /* True if this expression is reusable */
+){
+ ExprList *p;
+ assert( ConstFactorOk(pParse) );
+ p = pParse->pConstExpr;
+ pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
+ p = sqlite3ExprListAppend(pParse, p, pExpr);
+ if( p ){
+ struct ExprList_item *pItem = &p->a[p->nExpr-1];
+ pItem->u.iConstExprReg = regDest;
+ pItem->reusable = reusable;
+ }
+ pParse->pConstExpr = p;
+}
+
+/*
** Generate code to evaluate an expression and store the results
** into a register. Return the register number where the results
** are stored.
@@ -78181,15 +79632,40 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** If the register is a temporary register that can be deallocated,
** then write its number into *pReg. If the result register is not
** a temporary, then set *pReg to zero.
+**
+** If pExpr is a constant, then this routine might generate this
+** code to fill the register in the initialization section of the
+** VDBE program, in order to factor it out of the evaluation loop.
*/
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( r2==r1 ){
- *pReg = r1;
+ int r2;
+ pExpr = sqlite3ExprSkipCollate(pExpr);
+ if( ConstFactorOk(pParse)
+ && pExpr->op!=TK_REGISTER
+ && sqlite3ExprIsConstantNotJoin(pExpr)
+ ){
+ ExprList *p = pParse->pConstExpr;
+ int i;
+ *pReg = 0;
+ if( p ){
+ struct ExprList_item *pItem;
+ for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+ if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+ return pItem->u.iConstExprReg;
+ }
+ }
+ }
+ r2 = ++pParse->nMem;
+ sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
}else{
- sqlite3ReleaseTempReg(pParse, r1);
- *pReg = 0;
+ int r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
+ if( r2==r1 ){
+ *pReg = r1;
+ }else{
+ sqlite3ReleaseTempReg(pParse, r1);
+ *pReg = 0;
+ }
}
return r2;
}
@@ -78232,19 +79708,18 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe
int inReg;
inReg = sqlite3ExprCode(pParse, pExpr, target);
assert( target>0 );
- /* This routine is called for terms to INSERT or UPDATE. And the only
- ** other place where expressions can be converted into TK_REGISTER is
- ** in WHERE clause processing. So as currently implemented, there is
- ** no way for a TK_REGISTER to exist here. But it seems prudent to
- ** keep the ALWAYS() in case the conditions above change with future
- ** modifications or enhancements. */
+ /* The only place, other than this routine, where expressions can be
+ ** converted to TK_REGISTER is internal subexpressions in BETWEEN and
+ ** CASE operators. Neither ever calls this routine. And this routine
+ ** is never called twice on the same expression. Hence it is impossible
+ ** for the input to this routine to already be a register. Nevertheless,
+ ** it seems prudent to keep the ALWAYS() in case the conditions above
+ ** change with future modifications or enhancements. */
if( ALWAYS(pExpr->op!=TK_REGISTER) ){
int iMem;
iMem = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
- pExpr->iTable = iMem;
- pExpr->op2 = pExpr->op;
- pExpr->op = TK_REGISTER;
+ exprToRegister(pExpr, iMem);
}
return inReg;
}
@@ -78323,7 +79798,7 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
case TK_CAST: {
/* Expressions of the form: CAST(pLeft AS token) */
const char *zAff = "unk";
- switch( sqlite3AffinityType(pExpr->u.zToken) ){
+ switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
case SQLITE_AFF_TEXT: zAff = "TEXT"; break;
case SQLITE_AFF_NONE: zAff = "NONE"; break;
case SQLITE_AFF_NUMERIC: zAff = "NUMERIC"; break;
@@ -78371,10 +79846,9 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
}
case TK_AGG_FUNCTION:
- case TK_CONST_FUNC:
case TK_FUNCTION: {
ExprList *pFarg; /* List of function arguments */
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
@@ -78523,165 +79997,40 @@ SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
#endif /* SQLITE_DEBUG */
/*
-** Return TRUE if pExpr is an constant expression that is appropriate
-** for factoring out of a loop. Appropriate expressions are:
-**
-** * Any expression that evaluates to two or more opcodes.
-**
-** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null,
-** or OP_Variable that does not need to be placed in a
-** specific register.
-**
-** There is no point in factoring out single-instruction constant
-** expressions that need to be placed in a particular register.
-** We could factor them out, but then we would end up adding an
-** OP_SCopy instruction to move the value into the correct register
-** later. We might as well just use the original instruction and
-** avoid the OP_SCopy.
-*/
-static int isAppropriateForFactoring(Expr *p){
- if( !sqlite3ExprIsConstantNotJoin(p) ){
- return 0; /* Only constant expressions are appropriate for factoring */
- }
- if( (p->flags & EP_FixedDest)==0 ){
- return 1; /* Any constant without a fixed destination is appropriate */
- }
- while( p->op==TK_UPLUS ) p = p->pLeft;
- switch( p->op ){
-#ifndef SQLITE_OMIT_BLOB_LITERAL
- case TK_BLOB:
-#endif
- case TK_VARIABLE:
- case TK_INTEGER:
- case TK_FLOAT:
- case TK_NULL:
- case TK_STRING: {
- testcase( p->op==TK_BLOB );
- testcase( p->op==TK_VARIABLE );
- testcase( p->op==TK_INTEGER );
- testcase( p->op==TK_FLOAT );
- testcase( p->op==TK_NULL );
- testcase( p->op==TK_STRING );
- /* Single-instruction constants with a fixed destination are
- ** better done in-line. If we factor them, they will just end
- ** up generating an OP_SCopy to move the value to the destination
- ** register. */
- return 0;
- }
- case TK_UMINUS: {
- if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
- return 0;
- }
- break;
- }
- default: {
- break;
- }
- }
- return 1;
-}
-
-/*
-** If pExpr is a constant expression that is appropriate for
-** factoring out of a loop, then evaluate the expression
-** into a register and convert the expression into a TK_REGISTER
-** expression.
-*/
-static int evalConstExpr(Walker *pWalker, Expr *pExpr){
- Parse *pParse = pWalker->pParse;
- switch( pExpr->op ){
- case TK_IN:
- case TK_REGISTER: {
- return WRC_Prune;
- }
- case TK_COLLATE: {
- return WRC_Continue;
- }
- case TK_FUNCTION:
- case TK_AGG_FUNCTION:
- case TK_CONST_FUNC: {
- /* The arguments to a function have a fixed destination.
- ** Mark them this way to avoid generated unneeded OP_SCopy
- ** instructions.
- */
- ExprList *pList = pExpr->x.pList;
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- if( pList ){
- int i = pList->nExpr;
- struct ExprList_item *pItem = pList->a;
- for(; i>0; i--, pItem++){
- if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
- }
- }
- break;
- }
- }
- if( isAppropriateForFactoring(pExpr) ){
- int r1 = ++pParse->nMem;
- int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- /* If r2!=r1, it means that register r1 is never used. That is harmless
- ** but suboptimal, so we want to know about the situation to fix it.
- ** Hence the following assert: */
- assert( r2==r1 );
- pExpr->op2 = pExpr->op;
- pExpr->op = TK_REGISTER;
- pExpr->iTable = r2;
- return WRC_Prune;
- }
- return WRC_Continue;
-}
-
-/*
-** Preevaluate constant subexpressions within pExpr and store the
-** results in registers. Modify pExpr so that the constant subexpresions
-** are TK_REGISTER opcodes that refer to the precomputed values.
-**
-** This routine is a no-op if the jump to the cookie-check code has
-** already occur. Since the cookie-check jump is generated prior to
-** any other serious processing, this check ensures that there is no
-** way to accidently bypass the constant initializations.
-**
-** This routine is also a no-op if the SQLITE_FactorOutConst optimization
-** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)
-** interface. This allows test logic to verify that the same answer is
-** obtained for queries regardless of whether or not constants are
-** precomputed into registers or if they are inserted in-line.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){
- Walker w;
- if( pParse->cookieGoto ) return;
- if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return;
- memset(&w, 0, sizeof(w));
- w.xExprCallback = evalConstExpr;
- w.pParse = pParse;
- sqlite3WalkExpr(&w, pExpr);
-}
-
-
-/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
** Return the number of elements evaluated.
+**
+** The SQLITE_ECEL_DUP flag prevents the arguments from being
+** filled using OP_SCopy. OP_Copy must be used instead.
+**
+** The SQLITE_ECEL_FACTOR argument allows constant arguments to be
+** factored out into initialization code.
*/
SQLITE_PRIVATE int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
ExprList *pList, /* The expression list to be coded */
int target, /* Where to write results */
- int doHardCopy /* Make a hard copy of every element */
+ u8 flags /* SQLITE_ECEL_* flags */
){
struct ExprList_item *pItem;
int i, n;
+ u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy;
assert( pList!=0 );
assert( target>0 );
assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */
n = pList->nExpr;
+ if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
- int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
- if( inReg!=target+i ){
- sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy,
- inReg, target+i);
+ if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
+ }else{
+ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
+ if( inReg!=target+i ){
+ sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i);
+ }
}
}
return n;
@@ -78723,8 +80072,7 @@ static void exprCodeBetween(
compRight.op = TK_LE;
compRight.pLeft = &exprX;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprX.iTable = sqlite3ExprCodeTemp(pParse, &exprX, &regFree1);
- exprX.op = TK_REGISTER;
+ exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, &regFree1));
if( jumpIfTrue ){
sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
}else{
@@ -79019,6 +80367,12 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
** by a COLLATE operator at the top level. Return 2 if there are differences
** other than the top-level COLLATE operator.
**
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
+** The pA side might be using TK_REGISTER. If that is the case and pB is
+** not using TK_REGISTER but is otherwise equivalent, then still return 0.
+**
** Sometimes this routine will return 2 even if the two expressions
** really are equivalent. If we cannot prove that the expressions are
** identical, we return 2 just to be safe. So if this routine
@@ -79029,39 +80383,44 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
** just might result in some slightly slower code. But returning
** an incorrect 0 or 1 could lead to a malfunction.
*/
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
- if( pA==0||pB==0 ){
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
+ u32 combinedFlags;
+ if( pA==0 || pB==0 ){
return pB==pA ? 0 : 2;
}
- assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
- assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
- if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
+ combinedFlags = pA->flags | pB->flags;
+ if( combinedFlags & EP_IntValue ){
+ if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
+ return 0;
+ }
return 2;
}
- if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( pA->op!=pB->op ){
- if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
return 1;
}
- if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
return 1;
}
return 2;
}
- if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
- if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
- if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
- if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
- if( ExprHasProperty(pA, EP_IntValue) ){
- if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
- return 2;
- }
- }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
- if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
+ if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return pA->op==TK_COLLATE ? 1 : 2;
}
}
+ if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
+ if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
+ if( combinedFlags & EP_xIsSelect ) return 2;
+ if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
+ if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
+ if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
+ if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
+ if( pA->iColumn!=pB->iColumn ) return 2;
+ if( pA->iTable!=pB->iTable
+ && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+ }
+ }
return 0;
}
@@ -79069,6 +80428,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
** Compare two ExprList objects. Return 0 if they are identical and
** non-zero if they differ in any way.
**
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
+**
** This routine might return non-zero for equivalent ExprLists. The
** only consequence will be disabled optimizations. But this routine
** must never return 0 if the two ExprList objects are different, or
@@ -79077,7 +80439,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
** Two NULL pointers are considered to be the same. But a NULL pointer
** always differs from a non-NULL pointer.
*/
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
@@ -79086,7 +80448,46 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
- if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
+ if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Return true if we can prove the pE2 will always be true if pE1 is
+** true. Return false if we cannot complete the proof or if pE2 might
+** be false. Examples:
+**
+** pE1: x==5 pE2: x==5 Result: true
+** pE1: x>0 pE2: x==5 Result: false
+** pE1: x=21 pE2: x=21 OR y=43 Result: true
+** pE1: x!=123 pE2: x IS NOT NULL Result: true
+** pE1: x!=?1 pE2: x IS NOT NULL Result: true
+** pE1: x IS NULL pE2: x IS NOT NULL Result: false
+** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false
+**
+** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
+** Expr.iTable<0 then assume a table number given by iTab.
+**
+** When in doubt, return false. Returning true might give a performance
+** improvement. Returning false might cause a performance reduction, but
+** it will always give the correct answer and is hence always safe.
+*/
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
+ if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
+ return 1;
+ }
+ if( pE2->op==TK_OR
+ && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
+ || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
+ ){
+ return 1;
+ }
+ if( pE2->op==TK_NOTNULL
+ && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
+ && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
+ ){
+ return 1;
}
return 0;
}
@@ -79203,7 +80604,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
@@ -79252,7 +80653,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
- ExprSetIrreducible(pExpr);
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
pExpr->iAgg = (i16)k;
@@ -79271,7 +80672,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
- if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
+ if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
break;
}
}
@@ -79298,8 +80699,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
- assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pExpr);
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(pExpr, EP_NoReduce);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
@@ -80106,7 +81507,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
** can handle (i.e. not CURRENT_TIME etc.)
*/
if( pDflt ){
- sqlite3_value *pVal;
+ sqlite3_value *pVal = 0;
if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
db->mallocFailed = 1;
return;
@@ -80247,7 +81648,7 @@ exit_begin_add_column:
/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
/*
-** 2005 July 8
+** 2005-07-08
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
@@ -80268,15 +81669,23 @@ exit_begin_add_column:
** CREATE TABLE sqlite_stat1(tbl, idx, stat);
** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
+** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample);
**
** Additional tables might be added in future releases of SQLite.
** The sqlite_stat2 table is not created or used unless the SQLite version
** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
-** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
+** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
** created and used by SQLite versions 3.7.9 and later and with
-** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3
-** is a superset of sqlite_stat2.
+** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
+** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced
+** version of sqlite_stat3 and is only available when compiled with
+** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 and later. It is
+** not possible to enable both STAT3 and STAT4 at the same time. If they
+** are both enabled, then STAT4 takes precedence.
+**
+** For most applications, sqlite_stat1 provides all the statisics required
+** for the query planner to make good choices.
**
** Format of sqlite_stat1:
**
@@ -80284,7 +81693,8 @@ exit_begin_add_column:
** name in the idx column. The tbl column is the name of the table to
** which the index belongs. In each such row, the stat column will be
** a string consisting of a list of integers. The first integer in this
-** list is the number of rows in the index and in the table. The second
+** list is the number of rows in the index. (This is the same as the
+** number of rows in the table, except for partial indices.) The second
** integer is the average number of rows in the index that have the same
** value in the first column of the index. The third integer is the average
** number of rows in the index that have the same value for the first two
@@ -80331,53 +81741,81 @@ exit_begin_add_column:
**
** Format for sqlite_stat3:
**
-** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
-** used to avoid compatibility problems.
+** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the
+** sqlite_stat4 format will be described first. Further information
+** about sqlite_stat3 follows the sqlite_stat4 description.
+**
+** Format for sqlite_stat4:
+**
+** As with sqlite_stat2, the sqlite_stat4 table contains histogram data
+** to aid the query planner in choosing good indices based on the values
+** that indexed columns are compared against in the WHERE clauses of
+** queries.
**
-** The format of the sqlite_stat3 table is similar to the format of
-** the sqlite_stat2 table. There are multiple entries for each index.
+** The sqlite_stat4 table contains multiple entries for each index.
** The idx column names the index and the tbl column is the table of the
** index. If the idx and tbl columns are the same, then the sample is
-** of the INTEGER PRIMARY KEY. The sample column is a value taken from
-** the left-most column of the index. The nEq column is the approximate
-** number of entires in the index whose left-most column exactly matches
-** the sample. nLt is the approximate number of entires whose left-most
-** column is less than the sample. The nDLt column is the approximate
-** number of distinct left-most entries in the index that are less than
-** the sample.
-**
-** Future versions of SQLite might change to store a string containing
-** multiple integers values in the nDLt column of sqlite_stat3. The first
-** integer will be the number of prior index entires that are distinct in
-** the left-most column. The second integer will be the number of prior index
-** entries that are distinct in the first two columns. The third integer
-** will be the number of prior index entries that are distinct in the first
-** three columns. And so forth. With that extension, the nDLt field is
-** similar in function to the sqlite_stat1.stat field.
-**
-** There can be an arbitrary number of sqlite_stat3 entries per index.
-** The ANALYZE command will typically generate sqlite_stat3 tables
+** of the INTEGER PRIMARY KEY. The sample column is a blob which is the
+** binary encoding of a key from the index. The nEq column is a
+** list of integers. The first integer is the approximate number
+** of entries in the index whose left-most column exactly matches
+** the left-most column of the sample. The second integer in nEq
+** is the approximate number of entries in the index where the
+** first two columns match the first two columns of the sample.
+** And so forth. nLt is another list of integers that show the approximate
+** number of entries that are strictly less than the sample. The first
+** integer in nLt contains the number of entries in the index where the
+** left-most column is less than the left-most column of the sample.
+** The K-th integer in the nLt entry is the number of index entries
+** where the first K columns are less than the first K columns of the
+** sample. The nDLt column is like nLt except that it contains the
+** number of distinct entries in the index that are less than the
+** sample.
+**
+** There can be an arbitrary number of sqlite_stat4 entries per index.
+** The ANALYZE command will typically generate sqlite_stat4 tables
** that contain between 10 and 40 samples which are distributed across
** the key space, though not uniformly, and which include samples with
-** largest possible nEq values.
+** large nEq values.
+**
+** Format for sqlite_stat3 redux:
+**
+** The sqlite_stat3 table is like sqlite_stat4 except that it only
+** looks at the left-most column of the index. The sqlite_stat3.sample
+** column contains the actual value of the left-most column instead
+** of a blob encoding of the complete index key as is found in
+** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3
+** all contain just a single integer which is the same as the first
+** integer in the equivalent columns in sqlite_stat4.
*/
#ifndef SQLITE_OMIT_ANALYZE
+#if defined(SQLITE_ENABLE_STAT4)
+# define IsStat4 1
+# define IsStat3 0
+#elif defined(SQLITE_ENABLE_STAT3)
+# define IsStat4 0
+# define IsStat3 1
+#else
+# define IsStat4 0
+# define IsStat3 0
+# undef SQLITE_STAT4_SAMPLES
+# define SQLITE_STAT4_SAMPLES 1
+#endif
+#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */
+
/*
-** This routine generates code that opens the sqlite_stat1 table for
-** writing with cursor iStatCur. If the library was built with the
-** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is
-** opened for writing using cursor (iStatCur+1)
+** This routine generates code that opens the sqlite_statN tables.
+** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
+** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
+** appropriate compile-time options are provided.
**
-** If the sqlite_stat1 tables does not previously exist, it is created.
-** Similarly, if the sqlite_stat3 table does not exist and the library
-** is compiled with SQLITE_ENABLE_STAT3 defined, it is created.
+** If the sqlite_statN tables do not previously exist, it is created.
**
** Argument zWhere may be a pointer to a buffer containing a table name,
** or it may be a NULL pointer. If it is not NULL, then all entries in
-** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated
-** with the named table are deleted. If zWhere==0, then code is generated
-** to delete all stat table entries.
+** the sqlite_statN tables associated with the named table are deleted.
+** If zWhere==0, then code is generated to delete all stat table entries.
*/
static void openStatTable(
Parse *pParse, /* Parsing context */
@@ -80391,18 +81829,24 @@ static void openStatTable(
const char *zCols;
} aTable[] = {
{ "sqlite_stat1", "tbl,idx,stat" },
-#ifdef SQLITE_ENABLE_STAT3
+#if defined(SQLITE_ENABLE_STAT4)
+ { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat3", 0 },
+#elif defined(SQLITE_ENABLE_STAT3)
{ "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
+ { "sqlite_stat4", 0 },
+#else
+ { "sqlite_stat3", 0 },
+ { "sqlite_stat4", 0 },
#endif
};
-
- int aRoot[] = {0, 0};
- u8 aCreateTbl[] = {0, 0};
-
int i;
sqlite3 *db = pParse->db;
Db *pDb;
Vdbe *v = sqlite3GetVdbe(pParse);
+ int aRoot[ArraySize(aTable)];
+ u8 aCreateTbl[ArraySize(aTable)];
+
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3VdbeDb(v)==db );
@@ -80415,258 +81859,712 @@ static void openStatTable(
const char *zTab = aTable[i].zName;
Table *pStat;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
- /* The sqlite_stat[12] table does not exist. Create it. Note that a
- ** side-effect of the CREATE TABLE statement is to leave the rootpage
- ** of the new table in register pParse->regRoot. This is important
- ** because the OpenWrite opcode below will be needing it. */
- sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
- );
- aRoot[i] = pParse->regRoot;
- aCreateTbl[i] = OPFLAG_P2ISREG;
+ if( aTable[i].zCols ){
+ /* The sqlite_statN table does not exist. Create it. Note that a
+ ** side-effect of the CREATE TABLE statement is to leave the rootpage
+ ** of the new table in register pParse->regRoot. This is important
+ ** because the OpenWrite opcode below will be needing it. */
+ sqlite3NestedParse(pParse,
+ "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
+ );
+ aRoot[i] = pParse->regRoot;
+ aCreateTbl[i] = OPFLAG_P2ISREG;
+ }
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
+ aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
- "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
+ "DELETE FROM %Q.%s WHERE %s=%Q",
+ pDb->zName, zTab, zWhereType, zWhere
);
}else{
- /* The sqlite_stat[12] table already exists. Delete all rows. */
+ /* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
}
}
}
- /* Open the sqlite_stat[13] tables for writing. */
- for(i=0; i<ArraySize(aTable); i++){
- sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
+ /* Open the sqlite_stat[134] tables for writing. */
+ for(i=0; aTable[i].zCols; i++){
+ assert( i<ArraySize(aTable) );
+ sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
}
}
/*
-** Recommended number of samples for sqlite_stat3
+** Recommended number of samples for sqlite_stat4
*/
-#ifndef SQLITE_STAT3_SAMPLES
-# define SQLITE_STAT3_SAMPLES 24
+#ifndef SQLITE_STAT4_SAMPLES
+# define SQLITE_STAT4_SAMPLES 24
#endif
/*
-** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
+** Three SQL functions - stat_init(), stat_push(), and stat_get() -
** share an instance of the following structure to hold their state
** information.
*/
-typedef struct Stat3Accum Stat3Accum;
-struct Stat3Accum {
+typedef struct Stat4Accum Stat4Accum;
+typedef struct Stat4Sample Stat4Sample;
+struct Stat4Sample {
+ tRowcnt *anEq; /* sqlite_stat4.nEq */
+ tRowcnt *anDLt; /* sqlite_stat4.nDLt */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ tRowcnt *anLt; /* sqlite_stat4.nLt */
+ union {
+ i64 iRowid; /* Rowid in main table of the key */
+ u8 *aRowid; /* Key for WITHOUT ROWID tables */
+ } u;
+ u32 nRowid; /* Sizeof aRowid[] */
+ u8 isPSample; /* True if a periodic sample */
+ int iCol; /* If !isPSample, the reason for inclusion */
+ u32 iHash; /* Tiebreaker hash */
+#endif
+};
+struct Stat4Accum {
tRowcnt nRow; /* Number of rows in the entire table */
tRowcnt nPSample; /* How often to do a periodic sample */
- int iMin; /* Index of entry with minimum nEq and hash */
+ int nCol; /* Number of columns in index + rowid */
int mxSample; /* Maximum number of samples to accumulate */
- int nSample; /* Current number of samples */
+ Stat4Sample current; /* Current row as a Stat4Sample */
u32 iPrn; /* Pseudo-random number used for sampling */
- struct Stat3Sample {
- i64 iRowid; /* Rowid in main table of the key */
- tRowcnt nEq; /* sqlite_stat3.nEq */
- tRowcnt nLt; /* sqlite_stat3.nLt */
- tRowcnt nDLt; /* sqlite_stat3.nDLt */
- u8 isPSample; /* True if a periodic sample */
- u32 iHash; /* Tiebreaker hash */
- } *a; /* An array of samples */
+ Stat4Sample *aBest; /* Array of nCol best samples */
+ int iMin; /* Index in a[] of entry with minimum score */
+ int nSample; /* Current number of samples */
+ int iGet; /* Index of current sample accessed by stat_get() */
+ Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
+ sqlite3 *db; /* Database connection, for malloc() */
};
-#ifdef SQLITE_ENABLE_STAT3
+/* Reclaim memory used by a Stat4Sample
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleClear(sqlite3 *db, Stat4Sample *p){
+ assert( db!=0 );
+ if( p->nRowid ){
+ sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the BLOB value of a ROWID
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->u.aRowid = sqlite3DbMallocRaw(db, n);
+ if( p->u.aRowid ){
+ p->nRowid = n;
+ memcpy(p->u.aRowid, pData, n);
+ }else{
+ p->nRowid = 0;
+ }
+}
+#endif
+
+/* Initialize the INTEGER value of a ROWID.
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
+ assert( db!=0 );
+ if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
+ p->nRowid = 0;
+ p->u.iRowid = iRowid;
+}
+#endif
+
+
/*
-** Implementation of the stat3_init(C,S) SQL function. The two parameters
-** are the number of rows in the table or index (C) and the number of samples
-** to accumulate (S).
-**
-** This routine allocates the Stat3Accum object.
+** Copy the contents of object (*pFrom) into (*pTo).
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
+ pTo->isPSample = pFrom->isPSample;
+ pTo->iCol = pFrom->iCol;
+ pTo->iHash = pFrom->iHash;
+ memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
+ memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
+ if( pFrom->nRowid ){
+ sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid);
+ }else{
+ sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid);
+ }
+}
+#endif
+
+/*
+** Reclaim all memory of a Stat4Accum structure.
+*/
+static void stat4Destructor(void *pOld){
+ Stat4Accum *p = (Stat4Accum*)pOld;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int i;
+ for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
+ for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
+ sampleClear(p->db, &p->current);
+#endif
+ sqlite3DbFree(p->db, p);
+}
+
+/*
+** Implementation of the stat_init(N,C) SQL function. The two parameters
+** are the number of rows in the table or index (C) and the number of columns
+** in the index (N). The second argument (C) is only used for STAT3 and STAT4.
**
-** The return value is the Stat3Accum object (P).
+** This routine allocates the Stat4Accum object in heap memory. The return
+** value is a pointer to the the Stat4Accum object encoded as a blob (i.e.
+** the size of the blob is sizeof(void*) bytes).
*/
-static void stat3Init(
+static void statInit(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- Stat3Accum *p;
- tRowcnt nRow;
- int mxSample;
- int n;
+ Stat4Accum *p;
+ int nCol; /* Number of columns in index being sampled */
+ int nColUp; /* nCol rounded up for alignment */
+ int n; /* Bytes of space to allocate */
+ sqlite3 *db; /* Database connection */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int mxSample = SQLITE_STAT4_SAMPLES;
+#endif
+ /* Decode the three function arguments */
UNUSED_PARAMETER(argc);
- nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
- mxSample = sqlite3_value_int(argv[1]);
- n = sizeof(*p) + sizeof(p->a[0])*mxSample;
- p = sqlite3MallocZero( n );
+ nCol = sqlite3_value_int(argv[0]);
+ assert( nCol>1 ); /* >1 because it includes the rowid column */
+ nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
+
+ /* Allocate the space required for the Stat4Accum object */
+ n = sizeof(*p)
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
+#endif
+ ;
+ db = sqlite3_context_db_handle(context);
+ p = sqlite3DbMallocZero(db, n);
if( p==0 ){
sqlite3_result_error_nomem(context);
return;
}
- p->a = (struct Stat3Sample*)&p[1];
- p->nRow = nRow;
- p->mxSample = mxSample;
- p->nPSample = p->nRow/(mxSample/3+1) + 1;
- sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
- sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
-}
-static const FuncDef stat3InitFuncdef = {
- 2, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Init, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_init", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+
+ p->db = db;
+ p->nRow = 0;
+ p->nCol = nCol;
+ p->current.anDLt = (tRowcnt*)&p[1];
+ p->current.anEq = &p->current.anDLt[nColUp];
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ {
+ u8 *pSpace; /* Allocated space not yet assigned */
+ int i; /* Used to iterate through p->aSample[] */
+
+ p->iGet = -1;
+ p->mxSample = mxSample;
+ p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1);
+ p->current.anLt = &p->current.anEq[nColUp];
+ p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[1])*0xd0944565;
+
+ /* Set up the Stat4Accum.a[] and aBest[] arrays */
+ p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
+ p->aBest = &p->a[mxSample];
+ pSpace = (u8*)(&p->a[mxSample+nCol]);
+ for(i=0; i<(mxSample+nCol); i++){
+ p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+ }
+ assert( (pSpace - (u8*)p)==n );
+
+ for(i=0; i<nCol; i++){
+ p->aBest[i].iCol = i;
+ }
+ }
+#endif
+
+ /* Return a pointer to the allocated object to the caller */
+ sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
+}
+static const FuncDef statInitFuncdef = {
+ 1+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statInit, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_init", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
};
+#ifdef SQLITE_ENABLE_STAT4
+/*
+** pNew and pOld are both candidate non-periodic samples selected for
+** the same column (pNew->iCol==pOld->iCol). Ignoring this column and
+** considering only any trailing columns and the sample hash value, this
+** function returns true if sample pNew is to be preferred over pOld.
+** In other words, if we assume that the cardinalities of the selected
+** column for pNew and pOld are equal, is pNew to be preferred over pOld.
+**
+** This function assumes that for each argument sample, the contents of
+** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
+*/
+static int sampleIsBetterPost(
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
+){
+ int nCol = pAccum->nCol;
+ int i;
+ assert( pNew->iCol==pOld->iCol );
+ for(i=pNew->iCol+1; i<nCol; i++){
+ if( pNew->anEq[i]>pOld->anEq[i] ) return 1;
+ if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
+ }
+ if( pNew->iHash>pOld->iHash ) return 1;
+ return 0;
+}
+#endif
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
-** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The
-** arguments describe a single key instance. This routine makes the
-** decision about whether or not to retain this key for the sqlite_stat3
-** table.
+** Return true if pNew is to be preferred over pOld.
**
-** The return value is NULL.
+** This function assumes that for each argument sample, the contents of
+** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
*/
-static void stat3Push(
+static int sampleIsBetter(
+ Stat4Accum *pAccum,
+ Stat4Sample *pNew,
+ Stat4Sample *pOld
+){
+ tRowcnt nEqNew = pNew->anEq[pNew->iCol];
+ tRowcnt nEqOld = pOld->anEq[pOld->iCol];
+
+ assert( pOld->isPSample==0 && pNew->isPSample==0 );
+ assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
+
+ if( (nEqNew>nEqOld) ) return 1;
+#ifdef SQLITE_ENABLE_STAT4
+ if( nEqNew==nEqOld ){
+ if( pNew->iCol<pOld->iCol ) return 1;
+ return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
+ }
+ return 0;
+#else
+ return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
+#endif
+}
+
+/*
+** Copy the contents of sample *pNew into the p->a[] array. If necessary,
+** remove the least desirable sample from p->a[] to make room.
+*/
+static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
+ Stat4Sample *pSample = 0;
+ int i;
+
+ assert( IsStat4 || nEqZero==0 );
+
+#ifdef SQLITE_ENABLE_STAT4
+ if( pNew->isPSample==0 ){
+ Stat4Sample *pUpgrade = 0;
+ assert( pNew->anEq[pNew->iCol]>0 );
+
+ /* This sample is being added because the prefix that ends in column
+ ** iCol occurs many times in the table. However, if we have already
+ ** added a sample that shares this prefix, there is no need to add
+ ** this one. Instead, upgrade the priority of the highest priority
+ ** existing sample that shares this prefix. */
+ for(i=p->nSample-1; i>=0; i--){
+ Stat4Sample *pOld = &p->a[i];
+ if( pOld->anEq[pNew->iCol]==0 ){
+ if( pOld->isPSample ) return;
+ assert( pOld->iCol>pNew->iCol );
+ assert( sampleIsBetter(p, pNew, pOld) );
+ if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
+ pUpgrade = pOld;
+ }
+ }
+ }
+ if( pUpgrade ){
+ pUpgrade->iCol = pNew->iCol;
+ pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
+ goto find_new_min;
+ }
+ }
+#endif
+
+ /* If necessary, remove sample iMin to make room for the new sample. */
+ if( p->nSample>=p->mxSample ){
+ Stat4Sample *pMin = &p->a[p->iMin];
+ tRowcnt *anEq = pMin->anEq;
+ tRowcnt *anLt = pMin->anLt;
+ tRowcnt *anDLt = pMin->anDLt;
+ sampleClear(p->db, pMin);
+ memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
+ pSample = &p->a[p->nSample-1];
+ pSample->nRowid = 0;
+ pSample->anEq = anEq;
+ pSample->anDLt = anDLt;
+ pSample->anLt = anLt;
+ p->nSample = p->mxSample-1;
+ }
+
+ /* The "rows less-than" for the rowid column must be greater than that
+ ** for the last sample in the p->a[] array. Otherwise, the samples would
+ ** be out of order. */
+#ifdef SQLITE_ENABLE_STAT4
+ assert( p->nSample==0
+ || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
+#endif
+
+ /* Insert the new sample */
+ pSample = &p->a[p->nSample];
+ sampleCopy(p, pSample, pNew);
+ p->nSample++;
+
+ /* Zero the first nEqZero entries in the anEq[] array. */
+ memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
+
+#ifdef SQLITE_ENABLE_STAT4
+ find_new_min:
+#endif
+ if( p->nSample>=p->mxSample ){
+ int iMin = -1;
+ for(i=0; i<p->mxSample; i++){
+ if( p->a[i].isPSample ) continue;
+ if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
+ iMin = i;
+ }
+ }
+ assert( iMin>=0 );
+ p->iMin = iMin;
+ }
+}
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+/*
+** Field iChng of the index being scanned has changed. So at this point
+** p->current contains a sample that reflects the previous row of the
+** index. The value of anEq[iChng] and subsequent anEq[] elements are
+** correct at this point.
+*/
+static void samplePushPrevious(Stat4Accum *p, int iChng){
+#ifdef SQLITE_ENABLE_STAT4
+ int i;
+
+ /* Check if any samples from the aBest[] array should be pushed
+ ** into IndexSample.a[] at this point. */
+ for(i=(p->nCol-2); i>=iChng; i--){
+ Stat4Sample *pBest = &p->aBest[i];
+ pBest->anEq[i] = p->current.anEq[i];
+ if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
+ sampleInsert(p, pBest, i);
+ }
+ }
+
+ /* Update the anEq[] fields of any samples already collected. */
+ for(i=p->nSample-1; i>=0; i--){
+ int j;
+ for(j=iChng; j<p->nCol; j++){
+ if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ }
+ }
+#endif
+
+#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
+ if( iChng==0 ){
+ tRowcnt nLt = p->current.anLt[0];
+ tRowcnt nEq = p->current.anEq[0];
+
+ /* Check if this is to be a periodic sample. If so, add it. */
+ if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
+ p->current.isPSample = 1;
+ sampleInsert(p, &p->current, 0);
+ p->current.isPSample = 0;
+ }else
+
+ /* Or if it is a non-periodic sample. Add it in this case too. */
+ if( p->nSample<p->mxSample
+ || sampleIsBetter(p, &p->current, &p->a[p->iMin])
+ ){
+ sampleInsert(p, &p->current, 0);
+ }
+ }
+#endif
+
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+ UNUSED_PARAMETER( p );
+ UNUSED_PARAMETER( iChng );
+#endif
+}
+
+/*
+** Implementation of the stat_push SQL function: stat_push(P,C,R)
+** Arguments:
+**
+** P Pointer to the Stat4Accum object created by stat_init()
+** C Index of left-most column to differ from previous row
+** R Rowid for the current row. Might be a key record for
+** WITHOUT ROWID tables.
+**
+** The SQL function always returns NULL.
+**
+** The R parameter is only used for STAT3 and STAT4
+*/
+static void statPush(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]);
- tRowcnt nEq = sqlite3_value_int64(argv[0]);
- tRowcnt nLt = sqlite3_value_int64(argv[1]);
- tRowcnt nDLt = sqlite3_value_int64(argv[2]);
- i64 rowid = sqlite3_value_int64(argv[3]);
- u8 isPSample = 0;
- u8 doInsert = 0;
- int iMin = p->iMin;
- struct Stat3Sample *pSample;
int i;
- u32 h;
- UNUSED_PARAMETER(context);
- UNUSED_PARAMETER(argc);
- if( nEq==0 ) return;
- h = p->iPrn = p->iPrn*1103515245 + 12345;
- if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
- doInsert = isPSample = 1;
- }else if( p->nSample<p->mxSample ){
- doInsert = 1;
+ /* The three function arguments */
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+ int iChng = sqlite3_value_int(argv[1]);
+
+ UNUSED_PARAMETER( argc );
+ UNUSED_PARAMETER( context );
+ assert( p->nCol>1 ); /* Includes rowid field */
+ assert( iChng<p->nCol );
+
+ if( p->nRow==0 ){
+ /* This is the first call to this function. Do initialization. */
+ for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
- if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
- doInsert = 1;
+ /* Second and subsequent calls get processed here */
+ samplePushPrevious(p, iChng);
+
+ /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
+ ** to the current row of the index. */
+ for(i=0; i<iChng; i++){
+ p->current.anEq[i]++;
+ }
+ for(i=iChng; i<p->nCol; i++){
+ p->current.anDLt[i]++;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ p->current.anLt[i] += p->current.anEq[i];
+#endif
+ p->current.anEq[i] = 1;
}
}
- if( !doInsert ) return;
- if( p->nSample==p->mxSample ){
- assert( p->nSample - iMin - 1 >= 0 );
- memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
- pSample = &p->a[p->nSample-1];
+ p->nRow++;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
}else{
- pSample = &p->a[p->nSample++];
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
+ sqlite3_value_blob(argv[2]));
}
- pSample->iRowid = rowid;
- pSample->nEq = nEq;
- pSample->nLt = nLt;
- pSample->nDLt = nDLt;
- pSample->iHash = h;
- pSample->isPSample = isPSample;
+ p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+#endif
- /* Find the new minimum */
- if( p->nSample==p->mxSample ){
- pSample = p->a;
- i = 0;
- while( pSample->isPSample ){
- i++;
- pSample++;
- assert( i<p->nSample );
- }
- nEq = pSample->nEq;
- h = pSample->iHash;
- iMin = i;
- for(i++, pSample++; i<p->nSample; i++, pSample++){
- if( pSample->isPSample ) continue;
- if( pSample->nEq<nEq
- || (pSample->nEq==nEq && pSample->iHash<h)
- ){
- iMin = i;
- nEq = pSample->nEq;
- h = pSample->iHash;
+#ifdef SQLITE_ENABLE_STAT4
+ {
+ tRowcnt nLt = p->current.anLt[p->nCol-1];
+
+ /* Check if this is to be a periodic sample. If so, add it. */
+ if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
+ p->current.isPSample = 1;
+ p->current.iCol = 0;
+ sampleInsert(p, &p->current, p->nCol-1);
+ p->current.isPSample = 0;
+ }
+
+ /* Update the aBest[] array. */
+ for(i=0; i<(p->nCol-1); i++){
+ p->current.iCol = i;
+ if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
+ sampleCopy(p, &p->aBest[i], &p->current);
}
}
- p->iMin = iMin;
}
+#endif
}
-static const FuncDef stat3PushFuncdef = {
- 5, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Push, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_push", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+static const FuncDef statPushFuncdef = {
+ 2+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statPush, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_push", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
};
+#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
+#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */
+#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */
+#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */
+#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */
+
/*
-** Implementation of the stat3_get(P,N,...) SQL function. This routine is
-** used to query the results. Content is returned for the Nth sqlite_stat3
-** row where N is between 0 and S-1 and S is the number of samples. The
-** value returned depends on the number of arguments.
+** Implementation of the stat_get(P,J) SQL function. This routine is
+** used to query the results. Content is returned for parameter J
+** which is one of the STAT_GET_xxxx values defined above.
**
-** argc==2 result: rowid
-** argc==3 result: nEq
-** argc==4 result: nLt
-** argc==5 result: nDLt
+** If neither STAT3 nor STAT4 are enabled, then J is always
+** STAT_GET_STAT1 and is hence omitted and this routine becomes
+** a one-parameter function, stat_get(P), that always returns the
+** stat1 table entry information.
*/
-static void stat3Get(
+static void statGet(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
- int n = sqlite3_value_int(argv[1]);
- Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);
+ Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ /* STAT3 and STAT4 have a parameter on this routine. */
+ int eCall = sqlite3_value_int(argv[1]);
+ assert( argc==2 );
+ assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
+ || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
+ || eCall==STAT_GET_NDLT
+ );
+ if( eCall==STAT_GET_STAT1 )
+#else
+ assert( argc==1 );
+#endif
+ {
+ /* Return the value to store in the "stat" column of the sqlite_stat1
+ ** table for this index.
+ **
+ ** The value is a string composed of a list of integers describing
+ ** the index. The first integer in the list is the total number of
+ ** entries in the index. There is one additional integer in the list
+ ** for each indexed column. This additional integer is an estimate of
+ ** the number of rows matched by a stabbing query on the index using
+ ** a key with the corresponding number of fields. In other words,
+ ** if the index is on columns (a,b) and the sqlite_stat1 value is
+ ** "100 10 2", then SQLite estimates that:
+ **
+ ** * the index contains 100 rows,
+ ** * "WHERE a=?" matches 10 rows, and
+ ** * "WHERE a=? AND b=?" matches 2 rows.
+ **
+ ** If D is the count of distinct values and K is the total number of
+ ** rows, then each estimate is computed as:
+ **
+ ** I = (K+D-1)/D
+ */
+ char *z;
+ int i;
- assert( p!=0 );
- if( p->nSample<=n ) return;
- switch( argc ){
- case 2: sqlite3_result_int64(context, p->a[n].iRowid); break;
- case 3: sqlite3_result_int64(context, p->a[n].nEq); break;
- case 4: sqlite3_result_int64(context, p->a[n].nLt); break;
- default: sqlite3_result_int64(context, p->a[n].nDLt); break;
- }
-}
-static const FuncDef stat3GetFuncdef = {
- -1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
- 0, /* pUserData */
- 0, /* pNext */
- stat3Get, /* xFunc */
- 0, /* xStep */
- 0, /* xFinalize */
- "stat3_get", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
-};
-#endif /* SQLITE_ENABLE_STAT3 */
+ char *zRet = sqlite3MallocZero(p->nCol * 25);
+ if( zRet==0 ){
+ sqlite3_result_error_nomem(context);
+ return;
+ }
+
+ sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
+ z = zRet + sqlite3Strlen30(zRet);
+ for(i=0; i<(p->nCol-1); i++){
+ u64 nDistinct = p->current.anDLt[i] + 1;
+ u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
+ sqlite3_snprintf(24, z, " %llu", iVal);
+ z += sqlite3Strlen30(z);
+ assert( p->current.anEq[i] );
+ }
+ assert( z[0]=='\0' && z>zRet );
+
+ sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ }
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ else if( eCall==STAT_GET_ROWID ){
+ if( p->iGet<0 ){
+ samplePushPrevious(p, 0);
+ p->iGet = 0;
+ }
+ if( p->iGet<p->nSample ){
+ Stat4Sample *pS = p->a + p->iGet;
+ if( pS->nRowid==0 ){
+ sqlite3_result_int64(context, pS->u.iRowid);
+ }else{
+ sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
+ SQLITE_TRANSIENT);
+ }
+ }
+ }else{
+ tRowcnt *aCnt = 0;
+ assert( p->iGet<p->nSample );
+ switch( eCall ){
+ case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break;
+ case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break;
+ default: {
+ aCnt = p->a[p->iGet].anDLt;
+ p->iGet++;
+ break;
+ }
+ }
+ if( IsStat3 ){
+ sqlite3_result_int64(context, (i64)aCnt[0]);
+ }else{
+ char *zRet = sqlite3MallocZero(p->nCol * 25);
+ if( zRet==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ int i;
+ char *z = zRet;
+ for(i=0; i<p->nCol; i++){
+ sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]);
+ z += sqlite3Strlen30(z);
+ }
+ assert( z[0]=='\0' && z>zRet );
+ z[-1] = '\0';
+ sqlite3_result_text(context, zRet, -1, sqlite3_free);
+ }
+ }
+ }
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+#ifndef SQLITE_DEBUG
+ UNUSED_PARAMETER( argc );
+#endif
+}
+static const FuncDef statGetFuncdef = {
+ 1+IsStat34, /* nArg */
+ SQLITE_UTF8, /* funcFlags */
+ 0, /* pUserData */
+ 0, /* pNext */
+ statGet, /* xFunc */
+ 0, /* xStep */
+ 0, /* xFinalize */
+ "stat_get", /* zName */
+ 0, /* pHash */
+ 0 /* pDestructor */
+};
+static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
+ assert( regOut!=regStat4 && regOut!=regStat4+1 );
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
+#elif SQLITE_DEBUG
+ assert( iParam==STAT_GET_STAT1 );
+#else
+ UNUSED_PARAMETER( iParam );
+#endif
+ sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 1 + IsStat34);
+}
/*
** Generate code to do an analysis of all indices associated with
@@ -80677,41 +82575,31 @@ static void analyzeOneTable(
Table *pTab, /* Table whose indices are to be analyzed */
Index *pOnlyIdx, /* If not NULL, only analyze this one index */
int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
- int iMem /* Available memory locations begin here */
+ int iMem, /* Available memory locations begin here */
+ int iTab /* Next available cursor */
){
sqlite3 *db = pParse->db; /* Database handle */
Index *pIdx; /* An index to being analyzed */
int iIdxCur; /* Cursor open on index being analyzed */
+ int iTabCur; /* Table cursor */
Vdbe *v; /* The virtual machine being built up */
int i; /* Loop counter */
- int topOfLoop; /* The top of the loop */
- int endOfLoop; /* The end of the loop */
int jZeroRows = -1; /* Jump from here if number of rows is zero */
int iDb; /* Index of database containing pTab */
+ u8 needTableCnt = 1; /* True to count the table */
+ int regNewRowid = iMem++; /* Rowid for the inserted record */
+ int regStat4 = iMem++; /* Register to hold Stat4Accum object */
+ int regChng = iMem++; /* Index of changed index field */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int regRowid = iMem++; /* Rowid argument passed to stat_push() */
+#endif
+ int regTemp = iMem++; /* Temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
- int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
-#ifdef SQLITE_ENABLE_STAT3
- int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
- int regNumLt = iMem++; /* Number of keys less than regSample */
- int regNumDLt = iMem++; /* Number of distinct keys less than regSample */
- int regSample = iMem++; /* The next sample value */
- int regRowid = regSample; /* Rowid of a sample */
- int regAccum = iMem++; /* Register to hold Stat3Accum object */
- int regLoop = iMem++; /* Loop counter */
- int regCount = iMem++; /* Number of rows in the table or index */
- int regTemp1 = iMem++; /* Intermediate register */
- int regTemp2 = iMem++; /* Intermediate register */
- int once = 1; /* One-time initialization */
- int shortJump = 0; /* Instruction address */
- int iTabCur = pParse->nTab++; /* Table cursor */
-#endif
- int regCol = iMem++; /* Content of a column in analyzed table */
- int regRec = iMem++; /* Register holding completed record */
- int regTemp = iMem++; /* Temporary use register */
- int regNewRowid = iMem++; /* Rowid for the inserted record */
-
+ int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
+ int regPrev = iMem; /* MUST BE LAST (see below) */
+ pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
if( v==0 || NEVER(pTab==0) ){
return;
@@ -80735,215 +82623,244 @@ static void analyzeOneTable(
}
#endif
- /* Establish a read-lock on the table at the shared-cache level. */
+ /* Establish a read-lock on the table at the shared-cache level.
+ ** Open a read-only cursor on the table. Also allocate a cursor number
+ ** to use for scanning indexes (iIdxCur). No index cursor is opened at
+ ** this time though. */
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
- iIdxCur = pParse->nTab++;
+ iTabCur = iTab++;
+ iIdxCur = iTab++;
+ pParse->nTab = MAX(pParse->nTab, iTab);
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
+
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- int nCol;
- KeyInfo *pKey;
- int addrIfNot = 0; /* address of OP_IfNot */
- int *aChngAddr; /* Array of jump instruction addresses */
+ int nCol; /* Number of columns indexed by pIdx */
+ int *aGotoChng; /* Array of jump instruction addresses */
+ int addrRewind; /* Address of "OP_Rewind iIdxCur" */
+ int addrGotoChng0; /* Address of "Goto addr_chng_0" */
+ int addrNextRow; /* Address of "next_row:" */
+ const char *zIdxName; /* Name of the index */
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
+ if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
- nCol = pIdx->nColumn;
- aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
- if( aChngAddr==0 ) continue;
- pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- if( iMem+1+(nCol*2)>pParse->nMem ){
- pParse->nMem = iMem+1+(nCol*2);
- }
-
- /* Open a cursor to the index to be analyzed. */
- assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
+ nCol = pIdx->nKeyCol;
+ aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
+ if( aGotoChng==0 ) continue;
/* Populate the register containing the index name. */
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
+ zIdxName = pTab->zName;
+ }else{
+ zIdxName = pIdx->zName;
+ }
+ sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
-#ifdef SQLITE_ENABLE_STAT3
- if( once ){
- once = 0;
- sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- }
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
- sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
- (char*)&stat3InitFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2);
-#endif /* SQLITE_ENABLE_STAT3 */
-
- /* The block of memory cells initialized here is used as follows.
+ /*
+ ** Pseudo-code for loop that calls stat_push():
+ **
+ ** Rewind csr
+ ** if eof(csr) goto end_of_scan;
+ ** regChng = 0
+ ** goto chng_addr_0;
**
- ** iMem:
- ** The total number of rows in the table.
+ ** next_row:
+ ** regChng = 0
+ ** if( idx(0) != regPrev(0) ) goto chng_addr_0
+ ** regChng = 1
+ ** if( idx(1) != regPrev(1) ) goto chng_addr_1
+ ** ...
+ ** regChng = N
+ ** goto chng_addr_N
**
- ** iMem+1 .. iMem+nCol:
- ** Number of distinct entries in index considering the
- ** left-most N columns only, where N is between 1 and nCol,
- ** inclusive.
+ ** chng_addr_0:
+ ** regPrev(0) = idx(0)
+ ** chng_addr_1:
+ ** regPrev(1) = idx(1)
+ ** ...
**
- ** iMem+nCol+1 .. Mem+2*nCol:
- ** Previous value of indexed columns, from left to right.
+ ** chng_addr_N:
+ ** regRowid = idx(rowid)
+ ** stat_push(P, regChng, regRowid)
+ ** Next csr
+ ** if !eof(csr) goto next_row;
**
- ** Cells iMem through iMem+nCol are initialized to 0. The others are
- ** initialized to contain an SQL NULL.
+ ** end_of_scan:
*/
- for(i=0; i<=nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
- }
- for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
- }
- /* Start the analysis loop. This loop runs through all the entries in
- ** the index b-tree. */
- endOfLoop = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
- topOfLoop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */
+ /* Make sure there are enough memory cells allocated to accommodate
+ ** the regPrev array and a trailing rowid (the rowid slot is required
+ ** when building a record to insert into the sample column of
+ ** the sqlite_stat4 table. */
+ pParse->nMem = MAX(pParse->nMem, regPrev+nCol);
- for(i=0; i<nCol; i++){
- CollSeq *pColl;
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
- if( i==0 ){
- /* Always record the very first row */
- addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
- }
- assert( pIdx->azColl!=0 );
- assert( pIdx->azColl[i]!=0 );
- pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
- aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
- (char*)pColl, P4_COLLSEQ);
- sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
- VdbeComment((v, "jump if column %d changed", i));
-#ifdef SQLITE_ENABLE_STAT3
- if( i==0 ){
- sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
- VdbeComment((v, "incr repeat count"));
- }
-#endif
- }
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
- for(i=0; i<nCol; i++){
- sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */
- if( i==0 ){
- sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */
-#ifdef SQLITE_ENABLE_STAT3
- sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
- (char*)&stat3PushFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
- sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
- sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq);
-#endif
- }
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
- }
- sqlite3DbFree(db, aChngAddr);
-
- /* Always jump here after updating the iMem+1...iMem+1+nCol counters */
- sqlite3VdbeResolveLabel(v, endOfLoop);
+ /* Open a read-only cursor on the index being analyzed. */
+ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ VdbeComment((v, "%s", pIdx->zName));
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
-#ifdef SQLITE_ENABLE_STAT3
- sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
- (char*)&stat3PushFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);
- shortJump =
- sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2);
- sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);
- sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
- sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);
- sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 3);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 4);
- sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
- (char*)&stat3GetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 5);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump);
- sqlite3VdbeJumpHere(v, shortJump+2);
-#endif
-
- /* Store the results in sqlite_stat1.
+ /* Invoke the stat_init() function. The arguments are:
+ **
+ ** (1) the number of columns in the index including the rowid,
+ ** (2) the number of rows in the index,
**
- ** The result is a single row of the sqlite_stat1 table. The first
- ** two columns are the names of the table and index. The third column
- ** is a string composed of a list of integer statistics about the
- ** index. The first integer in the list is the total number of entries
- ** in the index. There is one additional integer in the list for each
- ** column of the table. This additional integer is a guess of how many
- ** rows of the table the index will select. If D is the count of distinct
- ** values and K is the total number of rows, then the integer is computed
- ** as:
+ ** The second argument is only used for STAT3 and STAT4
+ */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
+#endif
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
+ sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 1+IsStat34);
+
+ /* Implementation of the following:
**
- ** I = (K+D-1)/D
+ ** Rewind csr
+ ** if eof(csr) goto end_of_scan;
+ ** regChng = 0
+ ** goto next_push_0;
**
- ** If K==0 then no entry is made into the sqlite_stat1 table.
- ** If K>0 then it is always the case the D>0 so division by zero
- ** is never possible.
*/
- sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
- if( jZeroRows<0 ){
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
+ addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);
+
+ /*
+ ** next_row:
+ ** regChng = 0
+ ** if( idx(0) != regPrev(0) ) goto chng_addr_0
+ ** regChng = 1
+ ** if( idx(1) != regPrev(1) ) goto chng_addr_1
+ ** ...
+ ** regChng = N
+ ** goto chng_addr_N
+ */
+ addrNextRow = sqlite3VdbeCurrentAddr(v);
+ for(i=0; i<nCol; i++){
+ char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
+ sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
+ aGotoChng[i] =
+ sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
+ sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
+ aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
+
+ /*
+ ** chng_addr_0:
+ ** regPrev(0) = idx(0)
+ ** chng_addr_1:
+ ** regPrev(1) = idx(1)
+ ** ...
+ */
+ sqlite3VdbeJumpHere(v, addrGotoChng0);
for(i=0; i<nCol; i++){
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
- sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
- sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
- sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
- sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
- }
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
+ sqlite3VdbeJumpHere(v, aGotoChng[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
+ }
+
+ /*
+ ** chng_addr_N:
+ ** regRowid = idx(rowid) // STAT34 only
+ ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only
+ ** Next csr
+ ** if !eof(csr) goto next_row;
+ */
+ sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ assert( regRowid==(regStat4+2) );
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ int j, k, regKey;
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; j<pPk->nKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+ VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
+ }
+#endif
+ assert( regChng==(regStat4+1) );
+ sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
+ sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
+
+ /* Add the entry to the stat1 table. */
+ callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+
+ /* Add the entries to the stat3 or stat4 table. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ {
+ int regEq = regStat1;
+ int regLt = regStat1+1;
+ int regDLt = regStat1+2;
+ int regSample = regStat1+3;
+ int regCol = regStat1+4;
+ int regSampleRowid = regCol + nCol;
+ int addrNext;
+ int addrIsNull;
+ u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+
+ pParse->nMem = MAX(pParse->nMem, regCol+nCol+1);
+
+ addrNext = sqlite3VdbeCurrentAddr(v);
+ callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
+ addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
+ callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
+ callStatGet(v, regStat4, STAT_GET_NLT, regLt);
+ callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
+ sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
+#ifdef SQLITE_ENABLE_STAT3
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
+ pIdx->aiColumn[0], regSample);
+#else
+ for(i=0; i<nCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
+#endif
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
+ sqlite3VdbeJumpHere(v, addrIsNull);
+ }
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
+
+ /* End of analysis */
+ sqlite3VdbeJumpHere(v, addrRewind);
+ sqlite3DbFree(db, aGotoChng);
}
- /* If the table has no indices, create a single sqlite_stat1 entry
- ** containing NULL as the index name and the row count as the content.
+
+ /* Create a single sqlite_stat1 entry containing NULL as the index
+ ** name and the row count as the content.
*/
- if( pTab->pIndex==0 ){
- sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
+ if( pOnlyIdx==0 && needTableCnt ){
VdbeComment((v, "%s", pTab->zName));
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
- }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeJumpHere(v, jZeroRows);
- jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
}
- sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
- if( pParse->nMem<regRec ) pParse->nMem = regRec;
- sqlite3VdbeJumpHere(v, jZeroRows);
}
@@ -80967,16 +82884,18 @@ static void analyzeDatabase(Parse *pParse, int iDb){
HashElem *k;
int iStatCur;
int iMem;
+ int iTab;
sqlite3BeginWriteOperation(pParse, 0, iDb);
iStatCur = pParse->nTab;
pParse->nTab += 3;
openStatTable(pParse, iDb, iStatCur, 0, 0);
iMem = pParse->nMem+1;
+ iTab = pParse->nTab;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
Table *pTab = (Table*)sqliteHashData(k);
- analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
+ analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
}
loadAnalysis(pParse, iDb);
}
@@ -81001,7 +82920,7 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
}else{
openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
}
- analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
+ analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab);
loadAnalysis(pParse, iDb);
}
@@ -81085,6 +83004,52 @@ struct analysisInfo {
};
/*
+** The first argument points to a nul-terminated string containing a
+** list of space separated integers. Read the first nOut of these into
+** the array aOut[].
+*/
+static void decodeIntArray(
+ char *zIntArray, /* String containing int array to decode */
+ int nOut, /* Number of slots in aOut[] */
+ tRowcnt *aOut, /* Store integers here */
+ Index *pIndex /* Handle extra flags for this index, if not NULL */
+){
+ char *z = zIntArray;
+ int c;
+ int i;
+ tRowcnt v;
+
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( z==0 ) z = "";
+#else
+ if( NEVER(z==0) ) z = "";
+#endif
+ for(i=0; *z && i<nOut; i++){
+ v = 0;
+ while( (c=z[0])>='0' && c<='9' ){
+ v = v*10 + c - '0';
+ z++;
+ }
+ aOut[i] = v;
+ if( *z==' ' ) z++;
+ }
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+ assert( pIndex!=0 );
+#else
+ if( pIndex )
+#endif
+ {
+ if( strcmp(z, "unordered")==0 ){
+ pIndex->bUnordered = 1;
+ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
+ int v32 = 0;
+ sqlite3GetInt32(z+3, &v32);
+ pIndex->szIdxRow = sqlite3LogEst(v32);
+ }
+ }
+}
+
+/*
** This callback is invoked once for each index when reading the
** sqlite_stat1 table.
**
@@ -81099,8 +83064,6 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
analysisInfo *pInfo = (analysisInfo*)pData;
Index *pIndex;
Table *pTable;
- int i, c, n;
- tRowcnt v;
const char *z;
assert( argc==3 );
@@ -81113,28 +83076,25 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
if( pTable==0 ){
return 0;
}
- if( argv[1] ){
- pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
- }else{
+ if( argv[1]==0 ){
pIndex = 0;
+ }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){
+ pIndex = sqlite3PrimaryKeyIndex(pTable);
+ }else{
+ pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
}
- n = pIndex ? pIndex->nColumn : 0;
z = argv[2];
- for(i=0; *z && i<=n; i++){
- v = 0;
- while( (c=z[0])>='0' && c<='9' ){
- v = v*10 + c - '0';
- z++;
- }
- if( i==0 ) pTable->nRowEst = v;
- if( pIndex==0 ) break;
- pIndex->aiRowEst[i] = v;
- if( *z==' ' ) z++;
- if( strcmp(z, "unordered")==0 ){
- pIndex->bUnordered = 1;
- break;
- }
+
+ if( pIndex ){
+ decodeIntArray((char*)z, pIndex->nKeyCol+1, pIndex->aiRowEst, pIndex);
+ if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
+ }else{
+ Index fakeIdx;
+ fakeIdx.szIdxRow = pTable->szTabRow;
+ decodeIntArray((char*)z, 1, &pTable->nRowEst, &fakeIdx);
+ pTable->szTabRow = fakeIdx.szIdxRow;
}
+
return 0;
}
@@ -81143,14 +83103,12 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** and its contents.
*/
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pIdx->aSample ){
int j;
for(j=0; j<pIdx->nSample; j++){
IndexSample *p = &pIdx->aSample[j];
- if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
- sqlite3DbFree(db, p->u.z);
- }
+ sqlite3DbFree(db, p->p);
}
sqlite3DbFree(db, pIdx->aSample);
}
@@ -81161,31 +83119,92 @@ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx);
-#endif
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
}
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
-** Load content from the sqlite_stat3 table into the Index.aSample[]
-** arrays of all indices.
+** Populate the pIdx->aAvgEq[] array based on the samples currently
+** stored in pIdx->aSample[].
*/
-static int loadStat3(sqlite3 *db, const char *zDb){
+static void initAvgEq(Index *pIdx){
+ if( pIdx ){
+ IndexSample *aSample = pIdx->aSample;
+ IndexSample *pFinal = &aSample[pIdx->nSample-1];
+ int iCol;
+ for(iCol=0; iCol<pIdx->nKeyCol; iCol++){
+ int i; /* Used to iterate through samples */
+ tRowcnt sumEq = 0; /* Sum of the nEq values */
+ tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
+ tRowcnt avgEq = 0;
+ tRowcnt nDLt = pFinal->anDLt[iCol];
+
+ /* Set nSum to the number of distinct (iCol+1) field prefixes that
+ ** occur in the stat4 table for this index before pFinal. Set
+ ** sumEq to the sum of the nEq values for column iCol for the same
+ ** set (adding the value only once where there exist dupicate
+ ** prefixes). */
+ for(i=0; i<(pIdx->nSample-1); i++){
+ if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
+ sumEq += aSample[i].anEq[iCol];
+ nSum++;
+ }
+ }
+ if( nDLt>nSum ){
+ avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
+ }
+ if( avgEq==0 ) avgEq = 1;
+ pIdx->aAvgEq[iCol] = avgEq;
+ if( pIdx->nSampleCol==1 ) break;
+ }
+ }
+}
+
+/*
+** Look up an index by name. Or, if the name of a WITHOUT ROWID table
+** is supplied instead, find the PRIMARY KEY index for that table.
+*/
+static Index *findIndexOrPrimaryKey(
+ sqlite3 *db,
+ const char *zName,
+ const char *zDb
+){
+ Index *pIdx = sqlite3FindIndex(db, zName, zDb);
+ if( pIdx==0 ){
+ Table *pTab = sqlite3FindTable(db, zName, zDb);
+ if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
+ }
+ return pIdx;
+}
+
+/*
+** Load the content from either the sqlite_stat4 or sqlite_stat3 table
+** into the relevant Index.aSample[] arrays.
+**
+** Arguments zSql1 and zSql2 must point to SQL statements that return
+** data equivalent to the following (statements are different for stat3,
+** see the caller of this function for details):
+**
+** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
+** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
+**
+** where %Q is replaced with the database name before the SQL is executed.
+*/
+static int loadStatTbl(
+ sqlite3 *db, /* Database handle */
+ int bStat3, /* Assume single column records only */
+ const char *zSql1, /* SQL statement 1 (see above) */
+ const char *zSql2, /* SQL statement 2 (see above) */
+ const char *zDb /* Database name (e.g. "main") */
+){
int rc; /* Result codes from subroutines */
sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
char *zSql; /* Text of the SQL statement */
Index *pPrevIdx = 0; /* Previous index in the loop */
- int idx = 0; /* slot in pIdx->aSample[] for next sample */
- int eType; /* Datatype of a sample */
IndexSample *pSample; /* A slot in pIdx->aSample[] */
assert( db->lookaside.bEnabled==0 );
- if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
- return SQLITE_OK;
- }
-
- zSql = sqlite3MPrintf(db,
- "SELECT idx,count(*) FROM %Q.sqlite_stat3"
- " GROUP BY idx", zDb);
+ zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
@@ -81194,30 +83213,51 @@ static int loadStat3(sqlite3 *db, const char *zDb){
if( rc ) return rc;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
+ int nIdxCol = 1; /* Number of columns in stat4 records */
+ int nAvgCol = 1; /* Number of entries in Index.aAvgEq */
+
char *zIndex; /* Index name */
Index *pIdx; /* Pointer to the index object */
int nSample; /* Number of samples */
+ int nByte; /* Bytes of space required */
+ int i; /* Bytes of space required */
+ tRowcnt *pSpace;
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
nSample = sqlite3_column_int(pStmt, 1);
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
- if( pIdx==0 ) continue;
- assert( pIdx->nSample==0 );
- pIdx->nSample = nSample;
- pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample));
- pIdx->avgEq = pIdx->aiRowEst[1];
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
+ assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
+ /* Index.nSample is non-zero at this point if data has already been
+ ** loaded from the stat4 table. In this case ignore stat3 data. */
+ if( pIdx==0 || pIdx->nSample ) continue;
+ if( bStat3==0 ){
+ nIdxCol = pIdx->nKeyCol+1;
+ nAvgCol = pIdx->nKeyCol;
+ }
+ pIdx->nSampleCol = nIdxCol;
+ nByte = sizeof(IndexSample) * nSample;
+ nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
+ nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
+
+ pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
- db->mallocFailed = 1;
sqlite3_finalize(pStmt);
return SQLITE_NOMEM;
}
+ pSpace = (tRowcnt*)&pIdx->aSample[nSample];
+ pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
+ for(i=0; i<nSample; i++){
+ pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
+ pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
+ pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
+ }
+ assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) );
}
rc = sqlite3_finalize(pStmt);
if( rc ) return rc;
- zSql = sqlite3MPrintf(db,
- "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
+ zSql = sqlite3MPrintf(db, zSql2, zDb);
if( !zSql ){
return SQLITE_NOMEM;
}
@@ -81226,86 +83266,88 @@ static int loadStat3(sqlite3 *db, const char *zDb){
if( rc ) return rc;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
- char *zIndex; /* Index name */
- Index *pIdx; /* Pointer to the index object */
- int i; /* Loop counter */
- tRowcnt sumEq; /* Sum of the nEq values */
+ char *zIndex; /* Index name */
+ Index *pIdx; /* Pointer to the index object */
+ int nCol = 1; /* Number of columns in index */
zIndex = (char *)sqlite3_column_text(pStmt, 0);
if( zIndex==0 ) continue;
- pIdx = sqlite3FindIndex(db, zIndex, zDb);
+ pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
if( pIdx==0 ) continue;
- if( pIdx==pPrevIdx ){
- idx++;
- }else{
+ /* This next condition is true if data has already been loaded from
+ ** the sqlite_stat4 table. In this case ignore stat3 data. */
+ nCol = pIdx->nSampleCol;
+ if( bStat3 && nCol>1 ) continue;
+ if( pIdx!=pPrevIdx ){
+ initAvgEq(pPrevIdx);
pPrevIdx = pIdx;
- idx = 0;
- }
- assert( idx<pIdx->nSample );
- pSample = &pIdx->aSample[idx];
- pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1);
- pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2);
- pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3);
- if( idx==pIdx->nSample-1 ){
- if( pSample->nDLt>0 ){
- for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
- pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;
- }
- if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
- }
- eType = sqlite3_column_type(pStmt, 4);
- pSample->eType = (u8)eType;
- switch( eType ){
- case SQLITE_INTEGER: {
- pSample->u.i = sqlite3_column_int64(pStmt, 4);
- break;
- }
- case SQLITE_FLOAT: {
- pSample->u.r = sqlite3_column_double(pStmt, 4);
- break;
- }
- case SQLITE_NULL: {
- break;
- }
- default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {
- const char *z = (const char *)(
- (eType==SQLITE_BLOB) ?
- sqlite3_column_blob(pStmt, 4):
- sqlite3_column_text(pStmt, 4)
- );
- int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
- pSample->nByte = n;
- if( n < 1){
- pSample->u.z = 0;
- }else{
- pSample->u.z = sqlite3DbMallocRaw(db, n);
- if( pSample->u.z==0 ){
- db->mallocFailed = 1;
- sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
- }
- memcpy(pSample->u.z, z, n);
- }
- }
}
+ pSample = &pIdx->aSample[pIdx->nSample];
+ decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0);
+ decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0);
+
+ /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
+ ** This is in case the sample record is corrupted. In that case, the
+ ** sqlite3VdbeRecordCompare() may read up to two varints past the
+ ** end of the allocated buffer before it realizes it is dealing with
+ ** a corrupt record. Adding the two 0x00 bytes prevents this from causing
+ ** a buffer overread. */
+ pSample->n = sqlite3_column_bytes(pStmt, 4);
+ pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
+ if( pSample->p==0 ){
+ sqlite3_finalize(pStmt);
+ return SQLITE_NOMEM;
+ }
+ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+ pIdx->nSample++;
}
- return sqlite3_finalize(pStmt);
+ rc = sqlite3_finalize(pStmt);
+ if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
+ return rc;
+}
+
+/*
+** Load content from the sqlite_stat4 and sqlite_stat3 tables into
+** the Index.aSample[] arrays of all indices.
+*/
+static int loadStat4(sqlite3 *db, const char *zDb){
+ int rc = SQLITE_OK; /* Result codes from subroutines */
+
+ assert( db->lookaside.bEnabled==0 );
+ if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
+ rc = loadStatTbl(db, 0,
+ "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
+ "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
+ zDb
+ );
+ }
+
+ if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
+ rc = loadStatTbl(db, 1,
+ "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx",
+ "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
+ zDb
+ );
+ }
+
+ return rc;
}
-#endif /* SQLITE_ENABLE_STAT3 */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
-** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
+** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
-** arrays. The contents of sqlite_stat3 are used to populate the
+** arrays. The contents of sqlite_stat3/4 are used to populate the
** Index.aSample[] arrays.
**
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
-** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined
-** during compilation and the sqlite_stat3 table is present, no data is
+** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined
+** during compilation and the sqlite_stat3/4 table is present, no data is
** read from it.
**
-** If SQLITE_ENABLE_STAT3 was defined during compilation and the
-** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
+** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the
+** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
** returned. However, in this case, data is read from the sqlite_stat1
** table (if it is present) before returning.
**
@@ -81327,7 +83369,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx);
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
@@ -81351,12 +83393,12 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
}
- /* Load the statistics from the sqlite_stat3 table. */
-#ifdef SQLITE_ENABLE_STAT3
+ /* Load the statistics from the sqlite_stat4 table. */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK ){
int lookasideEnabled = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0;
- rc = loadStat3(db, sInfo.zDatabase);
+ rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bEnabled = lookasideEnabled;
}
#endif
@@ -81531,6 +83573,9 @@ static void attachFunc(
sqlite3PagerLockingMode(pPager, db->dfltLockMode);
sqlite3BtreeSecureDelete(aNew->pBt,
sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+ sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
+#endif
}
aNew->safety_level = 3;
aNew->zName = sqlite3DbStrDup(db, zName);
@@ -81749,8 +83794,7 @@ attach_end:
SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
static const FuncDef detach_func = {
1, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
+ SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
detachFunc, /* xFunc */
@@ -81771,8 +83815,7 @@ SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){
SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
static const FuncDef attach_func = {
3, /* nArg */
- SQLITE_UTF8, /* iPrefEnc */
- 0, /* flags */
+ SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
attachFunc, /* xFunc */
@@ -81789,11 +83832,8 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p
/*
** Initialize a DbFixer structure. This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
-**
-** The return value indicates whether or not fixation is required. TRUE
-** means we do need to fix the database references, FALSE means we do not.
*/
-SQLITE_PRIVATE int sqlite3FixInit(
+SQLITE_PRIVATE void sqlite3FixInit(
DbFixer *pFix, /* The fixer to be initialized */
Parse *pParse, /* Error messages will be written here */
int iDb, /* This is the database that must be used */
@@ -81802,7 +83842,6 @@ SQLITE_PRIVATE int sqlite3FixInit(
){
sqlite3 *db;
- if( NEVER(iDb<0) || iDb==1 ) return 0;
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
@@ -81810,7 +83849,7 @@ SQLITE_PRIVATE int sqlite3FixInit(
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
- return 1;
+ pFix->bVarOnly = (iDb==1);
}
/*
@@ -81838,15 +83877,17 @@ SQLITE_PRIVATE int sqlite3FixSrcList(
if( NEVER(pList==0) ) return 0;
zDb = pFix->zDb;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
- sqlite3ErrorMsg(pFix->pParse,
- "%s %T cannot reference objects in database %s",
- pFix->zType, pFix->pName, pItem->zDatabase);
- return 1;
+ if( pFix->bVarOnly==0 ){
+ if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
+ sqlite3ErrorMsg(pFix->pParse,
+ "%s %T cannot reference objects in database %s",
+ pFix->zType, pFix->pName, pItem->zDatabase);
+ return 1;
+ }
+ sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
+ pItem->zDatabase = 0;
+ pItem->pSchema = pFix->pSchema;
}
- sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
- pItem->zDatabase = 0;
- pItem->pSchema = pFix->pSchema;
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
@@ -81869,9 +83910,21 @@ SQLITE_PRIVATE int sqlite3FixSelect(
if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
return 1;
}
+ if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){
+ return 1;
+ }
if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
return 1;
}
+ if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
+ return 1;
+ }
+ if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
+ return 1;
+ }
pSelect = pSelect->pPrior;
}
return 0;
@@ -81881,7 +83934,15 @@ SQLITE_PRIVATE int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
+ if( pExpr->op==TK_VARIABLE ){
+ if( pFix->pParse->db->init.busy ){
+ pExpr->op = TK_NULL;
+ }else{
+ sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType);
+ return 1;
+ }
+ }
+ if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
@@ -82335,7 +84396,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
*/
if( pParse->cookieGoto>0 ){
yDbMask mask;
- int iDb;
+ int iDb, i, addr;
sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
if( (mask & pParse->cookieMask)==0 ) continue;
@@ -82349,14 +84410,11 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- {
- int i;
- for(i=0; i<pParse->nVtabLock; i++){
- char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
- sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
- }
- pParse->nVtabLock = 0;
+ for(i=0; i<pParse->nVtabLock; i++){
+ char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
+ sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
}
+ pParse->nVtabLock = 0;
#endif
/* Once all the cookies have been verified and transactions opened,
@@ -82369,8 +84427,18 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
*/
sqlite3AutoincrementBegin(pParse);
+ /* Code constant expressions that where factored out of inner loops */
+ addr = pParse->cookieGoto;
+ if( pParse->pConstExpr ){
+ ExprList *pEL = pParse->pConstExpr;
+ pParse->cookieGoto = 0;
+ for(i=0; i<pEL->nExpr; i++){
+ sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
+ }
+ }
+
/* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
}
}
@@ -82378,10 +84446,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
-#ifdef SQLITE_DEBUG
- FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
- sqlite3VdbeTrace(v, trace);
-#endif
assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */
/* A minimum of one cursor is required if autoincrement is used
* See ticket [a696379c1f08866] */
@@ -82567,7 +84631,10 @@ static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
+ if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
+ sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3DbFree(db, p->zColAff);
+ if( p->isResized ) sqlite3DbFree(db, p->azColl);
sqlite3DbFree(db, p);
}
@@ -82825,8 +84892,7 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
Vdbe *v = sqlite3GetVdbe(p);
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
- sqlite3VdbeAddOp3(v, OP_OpenWrite, 0, MASTER_ROOT, iDb);
- sqlite3VdbeChangeP4(v, -1, (char *)5, P4_INT32); /* 5 column table */
+ sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
if( p->nTab==0 ){
p->nTab = 1;
}
@@ -82932,6 +84998,27 @@ SQLITE_PRIVATE int sqlite3CheckObjectName(Parse *pParse, const char *zName){
}
/*
+** Return the PRIMARY KEY index of a table
+*/
+SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){
+ Index *p;
+ for(p=pTab->pIndex; p && p->autoIndex!=2; p=p->pNext){}
+ return p;
+}
+
+/*
+** Return the column of index pIdx that corresponds to table
+** column iCol. Return -1 if not found.
+*/
+SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
+ int i;
+ for(i=0; i<pIdx->nColumn; i++){
+ if( iCol==pIdx->aiColumn[i] ) return i;
+ }
+ return -1;
+}
+
+/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement. In particular, this routine is called
@@ -83063,7 +85150,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->nRowEst = 1000000;
+ pTable->nRowEst = 1048576;
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
@@ -83130,7 +85217,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
}else
#endif
{
- sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
+ pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
@@ -83210,6 +85297,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
** be called next to set pCol->affinity correctly.
*/
pCol->affinity = SQLITE_AFF_NONE;
+ pCol->szEst = 1;
p->nCol++;
}
@@ -83251,15 +85339,18 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
+ const char *zChar = 0;
- if( zIn ) while( zIn[0] ){
+ if( zIn==0 ) return aff;
+ while( zIn[0] ){
h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
- aff = SQLITE_AFF_TEXT;
+ aff = SQLITE_AFF_TEXT;
+ zChar = zIn;
}else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */
aff = SQLITE_AFF_TEXT;
}else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */
@@ -83267,6 +85358,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
}else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */
&& (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
aff = SQLITE_AFF_NONE;
+ if( zIn[0]=='(' ) zChar = zIn;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l') /* REAL */
&& aff==SQLITE_AFF_NUMERIC ){
@@ -83284,6 +85376,28 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
}
}
+ /* If pszEst is not NULL, store an estimate of the field size. The
+ ** estimate is scaled so that the size of an integer is 1. */
+ if( pszEst ){
+ *pszEst = 1; /* default size is approx 4 bytes */
+ if( aff<=SQLITE_AFF_NONE ){
+ if( zChar ){
+ while( zChar[0] ){
+ if( sqlite3Isdigit(zChar[0]) ){
+ int v = 0;
+ sqlite3GetInt32(zChar, &v);
+ v = v/4 + 1;
+ if( v>255 ) v = 255;
+ *pszEst = v; /* BLOB(k), VARCHAR(k), CHAR(k) -> r=(k/4+1) */
+ break;
+ }
+ zChar++;
+ }
+ }else{
+ *pszEst = 5; /* BLOB, TEXT, CLOB -> r=5 (approx 20 bytes)*/
+ }
+ }
+ }
return aff;
}
@@ -83305,7 +85419,7 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
pCol = &p->aCol[p->nCol-1];
assert( pCol->zType==0 );
pCol->zType = sqlite3NameFromToken(pParse->db, pType);
- pCol->affinity = sqlite3AffinityType(pCol->zType);
+ pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
}
/*
@@ -83371,6 +85485,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
Table *pTab = pParse->pNewTable;
char *zType = 0;
int iCol = -1, i;
+ int nTerm;
if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
if( pTab->tabFlags & TF_HasPrimaryKey ){
sqlite3ErrorMsg(pParse,
@@ -83381,38 +85496,43 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
if( pList==0 ){
iCol = pTab->nCol - 1;
pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
+ nTerm = 1;
}else{
- for(i=0; i<pList->nExpr; i++){
+ nTerm = pList->nExpr;
+ for(i=0; i<nTerm; i++){
for(iCol=0; iCol<pTab->nCol; iCol++){
if( sqlite3StrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ){
+ pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
+ zType = pTab->aCol[iCol].zType;
break;
}
}
- if( iCol<pTab->nCol ){
- pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
- }
}
- if( pList->nExpr>1 ) iCol = -1;
- }
- if( iCol>=0 && iCol<pTab->nCol ){
- zType = pTab->aCol[iCol].zType;
}
- if( zType && sqlite3StrICmp(zType, "INTEGER")==0
- && sortOrder==SQLITE_SO_ASC ){
+ if( nTerm==1
+ && zType && sqlite3StrICmp(zType, "INTEGER")==0
+ && sortOrder==SQLITE_SO_ASC
+ ){
pTab->iPKey = iCol;
pTab->keyConf = (u8)onError;
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
+ if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
}else{
+ Vdbe *v = pParse->pVdbe;
Index *p;
- p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
+ if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
+ p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
+ 0, sortOrder, 0);
if( p ){
p->autoIndex = 2;
+ if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
}
pList = 0;
}
@@ -83461,6 +85581,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
if( sqlite3LocateCollSeq(pParse, zColl) ){
Index *pIdx;
+ sqlite3DbFree(db, p->aCol[i].zColl);
p->aCol[i].zColl = zColl;
/* If the column is declared as "<name> PRIMARY KEY COLLATE <type>",
@@ -83468,7 +85589,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
** collation type was added. Correct this if it is the case.
*/
for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
- assert( pIdx->nColumn==1 );
+ assert( pIdx->nKeyCol==1 );
if( pIdx->aiColumn[0]==i ){
pIdx->azColl[0] = p->aCol[i].zColl;
}
@@ -83651,7 +85772,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){
zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
len = sqlite3Strlen30(zType);
assert( pCol->affinity==SQLITE_AFF_NONE
- || pCol->affinity==sqlite3AffinityType(zType) );
+ || pCol->affinity==sqlite3AffinityType(zType, 0) );
memcpy(&zStmt[k], zType, len);
k += len;
assert( k<=n );
@@ -83661,6 +85782,191 @@ static char *createTableStmt(sqlite3 *db, Table *p){
}
/*
+** Resize an Index object to hold N columns total. Return SQLITE_OK
+** on success and SQLITE_NOMEM on an OOM error.
+*/
+static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
+ char *zExtra;
+ int nByte;
+ if( pIdx->nColumn>=N ) return SQLITE_OK;
+ assert( pIdx->isResized==0 );
+ nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
+ zExtra = sqlite3DbMallocZero(db, nByte);
+ if( zExtra==0 ) return SQLITE_NOMEM;
+ memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
+ pIdx->azColl = (char**)zExtra;
+ zExtra += sizeof(char*)*N;
+ memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn);
+ pIdx->aiColumn = (i16*)zExtra;
+ zExtra += sizeof(i16)*N;
+ memcpy(zExtra, pIdx->aSortOrder, pIdx->nColumn);
+ pIdx->aSortOrder = (u8*)zExtra;
+ pIdx->nColumn = N;
+ pIdx->isResized = 1;
+ return SQLITE_OK;
+}
+
+/*
+** Estimate the total row width for a table.
+*/
+static void estimateTableWidth(Table *pTab){
+ unsigned wTable = 0;
+ const Column *pTabCol;
+ int i;
+ for(i=pTab->nCol, pTabCol=pTab->aCol; i>0; i--, pTabCol++){
+ wTable += pTabCol->szEst;
+ }
+ if( pTab->iPKey<0 ) wTable++;
+ pTab->szTabRow = sqlite3LogEst(wTable*4);
+}
+
+/*
+** Estimate the average size of a row for an index.
+*/
+static void estimateIndexWidth(Index *pIdx){
+ unsigned wIndex = 0;
+ int i;
+ const Column *aCol = pIdx->pTable->aCol;
+ for(i=0; i<pIdx->nColumn; i++){
+ i16 x = pIdx->aiColumn[i];
+ assert( x<pIdx->pTable->nCol );
+ wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst;
+ }
+ pIdx->szIdxRow = sqlite3LogEst(wIndex*4);
+}
+
+/* Return true if value x is found any of the first nCol entries of aiCol[]
+*/
+static int hasColumn(const i16 *aiCol, int nCol, int x){
+ while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1;
+ return 0;
+}
+
+/*
+** This routine runs at the end of parsing a CREATE TABLE statement that
+** has a WITHOUT ROWID clause. The job of this routine is to convert both
+** internal schema data structures and the generated VDBE code so that they
+** are appropriate for a WITHOUT ROWID table instead of a rowid table.
+** Changes include:
+**
+** (1) Convert the OP_CreateTable into an OP_CreateIndex. There is
+** no rowid btree for a WITHOUT ROWID. Instead, the canonical
+** data storage is a covering index btree.
+** (2) Bypass the creation of the sqlite_master table entry
+** for the PRIMARY KEY as the the primary key index is now
+** identified by the sqlite_master table entry of the table itself.
+** (3) Set the Index.tnum of the PRIMARY KEY Index object in the
+** schema to the rootpage from the main table.
+** (4) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
+** (5) Add all table columns to the PRIMARY KEY Index object
+** so that the PRIMARY KEY is a covering index. The surplus
+** columns are part of KeyInfo.nXField and are not used for
+** sorting or lookup or uniqueness checks.
+** (6) Replace the rowid tail on all automatically generated UNIQUE
+** indices with the PRIMARY KEY columns.
+*/
+static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
+ Index *pIdx;
+ Index *pPk;
+ int nPk;
+ int i, j;
+ sqlite3 *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+
+ /* Convert the OP_CreateTable opcode that would normally create the
+ ** root-page for the table into a OP_CreateIndex opcode. The index
+ ** created will become the PRIMARY KEY index.
+ */
+ if( pParse->addrCrTab ){
+ assert( v );
+ sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
+ }
+
+ /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
+ ** table entry.
+ */
+ if( pParse->addrSkipPK ){
+ assert( v );
+ sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
+ }
+
+ /* Locate the PRIMARY KEY index. Or, if this table was originally
+ ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
+ */
+ if( pTab->iPKey>=0 ){
+ ExprList *pList;
+ pList = sqlite3ExprListAppend(pParse, 0, 0);
+ if( pList==0 ) return;
+ pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+ pTab->aCol[pTab->iPKey].zName);
+ pList->a[0].sortOrder = pParse->iPkSortOrder;
+ assert( pParse->pNewTable==pTab );
+ pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
+ if( pPk==0 ) return;
+ pPk->autoIndex = 2;
+ pTab->iPKey = -1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ }
+ pPk->isCovering = 1;
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+
+ /* Make sure every column of the PRIMARY KEY is NOT NULL */
+ for(i=0; i<nPk; i++){
+ pTab->aCol[pPk->aiColumn[i]].notNull = 1;
+ }
+ pPk->uniqNotNull = 1;
+
+ /* The root page of the PRIMARY KEY is the table root page */
+ pPk->tnum = pTab->tnum;
+
+ /* Update the in-memory representation of all UNIQUE indices by converting
+ ** the final rowid column into one or more columns of the PRIMARY KEY.
+ */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int n;
+ if( pIdx->autoIndex==2 ) continue;
+ for(i=n=0; i<nPk; i++){
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++;
+ }
+ if( n==0 ){
+ /* This index is a superset of the primary key */
+ pIdx->nColumn = pIdx->nKeyCol;
+ continue;
+ }
+ if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return;
+ for(i=0, j=pIdx->nKeyCol; i<nPk; i++){
+ if( !hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){
+ pIdx->aiColumn[j] = pPk->aiColumn[i];
+ pIdx->azColl[j] = pPk->azColl[i];
+ j++;
+ }
+ }
+ assert( pIdx->nColumn>=pIdx->nKeyCol+n );
+ assert( pIdx->nColumn>=j );
+ }
+
+ /* Add all table columns to the PRIMARY KEY index
+ */
+ if( nPk<pTab->nCol ){
+ if( resizeIndexObject(db, pPk, pTab->nCol) ) return;
+ for(i=0, j=nPk; i<pTab->nCol; i++){
+ if( !hasColumn(pPk->aiColumn, j, i) ){
+ assert( j<pPk->nColumn );
+ pPk->aiColumn[j] = i;
+ pPk->azColl[j] = "BINARY";
+ j++;
+ }
+ }
+ assert( pPk->nColumn==j );
+ assert( pTab->nCol==j );
+ }else{
+ pPk->nColumn = pTab->nCol;
+ }
+}
+
+/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
@@ -83683,12 +85989,14 @@ static char *createTableStmt(sqlite3 *db, Table *p){
SQLITE_PRIVATE void sqlite3EndTable(
Parse *pParse, /* Parse context */
Token *pCons, /* The ',' token after the last column defn. */
- Token *pEnd, /* The final ')' token in the CREATE TABLE */
+ Token *pEnd, /* The ')' before options in the CREATE TABLE */
+ u8 tabOpts, /* Extra table options. Usually 0. */
Select *pSelect /* Select from a "CREATE ... AS SELECT" */
){
- Table *p;
- sqlite3 *db = pParse->db;
- int iDb;
+ Table *p; /* The new table */
+ sqlite3 *db = pParse->db; /* The database connection */
+ int iDb; /* Database in which the table lives */
+ Index *pIdx; /* An implied index of the table */
if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
return;
@@ -83698,43 +86006,45 @@ SQLITE_PRIVATE void sqlite3EndTable(
assert( !db->init.busy || !pSelect );
+ /* If the db->init.busy is 1 it means we are reading the SQL off the
+ ** "sqlite_master" or "sqlite_temp_master" table on the disk.
+ ** So do not write to the disk again. Extract the root page number
+ ** for the table from the db->init.newTnum field. (The page number
+ ** should have been put there by the sqliteOpenCb routine.)
+ */
+ if( db->init.busy ){
+ p->tnum = db->init.newTnum;
+ }
+
+ /* Special processing for WITHOUT ROWID Tables */
+ if( tabOpts & TF_WithoutRowid ){
+ if( (p->tabFlags & TF_Autoincrement) ){
+ sqlite3ErrorMsg(pParse,
+ "AUTOINCREMENT not allowed on WITHOUT ROWID tables");
+ return;
+ }
+ if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
+ sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
+ }else{
+ p->tabFlags |= TF_WithoutRowid;
+ convertToWithoutRowidTable(pParse, p);
+ }
+ }
+
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
*/
if( p->pCheck ){
- SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
- NameContext sNC; /* Name context for pParse->pNewTable */
- ExprList *pList; /* List of all CHECK constraints */
- int i; /* Loop counter */
-
- memset(&sNC, 0, sizeof(sNC));
- memset(&sSrc, 0, sizeof(sSrc));
- sSrc.nSrc = 1;
- sSrc.a[0].zName = p->zName;
- sSrc.a[0].pTab = p;
- sSrc.a[0].iCursor = -1;
- sNC.pParse = pParse;
- sNC.pSrcList = &sSrc;
- sNC.ncFlags = NC_IsCheck;
- pList = p->pCheck;
- for(i=0; i<pList->nExpr; i++){
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
- return;
- }
- }
+ sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
- /* If the db->init.busy is 1 it means we are reading the SQL off the
- ** "sqlite_master" or "sqlite_temp_master" table on the disk.
- ** So do not write to the disk again. Extract the root page number
- ** for the table from the db->init.newTnum field. (The page number
- ** should have been put there by the sqliteOpenCb routine.)
- */
- if( db->init.busy ){
- p->tnum = db->init.newTnum;
+ /* Estimate the average row size for the table and for all implied indices */
+ estimateTableWidth(p);
+ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){
+ estimateIndexWidth(pIdx);
}
/* If not initializing, then create a record for the new table
@@ -83810,7 +86120,9 @@ SQLITE_PRIVATE void sqlite3EndTable(
if( pSelect ){
zStmt = createTableStmt(db, p);
}else{
- n = (int)(pEnd->z - pParse->sNameToken.z) + 1;
+ Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd;
+ n = (int)(pEnd2->z - pParse->sNameToken.z);
+ if( pEnd2->z[0]!=';' ) n += pEnd2->n;
zStmt = sqlite3MPrintf(db,
"CREATE %s %.*s", zType2, n, pParse->sNameToken.z
);
@@ -83853,7 +86165,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
- sqlite3MPrintf(db, "tbl_name='%q'", p->zName));
+ sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
}
@@ -83923,9 +86235,8 @@ SQLITE_PRIVATE void sqlite3CreateView(
}
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
- if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
- && sqlite3FixSelect(&sFix, pSelect)
- ){
+ sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
+ if( sqlite3FixSelect(&sFix, pSelect) ){
sqlite3SelectDelete(db, pSelect);
return;
}
@@ -83959,7 +86270,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */
- sqlite3EndTable(pParse, 0, &sEnd, 0);
+ sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
return;
}
#endif /* SQLITE_OMIT_VIEW */
@@ -84225,7 +86536,7 @@ static void sqlite3ClearStatTables(
){
int i;
const char *zDbName = pParse->db->aDb[iDb].zName;
- for(i=1; i<=3; i++){
+ for(i=1; i<=4; i++){
char zTab[24];
sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
@@ -84414,8 +86725,8 @@ exit_drop_table:
** currently under construction. pFromCol determines which columns
** in the current table point to the foreign key. If pFromCol==0 then
** connect the key to the last column inserted. pTo is the name of
-** the table referred to. pToCol is a list of tables in the other
-** pTo table that the foreign key points to. flags contains all
+** the table referred to (a.k.a the "parent" table). pToCol is a list
+** of tables in the parent pTo table. flags contains all
** information about the conflict resolution algorithms specified
** in the ON DELETE, ON UPDATE and ON INSERT clauses.
**
@@ -84575,6 +86886,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
int addr1; /* Address of top of loop */
int addr2; /* Address to jump to for next iteration */
int tnum; /* Root page of index */
+ int iPartIdxLabel; /* Jump to this label to skip a row */
Vdbe *v; /* Generate code into this virtual machine */
KeyInfo *pKey; /* KeyInfo for index */
int regRecord; /* Register holding assemblied index record */
@@ -84597,16 +86909,13 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
tnum = memRootPage;
}else{
tnum = pIndex->tnum;
- sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
}
- pKey = sqlite3IndexKeyinfo(pParse, pIndex);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
- (char *)pKey, P4_KEYINFO_HANDOFF);
- sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+ pKey = sqlite3KeyInfoOfIndex(pParse, pIndex);
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
- sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
+ sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
+ sqlite3KeyInfoRef(pKey), P4_KEYINFO);
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
@@ -84614,19 +86923,25 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
+ sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
+ sqlite3VdbeResolveLabel(v, iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
+ if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
+ sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
+ (char *)pKey, P4_KEYINFO);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
+
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
- if( pIndex->onError!=OE_None ){
+ assert( pKey!=0 || db->mallocFailed || pParse->nErr );
+ if( pIndex->onError!=OE_None && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
- OE_Abort, "indexed columns are not unique", P4_STATIC
- );
+ sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
+ pKey->nField - pIndex->nKeyCol);
+ sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
@@ -84643,6 +86958,41 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}
/*
+** Allocate heap space to hold an Index object with nCol columns.
+**
+** Increase the allocation size to provide an extra nExtra bytes
+** of 8-byte aligned space after the Index object and return a
+** pointer to this extra space in *ppExtra.
+*/
+SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
+ sqlite3 *db, /* Database connection */
+ i16 nCol, /* Total number of columns in the index */
+ int nExtra, /* Number of bytes of extra space to alloc */
+ char **ppExtra /* Pointer to the "extra" space */
+){
+ Index *p; /* Allocated index object */
+ int nByte; /* Bytes of space for Index object + arrays */
+
+ nByte = ROUND8(sizeof(Index)) + /* Index structure */
+ ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
+ ROUND8(sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
+ sizeof(i16)*nCol + /* Index.aiColumn */
+ sizeof(u8)*nCol); /* Index.aSortOrder */
+ p = sqlite3DbMallocZero(db, nByte + nExtra);
+ if( p ){
+ char *pExtra = ((char*)p)+ROUND8(sizeof(Index));
+ p->azColl = (char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol);
+ p->aiRowEst = (tRowcnt*)pExtra; pExtra += sizeof(tRowcnt)*(nCol+1);
+ p->aiColumn = (i16*)pExtra; pExtra += sizeof(i16)*nCol;
+ p->aSortOrder = (u8*)pExtra;
+ p->nColumn = nCol;
+ p->nKeyCol = nCol - 1;
+ *ppExtra = ((char*)p) + nByte;
+ }
+ return p;
+}
+
+/*
** Create a new index for an SQL table. pName1.pName2 is the name of the index
** and pTblList is the name of the table that is to be indexed. Both will
** be NULL for a primary key or an index that is created to satisfy a
@@ -84666,7 +87016,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
ExprList *pList, /* A list of columns to be indexed */
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
Token *pStart, /* The CREATE token that begins this statement */
- Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
+ Expr *pPIWhere, /* WHERE clause for partial indices */
int sortOrder, /* Sort order of primary key when pList==NULL */
int ifNotExist /* Omit error if index already exists */
){
@@ -84676,7 +87026,6 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
char *zName = 0; /* Name of the index */
int nName; /* Number of characters in zName */
int i, j;
- Token nullId; /* Fake token for an empty ID list */
DbFixer sFix; /* For assigning database names to pTable */
int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */
sqlite3 *db = pParse->db;
@@ -84684,11 +87033,12 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
- int nCol;
- int nExtra = 0;
- char *zExtra;
+ const Column *pTabCol; /* A column in the table */
+ int nExtra = 0; /* Space allocated for zExtra[] */
+ int nExtraCol; /* Number of extra columns needed */
+ char *zExtra = 0; /* Extra space after the Index object */
+ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */
- assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed || IN_DECLARE_VTAB ){
goto exit_create_index;
@@ -84724,9 +87074,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
}
#endif
- if( sqlite3FixInit(&sFix, pParse, iDb, "index", pName) &&
- sqlite3FixSrcList(&sFix, pTblName)
- ){
+ sqlite3FixInit(&sFix, pParse, iDb, "index", pName);
+ if( sqlite3FixSrcList(&sFix, pTblName) ){
/* Because the parser constructs pTblName from a single identifier,
** sqlite3FixSrcList can never fail. */
assert(0);
@@ -84734,7 +87083,13 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
assert( db->mallocFailed==0 || pTab==0 );
if( pTab==0 ) goto exit_create_index;
- assert( db->aDb[iDb].pSchema==pTab->pSchema );
+ if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
+ sqlite3ErrorMsg(pParse,
+ "cannot create a TEMP index on non-TEMP table \"%s\"",
+ pTab->zName);
+ goto exit_create_index;
+ }
+ if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab);
}else{
assert( pName==0 );
assert( pStart==0 );
@@ -84830,11 +87185,10 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
** So create a fake list to simulate this.
*/
if( pList==0 ){
- nullId.z = pTab->aCol[pTab->nCol-1].zName;
- nullId.n = sqlite3Strlen30((char*)nullId.z);
pList = sqlite3ExprListAppend(pParse, 0, 0);
if( pList==0 ) goto exit_create_index;
- sqlite3ExprListSetName(pParse, pList, &nullId, 0);
+ pList->a[0].zName = sqlite3DbStrDup(pParse->db,
+ pTab->aCol[pTab->nCol-1].zName);
pList->a[0].sortOrder = (u8)sortOrder;
}
@@ -84853,35 +87207,28 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
** Allocate the index structure.
*/
nName = sqlite3Strlen30(zName);
- nCol = pList->nExpr;
- pIndex = sqlite3DbMallocZero(db,
- ROUND8(sizeof(Index)) + /* Index structure */
- ROUND8(sizeof(tRowcnt)*(nCol+1)) + /* Index.aiRowEst */
- sizeof(char *)*nCol + /* Index.azColl */
- sizeof(int)*nCol + /* Index.aiColumn */
- sizeof(u8)*nCol + /* Index.aSortOrder */
- nName + 1 + /* Index.zName */
- nExtra /* Collation sequence names */
- );
+ nExtraCol = pPk ? pPk->nKeyCol : 1;
+ pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
+ nName + nExtra + 1, &zExtra);
if( db->mallocFailed ){
goto exit_create_index;
}
- zExtra = (char*)pIndex;
- pIndex->aiRowEst = (tRowcnt*)&zExtra[ROUND8(sizeof(Index))];
- pIndex->azColl = (char**)
- ((char*)pIndex->aiRowEst + ROUND8(sizeof(tRowcnt)*nCol+1));
assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowEst) );
assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
- pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
- pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
- pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
- zExtra = (char *)(&pIndex->zName[nName+1]);
+ pIndex->zName = zExtra;
+ zExtra += nName + 1;
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
- pIndex->nColumn = pList->nExpr;
pIndex->onError = (u8)onError;
+ pIndex->uniqNotNull = onError!=OE_None;
pIndex->autoIndex = (u8)(pName==0);
pIndex->pSchema = db->aDb[iDb].pSchema;
+ pIndex->nKeyCol = pList->nExpr;
+ if( pPIWhere ){
+ sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
+ pIndex->pPartIdxWhere = pPIWhere;
+ pPIWhere = 0;
+ }
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
/* Check to see if we should honor DESC requests on index columns
@@ -84904,7 +87251,6 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
*/
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
const char *zColName = pListItem->zName;
- Column *pTabCol;
int requestedSortOrder;
char *zColl; /* Collation sequence name */
@@ -84917,7 +87263,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
pParse->checkSchema = 1;
goto exit_create_index;
}
- pIndex->aiColumn[i] = j;
+ assert( pTab->nCol<=0x7fff && j<=0x7fff );
+ pIndex->aiColumn[i] = (i16)j;
if( pListItem->pExpr ){
int nColl;
assert( pListItem->pExpr->op==TK_COLLATE );
@@ -84938,8 +87285,27 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
pIndex->aSortOrder[i] = (u8)requestedSortOrder;
+ if( pTab->aCol[j].notNull==0 ) pIndex->uniqNotNull = 0;
+ }
+ if( pPk ){
+ for(j=0; j<pPk->nKeyCol; j++){
+ int x = pPk->aiColumn[j];
+ if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){
+ pIndex->nColumn--;
+ }else{
+ pIndex->aiColumn[i] = x;
+ pIndex->azColl[i] = pPk->azColl[j];
+ pIndex->aSortOrder[i] = pPk->aSortOrder[j];
+ i++;
+ }
+ }
+ assert( i==pIndex->nColumn );
+ }else{
+ pIndex->aiColumn[i] = -1;
+ pIndex->azColl[i] = "BINARY";
}
sqlite3DefaultRowEst(pIndex);
+ if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
@@ -84970,8 +87336,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
assert( pIdx->autoIndex );
assert( pIndex->onError!=OE_None );
- if( pIdx->nColumn!=pIndex->nColumn ) continue;
- for(k=0; k<pIdx->nColumn; k++){
+ if( pIdx->nKeyCol!=pIndex->nKeyCol ) continue;
+ for(k=0; k<pIdx->nKeyCol; k++){
const char *z1;
const char *z2;
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
@@ -84979,7 +87345,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
}
- if( k==pIdx->nColumn ){
+ if( k==pIdx->nKeyCol ){
if( pIdx->onError!=pIndex->onError ){
/* This constraint creates the same index as a previous
** constraint specified somewhere in the CREATE TABLE statement.
@@ -85021,22 +87387,20 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
}
}
- /* If the db->init.busy is 0 then create the index on disk. This
- ** involves writing the index into the master table and filling in the
- ** index with the current table contents.
- **
- ** The db->init.busy is 0 when the user first enters a CREATE INDEX
- ** command. db->init.busy is 1 when a database is opened and
- ** CREATE INDEX statements are read out of the master table. In
- ** the latter case the index already exists on disk, which is why
- ** we don't want to recreate it.
+ /* If this is the initial CREATE INDEX statement (or CREATE TABLE if the
+ ** index is an implied index for a UNIQUE or PRIMARY KEY constraint) then
+ ** emit code to allocate the index rootpage on disk and make an entry for
+ ** the index in the sqlite_master table and populate the index with
+ ** content. But, do not do this if we are simply reading the sqlite_master
+ ** table to parse the schema, or if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table.
**
- ** If pTblName==0 it means this index is generated as a primary key
- ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
+ ** If pTblName==0 it means this index is generated as an implied PRIMARY KEY
+ ** or UNIQUE index in a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
- else{ /* if( db->init.busy==0 ) */
+ else if( pParse->nErr==0 && (HasRowid(pTab) || pTblName!=0) ){
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
@@ -85054,12 +87418,11 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
** the zStmt variable
*/
if( pStart ){
- assert( pEnd!=0 );
+ int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
+ if( pName->z[n-1]==';' ) n--;
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
- onError==OE_None ? "" : " UNIQUE",
- (int)(pEnd->z - pName->z) + 1,
- pName->z);
+ onError==OE_None ? "" : " UNIQUE", n, pName->z);
}else{
/* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
/* zStmt = sqlite3MPrintf(""); */
@@ -85115,10 +87478,8 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
/* Clean up before exiting */
exit_create_index:
- if( pIndex ){
- sqlite3DbFree(db, pIndex->zColAff);
- sqlite3DbFree(db, pIndex);
- }
+ if( pIndex ) freeIndex(db, pIndex);
+ sqlite3ExprDelete(db, pPIWhere);
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
@@ -85151,12 +87512,12 @@ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
a[0] = pIdx->pTable->nRowEst;
if( a[0]<10 ) a[0] = 10;
n = 10;
- for(i=1; i<=pIdx->nColumn; i++){
+ for(i=1; i<=pIdx->nKeyCol; i++){
a[i] = n;
if( n>5 ) n--;
}
if( pIdx->onError!=OE_None ){
- a[pIdx->nColumn] = 1;
+ a[pIdx->nKeyCol] = 1;
}
}
@@ -85369,7 +87730,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
}
pSrc = pNew;
nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = (u16)nGot;
+ pSrc->nAlloc = (u8)nGot;
}
/* Move existing slots that come after the newly inserted slots
@@ -85377,7 +87738,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
- pSrc->nSrc += (i16)nExtra;
+ pSrc->nSrc += (i8)nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
@@ -85844,7 +88205,8 @@ SQLITE_PRIVATE void sqlite3HaltConstraint(
int errCode, /* extended error code */
int onError, /* Constraint type */
char *p4, /* Error message */
- int p4type /* P4_STATIC or P4_TRANSIENT */
+ i8 p4type, /* P4_STATIC or P4_TRANSIENT */
+ u8 p5Errmsg /* P5_ErrMsg type */
){
Vdbe *v = sqlite3GetVdbe(pParse);
assert( (errCode&0xff)==SQLITE_CONSTRAINT );
@@ -85852,6 +88214,58 @@ SQLITE_PRIVATE void sqlite3HaltConstraint(
sqlite3MayAbort(pParse);
}
sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
+ if( p5Errmsg ) sqlite3VdbeChangeP5(v, p5Errmsg);
+}
+
+/*
+** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation.
+*/
+SQLITE_PRIVATE void sqlite3UniqueConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Constraint type */
+ Index *pIdx /* The index that triggers the constraint */
+){
+ char *zErr;
+ int j;
+ StrAccum errMsg;
+ Table *pTab = pIdx->pTable;
+
+ sqlite3StrAccumInit(&errMsg, 0, 0, 200);
+ errMsg.db = pParse->db;
+ for(j=0; j<pIdx->nKeyCol; j++){
+ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
+ sqlite3StrAccumAppend(&errMsg, pTab->zName, -1);
+ sqlite3StrAccumAppend(&errMsg, ".", 1);
+ sqlite3StrAccumAppend(&errMsg, zCol, -1);
+ }
+ zErr = sqlite3StrAccumFinish(&errMsg);
+ sqlite3HaltConstraint(pParse,
+ (pIdx->autoIndex==2)?SQLITE_CONSTRAINT_PRIMARYKEY:SQLITE_CONSTRAINT_UNIQUE,
+ onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);
+}
+
+
+/*
+** Code an OP_Halt due to non-unique rowid.
+*/
+SQLITE_PRIVATE void sqlite3RowidConstraint(
+ Parse *pParse, /* Parsing context */
+ int onError, /* Conflict resolution algorithm */
+ Table *pTab /* The table with the non-unique rowid */
+){
+ char *zMsg;
+ int rc;
+ if( pTab->iPKey>=0 ){
+ zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName,
+ pTab->aCol[pTab->iPKey].zName);
+ rc = SQLITE_CONSTRAINT_PRIMARYKEY;
+ }else{
+ zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName);
+ rc = SQLITE_CONSTRAINT_ROWID;
+ }
+ sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC,
+ P5_ConstraintUnique);
}
/*
@@ -85864,8 +88278,8 @@ static int collationMatch(const char *zColl, Index *pIndex){
assert( zColl!=0 );
for(i=0; i<pIndex->nColumn; i++){
const char *z = pIndex->azColl[i];
- assert( z!=0 );
- if( 0==sqlite3StrICmp(z, zColl) ){
+ assert( z!=0 || pIndex->aiColumn[i]<0 );
+ if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){
return 1;
}
}
@@ -85984,40 +88398,49 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
#endif
/*
-** Return a dynamicly allocated KeyInfo structure that can be used
-** with OP_OpenRead or OP_OpenWrite to access database index pIdx.
+** Return a KeyInfo structure that is appropriate for the given Index.
**
-** If successful, a pointer to the new structure is returned. In this case
-** the caller is responsible for calling sqlite3DbFree(db, ) on the returned
-** pointer. If an error occurs (out of memory or missing collation
-** sequence), NULL is returned and the state of pParse updated to reflect
-** the error.
+** The KeyInfo structure for an index is cached in the Index object.
+** So there might be multiple references to the returned pointer. The
+** caller should not try to modify the KeyInfo object.
+**
+** The caller should invoke sqlite3KeyInfoUnref() on the returned object
+** when it has finished using it.
*/
-SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
- int i;
- int nCol = pIdx->nColumn;
- int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
- sqlite3 *db = pParse->db;
- KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
-
- if( pKey ){
- pKey->db = pParse->db;
- pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
- assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
- for(i=0; i<nCol; i++){
- char *zColl = pIdx->azColl[i];
- assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
- pKey->aSortOrder[i] = pIdx->aSortOrder[i];
- }
- pKey->nField = (u16)nCol;
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
+ if( pParse->nErr ) return 0;
+#ifndef SQLITE_OMIT_SHARED_CACHE
+ if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
+ sqlite3KeyInfoUnref(pIdx->pKeyInfo);
+ pIdx->pKeyInfo = 0;
}
-
- if( pParse->nErr ){
- sqlite3DbFree(db, pKey);
- pKey = 0;
+#endif
+ if( pIdx->pKeyInfo==0 ){
+ int i;
+ int nCol = pIdx->nColumn;
+ int nKey = pIdx->nKeyCol;
+ KeyInfo *pKey;
+ if( pIdx->uniqNotNull ){
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+ }else{
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
+ }
+ if( pKey ){
+ assert( sqlite3KeyInfoIsWriteable(pKey) );
+ for(i=0; i<nCol; i++){
+ char *zColl = pIdx->azColl[i];
+ if( NEVER(zColl==0) ) zColl = "BINARY";
+ pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
+ pKey->aSortOrder[i] = pIdx->aSortOrder[i];
+ }
+ if( pParse->nErr ){
+ sqlite3KeyInfoUnref(pKey);
+ }else{
+ pIdx->pKeyInfo = pKey;
+ }
+ }
}
- return pKey;
+ return sqlite3KeyInfoRef(pIdx->pKeyInfo);
}
/************** End of build.c ***********************************************/
@@ -86293,9 +88716,9 @@ static int matchQuality(
}
/* Bonus points if the text encoding matches */
- if( enc==p->iPrefEnc ){
+ if( enc==(p->funcFlags & SQLITE_FUNC_ENCMASK) ){
match += 2; /* Exact encoding match */
- }else if( (enc & p->iPrefEnc & 2)!=0 ){
+ }else if( (enc & p->funcFlags & 2)!=0 ){
match += 1; /* Both are UTF16, but with different byte orders */
}
@@ -86429,7 +88852,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
pBest->zName = (char *)&pBest[1];
pBest->nArg = (u16)nArg;
- pBest->iPrefEnc = enc;
+ pBest->funcFlags = enc;
memcpy(pBest->zName, zName, nName);
pBest->zName[nName] = 0;
sqlite3FuncDefInsert(&db->aFunc, pBest);
@@ -86637,7 +89060,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
ExprList *pOrderBy, /* The ORDER BY clause. May be null */
Expr *pLimit, /* The LIMIT clause. May be null */
Expr *pOffset, /* The OFFSET clause. May be null */
- char *zStmtType /* Either DELETE or UPDATE. For error messages. */
+ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
Expr *pWhereRowid = NULL; /* WHERE rowid .. */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
@@ -86712,7 +89135,8 @@ limit_where_cleanup_2:
sqlite3ExprDelete(pParse->db, pOffset);
return 0;
}
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
+ /* && !defined(SQLITE_OMIT_SUBQUERY) */
/*
** Generate code for a DELETE FROM statement.
@@ -86729,18 +89153,34 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
Vdbe *v; /* The virtual database engine */
Table *pTab; /* The table from which records will be deleted */
const char *zDb; /* Name of database holding pTab */
- int end, addr = 0; /* A couple addresses of generated code */
int i; /* Loop counter */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Index *pIdx; /* For looping over indices of the table */
- int iCur; /* VDBE Cursor number for pTab */
+ int iTabCur; /* Cursor number for the table */
+ int iDataCur; /* VDBE cursor for the canonical data source */
+ int iIdxCur; /* Cursor number of the first index */
+ int nIdx; /* Number of indices */
sqlite3 *db; /* Main database structure */
AuthContext sContext; /* Authorization context */
NameContext sNC; /* Name context to resolve expressions in */
int iDb; /* Database number */
int memCnt = -1; /* Memory cell used for change counting */
int rcauth; /* Value returned by authorization callback */
-
+ int okOnePass; /* True for one-pass algorithm without the FIFO */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
+ u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */
+ Index *pPk; /* The PRIMARY KEY index on the table */
+ int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */
+ i16 nPk = 1; /* Number of columns in the PRIMARY KEY */
+ int iKey; /* Memory cell holding key of row to be deleted */
+ i16 nKey; /* Number of memory cells in the row key */
+ int iEphCur = 0; /* Ephemeral table holding all primary key values */
+ int iRowSet = 0; /* Register for rowset of rows to delete */
+ int addrBypass = 0; /* Address of jump over the delete logic */
+ int addrLoop = 0; /* Top of the delete loop */
+ int addrDelete = 0; /* Jump directly to the delete logic */
+ int addrEphOpen = 0; /* Instruction to open the Ephermeral table */
+
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True if attempting to delete from a view */
Trigger *pTrigger; /* List of table triggers, if required */
@@ -86795,11 +89235,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
assert(!isView || pTrigger);
- /* Assign cursor number to the table and all its indices.
+ /* Assign cursor numbers to the table and all its indices.
*/
assert( pTabList->nSrc==1 );
- iCur = pTabList->a[0].iCursor = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ iTabCur = pTabList->a[0].iCursor = pParse->nTab++;
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
pParse->nTab++;
}
@@ -86823,7 +89263,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ iDataCur = iIdxCur = iTabCur;
}
#endif
@@ -86853,78 +89294,169 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
&& 0==sqlite3FkRequired(pParse, pTab, 0, 0)
){
assert( !isView );
- sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
- pTab->zName, P4_STATIC);
+ sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt,
+ pTab->zName, P4_STATIC);
+ }
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
assert( pIdx->pSchema==pTab->pSchema );
sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb);
}
}else
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
- /* The usual case: There is a WHERE clause so we have to scan through
- ** the table and pick which records to delete.
- */
{
- int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */
- int iRowid = ++pParse->nMem; /* Used for storing rowid values. */
- int regRowid; /* Actual register containing rowids */
-
- /* Collect rowids of every row to be deleted.
+ if( HasRowid(pTab) ){
+ /* For a rowid table, initialize the RowSet to an empty set */
+ pPk = 0;
+ nPk = 1;
+ iRowSet = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
+ }else{
+ /* For a WITHOUT ROWID table, create an ephermeral table used to
+ ** hold all primary keys for rows to be deleted. */
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ iEphCur = pParse->nTab++;
+ addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ }
+
+ /* Construct a query to find the rowid or primary key for every row
+ ** to be deleted, based on the WHERE clause.
*/
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0
- );
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
+ WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK,
+ iTabCur+1);
if( pWInfo==0 ) goto delete_from_cleanup;
- regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, iRowid, 0);
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid);
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+
+ /* Keep track of the number of rows to be deleted */
if( db->flags & SQLITE_CountRows ){
sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
}
+
+ /* Extract the rowid or primary key for the current row */
+ if( pPk ){
+ for(i=0; i<nPk; i++){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
+ pPk->aiColumn[i], iPk+i);
+ }
+ iKey = iPk;
+ }else{
+ iKey = pParse->nMem + 1;
+ iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
+ if( iKey>pParse->nMem ) pParse->nMem = iKey;
+ }
+
+ if( okOnePass ){
+ /* For ONEPASS, no need to store the rowid/primary-key. There is only
+ ** one, so just keep it in its register(s) and fall through to the
+ ** delete code.
+ */
+ nKey = nPk; /* OP_Found will use an unpacked key */
+ aToOpen = sqlite3DbMallocRaw(db, nIdx+2);
+ if( aToOpen==0 ){
+ sqlite3WhereEnd(pWInfo);
+ goto delete_from_cleanup;
+ }
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0;
+ if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen);
+ addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */
+ }else if( pPk ){
+ /* Construct a composite key for the row to be deleted and remember it */
+ iKey = ++pParse->nMem;
+ nKey = 0; /* Zero tells OP_Found to use a composite key */
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
+ sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
+ }else{
+ /* Get the rowid of the row to be deleted and remember it in the RowSet */
+ nKey = 1; /* OP_Seek always uses a single rowid */
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
+ }
+
+ /* End of the WHERE loop */
sqlite3WhereEnd(pWInfo);
-
- /* Delete every item whose key was written to the list during the
- ** database scan. We have to delete items after the scan is complete
- ** because deleting an item can change the scan order. */
- end = sqlite3VdbeMakeLabel(v);
-
+ if( okOnePass ){
+ /* Bypass the delete logic below if the WHERE loop found zero rows */
+ addrBypass = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass);
+ sqlite3VdbeJumpHere(v, addrDelete);
+ }
+
/* Unless this is a view, open cursors for the table we are
** deleting from and all its indices. If this is a view, then the
** only effect this statement has is to fire the INSTEAD OF
- ** triggers. */
+ ** triggers.
+ */
if( !isView ){
- sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
+ &iDataCur, &iIdxCur);
+ assert( pPk || iDataCur==iTabCur );
+ assert( pPk || iIdxCur==iDataCur+1 );
}
-
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid);
-
+
+ /* Set up a loop over the rowids/primary-keys that were found in the
+ ** where-clause loop above.
+ */
+ if( okOnePass ){
+ /* Just one row. Hence the top-of-loop is a no-op */
+ assert( nKey==nPk ); /* OP_Found will use an unpacked key */
+ if( aToOpen[iDataCur-iTabCur] ){
+ assert( pPk!=0 );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+ }
+ }else if( pPk ){
+ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
+ sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
+ assert( nKey==0 ); /* OP_Found will use a composite key */
+ }else{
+ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+ assert( nKey==1 );
+ }
+
/* Delete the row */
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
sqlite3VtabMakeWritable(pParse, pTab);
- sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB);
+ sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, OE_Abort);
sqlite3MayAbort(pParse);
}else
#endif
{
int count = (pParse->nested==0); /* True to count changes */
- sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default);
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ iKey, nKey, count, OE_Default, okOnePass);
}
-
- /* End of the delete loop */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeResolveLabel(v, end);
-
+
+ /* End of the loop over all rowids/primary-keys. */
+ if( okOnePass ){
+ sqlite3VdbeResolveLabel(v, addrBypass);
+ }else if( pPk ){
+ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
+ sqlite3VdbeJumpHere(v, addrLoop);
+ }
+
/* Close the cursors open on the table and its indexes. */
if( !isView && !IsVirtual(pTab) ){
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum);
+ if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
}
- sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
- }
+ } /* End non-truncate path */
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -86948,6 +89480,7 @@ delete_from_cleanup:
sqlite3AuthContextPop(&sContext);
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprDelete(db, pWhere);
+ sqlite3DbFree(db, aToOpen);
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
@@ -86962,50 +89495,59 @@ delete_from_cleanup:
/*
** This routine generates VDBE code that causes a single row of a
-** single table to be deleted.
+** single table to be deleted. Both the original table entry and
+** all indices are removed.
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number $iCur.
+** 1. iDataCur is an open cursor on the btree that is the canonical data
+** store for the table. (This will be either the table itself,
+** in the case of a rowid table, or the PRIMARY KEY index in the case
+** of a WITHOUT ROWID table.)
**
** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number base+i for the i-th index.
+** cursor number iIdxCur+i for the i-th index.
**
-** 3. The record number of the row to be deleted must be stored in
-** memory cell iRowid.
-**
-** This routine generates code to remove both the table record and all
-** index entries that point to that record.
+** 3. The primary key for the row to be deleted must be stored in a
+** sequence of nPk memory cells starting at iPk. If nPk==0 that means
+** that a search record formed from OP_MakeRecord is contained in the
+** single memory location iPk.
*/
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
- int iRowid, /* Memory cell that contains the rowid to delete */
- int count, /* If non-zero, increment the row change counter */
Trigger *pTrigger, /* List of triggers to (potentially) fire */
- int onconf /* Default ON CONFLICT policy for triggers */
+ int iDataCur, /* Cursor from which column data is extracted */
+ int iIdxCur, /* First index cursor */
+ int iPk, /* First memory cell containing the PRIMARY KEY */
+ i16 nPk, /* Number of PRIMARY KEY memory cells */
+ u8 count, /* If non-zero, increment the row change counter */
+ u8 onconf, /* Default ON CONFLICT policy for triggers */
+ u8 bNoSeek /* iDataCur is already pointing to the row to delete */
){
Vdbe *v = pParse->pVdbe; /* Vdbe */
int iOld = 0; /* First register in OLD.* array */
int iLabel; /* Label resolved to end of generated code */
+ u8 opSeek; /* Seek opcode */
/* Vdbe is guaranteed to have been allocated by this stage. */
assert( v );
+ VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
+ iDataCur, iIdxCur, iPk, (int)nPk));
/* Seek cursor iCur to the row to delete. If this row no longer exists
** (this can happen if a trigger program has already deleted it), do
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
+ opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
+ if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
/* If there are any triggers to fire, allocate a range of registers to
** use for the old.* references in the triggers. */
if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){
u32 mask; /* Mask of OLD.* columns in use */
int iCol; /* Iterator used while populating OLD.* */
+ int addrStart; /* Start of BEFORE trigger programs */
/* TODO: Could use temporary registers here. Also could attempt to
** avoid copying the contents of the rowid register. */
@@ -87018,36 +89560,40 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* Populate the OLD.* pseudo-table register array. These values will be
** used by any BEFORE and AFTER triggers that exist. */
- sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld);
+ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iCol<pTab->nCol; iCol++){
if( mask==0xffffffff || mask&(1<<iCol) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol, iOld+iCol+1);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}
/* Invoke BEFORE DELETE trigger programs. */
+ addrStart = sqlite3VdbeCurrentAddr(v);
sqlite3CodeRowTrigger(pParse, pTrigger,
TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel
);
- /* Seek the cursor to the row to be deleted again. It may be that
- ** the BEFORE triggers coded above have already removed the row
- ** being deleted. Do not attempt to delete the row a second time, and
- ** do not fire AFTER triggers. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid);
+ /* If any BEFORE triggers were coded, then seek the cursor to the
+ ** row to be deleted again. It may be that the BEFORE triggers moved
+ ** the cursor or of already deleted the row that the cursor was
+ ** pointing to.
+ */
+ if( addrStart<sqlite3VdbeCurrentAddr(v) ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ }
/* Do FK processing. This call checks that any FK constraints that
** refer to this table (i.e. constraints attached to other tables)
** are not violated by deleting this row. */
- sqlite3FkCheck(pParse, pTab, iOld, 0);
+ sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0);
}
/* Delete the index and table entries. Skip this step if pTab is really
** a view (in which case the only effect of the DELETE statement is to
** fire the INSTEAD OF triggers). */
if( pTab->pSelect==0 ){
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
if( count ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
@@ -87056,7 +89602,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
** handle rows (possibly in other tables) that refer via a foreign key
** to the row just deleted. */
- sqlite3FkActions(pParse, pTab, 0, iOld);
+ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);
/* Invoke AFTER DELETE trigger programs. */
sqlite3CodeRowTrigger(pParse, pTrigger,
@@ -87067,78 +89613,113 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
** trigger programs were invoked. Or if a trigger program throws a
** RAISE(IGNORE) exception. */
sqlite3VdbeResolveLabel(v, iLabel);
+ VdbeModuleComment((v, "END: GenRowDel()"));
}
/*
** This routine generates VDBE code that causes the deletion of all
-** index entries associated with a single row of a single table.
+** index entries associated with a single row of a single table, pTab
**
-** The VDBE must be in a particular state when this routine is called.
-** These are the requirements:
+** Preconditions:
**
-** 1. A read/write cursor pointing to pTab, the table containing the row
-** to be deleted, must be opened as cursor number "iCur".
+** 1. A read/write cursor "iDataCur" must be open on the canonical storage
+** btree for the table pTab. (This will be either the table itself
+** for rowid tables or to the primary key index for WITHOUT ROWID
+** tables.)
**
** 2. Read/write cursors for all indices of pTab must be open as
-** cursor number iCur+i for the i-th index.
+** cursor number iIdxCur+i for the i-th index. (The pTab->pIndex
+** index is the 0-th index.)
**
-** 3. The "iCur" cursor must be pointing to the row that is to be
-** deleted.
+** 3. The "iDataCur" cursor must be already be positioned on the row
+** that is to be deleted.
*/
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
Parse *pParse, /* Parsing and code generating context */
Table *pTab, /* Table containing the row to be deleted */
- int iCur, /* Cursor number for the table */
+ int iDataCur, /* Cursor of table holding data. */
+ int iIdxCur, /* First index cursor */
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
- int i;
- Index *pIdx;
- int r1;
+ int i; /* Index loop counter */
+ int r1; /* Register holding an index key */
+ int iPartIdxLabel; /* Jump destination for skipping partial index entries */
+ Index *pIdx; /* Current index */
+ Vdbe *v; /* The prepared statement under construction */
+ Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
- for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
+ v = pParse->pVdbe;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ assert( iIdxCur+i!=iDataCur || pPk==pIdx );
+ if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
+ if( pIdx==pPk ) continue;
+ VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+ sqlite3VdbeResolveLabel(v, iPartIdxLabel);
}
}
/*
-** Generate code that will assemble an index key and put it in register
+** Generate code that will assemble an index key and stores it in register
** regOut. The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
-** the entry that needs indexing.
+** the entry that needs indexing. If pTab is a WITHOUT ROWID table, then
+** iCur must be the cursor of the PRIMARY KEY index.
**
** Return a register number which is the first in a block of
** registers that holds the elements of the index key. The
** block of registers has already been deallocated by the time
** this routine returns.
+**
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
+** to that label if pIdx is a partial index that should be skipped.
+** A partial index should be skipped if its WHERE clause evaluates
+** to false or null. If pIdx is not a partial index, *piPartIdxLabel
+** will be set to zero which is an empty label that is ignored by
+** sqlite3VdbeResolveLabel().
*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
- Parse *pParse, /* Parsing context */
- Index *pIdx, /* The index for which to generate a key */
- int iCur, /* Cursor number for the pIdx->pTable table */
- int regOut, /* Write the new index key to this register */
- int doMakeRec /* Run the OP_MakeRecord instruction if true */
+ Parse *pParse, /* Parsing context */
+ Index *pIdx, /* The index for which to generate a key */
+ int iDataCur, /* Cursor number from which to take column data */
+ int regOut, /* Put the new key into this register if not 0 */
+ int prefixOnly, /* Compute only a unique prefix of the key */
+ int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
){
Vdbe *v = pParse->pVdbe;
int j;
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
-
- nCol = pIdx->nColumn;
- regBase = sqlite3GetTempRange(pParse, nCol+1);
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
+ Index *pPk;
+
+ if( piPartIdxLabel ){
+ if( pIdx->pPartIdxWhere ){
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
+ pParse->iPartIdxTab = iDataCur;
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
+ SQLITE_JUMPIFNULL);
+ }else{
+ *piPartIdxLabel = 0;
+ }
+ }
+ nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
+ regBase = sqlite3GetTempRange(pParse, nCol);
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
for(j=0; j<nCol; j++){
- int idx = pIdx->aiColumn[j];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
+ i16 idx = pIdx->aiColumn[j];
+ if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
+ if( idx<0 || idx==pTab->iPKey ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j);
}else{
- sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, idx, -1);
+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j);
+ sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
}
}
- if( doMakeRec ){
+ if( regOut ){
const char *zAff;
if( pTab->pSelect
|| OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
@@ -87147,10 +89728,10 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
}
- sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
+ sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
}
@@ -87294,8 +89875,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ){
if( (iVal<<1)==0 ){
- /* IMP: R-35460-15084 If X is the integer -9223372036854775807 then
- ** abs(X) throws an integer overflow error since there is no
+ /* IMP: R-31676-45509 If X is the integer -9223372036854775808
+ ** then abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */
sqlite3_result_error(context, "integer overflow", -1);
return;
@@ -87384,7 +89965,7 @@ static void instrFunc(
**
** If p1 is negative, then we begin abs(p1) from the end of x[].
**
-** If p2 is negative, return the p2 characters preceeding p1.
+** If p2 is negative, return the p2 characters preceding p1.
*/
static void substrFunc(
sqlite3_context *context,
@@ -87574,14 +90155,14 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
/*
-** The COALESCE() and IFNULL() functions are implemented as VDBE code so
-** that unused argument values do not have to be computed. However, we
-** still need some kind of function implementation for this routines in
-** the function table. That function implementation will never be called
-** so it doesn't matter what the implementation is. We might as well use
-** the "version()" function as a substitute.
+** Some functions like COALESCE() and IFNULL() and UNLIKELY() are implemented
+** as VDBE code so that unused argument values do not have to be computed.
+** However, we still need some kind of function implementation for this
+** routines in the function table. The noopFunc macro provides this.
+** noopFunc will never be called so it doesn't matter what the implementation
+** is. We might as well use the "version()" function as a substitute.
*/
-#define ifnullFunc versionFunc /* Substitute function - never called */
+#define noopFunc versionFunc /* Substitute function - never called */
/*
** Implementation of random(). Return a random integer.
@@ -87700,9 +90281,9 @@ struct compareInfo {
*/
#if defined(SQLITE_EBCDIC)
# define sqlite3Utf8Read(A) (*((*A)++))
-# define GlogUpperToLower(A) A = sqlite3UpperToLower[A]
+# define GlobUpperToLower(A) A = sqlite3UpperToLower[A]
#else
-# define GlogUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
+# define GlobUpperToLower(A) if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
#endif
static const struct compareInfo globInfo = { '*', '?', '[', 0 };
@@ -87781,11 +90362,11 @@ static int patternCompare(
}
while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
if( noCase ){
- GlogUpperToLower(c2);
- GlogUpperToLower(c);
+ GlobUpperToLower(c2);
+ GlobUpperToLower(c);
while( c2 != 0 && c2 != c ){
c2 = sqlite3Utf8Read(&zString);
- GlogUpperToLower(c2);
+ GlobUpperToLower(c2);
}
}else{
while( c2 != 0 && c2 != c ){
@@ -87837,8 +90418,8 @@ static int patternCompare(
}else{
c2 = sqlite3Utf8Read(&zString);
if( noCase ){
- GlogUpperToLower(c);
- GlogUpperToLower(c2);
+ GlobUpperToLower(c);
+ GlobUpperToLower(c2);
}
if( c!=c2 ){
return 0;
@@ -88043,10 +90624,6 @@ static const char hexdigits[] = {
};
/*
-** EXPERIMENTAL - This is not an official function. The interface may
-** change. This function may disappear. Do not write code that depends
-** on this function.
-**
** Implementation of the QUOTE() function. This function takes a single
** argument. If the argument is numeric, the return value is the same as
** the argument. If the argument is NULL, the return value is the string
@@ -88235,7 +90812,7 @@ static void zeroblobFunc(
/*
** The replace() function. Three arguments are all strings: call
** them A, B, and C. The result is also a string which is derived
-** from A by replacing every occurance of B with C. The match
+** from A by replacing every occurrence of B with C. The match
** must be exact. Collating sequences are not used.
*/
static void replaceFunc(
@@ -88682,9 +91259,9 @@ static void groupConcatFinalize(sqlite3_context *context){
StrAccum *pAccum;
pAccum = sqlite3_aggregate_context(context, 0);
if( pAccum ){
- if( pAccum->tooBig ){
+ if( pAccum->accError==STRACCUM_TOOBIG ){
sqlite3_result_error_toobig(context);
- }else if( pAccum->mallocFailed ){
+ }else if( pAccum->accError==STRACCUM_NOMEM ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1,
@@ -88714,7 +91291,7 @@ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
- pDef->flags = flagVal;
+ pDef->funcFlags |= flagVal;
}
}
@@ -88758,7 +91335,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
pDef = sqlite3FindFunction(db, pExpr->u.zToken,
sqlite3Strlen30(pExpr->u.zToken),
2, SQLITE_UTF8, 0);
- if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
+ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -88770,7 +91347,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
- *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
+ *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0;
return 1;
}
@@ -88819,11 +91396,13 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(coalesce, 1, 0, 0, 0 ),
FUNCTION(coalesce, 0, 0, 0, 0 ),
- FUNCTION2(coalesce, -1, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
FUNCTION(hex, 1, 0, 0, hexFunc ),
- FUNCTION2(ifnull, 2, 0, 0, ifnullFunc, SQLITE_FUNC_COALESCE),
- FUNCTION(random, 0, 0, 0, randomFunc ),
- FUNCTION(randomblob, 1, 0, 0, randomBlob ),
+ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ VFUNCTION(random, 0, 0, 0, randomFunc ),
+ VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -88833,9 +91412,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
FUNCTION(quote, 1, 0, 0, quoteFunc ),
- FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
- FUNCTION(changes, 0, 0, 0, changes ),
- FUNCTION(total_changes, 0, 0, 0, total_changes ),
+ VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
+ VFUNCTION(changes, 0, 0, 0, changes ),
+ VFUNCTION(total_changes, 0, 0, 0, total_changes ),
FUNCTION(replace, 3, 0, 0, replaceFunc ),
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
#ifdef SQLITE_SOUNDEX
@@ -88849,7 +91428,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
/* AGGREGATE(count, 0, 0, 0, countStep, countFinalize ), */
- {0,SQLITE_UTF8,SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
+ {0,SQLITE_UTF8|SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
AGGREGATE(count, 1, 0, 0, countStep, countFinalize ),
AGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize),
AGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize),
@@ -88875,6 +91454,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
+#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+ sqlite3AnalyzeFunctions();
+#endif
}
/************** End of func.c ************************************************/
@@ -89105,7 +91687,7 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(
}
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){
+ if( pIdx->nKeyCol==nCol && pIdx->onError!=OE_None ){
/* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
** of columns. If each indexed column corresponds to a foreign key
** column of pFKey, then this index is a winner. */
@@ -89128,7 +91710,7 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(
** the default collation sequences for each column. */
int i, j;
for(i=0; i<nCol; i++){
- int iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
+ i16 iCol = pIdx->aiColumn[i]; /* Index of column in parent tbl */
char *zDfltColl; /* Def. collation for column */
char *zIdxCol; /* Name of indexed column */
@@ -89259,10 +91841,9 @@ static void fkLookupParent(
int nCol = pFKey->nCol;
int regTemp = sqlite3GetTempRange(pParse, nCol);
int regRec = sqlite3GetTempReg(pParse);
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
}
@@ -89302,15 +91883,17 @@ static void fkLookupParent(
}
}
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
+ if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
+ && !pParse->pToplevel
+ && !pParse->isMultiWrite
+ ){
/* Special case: If this is an INSERT statement that will insert exactly
** one row into the table, raise a constraint immediately instead of
** incrementing a counter. This is necessary as the VM code is being
** generated for will not open a statement transaction. */
assert( nIncr==1 );
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
- OE_Abort, "foreign key constraint failed", P4_STATIC
- );
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
}else{
if( nIncr>0 && pFKey->isDeferred==0 ){
sqlite3ParseToplevel(pParse)->mayAbort = 1;
@@ -89322,6 +91905,62 @@ static void fkLookupParent(
sqlite3VdbeAddOp1(v, OP_Close, iCur);
}
+
+/*
+** Return an Expr object that refers to a memory register corresponding
+** to column iCol of table pTab.
+**
+** regBase is the first of an array of register that contains the data
+** for pTab. regBase itself holds the rowid. regBase+1 holds the first
+** column. regBase+2 holds the second column, and so forth.
+*/
+static Expr *exprTableRegister(
+ Parse *pParse, /* Parsing and code generating context */
+ Table *pTab, /* The table whose content is at r[regBase]... */
+ int regBase, /* Contents of table pTab */
+ i16 iCol /* Which column of pTab is desired */
+){
+ Expr *pExpr;
+ Column *pCol;
+ const char *zColl;
+ sqlite3 *db = pParse->db;
+
+ pExpr = sqlite3Expr(db, TK_REGISTER, 0);
+ if( pExpr ){
+ if( iCol>=0 && iCol!=pTab->iPKey ){
+ pCol = &pTab->aCol[iCol];
+ pExpr->iTable = regBase + iCol + 1;
+ pExpr->affinity = pCol->affinity;
+ zColl = pCol->zColl;
+ if( zColl==0 ) zColl = db->pDfltColl->zName;
+ pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl);
+ }else{
+ pExpr->iTable = regBase;
+ pExpr->affinity = SQLITE_AFF_INTEGER;
+ }
+ }
+ return pExpr;
+}
+
+/*
+** Return an Expr object that refers to column iCol of table pTab which
+** has cursor iCur.
+*/
+static Expr *exprTableColumn(
+ sqlite3 *db, /* The database connection */
+ Table *pTab, /* The table whose column is desired */
+ int iCursor, /* The open cursor on the table */
+ i16 iCol /* The column that is wanted */
+){
+ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
+ if( pExpr ){
+ pExpr->pTab = pTab;
+ pExpr->iTable = iCursor;
+ pExpr->iColumn = iCol;
+ }
+ return pExpr;
+}
+
/*
** This function is called to generate code executed when a row is deleted
** from the parent table of foreign key constraint pFKey and, if pFKey is
@@ -89337,13 +91976,13 @@ static void fkLookupParent(
** --------------------------------------------------------------------------
** DELETE immediate Increment the "immediate constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
+** throw a "FOREIGN KEY constraint failed" exception.
**
** INSERT immediate Decrement the "immediate constraint counter".
**
** DELETE deferred Increment the "deferred constraint counter".
** Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-** throw a "foreign key constraint failed" exception.
+** throw a "FOREIGN KEY constraint failed" exception.
**
** INSERT deferred Decrement the "deferred constraint counter".
**
@@ -89352,12 +91991,12 @@ static void fkLookupParent(
*/
static void fkScanChildren(
Parse *pParse, /* Parse context */
- SrcList *pSrc, /* SrcList containing the table to scan */
- Table *pTab,
- Index *pIdx, /* Foreign key index */
- FKey *pFKey, /* Foreign key relationship */
+ SrcList *pSrc, /* The child table to be scanned */
+ Table *pTab, /* The parent table */
+ Index *pIdx, /* Index on parent covering the foreign key */
+ FKey *pFKey, /* The foreign key linking pSrc to pTab */
int *aiCol, /* Map from pIdx cols to child table cols */
- int regData, /* Referenced table data starts here */
+ int regData, /* Parent row data starts here */
int nIncr /* Amount to increment deferred counter by */
){
sqlite3 *db = pParse->db; /* Database handle */
@@ -89368,7 +92007,10 @@ static void fkScanChildren(
int iFkIfZero = 0; /* Address of OP_FkIfZero */
Vdbe *v = sqlite3GetVdbe(pParse);
- assert( !pIdx || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->pTable==pTab );
+ assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol );
+ assert( pIdx!=0 || pFKey->nCol==1 );
+ assert( pIdx!=0 || HasRowid(pTab) );
if( nIncr<0 ){
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
@@ -89386,29 +92028,11 @@ static void fkScanChildren(
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
Expr *pEq; /* Expression (pLeft = pRight) */
- int iCol; /* Index of column in child table */
+ i16 iCol; /* Index of column in child table */
const char *zCol; /* Name of column in child table */
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- if( pLeft ){
- /* Set the collation sequence and affinity of the LHS of each TK_EQ
- ** expression to the parent key column defaults. */
- if( pIdx ){
- Column *pCol;
- const char *zColl;
- iCol = pIdx->aiColumn[i];
- pCol = &pTab->aCol[iCol];
- if( pTab->iPKey==iCol ) iCol = -1;
- pLeft->iTable = regData+iCol+1;
- pLeft->affinity = pCol->affinity;
- zColl = pCol->zColl;
- if( zColl==0 ) zColl = db->pDfltColl->zName;
- pLeft = sqlite3ExprAddCollateString(pParse, pLeft, zColl);
- }else{
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- }
- }
+ iCol = pIdx ? pIdx->aiColumn[i] : -1;
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
@@ -89417,24 +92041,39 @@ static void fkScanChildren(
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
}
- /* If the child table is the same as the parent table, and this scan
- ** is taking place as part of a DELETE operation (operation D.2), omit the
- ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE
- ** clause, where $rowid is the rowid of the row being deleted. */
+ /* If the child table is the same as the parent table, then add terms
+ ** to the WHERE clause that prevent this entry from being scanned.
+ ** The added WHERE clause terms are like this:
+ **
+ ** $current_rowid!=rowid
+ ** NOT( $current_a==a AND $current_b==b AND ... )
+ **
+ ** The first form is used for rowid tables. The second form is used
+ ** for WITHOUT ROWID tables. In the second form, the primary key is
+ ** (a,b,...)
+ */
if( pTab==pFKey->pFrom && nIncr>0 ){
- Expr *pEq; /* Expression (pLeft = pRight) */
+ Expr *pNe; /* Expression (pLeft != pRight) */
Expr *pLeft; /* Value from parent table row */
Expr *pRight; /* Column ref to child table */
- pLeft = sqlite3Expr(db, TK_REGISTER, 0);
- pRight = sqlite3Expr(db, TK_COLUMN, 0);
- if( pLeft && pRight ){
- pLeft->iTable = regData;
- pLeft->affinity = SQLITE_AFF_INTEGER;
- pRight->iTable = pSrc->a[0].iCursor;
- pRight->iColumn = -1;
- }
- pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
- pWhere = sqlite3ExprAnd(db, pWhere, pEq);
+ if( HasRowid(pTab) ){
+ pLeft = exprTableRegister(pParse, pTab, regData, -1);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
+ }else{
+ Expr *pEq, *pAll = 0;
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pIdx!=0 );
+ for(i=0; i<pPk->nKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
+ pLeft = exprTableRegister(pParse, pTab, regData, iCol);
+ pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
+ pAll = sqlite3ExprAnd(db, pAll, pEq);
+ }
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
+ }
+ pWhere = sqlite3ExprAnd(db, pWhere, pNe);
}
/* Resolve the references in the WHERE clause. */
@@ -89464,8 +92103,8 @@ static void fkScanChildren(
}
/*
-** This function returns a pointer to the head of a linked list of FK
-** constraints for which table pTab is the parent table. For example,
+** This function returns a linked list of FKey objects (connected by
+** FKey.pNextTo) holding all children of table pTab. For example,
** given the following schema:
**
** CREATE TABLE t1(a PRIMARY KEY);
@@ -89533,7 +92172,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
** when this statement is run. */
FKey *p;
for(p=pTab->pFKey; p; p=p->pNextFrom){
- if( p->isDeferred ) break;
+ if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
}
if( !p ) return;
iSkip = sqlite3VdbeMakeLabel(v);
@@ -89547,11 +92186,17 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
/* If the DELETE has generated immediate foreign key constraint
** violations, halt the VDBE and return an error at this point, before
** any modifications to the schema are made. This is because statement
- ** transactions are not able to rollback schema changes. */
- sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
- OE_Abort, "foreign key constraint failed", P4_STATIC
- );
+ ** transactions are not able to rollback schema changes.
+ **
+ ** If the SQLITE_DeferFKs flag is set, then this is not required, as
+ ** the statement transaction will not be rolled back even if FK
+ ** constraints are violated.
+ */
+ if( (db->flags & SQLITE_DeferFKs)==0 ){
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
+ OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
+ }
if( iSkip ){
sqlite3VdbeResolveLabel(v, iSkip);
@@ -89559,6 +92204,70 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
}
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the child table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** child key for FK constraint *p are modified.
+*/
+static int fkChildIsModified(
+ Table *pTab, /* Table being updated */
+ FKey *p, /* Foreign key for which pTab is the child */
+ int *aChange, /* Array indicating modified columns */
+ int bChngRowid /* True if rowid is modified by this update */
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ int iChildKey = p->aCol[i].iFrom;
+ if( aChange[iChildKey]>=0 ) return 1;
+ if( iChildKey==pTab->iPKey && bChngRowid ) return 1;
+ }
+ return 0;
+}
+
+/*
+** The second argument points to an FKey object representing a foreign key
+** for which pTab is the parent table. An UPDATE statement against pTab
+** is currently being processed. For each column of the table that is
+** actually updated, the corresponding element in the aChange[] array
+** is zero or greater (if a column is unmodified the corresponding element
+** is set to -1). If the rowid column is modified by the UPDATE statement
+** the bChngRowid argument is non-zero.
+**
+** This function returns true if any of the columns that are part of the
+** parent key for FK constraint *p are modified.
+*/
+static int fkParentIsModified(
+ Table *pTab,
+ FKey *p,
+ int *aChange,
+ int bChngRowid
+){
+ int i;
+ for(i=0; i<p->nCol; i++){
+ char *zKey = p->aCol[i].zCol;
+ int iKey;
+ for(iKey=0; iKey<pTab->nCol; iKey++){
+ if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){
+ Column *pCol = &pTab->aCol[iKey];
+ if( zKey ){
+ if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1;
+ }else if( pCol->colFlags & COLFLAG_PRIMKEY ){
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
/*
** This function is called when inserting, deleting or updating a row of
** table pTab to generate VDBE code to perform foreign key constraint
@@ -89583,7 +92292,9 @@ SQLITE_PRIVATE void sqlite3FkCheck(
Parse *pParse, /* Parse context */
Table *pTab, /* Row is being deleted from this table */
int regOld, /* Previous row data is stored here */
- int regNew /* New row data is stored here */
+ int regNew, /* New row data is stored here */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
){
sqlite3 *db = pParse->db; /* Database handle */
FKey *pFKey; /* Used to iterate through FKs */
@@ -89611,6 +92322,13 @@ SQLITE_PRIVATE void sqlite3FkCheck(
int i;
int isIgnore = 0;
+ if( aChange
+ && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
+ && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0
+ ){
+ continue;
+ }
+
/* Find the parent table of this foreign key. Also find a unique index
** on the parent key columns in the parent table. If either of these
** schema items cannot be located, set an error in pParse and return
@@ -89687,13 +92405,20 @@ SQLITE_PRIVATE void sqlite3FkCheck(
sqlite3DbFree(db, aiFree);
}
- /* Loop through all the foreign key constraints that refer to this table */
+ /* Loop through all the foreign key constraints that refer to this table.
+ ** (the "child" constraints) */
for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
Index *pIdx = 0; /* Foreign key index for pFKey */
SrcList *pSrc;
int *aiCol = 0;
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
+ if( aChange && fkParentIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){
+ continue;
+ }
+
+ if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
+ && !pParse->pToplevel && !pParse->isMultiWrite
+ ){
assert( regOld==0 && regNew!=0 );
/* Inserting a single row into a parent table cannot cause an immediate
** foreign key violation. So do nothing in this case. */
@@ -89706,9 +92431,8 @@ SQLITE_PRIVATE void sqlite3FkCheck(
}
assert( aiCol || pFKey->nCol==1 );
- /* Create a SrcList structure containing a single table (the table
- ** the foreign key that refers to this table is attached to). This
- ** is required for the sqlite3WhereXXX() interface. */
+ /* Create a SrcList structure containing the child table. We need the
+ ** child table as a SrcList for sqlite3WhereBegin() */
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
struct SrcList_item *pItem = pSrc->a;
@@ -89757,13 +92481,14 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask(
Index *pIdx = 0;
sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
if( pIdx ){
- for(i=0; i<pIdx->nColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
+ for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
}
}
}
return mask;
}
+
/*
** This function is called before generating code to update or delete a
** row contained in table pTab. If the operation is a DELETE, then
@@ -89793,32 +92518,16 @@ SQLITE_PRIVATE int sqlite3FkRequired(
}else{
/* This is an UPDATE. Foreign key processing is only required if the
** operation modifies one or more child or parent key columns. */
- int i;
FKey *p;
/* Check if any child key columns are being modified. */
for(p=pTab->pFKey; p; p=p->pNextFrom){
- for(i=0; i<p->nCol; i++){
- int iChildKey = p->aCol[i].iFrom;
- if( aChange[iChildKey]>=0 ) return 1;
- if( iChildKey==pTab->iPKey && chngRowid ) return 1;
- }
+ if( fkChildIsModified(pTab, p, aChange, chngRowid) ) return 1;
}
/* Check if any parent key columns are being modified. */
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
- for(i=0; i<p->nCol; i++){
- char *zKey = p->aCol[i].zCol;
- int iKey;
- for(iKey=0; iKey<pTab->nCol; iKey++){
- Column *pCol = &pTab->aCol[iKey];
- if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey)
- : (pCol->colFlags & COLFLAG_PRIMKEY)!=0) ){
- if( aChange[iKey]>=0 ) return 1;
- if( iKey==pTab->iPKey && chngRowid ) return 1;
- }
- }
- }
+ if( fkParentIsModified(pTab, p, aChange, chngRowid) ) return 1;
}
}
}
@@ -89964,7 +92673,7 @@ static Trigger *fkActionTrigger(
tFrom.z = zFrom;
tFrom.n = nFrom;
- pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed");
+ pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
if( pRaise ){
pRaise->affinity = OE_Abort;
}
@@ -90044,7 +92753,9 @@ SQLITE_PRIVATE void sqlite3FkActions(
Parse *pParse, /* Parse context */
Table *pTab, /* Table being updated or deleted from */
ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */
- int regOld /* Address of array containing old row */
+ int regOld, /* Address of array containing old row */
+ int *aChange, /* Array indicating UPDATEd columns (or 0) */
+ int bChngRowid /* True if rowid is UPDATEd */
){
/* If foreign-key support is enabled, iterate through all FKs that
** refer to table pTab. If there is an action associated with the FK
@@ -90053,9 +92764,11 @@ SQLITE_PRIVATE void sqlite3FkActions(
if( pParse->db->flags&SQLITE_ForeignKeys ){
FKey *pFKey; /* Iterator variable */
for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
- Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges);
- if( pAction ){
- sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0);
+ if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){
+ Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges);
+ if( pAct ){
+ sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0);
+ }
}
}
}
@@ -90124,10 +92837,16 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
*/
/*
-** Generate code that will open a table for reading.
+** Generate code that will
+**
+** (1) acquire a lock for table pTab then
+** (2) open pTab as cursor iCur.
+**
+** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index
+** for that table that is actually opened.
*/
SQLITE_PRIVATE void sqlite3OpenTable(
- Parse *p, /* Generate code into this VDBE */
+ Parse *pParse, /* Generate code into this VDBE */
int iCur, /* The cursor number of the table */
int iDb, /* The database index in sqlite3.aDb[] */
Table *pTab, /* The table to be opened */
@@ -90135,12 +92854,21 @@ SQLITE_PRIVATE void sqlite3OpenTable(
){
Vdbe *v;
assert( !IsVirtual(pTab) );
- v = sqlite3GetVdbe(p);
+ v = sqlite3GetVdbe(pParse);
assert( opcode==OP_OpenWrite || opcode==OP_OpenRead );
- sqlite3TableLock(p, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName);
- sqlite3VdbeAddOp3(v, opcode, iCur, pTab->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(pTab->nCol), P4_INT32);
- VdbeComment((v, "%s", pTab->zName));
+ sqlite3TableLock(pParse, iDb, pTab->tnum,
+ (opcode==OP_OpenWrite)?1:0, pTab->zName);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
+ VdbeComment((v, "%s", pTab->zName));
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ assert( pPk->tnum=pTab->tnum );
+ sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ VdbeComment((v, "%s", pTab->zName));
+ }
}
/*
@@ -90176,15 +92904,15 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
int n;
Table *pTab = pIdx->pTable;
sqlite3 *db = sqlite3VdbeDb(v);
- pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
+ pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
if( !pIdx->zColAff ){
db->mallocFailed = 1;
return 0;
}
for(n=0; n<pIdx->nColumn; n++){
- pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity;
+ i16 x = pIdx->aiColumn[n];
+ pIdx->zColAff[n] = x<0 ? SQLITE_AFF_INTEGER : pTab->aCol[x].affinity;
}
- pIdx->zColAff[n++] = SQLITE_AFF_INTEGER;
pIdx->zColAff[n] = 0;
}
@@ -90530,7 +93258,7 @@ static int xferOptimization(
);
/*
-** This routine is call to handle SQL of the following forms:
+** This routine is called to handle SQL of the following forms:
**
** insert into TABLE (IDLIST) values(EXPRLIST)
** insert into TABLE (IDLIST) select
@@ -90545,12 +93273,12 @@ static int xferOptimization(
** data for the insert.
**
** The code generated follows one of four templates. For a simple
-** select with data coming from a VALUES clause, the code executes
+** insert with data coming from a VALUES clause, the code executes
** once straight down through. Pseudo-code follows (we call this
** the "1st template"):
**
** open write cursor to <table> and its indices
-** puts VALUES clause expressions onto the stack
+** put VALUES clause expressions into registers
** write the resulting record into <table>
** cleanup
**
@@ -90648,8 +93376,9 @@ SQLITE_PRIVATE void sqlite3Insert(
Index *pIdx; /* For looping over indices of the table */
int nColumn; /* Number of columns in the data */
int nHidden = 0; /* Number of hidden columns if TABLE is virtual */
- int baseCur = 0; /* VDBE Cursor number for pTab */
- int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
+ int iDataCur = 0; /* VDBE cursor that is the main data repository */
+ int iIdxCur = 0; /* First index cursor */
+ int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
int endOfLoop; /* Label for the end of the insertion loop */
int useTempTable = 0; /* Store SELECT results in intermediate table */
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
@@ -90660,6 +93389,7 @@ SQLITE_PRIVATE void sqlite3Insert(
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
int appendFlag = 0; /* True if the insert is likely to be an append */
+ int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -90699,6 +93429,7 @@ SQLITE_PRIVATE void sqlite3Insert(
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
}
+ withoutRowid = !HasRowid(pTab);
/* Figure out if we have any triggers and if the table being
** inserted into is a view
@@ -90718,16 +93449,13 @@ SQLITE_PRIVATE void sqlite3Insert(
assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );
/* If pTab is really a view, make sure it has been initialized.
- ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual
- ** module table).
+ ** ViewGetColumnNames() is a no-op if pTab is not a view.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto insert_cleanup;
}
- /* Ensure that:
- * (a) the table is not read-only,
- * (b) that if it is a view then ON INSERT triggers exist
+ /* Cannot insert into a read-only table.
*/
if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
goto insert_cleanup;
@@ -90768,8 +93496,7 @@ SQLITE_PRIVATE void sqlite3Insert(
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
- /* Data is coming from a SELECT. Generate a co-routine to run that
- ** SELECT. */
+ /* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
if( rc ) goto insert_cleanup;
@@ -90781,7 +93508,7 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
- ** FALSE if each* row of the SELECT can be written directly into
+ ** FALSE if each output row of the SELECT can be written directly into
** the destination table (template 3).
**
** A temp table must be used if the table being updated is also one
@@ -90864,11 +93591,11 @@ SQLITE_PRIVATE void sqlite3Insert(
** remember the column indices.
**
** If the table has an INTEGER PRIMARY KEY column and that column
- ** is named in the IDLIST, then record in the keyColumn variable
- ** the index into IDLIST of the primary key column. keyColumn is
+ ** is named in the IDLIST, then record in the ipkColumn variable
+ ** the index into IDLIST of the primary key column. ipkColumn is
** the index of the primary key as it appears in IDLIST, not as
- ** is appears in the original table. (The index of the primary
- ** key in the original table is pTab->iPKey.)
+ ** is appears in the original table. (The index of the INTEGER
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
*/
if( pColumn ){
for(i=0; i<pColumn->nId; i++){
@@ -90879,14 +93606,14 @@ SQLITE_PRIVATE void sqlite3Insert(
if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
pColumn->a[i].idx = j;
if( j==pTab->iPKey ){
- keyColumn = i;
+ ipkColumn = i; assert( !withoutRowid );
}
break;
}
}
if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pColumn->a[i].zName) ){
- keyColumn = i;
+ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
+ ipkColumn = i;
}else{
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
pTabList, 0, pColumn->a[i].zName);
@@ -90898,11 +93625,11 @@ SQLITE_PRIVATE void sqlite3Insert(
}
/* If there is no IDLIST term but the table has an integer primary
- ** key, the set the keyColumn variable to the primary key column index
- ** in the original table definition.
+ ** key, the set the ipkColumn variable to the integer primary key
+ ** column index in the original table definition.
*/
if( pColumn==0 && nColumn>0 ){
- keyColumn = pTab->iPKey;
+ ipkColumn = pTab->iPKey;
}
/* Initialize the count of rows to be inserted
@@ -90915,9 +93642,8 @@ SQLITE_PRIVATE void sqlite3Insert(
/* If this is not a view, open the table and and all indices */
if( !isView ){
int nIdx;
-
- baseCur = pParse->nTab;
- nIdx = sqlite3OpenTableAndIndices(pParse, pTab, baseCur, OP_OpenWrite);
+ nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0,
+ &iDataCur, &iIdxCur);
aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1));
if( aRegIdx==0 ){
goto insert_cleanup;
@@ -90977,15 +93703,16 @@ SQLITE_PRIVATE void sqlite3Insert(
** we do not know what the unique ID will be (because the insert has
** not happened yet) so we substitute a rowid of -1
*/
- if( keyColumn<0 ){
+ if( ipkColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
}else{
int j1;
+ assert( !withoutRowid );
if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
}else{
assert( pSelect==0 ); /* Otherwise useTempTable is true */
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
@@ -91035,29 +93762,27 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
}
- /* Push the record number for the new entry onto the stack. The
- ** record number is a randomly generate integer created by NewRowid
- ** except when the table has an INTEGER PRIMARY KEY column, in which
- ** case the record number is the same as that column.
+ /* Compute the content of the next row to insert into a range of
+ ** registers beginning at regIns.
*/
if( !isView ){
if( IsVirtual(pTab) ){
/* The row that the VUpdate opcode will delete: none */
sqlite3VdbeAddOp2(v, OP_Null, 0, regIns);
}
- if( keyColumn>=0 ){
+ if( ipkColumn>=0 ){
if( useTempTable ){
- sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+keyColumn, regRowid);
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+ipkColumn, regRowid);
}else{
VdbeOp *pOp;
- sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
+ sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
pOp = sqlite3VdbeGetOp(v, -1);
if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
- pOp->p1 = baseCur;
+ pOp->p1 = iDataCur;
pOp->p2 = regRowid;
pOp->p3 = regAutoinc;
}
@@ -91069,7 +93794,7 @@ SQLITE_PRIVATE void sqlite3Insert(
int j1;
if( !IsVirtual(pTab) ){
j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
sqlite3VdbeJumpHere(v, j1);
}else{
j1 = sqlite3VdbeCurrentAddr(v);
@@ -91077,15 +93802,15 @@ SQLITE_PRIVATE void sqlite3Insert(
}
sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
}
- }else if( IsVirtual(pTab) ){
+ }else if( IsVirtual(pTab) || withoutRowid ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
}else{
- sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+ sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
appendFlag = 1;
}
autoIncStep(pParse, regAutoinc, regRowid);
- /* Push onto the stack, data for all columns of the new entry, beginning
+ /* Compute data for all columns of the new entry, beginning
** with the first column.
*/
nHidden = 0;
@@ -91093,8 +93818,8 @@ SQLITE_PRIVATE void sqlite3Insert(
int iRegStore = regRowid+1+i;
if( i==pTab->iPKey ){
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
- ** Whenever this column is read, the record number will be substituted
- ** in its place. So will fill this column with a NULL to avoid
+ ** Whenever this column is read, the rowid will be substituted
+ ** in its place. Hence, fill this column with a NULL to avoid
** taking up data space with information that will never be used. */
sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
continue;
@@ -91137,13 +93862,12 @@ SQLITE_PRIVATE void sqlite3Insert(
#endif
{
int isReplace; /* Set to true if constraints may cause a replace */
- sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
- keyColumn>=0, 0, onError, endOfLoop, &isReplace
- );
- sqlite3FkCheck(pParse, pTab, 0, regIns);
- sqlite3CompleteInsertion(
- pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
);
+ sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regIns, aRegIdx, 0, appendFlag, isReplace==0);
}
}
@@ -91174,9 +93898,9 @@ SQLITE_PRIVATE void sqlite3Insert(
if( !IsVirtual(pTab) && !isView ){
/* Close all tables opened */
- sqlite3VdbeAddOp1(v, OP_Close, baseCur);
- for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
- sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur);
+ if( iDataCur<iIdxCur ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
+ for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur);
}
}
@@ -91221,36 +93945,48 @@ insert_cleanup:
#undef tmask
#endif
-
/*
-** Generate code to do constraint checks prior to an INSERT or an UPDATE.
-**
-** The input is a range of consecutive registers as follows:
+** Generate code to do constraint checks prior to an INSERT or an UPDATE
+** on table pTab.
**
-** 1. The rowid of the row after the update.
+** The regNewData parameter is the first register in a range that contains
+** the data to be inserted or the data after the update. There will be
+** pTab->nCol+1 registers in this range. The first register (the one
+** that regNewData points to) will contain the new rowid, or NULL in the
+** case of a WITHOUT ROWID table. The second register in the range will
+** contain the content of the first table column. The third register will
+** contain the content of the second table column. And so forth.
**
-** 2. The data in the first column of the entry after the update.
+** The regOldData parameter is similar to regNewData except that it contains
+** the data prior to an UPDATE rather than afterwards. regOldData is zero
+** for an INSERT. This routine can distinguish between UPDATE and INSERT by
+** checking regOldData for zero.
**
-** i. Data from middle columns...
+** For an UPDATE, the pkChng boolean is true if the true primary key (the
+** rowid for a normal table or the PRIMARY KEY for a WITHOUT ROWID table)
+** might be modified by the UPDATE. If pkChng is false, then the key of
+** the iDataCur content table is guaranteed to be unchanged by the UPDATE.
**
-** N. The data in the last column of the entry after the update.
+** For an INSERT, the pkChng boolean indicates whether or not the rowid
+** was explicitly specified as part of the INSERT statement. If pkChng
+** is zero, it means that the either rowid is computed automatically or
+** that the table is a WITHOUT ROWID table and has no rowid. On an INSERT,
+** pkChng will only be true if the INSERT statement provides an integer
+** value for either the rowid column or its INTEGER PRIMARY KEY alias.
**
-** The regRowid parameter is the index of the register containing (1).
-**
-** If isUpdate is true and rowidChng is non-zero, then rowidChng contains
-** the address of a register containing the rowid before the update takes
-** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate
-** is false, indicating an INSERT statement, then a non-zero rowidChng
-** indicates that the rowid was explicitly specified as part of the
-** INSERT statement. If rowidChng is false, it means that the rowid is
-** computed automatically in an insert or that the rowid value is not
-** modified by an update.
-**
-** The code generated by this routine store new index entries into
+** The code generated by this routine will store new index entries into
** registers identified by aRegIdx[]. No index entry is created for
** indices where aRegIdx[i]==0. The order of indices in aRegIdx[] is
** the same as the order of indices on the linked list of indices
-** attached to the table.
+** at pTab->pIndex.
+**
+** The caller must have already opened writeable cursors on the main
+** table and all applicable indices (that is to say, all indices for which
+** aRegIdx[] is not zero). iDataCur is the cursor for the main table when
+** inserting or updating a rowid table, or the cursor for the PRIMARY KEY
+** index when operating on a WITHOUT ROWID table. iIdxCur is the cursor
+** for the first index in the pTab->pIndex list. Cursors for other indices
+** are at iIdxCur+N for the N-th element of the pTab->pIndex list.
**
** This routine also generates code to check constraints. NOT NULL,
** CHECK, and UNIQUE constraints are all checked. If a constraint fails,
@@ -91260,22 +93996,23 @@ insert_cleanup:
** Constraint type Action What Happens
** --------------- ---------- ----------------------------------------
** any ROLLBACK The current transaction is rolled back and
-** sqlite3_exec() returns immediately with a
+** sqlite3_step() returns immediately with a
** return code of SQLITE_CONSTRAINT.
**
** any ABORT Back out changes from the current command
** only (do not do a complete rollback) then
-** cause sqlite3_exec() to return immediately
+** cause sqlite3_step() to return immediately
** with SQLITE_CONSTRAINT.
**
-** any FAIL Sqlite3_exec() returns immediately with a
+** any FAIL Sqlite3_step() returns immediately with a
** return code of SQLITE_CONSTRAINT. The
** transaction is not rolled back and any
-** prior changes are retained.
+** changes to prior rows are retained.
**
-** any IGNORE The record number and data is popped from
-** the stack and there is an immediate jump
-** to label ignoreDest.
+** any IGNORE The attempt in insert or update the current
+** row is skipped, without throwing an error.
+** Processing continues with the next row.
+** (There is an immediate jump to ignoreDest.)
**
** NOT NULL REPLACE The NULL value is replace by the default
** value for that column. If the default value
@@ -91290,44 +94027,57 @@ insert_cleanup:
** Or if overrideError==OE_Default, then the pParse->onError parameter
** is used. Or if pParse->onError==OE_Default then the onError value
** for the constraint is used.
-**
-** The calling routine must open a read/write cursor for pTab with
-** cursor number "baseCur". All indices of pTab must also have open
-** read/write cursors with cursor number baseCur+i for the i-th cursor.
-** Except, if there is no possibility of a REPLACE action then
-** cursors do not need to be open for indices where aRegIdx[i]==0.
*/
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
- Parse *pParse, /* The parser context */
- Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Index of the range of input registers */
- int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int rowidChng, /* True if the rowid might collide with existing entry */
- int isUpdate, /* True for UPDATE, False for INSERT */
- int overrideError, /* Override onError to this if not OE_Default */
- int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
- int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
-){
- int i; /* loop counter */
- Vdbe *v; /* VDBE under constrution */
- int nCol; /* Number of columns */
- int onError; /* Conflict resolution strategy */
- int j1; /* Addresss of jump instruction */
- int j2 = 0, j3; /* Addresses of jump instructions */
- int regData; /* Register containing first data column */
- int iCur; /* Table cursor number */
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* The table being inserted or updated */
+ int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */
+ int iDataCur, /* Canonical data cursor (main table or PK index) */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* First register in a range holding values to insert */
+ int regOldData, /* Previous content. 0 for INSERTs */
+ u8 pkChng, /* Non-zero if the rowid or PRIMARY KEY changed */
+ u8 overrideError, /* Override onError to this if not OE_Default */
+ int ignoreDest, /* Jump to this label on an OE_Ignore resolution */
+ int *pbMayReplace /* OUT: Set to true if constraint may cause a replace */
+){
+ Vdbe *v; /* VDBE under constrution */
Index *pIdx; /* Pointer to one of the indices */
+ Index *pPk = 0; /* The PRIMARY KEY index */
sqlite3 *db; /* Database connection */
+ int i; /* loop counter */
+ int ix; /* Index loop counter */
+ int nCol; /* Number of columns */
+ int onError; /* Conflict resolution strategy */
+ int j1; /* Addresss of jump instruction */
int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
- int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid;
+ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
+ int ipkTop = 0; /* Top of the rowid change constraint check */
+ int ipkBottom = 0; /* Bottom of the rowid change constraint check */
+ u8 isUpdate; /* True if this is an UPDATE operation */
+ isUpdate = regOldData!=0;
db = pParse->db;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
nCol = pTab->nCol;
- regData = regRowid + 1;
+
+ /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for
+ ** normal rowid tables. nPkField is the number of key fields in the
+ ** pPk index or 1 for a rowid table. In other words, nPkField is the
+ ** number of fields in the true primary key of the table. */
+ if( HasRowid(pTab) ){
+ pPk = 0;
+ nPkField = 1;
+ }else{
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ nPkField = pPk->nKeyCol;
+ }
+
+ /* Record that this module has started */
+ VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
+ iDataCur, iIdxCur, regNewData, regOldData, pkChng));
/* Test all NOT NULL constraints.
*/
@@ -91350,24 +94100,24 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
switch( onError ){
case OE_Abort:
sqlite3MayAbort(pParse);
+ /* Fall through */
case OE_Rollback:
case OE_Fail: {
- char *zMsg;
- sqlite3VdbeAddOp3(v, OP_HaltIfNull,
- SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
- zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
- pTab->zName, pTab->aCol[i].zName);
- sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
+ char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
+ pTab->aCol[i].zName);
+ sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i, zMsg, P4_DYNAMIC);
+ sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
break;
}
case OE_Ignore: {
- sqlite3VdbeAddOp2(v, OP_IsNull, regData+i, ignoreDest);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
break;
}
default: {
assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regData+i);
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regData+i);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
+ sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeJumpHere(v, j1);
break;
}
@@ -91379,7 +94129,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
#ifndef SQLITE_OMIT_CHECK
if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
ExprList *pCheck = pTab->pCheck;
- pParse->ckBase = regData;
+ pParse->ckBase = regNewData+1;
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
for(i=0; i<pCheck->nExpr; i++){
int allOk = sqlite3VdbeMakeLabel(v);
@@ -91387,37 +94137,58 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
if( onError==OE_Ignore ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
}else{
- char *zConsName = pCheck->a[i].zName;
+ char *zName = pCheck->a[i].zName;
+ if( zName==0 ) zName = pTab->zName;
if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
- if( zConsName ){
- zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
- }else{
- zConsName = 0;
- }
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
- onError, zConsName, P4_DYNAMIC);
+ onError, zName, P4_TRANSIENT,
+ P5_ConstraintCheck);
}
sqlite3VdbeResolveLabel(v, allOk);
}
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
- /* If we have an INTEGER PRIMARY KEY, make sure the primary key
- ** of the new record does not previously exist. Except, if this
- ** is an UPDATE and the primary key is not changing, that is OK.
+ /* If rowid is changing, make sure the new rowid does not previously
+ ** exist in the table.
*/
- if( rowidChng ){
+ if( pkChng && pPk==0 ){
+ int addrRowidOk = sqlite3VdbeMakeLabel(v);
+
+ /* Figure out what action to take in case of a rowid collision */
onError = pTab->keyConf;
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
-
+
if( isUpdate ){
- j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
+ /* pkChng!=0 does not mean that the rowid has change, only that
+ ** it might have changed. Skip the conflict logic below if the rowid
+ ** is unchanged. */
+ sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
}
- j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
+
+ /* If the response to a rowid conflict is REPLACE but the response
+ ** to some other UNIQUE constraint is FAIL or IGNORE, then we need
+ ** to defer the running of the rowid conflict checking until after
+ ** the UNIQUE constraints have run.
+ */
+ if( onError==OE_Replace && overrideError!=OE_Replace ){
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Ignore || pIdx->onError==OE_Fail ){
+ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto);
+ break;
+ }
+ }
+ }
+
+ /* Check to see if the new rowid already exists in the table. Skip
+ ** the following conflict logic if it does not. */
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+
+ /* Generate code that deals with a rowid collision */
switch( onError ){
default: {
onError = OE_Abort;
@@ -91426,8 +94197,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
- onError, "PRIMARY KEY must be unique", P4_STATIC);
+ sqlite3RowidConstraint(pParse, onError, pTab);
break;
}
case OE_Replace: {
@@ -91459,57 +94229,88 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
sqlite3MultiWrite(pParse);
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
- );
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regNewData, 1, 0, OE_Replace, 1);
}else if( pTab->pIndex ){
sqlite3MultiWrite(pParse);
- sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0);
}
seenReplace = 1;
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
+ /*assert( seenReplace==0 );*/
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- if( isUpdate ){
- sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeResolveLabel(v, addrRowidOk);
+ if( ipkTop ){
+ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto);
+ sqlite3VdbeJumpHere(v, ipkTop);
}
}
/* Test all UNIQUE constraints by creating entries for each UNIQUE
** index and making sure that duplicate entries do not already exist.
- ** Add the new records to the indices as we go.
- */
- for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
- int regIdx;
- int regR;
-
- if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
-
- /* Create a key for accessing the index entry */
- regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
+ ** Compute the revised record entries for indices as we go.
+ **
+ ** This loop also handles the case of the PRIMARY KEY index for a
+ ** WITHOUT ROWID table.
+ */
+ for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){
+ int regIdx; /* Range of registers hold conent for pIdx */
+ int regR; /* Range of registers holding conflicting PK */
+ int iThisCur; /* Cursor for this UNIQUE index */
+ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
+
+ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
+ iThisCur = iIdxCur+ix;
+ addrUniqueOk = sqlite3VdbeMakeLabel(v);
+
+ /* Skip partial indices for which the WHERE clause is not true */
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]);
+ pParse->ckBase = regNewData+1;
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrUniqueOk,
+ SQLITE_JUMPIFNULL);
+ pParse->ckBase = 0;
+ }
+
+ /* Create a record for this index entry as it should appear after
+ ** the insert or update. Store that record in the aRegIdx[ix] register
+ */
+ regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
for(i=0; i<pIdx->nColumn; i++){
- int idx = pIdx->aiColumn[i];
- if( idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
+ int iField = pIdx->aiColumn[i];
+ int x;
+ if( iField<0 || iField==pTab->iPKey ){
+ x = regNewData;
}else{
- sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
+ x = iField + regNewData + 1;
}
+ sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
+ VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
- sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
- sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
+ VdbeComment((v, "for %s", pIdx->zName));
+ sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
+
+ /* In an UPDATE operation, if this index is the PRIMARY KEY index
+ ** of a WITHOUT ROWID table and there has been no change the
+ ** primary key, then no collision is possible. The collision detection
+ ** logic below can all be skipped. */
+ if( isUpdate && pPk==pIdx && pkChng==0 ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
- /* Find out what action to take in case there is an indexing conflict */
+ /* Find out what action to take in case there is a uniqueness conflict */
onError = pIdx->onError;
if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
@@ -91517,18 +94318,57 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}else if( onError==OE_Default ){
onError = OE_Abort;
}
- if( seenReplace ){
- if( onError==OE_Ignore ) onError = OE_Replace;
- else if( onError==OE_Fail ) onError = OE_Abort;
- }
/* Check to see if the new index entry will be unique */
- regR = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR);
- j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
- regR, SQLITE_INT_TO_PTR(regIdx),
- P4_INT32);
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+ sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
+ regIdx, pIdx->nKeyCol);
+
+ /* Generate code to handle collisions */
+ regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
+ }
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
+ for(i=0; i<pPk->nKeyCol; i++){
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
+
+ for(i=0; i<pPk->nKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
+ }
+ }
+ }
/* Generate code that executes if the new index entry is not unique */
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
@@ -91537,30 +94377,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
case OE_Rollback:
case OE_Abort:
case OE_Fail: {
- int j;
- StrAccum errMsg;
- const char *zSep;
- char *zErr;
-
- sqlite3StrAccumInit(&errMsg, 0, 0, 200);
- errMsg.db = db;
- zSep = pIdx->nColumn>1 ? "columns " : "column ";
- for(j=0; j<pIdx->nColumn; j++){
- char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
- sqlite3StrAccumAppend(&errMsg, zSep, -1);
- zSep = ", ";
- sqlite3StrAccumAppend(&errMsg, zCol, -1);
- }
- sqlite3StrAccumAppend(&errMsg,
- pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
- zErr = sqlite3StrAccumFinish(&errMsg);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
- onError, zErr, 0);
- sqlite3DbFree(errMsg.db, zErr);
+ sqlite3UniqueConstraint(pParse, onError, pIdx);
break;
}
case OE_Ignore: {
- assert( seenReplace==0 );
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
break;
}
@@ -91571,26 +94391,29 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
if( db->flags&SQLITE_RecTriggers ){
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
}
- sqlite3GenerateRowDelete(
- pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
- );
+ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
+ regR, nPkField, 0, OE_Replace, pIdx==pPk);
seenReplace = 1;
break;
}
}
- sqlite3VdbeJumpHere(v, j3);
- sqlite3ReleaseTempReg(pParse, regR);
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
+ if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
-
- if( pbMayReplace ){
- *pbMayReplace = seenReplace;
+ if( ipkTop ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, ipkTop+1);
+ sqlite3VdbeJumpHere(v, ipkBottom);
}
+
+ *pbMayReplace = seenReplace;
+ VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
-** A consecutive range of registers starting at regRowid contains the
+** A consecutive range of registers starting at regNewData contains the
** rowid and the content to be inserted.
**
** The arguments to this routine should be the same as the first six
@@ -91599,33 +94422,40 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
SQLITE_PRIVATE void sqlite3CompleteInsertion(
Parse *pParse, /* The parser context */
Table *pTab, /* the table into which we are inserting */
- int baseCur, /* Index of a read/write cursor pointing at pTab */
- int regRowid, /* Range of content */
+ int iDataCur, /* Cursor of the canonical data source */
+ int iIdxCur, /* First index cursor */
+ int regNewData, /* Range of content */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int isUpdate, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
- int i;
- Vdbe *v;
- int nIdx;
- Index *pIdx;
- u8 pik_flags;
- int regData;
- int regRec;
+ Vdbe *v; /* Prepared statements under construction */
+ Index *pIdx; /* An index being inserted or updated */
+ u8 pik_flags; /* flag values passed to the btree insert */
+ int regData; /* Content registers (after the rowid) */
+ int regRec; /* Register holding assemblied record for the table */
+ int i; /* Loop counter */
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- for(i=nIdx-1; i>=0; i--){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
- sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
- if( useSeekResult ){
- sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
}
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
+ pik_flags = 0;
+ if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) ){
+ assert( pParse->nested==0 );
+ pik_flags |= OPFLAG_NCHANGE;
+ }
+ if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags);
}
- regData = regRowid + 1;
+ if( !HasRowid(pTab) ) return;
+ regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
sqlite3TableAffinityStr(v, pTab);
@@ -91642,7 +94472,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
if( useSeekResult ){
pik_flags |= OPFLAG_USESEEKRESULT;
}
- sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
}
@@ -91650,39 +94480,71 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
}
/*
-** Generate code that will open cursors for a table and for all
-** indices of that table. The "baseCur" parameter is the cursor number used
-** for the table. Indices are opened on subsequent cursors.
+** Allocate cursors for the pTab table and all its indices and generate
+** code to open and initialized those cursors.
+**
+** The cursor for the object that contains the complete data (normally
+** the table itself, but the PRIMARY KEY index in the case of a WITHOUT
+** ROWID table) is returned in *piDataCur. The first index cursor is
+** returned in *piIdxCur. The number of indices is returned.
+**
+** Use iBase as the first cursor (either the *piDataCur for rowid tables
+** or the first index for WITHOUT ROWID tables) if it is non-negative.
+** If iBase is negative, then allocate the next available cursor.
**
-** Return the number of indices on the table.
+** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
+** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
+** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
+** pTab->pIndex list.
*/
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */
Table *pTab, /* Table to be opened */
- int baseCur, /* Cursor number assigned to the table */
- int op /* OP_OpenRead or OP_OpenWrite */
+ int op, /* OP_OpenRead or OP_OpenWrite */
+ int iBase, /* Use this for the table cursor, if there is one */
+ u8 *aToOpen, /* If not NULL: boolean for each table and index */
+ int *piDataCur, /* Write the database source cursor number here */
+ int *piIdxCur /* Write the first index cursor number here */
){
int i;
int iDb;
+ int iDataCur;
Index *pIdx;
Vdbe *v;
- if( IsVirtual(pTab) ) return 0;
+ assert( op==OP_OpenRead || op==OP_OpenWrite );
+ if( IsVirtual(pTab) ){
+ assert( aToOpen==0 );
+ *piDataCur = 0;
+ *piIdxCur = 1;
+ return 0;
+ }
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- sqlite3OpenTable(pParse, baseCur, iDb, pTab, op);
- for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- assert( pIdx->pSchema==pTab->pSchema );
- sqlite3VdbeAddOp4(v, op, i+baseCur, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- VdbeComment((v, "%s", pIdx->zName));
+ if( iBase<0 ) iBase = pParse->nTab;
+ iDataCur = iBase++;
+ if( piDataCur ) *piDataCur = iDataCur;
+ if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){
+ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op);
+ }else{
+ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
}
- if( pParse->nTab<baseCur+i ){
- pParse->nTab = baseCur+i;
+ if( piIdxCur ) *piIdxCur = iBase;
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ int iIdxCur = iBase++;
+ assert( pIdx->pSchema==pTab->pSchema );
+ if( pIdx->autoIndex==2 && !HasRowid(pTab) && piDataCur ){
+ *piDataCur = iIdxCur;
+ }
+ if( aToOpen==0 || aToOpen[i+1] ){
+ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ VdbeComment((v, "%s", pIdx->zName));
+ }
}
- return i-1;
+ if( iBase>pParse->nTab ) pParse->nTab = iBase;
+ return i;
}
@@ -91721,18 +94583,19 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
+** * The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
- if( pDest->nColumn!=pSrc->nColumn ){
+ if( pDest->nKeyCol!=pSrc->nKeyCol ){
return 0; /* Different number of columns */
}
if( pDest->onError!=pSrc->onError ){
return 0; /* Different conflict resolution strategies */
}
- for(i=0; i<pSrc->nColumn; i++){
+ for(i=0; i<pSrc->nKeyCol; i++){
if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
return 0; /* Different columns indexed */
}
@@ -91743,6 +94606,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
return 0; /* Different collating sequences */
}
}
+ if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+ return 0; /* Different WHERE clauses */
+ }
/* If no test above fails then the indices must be compatible */
return 1;
@@ -91788,10 +94654,9 @@ static int xferOptimization(
int iDbSrc; /* The database of pSrc */
int iSrc, iDest; /* Cursors from source and destination */
int addr1, addr2; /* Loop addresses */
- int emptyDestTest; /* Address of test for empty pDest */
- int emptySrcTest; /* Address of test for empty pSrc */
+ int emptyDestTest = 0; /* Address of test for empty pDest */
+ int emptySrcTest = 0; /* Address of test for empty pSrc */
Vdbe *v; /* The VDBE we are building */
- KeyInfo *pKey; /* Key information for an index */
int regAutoinc; /* Memory register used by AUTOINC */
int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */
int regData, regRowid; /* Registers holding data and rowid */
@@ -91861,6 +94726,9 @@ static int xferOptimization(
if( pSrc==pDest ){
return 0; /* tab1 and tab2 may not be the same table */
}
+ if( HasRowid(pDest)!=HasRowid(pSrc) ){
+ return 0; /* source and destination must both be WITHOUT ROWID or not */
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( pSrc->tabFlags & TF_Virtual ){
return 0; /* tab2 must not be a virtual table */
@@ -91898,7 +94766,7 @@ static int xferOptimization(
}
}
#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
+ if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif
@@ -91931,7 +94799,10 @@ static int xferOptimization(
iSrc = pParse->nTab++;
iDest = pParse->nTab++;
regAutoinc = autoIncBegin(pParse, iDbDest, pDest);
+ regData = sqlite3GetTempReg(pParse);
+ regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
+ assert( HasRowid(pDest) || destHasUniqueIdx );
if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
@@ -91953,57 +94824,56 @@ static int xferOptimization(
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite3VdbeJumpHere(v, addr1);
- }else{
- emptyDestTest = 0;
}
- sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
- emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
- regData = sqlite3GetTempReg(pParse);
- regRowid = sqlite3GetTempReg(pParse);
- if( pDest->iPKey>=0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
- onError, "PRIMARY KEY must be unique", P4_STATIC);
- sqlite3VdbeJumpHere(v, addr2);
- autoIncStep(pParse, regAutoinc, regRowid);
- }else if( pDest->pIndex==0 ){
- addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
+ if( HasRowid(pSrc) ){
+ sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
+ emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
+ if( pDest->iPKey>=0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+ sqlite3RowidConstraint(pParse, onError, pDest);
+ sqlite3VdbeJumpHere(v, addr2);
+ autoIncStep(pParse, regAutoinc, regRowid);
+ }else if( pDest->pIndex==0 ){
+ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
+ }else{
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
+ assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+ }
+ sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
+ sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
+ sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
+ sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
- addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
- assert( (pDest->tabFlags & TF_Autoincrement)==0 );
+ sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
+ sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
}
- sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
- sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
- sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
- sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
assert( pSrcIdx );
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
- pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
- sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
+ sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
VdbeComment((v, "%s", pSrcIdx->zName));
- pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest);
+ sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
+ sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
+ sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
+ sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
- sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
- sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
if( emptyDestTest ){
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
sqlite3VdbeJumpHere(v, emptyDestTest);
@@ -92655,11 +95525,14 @@ struct sqlite3_api_routines {
** extension */
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
+# define SQLITE_EXTENSION_INIT3 \
+ extern const sqlite3_api_routines *sqlite3_api;
#else
/* This case when the file is being statically linked into the
** application */
# define SQLITE_EXTENSION_INIT1 /*no-op*/
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
+# define SQLITE_EXTENSION_INIT3 /*no-op*/
#endif
#endif /* _SQLITE3EXT_H_ */
@@ -93317,6 +96190,35 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
}
/*
+** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
+** set of routines that is invoked for each new database connection, if it
+** is currently on the list. If xInit is not on the list, then this
+** routine is a no-op.
+**
+** Return 1 if xInit was found on the list and removed. Return 0 if xInit
+** was not on the list.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
+#if SQLITE_THREADSAFE
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+#endif
+ int i;
+ int n = 0;
+ wsdAutoextInit;
+ sqlite3_mutex_enter(mutex);
+ for(i=wsdAutoext.nExt-1; i>=0; i--){
+ if( wsdAutoext.aExt[i]==xInit ){
+ wsdAutoext.nExt--;
+ wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
+ n++;
+ break;
+ }
+ }
+ sqlite3_mutex_leave(mutex);
+ return n;
+}
+
+/*
** Reset the automatic extension loading mechanism.
*/
SQLITE_API void sqlite3_reset_auto_extension(void){
@@ -93392,6 +96294,462 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
** This file contains code used to implement the PRAGMA command.
*/
+#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
+# if defined(__APPLE__)
+# define SQLITE_ENABLE_LOCKING_STYLE 1
+# else
+# define SQLITE_ENABLE_LOCKING_STYLE 0
+# endif
+#endif
+
+/***************************************************************************
+** The next block of code, including the PragTyp_XXXX macro definitions and
+** the aPragmaName[] object is composed of generated code. DO NOT EDIT.
+**
+** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun
+** that script. Then copy/paste the output in place of the following:
+*/
+#define PragTyp_HEADER_VALUE 0
+#define PragTyp_AUTO_VACUUM 1
+#define PragTyp_FLAG 2
+#define PragTyp_BUSY_TIMEOUT 3
+#define PragTyp_CACHE_SIZE 4
+#define PragTyp_CASE_SENSITIVE_LIKE 5
+#define PragTyp_COLLATION_LIST 6
+#define PragTyp_COMPILE_OPTIONS 7
+#define PragTyp_DATA_STORE_DIRECTORY 8
+#define PragTyp_DATABASE_LIST 9
+#define PragTyp_DEFAULT_CACHE_SIZE 10
+#define PragTyp_ENCODING 11
+#define PragTyp_FOREIGN_KEY_CHECK 12
+#define PragTyp_FOREIGN_KEY_LIST 13
+#define PragTyp_INCREMENTAL_VACUUM 14
+#define PragTyp_INDEX_INFO 15
+#define PragTyp_INDEX_LIST 16
+#define PragTyp_INTEGRITY_CHECK 17
+#define PragTyp_JOURNAL_MODE 18
+#define PragTyp_JOURNAL_SIZE_LIMIT 19
+#define PragTyp_LOCK_PROXY_FILE 20
+#define PragTyp_LOCKING_MODE 21
+#define PragTyp_PAGE_COUNT 22
+#define PragTyp_MMAP_SIZE 23
+#define PragTyp_PAGE_SIZE 24
+#define PragTyp_SECURE_DELETE 25
+#define PragTyp_SHRINK_MEMORY 26
+#define PragTyp_SOFT_HEAP_LIMIT 27
+#define PragTyp_STATS 28
+#define PragTyp_SYNCHRONOUS 29
+#define PragTyp_TABLE_INFO 30
+#define PragTyp_TEMP_STORE 31
+#define PragTyp_TEMP_STORE_DIRECTORY 32
+#define PragTyp_WAL_AUTOCHECKPOINT 33
+#define PragTyp_WAL_CHECKPOINT 34
+#define PragTyp_ACTIVATE_EXTENSIONS 35
+#define PragTyp_HEXKEY 36
+#define PragTyp_KEY 37
+#define PragTyp_REKEY 38
+#define PragTyp_LOCK_STATUS 39
+#define PragTyp_PARSER_TRACE 40
+#define PragFlag_NeedSchema 0x01
+static const struct sPragmaNames {
+ const char *const zName; /* Name of pragma */
+ u8 ePragTyp; /* PragTyp_XXX value */
+ u8 mPragFlag; /* Zero or more PragFlag_XXX values */
+ u32 iArg; /* Extra argument */
+} aPragmaNames[] = {
+#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
+ { /* zName: */ "activate_extensions",
+ /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "application_id",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ { /* zName: */ "auto_vacuum",
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
+ { /* zName: */ "automatic_index",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_AutoIndex },
+#endif
+#endif
+ { /* zName: */ "busy_timeout",
+ /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "cache_size",
+ /* ePragTyp: */ PragTyp_CACHE_SIZE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "cache_spill",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CacheSpill },
+#endif
+ { /* zName: */ "case_sensitive_like",
+ /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "checkpoint_fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CkptFullFSync },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "collation_list",
+ /* ePragTyp: */ PragTyp_COLLATION_LIST,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
+ { /* zName: */ "compile_options",
+ /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "count_changes",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_CountRows },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
+ { /* zName: */ "data_store_directory",
+ /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "database_list",
+ /* ePragTyp: */ PragTyp_DATABASE_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
+ { /* zName: */ "default_cache_size",
+ /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "defer_foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_DeferFKs },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "empty_result_callbacks",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_NullCallback },
+#endif
+#if !defined(SQLITE_OMIT_UTF16)
+ { /* zName: */ "encoding",
+ /* ePragTyp: */ PragTyp_ENCODING,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "foreign_key_check",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FOREIGN_KEY)
+ { /* zName: */ "foreign_key_list",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
+ { /* zName: */ "foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ForeignKeys },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "freelist_count",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "full_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_FullColNames },
+ { /* zName: */ "fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_FullFSync },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "hexkey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "hexrekey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if !defined(SQLITE_OMIT_CHECK)
+ { /* zName: */ "ignore_check_constraints",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_IgnoreChecks },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_AUTOVACUUM)
+ { /* zName: */ "incremental_vacuum",
+ /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "index_info",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "index_list",
+ /* ePragTyp: */ PragTyp_INDEX_LIST,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ { /* zName: */ "integrity_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "journal_mode",
+ /* ePragTyp: */ PragTyp_JOURNAL_MODE,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "journal_size_limit",
+ /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "key",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "legacy_file_format",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_LegacyFileFmt },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
+ { /* zName: */ "lock_proxy_file",
+ /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
+ { /* zName: */ "lock_status",
+ /* ePragTyp: */ PragTyp_LOCK_STATUS,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "locking_mode",
+ /* ePragTyp: */ PragTyp_LOCKING_MODE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "max_page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "mmap_size",
+ /* ePragTyp: */ PragTyp_MMAP_SIZE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+ { /* zName: */ "page_size",
+ /* ePragTyp: */ PragTyp_PAGE_SIZE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if defined(SQLITE_DEBUG)
+ { /* zName: */ "parser_trace",
+ /* ePragTyp: */ PragTyp_PARSER_TRACE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "query_only",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_QueryOnly },
+#endif
+#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
+ { /* zName: */ "quick_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "read_uncommitted",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ReadUncommitted },
+ { /* zName: */ "recursive_triggers",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_RecTriggers },
+#endif
+#if defined(SQLITE_HAS_CODEC)
+ { /* zName: */ "rekey",
+ /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "reverse_unordered_selects",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ReverseOrder },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "schema_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "secure_delete",
+ /* ePragTyp: */ PragTyp_SECURE_DELETE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "short_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_ShortColNames },
+#endif
+ { /* zName: */ "shrink_memory",
+ /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "soft_heap_limit",
+ /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ { /* zName: */ "sql_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_SqlTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "stats",
+ /* ePragTyp: */ PragTyp_STATS,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "synchronous",
+ /* ePragTyp: */ PragTyp_SYNCHRONOUS,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
+ { /* zName: */ "table_info",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ { /* zName: */ "temp_store",
+ /* ePragTyp: */ PragTyp_TEMP_STORE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "temp_store_directory",
+ /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+ { /* zName: */ "user_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+#if defined(SQLITE_DEBUG)
+ { /* zName: */ "vdbe_addoptrace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeAddopTrace },
+ { /* zName: */ "vdbe_debug",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+ { /* zName: */ "vdbe_eqp",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeEQP },
+ { /* zName: */ "vdbe_listing",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeListing },
+ { /* zName: */ "vdbe_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_VdbeTrace },
+#endif
+#endif
+#if !defined(SQLITE_OMIT_WAL)
+ { /* zName: */ "wal_autocheckpoint",
+ /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
+ /* ePragFlag: */ 0,
+ /* iArg: */ 0 },
+ { /* zName: */ "wal_checkpoint",
+ /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
+ /* ePragFlag: */ PragFlag_NeedSchema,
+ /* iArg: */ 0 },
+#endif
+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
+ { /* zName: */ "writable_schema",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlag: */ 0,
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+#endif
+};
+/* Number of pragmas: 56 on by default, 69 total. */
+/* End of the automatically generated pragma table.
+***************************************************************************/
+
/*
** Interpret the given string as a safety level. Return 0 for OFF,
** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
@@ -93537,92 +96895,35 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
}
-#ifndef SQLITE_OMIT_FLAG_PRAGMAS
-/*
-** Check to see if zRight and zLeft refer to a pragma that queries
-** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
-** Also, implement the pragma.
-*/
-static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
- static const struct sPragmaType {
- const char *zName; /* Name of the pragma */
- int mask; /* Mask for the db->flags value */
- } aPragma[] = {
- { "full_column_names", SQLITE_FullColNames },
- { "short_column_names", SQLITE_ShortColNames },
- { "count_changes", SQLITE_CountRows },
- { "empty_result_callbacks", SQLITE_NullCallback },
- { "legacy_file_format", SQLITE_LegacyFileFmt },
- { "fullfsync", SQLITE_FullFSync },
- { "checkpoint_fullfsync", SQLITE_CkptFullFSync },
- { "reverse_unordered_selects", SQLITE_ReverseOrder },
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
- { "automatic_index", SQLITE_AutoIndex },
-#endif
-#ifdef SQLITE_DEBUG
- { "sql_trace", SQLITE_SqlTrace },
- { "vdbe_listing", SQLITE_VdbeListing },
- { "vdbe_trace", SQLITE_VdbeTrace },
- { "vdbe_addoptrace", SQLITE_VdbeAddopTrace},
- { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing
- | SQLITE_VdbeTrace },
-#endif
-#ifndef SQLITE_OMIT_CHECK
- { "ignore_check_constraints", SQLITE_IgnoreChecks },
-#endif
- /* The following is VERY experimental */
- { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
-
- /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
- ** flag if there are any active statements. */
- { "read_uncommitted", SQLITE_ReadUncommitted },
- { "recursive_triggers", SQLITE_RecTriggers },
-
- /* This flag may only be set if both foreign-key and trigger support
- ** are present in the build. */
-#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- { "foreign_keys", SQLITE_ForeignKeys },
-#endif
- };
- int i;
- const struct sPragmaType *p;
- for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
- if( sqlite3StrICmp(zLeft, p->zName)==0 ){
- sqlite3 *db = pParse->db;
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- assert( v!=0 ); /* Already allocated by sqlite3Pragma() */
- if( ALWAYS(v) ){
- if( zRight==0 ){
- returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
- }else{
- int mask = p->mask; /* Mask of bits to set or clear. */
- if( db->autoCommit==0 ){
- /* Foreign key support may not be enabled or disabled while not
- ** in auto-commit mode. */
- mask &= ~(SQLITE_ForeignKeys);
- }
-
- if( sqlite3GetBoolean(zRight, 0) ){
- db->flags |= mask;
- }else{
- db->flags &= ~mask;
- }
- /* Many of the flag-pragmas modify the code generated by the SQL
- ** compiler (eg. count_changes). So add an opcode to expire all
- ** compiled SQL statements after modifying a pragma value.
- */
- sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
- }
+/*
+** Set the safety_level and pager flags for pager iDb. Or if iDb<0
+** set these values for all pagers.
+*/
+#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+static void setAllPagerFlags(sqlite3 *db){
+ if( db->autoCommit ){
+ Db *pDb = db->aDb;
+ int n = db->nDb;
+ assert( SQLITE_FullFSync==PAGER_FULLFSYNC );
+ assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC );
+ assert( SQLITE_CacheSpill==PAGER_CACHESPILL );
+ assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL)
+ == PAGER_FLAGS_MASK );
+ assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level );
+ while( (n--) > 0 ){
+ if( pDb->pBt ){
+ sqlite3BtreeSetPagerFlags(pDb->pBt,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) );
}
-
- return 1;
+ pDb++;
}
}
- return 0;
}
-#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
+#else
+# define setAllPagerFlags(X) /* no-op */
+#endif
+
/*
** Return a human-readable name for a constraint resolution action.
@@ -93693,8 +96994,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */
const char *zDb = 0; /* The database name */
Token *pId; /* Pointer to <id> token */
- int iDb; /* Database index for <database> */
char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
+ int iDb; /* Database index for <database> */
+ int lwr, upr, mid; /* Binary search bounds */
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
sqlite3 *db = pParse->db; /* The database connection */
Db *pDb; /* The specific database being pragmaed */
@@ -93750,16 +97052,41 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
sqlite3_free(aFcntl[0]);
}
- }else if( rc!=SQLITE_NOTFOUND ){
+ goto pragma_out;
+ }
+ if( rc!=SQLITE_NOTFOUND ){
if( aFcntl[0] ){
sqlite3ErrorMsg(pParse, "%s", aFcntl[0]);
sqlite3_free(aFcntl[0]);
}
pParse->nErr++;
pParse->rc = rc;
- }else
-
-
+ goto pragma_out;
+ }
+
+ /* Locate the pragma in the lookup table */
+ lwr = 0;
+ upr = ArraySize(aPragmaNames)-1;
+ while( lwr<=upr ){
+ mid = (lwr+upr)/2;
+ rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName);
+ if( rc==0 ) break;
+ if( rc<0 ){
+ upr = mid - 1;
+ }else{
+ lwr = mid + 1;
+ }
+ }
+ if( lwr>upr ) goto pragma_out;
+
+ /* Make sure the database schema is loaded if the pragma requires that */
+ if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){
+ if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ }
+
+ /* Jump to the appropriate pragma handler */
+ switch( aPragmaNames[mid].ePragTyp ){
+
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
/*
** PRAGMA [database.]default_cache_size
@@ -93777,7 +97104,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** size. But continue to take the absolute value of the default cache
** size of historical compatibility.
*/
- if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
+ case PragTyp_DEFAULT_CACHE_SIZE: {
static const VdbeOpList getCacheSize[] = {
{ OP_Transaction, 0, 0, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
@@ -93790,7 +97117,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_ResultRow, 1, 1, 0},
};
int addr;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeUsesBtree(v, iDb);
if( !zRight ){
sqlite3VdbeSetNumCols(v, 1);
@@ -93809,7 +97135,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
- }else
+ break;
+ }
#endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
@@ -93822,7 +97149,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** database page size value. The value can only be set if
** the database has not yet been created.
*/
- if( sqlite3StrICmp(zLeft,"page_size")==0 ){
+ case PragTyp_PAGE_SIZE: {
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
@@ -93837,7 +97164,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
db->mallocFailed = 1;
}
}
- }else
+ break;
+ }
/*
** PRAGMA [database.]secure_delete
@@ -93847,7 +97175,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** secure_delete flag. The second form changes the secure_delete
** flag setting and reports thenew value.
*/
- if( sqlite3StrICmp(zLeft,"secure_delete")==0 ){
+ case PragTyp_SECURE_DELETE: {
Btree *pBt = pDb->pBt;
int b = -1;
assert( pBt!=0 );
@@ -93862,7 +97190,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
b = sqlite3BtreeSecureDelete(pBt, b);
returnSingleInt(pParse, "secure_delete", b);
- }else
+ break;
+ }
/*
** PRAGMA [database.]max_page_count
@@ -93881,11 +97210,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
**
** Return the number of pages in the specified database.
*/
- if( sqlite3StrICmp(zLeft,"page_count")==0
- || sqlite3StrICmp(zLeft,"max_page_count")==0
- ){
+ case PragTyp_PAGE_COUNT: {
int iReg;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3CodeVerifySchema(pParse, iDb);
iReg = ++pParse->nMem;
if( sqlite3Tolower(zLeft[0])=='p' ){
@@ -93897,13 +97223,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
- }else
+ break;
+ }
/*
** PRAGMA [database.]locking_mode
** PRAGMA [database.]locking_mode = (normal|exclusive)
*/
- if( sqlite3StrICmp(zLeft,"locking_mode")==0 ){
+ case PragTyp_LOCKING_MODE: {
const char *zRet = "normal";
int eMode = getLockingMode(zRight);
@@ -93936,7 +97263,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
eMode = sqlite3PagerLockingMode(pPager, eMode);
}
- assert(eMode==PAGER_LOCKINGMODE_NORMAL||eMode==PAGER_LOCKINGMODE_EXCLUSIVE);
+ assert( eMode==PAGER_LOCKINGMODE_NORMAL
+ || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
zRet = "exclusive";
}
@@ -93944,25 +97272,18 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "locking_mode", SQLITE_STATIC);
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zRet, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
+ break;
+ }
/*
** PRAGMA [database.]journal_mode
** PRAGMA [database.]journal_mode =
** (delete|persist|off|truncate|memory|wal|off)
*/
- if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
+ case PragTyp_JOURNAL_MODE: {
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
int ii; /* Loop counter */
- /* Force the schema to be loaded on all databases. This causes all
- ** database files to be opened and the journal_modes set. This is
- ** necessary because subsequent processing must know if the databases
- ** are in WAL mode. */
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
-
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);
@@ -93994,7 +97315,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
- }else
+ break;
+ }
/*
** PRAGMA [database.]journal_size_limit
@@ -94002,16 +97324,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
**
** Get or set the size limit on rollback journal files.
*/
- if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
+ case PragTyp_JOURNAL_SIZE_LIMIT: {
Pager *pPager = sqlite3BtreePager(pDb->pBt);
i64 iLimit = -2;
if( zRight ){
- sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
+ sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8);
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
returnSingleInt(pParse, "journal_size_limit", iLimit);
- }else
+ break;
+ }
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
@@ -94023,57 +97346,47 @@ SQLITE_PRIVATE void sqlite3Pragma(
** The value is one of: 0 NONE 1 FULL 2 INCREMENTAL
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){
+ case PragTyp_AUTO_VACUUM: {
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
if( !zRight ){
- int auto_vacuum;
- if( ALWAYS(pBt) ){
- auto_vacuum = sqlite3BtreeGetAutoVacuum(pBt);
- }else{
- auto_vacuum = SQLITE_DEFAULT_AUTOVACUUM;
- }
- returnSingleInt(pParse, "auto_vacuum", auto_vacuum);
+ returnSingleInt(pParse, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
}else{
int eAuto = getAutoVacuum(zRight);
assert( eAuto>=0 && eAuto<=2 );
db->nextAutovac = (u8)eAuto;
- if( ALWAYS(eAuto>=0) ){
- /* Call SetAutoVacuum() to set initialize the internal auto and
- ** incr-vacuum flags. This is required in case this connection
- ** creates the database file. It is important that it is created
- ** as an auto-vacuum capable db.
+ /* Call SetAutoVacuum() to set initialize the internal auto and
+ ** incr-vacuum flags. This is required in case this connection
+ ** creates the database file. It is important that it is created
+ ** as an auto-vacuum capable db.
+ */
+ rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
+ if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
+ /* When setting the auto_vacuum mode to either "full" or
+ ** "incremental", write the value of meta[6] in the database
+ ** file. Before writing to meta[6], check that meta[3] indicates
+ ** that this really is an auto-vacuum capable database.
*/
- rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto);
- if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){
- /* When setting the auto_vacuum mode to either "full" or
- ** "incremental", write the value of meta[6] in the database
- ** file. Before writing to meta[6], check that meta[3] indicates
- ** that this really is an auto-vacuum capable database.
- */
- static const VdbeOpList setMeta6[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
- { OP_If, 1, 0, 0}, /* 2 */
- { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_Integer, 0, 1, 0}, /* 4 */
- { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
- };
- int iAddr;
- iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
- sqlite3VdbeChangeP1(v, iAddr, iDb);
- sqlite3VdbeChangeP1(v, iAddr+1, iDb);
- sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
- sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
- sqlite3VdbeChangeP1(v, iAddr+5, iDb);
- sqlite3VdbeUsesBtree(v, iDb);
- }
+ static const VdbeOpList setMeta6[] = {
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
+ { OP_If, 1, 0, 0}, /* 2 */
+ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
+ { OP_Integer, 0, 1, 0}, /* 4 */
+ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
+ };
+ int iAddr;
+ iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
+ sqlite3VdbeChangeP1(v, iAddr, iDb);
+ sqlite3VdbeChangeP1(v, iAddr+1, iDb);
+ sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
+ sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1);
+ sqlite3VdbeChangeP1(v, iAddr+5, iDb);
+ sqlite3VdbeUsesBtree(v, iDb);
}
}
- }else
+ break;
+ }
#endif
/*
@@ -94082,11 +97395,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Do N steps of incremental vacuuming on a database.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( sqlite3StrICmp(zLeft,"incremental_vacuum")==0 ){
+ case PragTyp_INCREMENTAL_VACUUM: {
int iLimit, addr;
- if( sqlite3ReadSchema(pParse) ){
- goto pragma_out;
- }
if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
iLimit = 0x7fffffff;
}
@@ -94097,7 +97407,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
sqlite3VdbeJumpHere(v, addr);
- }else
+ break;
+ }
#endif
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
@@ -94112,8 +97423,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** number of pages is adjusted so that the cache uses -N kibibytes
** of memory.
*/
- if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ case PragTyp_CACHE_SIZE: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size);
@@ -94122,7 +97432,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
- }else
+ break;
+ }
/*
** PRAGMA [database.]mmap_size(N)
@@ -94138,12 +97449,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
** as little or as much as it wants. Except, if N is set to 0 then the
** upper layers will never invoke the xFetch interfaces to the VFS.
*/
- if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){
+ case PragTyp_MMAP_SIZE: {
sqlite3_int64 sz;
+#if SQLITE_MAX_MMAP_SIZE>0
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( zRight ){
int ii;
- sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8);
+ sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8);
if( sz<0 ) sz = sqlite3GlobalConfig.szMmap;
if( pId2->n==0 ) db->szMmap = sz;
for(ii=db->nDb-1; ii>=0; ii--){
@@ -94153,13 +97465,19 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
sz = -1;
- if( sqlite3_file_control(db,zDb,SQLITE_FCNTL_MMAP_SIZE,&sz)==SQLITE_OK ){
-#if SQLITE_MAX_MMAP_SIZE==0
- sz = 0;
+ rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz);
+#else
+ sz = 0;
+ rc = SQLITE_OK;
#endif
+ if( rc==SQLITE_OK ){
returnSingleInt(pParse, "mmap_size", sz);
+ }else if( rc!=SQLITE_NOTFOUND ){
+ pParse->nErr++;
+ pParse->rc = rc;
}
- }else
+ break;
+ }
/*
** PRAGMA temp_store
@@ -94172,13 +97490,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Note that it is possible for the library compile-time options to
** override this setting
*/
- if( sqlite3StrICmp(zLeft, "temp_store")==0 ){
+ case PragTyp_TEMP_STORE: {
if( !zRight ){
returnSingleInt(pParse, "temp_store", db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
- }else
+ break;
+ }
/*
** PRAGMA temp_store_directory
@@ -94190,7 +97509,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** If temporary directory is changed, then invalidateTempStorage.
**
*/
- if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){
+ case PragTyp_TEMP_STORE_DIRECTORY: {
if( !zRight ){
if( sqlite3_temp_directory ){
sqlite3VdbeSetNumCols(v, 1);
@@ -94223,7 +97542,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
- }else
+ break;
+ }
#if SQLITE_OS_WIN
/*
@@ -94239,7 +97559,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** by this setting, regardless of its value.
**
*/
- if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
+ case PragTyp_DATA_STORE_DIRECTORY: {
if( !zRight ){
if( sqlite3_data_directory ){
sqlite3VdbeSetNumCols(v, 1);
@@ -94266,26 +97586,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
#endif /* SQLITE_OMIT_WSD */
}
- }else
+ break;
+ }
#endif
-#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
-# if defined(__APPLE__)
-# define SQLITE_ENABLE_LOCKING_STYLE 1
-# else
-# define SQLITE_ENABLE_LOCKING_STYLE 0
-# endif
-#endif
#if SQLITE_ENABLE_LOCKING_STYLE
/*
- ** PRAGMA [database.]lock_proxy_file
- ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
- **
- ** Return or set the value of the lock_proxy_file flag. Changing
- ** the value sets a specific file to be used for database access locks.
- **
- */
- if( sqlite3StrICmp(zLeft, "lock_proxy_file")==0 ){
+ ** PRAGMA [database.]lock_proxy_file
+ ** PRAGMA [database.]lock_proxy_file = ":auto:"|"lock_file_path"
+ **
+ ** Return or set the value of the lock_proxy_file flag. Changing
+ ** the value sets a specific file to be used for database access locks.
+ **
+ */
+ case PragTyp_LOCK_PROXY_FILE: {
if( !zRight ){
Pager *pPager = sqlite3BtreePager(pDb->pBt);
char *proxy_file_path = NULL;
@@ -94316,7 +97630,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
goto pragma_out;
}
}
- }else
+ break;
+ }
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
@@ -94328,8 +97643,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** default value will be restored the next time the database is
** opened.
*/
- if( sqlite3StrICmp(zLeft,"synchronous")==0 ){
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ case PragTyp_SYNCHRONOUS: {
if( !zRight ){
returnSingleInt(pParse, "synchronous", pDb->safety_level-1);
}else{
@@ -94338,16 +97652,42 @@ SQLITE_PRIVATE void sqlite3Pragma(
"Safety level may not be changed inside a transaction");
}else{
pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
+ setAllPagerFlags(db);
}
}
- }else
+ break;
+ }
#endif /* SQLITE_OMIT_PAGER_PRAGMAS */
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
- if( flagPragma(pParse, zLeft, zRight) ){
- /* The flagPragma() subroutine also generates any necessary code
- ** there is nothing more to do here */
- }else
+ case PragTyp_FLAG: {
+ if( zRight==0 ){
+ returnSingleInt(pParse, aPragmaNames[mid].zName,
+ (db->flags & aPragmaNames[mid].iArg)!=0 );
+ }else{
+ int mask = aPragmaNames[mid].iArg; /* Mask of bits to set or clear. */
+ if( db->autoCommit==0 ){
+ /* Foreign key support may not be enabled or disabled while not
+ ** in auto-commit mode. */
+ mask &= ~(SQLITE_ForeignKeys);
+ }
+
+ if( sqlite3GetBoolean(zRight, 0) ){
+ db->flags |= mask;
+ }else{
+ db->flags &= ~mask;
+ if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
+ }
+
+ /* Many of the flag-pragmas modify the code generated by the SQL
+ ** compiler (eg. count_changes). So add an opcode to expire all
+ ** compiled SQL statements after modifying a pragma value.
+ */
+ sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
+ setAllPagerFlags(db);
+ }
+ break;
+ }
#endif /* SQLITE_OMIT_FLAG_PRAGMAS */
#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
@@ -94363,16 +97703,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
** notnull: True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
*/
- if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){
+ case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
int i, k;
int nHidden = 0;
Column *pCol;
- Index *pPk;
- for(pPk=pTab->pIndex; pPk && pPk->autoIndex!=2; pPk=pPk->pNext){}
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
sqlite3VdbeSetNumCols(v, 6);
pParse->nMem = 6;
sqlite3CodeVerifySchema(pParse, iDb);
@@ -94409,12 +97747,42 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
}
}
- }else
+ }
+ break;
+
+ case PragTyp_STATS: {
+ Index *pIdx;
+ HashElem *i;
+ v = sqlite3GetVdbe(pParse);
+ sqlite3VdbeSetNumCols(v, 4);
+ pParse->nMem = 4;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "table", SQLITE_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "index", SQLITE_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "width", SQLITE_STATIC);
+ sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "height", SQLITE_STATIC);
+ for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, pTab->zName, 0);
+ sqlite3VdbeAddOp2(v, OP_Null, 0, 2);
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ (int)sqlite3LogEstToInt(pTab->szTabRow), 3);
+ sqlite3VdbeAddOp2(v, OP_Integer, (int)pTab->nRowEst, 4);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ (int)sqlite3LogEstToInt(pIdx->szIdxRow), 3);
+ sqlite3VdbeAddOp2(v, OP_Integer, (int)pIdx->aiRowEst[0], 4);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ }
+ }
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){
+ case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
int i;
@@ -94425,8 +97793,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
- for(i=0; i<pIdx->nColumn; i++){
- int cnum = pIdx->aiColumn[i];
+ for(i=0; i<pIdx->nKeyCol; i++){
+ i16 cnum = pIdx->aiColumn[i];
sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
assert( pTab->nCol>cnum );
@@ -94434,39 +97802,34 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){
+ case PragTyp_INDEX_LIST: if( zRight ){
Index *pIdx;
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
+ int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite3GetVdbe(pParse);
- pIdx = pTab->pIndex;
- if( pIdx ){
- int i = 0;
- sqlite3VdbeSetNumCols(v, 3);
- pParse->nMem = 3;
- sqlite3CodeVerifySchema(pParse, iDb);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
- sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
- while(pIdx){
- sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
- sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- ++i;
- pIdx = pIdx->pNext;
- }
+ sqlite3VdbeSetNumCols(v, 3);
+ pParse->nMem = 3;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
+ sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
+ sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
+ for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+ sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->onError!=OE_None, 3);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "database_list")==0 ){
+ case PragTyp_DATABASE_LIST: {
int i;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
@@ -94481,9 +97844,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3BtreeGetFilename(db->aDb[i].pBt), 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
- }else
+ }
+ break;
- if( sqlite3StrICmp(zLeft, "collation_list")==0 ){
+ case PragTyp_COLLATION_LIST: {
int i = 0;
HashElem *p;
sqlite3VdbeSetNumCols(v, 2);
@@ -94496,14 +97860,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pColl->zName, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
#ifndef SQLITE_OMIT_FOREIGN_KEY
- if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){
+ case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
FKey *pFK;
Table *pTab;
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
v = sqlite3GetVdbe(pParse);
@@ -94543,12 +97907,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
}
- }else
+ }
+ break;
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef SQLITE_OMIT_FOREIGN_KEY
#ifndef SQLITE_OMIT_TRIGGER
- if( sqlite3StrICmp(zLeft, "foreign_key_check")==0 ){
+ case PragTyp_FOREIGN_KEY_CHECK: {
FKey *pFK; /* A foreign key constraint */
Table *pTab; /* Child table contain "REFERENCES" keyword */
Table *pParent; /* Parent table that child points to */
@@ -94564,7 +97929,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
int addrOk; /* Jump here if the key is OK */
int *aiCols; /* child to parent column mapping */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
regResult = pParse->nMem+1;
pParse->nMem += 4;
regKey = ++pParse->nMem;
@@ -94592,8 +97956,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, regResult, 0, pTab->zName,
P4_TRANSIENT);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
- pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
- if( pParent==0 ) break;
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
+ if( pParent==0 ) continue;
pIdx = 0;
sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
@@ -94601,27 +97965,28 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pIdx==0 ){
sqlite3OpenTable(pParse, i, iDb, pParent, OP_OpenRead);
}else{
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iDb);
- sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
}
}else{
k = 0;
break;
}
}
+ assert( pParse->nErr>0 || pFK==0 );
if( pFK ) break;
if( pParse->nTab<i ) pParse->nTab = i;
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
- pParent = sqlite3LocateTable(pParse, 0, pFK->zTo, zDb);
- assert( pParent!=0 );
+ pParent = sqlite3FindTable(db, pFK->zTo, zDb);
pIdx = 0;
aiCols = 0;
- x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
- assert( x==0 );
+ if( pParent ){
+ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
+ assert( x==0 );
+ }
addrOk = sqlite3VdbeMakeLabel(v);
- if( pIdx==0 ){
+ if( pParent && pIdx==0 ){
int iKey = pFK->aCol[0].iFrom;
assert( iKey>=0 && iKey<pTab->nCol );
if( iKey!=pTab->iPKey ){
@@ -94639,13 +98004,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
}else{
for(j=0; j<pFK->nCol; j++){
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
- aiCols ? aiCols[j] : pFK->aCol[0].iFrom, regRow+j);
+ aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
- sqlite3VdbeChangeP4(v, -1,
- sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
- sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ if( pParent ){
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
+ sqlite3VdbeChangeP4(v, -1,
+ sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
+ sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ }
}
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
sqlite3VdbeAddOp4(v, OP_String8, 0, regResult+2, 0,
@@ -94658,12 +98025,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
sqlite3VdbeJumpHere(v, addrTop);
}
- }else
+ }
+ break;
#endif /* !defined(SQLITE_OMIT_TRIGGER) */
#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */
#ifndef NDEBUG
- if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){
+ case PragTyp_PARSER_TRACE: {
if( zRight ){
if( sqlite3GetBoolean(zRight, 0) ){
sqlite3ParserTrace(stderr, "parser: ");
@@ -94671,30 +98039,30 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3ParserTrace(0, 0);
}
}
- }else
+ }
+ break;
#endif
/* Reinstall the LIKE and GLOB functions. The variant of LIKE
** used will be case sensitive or not depending on the RHS.
*/
- if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){
+ case PragTyp_CASE_SENSITIVE_LIKE: {
if( zRight ){
sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0));
}
- }else
+ }
+ break;
#ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX
# define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100
#endif
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Pragma "quick_check" is an experimental reduced version of
+ /* Pragma "quick_check" is reduced version of
** integrity_check designed to detect most database corruption
** without most of the overhead of a full integrity-check.
*/
- if( sqlite3StrICmp(zLeft, "integrity_check")==0
- || sqlite3StrICmp(zLeft, "quick_check")==0
- ){
+ case PragTyp_INTEGRITY_CHECK: {
int i, j, addr, mxErr;
/* Code that appears at the end of the integrity check. If no error
@@ -94724,7 +98092,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( pId2->z==0 ) iDb = -1;
/* Initialize the VDBE program */
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pParse->nMem = 6;
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
@@ -94763,18 +98130,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx;
- sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
- cnt++;
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
+ VdbeComment((v, "%s", pTab->zName));
+ cnt++;
+ }
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
+ VdbeComment((v, "%s", pIdx->zName));
cnt++;
}
}
/* Make sure sufficient number of registers have been allocated */
- if( pParse->nMem < cnt+4 ){
- pParse->nMem = cnt+4;
- }
+ pParse->nMem = MAX( pParse->nMem, cnt+8 );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
@@ -94792,77 +98161,74 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
- Index *pIdx;
+ Index *pIdx, *pPk;
int loopTop;
+ int iDataCur, iIdxCur;
if( pTab->pIndex==0 ) continue;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
- sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */
- loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
- sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
+ sqlite3ExprCacheClear(pParse);
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead,
+ 1, 0, &iDataCur, &iIdxCur);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- int jmp2;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
+ }
+ pParse->nMem = MAX(pParse->nMem, 8+j);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0);
+ loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2, jmp3, jmp4;
int r1;
- static const VdbeOpList idxErr[] = {
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 3, 0}, /* 1 */
- { OP_Rowid, 1, 4, 0},
- { OP_String8, 0, 5, 0}, /* 3 */
- { OP_String8, 0, 6, 0}, /* 4 */
- { OP_Concat, 4, 3, 3},
- { OP_Concat, 5, 3, 3},
- { OP_Concat, 6, 3, 3},
- { OP_ResultRow, 3, 1, 0},
- { OP_IfPos, 1, 0, 0}, /* 9 */
- { OP_Halt, 0, 0, 0},
- };
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
- addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
- sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
- sqlite3VdbeJumpHere(v, addr+9);
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
+ pIdx->nColumn);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, " missing from index ",
+ P4_STATIC);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
+ jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
+ sqlite3VdbeAddOp0(v, OP_Halt);
+ sqlite3VdbeJumpHere(v, jmp4);
sqlite3VdbeJumpHere(v, jmp2);
+ sqlite3VdbeResolveLabel(v, jmp3);
}
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
- sqlite3VdbeJumpHere(v, loopTop);
+ sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
+ sqlite3VdbeJumpHere(v, loopTop-1);
+#ifndef SQLITE_OMIT_BTREECOUNT
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
+ "wrong # of entries in index ", P4_STATIC);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- static const VdbeOpList cntIdx[] = {
- { OP_Integer, 0, 3, 0},
- { OP_Rewind, 0, 0, 0}, /* 1 */
- { OP_AddImm, 3, 1, 0},
- { OP_Next, 0, 0, 0}, /* 3 */
- { OP_Eq, 2, 0, 3}, /* 4 */
- { OP_AddImm, 1, -1, 0},
- { OP_String8, 0, 2, 0}, /* 6 */
- { OP_String8, 0, 3, 0}, /* 7 */
- { OP_Concat, 3, 2, 2},
- { OP_ResultRow, 2, 1, 0},
- };
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
+ if( pPk==pIdx ) continue;
+ addr = sqlite3VdbeCurrentAddr(v);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
- addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
- sqlite3VdbeChangeP1(v, addr+1, j+2);
- sqlite3VdbeChangeP2(v, addr+1, addr+4);
- sqlite3VdbeChangeP1(v, addr+3, j+2);
- sqlite3VdbeChangeP2(v, addr+3, addr+2);
- sqlite3VdbeJumpHere(v, addr+4);
- sqlite3VdbeChangeP4(v, addr+6,
- "wrong # of entries in index ", P4_STATIC);
- sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
+#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
#ifndef SQLITE_OMIT_UTF16
@@ -94888,7 +98254,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** new database files created using this database handle. It is only
** useful if invoked immediately after the main database i
*/
- if( sqlite3StrICmp(zLeft, "encoding")==0 ){
+ case PragTyp_ENCODING: {
static const struct EncName {
char *zName;
u8 enc;
@@ -94935,7 +98301,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_UTF16 */
#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
@@ -94969,11 +98336,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** The user-version is not used internally by SQLite. It may be used by
** applications for any purpose.
*/
- if( sqlite3StrICmp(zLeft, "schema_version")==0
- || sqlite3StrICmp(zLeft, "user_version")==0
- || sqlite3StrICmp(zLeft, "freelist_count")==0
- || sqlite3StrICmp(zLeft, "application_id")==0
- ){
+ case PragTyp_HEADER_VALUE: {
int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
sqlite3VdbeUsesBtree(v, iDb);
switch( zLeft[0] ){
@@ -95017,7 +98380,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
@@ -95027,7 +98391,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Return the names of all compile-time options used in this build,
** one option per row.
*/
- if( sqlite3StrICmp(zLeft, "compile_options")==0 ){
+ case PragTyp_COMPILE_OPTIONS: {
int i = 0;
const char *zOpt;
sqlite3VdbeSetNumCols(v, 1);
@@ -95037,7 +98401,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, zOpt, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
- }else
+ }
+ break;
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
#ifndef SQLITE_OMIT_WAL
@@ -95046,7 +98411,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
**
** Checkpoint the database.
*/
- if( sqlite3StrICmp(zLeft, "wal_checkpoint")==0 ){
+ case PragTyp_WAL_CHECKPOINT: {
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
int eMode = SQLITE_CHECKPOINT_PASSIVE;
if( zRight ){
@@ -95056,7 +98421,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
eMode = SQLITE_CHECKPOINT_RESTART;
}
}
- if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 3);
pParse->nMem = 3;
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "busy", SQLITE_STATIC);
@@ -95065,7 +98429,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
- }else
+ }
+ break;
/*
** PRAGMA wal_autocheckpoint
@@ -95075,14 +98440,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
** after accumulating N frames in the log. Or query for the current value
** of N.
*/
- if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
+ case PragTyp_WAL_AUTOCHECKPOINT: {
if( zRight ){
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
}
returnSingleInt(pParse, "wal_autocheckpoint",
db->xWalCallback==sqlite3WalDefaultHook ?
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
- }else
+ }
+ break;
#endif
/*
@@ -95091,9 +98457,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
** This pragma attempts to free as much memory as possible from the
** current database connection.
*/
- if( sqlite3StrICmp(zLeft, "shrink_memory")==0 ){
+ case PragTyp_SHRINK_MEMORY: {
sqlite3_db_release_memory(db);
- }else
+ break;
+ }
/*
** PRAGMA busy_timeout
@@ -95104,18 +98471,36 @@ SQLITE_PRIVATE void sqlite3Pragma(
** then 0 is returned. Setting the busy_timeout to 0 or negative
** disables the timeout.
*/
- if( sqlite3StrICmp(zLeft, "busy_timeout")==0 ){
+ /*case PragTyp_BUSY_TIMEOUT*/ default: {
+ assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT );
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
returnSingleInt(pParse, "timeout", db->busyTimeout);
- }else
+ break;
+ }
+
+ /*
+ ** PRAGMA soft_heap_limit
+ ** PRAGMA soft_heap_limit = N
+ **
+ ** Call sqlite3_soft_heap_limit64(N). Return the result. If N is omitted,
+ ** use -1.
+ */
+ case PragTyp_SOFT_HEAP_LIMIT: {
+ sqlite3_int64 N;
+ if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){
+ sqlite3_soft_heap_limit64(N);
+ }
+ returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
+ break;
+ }
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/*
** Report the current state of file logs for all databases
*/
- if( sqlite3StrICmp(zLeft, "lock_status")==0 ){
+ case PragTyp_LOCK_STATUS: {
static const char *const azLockName[] = {
"unlocked", "shared", "reserved", "pending", "exclusive"
};
@@ -95140,35 +98525,39 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, zState, P4_STATIC);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
-
- }else
+ break;
+ }
#endif
#ifdef SQLITE_HAS_CODEC
- if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){
- sqlite3_key(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( sqlite3StrICmp(zLeft, "rekey")==0 && zRight ){
- sqlite3_rekey(db, zRight, sqlite3Strlen30(zRight));
- }else
- if( zRight && (sqlite3StrICmp(zLeft, "hexkey")==0 ||
- sqlite3StrICmp(zLeft, "hexrekey")==0) ){
- int i, h1, h2;
- char zKey[40];
- for(i=0; (h1 = zRight[i])!=0 && (h2 = zRight[i+1])!=0; i+=2){
- h1 += 9*(1&(h1>>6));
- h2 += 9*(1&(h2>>6));
- zKey[i/2] = (h2 & 0x0f) | ((h1 & 0xf)<<4);
- }
- if( (zLeft[3] & 0xf)==0xb ){
- sqlite3_key(db, zKey, i/2);
- }else{
- sqlite3_rekey(db, zKey, i/2);
+ case PragTyp_KEY: {
+ if( zRight ) sqlite3_key_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_REKEY: {
+ if( zRight ) sqlite3_rekey_v2(db, zDb, zRight, sqlite3Strlen30(zRight));
+ break;
+ }
+ case PragTyp_HEXKEY: {
+ if( zRight ){
+ u8 iByte;
+ int i;
+ char zKey[40];
+ for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zRight[i]); i++){
+ iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
+ if( (i&1)!=0 ) zKey[i/2] = iByte;
+ }
+ if( (zLeft[3] & 0xf)==0xb ){
+ sqlite3_key_v2(db, zDb, zKey, i/2);
+ }else{
+ sqlite3_rekey_v2(db, zDb, zKey, i/2);
+ }
}
- }else
+ break;
+ }
#endif
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
- if( sqlite3StrICmp(zLeft, "activate_extensions")==0 && zRight ){
+ case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
#ifdef SQLITE_HAS_CODEC
if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
sqlite3_activate_see(&zRight[4]);
@@ -95179,23 +98568,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3_activate_cerod(&zRight[6]);
}
#endif
- }else
+ }
+ break;
#endif
-
- {/* Empty ELSE clause */}
+ } /* End of the PRAGMA switch */
- /*
- ** Reset the safety level, in case the fullfsync flag or synchronous
- ** setting changed.
- */
-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
- if( db->autoCommit ){
- sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level,
- (db->flags&SQLITE_FullFSync)!=0,
- (db->flags&SQLITE_CkptFullFSync)!=0);
- }
-#endif
pragma_out:
sqlite3DbFree(db, zLeft);
sqlite3DbFree(db, zRight);
@@ -95731,6 +99109,13 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
}
/*
+** Free all memory allocations in the pParse object
+*/
+SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
+ if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr);
+}
+
+/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
static int sqlite3Prepare(
@@ -95798,7 +99183,7 @@ static int sqlite3Prepare(
sqlite3VtabUnlockList(db);
pParse->db = db;
- pParse->nQueryLoop = (double)1;
+ pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -95820,7 +99205,7 @@ static int sqlite3Prepare(
}else{
sqlite3RunParser(pParse, zSql, &zErrMsg);
}
- assert( 1==(int)pParse->nQueryLoop );
+ assert( 0==pParse->nQueryLoop );
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
@@ -95887,6 +99272,7 @@ static int sqlite3Prepare(
end_prepare:
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
@@ -96016,6 +99402,12 @@ static int sqlite3Prepare16(
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
+ if( nBytes>=0 ){
+ int sz;
+ const char *z = (const char*)zSql;
+ for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
+ nBytes = sz;
+ }
sqlite3_mutex_enter(db->mutex);
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
@@ -96184,7 +99576,7 @@ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
}
/*
-** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
+** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
** type of join. Return an integer constant that expresses that type
** in terms of the following bit values:
**
@@ -96339,8 +99731,8 @@ static void addWhereTerm(
pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
if( pEq && isOuterJoin ){
ExprSetProperty(pEq, EP_FromJoin);
- assert( !ExprHasAnyProperty(pEq, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(pEq);
+ assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = (i16)pE2->iTable;
}
*ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq);
@@ -96375,8 +99767,8 @@ static void addWhereTerm(
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
- assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
- ExprSetIrreducible(p);
+ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
@@ -96674,7 +100066,8 @@ static void selectInnerLoop(
** values returned by the SELECT are not required.
*/
sqlite3ExprCacheClear(pParse);
- sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output);
+ sqlite3ExprCodeExprList(pParse, pEList, regResult,
+ (eDest==SRT_Output)?SQLITE_ECEL_DUP:0);
}
nColumn = nResultCol;
@@ -96878,6 +100271,58 @@ static void selectInnerLoop(
}
/*
+** Allocate a KeyInfo object sufficient for an index of N key columns and
+** X extra columns.
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
+ KeyInfo *p = sqlite3DbMallocZero(0,
+ sizeof(KeyInfo) + (N+X)*(sizeof(CollSeq*)+1));
+ if( p ){
+ p->aSortOrder = (u8*)&p->aColl[N+X];
+ p->nField = (u16)N;
+ p->nXField = (u16)X;
+ p->enc = ENC(db);
+ p->db = db;
+ p->nRef = 1;
+ }else{
+ db->mallocFailed = 1;
+ }
+ return p;
+}
+
+/*
+** Deallocate a KeyInfo object
+*/
+SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef--;
+ if( p->nRef==0 ) sqlite3DbFree(0, p);
+ }
+}
+
+/*
+** Make a new pointer to a KeyInfo object
+*/
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){
+ if( p ){
+ assert( p->nRef>0 );
+ p->nRef++;
+ }
+ return p;
+}
+
+#ifdef SQLITE_DEBUG
+/*
+** Return TRUE if a KeyInfo object can be change. The KeyInfo object
+** can only be changed if this is just a single reference to the object.
+**
+** This routine is used only inside of assert() statements.
+*/
+SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
+#endif /* SQLITE_DEBUG */
+
+/*
** Given an expression list, generate a KeyInfo structure that records
** the collating sequence for each expression in that expression list.
**
@@ -96889,29 +100334,23 @@ static void selectInnerLoop(
**
** Space to hold the KeyInfo structure is obtain from malloc. The calling
** function is responsible for seeing that this structure is eventually
-** freed. Add the KeyInfo structure to the P4 field of an opcode using
-** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
+** freed.
*/
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
- sqlite3 *db = pParse->db;
int nExpr;
KeyInfo *pInfo;
struct ExprList_item *pItem;
+ sqlite3 *db = pParse->db;
int i;
nExpr = pList->nExpr;
- pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1);
if( pInfo ){
- pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
- pInfo->nField = (u16)nExpr;
- pInfo->enc = ENC(db);
- pInfo->db = db;
+ assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
CollSeq *pColl;
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- if( !pColl ){
- pColl = db->pDfltColl;
- }
+ if( !pColl ) pColl = db->pDfltColl;
pInfo->aColl[i] = pColl;
pInfo->aSortOrder[i] = pItem->sortOrder;
}
@@ -97123,6 +100562,9 @@ static void generateSortTail(
** Return a pointer to a string containing the 'declaration type' of the
** expression pExpr. The string may be treated as static by the caller.
**
+** Also try to estimate the size of the returned value and return that
+** result in *pEstWidth.
+**
** The declaration type is the exact datatype definition extracted from the
** original CREATE TABLE statement if the expression is a column. The
** declaration type for a ROWID field is INTEGER. Exactly when an expression
@@ -97136,21 +100578,36 @@ static void generateSortTail(
** SELECT abc FROM (SELECT col AS abc FROM tbl);
**
** The declaration type for any expression other than a column is NULL.
+**
+** This routine has either 3 or 6 parameters depending on whether or not
+** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
*/
-static const char *columnType(
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
+static const char *columnTypeImpl(
+ NameContext *pNC,
+ Expr *pExpr,
+ const char **pzOrigDb,
+ const char **pzOrigTab,
+ const char **pzOrigCol,
+ u8 *pEstWidth
+){
+ char const *zOrigDb = 0;
+ char const *zOrigTab = 0;
+ char const *zOrigCol = 0;
+#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
+# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
+static const char *columnTypeImpl(
NameContext *pNC,
Expr *pExpr,
- const char **pzOriginDb,
- const char **pzOriginTab,
- const char **pzOriginCol
+ u8 *pEstWidth
){
+#endif /* !defined(SQLITE_ENABLE_COLUMN_METADATA) */
char const *zType = 0;
- char const *zOriginDb = 0;
- char const *zOriginTab = 0;
- char const *zOriginCol = 0;
int j;
- if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
+ u8 estWidth = 1;
+ if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
switch( pExpr->op ){
case TK_AGG_COLUMN:
case TK_COLUMN: {
@@ -97211,25 +100668,35 @@ static const char *columnType(
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
+ zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth);
}
}else if( ALWAYS(pTab->pSchema) ){
/* A real table */
assert( !pS );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
if( iCol<0 ){
zType = "INTEGER";
- zOriginCol = "rowid";
+ zOrigCol = "rowid";
}else{
zType = pTab->aCol[iCol].zType;
- zOriginCol = pTab->aCol[iCol].zName;
+ zOrigCol = pTab->aCol[iCol].zName;
+ estWidth = pTab->aCol[iCol].szEst;
}
- zOriginTab = pTab->zName;
+ zOrigTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOriginDb = pNC->pParse->db->aDb[iDb].zName;
+ zOrigDb = pNC->pParse->db->aDb[iDb].zName;
+ }
+#else
+ if( iCol<0 ){
+ zType = "INTEGER";
+ }else{
+ zType = pTab->aCol[iCol].zType;
+ estWidth = pTab->aCol[iCol].szEst;
}
+#endif
}
break;
}
@@ -97246,18 +100713,21 @@ static const char *columnType(
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth);
break;
}
#endif
}
-
- if( pzOriginDb ){
- assert( pzOriginTab && pzOriginCol );
- *pzOriginDb = zOriginDb;
- *pzOriginTab = zOriginTab;
- *pzOriginCol = zOriginCol;
+
+#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ if( pzOrigDb ){
+ assert( pzOrigTab && pzOrigCol );
+ *pzOrigDb = zOrigDb;
+ *pzOrigTab = zOrigTab;
+ *pzOrigCol = zOrigCol;
}
+#endif
+ if( pEstWidth ) *pEstWidth = estWidth;
return zType;
}
@@ -97283,7 +100753,7 @@ static void generateColumnTypes(
const char *zOrigDb = 0;
const char *zOrigTab = 0;
const char *zOrigCol = 0;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0);
/* The vdbe must make its own copy of the column-type and other
** column specific strings, in case the schema is reset before this
@@ -97293,11 +100763,11 @@ static void generateColumnTypes(
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
- zType = columnType(&sNC, p, 0, 0, 0);
+ zType = columnType(&sNC, p, 0, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
-#endif /* SQLITE_OMIT_DECLTYPE */
+#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
/*
@@ -97486,8 +100956,7 @@ static int selectColumnsFromExprList(
*/
static void selectAddColumnTypeAndCollation(
Parse *pParse, /* Parsing contexts */
- int nCol, /* Number of columns */
- Column *aCol, /* List of columns */
+ Table *pTab, /* Add column type information to this table */
Select *pSelect /* SELECT used to determine types and collations */
){
sqlite3 *db = pParse->db;
@@ -97497,17 +100966,19 @@ static void selectAddColumnTypeAndCollation(
int i;
Expr *p;
struct ExprList_item *a;
+ u64 szAll = 0;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
if( db->mallocFailed ) return;
memset(&sNC, 0, sizeof(sNC));
sNC.pSrcList = pSelect->pSrc;
a = pSelect->pEList->a;
- for(i=0, pCol=aCol; i<nCol; i++, pCol++){
+ for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
p = a[i].pExpr;
- pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
+ pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
+ szAll += pCol->szEst;
pCol->affinity = sqlite3ExprAffinity(p);
if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
@@ -97515,6 +100986,7 @@ static void selectAddColumnTypeAndCollation(
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
+ pTab->szTabRow = sqlite3LogEst(szAll*4);
}
/*
@@ -97542,9 +101014,9 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
assert( db->lookaside.bEnabled==0 );
pTab->nRef = 1;
pTab->zName = 0;
- pTab->nRowEst = 1000000;
+ pTab->nRowEst = 1048576;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSelect);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSelect);
pTab->iPKey = -1;
if( db->mallocFailed ){
sqlite3DeleteTable(db, pTab);
@@ -97598,7 +101070,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
/*
** "LIMIT -1" always shows all rows. There is some
- ** contraversy about what the correct behavior should be.
+ ** controversy about what the correct behavior should be.
** The current implementation interprets "LIMIT 0" to mean
** no rows.
*/
@@ -97613,8 +101085,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
- }else{
- if( p->nSelectRow > (double)n ) p->nSelectRow = (double)n;
+ }else if( n>=0 && p->nSelectRow>(u64)n ){
+ p->nSelectRow = n;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -97808,9 +101280,9 @@ static int multiSelect(
p->nSelectRow += pPrior->nSelectRow;
if( pPrior->pLimit
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && p->nSelectRow > (double)nLimit
+ && nLimit>0 && p->nSelectRow > (u64)nLimit
){
- p->nSelectRow = (double)nLimit;
+ p->nSelectRow = nLimit;
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
@@ -98017,23 +101489,17 @@ static int multiSelect(
assert( p->pRightmost==p );
nCol = p->pEList->nExpr;
- pKeyInfo = sqlite3DbMallocZero(db,
- sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
+ pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
rc = SQLITE_NOMEM;
goto multi_select_end;
}
-
- pKeyInfo->enc = ENC(db);
- pKeyInfo->nField = (u16)nCol;
-
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
*apColl = multiSelectCollSeq(pParse, p, i);
if( 0==*apColl ){
*apColl = db->pDfltColl;
}
}
- pKeyInfo->aSortOrder = (u8*)apColl;
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
for(i=0; i<2; i++){
@@ -98045,11 +101511,12 @@ static int multiSelect(
break;
}
sqlite3VdbeChangeP2(v, addr, nCol);
- sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO);
+ sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo),
+ P4_KEYINFO);
pLoop->addrOpenEphm[i] = -1;
}
}
- sqlite3DbFree(db, pKeyInfo);
+ sqlite3KeyInfoUnref(pKeyInfo);
}
multi_select_end:
@@ -98088,7 +101555,6 @@ static int generateOutputSubroutine(
int regReturn, /* The return address register */
int regPrev, /* Previous result register. No uniqueness if 0 */
KeyInfo *pKeyInfo, /* For comparing with previous entry */
- int p4type, /* The p4 type for pKeyInfo */
int iBreak /* Jump here if we hit the LIMIT */
){
Vdbe *v = pParse->pVdbe;
@@ -98104,7 +101570,7 @@ static int generateOutputSubroutine(
int j1, j2;
j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
- (char*)pKeyInfo, p4type);
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
@@ -98374,8 +101840,8 @@ static int multiSelectOrderBy(
for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
struct ExprList_item *pItem;
for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
- assert( pItem->iOrderByCol>0 );
- if( pItem->iOrderByCol==i ) break;
+ assert( pItem->u.x.iOrderByCol>0 );
+ if( pItem->u.x.iOrderByCol==i ) break;
}
if( j==nOrderBy ){
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -98383,7 +101849,7 @@ static int multiSelectOrderBy(
pNew->flags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
- if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
+ if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i;
}
}
}
@@ -98399,15 +101865,12 @@ static int multiSelectOrderBy(
if( aPermute ){
struct ExprList_item *pItem;
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
- assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
- aPermute[i] = pItem->iOrderByCol - 1;
+ assert( pItem->u.x.iOrderByCol>0
+ && pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+ aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
- pKeyMerge =
- sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
+ pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
if( pKeyMerge ){
- pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
- pKeyMerge->nField = (u16)nOrderBy;
- pKeyMerge->enc = ENC(db);
for(i=0; i<nOrderBy; i++){
CollSeq *pColl;
Expr *pTerm = pOrderBy->a[i].pExpr;
@@ -98419,6 +101882,7 @@ static int multiSelectOrderBy(
pOrderBy->a[i].pExpr =
sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
}
+ assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
pKeyMerge->aColl[i] = pColl;
pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
}
@@ -98444,12 +101908,9 @@ static int multiSelectOrderBy(
regPrev = pParse->nMem+1;
pParse->nMem += nExpr+1;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
- pKeyDup = sqlite3DbMallocZero(db,
- sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
+ pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1);
if( pKeyDup ){
- pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
- pKeyDup->nField = (u16)nExpr;
- pKeyDup->enc = ENC(db);
+ assert( sqlite3KeyInfoIsWriteable(pKeyDup) );
for(i=0; i<nExpr; i++){
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
pKeyDup->aSortOrder[i] = 0;
@@ -98531,7 +101992,7 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "Output routine for A"));
addrOutA = generateOutputSubroutine(pParse,
p, &destA, pDest, regOutA,
- regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
+ regPrev, pKeyDup, labelEnd);
/* Generate a subroutine that outputs the current row of the B
** select as the next output row of the compound select.
@@ -98540,8 +102001,9 @@ static int multiSelectOrderBy(
VdbeNoopComment((v, "Output routine for B"));
addrOutB = generateOutputSubroutine(pParse,
p, &destB, pDest, regOutB,
- regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
+ regPrev, pKeyDup, labelEnd);
}
+ sqlite3KeyInfoUnref(pKeyDup);
/* Generate a subroutine to run when the results from select A
** are exhausted and only data in select B remains.
@@ -98620,7 +102082,7 @@ static int multiSelectOrderBy(
sqlite3VdbeResolveLabel(v, labelCmpr);
sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
- (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
+ (char*)pKeyMerge, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
@@ -98985,7 +102447,7 @@ static int flattenSubquery(
if( p->pOrderBy ){
int ii;
for(ii=0; ii<p->pOrderBy->nExpr; ii++){
- if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
+ if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0;
}
}
}
@@ -99304,7 +102766,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
if( IsVirtual(pTab) ) return 0;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
if( NEVER(pAggInfo->nFunc==0) ) return 0;
- if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
+ if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
if( pExpr->flags&EP_Distinct ) return 0;
return pTab;
@@ -99470,11 +102932,11 @@ static int selectExpander(Walker *pWalker, Select *p){
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nRef = 1;
- pTab->zName = sqlite3MPrintf(db, "sqlite_subquery_%p_", (void*)pTab);
+ pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
selectColumnsFromExprList(pParse, pSel->pEList, &pTab->nCol, &pTab->aCol);
pTab->iPKey = -1;
- pTab->nRowEst = 1000000;
+ pTab->nRowEst = 1048576;
pTab->tabFlags |= TF_Ephemeral;
#endif
}else{
@@ -99715,10 +103177,12 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
memset(&w, 0, sizeof(w));
- w.xSelectCallback = convertCompoundSelectToSubquery;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
- sqlite3WalkSelect(&w, pSelect);
+ if( pParse->hasCompound ){
+ w.xSelectCallback = convertCompoundSelectToSubquery;
+ sqlite3WalkSelect(&w, pSelect);
+ }
w.xSelectCallback = selectExpander;
sqlite3WalkSelect(&w, pSelect);
}
@@ -99756,7 +103220,7 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Select *pSel = pFrom->pSelect;
assert( pSel );
while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
+ selectAddColumnTypeAndCollation(pParse, pTab, pSel);
}
}
}
@@ -99844,7 +103308,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
}else{
KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ (char*)pKeyInfo, P4_KEYINFO);
}
}
}
@@ -99889,7 +103353,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
if( pList ){
nArg = pList->nExpr;
regAgg = sqlite3GetTempRange(pParse, nArg);
- sqlite3ExprCodeExprList(pParse, pList, regAgg, 1);
+ sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP);
}else{
nArg = 0;
regAgg = 0;
@@ -99899,7 +103363,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
assert( nArg==1 );
codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
}
- if( pF->pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
CollSeq *pColl = 0;
struct ExprList_item *pItem;
int j;
@@ -99959,11 +103423,10 @@ static void explainSimpleCount(
Index *pIdx /* Index used to optimize scan, or NULL */
){
if( pParse->explain==2 ){
- char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s %s%s(~%d rows)",
+ char *zEqp = sqlite3MPrintf(pParse->db, "SCAN TABLE %s%s%s",
pTab->zName,
- pIdx ? "USING COVERING INDEX " : "",
- pIdx ? pIdx->zName : "",
- pTab->nRowEst
+ pIdx ? " USING COVERING INDEX " : "",
+ pIdx ? pIdx->zName : ""
);
sqlite3VdbeAddOp4(
pParse->pVdbe, OP_Explain, pParse->iSelectId, 0, 0, zEqp, P4_DYNAMIC
@@ -100121,7 +103584,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* Increment Parse.nHeight by the height of the largest expression
- ** tree refered to by this, the parent select. The child select
+ ** tree referred to by this, the parent select. The child select
** may contain expression trees of at most
** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
** more conservative than necessary, but much easier than enforcing
@@ -100253,7 +103716,7 @@ SQLITE_PRIVATE int sqlite3Select(
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
** to disable this optimization for testing purposes.
*/
- if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
+ if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
@@ -100274,7 +103737,7 @@ SQLITE_PRIVATE int sqlite3Select(
** BY and DISTINCT, and an index or separate temp-table for the other.
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
- && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
+ && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
){
p->selFlags &= ~SF_Distinct;
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
@@ -100300,7 +103763,7 @@ SQLITE_PRIVATE int sqlite3Select(
p->addrOpenEphm[2] = addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
pOrderBy->iECursor, pOrderBy->nExpr+2, 0,
- (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ (char*)pKeyInfo, P4_KEYINFO);
}else{
addrSortIndex = -1;
}
@@ -100314,7 +103777,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = (double)LARGEST_INT64;
+ p->nSelectRow = LARGEST_INT64;
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && addrSortIndex>=0 ){
sqlite3VdbeGetOp(v, addrSortIndex)->opcode = OP_SorterOpen;
@@ -100328,7 +103791,7 @@ SQLITE_PRIVATE int sqlite3Select(
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sDistinct.tabTnct, 0, 0,
(char*)keyInfoFromExprList(pParse, p->pEList),
- P4_KEYINFO_HANDOFF);
+ P4_KEYINFO);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
}else{
@@ -100337,14 +103800,19 @@ SQLITE_PRIVATE int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
- ExprList *pDist = (sDistinct.isTnct ? p->pEList : 0);
+ u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
/* Begin the database scan. */
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, pDist, 0,0);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pOrderBy, p->pEList,
+ wctrlFlags, 0);
if( pWInfo==0 ) goto select_end;
- if( pWInfo->nRowOut < p->nSelectRow ) p->nSelectRow = pWInfo->nRowOut;
- if( pWInfo->eDistinct ) sDistinct.eTnctType = pWInfo->eDistinct;
- if( pOrderBy && pWInfo->nOBSat==pOrderBy->nExpr ) pOrderBy = 0;
+ if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
+ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
+ }
+ if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){
+ sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo);
+ }
+ if( pOrderBy && sqlite3WhereIsOrdered(pWInfo) ) pOrderBy = 0;
/* If sorting index that was created by a prior OP_OpenEphemeral
** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -100357,7 +103825,8 @@ SQLITE_PRIVATE int sqlite3Select(
/* Use the standard inner loop. */
selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
- pWInfo->iContinue, pWInfo->iBreak);
+ sqlite3WhereContinueLabel(pWInfo),
+ sqlite3WhereBreakLabel(pWInfo));
/* End the database scan loop.
*/
@@ -100385,14 +103854,14 @@ SQLITE_PRIVATE int sqlite3Select(
struct ExprList_item *pItem; /* For looping over expression in a list */
for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
+ pItem->u.x.iAlias = 0;
}
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
- pItem->iAlias = 0;
+ pItem->u.x.iAlias = 0;
}
- if( p->nSelectRow>(double)100 ) p->nSelectRow = (double)100;
+ if( p->nSelectRow>100 ) p->nSelectRow = 100;
}else{
- p->nSelectRow = (double)1;
+ p->nSelectRow = 1;
}
@@ -100446,7 +103915,7 @@ SQLITE_PRIVATE int sqlite3Select(
pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
- 0, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
+ 0, (char*)pKeyInfo, P4_KEYINFO);
/* Initialize memory locations used by GROUP BY aggregate processing
*/
@@ -100472,9 +103941,10 @@ SQLITE_PRIVATE int sqlite3Select(
** in the right order to begin with.
*/
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 0, 0);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
+ WHERE_GROUPBY, 0);
if( pWInfo==0 ) goto select_end;
- if( pWInfo->nOBSat==pGroupBy->nExpr ){
+ if( sqlite3WhereIsOrdered(pWInfo) ){
/* The optimizer is able to deliver rows in group by order so
** we do not have to sort. The OP_OpenEphemeral table will be
** cancelled later because we still need to use the pKeyInfo
@@ -100559,7 +104029,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
}
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
- (char*)pKeyInfo, P4_KEYINFO);
+ (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
j1 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
@@ -100665,33 +104135,34 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- /* Search for the index that has the least amount of columns. If
- ** there is such an index, and it has less columns than the table
- ** does, then we can assume that it consumes less space on disk and
- ** will therefore be cheaper to scan to determine the query result.
- ** In this case set iRoot to the root page number of the index b-tree
- ** and pKeyInfo to the KeyInfo structure required to navigate the
- ** index.
+ /* Search for the index that has the lowest scan cost.
**
** (2011-04-15) Do not do a full scan of an unordered index.
**
+ ** (2013-10-03) Do not count the entries in a partial index.
+ **
** In practice the KeyInfo structure will not be used. It is only
** passed to keep OP_OpenRead happy.
*/
+ if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->bUnordered==0 && (!pBest || pIdx->nColumn<pBest->nColumn) ){
+ if( pIdx->bUnordered==0
+ && pIdx->szIdxRow<pTab->szTabRow
+ && pIdx->pPartIdxWhere==0
+ && (!pBest || pIdx->szIdxRow<pBest->szIdxRow)
+ ){
pBest = pIdx;
}
}
- if( pBest && pBest->nColumn<pTab->nCol ){
+ if( pBest ){
iRoot = pBest->tnum;
- pKeyInfo = sqlite3IndexKeyinfo(pParse, pBest);
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest);
}
/* Open a read-only cursor, execute the OP_Count, close the cursor. */
- sqlite3VdbeAddOp3(v, OP_OpenRead, iCsr, iRoot, iDb);
+ sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1);
if( pKeyInfo ){
- sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
@@ -100755,8 +104226,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
updateAccumulator(pParse, &sAggInfo);
assert( pMinMax==0 || pMinMax->nExpr==1 );
- if( pWInfo->nOBSat>0 ){
- sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
+ if( sqlite3WhereIsOrdered(pWInfo) ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index",
(flag==WHERE_ORDERBY_MIN?"min":"max")));
}
@@ -101261,8 +104732,8 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
/* Ensure the table name matches database name and that the table exists */
if( db->mallocFailed ) goto trigger_cleanup;
assert( pTableName->nSrc==1 );
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
- sqlite3FixSrcList(&sFix, pTableName) ){
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName);
+ if( sqlite3FixSrcList(&sFix, pTableName) ){
goto trigger_cleanup;
}
pTab = sqlite3SrcListLookup(pParse, pTableName);
@@ -101404,8 +104875,10 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
}
nameToken.z = pTrig->zName;
nameToken.n = sqlite3Strlen30(nameToken.z);
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
- && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
+ sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
+ if( sqlite3FixTriggerStep(&sFix, pTrig->step_list)
+ || sqlite3FixExpr(&sFix, pTrig->pWhen)
+ ){
goto triggerfinish_cleanup;
}
@@ -101895,7 +105368,7 @@ static int codeTriggerProgram(
return 0;
}
-#ifdef SQLITE_DEBUG
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
/*
** This function is used to add VdbeComment() annotations to a VDBE
** program. It is not used in production code, only for debugging.
@@ -102035,6 +105508,7 @@ static TriggerPrg *codeRowTrigger(
assert( !pSubParse->pAinc && !pSubParse->pZombieTab );
assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg );
+ sqlite3ParserReset(pSubParse);
sqlite3StackFree(db, pSubParse);
return pPrg;
@@ -102115,7 +105589,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(
/*
** This is called to code the required FOR EACH ROW triggers for an operation
** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
-** is given by the op paramater. The tr_tm parameter determines whether the
+** is given by the op parameter. The tr_tm parameter determines whether the
** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then
** parameter pChanges is passed the list of columns being modified.
**
@@ -102309,7 +105783,7 @@ static void updateVirtualTable(
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
assert( pTab!=0 );
if( !pTab->pSelect ){
- sqlite3_value *pValue;
+ sqlite3_value *pValue = 0;
u8 enc = ENC(sqlite3VdbeDb(v));
Column *pCol = &pTab->aCol[i];
VdbeComment((v, "%s.%s", pTab->zName, pCol->zName));
@@ -102343,25 +105817,32 @@ SQLITE_PRIVATE void sqlite3Update(
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
- int addr = 0; /* VDBE instruction address of the start of the loop */
+ int addrTop = 0; /* VDBE instruction address of the start of the loop */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Vdbe *v; /* The virtual database engine */
Index *pIdx; /* For looping over indices */
+ Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */
int nIdx; /* Number of indices that need updating */
- int iCur; /* VDBE Cursor number of pTab */
+ int iBaseCur; /* Base cursor number */
+ int iDataCur; /* Cursor for the canonical data btree */
+ int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
int *aRegIdx = 0; /* One register assigned to each index to be updated */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
- int chngRowid; /* True if the record number is being changed */
+ u8 *aToOpen; /* 1 for tables and indices to be opened */
+ u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */
+ u8 chngRowid; /* Rowid changed in a normal table */
+ u8 chngKey; /* Either chngPk or chngRowid */
Expr *pRowidExpr = 0; /* Expression defining the new record number */
- int openAll = 0; /* True if all indices need to be opened */
AuthContext sContext; /* The authorization context */
NameContext sNC; /* The name-context to resolve expressions in */
int iDb; /* Database containing the table being updated */
int okOnePass; /* True for one-pass algorithm without the FIFO */
int hasFK; /* True if foreign key processing is required */
+ int labelBreak; /* Jump here to break out of UPDATE loop */
+ int labelContinue; /* Jump here to continue next step of UPDATE loop */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
@@ -102369,6 +105850,9 @@ SQLITE_PRIVATE void sqlite3Update(
int tmask; /* Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
#endif
int newmask; /* Mask of NEW.* columns accessed by BEFORE triggers */
+ int iEph = 0; /* Ephemeral table holding all primary key values */
+ int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
+ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
/* Register Allocations */
int regRowCount = 0; /* A count of rows changed */
@@ -102377,6 +105861,7 @@ SQLITE_PRIVATE void sqlite3Update(
int regNew; /* Content of the NEW.* table in triggers */
int regOld = 0; /* Content of OLD.* table in triggers */
int regRowSet = 0; /* Rowset of rows to be updated */
+ int regKey = 0; /* composite PRIMARY KEY value */
memset(&sContext, 0, sizeof(sContext));
db = pParse->db;
@@ -102414,20 +105899,34 @@ SQLITE_PRIVATE void sqlite3Update(
if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
goto update_cleanup;
}
- aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol );
- if( aXRef==0 ) goto update_cleanup;
- for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
/* Allocate a cursors for the main database table and for all indices.
** The index cursors might not be used, but if they are used they
** need to occur right after the database cursor. So go ahead and
** allocate enough space, just in case.
*/
- pTabList->a[0].iCursor = iCur = pParse->nTab++;
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++;
+ iIdxCur = iDataCur+1;
+ pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){
+ if( pIdx->autoIndex==2 && pPk!=0 ){
+ iDataCur = pParse->nTab;
+ pTabList->a[0].iCursor = iDataCur;
+ }
pParse->nTab++;
}
+ /* Allocate space for aXRef[], aRegIdx[], and aToOpen[].
+ ** Initialize aXRef[] and aToOpen[] to their default values.
+ */
+ aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 );
+ if( aXRef==0 ) goto update_cleanup;
+ aRegIdx = aXRef+pTab->nCol;
+ aToOpen = (u8*)(aRegIdx+nIdx);
+ memset(aToOpen, 1, nIdx+1);
+ aToOpen[nIdx+1] = 0;
+ for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
+
/* Initialize the name-context */
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
@@ -102439,7 +105938,7 @@ SQLITE_PRIVATE void sqlite3Update(
** column to be updated, make sure we have authorization to change
** that column.
*/
- chngRowid = 0;
+ chngRowid = chngPk = 0;
for(i=0; i<pChanges->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
goto update_cleanup;
@@ -102449,13 +105948,15 @@ SQLITE_PRIVATE void sqlite3Update(
if( j==pTab->iPKey ){
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
+ }else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
+ chngPk = 1;
}
aXRef[j] = i;
break;
}
}
if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pChanges->a[i].zName) ){
+ if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zName) ){
j = -1;
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
@@ -102479,32 +105980,36 @@ SQLITE_PRIVATE void sqlite3Update(
}
#endif
}
+ assert( (chngRowid & chngPk)==0 );
+ assert( chngRowid==0 || chngRowid==1 );
+ assert( chngPk==0 || chngPk==1 );
+ chngKey = chngRowid + chngPk;
- hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid);
+ /* The SET expressions are not actually used inside the WHERE loop.
+ ** So reset the colUsed mask
+ */
+ pTabList->a[0].colUsed = 0;
+
+ hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey);
- /* Allocate memory for the array aRegIdx[]. There is one entry in the
- ** array for each index associated with table being updated. Fill in
- ** the value with a register number for indices that are to be used
- ** and with zero for unused indices.
+ /* There is one entry in the aRegIdx[] array for each index on the table
+ ** being updated. Fill in aRegIdx[] with a register number that will hold
+ ** the key for accessing each index.
*/
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- if( nIdx>0 ){
- aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
- if( aRegIdx==0 ) goto update_cleanup;
- }
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
- if( hasFK || chngRowid ){
+ if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
}else{
reg = 0;
- for(i=0; i<pIdx->nColumn; i++){
+ for(i=0; i<pIdx->nKeyCol; i++){
if( aXRef[pIdx->aiColumn[i]]>=0 ){
reg = ++pParse->nMem;
break;
}
}
}
+ if( reg==0 ) aToOpen[j+1] = 0;
aRegIdx[j] = reg;
}
@@ -102528,11 +106033,11 @@ SQLITE_PRIVATE void sqlite3Update(
/* Allocate required registers. */
regRowSet = ++pParse->nMem;
regOldRowid = regNewRowid = ++pParse->nMem;
- if( pTrigger || hasFK ){
+ if( chngPk || pTrigger || hasFK ){
regOld = pParse->nMem + 1;
pParse->nMem += pTab->nCol;
}
- if( chngRowid || pTrigger || hasFK ){
+ if( chngKey || pTrigger || hasFK ){
regNewRowid = ++pParse->nMem;
}
regNew = pParse->nMem + 1;
@@ -102548,7 +106053,7 @@ SQLITE_PRIVATE void sqlite3Update(
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iCur);
+ sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
}
#endif
@@ -102561,24 +106066,58 @@ SQLITE_PRIVATE void sqlite3Update(
/* Begin the database scan
*/
- sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, 0
- );
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = pWInfo->okOnePass;
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
+ pWInfo = sqlite3WhereBegin(
+ pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
+ );
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+
+ /* Remember the rowid of every item to be updated.
+ */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+ if( !okOnePass ){
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ }
+
+ /* End the database scan loop.
+ */
+ sqlite3WhereEnd(pWInfo);
+ }else{
+ int iPk; /* First of nPk memory cells holding PRIMARY KEY value */
+ i16 nPk; /* Number of components of the PRIMARY KEY */
+ int addrOpen; /* Address of the OpenEphemeral instruction */
- /* Remember the rowid of every item to be updated.
- */
- sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regOldRowid);
- if( !okOnePass ){
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ assert( pPk!=0 );
+ nPk = pPk->nKeyCol;
+ iPk = pParse->nMem+1;
+ pParse->nMem += nPk;
+ regKey = ++pParse->nMem;
+ iEph = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
+ addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
+ sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
+ WHERE_ONEPASS_DESIRED, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+ okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ for(i=0; i<nPk; i++){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
+ iPk+i);
+ }
+ if( okOnePass ){
+ sqlite3VdbeChangeToNoop(v, addrOpen);
+ nKey = nPk;
+ regKey = iPk;
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
+ sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+ }
+ sqlite3WhereEnd(pWInfo);
}
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
-
/* Initialize the count of updated rows
*/
if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
@@ -102586,6 +106125,7 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
}
+ labelBreak = sqlite3VdbeMakeLabel(v);
if( !isView ){
/*
** Open every index that needs updating. Note that if any
@@ -102593,68 +106133,71 @@ SQLITE_PRIVATE void sqlite3Update(
** action, then we need to open all indices because we might need
** to be deleting some records.
*/
- if( !okOnePass ) sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite);
if( onError==OE_Replace ){
- openAll = 1;
+ memset(aToOpen, 1, nIdx+1);
}else{
- openAll = 0;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_Replace ){
- openAll = 1;
+ memset(aToOpen, 1, nIdx+1);
break;
}
}
}
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- assert( aRegIdx );
- if( openAll || aRegIdx[i]>0 ){
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
- sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
- assert( pParse->nTab>iCur+i+1 );
- }
+ if( okOnePass ){
+ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
+ if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
}
+ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen,
+ 0, 0);
}
/* Top of the update loop */
if( okOnePass ){
- int a1 = sqlite3VdbeAddOp1(v, OP_NotNull, regOldRowid);
- addr = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, a1);
+ if( aToOpen[iDataCur-iBaseCur] ){
+ assert( pPk!=0 );
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+ }
+ labelContinue = labelBreak;
+ sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ }else if( pPk ){
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
}else{
- addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid);
+ labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
+ regOldRowid);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
}
- /* Make cursor iCur point to the record that is being updated. If
- ** this record does not exist for some reason (deleted by a trigger,
- ** for example, then jump to the next iteration of the RowSet loop. */
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
-
/* If the record number will change, set register regNewRowid to
** contain the new value. If the record number is not being modified,
** then regNewRowid is the same register as regOldRowid, which is
** already populated. */
- assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid );
+ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
if( chngRowid ){
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
}
- /* If there are triggers on this table, populate an array of registers
- ** with the required old.* column data. */
- if( hasFK || pTrigger ){
+ /* Compute the old pre-UPDATE content of the row being changed, if that
+ ** information is needed */
+ if( chngPk || hasFK || pTrigger ){
u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0);
oldmask |= sqlite3TriggerColmask(pParse,
pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError
);
for(i=0; i<pTab->nCol; i++){
- if( aXRef[i]<0 || oldmask==0xffffffff || (i<32 && (oldmask & (1<<i))) ){
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOld+i);
+ if( oldmask==0xffffffff
+ || (i<32 && (oldmask & (1<<i)))
+ || (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
+ ){
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
}
}
- if( chngRowid==0 ){
+ if( chngRowid==0 && pPk==0 ){
sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid);
}
}
@@ -102691,8 +106234,7 @@ SQLITE_PRIVATE void sqlite3Update(
*/
testcase( i==31 );
testcase( i==32 );
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}
}
}
@@ -102704,7 +106246,7 @@ SQLITE_PRIVATE void sqlite3Update(
sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
sqlite3TableAffinityStr(v, pTab);
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_BEFORE, pTab, regOldRowid, onError, addr);
+ TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
/* The row-trigger may have deleted the row being updated. In this
** case, jump to the next row. No updates or AFTER triggers are
@@ -102712,7 +106254,11 @@ SQLITE_PRIVATE void sqlite3Update(
** is deleted or renamed by a BEFORE trigger - is left undefined in the
** documentation.
*/
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid);
+ if( pPk ){
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
+ }else{
+ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ }
/* If it did not delete it, the row-trigger may still have modified
** some of the columns of the row being updated. Load the values for
@@ -102721,46 +106267,56 @@ SQLITE_PRIVATE void sqlite3Update(
*/
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]<0 && i!=pTab->iPKey ){
- sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i);
- sqlite3ColumnDefault(v, pTab, i, regNew+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}
}
}
if( !isView ){
- int j1; /* Address of jump instruction */
+ int j1 = 0; /* Address of jump instruction */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
/* Do constraint checks. */
- sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid,
- aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0);
+ assert( regOldRowid>0 );
+ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
+ regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
/* Do FK constraint checks. */
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, regOldRowid, 0);
+ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
}
/* Delete the index entries associated with the current record. */
- j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid);
- sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx);
+ if( bReplace || chngKey ){
+ if( pPk ){
+ j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
+ }else{
+ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
+ }
+ }
+ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
/* If changing the record number, delete the old record. */
- if( hasFK || chngRowid ){
- sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0);
+ if( hasFK || chngKey || pPk!=0 ){
+ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
+ }
+ if( bReplace || chngKey ){
+ sqlite3VdbeJumpHere(v, j1);
}
- sqlite3VdbeJumpHere(v, j1);
if( hasFK ){
- sqlite3FkCheck(pParse, pTab, 0, regNewRowid);
+ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
}
/* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0);
+ sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
+ regNewRowid, aRegIdx, 1, 0, 0);
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
** handle rows (possibly in other tables) that refer via a foreign key
** to the row just updated. */
if( hasFK ){
- sqlite3FkActions(pParse, pTab, pChanges, regOldRowid);
+ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey);
}
}
@@ -102771,22 +106327,29 @@ SQLITE_PRIVATE void sqlite3Update(
}
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
- TRIGGER_AFTER, pTab, regOldRowid, onError, addr);
+ TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue);
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
- sqlite3VdbeJumpHere(v, addr);
+ if( okOnePass ){
+ /* Nothing to do at end-of-loop for a single-pass */
+ }else if( pPk ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
+ }
+ sqlite3VdbeResolveLabel(v, labelBreak);
/* Close all tables */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
assert( aRegIdx );
- if( openAll || aRegIdx[i]>0 ){
- sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
+ if( aToOpen[i+1] ){
+ sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0);
}
}
- sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
+ if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0);
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -102809,8 +106372,7 @@ SQLITE_PRIVATE void sqlite3Update(
update_cleanup:
sqlite3AuthContextPop(&sContext);
- sqlite3DbFree(db, aRegIdx);
- sqlite3DbFree(db, aXRef);
+ sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pChanges);
sqlite3ExprDelete(db, pWhere);
@@ -102996,14 +106558,34 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
}
/*
-** The non-standard VACUUM command is used to clean up the database,
+** The VACUUM command is used to clean up the database,
** collapse free space, etc. It is modelled after the VACUUM command
-** in PostgreSQL.
-**
-** In version 1.0.x of SQLite, the VACUUM command would call
-** gdbm_reorganize() on all the database tables. But beginning
-** with 2.0.0, SQLite no longer uses GDBM so this command has
-** become a no-op.
+** in PostgreSQL. The VACUUM command works as follows:
+**
+** (1) Create a new transient database file
+** (2) Copy all content from the database being vacuumed into
+** the new transient database file
+** (3) Copy content from the transient database back into the
+** original database.
+**
+** The transient database requires temporary disk space approximately
+** equal to the size of the original database. The copy operation of
+** step (3) requires additional temporary disk space approximately equal
+** to the size of the original database for the rollback journal.
+** Hence, temporary disk space that is approximately 2x the size of the
+** orginal database is required. Every page of the database is written
+** approximately 3 times: Once for step (2) and twice for step (3).
+** Two writes per page are required in step (3) because the original
+** database content must be written into the rollback journal prior to
+** overwriting the database with the vacuumed content.
+**
+** Only 1x temporary space and only 1x writes would be required if
+** the copy of step (3) were replace by deleting the original database
+** and renaming the transient database as the original. But that will
+** not work if other processes are attached to the original database.
+** And a power loss in between deleting the original and renaming the
+** transient would cause the database file to appear to be deleted
+** following reboot.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
Vdbe *v = sqlite3GetVdbe(pParse);
@@ -103035,7 +106617,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
return SQLITE_ERROR;
}
- if( db->activeVdbeCnt>1 ){
+ if( db->nVdbeActive>1 ){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
return SQLITE_ERROR;
}
@@ -103138,7 +106720,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
rc = execExecSql(db, pzErrMsg,
"SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
" FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
- " AND rootpage>0"
+ " AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execExecSql(db, pzErrMsg,
@@ -103159,7 +106741,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
"|| ' SELECT * FROM main.' || quote(name) || ';'"
"FROM main.sqlite_master "
"WHERE type = 'table' AND name!='sqlite_sequence' "
- " AND rootpage>0"
+ " AND coalesce(rootpage,1)>0"
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -104013,6 +107595,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
sqlite3VdbeFinalize(pParse->pVdbe);
}
sqlite3DeleteTable(db, pParse->pNewTable);
+ sqlite3ParserReset(pParse);
sqlite3StackFree(db, pParse);
}
@@ -104085,10 +107668,9 @@ static void callFinaliser(sqlite3 *db, int offset){
** array. Return the error code for the first error that occurs, or
** SQLITE_OK if all xSync operations are successful.
**
-** Set *pzErrmsg to point to a buffer that should be released using
-** sqlite3DbFree() containing an error message, if one is available.
+** If an error message is available, leave it in p->zErrMsg.
*/
-SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
+SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){
int i;
int rc = SQLITE_OK;
VTable **aVTrans = db->aVTrans;
@@ -104099,9 +107681,7 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
rc = x(pVtab);
- sqlite3DbFree(db, *pzErrmsg);
- *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
- sqlite3_free(pVtab->zErrMsg);
+ sqlite3VtabImportErrmsg(p, pVtab);
}
}
db->aVTrans = aVTrans;
@@ -104291,7 +107871,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
pNew->xFunc = xFunc;
pNew->pUserData = pArg;
- pNew->flags |= SQLITE_FUNC_EPHEM;
+ pNew->funcFlags |= SQLITE_FUNC_EPHEM;
return pNew;
}
@@ -104393,7 +107973,24 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
*/
-
+/************** Include whereInt.h in the middle of where.c ******************/
+/************** Begin file whereInt.h ****************************************/
+/*
+** 2013-11-12
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains structure and macro definitions for the query
+** planner logic in "where.c". These definitions are broken out into
+** a separate source file for easier editing.
+*/
/*
** Trace output macros
@@ -104403,18 +108000,170 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
#endif
#if defined(SQLITE_DEBUG) \
&& (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE))
-# define WHERETRACE(X) if(sqlite3WhereTrace) sqlite3DebugPrintf X
+# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X
+# define WHERETRACE_ENABLED 1
#else
-# define WHERETRACE(X)
+# define WHERETRACE(K,X)
#endif
-/* Forward reference
+/* Forward references
*/
typedef struct WhereClause WhereClause;
typedef struct WhereMaskSet WhereMaskSet;
typedef struct WhereOrInfo WhereOrInfo;
typedef struct WhereAndInfo WhereAndInfo;
-typedef struct WhereCost WhereCost;
+typedef struct WhereLevel WhereLevel;
+typedef struct WhereLoop WhereLoop;
+typedef struct WherePath WherePath;
+typedef struct WhereTerm WhereTerm;
+typedef struct WhereLoopBuilder WhereLoopBuilder;
+typedef struct WhereScan WhereScan;
+typedef struct WhereOrCost WhereOrCost;
+typedef struct WhereOrSet WhereOrSet;
+
+/*
+** This object contains information needed to implement a single nested
+** loop in WHERE clause.
+**
+** Contrast this object with WhereLoop. This object describes the
+** implementation of the loop. WhereLoop describes the algorithm.
+** This object contains a pointer to the WhereLoop algorithm as one of
+** its elements.
+**
+** The WhereInfo object contains a single instance of this object for
+** each term in the FROM clause (which is to say, for each of the
+** nested loops as implemented). The order of WhereLevel objects determines
+** the loop nested order, with WhereInfo.a[0] being the outer loop and
+** WhereInfo.a[WhereInfo.nLevel-1] being the inner loop.
+*/
+struct WhereLevel {
+ int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
+ int iTabCur; /* The VDBE cursor used to access the table */
+ int iIdxCur; /* The VDBE cursor used to access pIdx */
+ int addrBrk; /* Jump here to break out of the loop */
+ int addrNxt; /* Jump here to start the next IN combination */
+ int addrSkip; /* Jump here for next iteration of skip-scan */
+ int addrCont; /* Jump here to continue with the next loop cycle */
+ int addrFirst; /* First instruction of interior of the loop */
+ int addrBody; /* Beginning of the body of this loop */
+ u8 iFrom; /* Which entry in the FROM clause */
+ u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
+ int p1, p2; /* Operands of the opcode used to ends the loop */
+ union { /* Information that depends on pWLoop->wsFlags */
+ struct {
+ int nIn; /* Number of entries in aInLoop[] */
+ struct InLoop {
+ int iCur; /* The VDBE cursor used by this IN operator */
+ int addrInTop; /* Top of the IN loop */
+ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
+ } *aInLoop; /* Information about each nested IN operator */
+ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
+ Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
+ } u;
+ struct WhereLoop *pWLoop; /* The selected WhereLoop object */
+ Bitmask notReady; /* FROM entries not usable at this level */
+};
+
+/*
+** Each instance of this object represents an algorithm for evaluating one
+** term of a join. Every term of the FROM clause will have at least
+** one corresponding WhereLoop object (unless INDEXED BY constraints
+** prevent a query solution - which is an error) and many terms of the
+** FROM clause will have multiple WhereLoop objects, each describing a
+** potential way of implementing that FROM-clause term, together with
+** dependencies and cost estimates for using the chosen algorithm.
+**
+** Query planning consists of building up a collection of these WhereLoop
+** objects, then computing a particular sequence of WhereLoop objects, with
+** one WhereLoop object per FROM clause term, that satisfy all dependencies
+** and that minimize the overall cost.
+*/
+struct WhereLoop {
+ Bitmask prereq; /* Bitmask of other loops that must run first */
+ Bitmask maskSelf; /* Bitmask identifying table iTab */
+#ifdef SQLITE_DEBUG
+ char cId; /* Symbolic ID of this loop for debugging use */
+#endif
+ u8 iTab; /* Position in FROM clause of table for this loop */
+ u8 iSortIdx; /* Sorting index number. 0==None */
+ LogEst rSetup; /* One-time setup cost (ex: create transient index) */
+ LogEst rRun; /* Cost of running each loop */
+ LogEst nOut; /* Estimated number of output rows */
+ union {
+ struct { /* Information for internal btree tables */
+ u16 nEq; /* Number of equality constraints */
+ u16 nSkip; /* Number of initial index columns to skip */
+ Index *pIndex; /* Index used, or NULL */
+ } btree;
+ struct { /* Information for virtual tables */
+ int idxNum; /* Index number */
+ u8 needFree; /* True if sqlite3_free(idxStr) is needed */
+ u8 isOrdered; /* True if satisfies ORDER BY */
+ u16 omitMask; /* Terms that may be omitted */
+ char *idxStr; /* Index identifier string */
+ } vtab;
+ } u;
+ u32 wsFlags; /* WHERE_* flags describing the plan */
+ u16 nLTerm; /* Number of entries in aLTerm[] */
+ /**** whereLoopXfer() copies fields above ***********************/
+# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
+ u16 nLSlot; /* Number of slots allocated for aLTerm[] */
+ WhereTerm **aLTerm; /* WhereTerms used */
+ WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
+ WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */
+};
+
+/* This object holds the prerequisites and the cost of running a
+** subquery on one operand of an OR operator in the WHERE clause.
+** See WhereOrSet for additional information
+*/
+struct WhereOrCost {
+ Bitmask prereq; /* Prerequisites */
+ LogEst rRun; /* Cost of running this subquery */
+ LogEst nOut; /* Number of outputs for this subquery */
+};
+
+/* The WhereOrSet object holds a set of possible WhereOrCosts that
+** correspond to the subquery(s) of OR-clause processing. Only the
+** best N_OR_COST elements are retained.
+*/
+#define N_OR_COST 3
+struct WhereOrSet {
+ u16 n; /* Number of valid a[] entries */
+ WhereOrCost a[N_OR_COST]; /* Set of best costs */
+};
+
+
+/* Forward declaration of methods */
+static int whereLoopResize(sqlite3*, WhereLoop*, int);
+
+/*
+** Each instance of this object holds a sequence of WhereLoop objects
+** that implement some or all of a query plan.
+**
+** Think of each WhereLoop object as a node in a graph with arcs
+** showing dependencies and costs for travelling between nodes. (That is
+** not a completely accurate description because WhereLoop costs are a
+** vector, not a scalar, and because dependencies are many-to-one, not
+** one-to-one as are graph nodes. But it is a useful visualization aid.)
+** Then a WherePath object is a path through the graph that visits some
+** or all of the WhereLoop objects once.
+**
+** The "solver" works by creating the N best WherePath objects of length
+** 1. Then using those as a basis to compute the N best WherePath objects
+** of length 2. And so forth until the length of WherePaths equals the
+** number of nodes in the FROM clause. The best (lowest cost) WherePath
+** at the end is the choosen query plan.
+*/
+struct WherePath {
+ Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
+ Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
+ LogEst nRow; /* Estimated number of rows generated by this path */
+ LogEst rCost; /* Total cost of this path */
+ u8 isOrdered; /* True if this path satisfies ORDER BY */
+ u8 isOrderedValid; /* True if the isOrdered field is valid */
+ WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
+};
/*
** The query generator uses an array of instances of this structure to
@@ -104442,9 +108191,9 @@ typedef struct WhereCost WhereCost;
**
** (t1.X <op> <expr>) OR (t1.Y <op> <expr>) OR ....
**
-** In this second case, wtFlag as the TERM_ORINFO set and eOperator==WO_OR
+** In this second case, wtFlag has the TERM_ORINFO bit set and eOperator==WO_OR
** and the WhereTerm.u.pOrInfo field points to auxiliary information that
-** is collected about the
+** is collected about the OR clause.
**
** If a term in the WHERE clause does not match either of the two previous
** categories, then eOperator==0. The WhereTerm.pExpr field is still set
@@ -104467,7 +108216,6 @@ typedef struct WhereCost WhereCost;
** in prereqRight and prereqAll. The default is 64 bits, hence SQLite
** is only able to process joins with 64 or fewer tables.
*/
-typedef struct WhereTerm WhereTerm;
struct WhereTerm {
Expr *pExpr; /* Pointer to the subexpression that is this term */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
@@ -104477,6 +108225,7 @@ struct WhereTerm {
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
} u;
+ LogEst truthProb; /* Probability of truth for this expression */
u16 eOperator; /* A WO_xx value describing <op> */
u8 wtFlags; /* TERM_xxx bit flags. See below */
u8 nChild; /* Number of children that must disable us */
@@ -104495,13 +108244,29 @@ struct WhereTerm {
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
#else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
#endif
/*
+** An instance of the WhereScan object is used as an iterator for locating
+** terms in the WHERE clause that are useful to the query planner.
+*/
+struct WhereScan {
+ WhereClause *pOrigWC; /* Original, innermost WhereClause */
+ WhereClause *pWC; /* WhereClause currently being scanned */
+ char *zCollName; /* Required collating sequence, if not NULL */
+ char idxaff; /* Must match this affinity, if zCollName!=NULL */
+ unsigned char nEquiv; /* Number of entries in aEquiv[] */
+ unsigned char iEquiv; /* Next unused slot in aEquiv[] */
+ u32 opMask; /* Acceptable operators */
+ int k; /* Resume scanning at this->pWC->a[this->k] */
+ int aEquiv[22]; /* Cursor,Column pairs for equivalence classes */
+};
+
+/*
** An instance of the following structure holds all information about a
** WHERE clause. Mostly this is a container for one or more WhereTerms.
**
@@ -104514,11 +108279,9 @@ struct WhereTerm {
** subclauses points to the WhereClause object for the whole clause.
*/
struct WhereClause {
- Parse *pParse; /* The parser context */
- WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
+ WhereInfo *pWInfo; /* WHERE clause processing context */
WhereClause *pOuter; /* Outer conjunction */
u8 op; /* Split operator. TK_AND or TK_OR */
- u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
@@ -104578,19 +108341,60 @@ struct WhereMaskSet {
};
/*
-** A WhereCost object records a lookup strategy and the estimated
-** cost of pursuing that strategy.
+** This object is a convenience wrapper holding all information needed
+** to construct WhereLoop objects for a particular query.
*/
-struct WhereCost {
- WherePlan plan; /* The lookup strategy */
- double rCost; /* Overall cost of pursuing this search strategy */
- Bitmask used; /* Bitmask of cursors used by this plan */
+struct WhereLoopBuilder {
+ WhereInfo *pWInfo; /* Information about this WHERE */
+ WhereClause *pWC; /* WHERE clause terms */
+ ExprList *pOrderBy; /* ORDER BY clause */
+ WhereLoop *pNew; /* Template WhereLoop */
+ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ UnpackedRecord *pRec; /* Probe for stat4 (if required) */
+ int nRecValid; /* Number of valid fields currently in pRec */
+#endif
+};
+
+/*
+** The WHERE clause processing routine has two halves. The
+** first part does the start of the WHERE loop and the second
+** half does the tail of the WHERE loop. An instance of
+** this structure is returned by the first half and passed
+** into the second half to give some continuity.
+**
+** An instance of this object holds the complete state of the query
+** planner.
+*/
+struct WhereInfo {
+ Parse *pParse; /* Parsing and code generating context */
+ SrcList *pTabList; /* List of tables in the join */
+ ExprList *pOrderBy; /* The ORDER BY clause or NULL */
+ ExprList *pResultSet; /* Result set. DISTINCT operates on these */
+ WhereLoop *pLoops; /* List of all WhereLoop objects */
+ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
+ LogEst nRowOut; /* Estimated number of output rows */
+ u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
+ u8 bOBSat; /* ORDER BY satisfied by indices */
+ u8 okOnePass; /* Ok to use one-pass algorithm for UPDATE/DELETE */
+ u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
+ u8 eDistinct; /* One of the WHERE_DISTINCT_* values below */
+ u8 nLevel; /* Number of nested loop */
+ int iTop; /* The very beginning of the WHERE loop */
+ int iContinue; /* Jump here to continue with next record */
+ int iBreak; /* Jump here to break out of the loop */
+ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
+ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
+ WhereClause sWC; /* Decomposition of the WHERE clause */
+ WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
/*
-** Bitmasks for the operators that indices are able to exploit. An
+** Bitmasks for the operators on WhereTerm objects. These are all
+** operators that are of interest to the query planner. An
** OR-ed combination of these values can be used when searching for
-** terms in the where clause.
+** particular WhereTerms within a WhereClause.
*/
#define WO_IN 0x001
#define WO_EQ 0x002
@@ -104609,74 +108413,136 @@ struct WhereCost {
#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
/*
-** Value for wsFlags returned by bestIndex() and stored in
-** WhereLevel.wsFlags. These flags determine which search
-** strategies are appropriate.
-**
-** The least significant 12 bits is reserved as a mask for WO_ values above.
-** The WhereLevel.wsFlags field is usually set to WO_IN|WO_EQ|WO_ISNULL.
-** But if the table is the right table of a left join, WhereLevel.wsFlags
-** is set to WO_IN|WO_EQ. The WhereLevel.wsFlags field can then be used as
-** the "op" parameter to findTerm when we are resolving equality constraints.
-** ISNULL constraints will then not be used on the right table of a left
-** join. Tickets #2177 and #2189.
-*/
-#define WHERE_ROWID_EQ 0x00001000 /* rowid=EXPR or rowid IN (...) */
-#define WHERE_ROWID_RANGE 0x00002000 /* rowid<EXPR and/or rowid>EXPR */
-#define WHERE_COLUMN_EQ 0x00010000 /* x=EXPR or x IN (...) or x IS NULL */
-#define WHERE_COLUMN_RANGE 0x00020000 /* x<EXPR and/or x>EXPR */
-#define WHERE_COLUMN_IN 0x00040000 /* x IN (...) */
-#define WHERE_COLUMN_NULL 0x00080000 /* x IS NULL */
-#define WHERE_INDEXED 0x000f0000 /* Anything that uses an index */
-#define WHERE_NOT_FULLSCAN 0x100f3000 /* Does not do a full table scan */
-#define WHERE_IN_ABLE 0x080f1000 /* Able to support an IN operator */
-#define WHERE_TOP_LIMIT 0x00100000 /* x<EXPR or x<=EXPR constraint */
-#define WHERE_BTM_LIMIT 0x00200000 /* x>EXPR or x>=EXPR constraint */
-#define WHERE_BOTH_LIMIT 0x00300000 /* Both x>EXPR and x<EXPR */
-#define WHERE_IDX_ONLY 0x00400000 /* Use index only - omit table */
-#define WHERE_ORDERED 0x00800000 /* Output will appear in correct order */
-#define WHERE_REVERSE 0x01000000 /* Scan in reverse order */
-#define WHERE_UNIQUE 0x02000000 /* Selects no more than one row */
-#define WHERE_ALL_UNIQUE 0x04000000 /* This and all prior have one row */
-#define WHERE_OB_UNIQUE 0x00004000 /* Values in ORDER BY columns are
- ** different for every output row */
-#define WHERE_VIRTUALTABLE 0x08000000 /* Use virtual-table processing */
-#define WHERE_MULTI_OR 0x10000000 /* OR using multiple indices */
-#define WHERE_TEMP_INDEX 0x20000000 /* Uses an ephemeral index */
-#define WHERE_DISTINCT 0x40000000 /* Correct order for DISTINCT */
-#define WHERE_COVER_SCAN 0x80000000 /* Full scan of a covering index */
-
-/*
-** This module contains many separate subroutines that work together to
-** find the best indices to use for accessing a particular table in a query.
-** An instance of the following structure holds context information about the
-** index search so that it can be more easily passed between the various
-** routines.
+** These are definitions of bits in the WhereLoop.wsFlags field.
+** The particular combination of bits in each WhereLoop help to
+** determine the algorithm that WhereLoop represents.
*/
-typedef struct WhereBestIdx WhereBestIdx;
-struct WhereBestIdx {
- Parse *pParse; /* Parser context */
- WhereClause *pWC; /* The WHERE clause */
- struct SrcList_item *pSrc; /* The FROM clause term to search */
- Bitmask notReady; /* Mask of cursors not available */
- Bitmask notValid; /* Cursors not available for any purpose */
- ExprList *pOrderBy; /* The ORDER BY clause */
- ExprList *pDistinct; /* The select-list if query is DISTINCT */
- sqlite3_index_info **ppIdxInfo; /* Index information passed to xBestIndex */
- int i, n; /* Which loop is being coded; # of loops */
- WhereLevel *aLevel; /* Info about outer loops */
- WhereCost cost; /* Lowest cost query plan */
-};
+#define WHERE_COLUMN_EQ 0x00000001 /* x=EXPR */
+#define WHERE_COLUMN_RANGE 0x00000002 /* x<EXPR and/or x>EXPR */
+#define WHERE_COLUMN_IN 0x00000004 /* x IN (...) */
+#define WHERE_COLUMN_NULL 0x00000008 /* x IS NULL */
+#define WHERE_CONSTRAINT 0x0000000f /* Any of the WHERE_COLUMN_xxx values */
+#define WHERE_TOP_LIMIT 0x00000010 /* x<EXPR or x<=EXPR constraint */
+#define WHERE_BTM_LIMIT 0x00000020 /* x>EXPR or x>=EXPR constraint */
+#define WHERE_BOTH_LIMIT 0x00000030 /* Both x>EXPR and x<EXPR */
+#define WHERE_IDX_ONLY 0x00000040 /* Use index only - omit table */
+#define WHERE_IPK 0x00000100 /* x is the INTEGER PRIMARY KEY */
+#define WHERE_INDEXED 0x00000200 /* WhereLoop.u.btree.pIndex is valid */
+#define WHERE_VIRTUALTABLE 0x00000400 /* WhereLoop.u.vtab is valid */
+#define WHERE_IN_ABLE 0x00000800 /* Able to support an IN operator */
+#define WHERE_ONEROW 0x00001000 /* Selects no more than one row */
+#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
+#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
+#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
+
+/************** End of whereInt.h ********************************************/
+/************** Continuing where we left off in where.c **********************/
/*
-** Return TRUE if the probe cost is less than the baseline cost
+** Return the estimated number of output rows from a WHERE clause
*/
-static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
- if( pProbe->rCost<pBaseline->rCost ) return 1;
- if( pProbe->rCost>pBaseline->rCost ) return 0;
- if( pProbe->plan.nOBSat>pBaseline->plan.nOBSat ) return 1;
- if( pProbe->plan.nRow<pBaseline->plan.nRow ) return 1;
- return 0;
+SQLITE_PRIVATE u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+ return sqlite3LogEstToInt(pWInfo->nRowOut);
+}
+
+/*
+** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this
+** WHERE clause returns outputs for DISTINCT processing.
+*/
+SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
+ return pWInfo->eDistinct;
+}
+
+/*
+** Return TRUE if the WHERE clause returns rows in ORDER BY order.
+** Return FALSE if the output needs to be sorted.
+*/
+SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
+ return pWInfo->bOBSat!=0;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to continue
+** immediately with the next row of a WHERE clause.
+*/
+SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){
+ return pWInfo->iContinue;
+}
+
+/*
+** Return the VDBE address or label to jump to in order to break
+** out of a WHERE loop.
+*/
+SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){
+ return pWInfo->iBreak;
+}
+
+/*
+** Return TRUE if an UPDATE or DELETE statement can operate directly on
+** the rowids returned by a WHERE clause. Return FALSE if doing an
+** UPDATE or DELETE might change subsequent WHERE clause results.
+**
+** If the ONEPASS optimization is used (if this routine returns true)
+** then also write the indices of open cursors used by ONEPASS
+** into aiCur[0] and aiCur[1]. iaCur[0] gets the cursor of the data
+** table and iaCur[1] gets the cursor used by an auxiliary index.
+** Either value may be -1, indicating that cursor is not used.
+** Any cursors returned will have been opened for writing.
+**
+** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
+** unable to use the ONEPASS optimization.
+*/
+SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
+ memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
+ return pWInfo->okOnePass;
+}
+
+/*
+** Move the content of pSrc into pDest
+*/
+static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
+ pDest->n = pSrc->n;
+ memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
+}
+
+/*
+** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
+**
+** The new entry might overwrite an existing entry, or it might be
+** appended, or it might be discarded. Do whatever is the right thing
+** so that pSet keeps the N_OR_COST best entries seen so far.
+*/
+static int whereOrInsert(
+ WhereOrSet *pSet, /* The WhereOrSet to be updated */
+ Bitmask prereq, /* Prerequisites of the new entry */
+ LogEst rRun, /* Run-cost of the new entry */
+ LogEst nOut /* Number of outputs for the new entry */
+){
+ u16 i;
+ WhereOrCost *p;
+ for(i=pSet->n, p=pSet->a; i>0; i--, p++){
+ if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
+ goto whereOrInsert_done;
+ }
+ if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
+ return 0;
+ }
+ }
+ if( pSet->n<N_OR_COST ){
+ p = &pSet->a[pSet->n++];
+ p->nOut = nOut;
+ }else{
+ p = pSet->a;
+ for(i=1; i<pSet->n; i++){
+ if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
+ }
+ if( p->rRun<=rRun ) return 0;
+ }
+whereOrInsert_done:
+ p->prereq = prereq;
+ p->rRun = rRun;
+ if( p->nOut>nOut ) p->nOut = nOut;
+ return 1;
}
/*
@@ -104684,17 +108550,13 @@ static int compareCost(const WhereCost *pProbe, const WhereCost *pBaseline){
*/
static void whereClauseInit(
WhereClause *pWC, /* The WhereClause to be initialized */
- Parse *pParse, /* The parsing context */
- WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */
- u16 wctrlFlags /* Might include WHERE_AND_ONLY */
+ WhereInfo *pWInfo /* The WHERE processing context */
){
- pWC->pParse = pParse;
- pWC->pMaskSet = pMaskSet;
+ pWC->pWInfo = pWInfo;
pWC->pOuter = 0;
pWC->nTerm = 0;
pWC->nSlot = ArraySize(pWC->aStatic);
pWC->a = pWC->aStatic;
- pWC->wctrlFlags = wctrlFlags;
}
/* Forward reference */
@@ -104723,7 +108585,7 @@ static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){
static void whereClauseClear(WhereClause *pWC){
int i;
WhereTerm *a;
- sqlite3 *db = pWC->pParse->db;
+ sqlite3 *db = pWC->pWInfo->pParse->db;
for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
if( a->wtFlags & TERM_DYNAMIC ){
sqlite3ExprDelete(db, a->pExpr);
@@ -104761,10 +108623,10 @@ static void whereClauseClear(WhereClause *pWC){
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
WhereTerm *pTerm;
int idx;
- testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
+ testcase( wtFlags & TERM_VIRTUAL );
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
- sqlite3 *db = pWC->pParse->db;
+ sqlite3 *db = pWC->pWInfo->pParse->db;
pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
if( wtFlags & TERM_DYNAMIC ){
@@ -104780,6 +108642,11 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
}
pTerm = &pWC->a[idx = pWC->nTerm++];
+ if( p && ExprHasProperty(p, EP_Unlikely) ){
+ pTerm->truthProb = sqlite3LogEst(p->iTable) - 99;
+ }else{
+ pTerm->truthProb = -1;
+ }
pTerm->pExpr = sqlite3ExprSkipCollate(p);
pTerm->wtFlags = wtFlags;
pTerm->pWC = pWC;
@@ -104804,8 +108671,8 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
** the WhereClause.a[] array. The slot[] array grows as needed to contain
** all terms of the WHERE clause.
*/
-static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
- pWC->op = (u8)op;
+static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+ pWC->op = op;
if( pExpr==0 ) return;
if( pExpr->op!=op ){
whereClauseInsert(pWC, pExpr, 0);
@@ -104816,9 +108683,9 @@ static void whereSplit(WhereClause *pWC, Expr *pExpr, int op){
}
/*
-** Initialize an expression mask set (a WhereMaskSet object)
+** Initialize a WhereMaskSet object
*/
-#define initMaskSet(P) memset(P, 0, sizeof(*P))
+#define initMaskSet(P) (P)->n=0
/*
** Return the bitmask for the given cursor number. Return 0 if
@@ -104829,7 +108696,7 @@ static Bitmask getMask(WhereMaskSet *pMaskSet, int iCursor){
assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
for(i=0; i<pMaskSet->n; i++){
if( pMaskSet->ix[i]==iCursor ){
- return ((Bitmask)1)<<i;
+ return MASKBIT(i);
}
}
return 0;
@@ -104849,18 +108716,9 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){
}
/*
-** This routine walks (recursively) an expression tree and generates
+** These routines walk (recursively) an expression tree and generate
** a bitmask indicating which tables are used in that expression
** tree.
-**
-** In order for this routine to work, the calling function must have
-** previously invoked sqlite3ResolveExprNames() on the expression. See
-** the header comment on that routine for additional information.
-** The sqlite3ResolveExprNames() routines looks for column names and
-** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
-** the VDBE cursor number of the table. This routine just has to
-** translate the cursor numbers into bitmask values and OR all
-** the bitmasks together.
*/
static Bitmask exprListTableUsage(WhereMaskSet*, ExprList*);
static Bitmask exprSelectTableUsage(WhereMaskSet*, Select*);
@@ -104914,14 +108772,7 @@ static Bitmask exprSelectTableUsage(WhereMaskSet *pMaskSet, Select *pS){
/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term. The allowed operators are
-** "=", "<", ">", "<=", ">=", and "IN".
-**
-** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
-** of one of the following forms: column = expression column > expression
-** column >= expression column < expression column <= expression
-** expression = column expression > column expression >= column
-** expression < column expression <= column column IN
-** (expression-list) column IN (subquery) column IS NULL
+** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
*/
static int allowedOp(int op){
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
@@ -104941,10 +108792,9 @@ static int allowedOp(int op){
** are converted into "Y op X".
**
** If left/right precedence rules come into play when determining the
-** collating
-** side of the comparison, it remains associated with the same side after
-** the commutation. So "Y collate NOCASE op X" becomes
-** "X op Y". This is because any collation sequence on
+** collating sequence, then COLLATE operators are adjusted to ensure
+** that the collating sequence does not change. For example:
+** "Y collate NOCASE op X" becomes "X op Y" because any collation sequence on
** the left hand side of a comparison overrides any collation sequence
** attached to the right. For the same reason the EP_Collate flag
** is not commuted.
@@ -105002,6 +108852,133 @@ static u16 operatorMask(int op){
}
/*
+** Advance to the next WhereTerm that matches according to the criteria
+** established when the pScan object was initialized by whereScanInit().
+** Return NULL if there are no more matching WhereTerms.
+*/
+static WhereTerm *whereScanNext(WhereScan *pScan){
+ int iCur; /* The cursor on the LHS of the term */
+ int iColumn; /* The column on the LHS of the term. -1 for IPK */
+ Expr *pX; /* An expression being tested */
+ WhereClause *pWC; /* Shorthand for pScan->pWC */
+ WhereTerm *pTerm; /* The term being tested */
+ int k = pScan->k; /* Where to start scanning */
+
+ while( pScan->iEquiv<=pScan->nEquiv ){
+ iCur = pScan->aEquiv[pScan->iEquiv-2];
+ iColumn = pScan->aEquiv[pScan->iEquiv-1];
+ while( (pWC = pScan->pWC)!=0 ){
+ for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
+ if( pTerm->leftCursor==iCur
+ && pTerm->u.leftColumn==iColumn
+ && (pScan->iEquiv<=2 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ ){
+ if( (pTerm->eOperator & WO_EQUIV)!=0
+ && pScan->nEquiv<ArraySize(pScan->aEquiv)
+ ){
+ int j;
+ pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
+ assert( pX->op==TK_COLUMN );
+ for(j=0; j<pScan->nEquiv; j+=2){
+ if( pScan->aEquiv[j]==pX->iTable
+ && pScan->aEquiv[j+1]==pX->iColumn ){
+ break;
+ }
+ }
+ if( j==pScan->nEquiv ){
+ pScan->aEquiv[j] = pX->iTable;
+ pScan->aEquiv[j+1] = pX->iColumn;
+ pScan->nEquiv += 2;
+ }
+ }
+ if( (pTerm->eOperator & pScan->opMask)!=0 ){
+ /* Verify the affinity and collating sequence match */
+ if( pScan->zCollName && (pTerm->eOperator & WO_ISNULL)==0 ){
+ CollSeq *pColl;
+ Parse *pParse = pWC->pWInfo->pParse;
+ pX = pTerm->pExpr;
+ if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){
+ continue;
+ }
+ assert(pX->pLeft);
+ pColl = sqlite3BinaryCompareCollSeq(pParse,
+ pX->pLeft, pX->pRight);
+ if( pColl==0 ) pColl = pParse->db->pDfltColl;
+ if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
+ continue;
+ }
+ }
+ if( (pTerm->eOperator & WO_EQ)!=0
+ && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
+ && pX->iTable==pScan->aEquiv[0]
+ && pX->iColumn==pScan->aEquiv[1]
+ ){
+ continue;
+ }
+ pScan->k = k+1;
+ return pTerm;
+ }
+ }
+ }
+ pScan->pWC = pScan->pWC->pOuter;
+ k = 0;
+ }
+ pScan->pWC = pScan->pOrigWC;
+ k = 0;
+ pScan->iEquiv += 2;
+ }
+ return 0;
+}
+
+/*
+** Initialize a WHERE clause scanner object. Return a pointer to the
+** first match. Return NULL if there are no matches.
+**
+** The scanner will be searching the WHERE clause pWC. It will look
+** for terms of the form "X <op> <expr>" where X is column iColumn of table
+** iCur. The <op> must be one of the operators described by opMask.
+**
+** If the search is for X and the WHERE clause contains terms of the
+** form X=Y then this routine might also return terms of the form
+** "Y <op> <expr>". The number of levels of transitivity is limited,
+** but is enough to handle most commonly occurring SQL statements.
+**
+** If X is not the INTEGER PRIMARY KEY then X must be compatible with
+** index pIdx.
+*/
+static WhereTerm *whereScanInit(
+ WhereScan *pScan, /* The WhereScan object being initialized */
+ WhereClause *pWC, /* The WHERE clause to be scanned */
+ int iCur, /* Cursor to scan for */
+ int iColumn, /* Column to scan for */
+ u32 opMask, /* Operator(s) to scan for */
+ Index *pIdx /* Must be compatible with this index */
+){
+ int j;
+
+ /* memset(pScan, 0, sizeof(*pScan)); */
+ pScan->pOrigWC = pWC;
+ pScan->pWC = pWC;
+ if( pIdx && iColumn>=0 ){
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+ for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
+ if( NEVER(j>=pIdx->nKeyCol) ) return 0;
+ }
+ pScan->zCollName = pIdx->azColl[j];
+ }else{
+ pScan->idxaff = 0;
+ pScan->zCollName = 0;
+ }
+ pScan->opMask = opMask;
+ pScan->k = 0;
+ pScan->aEquiv[0] = iCur;
+ pScan->aEquiv[1] = iColumn;
+ pScan->nEquiv = 2;
+ pScan->iEquiv = 2;
+ return whereScanNext(pScan);
+}
+
+/*
** Search for a term in the WHERE clause that is of the form "X <op> <expr>"
** where X is a reference to the iColumn of table iCur and <op> is one of
** the WO_xx operator codes specified by the op parameter.
@@ -105032,84 +109009,20 @@ static WhereTerm *findTerm(
u32 op, /* Mask of WO_xx values describing operator */
Index *pIdx /* Must be compatible with this index, if not NULL */
){
- WhereTerm *pTerm; /* Term being examined as possible result */
- WhereTerm *pResult = 0; /* The answer to return */
- WhereClause *pWCOrig = pWC; /* Original pWC value */
- int j, k; /* Loop counters */
- Expr *pX; /* Pointer to an expression */
- Parse *pParse; /* Parsing context */
- int iOrigCol = iColumn; /* Original value of iColumn */
- int nEquiv = 2; /* Number of entires in aEquiv[] */
- int iEquiv = 2; /* Number of entries of aEquiv[] processed so far */
- int aEquiv[22]; /* iCur,iColumn and up to 10 other equivalents */
-
- assert( iCur>=0 );
- aEquiv[0] = iCur;
- aEquiv[1] = iColumn;
- for(;;){
- for(pWC=pWCOrig; pWC; pWC=pWC->pOuter){
- for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
- if( pTerm->leftCursor==iCur
- && pTerm->u.leftColumn==iColumn
- ){
- if( (pTerm->prereqRight & notReady)==0
- && (pTerm->eOperator & op & WO_ALL)!=0
- ){
- if( iOrigCol>=0 && pIdx && (pTerm->eOperator & WO_ISNULL)==0 ){
- CollSeq *pColl;
- char idxaff;
-
- pX = pTerm->pExpr;
- pParse = pWC->pParse;
- idxaff = pIdx->pTable->aCol[iOrigCol].affinity;
- if( !sqlite3IndexAffinityOk(pX, idxaff) ){
- continue;
- }
-
- /* Figure out the collation sequence required from an index for
- ** it to be useful for optimising expression pX. Store this
- ** value in variable pColl.
- */
- assert(pX->pLeft);
- pColl = sqlite3BinaryCompareCollSeq(pParse,pX->pLeft,pX->pRight);
- if( pColl==0 ) pColl = pParse->db->pDfltColl;
-
- for(j=0; pIdx->aiColumn[j]!=iOrigCol; j++){
- if( NEVER(j>=pIdx->nColumn) ) return 0;
- }
- if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ){
- continue;
- }
- }
- if( pTerm->prereqRight==0 && (pTerm->eOperator&WO_EQ)!=0 ){
- pResult = pTerm;
- goto findTerm_success;
- }else if( pResult==0 ){
- pResult = pTerm;
- }
- }
- if( (pTerm->eOperator & WO_EQUIV)!=0
- && nEquiv<ArraySize(aEquiv)
- ){
- pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight);
- assert( pX->op==TK_COLUMN );
- for(j=0; j<nEquiv; j+=2){
- if( aEquiv[j]==pX->iTable && aEquiv[j+1]==pX->iColumn ) break;
- }
- if( j==nEquiv ){
- aEquiv[j] = pX->iTable;
- aEquiv[j+1] = pX->iColumn;
- nEquiv += 2;
- }
- }
- }
+ WhereTerm *pResult = 0;
+ WhereTerm *p;
+ WhereScan scan;
+
+ p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
+ while( p ){
+ if( (p->prereqRight & notReady)==0 ){
+ if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
+ return p;
}
+ if( pResult==0 ) pResult = p;
}
- if( iEquiv>=nEquiv ) break;
- iCur = aEquiv[iEquiv++];
- iColumn = aEquiv[iEquiv++];
+ p = whereScanNext(&scan);
}
-findTerm_success:
return pResult;
}
@@ -105118,8 +109031,6 @@ static void exprAnalyze(SrcList*, WhereClause*, int);
/*
** Call exprAnalyze on all terms in a WHERE clause.
-**
-**
*/
static void exprAnalyzeAll(
SrcList *pTabList, /* the FROM clause */
@@ -105177,13 +109088,10 @@ static int isLikeOrGlob(
pRight = pList->a[0].pExpr;
op = pRight->op;
- if( op==TK_REGISTER ){
- op = pRight->op2;
- }
if( op==TK_VARIABLE ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
- pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
+ pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
z = (char *)sqlite3_value_text(pVal);
}
@@ -105265,8 +109173,10 @@ static int isMatchOfColumn(
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
- pDerived->flags |= pBase->flags & EP_FromJoin;
- pDerived->iRightJoinTable = pBase->iRightJoinTable;
+ if( pDerived ){
+ pDerived->flags |= pBase->flags & EP_FromJoin;
+ pDerived->iRightJoinTable = pBase->iRightJoinTable;
+ }
}
#if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
@@ -105325,10 +109235,10 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
** From another point of view, "indexable" means that the subterm could
** potentially be used with an index if an appropriate index exists.
** This analysis does not consider whether or not the index exists; that
-** is something the bestIndex() routine will determine. This analysis
-** only looks at whether subterms appropriate for indexing exist.
+** is decided elsewhere. This analysis only looks at whether subterms
+** appropriate for indexing exist.
**
-** All examples A through E above all satisfy case 2. But if a term
+** All examples A through E above satisfy case 2. But if a term
** also statisfies case 1 (such as B) we know that the optimizer will
** always prefer case 1, so in that case we pretend that case 2 is not
** satisfied.
@@ -105351,11 +109261,11 @@ static void exprAnalyzeOrTerm(
WhereClause *pWC, /* the complete WHERE clause */
int idxTerm /* Index of the OR-term to be analyzed */
){
- Parse *pParse = pWC->pParse; /* Parser context */
+ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
+ Parse *pParse = pWInfo->pParse; /* Parser context */
sqlite3 *db = pParse->db; /* Database connection */
WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */
Expr *pExpr = pTerm->pExpr; /* The expression of the term */
- WhereMaskSet *pMaskSet = pWC->pMaskSet; /* Table use masks */
int i; /* Loop counters */
WhereClause *pOrWc; /* Breakup of pTerm into subterms */
WhereTerm *pOrTerm; /* A Sub-term within the pOrWc */
@@ -105374,7 +109284,7 @@ static void exprAnalyzeOrTerm(
if( pOrInfo==0 ) return;
pTerm->wtFlags |= TERM_ORINFO;
pOrWc = &pOrInfo->wc;
- whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
+ whereClauseInit(pOrWc, pWInfo);
whereSplit(pOrWc, pExpr, TK_OR);
exprAnalyzeAll(pSrc, pOrWc);
if( db->mallocFailed ) return;
@@ -105400,7 +109310,7 @@ static void exprAnalyzeOrTerm(
pOrTerm->wtFlags |= TERM_ANDINFO;
pOrTerm->eOperator = WO_AND;
pAndWC = &pAndInfo->wc;
- whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
+ whereClauseInit(pAndWC, pWC->pWInfo);
whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
exprAnalyzeAll(pSrc, pAndWC);
pAndWC->pOuter = pWC;
@@ -105409,7 +109319,7 @@ static void exprAnalyzeOrTerm(
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
assert( pAndTerm->pExpr );
if( allowedOp(pAndTerm->pExpr->op) ){
- b |= getMask(pMaskSet, pAndTerm->leftCursor);
+ b |= getMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
}
}
}
@@ -105420,10 +109330,10 @@ static void exprAnalyzeOrTerm(
** corresponding TERM_VIRTUAL term */
}else{
Bitmask b;
- b = getMask(pMaskSet, pOrTerm->leftCursor);
+ b = getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor);
if( pOrTerm->wtFlags & TERM_VIRTUAL ){
WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent];
- b |= getMask(pMaskSet, pOther->leftCursor);
+ b |= getMask(&pWInfo->sMaskSet, pOther->leftCursor);
}
indexable &= b;
if( (pOrTerm->eOperator & WO_EQ)==0 ){
@@ -105485,7 +109395,7 @@ static void exprAnalyzeOrTerm(
assert( j==1 );
continue;
}
- if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
+ if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){
/* This term must be of the form t1.a==t2.b where t2 is in the
** chngToIN set but t1 is not. This term will be either preceeded
** or follwed by an inverted copy (t2.b==t1.a). Skip this term
@@ -105504,7 +109414,7 @@ static void exprAnalyzeOrTerm(
** on the second iteration */
assert( j==1 );
assert( IsPowerOfTwo(chngToIN) );
- assert( chngToIN==getMask(pMaskSet, iCursor) );
+ assert( chngToIN==getMask(&pWInfo->sMaskSet, iCursor) );
break;
}
testcase( j==1 );
@@ -105538,8 +109448,6 @@ static void exprAnalyzeOrTerm(
/* At this point, okToChngToIN is true if original pTerm satisfies
** case 1. In that case, construct a new virtual term that is
** pTerm converted into an IN operator.
- **
- ** EV: R-00211-15100
*/
if( okToChngToIN ){
Expr *pDup; /* A transient duplicate expression */
@@ -105553,7 +109461,7 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
- pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
+ pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
@@ -105602,6 +109510,7 @@ static void exprAnalyze(
WhereClause *pWC, /* the WHERE clause */
int idxTerm /* Index of the term to be analyzed */
){
+ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */
WhereTerm *pTerm; /* The term to be analyzed */
WhereMaskSet *pMaskSet; /* Set of table index masks */
Expr *pExpr; /* The expression to be analyzed */
@@ -105612,14 +109521,14 @@ static void exprAnalyze(
int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
int noCase = 0; /* LIKE/GLOB distinguishes case */
int op; /* Top-level operator. pExpr->op */
- Parse *pParse = pWC->pParse; /* Parsing context */
+ Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
if( db->mallocFailed ){
return;
}
pTerm = &pWC->a[idxTerm];
- pMaskSet = pWC->pMaskSet;
+ pMaskSet = &pWInfo->sMaskSet;
pExpr = pTerm->pExpr;
assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
@@ -105724,6 +109633,7 @@ static void exprAnalyze(
pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
+ transferJoinMarkings(pNewExpr, pExpr);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
exprAnalyze(pSrc, pWC, idxNew);
@@ -105780,9 +109690,7 @@ static void exprAnalyze(
** inequality. To avoid this, make sure to also run the full
** LIKE on all candidate expressions by clearing the isComplete flag
*/
- if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
-
-
+ if( c=='A'-1 ) isComplete = 0;
c = sqlite3UpperToLower[c];
}
*pC = c + 1;
@@ -105793,6 +109701,7 @@ static void exprAnalyze(
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
pStr1, 0);
+ transferJoinMarkings(pNewExpr1, pExpr);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew1==0 );
exprAnalyze(pSrc, pWC, idxNew1);
@@ -105800,6 +109709,7 @@ static void exprAnalyze(
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
pStr2, 0);
+ transferJoinMarkings(pNewExpr2, pExpr);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew2==0 );
exprAnalyze(pSrc, pWC, idxNew2);
@@ -105849,7 +109759,7 @@ static void exprAnalyze(
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* When sqlite_stat3 histogram data is available an operator of the
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
@@ -105863,6 +109773,7 @@ static void exprAnalyze(
if( pExpr->op==TK_NOTNULL
&& pExpr->pLeft->op==TK_COLUMN
&& pExpr->pLeft->iColumn>=0
+ && OptimizationEnabled(db, SQLITE_Stat3)
){
Expr *pNewExpr;
Expr *pLeft = pExpr->pLeft;
@@ -105888,7 +109799,7 @@ static void exprAnalyze(
pNewTerm->prereqAll = pTerm->prereqAll;
}
}
-#endif /* SQLITE_ENABLE_STAT */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
@@ -105897,11 +109808,8 @@ static void exprAnalyze(
}
/*
-** This function searches the expression list passed as the second argument
-** for an expression of type TK_COLUMN that refers to the same column and
-** uses the same collation sequence as the iCol'th column of index pIdx.
-** Argument iBase is the cursor number used for the table that pIdx refers
-** to.
+** This function searches pList for a entry that matches the iCol-th column
+** of index pIdx.
**
** If such an expression is found, its index in pList->a[] is returned. If
** no expression is found, -1 is returned.
@@ -105933,76 +109841,17 @@ static int findIndexCol(
}
/*
-** This routine determines if pIdx can be used to assist in processing a
-** DISTINCT qualifier. In other words, it tests whether or not using this
-** index for the outer loop guarantees that rows with equal values for
-** all expressions in the pDistinct list are delivered grouped together.
-**
-** For example, the query
-**
-** SELECT DISTINCT a, b, c FROM tbl WHERE a = ?
-**
-** can benefit from any index on columns "b" and "c".
-*/
-static int isDistinctIndex(
- Parse *pParse, /* Parsing context */
- WhereClause *pWC, /* The WHERE clause */
- Index *pIdx, /* The index being considered */
- int base, /* Cursor number for the table pIdx is on */
- ExprList *pDistinct, /* The DISTINCT expressions */
- int nEqCol /* Number of index columns with == */
-){
- Bitmask mask = 0; /* Mask of unaccounted for pDistinct exprs */
- int i; /* Iterator variable */
-
- assert( pDistinct!=0 );
- if( pIdx->zName==0 || pDistinct->nExpr>=BMS ) return 0;
- testcase( pDistinct->nExpr==BMS-1 );
-
- /* Loop through all the expressions in the distinct list. If any of them
- ** are not simple column references, return early. Otherwise, test if the
- ** WHERE clause contains a "col=X" clause. If it does, the expression
- ** can be ignored. If it does not, and the column does not belong to the
- ** same table as index pIdx, return early. Finally, if there is no
- ** matching "col=X" expression and the column is on the same table as pIdx,
- ** set the corresponding bit in variable mask.
- */
- for(i=0; i<pDistinct->nExpr; i++){
- WhereTerm *pTerm;
- Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr);
- if( p->op!=TK_COLUMN ) return 0;
- pTerm = findTerm(pWC, p->iTable, p->iColumn, ~(Bitmask)0, WO_EQ, 0);
- if( pTerm ){
- Expr *pX = pTerm->pExpr;
- CollSeq *p1 = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
- CollSeq *p2 = sqlite3ExprCollSeq(pParse, p);
- if( p1==p2 ) continue;
- }
- if( p->iTable!=base ) return 0;
- mask |= (((Bitmask)1) << i);
- }
-
- for(i=nEqCol; mask && i<pIdx->nColumn; i++){
- int iExpr = findIndexCol(pParse, pDistinct, base, pIdx, i);
- if( iExpr<0 ) break;
- mask &= ~(((Bitmask)1) << iExpr);
- }
-
- return (mask==0);
-}
-
-
-/*
** Return true if the DISTINCT expression-list passed as the third argument
-** is redundant. A DISTINCT list is redundant if the database contains a
-** UNIQUE index that guarantees that the result of the query will be distinct
-** anyway.
+** is redundant.
+**
+** A DISTINCT list is redundant if the database contains some subset of
+** columns that are unique and non-null.
*/
static int isDistinctRedundant(
- Parse *pParse,
- SrcList *pTabList,
- WhereClause *pWC,
- ExprList *pDistinct
+ Parse *pParse, /* Parsing context */
+ SrcList *pTabList, /* The FROM clause */
+ WhereClause *pWC, /* The WHERE clause */
+ ExprList *pDistinct /* The result set that needs to be DISTINCT */
){
Table *pTab;
Index *pIdx;
@@ -106040,16 +109889,16 @@ static int isDistinctRedundant(
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
- for(i=0; i<pIdx->nColumn; i++){
- int iCol = pIdx->aiColumn[i];
+ for(i=0; i<pIdx->nKeyCol; i++){
+ i16 iCol = pIdx->aiColumn[i];
if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
- if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
+ if( iIdxCol<0 || pTab->aCol[iCol].notNull==0 ){
break;
}
}
}
- if( i==pIdx->nColumn ){
+ if( i==pIdx->nKeyCol ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
@@ -106058,21 +109907,13 @@ static int isDistinctRedundant(
return 0;
}
+
/*
-** Prepare a crude estimate of the logarithm of the input value.
-** The results need not be exact. This is only used for estimating
-** the total cost of performing operations with O(logN) or O(NlogN)
-** complexity. Because N is just a guess, it is no great tragedy if
-** logN is a little off.
+** Estimate the logarithm of the input value to base 2.
*/
-static double estLog(double N){
- double logN = 1;
- double x = 10;
- while( N>x ){
- logN += 1;
- x *= 10;
- }
- return logN;
+static LogEst estLog(LogEst N){
+ LogEst x = sqlite3LogEst(N);
+ return x>33 ? x - 33 : 0;
}
/*
@@ -106081,7 +109922,7 @@ static double estLog(double N){
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
** are no-ops.
*/
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_DEBUG)
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
static void TRACE_IDX_INPUTS(sqlite3_index_info *p){
int i;
if( !sqlite3WhereTrace ) return;
@@ -106113,113 +109954,13 @@ static void TRACE_IDX_OUTPUTS(sqlite3_index_info *p){
sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr);
sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed);
sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost);
+ sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows);
}
#else
#define TRACE_IDX_INPUTS(A)
#define TRACE_IDX_OUTPUTS(A)
#endif
-/*
-** Required because bestIndex() is called by bestOrClauseIndex()
-*/
-static void bestIndex(WhereBestIdx*);
-
-/*
-** This routine attempts to find an scanning strategy that can be used
-** to optimize an 'OR' expression that is part of a WHERE clause.
-**
-** The table associated with FROM clause term pSrc may be either a
-** regular B-Tree table or a virtual table.
-*/
-static void bestOrClauseIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- const int iCur = pSrc->iCursor; /* The cursor of the table */
- const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
- WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
-
- /* The OR-clause optimization is disallowed if the INDEXED BY or
- ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
- if( pSrc->notIndexed || pSrc->pIndex!=0 ){
- return;
- }
- if( pWC->wctrlFlags & WHERE_AND_ONLY ){
- return;
- }
-
- /* Search the WHERE clause terms for a usable WO_OR term. */
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( (pTerm->eOperator & WO_OR)!=0
- && ((pTerm->prereqAll & ~maskSrc) & p->notReady)==0
- && (pTerm->u.pOrInfo->indexable & maskSrc)!=0
- ){
- WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
- WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
- WhereTerm *pOrTerm;
- int flags = WHERE_MULTI_OR;
- double rTotal = 0;
- double nRow = 0;
- Bitmask used = 0;
- WhereBestIdx sBOI;
-
- sBOI = *p;
- sBOI.pOrderBy = 0;
- sBOI.pDistinct = 0;
- sBOI.ppIdxInfo = 0;
- for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
- WHERETRACE(("... Multi-index OR testing for term %d of %d....\n",
- (pOrTerm - pOrWC->a), (pTerm - pWC->a)
- ));
- if( (pOrTerm->eOperator& WO_AND)!=0 ){
- sBOI.pWC = &pOrTerm->u.pAndInfo->wc;
- bestIndex(&sBOI);
- }else if( pOrTerm->leftCursor==iCur ){
- WhereClause tempWC;
- tempWC.pParse = pWC->pParse;
- tempWC.pMaskSet = pWC->pMaskSet;
- tempWC.pOuter = pWC;
- tempWC.op = TK_AND;
- tempWC.a = pOrTerm;
- tempWC.wctrlFlags = 0;
- tempWC.nTerm = 1;
- sBOI.pWC = &tempWC;
- bestIndex(&sBOI);
- }else{
- continue;
- }
- rTotal += sBOI.cost.rCost;
- nRow += sBOI.cost.plan.nRow;
- used |= sBOI.cost.used;
- if( rTotal>=p->cost.rCost ) break;
- }
-
- /* If there is an ORDER BY clause, increase the scan cost to account
- ** for the cost of the sort. */
- if( p->pOrderBy!=0 ){
- WHERETRACE(("... sorting increases OR cost %.9g to %.9g\n",
- rTotal, rTotal+nRow*estLog(nRow)));
- rTotal += nRow*estLog(nRow);
- }
-
- /* If the cost of scanning using this OR term for optimization is
- ** less than the current cost stored in pCost, replace the contents
- ** of pCost. */
- WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n", rTotal, nRow));
- if( rTotal<p->cost.rCost ){
- p->cost.rCost = rTotal;
- p->cost.used = used;
- p->cost.plan.nRow = nRow;
- p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
- p->cost.plan.wsFlags = flags;
- p->cost.plan.u.pTerm = pTerm;
- }
- }
- }
-#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
-}
-
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
** Return TRUE if the WHERE clause term pTerm is of a form where it
@@ -106235,88 +109976,13 @@ static int termCanDriveIndex(
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
+ if( pTerm->u.leftColumn<0 ) return 0;
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
return 1;
}
#endif
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-/*
-** If the query plan for pSrc specified in pCost is a full table scan
-** and indexing is allows (if there is no NOT INDEXED clause) and it
-** possible to construct a transient index that would perform better
-** than a full table scan even when the cost of constructing the index
-** is taken into account, then alter the query plan to use the
-** transient index.
-*/
-static void bestAutomaticIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- double nTableRow; /* Rows in the input table */
- double logN; /* log(nTableRow) */
- double costTempIdx; /* per-query cost of the transient index */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
- WhereTerm *pWCEnd; /* End of pWC->a[] */
- Table *pTable; /* Table tht might be indexed */
-
- if( pParse->nQueryLoop<=(double)1 ){
- /* There is no point in building an automatic index for a single scan */
- return;
- }
- if( (pParse->db->flags & SQLITE_AutoIndex)==0 ){
- /* Automatic indices are disabled at run-time */
- return;
- }
- if( (p->cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0
- && (p->cost.plan.wsFlags & WHERE_COVER_SCAN)==0
- ){
- /* We already have some kind of index in use for this query. */
- return;
- }
- if( pSrc->viaCoroutine ){
- /* Cannot index a co-routine */
- return;
- }
- if( pSrc->notIndexed ){
- /* The NOT INDEXED clause appears in the SQL. */
- return;
- }
- if( pSrc->isCorrelated ){
- /* The source is a correlated sub-query. No point in indexing it. */
- return;
- }
-
- assert( pParse->nQueryLoop >= (double)1 );
- pTable = pSrc->pTab;
- nTableRow = pTable->nRowEst;
- logN = estLog(nTableRow);
- costTempIdx = 2*logN*(nTableRow/pParse->nQueryLoop + 1);
- if( costTempIdx>=p->cost.rCost ){
- /* The cost of creating the transient table would be greater than
- ** doing the full table scan */
- return;
- }
-
- /* Search for any equality comparison term */
- pWCEnd = &pWC->a[pWC->nTerm];
- for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
- if( termCanDriveIndex(pTerm, pSrc, p->notReady) ){
- WHERETRACE(("auto-index reduces cost from %.1f to %.1f\n",
- p->cost.rCost, costTempIdx));
- p->cost.rCost = costTempIdx;
- p->cost.plan.nRow = logN + 1;
- p->cost.plan.wsFlags = WHERE_TEMP_INDEX;
- p->cost.used = pTerm->prereqRight;
- break;
- }
- }
-}
-#else
-# define bestAutomaticIndex(A) /* no-op */
-#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
-
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/*
@@ -106331,23 +109997,24 @@ static void constructAutomaticIndex(
Bitmask notReady, /* Mask of cursors that are not available */
WhereLevel *pLevel /* Write new index here */
){
- int nColumn; /* Number of columns in the constructed index */
+ int nKeyCol; /* Number of columns in the constructed index */
WhereTerm *pTerm; /* A single term of the WHERE clause */
WhereTerm *pWCEnd; /* End of pWC->a[] */
- int nByte; /* Byte of memory needed for pIdx */
Index *pIdx; /* Object describing the transient index */
Vdbe *v; /* Prepared statement under construction */
int addrInit; /* Address of the initialization bypass jump */
Table *pTable; /* The table being indexed */
- KeyInfo *pKeyinfo; /* Key information for the index */
int addrTop; /* Top of the index fill loop */
int regRecord; /* Register holding an index record */
int n; /* Column counter */
int i; /* Loop counter */
int mxBitCol; /* Maximum column in pSrc->colUsed */
CollSeq *pColl; /* Collating sequence to on a column */
+ WhereLoop *pLoop; /* The Loop object */
+ char *zNotUsed; /* Extra space on the end of pIdx */
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
+ u8 sentWarning = 0; /* True if a warnning has been issued */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
@@ -106357,24 +110024,34 @@ static void constructAutomaticIndex(
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
- nColumn = 0;
+ nKeyCol = 0;
pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
+ pLoop = pLevel->pWLoop;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
- Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
+ Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
testcase( iCol==BMS );
testcase( iCol==BMS-1 );
+ if( !sentWarning ){
+ sqlite3_log(SQLITE_WARNING_AUTOINDEX,
+ "automatic index on %s(%s)", pTable->zName,
+ pTable->aCol[iCol].zName);
+ sentWarning = 1;
+ }
if( (idxCols & cMask)==0 ){
- nColumn++;
+ if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;
+ pLoop->aLTerm[nKeyCol++] = pTerm;
idxCols |= cMask;
}
}
}
- assert( nColumn>0 );
- pLevel->plan.nEq = nColumn;
+ assert( nKeyCol>0 );
+ pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol;
+ pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED
+ | WHERE_AUTO_INDEX;
/* Count the number of additional columns needed to create a
** covering index. A "covering index" is an index that contains all
@@ -106384,38 +110061,32 @@ static void constructAutomaticIndex(
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
- extraCols = pSrc->colUsed & (~idxCols | (((Bitmask)1)<<(BMS-1)));
+ extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
- if( extraCols & (((Bitmask)1)<<i) ) nColumn++;
+ if( extraCols & MASKBIT(i) ) nKeyCol++;
}
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
- nColumn += pTable->nCol - BMS + 1;
+ if( pSrc->colUsed & MASKBIT(BMS-1) ){
+ nKeyCol += pTable->nCol - BMS + 1;
}
- pLevel->plan.wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WO_EQ;
+ pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
/* Construct the Index object to describe this index */
- nByte = sizeof(Index);
- nByte += nColumn*sizeof(int); /* Index.aiColumn */
- nByte += nColumn*sizeof(char*); /* Index.azColl */
- nByte += nColumn; /* Index.aSortOrder */
- pIdx = sqlite3DbMallocZero(pParse->db, nByte);
+ pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
if( pIdx==0 ) return;
- pLevel->plan.u.pIdx = pIdx;
- pIdx->azColl = (char**)&pIdx[1];
- pIdx->aiColumn = (int*)&pIdx->azColl[nColumn];
- pIdx->aSortOrder = (u8*)&pIdx->aiColumn[nColumn];
+ pLoop->u.btree.pIndex = pIdx;
pIdx->zName = "auto-index";
- pIdx->nColumn = nColumn;
pIdx->pTable = pTable;
n = 0;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
int iCol = pTerm->u.leftColumn;
- Bitmask cMask = iCol>=BMS ? ((Bitmask)1)<<(BMS-1) : ((Bitmask)1)<<iCol;
+ Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
+ testcase( iCol==BMS-1 );
+ testcase( iCol==BMS );
if( (idxCols & cMask)==0 ){
Expr *pX = pTerm->pExpr;
idxCols |= cMask;
@@ -106426,37 +110097,39 @@ static void constructAutomaticIndex(
}
}
}
- assert( (u32)n==pLevel->plan.nEq );
+ assert( (u32)n==pLoop->u.btree.nEq );
/* Add additional columns needed to make the automatic index into
** a covering index */
for(i=0; i<mxBitCol; i++){
- if( extraCols & (((Bitmask)1)<<i) ){
+ if( extraCols & MASKBIT(i) ){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = "BINARY";
n++;
}
}
- if( pSrc->colUsed & (((Bitmask)1)<<(BMS-1)) ){
+ if( pSrc->colUsed & MASKBIT(BMS-1) ){
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = "BINARY";
n++;
}
}
- assert( n==nColumn );
+ assert( n==nKeyCol );
+ pIdx->aiColumn[n] = -1;
+ pIdx->azColl[n] = "BINARY";
/* Create the automatic index */
- pKeyinfo = sqlite3IndexKeyinfo(pParse, pIdx);
assert( pLevel->iIdxCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
- (char*)pKeyinfo, P4_KEYINFO_HANDOFF);
+ pLevel->iIdxCur = pParse->nTab++;
+ sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
+ sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
@@ -106475,11 +110148,12 @@ static void constructAutomaticIndex(
** responsibility of the caller to eventually release the structure
** by passing the pointer returned by this function to sqlite3_free().
*/
-static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
- Parse *pParse = p->pParse;
- WhereClause *pWC = p->pWC;
- struct SrcList_item *pSrc = p->pSrc;
- ExprList *pOrderBy = p->pOrderBy;
+static sqlite3_index_info *allocateIndexInfo(
+ Parse *pParse,
+ WhereClause *pWC,
+ struct SrcList_item *pSrc,
+ ExprList *pOrderBy
+){
int i, j;
int nTerm;
struct sqlite3_index_constraint *pIdxCons;
@@ -106489,8 +110163,6 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
int nOrderBy;
sqlite3_index_info *pIdxInfo;
- WHERETRACE(("Recomputing index info for %s...\n", pSrc->pTab->zName));
-
/* Count the number of possible WHERE clause constraints referring
** to this virtual table */
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
@@ -106526,7 +110198,6 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
+ sizeof(*pIdxOrderBy)*nOrderBy );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
- /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
return 0;
}
@@ -106582,8 +110253,8 @@ static sqlite3_index_info *allocateIndexInfo(WhereBestIdx *p){
/*
** The table object reference passed as the second argument to this function
** must represent a virtual table. This function invokes the xBestIndex()
-** method of the virtual table with the sqlite3_index_info pointer passed
-** as the argument.
+** method of the virtual table with the sqlite3_index_info object that
+** comes in as the 3rd argument to this function.
**
** If an error occurs, pParse is populated with an error message and a
** non-zero value is returned. Otherwise, 0 is returned and the output
@@ -106598,7 +110269,6 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
int i;
int rc;
- WHERETRACE(("xBestIndex for %s\n", pTab->zName));
TRACE_IDX_INPUTS(p);
rc = pVtab->pModule->xBestIndex(pVtab, p);
TRACE_IDX_OUTPUTS(p);
@@ -106624,209 +110294,10 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
return pParse->nErr;
}
+#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
-/*
-** Compute the best index for a virtual table.
-**
-** The best index is computed by the xBestIndex method of the virtual
-** table module. This routine is really just a wrapper that sets up
-** the sqlite3_index_info structure that is used to communicate with
-** xBestIndex.
-**
-** In a join, this routine might be called multiple times for the
-** same virtual table. The sqlite3_index_info structure is created
-** and initialized on the first invocation and reused on all subsequent
-** invocations. The sqlite3_index_info structure is also used when
-** code is generated to access the virtual table. The whereInfoDelete()
-** routine takes care of freeing the sqlite3_index_info structure after
-** everybody has finished with it.
-*/
-static void bestVirtualIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- Table *pTab = pSrc->pTab;
- sqlite3_index_info *pIdxInfo;
- struct sqlite3_index_constraint *pIdxCons;
- struct sqlite3_index_constraint_usage *pUsage;
- WhereTerm *pTerm;
- int i, j;
- int nOrderBy;
- int bAllowIN; /* Allow IN optimizations */
- double rCost;
-
- /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
- ** malloc in allocateIndexInfo() fails and this function returns leaving
- ** wsFlags in an uninitialized state, the caller may behave unpredictably.
- */
- memset(&p->cost, 0, sizeof(p->cost));
- p->cost.plan.wsFlags = WHERE_VIRTUALTABLE;
-
- /* If the sqlite3_index_info structure has not been previously
- ** allocated and initialized, then allocate and initialize it now.
- */
- pIdxInfo = *p->ppIdxInfo;
- if( pIdxInfo==0 ){
- *p->ppIdxInfo = pIdxInfo = allocateIndexInfo(p);
- }
- if( pIdxInfo==0 ){
- return;
- }
-
- /* At this point, the sqlite3_index_info structure that pIdxInfo points
- ** to will have been initialized, either during the current invocation or
- ** during some prior invocation. Now we just have to customize the
- ** details of pIdxInfo for the current invocation and pass it to
- ** xBestIndex.
- */
-
- /* The module name must be defined. Also, by this point there must
- ** be a pointer to an sqlite3_vtab structure. Otherwise
- ** sqlite3ViewGetColumnNames() would have picked up the error.
- */
- assert( pTab->azModuleArg && pTab->azModuleArg[0] );
- assert( sqlite3GetVTable(pParse->db, pTab) );
-
- /* Try once or twice. On the first attempt, allow IN optimizations.
- ** If an IN optimization is accepted by the virtual table xBestIndex
- ** method, but the pInfo->aConstrainUsage.omit flag is not set, then
- ** the query will not work because it might allow duplicate rows in
- ** output. In that case, run the xBestIndex method a second time
- ** without the IN constraints. Usually this loop only runs once.
- ** The loop will exit using a "break" statement.
- */
- for(bAllowIN=1; 1; bAllowIN--){
- assert( bAllowIN==0 || bAllowIN==1 );
-
- /* Set the aConstraint[].usable fields and initialize all
- ** output variables to zero.
- **
- ** aConstraint[].usable is true for constraints where the right-hand
- ** side contains only references to tables to the left of the current
- ** table. In other words, if the constraint is of the form:
- **
- ** column = expr
- **
- ** and we are evaluating a join, then the constraint on column is
- ** only valid if all tables referenced in expr occur to the left
- ** of the table containing column.
- **
- ** The aConstraints[] array contains entries for all constraints
- ** on the current table. That way we only have to compute it once
- ** even though we might try to pick the best index multiple times.
- ** For each attempt at picking an index, the order of tables in the
- ** join might be different so we have to recompute the usable flag
- ** each time.
- */
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- pUsage = pIdxInfo->aConstraintUsage;
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
- j = pIdxCons->iTermOffset;
- pTerm = &pWC->a[j];
- if( (pTerm->prereqRight&p->notReady)==0
- && (bAllowIN || (pTerm->eOperator & WO_IN)==0)
- ){
- pIdxCons->usable = 1;
- }else{
- pIdxCons->usable = 0;
- }
- }
- memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
- if( pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- }
- pIdxInfo->idxStr = 0;
- pIdxInfo->idxNum = 0;
- pIdxInfo->needToFreeIdxStr = 0;
- pIdxInfo->orderByConsumed = 0;
- /* ((double)2) In case of SQLITE_OMIT_FLOATING_POINT... */
- pIdxInfo->estimatedCost = SQLITE_BIG_DBL / ((double)2);
- nOrderBy = pIdxInfo->nOrderBy;
- if( !p->pOrderBy ){
- pIdxInfo->nOrderBy = 0;
- }
-
- if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
- return;
- }
-
- pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
- for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
- if( pUsage[i].argvIndex>0 ){
- j = pIdxCons->iTermOffset;
- pTerm = &pWC->a[j];
- p->cost.used |= pTerm->prereqRight;
- if( (pTerm->eOperator & WO_IN)!=0 ){
- if( pUsage[i].omit==0 ){
- /* Do not attempt to use an IN constraint if the virtual table
- ** says that the equivalent EQ constraint cannot be safely omitted.
- ** If we do attempt to use such a constraint, some rows might be
- ** repeated in the output. */
- break;
- }
- /* A virtual table that is constrained by an IN clause may not
- ** consume the ORDER BY clause because (1) the order of IN terms
- ** is not necessarily related to the order of output terms and
- ** (2) Multiple outputs from a single IN value will not merge
- ** together. */
- pIdxInfo->orderByConsumed = 0;
- }
- }
- }
- if( i>=pIdxInfo->nConstraint ) break;
- }
-
- /* The orderByConsumed signal is only valid if all outer loops collectively
- ** generate just a single row of output.
- */
- if( pIdxInfo->orderByConsumed ){
- for(i=0; i<p->i; i++){
- if( (p->aLevel[i].plan.wsFlags & WHERE_UNIQUE)==0 ){
- pIdxInfo->orderByConsumed = 0;
- }
- }
- }
-
- /* If there is an ORDER BY clause, and the selected virtual table index
- ** does not satisfy it, increase the cost of the scan accordingly. This
- ** matches the processing for non-virtual tables in bestBtreeIndex().
- */
- rCost = pIdxInfo->estimatedCost;
- if( p->pOrderBy && pIdxInfo->orderByConsumed==0 ){
- rCost += estLog(rCost)*rCost;
- }
-
- /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the
- ** inital value of lowestCost in this loop. If it is, then the
- ** (cost<lowestCost) test below will never be true.
- **
- ** Use "(double)2" instead of "2.0" in case OMIT_FLOATING_POINT
- ** is defined.
- */
- if( (SQLITE_BIG_DBL/((double)2))<rCost ){
- p->cost.rCost = (SQLITE_BIG_DBL/((double)2));
- }else{
- p->cost.rCost = rCost;
- }
- p->cost.plan.u.pVtabIdx = pIdxInfo;
- if( pIdxInfo->orderByConsumed ){
- p->cost.plan.wsFlags |= WHERE_ORDERED;
- p->cost.plan.nOBSat = nOrderBy;
- }else{
- p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
- }
- p->cost.plan.nEq = 0;
- pIdxInfo->nOrderBy = nOrderBy;
-
- /* Try to find a more efficient access pattern by using multiple indexes
- ** to optimize an OR expression within the WHERE clause.
- */
- bestOrClauseIndex(p);
-}
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the location of a particular key among all keys in an
** index. Store the results in aStat as follows:
@@ -106836,140 +110307,75 @@ static void bestVirtualIndex(WhereBestIdx *p){
**
** Return SQLITE_OK on success.
*/
-static int whereKeyStats(
+static void whereKeyStats(
Parse *pParse, /* Database connection */
Index *pIdx, /* Index to consider domain of */
- sqlite3_value *pVal, /* Value to consider */
+ UnpackedRecord *pRec, /* Vector of values to consider */
int roundUp, /* Round up if true. Round down if false */
tRowcnt *aStat /* OUT: stats written here */
){
- tRowcnt n;
- IndexSample *aSample;
- int i, eType;
- int isEq = 0;
- i64 v;
- double r, rS;
+ IndexSample *aSample = pIdx->aSample;
+ int iCol; /* Index of required stats in anEq[] etc. */
+ int iMin = 0; /* Smallest sample not yet tested */
+ int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */
+ int iTest; /* Next sample to test */
+ int res; /* Result of comparison operation */
- assert( roundUp==0 || roundUp==1 );
+#ifndef SQLITE_DEBUG
+ UNUSED_PARAMETER( pParse );
+#endif
+ assert( pRec!=0 );
+ iCol = pRec->nField - 1;
assert( pIdx->nSample>0 );
- if( pVal==0 ) return SQLITE_ERROR;
- n = pIdx->aiRowEst[0];
- aSample = pIdx->aSample;
- eType = sqlite3_value_type(pVal);
-
- if( eType==SQLITE_INTEGER ){
- v = sqlite3_value_int64(pVal);
- r = (i64)v;
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_NULL ) continue;
- if( aSample[i].eType>=SQLITE_TEXT ) break;
- if( aSample[i].eType==SQLITE_INTEGER ){
- if( aSample[i].u.i>=v ){
- isEq = aSample[i].u.i==v;
- break;
- }
- }else{
- assert( aSample[i].eType==SQLITE_FLOAT );
- if( aSample[i].u.r>=r ){
- isEq = aSample[i].u.r==r;
- break;
- }
- }
- }
- }else if( eType==SQLITE_FLOAT ){
- r = sqlite3_value_double(pVal);
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_NULL ) continue;
- if( aSample[i].eType>=SQLITE_TEXT ) break;
- if( aSample[i].eType==SQLITE_FLOAT ){
- rS = aSample[i].u.r;
- }else{
- rS = aSample[i].u.i;
- }
- if( rS>=r ){
- isEq = rS==r;
- break;
- }
+ assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
+ do{
+ iTest = (iMin+i)/2;
+ res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);
+ if( res<0 ){
+ iMin = iTest+1;
+ }else{
+ i = iTest;
}
- }else if( eType==SQLITE_NULL ){
- i = 0;
- if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
+ }while( res && iMin<i );
+
+#ifdef SQLITE_DEBUG
+ /* The following assert statements check that the binary search code
+ ** above found the right answer. This block serves no purpose other
+ ** than to invoke the asserts. */
+ if( res==0 ){
+ /* If (res==0) is true, then sample $i must be equal to pRec */
+ assert( i<pIdx->nSample );
+ assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
+ || pParse->db->mallocFailed );
}else{
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
- for(i=0; i<pIdx->nSample; i++){
- if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
- break;
- }
- }
- if( i<pIdx->nSample ){
- sqlite3 *db = pParse->db;
- CollSeq *pColl;
- const u8 *z;
- if( eType==SQLITE_BLOB ){
- z = (const u8 *)sqlite3_value_blob(pVal);
- pColl = db->pDfltColl;
- assert( pColl->enc==SQLITE_UTF8 );
- }else{
- pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl);
- if( pColl==0 ){
- return SQLITE_ERROR;
- }
- z = (const u8 *)sqlite3ValueText(pVal, pColl->enc);
- if( !z ){
- return SQLITE_NOMEM;
- }
- assert( z && pColl && pColl->xCmp );
- }
- n = sqlite3ValueBytes(pVal, pColl->enc);
-
- for(; i<pIdx->nSample; i++){
- int c;
- int eSampletype = aSample[i].eType;
- if( eSampletype<eType ) continue;
- if( eSampletype!=eType ) break;
-#ifndef SQLITE_OMIT_UTF16
- if( pColl->enc!=SQLITE_UTF8 ){
- int nSample;
- char *zSample = sqlite3Utf8to16(
- db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
- );
- if( !zSample ){
- assert( db->mallocFailed );
- return SQLITE_NOMEM;
- }
- c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z);
- sqlite3DbFree(db, zSample);
- }else
-#endif
- {
- c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
- }
- if( c>=0 ){
- if( c==0 ) isEq = 1;
- break;
- }
- }
- }
+ /* Otherwise, pRec must be smaller than sample $i and larger than
+ ** sample ($i-1). */
+ assert( i==pIdx->nSample
+ || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+ || pParse->db->mallocFailed );
+ assert( i==0
+ || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+ || pParse->db->mallocFailed );
}
+#endif /* ifdef SQLITE_DEBUG */
/* At this point, aSample[i] is the first sample that is greater than
** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
- ** than pVal. If aSample[i]==pVal, then isEq==1.
+ ** than pVal. If aSample[i]==pVal, then res==0.
*/
- if( isEq ){
- assert( i<pIdx->nSample );
- aStat[0] = aSample[i].nLt;
- aStat[1] = aSample[i].nEq;
+ if( res==0 ){
+ aStat[0] = aSample[i].anLt[iCol];
+ aStat[1] = aSample[i].anEq[iCol];
}else{
tRowcnt iLower, iUpper, iGap;
if( i==0 ){
iLower = 0;
- iUpper = aSample[0].nLt;
+ iUpper = aSample[0].anLt[iCol];
}else{
- iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
- iLower = aSample[i-1].nEq + aSample[i-1].nLt;
+ iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol];
+ iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
}
- aStat[1] = pIdx->avgEq;
+ aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
if( iLower>=iUpper ){
iGap = 0;
}else{
@@ -106982,44 +110388,8 @@ static int whereKeyStats(
}
aStat[0] = iLower + iGap;
}
- return SQLITE_OK;
-}
-#endif /* SQLITE_ENABLE_STAT3 */
-
-/*
-** If expression pExpr represents a literal value, set *pp to point to
-** an sqlite3_value structure containing the same value, with affinity
-** aff applied to it, before returning. It is the responsibility of the
-** caller to eventually release this structure by passing it to
-** sqlite3ValueFree().
-**
-** If the current parse is a recompile (sqlite3Reprepare()) and pExpr
-** is an SQL variable that currently has a non-NULL value bound to it,
-** create an sqlite3_value structure containing this value, again with
-** affinity aff applied to it, instead.
-**
-** If neither of the above apply, set *pp to NULL.
-**
-** If an error occurs, return an error code. Otherwise, SQLITE_OK.
-*/
-#ifdef SQLITE_ENABLE_STAT3
-static int valueFromExpr(
- Parse *pParse,
- Expr *pExpr,
- u8 aff,
- sqlite3_value **pp
-){
- if( pExpr->op==TK_VARIABLE
- || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
- ){
- int iVar = pExpr->iColumn;
- sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
- *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
- return SQLITE_OK;
- }
- return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
}
-#endif
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** This function is used to estimate the number of rows that will be visited
@@ -107036,97 +110406,161 @@ static int valueFromExpr(
** If either of the upper or lower bound is not present, then NULL is passed in
** place of the corresponding WhereTerm.
**
-** The nEq parameter is passed the index of the index column subject to the
-** range constraint. Or, equivalently, the number of equality constraints
-** optimized by the proposed index scan. For example, assuming index p is
-** on t1(a, b), and the SQL query is:
+** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index
+** column subject to the range constraint. Or, equivalently, the number of
+** equality constraints optimized by the proposed index scan. For example,
+** assuming index p is on t1(a, b), and the SQL query is:
**
** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ...
**
-** then nEq should be passed the value 1 (as the range restricted column,
-** b, is the second left-most column of the index). Or, if the query is:
+** then nEq is set to 1 (as the range restricted column, b, is the second
+** left-most column of the index). Or, if the query is:
**
** ... FROM t1 WHERE a > ? AND a < ? ...
**
-** then nEq should be passed 0.
+** then nEq is set to 0.
**
-** The returned value is an integer divisor to reduce the estimated
-** search space. A return value of 1 means that range constraints are
-** no help at all. A return value of 2 means range constraints are
-** expected to reduce the search space by half. And so forth...
-**
-** In the absence of sqlite_stat3 ANALYZE data, each range inequality
-** reduces the search space by a factor of 4. Hence a single constraint (x>?)
-** results in a return of 4 and a range constraint (x>? AND x<?) results
-** in a return of 16.
+** When this function is called, *pnOut is set to the sqlite3LogEst() of the
+** number of rows that the index scan is expected to visit without
+** considering the range constraints. If nEq is 0, this is the number of
+** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
+** to account for the range contraints pLower and pUpper.
+**
+** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
+** used, each range inequality reduces the search space by a factor of 4.
+** Hence a pair of constraints (x>? AND x<?) reduces the expected number of
+** rows visited by a factor of 16.
*/
static int whereRangeScanEst(
Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index containing the range-compared column; "x" */
- int nEq, /* index into p->aCol[] of the range-compared column */
+ WhereLoopBuilder *pBuilder,
WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
- double *pRangeDiv /* OUT: Reduce search space by this divisor */
+ WhereLoop *pLoop /* Modify the .nOut and maybe .rRun fields */
){
int rc = SQLITE_OK;
+ int nOut = pLoop->nOut;
+ LogEst nNew;
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ Index *p = pLoop->u.btree.pIndex;
+ int nEq = pLoop->u.btree.nEq;
- if( nEq==0 && p->nSample ){
- sqlite3_value *pRangeVal;
- tRowcnt iLower = 0;
- tRowcnt iUpper = p->aiRowEst[0];
+ if( p->nSample>0
+ && nEq==pBuilder->nRecValid
+ && nEq<p->nSampleCol
+ && OptimizationEnabled(pParse->db, SQLITE_Stat3)
+ ){
+ UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
- u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
+ u8 aff;
+
+ /* Variable iLower will be set to the estimate of the number of rows in
+ ** the index that are less than the lower bound of the range query. The
+ ** lower bound being the concatenation of $P and $L, where $P is the
+ ** key-prefix formed by the nEq values matched against the nEq left-most
+ ** columns of the index, and $L is the value in pLower.
+ **
+ ** Or, if pLower is NULL or $L cannot be extracted from it (because it
+ ** is not a simple variable or literal value), the lower bound of the
+ ** range is $P. Due to a quirk in the way whereKeyStats() works, even
+ ** if $L is available, whereKeyStats() is called for both ($P) and
+ ** ($P:$L) and the larger of the two returned values used.
+ **
+ ** Similarly, iUpper is to be set to the estimate of the number of rows
+ ** less than the upper bound of the range query. Where the upper bound
+ ** is either ($P) or ($P:$U). Again, even if $U is available, both values
+ ** of iUpper are requested of whereKeyStats() and the smaller used.
+ */
+ tRowcnt iLower;
+ tRowcnt iUpper;
+
+ if( nEq==p->nKeyCol ){
+ aff = SQLITE_AFF_INTEGER;
+ }else{
+ aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
+ }
+ /* Determine iLower and iUpper using ($P) only. */
+ if( nEq==0 ){
+ iLower = 0;
+ iUpper = p->aiRowEst[0];
+ }else{
+ /* Note: this call could be optimized away - since the same values must
+ ** have been requested when testing key $P in whereEqualScanEst(). */
+ whereKeyStats(pParse, p, pRec, 0, a);
+ iLower = a[0];
+ iUpper = a[0] + a[1];
+ }
+ /* If possible, improve on the iLower estimate using ($P:$L). */
if( pLower ){
+ int bOk; /* True if value is extracted from pExpr */
Expr *pExpr = pLower->pExpr->pRight;
- rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
- if( rc==SQLITE_OK
- && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
- ){
- iLower = a[0];
- if( (pLower->eOperator & WO_GT)!=0 ) iLower += a[1];
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+ if( rc==SQLITE_OK && bOk ){
+ tRowcnt iNew;
+ whereKeyStats(pParse, p, pRec, 0, a);
+ iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
+ if( iNew>iLower ) iLower = iNew;
+ nOut--;
}
- sqlite3ValueFree(pRangeVal);
}
- if( rc==SQLITE_OK && pUpper ){
+
+ /* If possible, improve on the iUpper estimate using ($P:$U). */
+ if( pUpper ){
+ int bOk; /* True if value is extracted from pExpr */
Expr *pExpr = pUpper->pExpr->pRight;
- rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
- if( rc==SQLITE_OK
- && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
- ){
- iUpper = a[0];
- if( (pUpper->eOperator & WO_LE)!=0 ) iUpper += a[1];
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
+ if( rc==SQLITE_OK && bOk ){
+ tRowcnt iNew;
+ whereKeyStats(pParse, p, pRec, 1, a);
+ iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
+ if( iNew<iUpper ) iUpper = iNew;
+ nOut--;
}
- sqlite3ValueFree(pRangeVal);
}
+
+ pBuilder->pRec = pRec;
if( rc==SQLITE_OK ){
- if( iUpper<=iLower ){
- *pRangeDiv = (double)p->aiRowEst[0];
+ if( iUpper>iLower ){
+ nNew = sqlite3LogEst(iUpper - iLower);
}else{
- *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
+ nNew = 10; assert( 10==sqlite3LogEst(2) );
+ }
+ if( nNew<nOut ){
+ nOut = nNew;
}
- WHERETRACE(("range scan regions: %u..%u div=%g\n",
- (u32)iLower, (u32)iUpper, *pRangeDiv));
+ pLoop->nOut = (LogEst)nOut;
+ WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
+ (u32)iLower, (u32)iUpper, nOut));
return SQLITE_OK;
}
}
#else
UNUSED_PARAMETER(pParse);
- UNUSED_PARAMETER(p);
- UNUSED_PARAMETER(nEq);
+ UNUSED_PARAMETER(pBuilder);
#endif
assert( pLower || pUpper );
- *pRangeDiv = (double)1;
- if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
- if( pUpper ) *pRangeDiv *= (double)4;
+ /* TUNING: Each inequality constraint reduces the search space 4-fold.
+ ** A BETWEEN operator, therefore, reduces the search space 16-fold */
+ nNew = nOut;
+ if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){
+ nNew -= 20; assert( 20==sqlite3LogEst(4) );
+ nOut--;
+ }
+ if( pUpper ){
+ nNew -= 20; assert( 20==sqlite3LogEst(4) );
+ nOut--;
+ }
+ if( nNew<10 ) nNew = 10;
+ if( nNew<nOut ) nOut = nNew;
+ pLoop->nOut = (LogEst)nOut;
return rc;
}
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in
@@ -107146,37 +110580,53 @@ static int whereRangeScanEst(
*/
static int whereEqualScanEst(
Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
+ WhereLoopBuilder *pBuilder,
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
- double *pnRow /* Write the revised row estimate here */
+ tRowcnt *pnRow /* Write the revised row estimate here */
){
- sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
+ Index *p = pBuilder->pNew->u.btree.pIndex;
+ int nEq = pBuilder->pNew->u.btree.nEq;
+ UnpackedRecord *pRec = pBuilder->pRec;
u8 aff; /* Column affinity */
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
+ int bOk;
+ assert( nEq>=1 );
+ assert( nEq<=(p->nKeyCol+1) );
assert( p->aSample!=0 );
assert( p->nSample>0 );
- aff = p->pTable->aCol[p->aiColumn[0]].affinity;
- if( pExpr ){
- rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
- if( rc ) goto whereEqualScanEst_cancel;
- }else{
- pRhs = sqlite3ValueNew(pParse->db);
+ assert( pBuilder->nRecValid<nEq );
+
+ /* If values are not available for all fields of the index to the left
+ ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */
+ if( pBuilder->nRecValid<(nEq-1) ){
+ return SQLITE_NOTFOUND;
}
- if( pRhs==0 ) return SQLITE_NOTFOUND;
- rc = whereKeyStats(pParse, p, pRhs, 0, a);
- if( rc==SQLITE_OK ){
- WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
- *pnRow = a[1];
+
+ /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
+ ** below would return the same value. */
+ if( nEq>p->nKeyCol ){
+ *pnRow = 1;
+ return SQLITE_OK;
}
-whereEqualScanEst_cancel:
- sqlite3ValueFree(pRhs);
+
+ aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
+ pBuilder->pRec = pRec;
+ if( rc!=SQLITE_OK ) return rc;
+ if( bOk==0 ) return SQLITE_NOTFOUND;
+ pBuilder->nRecValid = nEq;
+
+ whereKeyStats(pParse, p, pRec, 0, a);
+ WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
+ *pnRow = a[1];
+
return rc;
}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
-#ifdef SQLITE_ENABLE_STAT3
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/*
** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator
@@ -107195,902 +110645,34 @@ whereEqualScanEst_cancel:
*/
static int whereInScanEst(
Parse *pParse, /* Parsing & code generating context */
- Index *p, /* The index whose left-most column is pTerm */
+ WhereLoopBuilder *pBuilder,
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
- double *pnRow /* Write the revised row estimate here */
+ tRowcnt *pnRow /* Write the revised row estimate here */
){
- int rc = SQLITE_OK; /* Subfunction return code */
- double nEst; /* Number of rows for a single term */
- double nRowEst = (double)0; /* New estimate of the number of rows */
- int i; /* Loop counter */
+ Index *p = pBuilder->pNew->u.btree.pIndex;
+ int nRecValid = pBuilder->nRecValid;
+ int rc = SQLITE_OK; /* Subfunction return code */
+ tRowcnt nEst; /* Number of rows for a single term */
+ tRowcnt nRowEst = 0; /* New estimate of the number of rows */
+ int i; /* Loop counter */
assert( p->aSample!=0 );
for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
nEst = p->aiRowEst[0];
- rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
+ rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst);
nRowEst += nEst;
+ pBuilder->nRecValid = nRecValid;
}
+
if( rc==SQLITE_OK ){
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
*pnRow = nRowEst;
- WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
+ WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst));
}
+ assert( pBuilder->nRecValid==nRecValid );
return rc;
}
-#endif /* defined(SQLITE_ENABLE_STAT3) */
-
-/*
-** Check to see if column iCol of the table with cursor iTab will appear
-** in sorted order according to the current query plan.
-**
-** Return values:
-**
-** 0 iCol is not ordered
-** 1 iCol has only a single value
-** 2 iCol is in ASC order
-** 3 iCol is in DESC order
-*/
-static int isOrderedColumn(
- WhereBestIdx *p,
- int iTab,
- int iCol
-){
- int i, j;
- WhereLevel *pLevel = &p->aLevel[p->i-1];
- Index *pIdx;
- u8 sortOrder;
- for(i=p->i-1; i>=0; i--, pLevel--){
- if( pLevel->iTabCur!=iTab ) continue;
- if( (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
- return 1;
- }
- assert( (pLevel->plan.wsFlags & WHERE_ORDERED)!=0 );
- if( (pIdx = pLevel->plan.u.pIdx)!=0 ){
- if( iCol<0 ){
- sortOrder = 0;
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }else{
- int n = pIdx->nColumn;
- for(j=0; j<n; j++){
- if( iCol==pIdx->aiColumn[j] ) break;
- }
- if( j>=n ) return 0;
- sortOrder = pIdx->aSortOrder[j];
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }
- }else{
- if( iCol!=(-1) ) return 0;
- sortOrder = 0;
- testcase( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 );
- }
- if( (pLevel->plan.wsFlags & WHERE_REVERSE)!=0 ){
- assert( sortOrder==0 || sortOrder==1 );
- testcase( sortOrder==1 );
- sortOrder = 1 - sortOrder;
- }
- return sortOrder+2;
- }
- return 0;
-}
-
-/*
-** This routine decides if pIdx can be used to satisfy the ORDER BY
-** clause, either in whole or in part. The return value is the
-** cumulative number of terms in the ORDER BY clause that are satisfied
-** by the index pIdx and other indices in outer loops.
-**
-** The table being queried has a cursor number of "base". pIdx is the
-** index that is postulated for use to access the table.
-**
-** The *pbRev value is set to 0 order 1 depending on whether or not
-** pIdx should be run in the forward order or in reverse order.
-*/
-static int isSortingIndex(
- WhereBestIdx *p, /* Best index search context */
- Index *pIdx, /* The index we are testing */
- int base, /* Cursor number for the table to be sorted */
- int *pbRev, /* Set to 1 for reverse-order scan of pIdx */
- int *pbObUnique /* ORDER BY column values will different in every row */
-){
- int i; /* Number of pIdx terms used */
- int j; /* Number of ORDER BY terms satisfied */
- int sortOrder = 2; /* 0: forward. 1: backward. 2: unknown */
- int nTerm; /* Number of ORDER BY terms */
- struct ExprList_item *pOBItem;/* A term of the ORDER BY clause */
- Table *pTab = pIdx->pTable; /* Table that owns index pIdx */
- ExprList *pOrderBy; /* The ORDER BY clause */
- Parse *pParse = p->pParse; /* Parser context */
- sqlite3 *db = pParse->db; /* Database connection */
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
- int seenRowid = 0; /* True if an ORDER BY rowid term is seen */
- int uniqueNotNull; /* pIdx is UNIQUE with all terms are NOT NULL */
- int outerObUnique; /* Outer loops generate different values in
- ** every row for the ORDER BY columns */
-
- if( p->i==0 ){
- nPriorSat = 0;
- outerObUnique = 1;
- }else{
- u32 wsFlags = p->aLevel[p->i-1].plan.wsFlags;
- nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
- if( (wsFlags & WHERE_ORDERED)==0 ){
- /* This loop cannot be ordered unless the next outer loop is
- ** also ordered */
- return nPriorSat;
- }
- if( OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ){
- /* Only look at the outer-most loop if the OrderByIdxJoin
- ** optimization is disabled */
- return nPriorSat;
- }
- testcase( wsFlags & WHERE_OB_UNIQUE );
- testcase( wsFlags & WHERE_ALL_UNIQUE );
- outerObUnique = (wsFlags & (WHERE_OB_UNIQUE|WHERE_ALL_UNIQUE))!=0;
- }
- pOrderBy = p->pOrderBy;
- assert( pOrderBy!=0 );
- if( pIdx->bUnordered ){
- /* Hash indices (indicated by the "unordered" tag on sqlite_stat1) cannot
- ** be used for sorting */
- return nPriorSat;
- }
- nTerm = pOrderBy->nExpr;
- uniqueNotNull = pIdx->onError!=OE_None;
- assert( nTerm>0 );
-
- /* Argument pIdx must either point to a 'real' named index structure,
- ** or an index structure allocated on the stack by bestBtreeIndex() to
- ** represent the rowid index that is part of every table. */
- assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) );
-
- /* Match terms of the ORDER BY clause against columns of
- ** the index.
- **
- ** Note that indices have pIdx->nColumn regular columns plus
- ** one additional column containing the rowid. The rowid column
- ** of the index is also allowed to match against the ORDER BY
- ** clause.
- */
- j = nPriorSat;
- for(i=0,pOBItem=&pOrderBy->a[j]; j<nTerm && i<=pIdx->nColumn; i++){
- Expr *pOBExpr; /* The expression of the ORDER BY pOBItem */
- CollSeq *pColl; /* The collating sequence of pOBExpr */
- int termSortOrder; /* Sort order for this term */
- int iColumn; /* The i-th column of the index. -1 for rowid */
- int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */
- int isEq; /* Subject to an == or IS NULL constraint */
- int isMatch; /* ORDER BY term matches the index term */
- const char *zColl; /* Name of collating sequence for i-th index term */
- WhereTerm *pConstraint; /* A constraint in the WHERE clause */
-
- /* If the next term of the ORDER BY clause refers to anything other than
- ** a column in the "base" table, then this index will not be of any
- ** further use in handling the ORDER BY. */
- pOBExpr = sqlite3ExprSkipCollate(pOBItem->pExpr);
- if( pOBExpr->op!=TK_COLUMN || pOBExpr->iTable!=base ){
- break;
- }
-
- /* Find column number and collating sequence for the next entry
- ** in the index */
- if( pIdx->zName && i<pIdx->nColumn ){
- iColumn = pIdx->aiColumn[i];
- if( iColumn==pIdx->pTable->iPKey ){
- iColumn = -1;
- }
- iSortOrder = pIdx->aSortOrder[i];
- zColl = pIdx->azColl[i];
- assert( zColl!=0 );
- }else{
- iColumn = -1;
- iSortOrder = 0;
- zColl = 0;
- }
-
- /* Check to see if the column number and collating sequence of the
- ** index match the column number and collating sequence of the ORDER BY
- ** clause entry. Set isMatch to 1 if they both match. */
- if( pOBExpr->iColumn==iColumn ){
- if( zColl ){
- pColl = sqlite3ExprCollSeq(pParse, pOBItem->pExpr);
- if( !pColl ) pColl = db->pDfltColl;
- isMatch = sqlite3StrICmp(pColl->zName, zColl)==0;
- }else{
- isMatch = 1;
- }
- }else{
- isMatch = 0;
- }
-
- /* termSortOrder is 0 or 1 for whether or not the access loop should
- ** run forward or backwards (respectively) in order to satisfy this
- ** term of the ORDER BY clause. */
- assert( pOBItem->sortOrder==0 || pOBItem->sortOrder==1 );
- assert( iSortOrder==0 || iSortOrder==1 );
- termSortOrder = iSortOrder ^ pOBItem->sortOrder;
-
- /* If X is the column in the index and ORDER BY clause, check to see
- ** if there are any X= or X IS NULL constraints in the WHERE clause. */
- pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
- WO_EQ|WO_ISNULL|WO_IN, pIdx);
- if( pConstraint==0 ){
- isEq = 0;
- }else if( (pConstraint->eOperator & WO_IN)!=0 ){
- isEq = 0;
- }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){
- uniqueNotNull = 0;
- isEq = 1; /* "X IS NULL" means X has only a single value */
- }else if( pConstraint->prereqRight==0 ){
- isEq = 1; /* Constraint "X=constant" means X has only a single value */
- }else{
- Expr *pRight = pConstraint->pExpr->pRight;
- if( pRight->op==TK_COLUMN ){
- WHERETRACE((" .. isOrderedColumn(tab=%d,col=%d)",
- pRight->iTable, pRight->iColumn));
- isEq = isOrderedColumn(p, pRight->iTable, pRight->iColumn);
- WHERETRACE((" -> isEq=%d\n", isEq));
-
- /* If the constraint is of the form X=Y where Y is an ordered value
- ** in an outer loop, then make sure the sort order of Y matches the
- ** sort order required for X. */
- if( isMatch && isEq>=2 && isEq!=pOBItem->sortOrder+2 ){
- testcase( isEq==2 );
- testcase( isEq==3 );
- break;
- }
- }else{
- isEq = 0; /* "X=expr" places no ordering constraints on X */
- }
- }
- if( !isMatch ){
- if( isEq==0 ){
- break;
- }else{
- continue;
- }
- }else if( isEq!=1 ){
- if( sortOrder==2 ){
- sortOrder = termSortOrder;
- }else if( termSortOrder!=sortOrder ){
- break;
- }
- }
- j++;
- pOBItem++;
- if( iColumn<0 ){
- seenRowid = 1;
- break;
- }else if( pTab->aCol[iColumn].notNull==0 && isEq!=1 ){
- testcase( isEq==0 );
- testcase( isEq==2 );
- testcase( isEq==3 );
- uniqueNotNull = 0;
- }
- }
- if( seenRowid ){
- uniqueNotNull = 1;
- }else if( uniqueNotNull==0 || i<pIdx->nColumn ){
- uniqueNotNull = 0;
- }
-
- /* If we have not found at least one ORDER BY term that matches the
- ** index, then show no progress. */
- if( pOBItem==&pOrderBy->a[nPriorSat] ) return nPriorSat;
-
- /* Either the outer queries must generate rows where there are no two
- ** rows with the same values in all ORDER BY columns, or else this
- ** loop must generate just a single row of output. Example: Suppose
- ** the outer loops generate A=1 and A=1, and this loop generates B=3
- ** and B=4. Then without the following test, ORDER BY A,B would
- ** generate the wrong order output: 1,3 1,4 1,3 1,4
- */
- if( outerObUnique==0 && uniqueNotNull==0 ) return nPriorSat;
- *pbObUnique = uniqueNotNull;
-
- /* Return the necessary scan order back to the caller */
- *pbRev = sortOrder & 1;
-
- /* If there was an "ORDER BY rowid" term that matched, or it is only
- ** possible for a single row from this table to match, then skip over
- ** any additional ORDER BY terms dealing with this table.
- */
- if( uniqueNotNull ){
- /* Advance j over additional ORDER BY terms associated with base */
- WhereMaskSet *pMS = p->pWC->pMaskSet;
- Bitmask m = ~getMask(pMS, base);
- while( j<nTerm && (exprTableUsage(pMS, pOrderBy->a[j].pExpr)&m)==0 ){
- j++;
- }
- }
- return j;
-}
-
-/*
-** Find the best query plan for accessing a particular table. Write the
-** best query plan and its cost into the p->cost.
-**
-** The lowest cost plan wins. The cost is an estimate of the amount of
-** CPU and disk I/O needed to process the requested result.
-** Factors that influence cost include:
-**
-** * The estimated number of rows that will be retrieved. (The
-** fewer the better.)
-**
-** * Whether or not sorting must occur.
-**
-** * Whether or not there must be separate lookups in the
-** index and in the main table.
-**
-** If there was an INDEXED BY clause (pSrc->pIndex) attached to the table in
-** the SQL statement, then this function only considers plans using the
-** named index. If no such plan is found, then the returned cost is
-** SQLITE_BIG_DBL. If a plan is found that uses the named index,
-** then the cost is calculated in the usual way.
-**
-** If a NOT INDEXED clause was attached to the table
-** in the SELECT statement, then no indexes are considered. However, the
-** selected plan may still take advantage of the built-in rowid primary key
-** index.
-*/
-static void bestBtreeIndex(WhereBestIdx *p){
- Parse *pParse = p->pParse; /* The parsing context */
- WhereClause *pWC = p->pWC; /* The WHERE clause */
- struct SrcList_item *pSrc = p->pSrc; /* The FROM clause term to search */
- int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
- Index *pProbe; /* An index we are evaluating */
- Index *pIdx; /* Copy of pProbe, or zero for IPK index */
- int eqTermMask; /* Current mask of valid equality operators */
- int idxEqTermMask; /* Index mask of valid equality operators */
- Index sPk; /* A fake index object for the primary key */
- tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
- int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
- int wsFlagMask; /* Allowed flags in p->cost.plan.wsFlag */
- int nPriorSat; /* ORDER BY terms satisfied by outer loops */
- int nOrderBy; /* Number of ORDER BY terms */
- char bSortInit; /* Initializer for bSort in inner loop */
- char bDistInit; /* Initializer for bDist in inner loop */
-
-
- /* Initialize the cost to a worst-case value */
- memset(&p->cost, 0, sizeof(p->cost));
- p->cost.rCost = SQLITE_BIG_DBL;
-
- /* If the pSrc table is the right table of a LEFT JOIN then we may not
- ** use an index to satisfy IS NULL constraints on that table. This is
- ** because columns might end up being NULL if the table does not match -
- ** a circumstance which the index cannot help us discover. Ticket #2177.
- */
- if( pSrc->jointype & JT_LEFT ){
- idxEqTermMask = WO_EQ|WO_IN;
- }else{
- idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL;
- }
-
- if( pSrc->pIndex ){
- /* An INDEXED BY clause specifies a particular index to use */
- pIdx = pProbe = pSrc->pIndex;
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }else{
- /* There is no INDEXED BY clause. Create a fake Index object in local
- ** variable sPk to represent the rowid primary key index. Make this
- ** fake index the first in a chain of Index objects with all of the real
- ** indices to follow */
- Index *pFirst; /* First of real indices on the table */
- memset(&sPk, 0, sizeof(Index));
- sPk.nColumn = 1;
- sPk.aiColumn = &aiColumnPk;
- sPk.aiRowEst = aiRowEstPk;
- sPk.onError = OE_Replace;
- sPk.pTable = pSrc->pTab;
- aiRowEstPk[0] = pSrc->pTab->nRowEst;
- aiRowEstPk[1] = 1;
- pFirst = pSrc->pTab->pIndex;
- if( pSrc->notIndexed==0 ){
- /* The real indices of the table are only considered if the
- ** NOT INDEXED qualifier is omitted from the FROM clause */
- sPk.pNext = pFirst;
- }
- pProbe = &sPk;
- wsFlagMask = ~(
- WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE
- );
- eqTermMask = WO_EQ|WO_IN;
- pIdx = 0;
- }
-
- nOrderBy = p->pOrderBy ? p->pOrderBy->nExpr : 0;
- if( p->i ){
- nPriorSat = p->aLevel[p->i-1].plan.nOBSat;
- bSortInit = nPriorSat<nOrderBy;
- bDistInit = 0;
- }else{
- nPriorSat = 0;
- bSortInit = nOrderBy>0;
- bDistInit = p->pDistinct!=0;
- }
-
- /* Loop over all indices looking for the best one to use
- */
- for(; pProbe; pIdx=pProbe=pProbe->pNext){
- const tRowcnt * const aiRowEst = pProbe->aiRowEst;
- WhereCost pc; /* Cost of using pProbe */
- double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */
-
- /* The following variables are populated based on the properties of
- ** index being evaluated. They are then used to determine the expected
- ** cost and number of rows returned.
- **
- ** pc.plan.nEq:
- ** Number of equality terms that can be implemented using the index.
- ** In other words, the number of initial fields in the index that
- ** are used in == or IN or NOT NULL constraints of the WHERE clause.
- **
- ** nInMul:
- ** The "in-multiplier". This is an estimate of how many seek operations
- ** SQLite must perform on the index in question. For example, if the
- ** WHERE clause is:
- **
- ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6)
- **
- ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is
- ** set to 9. Given the same schema and either of the following WHERE
- ** clauses:
- **
- ** WHERE a = 1
- ** WHERE a >= 2
- **
- ** nInMul is set to 1.
- **
- ** If there exists a WHERE term of the form "x IN (SELECT ...)", then
- ** the sub-select is assumed to return 25 rows for the purposes of
- ** determining nInMul.
- **
- ** bInEst:
- ** Set to true if there was at least one "x IN (SELECT ...)" term used
- ** in determining the value of nInMul. Note that the RHS of the
- ** IN operator must be a SELECT, not a value list, for this variable
- ** to be true.
- **
- ** rangeDiv:
- ** An estimate of a divisor by which to reduce the search space due
- ** to inequality constraints. In the absence of sqlite_stat3 ANALYZE
- ** data, a single inequality reduces the search space to 1/4rd its
- ** original size (rangeDiv==4). Two inequalities reduce the search
- ** space to 1/16th of its original size (rangeDiv==16).
- **
- ** bSort:
- ** Boolean. True if there is an ORDER BY clause that will require an
- ** external sort (i.e. scanning the index being evaluated will not
- ** correctly order records).
- **
- ** bDist:
- ** Boolean. True if there is a DISTINCT clause that will require an
- ** external btree.
- **
- ** bLookup:
- ** Boolean. True if a table lookup is required for each index entry
- ** visited. In other words, true if this is not a covering index.
- ** This is always false for the rowid primary key index of a table.
- ** For other indexes, it is true unless all the columns of the table
- ** used by the SELECT statement are present in the index (such an
- ** index is sometimes described as a covering index).
- ** For example, given the index on (a, b), the second of the following
- ** two queries requires table b-tree lookups in order to find the value
- ** of column c, but the first does not because columns a and b are
- ** both available in the index.
- **
- ** SELECT a, b FROM tbl WHERE a = 1;
- ** SELECT a, b, c FROM tbl WHERE a = 1;
- */
- int bInEst = 0; /* True if "x IN (SELECT...)" seen */
- int nInMul = 1; /* Number of distinct equalities to lookup */
- double rangeDiv = (double)1; /* Estimated reduction in search space */
- int nBound = 0; /* Number of range constraints seen */
- char bSort = bSortInit; /* True if external sort required */
- char bDist = bDistInit; /* True if index cannot help with DISTINCT */
- char bLookup = 0; /* True if not a covering index */
- WhereTerm *pTerm; /* A single term of the WHERE clause */
-#ifdef SQLITE_ENABLE_STAT3
- WhereTerm *pFirstTerm = 0; /* First term matching the index */
-#endif
-
- WHERETRACE((
- " %s(%s):\n",
- pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk")
- ));
- memset(&pc, 0, sizeof(pc));
- pc.plan.nOBSat = nPriorSat;
-
- /* Determine the values of pc.plan.nEq and nInMul */
- for(pc.plan.nEq=0; pc.plan.nEq<pProbe->nColumn; pc.plan.nEq++){
- int j = pProbe->aiColumn[pc.plan.nEq];
- pTerm = findTerm(pWC, iCur, j, p->notReady, eqTermMask, pIdx);
- if( pTerm==0 ) break;
- pc.plan.wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
- testcase( pTerm->pWC!=pWC );
- if( pTerm->eOperator & WO_IN ){
- Expr *pExpr = pTerm->pExpr;
- pc.plan.wsFlags |= WHERE_COLUMN_IN;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
- nInMul *= 25;
- bInEst = 1;
- }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
- /* "x IN (value, value, ...)" */
- nInMul *= pExpr->x.pList->nExpr;
- }
- }else if( pTerm->eOperator & WO_ISNULL ){
- pc.plan.wsFlags |= WHERE_COLUMN_NULL;
- }
-#ifdef SQLITE_ENABLE_STAT3
- if( pc.plan.nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
-#endif
- pc.used |= pTerm->prereqRight;
- }
-
- /* If the index being considered is UNIQUE, and there is an equality
- ** constraint for all columns in the index, then this search will find
- ** at most a single row. In this case set the WHERE_UNIQUE flag to
- ** indicate this to the caller.
- **
- ** Otherwise, if the search may find more than one row, test to see if
- ** there is a range constraint on indexed column (pc.plan.nEq+1) that
- ** can be optimized using the index.
- */
- if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
- testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
- testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
- if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
- pc.plan.wsFlags |= WHERE_UNIQUE;
- if( p->i==0 || (p->aLevel[p->i-1].plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
- pc.plan.wsFlags |= WHERE_ALL_UNIQUE;
- }
- }
- }else if( pProbe->bUnordered==0 ){
- int j;
- j = (pc.plan.nEq==pProbe->nColumn ? -1 : pProbe->aiColumn[pc.plan.nEq]);
- if( findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
- WhereTerm *pTop, *pBtm;
- pTop = findTerm(pWC, iCur, j, p->notReady, WO_LT|WO_LE, pIdx);
- pBtm = findTerm(pWC, iCur, j, p->notReady, WO_GT|WO_GE, pIdx);
- whereRangeScanEst(pParse, pProbe, pc.plan.nEq, pBtm, pTop, &rangeDiv);
- if( pTop ){
- nBound = 1;
- pc.plan.wsFlags |= WHERE_TOP_LIMIT;
- pc.used |= pTop->prereqRight;
- testcase( pTop->pWC!=pWC );
- }
- if( pBtm ){
- nBound++;
- pc.plan.wsFlags |= WHERE_BTM_LIMIT;
- pc.used |= pBtm->prereqRight;
- testcase( pBtm->pWC!=pWC );
- }
- pc.plan.wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
- }
- }
-
- /* If there is an ORDER BY clause and the index being considered will
- ** naturally scan rows in the required order, set the appropriate flags
- ** in pc.plan.wsFlags. Otherwise, if there is an ORDER BY clause but
- ** the index will scan rows in a different order, set the bSort
- ** variable. */
- if( bSort && (pSrc->jointype & JT_LEFT)==0 ){
- int bRev = 2;
- int bObUnique = 0;
- WHERETRACE((" --> before isSortIndex: nPriorSat=%d\n",nPriorSat));
- pc.plan.nOBSat = isSortingIndex(p, pProbe, iCur, &bRev, &bObUnique);
- WHERETRACE((" --> after isSortIndex: bRev=%d bObU=%d nOBSat=%d\n",
- bRev, bObUnique, pc.plan.nOBSat));
- if( nPriorSat<pc.plan.nOBSat || (pc.plan.wsFlags & WHERE_ALL_UNIQUE)!=0 ){
- pc.plan.wsFlags |= WHERE_ORDERED;
- if( bObUnique ) pc.plan.wsFlags |= WHERE_OB_UNIQUE;
- }
- if( nOrderBy==pc.plan.nOBSat ){
- bSort = 0;
- pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE;
- }
- if( bRev & 1 ) pc.plan.wsFlags |= WHERE_REVERSE;
- }
-
- /* If there is a DISTINCT qualifier and this index will scan rows in
- ** order of the DISTINCT expressions, clear bDist and set the appropriate
- ** flags in pc.plan.wsFlags. */
- if( bDist
- && isDistinctIndex(pParse, pWC, pProbe, iCur, p->pDistinct, pc.plan.nEq)
- && (pc.plan.wsFlags & WHERE_COLUMN_IN)==0
- ){
- bDist = 0;
- pc.plan.wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_DISTINCT;
- }
-
- /* If currently calculating the cost of using an index (not the IPK
- ** index), determine if all required column data may be obtained without
- ** using the main table (i.e. if the index is a covering
- ** index for this query). If it is, set the WHERE_IDX_ONLY flag in
- ** pc.plan.wsFlags. Otherwise, set the bLookup variable to true. */
- if( pIdx ){
- Bitmask m = pSrc->colUsed;
- int j;
- for(j=0; j<pIdx->nColumn; j++){
- int x = pIdx->aiColumn[j];
- if( x<BMS-1 ){
- m &= ~(((Bitmask)1)<<x);
- }
- }
- if( m==0 ){
- pc.plan.wsFlags |= WHERE_IDX_ONLY;
- }else{
- bLookup = 1;
- }
- }
-
- /*
- ** Estimate the number of rows of output. For an "x IN (SELECT...)"
- ** constraint, do not let the estimate exceed half the rows in the table.
- */
- pc.plan.nRow = (double)(aiRowEst[pc.plan.nEq] * nInMul);
- if( bInEst && pc.plan.nRow*2>aiRowEst[0] ){
- pc.plan.nRow = aiRowEst[0]/2;
- nInMul = (int)(pc.plan.nRow / aiRowEst[pc.plan.nEq]);
- }
-
-#ifdef SQLITE_ENABLE_STAT3
- /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
- ** and we do not think that values of x are unique and if histogram
- ** data is available for column x, then it might be possible
- ** to get a better estimate on the number of rows based on
- ** VALUE and how common that value is according to the histogram.
- */
- if( pc.plan.nRow>(double)1 && pc.plan.nEq==1
- && pFirstTerm!=0 && aiRowEst[1]>1 ){
- assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
- if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
- testcase( pFirstTerm->eOperator & WO_EQ );
- testcase( pFirstTerm->eOperator & WO_EQUIV );
- testcase( pFirstTerm->eOperator & WO_ISNULL );
- whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight,
- &pc.plan.nRow);
- }else if( bInEst==0 ){
- assert( pFirstTerm->eOperator & WO_IN );
- whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList,
- &pc.plan.nRow);
- }
- }
-#endif /* SQLITE_ENABLE_STAT3 */
-
- /* Adjust the number of output rows and downward to reflect rows
- ** that are excluded by range constraints.
- */
- pc.plan.nRow = pc.plan.nRow/rangeDiv;
- if( pc.plan.nRow<1 ) pc.plan.nRow = 1;
-
- /* Experiments run on real SQLite databases show that the time needed
- ** to do a binary search to locate a row in a table or index is roughly
- ** log10(N) times the time to move from one row to the next row within
- ** a table or index. The actual times can vary, with the size of
- ** records being an important factor. Both moves and searches are
- ** slower with larger records, presumably because fewer records fit
- ** on one page and hence more pages have to be fetched.
- **
- ** The ANALYZE command and the sqlite_stat1 and sqlite_stat3 tables do
- ** not give us data on the relative sizes of table and index records.
- ** So this computation assumes table records are about twice as big
- ** as index records
- */
- if( (pc.plan.wsFlags&~(WHERE_REVERSE|WHERE_ORDERED|WHERE_OB_UNIQUE))
- ==WHERE_IDX_ONLY
- && (pWC->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
- && sqlite3GlobalConfig.bUseCis
- && OptimizationEnabled(pParse->db, SQLITE_CoverIdxScan)
- ){
- /* This index is not useful for indexing, but it is a covering index.
- ** A full-scan of the index might be a little faster than a full-scan
- ** of the table, so give this case a cost slightly less than a table
- ** scan. */
- pc.rCost = aiRowEst[0]*3 + pProbe->nColumn;
- pc.plan.wsFlags |= WHERE_COVER_SCAN|WHERE_COLUMN_RANGE;
- }else if( (pc.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
- /* The cost of a full table scan is a number of move operations equal
- ** to the number of rows in the table.
- **
- ** We add an additional 4x penalty to full table scans. This causes
- ** the cost function to err on the side of choosing an index over
- ** choosing a full scan. This 4x full-scan penalty is an arguable
- ** decision and one which we expect to revisit in the future. But
- ** it seems to be working well enough at the moment.
- */
- pc.rCost = aiRowEst[0]*4;
- pc.plan.wsFlags &= ~WHERE_IDX_ONLY;
- if( pIdx ){
- pc.plan.wsFlags &= ~WHERE_ORDERED;
- pc.plan.nOBSat = nPriorSat;
- }
- }else{
- log10N = estLog(aiRowEst[0]);
- pc.rCost = pc.plan.nRow;
- if( pIdx ){
- if( bLookup ){
- /* For an index lookup followed by a table lookup:
- ** nInMul index searches to find the start of each index range
- ** + nRow steps through the index
- ** + nRow table searches to lookup the table entry using the rowid
- */
- pc.rCost += (nInMul + pc.plan.nRow)*log10N;
- }else{
- /* For a covering index:
- ** nInMul index searches to find the initial entry
- ** + nRow steps through the index
- */
- pc.rCost += nInMul*log10N;
- }
- }else{
- /* For a rowid primary key lookup:
- ** nInMult table searches to find the initial entry for each range
- ** + nRow steps through the table
- */
- pc.rCost += nInMul*log10N;
- }
- }
-
- /* Add in the estimated cost of sorting the result. Actual experimental
- ** measurements of sorting performance in SQLite show that sorting time
- ** adds C*N*log10(N) to the cost, where N is the number of rows to be
- ** sorted and C is a factor between 1.95 and 4.3. We will split the
- ** difference and select C of 3.0.
- */
- if( bSort ){
- double m = estLog(pc.plan.nRow*(nOrderBy - pc.plan.nOBSat)/nOrderBy);
- m *= (double)(pc.plan.nOBSat ? 2 : 3);
- pc.rCost += pc.plan.nRow*m;
- }
- if( bDist ){
- pc.rCost += pc.plan.nRow*estLog(pc.plan.nRow)*3;
- }
-
- /**** Cost of using this index has now been computed ****/
-
- /* If there are additional constraints on this table that cannot
- ** be used with the current index, but which might lower the number
- ** of output rows, adjust the nRow value accordingly. This only
- ** matters if the current index is the least costly, so do not bother
- ** with this step if we already know this index will not be chosen.
- ** Also, never reduce the output row count below 2 using this step.
- **
- ** It is critical that the notValid mask be used here instead of
- ** the notReady mask. When computing an "optimal" index, the notReady
- ** mask will only have one bit set - the bit for the current table.
- ** The notValid mask, on the other hand, always has all bits set for
- ** tables that are not in outer loops. If notReady is used here instead
- ** of notValid, then a optimal index that depends on inner joins loops
- ** might be selected even when there exists an optimal index that has
- ** no such dependency.
- */
- if( pc.plan.nRow>2 && pc.rCost<=p->cost.rCost ){
- int k; /* Loop counter */
- int nSkipEq = pc.plan.nEq; /* Number of == constraints to skip */
- int nSkipRange = nBound; /* Number of < constraints to skip */
- Bitmask thisTab; /* Bitmap for pSrc */
-
- thisTab = getMask(pWC->pMaskSet, iCur);
- for(pTerm=pWC->a, k=pWC->nTerm; pc.plan.nRow>2 && k; k--, pTerm++){
- if( pTerm->wtFlags & TERM_VIRTUAL ) continue;
- if( (pTerm->prereqAll & p->notValid)!=thisTab ) continue;
- if( pTerm->eOperator & (WO_EQ|WO_IN|WO_ISNULL) ){
- if( nSkipEq ){
- /* Ignore the first pc.plan.nEq equality matches since the index
- ** has already accounted for these */
- nSkipEq--;
- }else{
- /* Assume each additional equality match reduces the result
- ** set size by a factor of 10 */
- pc.plan.nRow /= 10;
- }
- }else if( pTerm->eOperator & (WO_LT|WO_LE|WO_GT|WO_GE) ){
- if( nSkipRange ){
- /* Ignore the first nSkipRange range constraints since the index
- ** has already accounted for these */
- nSkipRange--;
- }else{
- /* Assume each additional range constraint reduces the result
- ** set size by a factor of 3. Indexed range constraints reduce
- ** the search space by a larger factor: 4. We make indexed range
- ** more selective intentionally because of the subjective
- ** observation that indexed range constraints really are more
- ** selective in practice, on average. */
- pc.plan.nRow /= 3;
- }
- }else if( (pTerm->eOperator & WO_NOOP)==0 ){
- /* Any other expression lowers the output row count by half */
- pc.plan.nRow /= 2;
- }
- }
- if( pc.plan.nRow<2 ) pc.plan.nRow = 2;
- }
-
-
- WHERETRACE((
- " nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%08x\n"
- " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f\n"
- " used=0x%llx nOBSat=%d\n",
- pc.plan.nEq, nInMul, (int)rangeDiv, bSort, bLookup, pc.plan.wsFlags,
- p->notReady, log10N, pc.plan.nRow, pc.rCost, pc.used,
- pc.plan.nOBSat
- ));
-
- /* If this index is the best we have seen so far, then record this
- ** index and its cost in the p->cost structure.
- */
- if( (!pIdx || pc.plan.wsFlags) && compareCost(&pc, &p->cost) ){
- p->cost = pc;
- p->cost.plan.wsFlags &= wsFlagMask;
- p->cost.plan.u.pIdx = pIdx;
- }
-
- /* If there was an INDEXED BY clause, then only that one index is
- ** considered. */
- if( pSrc->pIndex ) break;
-
- /* Reset masks for the next index in the loop */
- wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE);
- eqTermMask = idxEqTermMask;
- }
-
- /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag
- ** is set, then reverse the order that the index will be scanned
- ** in. This is used for application testing, to help find cases
- ** where application behavior depends on the (undefined) order that
- ** SQLite outputs rows in in the absence of an ORDER BY clause. */
- if( !p->pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){
- p->cost.plan.wsFlags |= WHERE_REVERSE;
- }
-
- assert( p->pOrderBy || (p->cost.plan.wsFlags&WHERE_ORDERED)==0 );
- assert( p->cost.plan.u.pIdx==0 || (p->cost.plan.wsFlags&WHERE_ROWID_EQ)==0 );
- assert( pSrc->pIndex==0
- || p->cost.plan.u.pIdx==0
- || p->cost.plan.u.pIdx==pSrc->pIndex
- );
-
- WHERETRACE((" best index is %s cost=%.1f\n",
- p->cost.plan.u.pIdx ? p->cost.plan.u.pIdx->zName : "ipk",
- p->cost.rCost));
-
- bestOrClauseIndex(p);
- bestAutomaticIndex(p);
- p->cost.plan.wsFlags |= eqTermMask;
-}
-
-/*
-** Find the query plan for accessing table pSrc->pTab. Write the
-** best query plan and its cost into the WhereCost object supplied
-** as the last parameter. This function may calculate the cost of
-** both real and virtual table scans.
-**
-** This function does not take ORDER BY or DISTINCT into account. Nor
-** does it remember the virtual table query plan. All it does is compute
-** the cost while determining if an OR optimization is applicable. The
-** details will be reconsidered later if the optimization is found to be
-** applicable.
-*/
-static void bestIndex(WhereBestIdx *p){
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(p->pSrc->pTab) ){
- sqlite3_index_info *pIdxInfo = 0;
- p->ppIdxInfo = &pIdxInfo;
- bestVirtualIndex(p);
- assert( pIdxInfo!=0 || p->pParse->db->mallocFailed );
- if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){
- sqlite3_free(pIdxInfo->idxStr);
- }
- sqlite3DbFree(p->pParse->db, pIdxInfo);
- }else
-#endif
- {
- bestBtreeIndex(p);
- }
-}
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/*
** Disable a term in the WHERE clause. Except, do not disable the term
@@ -108107,9 +110689,6 @@ static void bestIndex(WhereBestIdx *p){
** in the ON clause. The term is disabled in (3) because it is not part
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
**
-** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
-** completely satisfied by indices.
-**
** Disabling a term causes that term to not be tested in the inner loop
** of the join. Disabling is an optimization. When terms are satisfied
** by indices, we disable them to prevent redundant tests in the inner
@@ -108122,6 +110701,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
if( pTerm
&& (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+ && (pLevel->notReady & pTerm->prereqAll)==0
){
pTerm->wtFlags |= TERM_CODED;
if( pTerm->iParent>=0 ){
@@ -108189,6 +110769,7 @@ static int codeEqualityTerm(
WhereTerm *pTerm, /* The term of the WHERE clause to be coded */
WhereLevel *pLevel, /* The level of the FROM clause we are working on */
int iEq, /* Index of the equality term within this level */
+ int bRev, /* True for reverse-order IN operations */
int iTarget /* Attempt to leave results in this register */
){
Expr *pX = pTerm->pExpr;
@@ -108206,14 +110787,13 @@ static int codeEqualityTerm(
int eType;
int iTab;
struct InLoop *pIn;
- u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
+ WhereLoop *pLoop = pLevel->pWLoop;
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0
- && pLevel->plan.u.pIdx->aSortOrder[iEq]
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
+ && pLoop->u.btree.pIndex!=0
+ && pLoop->u.btree.pIndex->aSortOrder[iEq]
){
testcase( iEq==0 );
- testcase( iEq==pLevel->plan.u.pIdx->nColumn-1 );
- testcase( iEq>0 && iEq+1<pLevel->plan.u.pIdx->nColumn );
testcase( bRev );
bRev = !bRev;
}
@@ -108226,7 +110806,8 @@ static int codeEqualityTerm(
}
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
- assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
+ assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+ pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
}
@@ -108243,7 +110824,7 @@ static int codeEqualityTerm(
}else{
pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
}
- pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
+ pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
}else{
pLevel->u.in.nIn = 0;
@@ -108256,7 +110837,7 @@ static int codeEqualityTerm(
/*
** Generate code that will evaluate all == and IN constraints for an
-** index.
+** index scan.
**
** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c).
** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10
@@ -108271,9 +110852,15 @@ static int codeEqualityTerm(
** The only thing it does is allocate the pLevel->iMem memory cell and
** compute the affinity string.
**
-** This routine always allocates at least one memory cell and returns
-** the index of that memory cell. The code that
-** calls this routine will use that memory cell to store the termination
+** The nExtraReg parameter is 0 or 1. It is 0 if all WHERE clause constraints
+** are == or IN and are covered by the nEq. nExtraReg is 1 if there is
+** an inequality constraint (such as the "c>=5 AND c<10" in the example) that
+** occurs after the nEq quality constraints.
+**
+** This routine allocates a range of nEq+nExtraReg memory cells and returns
+** the index of the first memory cell in that range. The code that
+** calls this routine will use that memory range to store keys for
+** start and termination conditions of the loop.
** key value of the loop. If one or more IN operators appear, then
** this routine allocates an additional nEq memory cells for internal
** use.
@@ -108296,29 +110883,33 @@ static int codeEqualityTerm(
static int codeAllEqualityTerms(
Parse *pParse, /* Parsing context */
WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */
- WhereClause *pWC, /* The WHERE clause */
- Bitmask notReady, /* Which parts of FROM have not yet been coded */
+ int bRev, /* Reverse the order of IN operators */
int nExtraReg, /* Number of extra registers to allocate */
char **pzAff /* OUT: Set to point to affinity string */
){
- int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */
+ u16 nEq; /* The number of == or IN constraints to code */
+ u16 nSkip; /* Number of left-most columns to skip */
Vdbe *v = pParse->pVdbe; /* The vm under construction */
Index *pIdx; /* The index being used for this loop */
- int iCur = pLevel->iTabCur; /* The cursor of the table */
WhereTerm *pTerm; /* A single constraint term */
+ WhereLoop *pLoop; /* The WhereLoop object */
int j; /* Loop counter */
int regBase; /* Base register */
int nReg; /* Number of registers to allocate */
char *zAff; /* Affinity string to return */
/* This module is only called on query plans that use an index. */
- assert( pLevel->plan.wsFlags & WHERE_INDEXED );
- pIdx = pLevel->plan.u.pIdx;
+ pLoop = pLevel->pWLoop;
+ assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+ nEq = pLoop->u.btree.nEq;
+ nSkip = pLoop->u.btree.nSkip;
+ pIdx = pLoop->u.btree.pIndex;
+ assert( pIdx!=0 );
/* Figure out how many memory cells we will need then allocate them.
*/
regBase = pParse->nMem + 1;
- nReg = pLevel->plan.nEq + nExtraReg;
+ nReg = pLoop->u.btree.nEq + nExtraReg;
pParse->nMem += nReg;
zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx));
@@ -108326,19 +110917,33 @@ static int codeAllEqualityTerms(
pParse->db->mallocFailed = 1;
}
+ if( nSkip ){
+ int iIdxCur = pLevel->iIdxCur;
+ sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
+ VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
+ j = sqlite3VdbeAddOp0(v, OP_Goto);
+ pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt),
+ iIdxCur, 0, regBase, nSkip);
+ sqlite3VdbeJumpHere(v, j);
+ for(j=0; j<nSkip; j++){
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
+ assert( pIdx->aiColumn[j]>=0 );
+ VdbeComment((v, "%s", pIdx->pTable->aCol[pIdx->aiColumn[j]].zName));
+ }
+ }
+
/* Evaluate the equality constraints
*/
- assert( pIdx->nColumn>=nEq );
- for(j=0; j<nEq; j++){
+ assert( zAff==0 || (int)strlen(zAff)>=nEq );
+ for(j=nSkip; j<nEq; j++){
int r1;
- int k = pIdx->aiColumn[j];
- pTerm = findTerm(pWC, iCur, k, notReady, pLevel->plan.wsFlags, pIdx);
- if( pTerm==0 ) break;
- /* The following true for indices with redundant columns.
+ pTerm = pLoop->aLTerm[j];
+ assert( pTerm!=0 );
+ /* The following testcase is true for indices with redundant columns.
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, regBase+j);
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
if( r1!=regBase+j ){
if( nReg==1 ){
sqlite3ReleaseTempReg(pParse, regBase);
@@ -108406,32 +111011,40 @@ static void explainAppendTerm(
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
-static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
- WherePlan *pPlan = &pLevel->plan;
- Index *pIndex = pPlan->u.pIdx;
- int nEq = pPlan->nEq;
+static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
+ Index *pIndex = pLoop->u.btree.pIndex;
+ u16 nEq = pLoop->u.btree.nEq;
+ u16 nSkip = pLoop->u.btree.nSkip;
int i, j;
Column *aCol = pTab->aCol;
- int *aiColumn = pIndex->aiColumn;
+ i16 *aiColumn = pIndex->aiColumn;
StrAccum txt;
- if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
+ if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
return 0;
}
sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
txt.db = db;
sqlite3StrAccumAppend(&txt, " (", 2);
for(i=0; i<nEq; i++){
- explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
+ char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName;
+ if( i>=nSkip ){
+ explainAppendTerm(&txt, i, z, "=");
+ }else{
+ if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
+ sqlite3StrAccumAppend(&txt, "ANY(", 4);
+ sqlite3StrAccumAppend(&txt, z, -1);
+ sqlite3StrAccumAppend(&txt, ")", 1);
+ }
}
j = i;
- if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
+ char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
explainAppendTerm(&txt, i++, z, ">");
}
- if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
- char *z = (j==pIndex->nColumn ) ? "rowid" : aCol[aiColumn[j]].zName;
+ if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
+ char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
explainAppendTerm(&txt, i, z, "<");
}
sqlite3StrAccumAppend(&txt, ")", 1);
@@ -108452,21 +111065,26 @@ static void explainOneScan(
int iFrom, /* Value for "from" column of output */
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
){
- if( pParse->explain==2 ){
- u32 flags = pLevel->plan.wsFlags;
+#ifndef SQLITE_DEBUG
+ if( pParse->explain==2 )
+#endif
+ {
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
Vdbe *v = pParse->pVdbe; /* VM being constructed */
sqlite3 *db = pParse->db; /* Database handle */
char *zMsg; /* Text to add to EQP output */
- sqlite3_int64 nRow; /* Expected number of rows visited by scan */
int iId = pParse->iSelectId; /* Select id (left-most output column) */
int isSearch; /* True for a SEARCH. False for SCAN. */
+ WhereLoop *pLoop; /* The controlling WhereLoop object */
+ u32 flags; /* Flags that describe this loop */
+ pLoop = pLevel->pWLoop;
+ flags = pLoop->wsFlags;
if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
- isSearch = (pLevel->plan.nEq>0)
- || (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
- || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
+ isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
+ || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
+ || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
if( pItem->pSelect ){
@@ -108478,43 +111096,37 @@ static void explainOneScan(
if( pItem->zAlias ){
zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
}
- if( (flags & WHERE_INDEXED)!=0 ){
- char *zWhere = explainIndexRange(db, pLevel, pItem->pTab);
- zMsg = sqlite3MAppendf(db, zMsg, "%s USING %s%sINDEX%s%s%s", zMsg,
- ((flags & WHERE_TEMP_INDEX)?"AUTOMATIC ":""),
- ((flags & WHERE_IDX_ONLY)?"COVERING ":""),
- ((flags & WHERE_TEMP_INDEX)?"":" "),
- ((flags & WHERE_TEMP_INDEX)?"": pLevel->plan.u.pIdx->zName),
- zWhere
- );
+ if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
+ && ALWAYS(pLoop->u.btree.pIndex!=0)
+ ){
+ char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
+ zMsg = sqlite3MAppendf(db, zMsg,
+ ((flags & WHERE_AUTO_INDEX) ?
+ "%s USING AUTOMATIC %sINDEX%.0s%s" :
+ "%s USING %sINDEX %s%s"),
+ zMsg, ((flags & WHERE_IDX_ONLY) ? "COVERING " : ""),
+ pLoop->u.btree.pIndex->zName, zWhere);
sqlite3DbFree(db, zWhere);
- }else if( flags & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
+ }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
- if( flags&WHERE_ROWID_EQ ){
+ if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
}else if( flags&WHERE_BTM_LIMIT ){
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
- }else if( flags&WHERE_TOP_LIMIT ){
+ }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
}
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
- pVtabIdx->idxNum, pVtabIdx->idxStr);
+ pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
}
#endif
- if( wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ){
- testcase( wctrlFlags & WHERE_ORDERBY_MIN );
- nRow = 1;
- }else{
- nRow = (sqlite3_int64)pLevel->plan.nRow;
- }
- zMsg = sqlite3MAppendf(db, zMsg, "%s (~%lld rows)", zMsg, nRow);
+ zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
}
}
@@ -108530,7 +111142,6 @@ static void explainOneScan(
static Bitmask codeOneLoopStart(
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
int iLevel, /* Which level of pWInfo->a[] should be coded */
- u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
Bitmask notReady /* Which tables are currently available */
){
int j, k; /* Loop counters */
@@ -108539,27 +111150,31 @@ static Bitmask codeOneLoopStart(
int omitTable; /* True if we use the index only */
int bRev; /* True if we need to scan in reverse order */
WhereLevel *pLevel; /* The where level to be coded */
+ WhereLoop *pLoop; /* The WhereLoop object being coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
Parse *pParse; /* Parsing context */
+ sqlite3 *db; /* Database connection */
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
- Bitmask newNotReady; /* Return value */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
- pWC = pWInfo->pWC;
+ pWC = &pWInfo->sWC;
+ db = pParse->db;
pLevel = &pWInfo->a[iLevel];
+ pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
- bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
- omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0
- && (wctrlFlags & WHERE_FORCE_TABLE)==0;
- VdbeNoopComment((v, "Begin Join Loop %d", iLevel));
+ pLevel->notReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
+ bRev = (pWInfo->revMask>>iLevel)&1;
+ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
+ && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
+ VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
/* Create labels for the "break" and "continue" instructions
** for the current loop. Jump to addrBrk to break out of a loop.
@@ -108595,47 +111210,37 @@ static Bitmask codeOneLoopStart(
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
- /* Case 0: The table is a virtual-table. Use the VFilter and VNext
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+ /* Case 1: The table is a virtual-table. Use the VFilter and VNext
** to access the data.
*/
int iReg; /* P3 Value for OP_VFilter */
int addrNotFound;
- sqlite3_index_info *pVtabIdx = pLevel->plan.u.pVtabIdx;
- int nConstraint = pVtabIdx->nConstraint;
- struct sqlite3_index_constraint_usage *aUsage =
- pVtabIdx->aConstraintUsage;
- const struct sqlite3_index_constraint *aConstraint =
- pVtabIdx->aConstraint;
+ int nConstraint = pLoop->nLTerm;
sqlite3ExprCachePush(pParse);
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
addrNotFound = pLevel->addrBrk;
- for(j=1; j<=nConstraint; j++){
- for(k=0; k<nConstraint; k++){
- if( aUsage[k].argvIndex==j ){
- int iTarget = iReg+j+1;
- pTerm = &pWC->a[aConstraint[k].iTermOffset];
- if( pTerm->eOperator & WO_IN ){
- codeEqualityTerm(pParse, pTerm, pLevel, k, iTarget);
- addrNotFound = pLevel->addrNxt;
- }else{
- sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
- }
- break;
- }
+ for(j=0; j<nConstraint; j++){
+ int iTarget = iReg+j+2;
+ pTerm = pLoop->aLTerm[j];
+ if( pTerm==0 ) continue;
+ if( pTerm->eOperator & WO_IN ){
+ codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
+ addrNotFound = pLevel->addrNxt;
+ }else{
+ sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
}
- if( k==nConstraint ) break;
}
- sqlite3VdbeAddOp2(v, OP_Integer, pVtabIdx->idxNum, iReg);
- sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
- sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pVtabIdx->idxStr,
- pVtabIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
- pVtabIdx->needToFreeIdxStr = 0;
- for(j=0; j<nConstraint; j++){
- if( aUsage[j].omit ){
- int iTerm = aConstraint[j].iTermOffset;
- disableTerm(pLevel, &pWC->a[iTerm]);
+ sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
+ sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
+ sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
+ pLoop->u.vtab.idxStr,
+ pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+ pLoop->u.vtab.needFree = 0;
+ for(j=0; j<nConstraint && j<16; j++){
+ if( (pLoop->u.vtab.omitMask>>j)&1 ){
+ disableTerm(pLevel, pLoop->aLTerm[j]);
}
}
pLevel->op = OP_VNext;
@@ -108646,19 +111251,22 @@ static Bitmask codeOneLoopStart(
}else
#endif /* SQLITE_OMIT_VIRTUALTABLE */
- if( pLevel->plan.wsFlags & WHERE_ROWID_EQ ){
- /* Case 1: We can directly reference a single row using an
+ if( (pLoop->wsFlags & WHERE_IPK)!=0
+ && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0
+ ){
+ /* Case 2: We can directly reference a single row using an
** equality comparison against the ROWID field. Or
** we reference multiple rows using a "rowid IN (...)"
** construct.
*/
+ assert( pLoop->u.btree.nEq==1 );
iReleaseReg = sqlite3GetTempReg(pParse);
- pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0);
+ pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
- iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, iReleaseReg);
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
@@ -108666,8 +111274,10 @@ static Bitmask codeOneLoopStart(
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
VdbeComment((v, "pk"));
pLevel->op = OP_Noop;
- }else if( pLevel->plan.wsFlags & WHERE_ROWID_RANGE ){
- /* Case 2: We have an inequality comparison against the ROWID field.
+ }else if( (pLoop->wsFlags & WHERE_IPK)!=0
+ && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
+ ){
+ /* Case 3: We have an inequality comparison against the ROWID field.
*/
int testOp = OP_Noop;
int start;
@@ -108675,8 +111285,11 @@ static Bitmask codeOneLoopStart(
WhereTerm *pStart, *pEnd;
assert( omitTable==0 );
- pStart = findTerm(pWC, iCur, -1, notReady, WO_GT|WO_GE, 0);
- pEnd = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0);
+ j = 0;
+ pStart = pEnd = 0;
+ if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
+ if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
+ assert( pStart!=0 || pEnd!=0 );
if( bRev ){
pTerm = pStart;
pStart = pEnd;
@@ -108699,10 +111312,11 @@ static Bitmask codeOneLoopStart(
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
- testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+ assert( (pStart->wtFlags & TERM_VNULL)==0 );
+ testcase( pStart->wtFlags & TERM_VIRTUAL );
pX = pStart->pExpr;
assert( pX!=0 );
- assert( pStart->leftCursor==iCur );
+ testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk"));
@@ -108716,8 +111330,9 @@ static Bitmask codeOneLoopStart(
Expr *pX;
pX = pEnd->pExpr;
assert( pX!=0 );
- assert( pEnd->leftCursor==iCur );
- testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+ assert( (pEnd->wtFlags & TERM_VNULL)==0 );
+ testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
+ testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
if( pX->op==TK_LT || pX->op==TK_GT ){
@@ -108731,11 +111346,7 @@ static Bitmask codeOneLoopStart(
pLevel->op = bRev ? OP_Prev : OP_Next;
pLevel->p1 = iCur;
pLevel->p2 = start;
- if( pStart==0 && pEnd==0 ){
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
- }else{
- assert( pLevel->p5==0 );
- }
+ assert( pLevel->p5==0 );
if( testOp!=OP_Noop ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
@@ -108743,8 +111354,8 @@ static Bitmask codeOneLoopStart(
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
- }else if( pLevel->plan.wsFlags & (WHERE_COLUMN_RANGE|WHERE_COLUMN_EQ) ){
- /* Case 3: A scan using an index.
+ }else if( pLoop->wsFlags & WHERE_INDEXED ){
+ /* Case 4: A scan using an index.
**
** The WHERE clause may contain zero or more equality
** terms ("==" or "IN" operators) that refer to the N
@@ -108790,7 +111401,7 @@ static Bitmask codeOneLoopStart(
OP_IdxGE, /* 1: (end_constraints && !bRev) */
OP_IdxLT /* 2: (end_constraints && bRev) */
};
- int nEq = pLevel->plan.nEq; /* Number of == or IN terms */
+ u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
int regBase; /* Base register holding constraint values */
int r1; /* Temp register */
@@ -108805,11 +111416,11 @@ static Bitmask codeOneLoopStart(
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
- char *zEndAff; /* Affinity for end of range constraint */
+ char cEndAff = 0; /* Affinity for end of range constraint */
- pIdx = pLevel->plan.u.pIdx;
+ pIdx = pLoop->u.btree.pIndex;
iIdxCur = pLevel->iIdxCur;
- k = (nEq==pIdx->nColumn ? -1 : pIdx->aiColumn[nEq]);
+ assert( nEq>=pLoop->u.btree.nSkip );
/* If this loop satisfies a sort order (pOrderBy) request that
** was passed to this function to implement a "SELECT min(x) ..."
@@ -108819,12 +111430,11 @@ static Bitmask codeOneLoopStart(
** the first one after the nEq equality constraints in the index,
** this requires some special handling.
*/
- if( (wctrlFlags&WHERE_ORDERBY_MIN)!=0
- && (pLevel->plan.wsFlags&WHERE_ORDERED)
- && (pIdx->nColumn>nEq)
+ if( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0
+ && (pWInfo->bOBSat!=0)
+ && (pIdx->nKeyCol>nEq)
){
- /* assert( pOrderBy->nExpr==1 ); */
- /* assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] ); */
+ assert( pLoop->u.btree.nSkip==0 );
isMinQuery = 1;
nExtraReg = 1;
}
@@ -108832,12 +111442,13 @@ static Bitmask codeOneLoopStart(
/* Find any inequality constraint terms for the start and end
** of the range.
*/
- if( pLevel->plan.wsFlags & WHERE_TOP_LIMIT ){
- pRangeEnd = findTerm(pWC, iCur, k, notReady, (WO_LT|WO_LE), pIdx);
+ j = nEq;
+ if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
+ pRangeStart = pLoop->aLTerm[j++];
nExtraReg = 1;
}
- if( pLevel->plan.wsFlags & WHERE_BTM_LIMIT ){
- pRangeStart = findTerm(pWC, iCur, k, notReady, (WO_GT|WO_GE), pIdx);
+ if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
+ pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
}
@@ -108845,26 +111456,25 @@ static Bitmask codeOneLoopStart(
** and store the values of those terms in an array of registers
** starting at regBase.
*/
- regBase = codeAllEqualityTerms(
- pParse, pLevel, pWC, notReady, nExtraReg, &zStartAff
- );
- zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
+ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
+ assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
+ if( zStartAff ) cEndAff = zStartAff[nEq];
addrNxt = pLevel->addrNxt;
/* If we are doing a reverse order scan on an ascending index, or
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
- if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
- || (bRev && pIdx->nColumn==nEq)
+ if( (nEq<pIdx->nKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
+ || (bRev && pIdx->nKeyCol==nEq)
){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
}
- testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
- testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
- testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
+ testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 );
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 );
+ testcase( pRangeEnd && (pRangeEnd->eOperator & WO_GE)!=0 );
startEq = !pRangeStart || pRangeStart->eOperator & (WO_LE|WO_GE);
endEq = !pRangeEnd || pRangeEnd->eOperator & (WO_LE|WO_GE);
start_constraints = pRangeStart || nEq>0;
@@ -108889,7 +111499,7 @@ static Bitmask codeOneLoopStart(
}
}
nConstraint++;
- testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+ testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
}else if( isMinQuery ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++;
@@ -108918,23 +111528,15 @@ static Bitmask codeOneLoopStart(
if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
}
- if( zEndAff ){
- if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){
- /* Since the comparison is to be performed with no conversions
- ** applied to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_NONE. */
- zEndAff[nEq] = SQLITE_AFF_NONE;
- }
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
- zEndAff[nEq] = SQLITE_AFF_NONE;
- }
- }
- codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
+ if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE
+ && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
+ ){
+ codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff);
+ }
nConstraint++;
- testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
+ testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
}
- sqlite3DbFree(pParse->db, zStartAff);
- sqlite3DbFree(pParse->db, zEndAff);
+ sqlite3DbFree(db, zStartAff);
/* Top of the loop body */
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
@@ -108954,10 +111556,15 @@ static Bitmask codeOneLoopStart(
** If it is, jump to the next iteration of the loop.
*/
r1 = sqlite3GetTempReg(pParse);
- testcase( pLevel->plan.wsFlags & WHERE_BTM_LIMIT );
- testcase( pLevel->plan.wsFlags & WHERE_TOP_LIMIT );
- if( (pLevel->plan.wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 ){
+ testcase( pLoop->wsFlags & WHERE_BTM_LIMIT );
+ testcase( pLoop->wsFlags & WHERE_TOP_LIMIT );
+ if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
+ && (j = pIdx->aiColumn[nEq])>=0
+ && pIdx->pTable->aCol[j].notNull==0
+ && (nEq || (pLoop->wsFlags & WHERE_BTM_LIMIT)==0)
+ ){
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
+ VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName));
sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
}
sqlite3ReleaseTempReg(pParse, r1);
@@ -108965,17 +111572,28 @@ static Bitmask codeOneLoopStart(
/* Seek the table cursor, if required */
disableTerm(pLevel, pRangeStart);
disableTerm(pLevel, pRangeEnd);
- if( !omitTable ){
+ if( omitTable ){
+ /* pIdx is a covering index. No need to access the main table. */
+ }else if( HasRowid(pIdx->pTable) ){
iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; j<pPk->nKeyCol; j++){
+ k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
+ }
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
+ iRowidReg, pPk->nKeyCol);
}
/* Record the instruction used to terminate the loop. Disable
** WHERE clause terms made redundant by the index range scan.
*/
- if( pLevel->plan.wsFlags & WHERE_UNIQUE ){
+ if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
}else if( bRev ){
pLevel->op = OP_Prev;
@@ -108983,7 +111601,7 @@ static Bitmask codeOneLoopStart(
pLevel->op = OP_Next;
}
pLevel->p1 = iIdxCur;
- if( pLevel->plan.wsFlags & WHERE_COVER_SCAN ){
+ if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}else{
assert( pLevel->p5==0 );
@@ -108991,8 +111609,8 @@ static Bitmask codeOneLoopStart(
}else
#ifndef SQLITE_OMIT_OR_OPTIMIZATION
- if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
- /* Case 4: Two or more separately indexed terms connected by OR
+ if( pLoop->wsFlags & WHERE_MULTI_OR ){
+ /* Case 5: Two or more separately indexed terms connected by OR
**
** Example:
**
@@ -109045,7 +111663,7 @@ static Bitmask codeOneLoopStart(
int ii; /* Loop counter */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
- pTerm = pLevel->plan.u.pTerm;
+ pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->eOperator & WO_OR );
assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -109061,10 +111679,10 @@ static Bitmask codeOneLoopStart(
int nNotReady; /* The number of notReady tables */
struct SrcList_item *origSrc; /* Original list of tables */
nNotReady = pWInfo->nLevel - iLevel - 1;
- pOrTab = sqlite3StackAllocRaw(pParse->db,
+ pOrTab = sqlite3StackAllocRaw(db,
sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
if( pOrTab==0 ) return notReady;
- pOrTab->nAlloc = (i16)(nNotReady + 1);
+ pOrTab->nAlloc = (u8)(nNotReady + 1);
pOrTab->nSrc = pOrTab->nAlloc;
memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
origSrc = pWInfo->pTabList->a;
@@ -109086,7 +111704,7 @@ static Bitmask codeOneLoopStart(
** fall through to the next instruction, just as an OP_Next does if
** called on an uninitialized cursor.
*/
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
regRowset = ++pParse->nMem;
regRowid = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
@@ -109111,11 +111729,12 @@ static Bitmask codeOneLoopStart(
int iTerm;
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
Expr *pExpr = pWC->a[iTerm].pExpr;
+ if( &pWC->a[iTerm] == pTerm ) continue;
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
- if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
+ if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
- pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
- pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
+ pExpr = sqlite3ExprDup(db, pExpr, 0);
+ pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
}
if( pAndExpr ){
pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
@@ -109135,13 +111754,13 @@ static Bitmask codeOneLoopStart(
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
- assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
+ assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){
- WhereLevel *pLvl;
+ WhereLoop *pSubLoop;
explainOneScan(
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
);
- if( (wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
+ if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
int r;
r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur,
@@ -109170,13 +111789,13 @@ static Bitmask codeOneLoopStart(
** pCov to NULL to indicate that no candidate covering index will
** be available.
*/
- pLvl = &pSubWInfo->a[0];
- if( (pLvl->plan.wsFlags & WHERE_INDEXED)!=0
- && (pLvl->plan.wsFlags & WHERE_TEMP_INDEX)==0
- && (ii==0 || pLvl->plan.u.pIdx==pCov)
+ pSubLoop = pSubWInfo->a[0].pWLoop;
+ assert( (pSubLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
+ if( (pSubLoop->wsFlags & WHERE_INDEXED)!=0
+ && (ii==0 || pSubLoop->u.btree.pIndex==pCov)
){
- assert( pLvl->iIdxCur==iCovCur );
- pCov = pLvl->plan.u.pIdx;
+ assert( pSubWInfo->a[0].iIdxCur==iCovCur );
+ pCov = pSubLoop->u.btree.pIndex;
}else{
pCov = 0;
}
@@ -109190,45 +111809,39 @@ static Bitmask codeOneLoopStart(
if( pCov ) pLevel->iIdxCur = iCovCur;
if( pAndExpr ){
pAndExpr->pLeft = 0;
- sqlite3ExprDelete(pParse->db, pAndExpr);
+ sqlite3ExprDelete(db, pAndExpr);
}
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
- if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
+ if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
{
- /* Case 5: There is no usable index. We must do a complete
+ /* Case 6: There is no usable index. We must do a complete
** scan of the entire table.
*/
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
- assert( omitTable==0 );
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
- newNotReady = notReady & ~getMask(pWC->pMaskSet, iCur);
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
- **
- ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
- ** the use of indices become tests that are evaluated against each row of
- ** the relevant input tables.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & newNotReady)!=0 ){
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
testcase( pWInfo->untestedTerms==0
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
pWInfo->untestedTerms = 1;
@@ -109252,22 +111865,28 @@ static Bitmask codeOneLoopStart(
** the implied "t1.a=123" constraint.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE;
+ Expr *pE, *pEAlt;
WhereTerm *pAlt;
- Expr sEq;
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
if( pTerm->leftCursor!=iCur ) continue;
+ if( pLevel->iLeftJoin ) continue;
pE = pTerm->pExpr;
assert( !ExprHasProperty(pE, EP_FromJoin) );
- assert( (pTerm->prereqRight & newNotReady)!=0 );
+ assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
- VdbeNoopComment((v, "begin transitive constraint"));
- sEq = *pAlt->pExpr;
- sEq.pLeft = pE->pLeft;
- sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
+ testcase( pAlt->eOperator & WO_EQ );
+ testcase( pAlt->eOperator & WO_IN );
+ VdbeModuleComment((v, "begin transitive constraint"));
+ pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
+ if( pEAlt ){
+ *pEAlt = *pAlt->pExpr;
+ pEAlt->pLeft = pE->pLeft;
+ sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
+ sqlite3StackFree(db, pEAlt);
+ }
}
/* For a LEFT OUTER JOIN, generate code that will record the fact that
@@ -109279,10 +111898,10 @@ static Bitmask codeOneLoopStart(
VdbeComment((v, "record LEFT JOIN hit"));
sqlite3ExprCacheClear(pParse);
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
- if( (pTerm->prereqAll & newNotReady)!=0 ){
+ if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
assert( pWInfo->untestedTerms );
continue;
}
@@ -109293,50 +111912,1759 @@ static Bitmask codeOneLoopStart(
}
sqlite3ReleaseTempReg(pParse, iReleaseReg);
- return newNotReady;
+ return pLevel->notReady;
}
-#if defined(SQLITE_TEST)
+#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
-** The following variable holds a text description of query plan generated
-** by the most recent call to sqlite3WhereBegin(). Each call to WhereBegin
-** overwrites the previous. This information is used for testing and
-** analysis only.
+** Generate "Explanation" text for a WhereTerm.
*/
-SQLITE_API char sqlite3_query_plan[BMS*2*40]; /* Text of the join */
-static int nQPlan = 0; /* Next free slow in _query_plan[] */
+static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
+ char zType[4];
+ memcpy(zType, "...", 4);
+ if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
+ if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
+ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+ sqlite3ExplainPrintf(v, "%s ", zType);
+ sqlite3ExplainExpr(v, pTerm->pExpr);
+}
+#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
-#endif /* SQLITE_TEST */
+#ifdef WHERETRACE_ENABLED
+/*
+** Print a WhereLoop object for debugging purposes
+*/
+static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
+ WhereInfo *pWInfo = pWC->pWInfo;
+ int nb = 1+(pWInfo->pTabList->nSrc+7)/8;
+ struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab;
+ Table *pTab = pItem->pTab;
+ sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
+ p->iTab, nb, p->maskSelf, nb, p->prereq);
+ sqlite3DebugPrintf(" %12s",
+ pItem->zAlias ? pItem->zAlias : pTab->zName);
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ const char *zName;
+ if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
+ if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
+ int i = sqlite3Strlen30(zName) - 1;
+ while( zName[i]!='_' ) i--;
+ zName += i;
+ }
+ sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq);
+ }else{
+ sqlite3DebugPrintf("%20s","");
+ }
+ }else{
+ char *z;
+ if( p->u.vtab.idxStr ){
+ z = sqlite3_mprintf("(%d,\"%s\",%x)",
+ p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask);
+ }else{
+ z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
+ }
+ sqlite3DebugPrintf(" %-19s", z);
+ sqlite3_free(z);
+ }
+ sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
+ sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
+#ifdef SQLITE_ENABLE_TREE_EXPLAIN
+ /* If the 0x100 bit of wheretracing is set, then show all of the constraint
+ ** expressions in the WhereLoop.aLTerm[] array.
+ */
+ if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ /* WHERETRACE 0x100 */
+ int i;
+ Vdbe *v = pWInfo->pParse->pVdbe;
+ sqlite3ExplainBegin(v);
+ for(i=0; i<p->nLTerm; i++){
+ WhereTerm *pTerm = p->aLTerm[i];
+ if( pTerm==0 ) continue;
+ sqlite3ExplainPrintf(v, " (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
+ sqlite3ExplainPush(v);
+ whereExplainTerm(v, pTerm);
+ sqlite3ExplainPop(v);
+ sqlite3ExplainNL(v);
+ }
+ sqlite3ExplainFinish(v);
+ sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
+ }
+#endif
+}
+#endif
+
+/*
+** Convert bulk memory into a valid WhereLoop that can be passed
+** to whereLoopClear harmlessly.
+*/
+static void whereLoopInit(WhereLoop *p){
+ p->aLTerm = p->aLTermSpace;
+ p->nLTerm = 0;
+ p->nLSlot = ArraySize(p->aLTermSpace);
+ p->wsFlags = 0;
+}
+
+/*
+** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact.
+*/
+static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
+ if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){
+ sqlite3_free(p->u.vtab.idxStr);
+ p->u.vtab.needFree = 0;
+ p->u.vtab.idxStr = 0;
+ }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
+ sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
+ sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
+ sqlite3DbFree(db, p->u.btree.pIndex);
+ p->u.btree.pIndex = 0;
+ }
+ }
+}
+
+/*
+** Deallocate internal memory used by a WhereLoop object
+*/
+static void whereLoopClear(sqlite3 *db, WhereLoop *p){
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ whereLoopClearUnion(db, p);
+ whereLoopInit(p);
+}
+
+/*
+** Increase the memory allocation for pLoop->aLTerm[] to be at least n.
+*/
+static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
+ WhereTerm **paNew;
+ if( p->nLSlot>=n ) return SQLITE_OK;
+ n = (n+7)&~7;
+ paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n);
+ if( paNew==0 ) return SQLITE_NOMEM;
+ memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
+ if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
+ p->aLTerm = paNew;
+ p->nLSlot = n;
+ return SQLITE_OK;
+}
+
+/*
+** Transfer content from the second pLoop into the first.
+*/
+static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
+ whereLoopClearUnion(db, pTo);
+ if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
+ memset(&pTo->u, 0, sizeof(pTo->u));
+ return SQLITE_NOMEM;
+ }
+ memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
+ memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
+ if( pFrom->wsFlags & WHERE_VIRTUALTABLE ){
+ pFrom->u.vtab.needFree = 0;
+ }else if( (pFrom->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+ pFrom->u.btree.pIndex = 0;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Delete a WhereLoop object
+*/
+static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
+ whereLoopClear(db, p);
+ sqlite3DbFree(db, p);
+}
/*
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
if( ALWAYS(pWInfo) ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- sqlite3_index_info *pInfo = pWInfo->a[i].pIdxInfo;
- if( pInfo ){
- /* assert( pInfo->needToFreeIdxStr==0 || db->mallocFailed ); */
- if( pInfo->needToFreeIdxStr ){
- sqlite3_free(pInfo->idxStr);
+ whereClauseClear(&pWInfo->sWC);
+ while( pWInfo->pLoops ){
+ WhereLoop *p = pWInfo->pLoops;
+ pWInfo->pLoops = p->pNextLoop;
+ whereLoopDelete(db, p);
+ }
+ sqlite3DbFree(db, pWInfo);
+ }
+}
+
+/*
+** Insert or replace a WhereLoop entry using the template supplied.
+**
+** An existing WhereLoop entry might be overwritten if the new template
+** is better and has fewer dependencies. Or the template will be ignored
+** and no insert will occur if an existing WhereLoop is faster and has
+** fewer dependencies than the template. Otherwise a new WhereLoop is
+** added based on the template.
+**
+** If pBuilder->pOrSet is not NULL then we only care about only the
+** prerequisites and rRun and nOut costs of the N best loops. That
+** information is gathered in the pBuilder->pOrSet object. This special
+** processing mode is used only for OR clause processing.
+**
+** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
+** still might overwrite similar loops with the new template if the
+** template is better. Loops may be overwritten if the following
+** conditions are met:
+**
+** (1) They have the same iTab.
+** (2) They have the same iSortIdx.
+** (3) The template has same or fewer dependencies than the current loop
+** (4) The template has the same or lower cost than the current loop
+** (5) The template uses more terms of the same index but has no additional
+** dependencies
+*/
+static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
+ WhereLoop **ppPrev, *p, *pNext = 0;
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ sqlite3 *db = pWInfo->pParse->db;
+
+ /* If pBuilder->pOrSet is defined, then only keep track of the costs
+ ** and prereqs.
+ */
+ if( pBuilder->pOrSet!=0 ){
+#if WHERETRACE_ENABLED
+ u16 n = pBuilder->pOrSet->n;
+ int x =
+#endif
+ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
+ pTemplate->nOut);
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
+ return SQLITE_OK;
+ }
+
+ /* Search for an existing WhereLoop to overwrite, or which takes
+ ** priority over pTemplate.
+ */
+ for(ppPrev=&pWInfo->pLoops, p=*ppPrev; p; ppPrev=&p->pNextLoop, p=*ppPrev){
+ if( p->iTab!=pTemplate->iTab || p->iSortIdx!=pTemplate->iSortIdx ){
+ /* If either the iTab or iSortIdx values for two WhereLoop are different
+ ** then those WhereLoops need to be considered separately. Neither is
+ ** a candidate to replace the other. */
+ continue;
+ }
+ /* In the current implementation, the rSetup value is either zero
+ ** or the cost of building an automatic index (NlogN) and the NlogN
+ ** is the same for compatible WhereLoops. */
+ assert( p->rSetup==0 || pTemplate->rSetup==0
+ || p->rSetup==pTemplate->rSetup );
+
+ /* whereLoopAddBtree() always generates and inserts the automatic index
+ ** case first. Hence compatible candidate WhereLoops never have a larger
+ ** rSetup. Call this SETUP-INVARIANT */
+ assert( p->rSetup>=pTemplate->rSetup );
+
+ if( (p->prereq & pTemplate->prereq)==p->prereq
+ && p->rSetup<=pTemplate->rSetup
+ && p->rRun<=pTemplate->rRun
+ && p->nOut<=pTemplate->nOut
+ ){
+ /* This branch taken when p is equal or better than pTemplate in
+ ** all of (1) dependencies (2) setup-cost, (3) run-cost, and
+ ** (4) number of output rows. */
+ assert( p->rSetup==pTemplate->rSetup );
+ if( p->prereq==pTemplate->prereq
+ && p->nLTerm<pTemplate->nLTerm
+ && (p->wsFlags & pTemplate->wsFlags & WHERE_INDEXED)!=0
+ && (p->u.btree.pIndex==pTemplate->u.btree.pIndex
+ || pTemplate->rRun+p->nLTerm<=p->rRun+pTemplate->nLTerm)
+ ){
+ /* Overwrite an existing WhereLoop with an similar one that uses
+ ** more terms of the index */
+ pNext = p->pNextLoop;
+ break;
+ }else{
+ /* pTemplate is not helpful.
+ ** Return without changing or adding anything */
+ goto whereLoopInsert_noop;
+ }
+ }
+ if( (p->prereq & pTemplate->prereq)==pTemplate->prereq
+ && p->rRun>=pTemplate->rRun
+ && p->nOut>=pTemplate->nOut
+ ){
+ /* Overwrite an existing WhereLoop with a better one: one that is
+ ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost
+ ** or (4) number of output rows, and is no worse in any of those
+ ** categories. */
+ assert( p->rSetup>=pTemplate->rSetup ); /* SETUP-INVARIANT above */
+ pNext = p->pNextLoop;
+ break;
+ }
+ }
+
+ /* If we reach this point it means that either p[] should be overwritten
+ ** with pTemplate[] if p[] exists, or if p==NULL then allocate a new
+ ** WhereLoop and insert it.
+ */
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ if( p!=0 ){
+ sqlite3DebugPrintf("ins-del: ");
+ whereLoopPrint(p, pBuilder->pWC);
+ }
+ sqlite3DebugPrintf("ins-new: ");
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
+ if( p==0 ){
+ p = sqlite3DbMallocRaw(db, sizeof(WhereLoop));
+ if( p==0 ) return SQLITE_NOMEM;
+ whereLoopInit(p);
+ }
+ whereLoopXfer(db, p, pTemplate);
+ p->pNextLoop = pNext;
+ *ppPrev = p;
+ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
+ Index *pIndex = p->u.btree.pIndex;
+ if( pIndex && pIndex->tnum==0 ){
+ p->u.btree.pIndex = 0;
+ }
+ }
+ return SQLITE_OK;
+
+ /* Jump here if the insert is a no-op */
+whereLoopInsert_noop:
+#if WHERETRACE_ENABLED /* 0x8 */
+ if( sqlite3WhereTrace & 0x8 ){
+ sqlite3DebugPrintf("ins-noop: ");
+ whereLoopPrint(pTemplate, pBuilder->pWC);
+ }
+#endif
+ return SQLITE_OK;
+}
+
+/*
+** Adjust the WhereLoop.nOut value downward to account for terms of the
+** WHERE clause that reference the loop but which are not used by an
+** index.
+**
+** In the current implementation, the first extra WHERE clause term reduces
+** the number of output rows by a factor of 10 and each additional term
+** reduces the number of output rows by sqrt(2).
+*/
+static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){
+ WhereTerm *pTerm, *pX;
+ Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
+ int i, j;
+
+ if( !OptimizationEnabled(pWC->pWInfo->pParse->db, SQLITE_AdjustOutEst) ){
+ return;
+ }
+ for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
+ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
+ if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
+ if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
+ for(j=pLoop->nLTerm-1; j>=0; j--){
+ pX = pLoop->aLTerm[j];
+ if( pX==0 ) continue;
+ if( pX==pTerm ) break;
+ if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
+ }
+ if( j<0 ) pLoop->nOut += pTerm->truthProb;
+ }
+}
+
+/*
+** We have so far matched pBuilder->pNew->u.btree.nEq terms of the index pIndex.
+** Try to match one more.
+**
+** If pProbe->tnum==0, that means pIndex is a fake index used for the
+** INTEGER PRIMARY KEY.
+*/
+static int whereLoopAddBtreeIndex(
+ WhereLoopBuilder *pBuilder, /* The WhereLoop factory */
+ struct SrcList_item *pSrc, /* FROM clause term being analyzed */
+ Index *pProbe, /* An index on pSrc */
+ LogEst nInMul /* log(Number of iterations due to IN) */
+){
+ WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */
+ Parse *pParse = pWInfo->pParse; /* Parsing context */
+ sqlite3 *db = pParse->db; /* Database connection malloc context */
+ WhereLoop *pNew; /* Template WhereLoop under construction */
+ WhereTerm *pTerm; /* A WhereTerm under consideration */
+ int opMask; /* Valid operators for constraints */
+ WhereScan scan; /* Iterator for WHERE terms */
+ Bitmask saved_prereq; /* Original value of pNew->prereq */
+ u16 saved_nLTerm; /* Original value of pNew->nLTerm */
+ u16 saved_nEq; /* Original value of pNew->u.btree.nEq */
+ u16 saved_nSkip; /* Original value of pNew->u.btree.nSkip */
+ u32 saved_wsFlags; /* Original value of pNew->wsFlags */
+ LogEst saved_nOut; /* Original value of pNew->nOut */
+ int iCol; /* Index of the column in the table */
+ int rc = SQLITE_OK; /* Return code */
+ LogEst nRowEst; /* Estimated index selectivity */
+ LogEst rLogSize; /* Logarithm of table size */
+ WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
+
+ pNew = pBuilder->pNew;
+ if( db->mallocFailed ) return SQLITE_NOMEM;
+
+ assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
+ assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
+ if( pNew->wsFlags & WHERE_BTM_LIMIT ){
+ opMask = WO_LT|WO_LE;
+ }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
+ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
+ }else{
+ opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
+ }
+ if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
+
+ assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
+ if( pNew->u.btree.nEq < pProbe->nKeyCol ){
+ iCol = pProbe->aiColumn[pNew->u.btree.nEq];
+ nRowEst = sqlite3LogEst(pProbe->aiRowEst[pNew->u.btree.nEq+1]);
+ if( nRowEst==0 && pProbe->onError==OE_None ) nRowEst = 1;
+ }else{
+ iCol = -1;
+ nRowEst = 0;
+ }
+ pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
+ opMask, pProbe);
+ saved_nEq = pNew->u.btree.nEq;
+ saved_nSkip = pNew->u.btree.nSkip;
+ saved_nLTerm = pNew->nLTerm;
+ saved_wsFlags = pNew->wsFlags;
+ saved_prereq = pNew->prereq;
+ saved_nOut = pNew->nOut;
+ pNew->rSetup = 0;
+ rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0]));
+
+ /* Consider using a skip-scan if there are no WHERE clause constraints
+ ** available for the left-most terms of the index, and if the average
+ ** number of repeats in the left-most terms is at least 18. The magic
+ ** number 18 was found by experimentation to be the payoff point where
+ ** skip-scan become faster than a full-scan.
+ */
+ if( pTerm==0
+ && saved_nEq==saved_nSkip
+ && saved_nEq+1<pProbe->nKeyCol
+ && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
+ ){
+ LogEst nIter;
+ pNew->u.btree.nEq++;
+ pNew->u.btree.nSkip++;
+ pNew->aLTerm[pNew->nLTerm++] = 0;
+ pNew->wsFlags |= WHERE_SKIPSCAN;
+ nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
+ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
+ }
+ for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
+ int nIn = 0;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ int nRecValid = pBuilder->nRecValid;
+#endif
+ if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
+ && (iCol<0 || pSrc->pTab->aCol[iCol].notNull)
+ ){
+ continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
+ }
+ if( pTerm->prereqRight & pNew->maskSelf ) continue;
+
+ assert( pNew->nOut==saved_nOut );
+
+ pNew->wsFlags = saved_wsFlags;
+ pNew->u.btree.nEq = saved_nEq;
+ pNew->nLTerm = saved_nLTerm;
+ if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+ pNew->aLTerm[pNew->nLTerm++] = pTerm;
+ pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf;
+ pNew->rRun = rLogSize; /* Baseline cost is log2(N). Adjustments below */
+ if( pTerm->eOperator & WO_IN ){
+ Expr *pExpr = pTerm->pExpr;
+ pNew->wsFlags |= WHERE_COLUMN_IN;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
+ nIn = 46; assert( 46==sqlite3LogEst(25) );
+ }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
+ /* "x IN (value, value, ...)" */
+ nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
+ }
+ pNew->rRun += nIn;
+ pNew->u.btree.nEq++;
+ pNew->nOut = nRowEst + nInMul + nIn;
+ }else if( pTerm->eOperator & (WO_EQ) ){
+ assert(
+ (pNew->wsFlags & (WHERE_COLUMN_NULL|WHERE_COLUMN_IN|WHERE_SKIPSCAN))!=0
+ || nInMul==0
+ );
+ pNew->wsFlags |= WHERE_COLUMN_EQ;
+ if( iCol<0
+ || (pProbe->onError!=OE_None && nInMul==0
+ && pNew->u.btree.nEq==pProbe->nKeyCol-1)
+ ){
+ assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
+ pNew->wsFlags |= WHERE_ONEROW;
+ }
+ pNew->u.btree.nEq++;
+ pNew->nOut = nRowEst + nInMul;
+ }else if( pTerm->eOperator & (WO_ISNULL) ){
+ pNew->wsFlags |= WHERE_COLUMN_NULL;
+ pNew->u.btree.nEq++;
+ /* TUNING: IS NULL selects 2 rows */
+ nIn = 10; assert( 10==sqlite3LogEst(2) );
+ pNew->nOut = nRowEst + nInMul + nIn;
+ }else if( pTerm->eOperator & (WO_GT|WO_GE) ){
+ testcase( pTerm->eOperator & WO_GT );
+ testcase( pTerm->eOperator & WO_GE );
+ pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
+ pBtm = pTerm;
+ pTop = 0;
+ }else{
+ assert( pTerm->eOperator & (WO_LT|WO_LE) );
+ testcase( pTerm->eOperator & WO_LT );
+ testcase( pTerm->eOperator & WO_LE );
+ pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
+ pTop = pTerm;
+ pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
+ pNew->aLTerm[pNew->nLTerm-2] : 0;
+ }
+ if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
+ /* Adjust nOut and rRun for STAT3 range values */
+ assert( pNew->nOut==saved_nOut );
+ whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
+ }
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( nInMul==0
+ && pProbe->nSample
+ && pNew->u.btree.nEq<=pProbe->nSampleCol
+ && OptimizationEnabled(db, SQLITE_Stat3)
+ ){
+ Expr *pExpr = pTerm->pExpr;
+ tRowcnt nOut = 0;
+ if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){
+ testcase( pTerm->eOperator & WO_EQ );
+ testcase( pTerm->eOperator & WO_ISNULL );
+ rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
+ }else if( (pTerm->eOperator & WO_IN)
+ && !ExprHasProperty(pExpr, EP_xIsSelect) ){
+ rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
+ }
+ assert( nOut==0 || rc==SQLITE_OK );
+ if( nOut ){
+ pNew->nOut = sqlite3LogEst(nOut);
+ if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut;
+ }
+ }
+#endif
+ if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
+ /* Each row involves a step of the index, then a binary search of
+ ** the main table */
+ pNew->rRun = sqlite3LogEstAdd(pNew->rRun,rLogSize>27 ? rLogSize-17 : 10);
+ }
+ /* Step cost for each output row */
+ pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut);
+ whereLoopOutputAdjust(pBuilder->pWC, pNew);
+ rc = whereLoopInsert(pBuilder, pNew);
+ if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
+ && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0))
+ ){
+ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
+ }
+ pNew->nOut = saved_nOut;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ pBuilder->nRecValid = nRecValid;
+#endif
+ }
+ pNew->prereq = saved_prereq;
+ pNew->u.btree.nEq = saved_nEq;
+ pNew->u.btree.nSkip = saved_nSkip;
+ pNew->wsFlags = saved_wsFlags;
+ pNew->nOut = saved_nOut;
+ pNew->nLTerm = saved_nLTerm;
+ return rc;
+}
+
+/*
+** Return True if it is possible that pIndex might be useful in
+** implementing the ORDER BY clause in pBuilder.
+**
+** Return False if pBuilder does not contain an ORDER BY clause or
+** if there is no way for pIndex to be useful in implementing that
+** ORDER BY clause.
+*/
+static int indexMightHelpWithOrderBy(
+ WhereLoopBuilder *pBuilder,
+ Index *pIndex,
+ int iCursor
+){
+ ExprList *pOB;
+ int ii, jj;
+
+ if( pIndex->bUnordered ) return 0;
+ if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
+ for(ii=0; ii<pOB->nExpr; ii++){
+ Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
+ if( pExpr->op!=TK_COLUMN ) return 0;
+ if( pExpr->iTable==iCursor ){
+ for(jj=0; jj<pIndex->nKeyCol; jj++){
+ if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Return a bitmask where 1s indicate that the corresponding column of
+** the table is used by an index. Only the first 63 columns are considered.
+*/
+static Bitmask columnsInIndex(Index *pIdx){
+ Bitmask m = 0;
+ int j;
+ for(j=pIdx->nColumn-1; j>=0; j--){
+ int x = pIdx->aiColumn[j];
+ if( x>=0 ){
+ testcase( x==BMS-1 );
+ testcase( x==BMS-2 );
+ if( x<BMS-1 ) m |= MASKBIT(x);
+ }
+ }
+ return m;
+}
+
+/* Check to see if a partial index with pPartIndexWhere can be used
+** in the current query. Return true if it can be and false if not.
+*/
+static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
+ int i;
+ WhereTerm *pTerm;
+ for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
+ if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Add all WhereLoop objects for a single table of the join where the table
+** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
+** a b-tree table, not a virtual table.
+*/
+static int whereLoopAddBtree(
+ WhereLoopBuilder *pBuilder, /* WHERE clause information */
+ Bitmask mExtra /* Extra prerequesites for using this table */
+){
+ WhereInfo *pWInfo; /* WHERE analysis context */
+ Index *pProbe; /* An index we are evaluating */
+ Index sPk; /* A fake index object for the primary key */
+ tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
+ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */
+ SrcList *pTabList; /* The FROM clause */
+ struct SrcList_item *pSrc; /* The FROM clause btree term to add */
+ WhereLoop *pNew; /* Template WhereLoop object */
+ int rc = SQLITE_OK; /* Return code */
+ int iSortIdx = 1; /* Index number */
+ int b; /* A boolean value */
+ LogEst rSize; /* number of rows in the table */
+ LogEst rLogSize; /* Logarithm of the number of rows in the table */
+ WhereClause *pWC; /* The parsed WHERE clause */
+ Table *pTab; /* Table being queried */
+
+ pNew = pBuilder->pNew;
+ pWInfo = pBuilder->pWInfo;
+ pTabList = pWInfo->pTabList;
+ pSrc = pTabList->a + pNew->iTab;
+ pTab = pSrc->pTab;
+ pWC = pBuilder->pWC;
+ assert( !IsVirtual(pSrc->pTab) );
+
+ if( pSrc->pIndex ){
+ /* An INDEXED BY clause specifies a particular index to use */
+ pProbe = pSrc->pIndex;
+ }else if( !HasRowid(pTab) ){
+ pProbe = pTab->pIndex;
+ }else{
+ /* There is no INDEXED BY clause. Create a fake Index object in local
+ ** variable sPk to represent the rowid primary key index. Make this
+ ** fake index the first in a chain of Index objects with all of the real
+ ** indices to follow */
+ Index *pFirst; /* First of real indices on the table */
+ memset(&sPk, 0, sizeof(Index));
+ sPk.nKeyCol = 1;
+ sPk.aiColumn = &aiColumnPk;
+ sPk.aiRowEst = aiRowEstPk;
+ sPk.onError = OE_Replace;
+ sPk.pTable = pTab;
+ aiRowEstPk[0] = pTab->nRowEst;
+ aiRowEstPk[1] = 1;
+ pFirst = pSrc->pTab->pIndex;
+ if( pSrc->notIndexed==0 ){
+ /* The real indices of the table are only considered if the
+ ** NOT INDEXED qualifier is omitted from the FROM clause */
+ sPk.pNext = pFirst;
+ }
+ pProbe = &sPk;
+ }
+ rSize = sqlite3LogEst(pTab->nRowEst);
+ rLogSize = estLog(rSize);
+
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+ /* Automatic indexes */
+ if( !pBuilder->pOrSet
+ && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
+ && pSrc->pIndex==0
+ && !pSrc->viaCoroutine
+ && !pSrc->notIndexed
+ && HasRowid(pTab)
+ && !pSrc->isCorrelated
+ ){
+ /* Generate auto-index WhereLoops */
+ WhereTerm *pTerm;
+ WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
+ for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
+ if( pTerm->prereqRight & pNew->maskSelf ) continue;
+ if( termCanDriveIndex(pTerm, pSrc, 0) ){
+ pNew->u.btree.nEq = 1;
+ pNew->u.btree.nSkip = 0;
+ pNew->u.btree.pIndex = 0;
+ pNew->nLTerm = 1;
+ pNew->aLTerm[0] = pTerm;
+ /* TUNING: One-time cost for computing the automatic index is
+ ** approximately 7*N*log2(N) where N is the number of rows in
+ ** the table being indexed. */
+ pNew->rSetup = rLogSize + rSize + 28; assert( 28==sqlite3LogEst(7) );
+ /* TUNING: Each index lookup yields 20 rows in the table. This
+ ** is more than the usual guess of 10 rows, since we have no way
+ ** of knowning how selective the index will ultimately be. It would
+ ** not be unreasonable to make this value much larger. */
+ pNew->nOut = 43; assert( 43==sqlite3LogEst(20) );
+ pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
+ pNew->wsFlags = WHERE_AUTO_INDEX;
+ pNew->prereq = mExtra | pTerm->prereqRight;
+ rc = whereLoopInsert(pBuilder, pNew);
+ }
+ }
+ }
+#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
+
+ /* Loop over all indices
+ */
+ for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+ if( pProbe->pPartIdxWhere!=0
+ && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
+ continue; /* Partial index inappropriate for this query */
+ }
+ pNew->u.btree.nEq = 0;
+ pNew->u.btree.nSkip = 0;
+ pNew->nLTerm = 0;
+ pNew->iSortIdx = 0;
+ pNew->rSetup = 0;
+ pNew->prereq = mExtra;
+ pNew->nOut = rSize;
+ pNew->u.btree.pIndex = pProbe;
+ b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
+ /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
+ assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
+ if( pProbe->tnum<=0 ){
+ /* Integer primary key index */
+ pNew->wsFlags = WHERE_IPK;
+
+ /* Full table scan */
+ pNew->iSortIdx = b ? iSortIdx : 0;
+ /* TUNING: Cost of full table scan is 3*(N + log2(N)).
+ ** + The extra 3 factor is to encourage the use of indexed lookups
+ ** over full scans. FIXME */
+ pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16;
+ whereLoopOutputAdjust(pWC, pNew);
+ rc = whereLoopInsert(pBuilder, pNew);
+ pNew->nOut = rSize;
+ if( rc ) break;
+ }else{
+ Bitmask m;
+ if( pProbe->isCovering ){
+ pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
+ m = 0;
+ }else{
+ m = pSrc->colUsed & ~columnsInIndex(pProbe);
+ pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
+ }
+
+ /* Full scan via index */
+ if( b
+ || !HasRowid(pTab)
+ || ( m==0
+ && pProbe->bUnordered==0
+ && (pProbe->szIdxRow<pTab->szTabRow)
+ && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
+ && sqlite3GlobalConfig.bUseCis
+ && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
+ )
+ ){
+ pNew->iSortIdx = b ? iSortIdx : 0;
+ if( m==0 ){
+ /* TUNING: Cost of a covering index scan is K*(N + log2(N)).
+ ** + The extra factor K of between 1.1 and 3.0 that depends
+ ** on the relative sizes of the table and the index. K
+ ** is smaller for smaller indices, thus favoring them.
+ */
+ pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 +
+ (15*pProbe->szIdxRow)/pTab->szTabRow;
+ }else{
+ /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
+ ** which we will simplify to just N*log2(N) */
+ pNew->rRun = rSize + rLogSize;
}
- sqlite3DbFree(db, pInfo);
+ whereLoopOutputAdjust(pWC, pNew);
+ rc = whereLoopInsert(pBuilder, pNew);
+ pNew->nOut = rSize;
+ if( rc ) break;
}
- if( pWInfo->a[i].plan.wsFlags & WHERE_TEMP_INDEX ){
- Index *pIdx = pWInfo->a[i].plan.u.pIdx;
- if( pIdx ){
- sqlite3DbFree(db, pIdx->zColAff);
- sqlite3DbFree(db, pIdx);
+ }
+
+ rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sqlite3Stat4ProbeFree(pBuilder->pRec);
+ pBuilder->nRecValid = 0;
+ pBuilder->pRec = 0;
+#endif
+
+ /* If there was an INDEXED BY clause, then only that one index is
+ ** considered. */
+ if( pSrc->pIndex ) break;
+ }
+ return rc;
+}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Add all WhereLoop objects for a table of the join identified by
+** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table.
+*/
+static int whereLoopAddVirtual(
+ WhereLoopBuilder *pBuilder, /* WHERE clause information */
+ Bitmask mExtra
+){
+ WhereInfo *pWInfo; /* WHERE analysis context */
+ Parse *pParse; /* The parsing context */
+ WhereClause *pWC; /* The WHERE clause */
+ struct SrcList_item *pSrc; /* The FROM clause term to search */
+ Table *pTab;
+ sqlite3 *db;
+ sqlite3_index_info *pIdxInfo;
+ struct sqlite3_index_constraint *pIdxCons;
+ struct sqlite3_index_constraint_usage *pUsage;
+ WhereTerm *pTerm;
+ int i, j;
+ int iTerm, mxTerm;
+ int nConstraint;
+ int seenIn = 0; /* True if an IN operator is seen */
+ int seenVar = 0; /* True if a non-constant constraint is seen */
+ int iPhase; /* 0: const w/o IN, 1: const, 2: no IN, 2: IN */
+ WhereLoop *pNew;
+ int rc = SQLITE_OK;
+
+ pWInfo = pBuilder->pWInfo;
+ pParse = pWInfo->pParse;
+ db = pParse->db;
+ pWC = pBuilder->pWC;
+ pNew = pBuilder->pNew;
+ pSrc = &pWInfo->pTabList->a[pNew->iTab];
+ pTab = pSrc->pTab;
+ assert( IsVirtual(pTab) );
+ pIdxInfo = allocateIndexInfo(pParse, pWC, pSrc, pBuilder->pOrderBy);
+ if( pIdxInfo==0 ) return SQLITE_NOMEM;
+ pNew->prereq = 0;
+ pNew->rSetup = 0;
+ pNew->wsFlags = WHERE_VIRTUALTABLE;
+ pNew->nLTerm = 0;
+ pNew->u.vtab.needFree = 0;
+ pUsage = pIdxInfo->aConstraintUsage;
+ nConstraint = pIdxInfo->nConstraint;
+ if( whereLoopResize(db, pNew, nConstraint) ){
+ sqlite3DbFree(db, pIdxInfo);
+ return SQLITE_NOMEM;
+ }
+
+ for(iPhase=0; iPhase<=3; iPhase++){
+ if( !seenIn && (iPhase&1)!=0 ){
+ iPhase++;
+ if( iPhase>3 ) break;
+ }
+ if( !seenVar && iPhase>1 ) break;
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
+ j = pIdxCons->iTermOffset;
+ pTerm = &pWC->a[j];
+ switch( iPhase ){
+ case 0: /* Constants without IN operator */
+ pIdxCons->usable = 0;
+ if( (pTerm->eOperator & WO_IN)!=0 ){
+ seenIn = 1;
+ }
+ if( pTerm->prereqRight!=0 ){
+ seenVar = 1;
+ }else if( (pTerm->eOperator & WO_IN)==0 ){
+ pIdxCons->usable = 1;
+ }
+ break;
+ case 1: /* Constants with IN operators */
+ assert( seenIn );
+ pIdxCons->usable = (pTerm->prereqRight==0);
+ break;
+ case 2: /* Variables without IN */
+ assert( seenVar );
+ pIdxCons->usable = (pTerm->eOperator & WO_IN)==0;
+ break;
+ default: /* Variables with IN */
+ assert( seenVar && seenIn );
+ pIdxCons->usable = 1;
+ break;
+ }
+ }
+ memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint);
+ if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+ pIdxInfo->idxStr = 0;
+ pIdxInfo->idxNum = 0;
+ pIdxInfo->needToFreeIdxStr = 0;
+ pIdxInfo->orderByConsumed = 0;
+ pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
+ pIdxInfo->estimatedRows = 25;
+ rc = vtabBestIndex(pParse, pTab, pIdxInfo);
+ if( rc ) goto whereLoopAddVtab_exit;
+ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
+ pNew->prereq = mExtra;
+ mxTerm = -1;
+ assert( pNew->nLSlot>=nConstraint );
+ for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
+ pNew->u.vtab.omitMask = 0;
+ for(i=0; i<nConstraint; i++, pIdxCons++){
+ if( (iTerm = pUsage[i].argvIndex - 1)>=0 ){
+ j = pIdxCons->iTermOffset;
+ if( iTerm>=nConstraint
+ || j<0
+ || j>=pWC->nTerm
+ || pNew->aLTerm[iTerm]!=0
+ ){
+ rc = SQLITE_ERROR;
+ sqlite3ErrorMsg(pParse, "%s.xBestIndex() malfunction", pTab->zName);
+ goto whereLoopAddVtab_exit;
+ }
+ testcase( iTerm==nConstraint-1 );
+ testcase( j==0 );
+ testcase( j==pWC->nTerm-1 );
+ pTerm = &pWC->a[j];
+ pNew->prereq |= pTerm->prereqRight;
+ assert( iTerm<pNew->nLSlot );
+ pNew->aLTerm[iTerm] = pTerm;
+ if( iTerm>mxTerm ) mxTerm = iTerm;
+ testcase( iTerm==15 );
+ testcase( iTerm==16 );
+ if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
+ if( (pTerm->eOperator & WO_IN)!=0 ){
+ if( pUsage[i].omit==0 ){
+ /* Do not attempt to use an IN constraint if the virtual table
+ ** says that the equivalent EQ constraint cannot be safely omitted.
+ ** If we do attempt to use such a constraint, some rows might be
+ ** repeated in the output. */
+ break;
+ }
+ /* A virtual table that is constrained by an IN clause may not
+ ** consume the ORDER BY clause because (1) the order of IN terms
+ ** is not necessarily related to the order of output terms and
+ ** (2) Multiple outputs from a single IN value will not merge
+ ** together. */
+ pIdxInfo->orderByConsumed = 0;
}
}
}
- whereClauseClear(pWInfo->pWC);
- sqlite3DbFree(db, pWInfo);
+ if( i>=nConstraint ){
+ pNew->nLTerm = mxTerm+1;
+ assert( pNew->nLTerm<=pNew->nLSlot );
+ pNew->u.vtab.idxNum = pIdxInfo->idxNum;
+ pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr;
+ pIdxInfo->needToFreeIdxStr = 0;
+ pNew->u.vtab.idxStr = pIdxInfo->idxStr;
+ pNew->u.vtab.isOrdered = (u8)((pIdxInfo->nOrderBy!=0)
+ && pIdxInfo->orderByConsumed);
+ pNew->rSetup = 0;
+ pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
+ pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
+ whereLoopInsert(pBuilder, pNew);
+ if( pNew->u.vtab.needFree ){
+ sqlite3_free(pNew->u.vtab.idxStr);
+ pNew->u.vtab.needFree = 0;
+ }
+ }
+ }
+
+whereLoopAddVtab_exit:
+ if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
+ sqlite3DbFree(db, pIdxInfo);
+ return rc;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+/*
+** Add WhereLoop entries to handle OR terms. This works for either
+** btrees or virtual tables.
+*/
+static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ WhereClause *pWC;
+ WhereLoop *pNew;
+ WhereTerm *pTerm, *pWCEnd;
+ int rc = SQLITE_OK;
+ int iCur;
+ WhereClause tempWC;
+ WhereLoopBuilder sSubBuild;
+ WhereOrSet sSum, sCur, sPrev;
+ struct SrcList_item *pItem;
+
+ pWC = pBuilder->pWC;
+ if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
+ pWCEnd = pWC->a + pWC->nTerm;
+ pNew = pBuilder->pNew;
+ memset(&sSum, 0, sizeof(sSum));
+ pItem = pWInfo->pTabList->a + pNew->iTab;
+ if( !HasRowid(pItem->pTab) ) return SQLITE_OK;
+ iCur = pItem->iCursor;
+
+ for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
+ if( (pTerm->eOperator & WO_OR)!=0
+ && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
+ ){
+ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
+ WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
+ WhereTerm *pOrTerm;
+ int once = 1;
+ int i, j;
+
+ sSubBuild = *pBuilder;
+ sSubBuild.pOrderBy = 0;
+ sSubBuild.pOrSet = &sCur;
+
+ for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
+ if( (pOrTerm->eOperator & WO_AND)!=0 ){
+ sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
+ }else if( pOrTerm->leftCursor==iCur ){
+ tempWC.pWInfo = pWC->pWInfo;
+ tempWC.pOuter = pWC;
+ tempWC.op = TK_AND;
+ tempWC.nTerm = 1;
+ tempWC.a = pOrTerm;
+ sSubBuild.pWC = &tempWC;
+ }else{
+ continue;
+ }
+ sCur.n = 0;
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ if( IsVirtual(pItem->pTab) ){
+ rc = whereLoopAddVirtual(&sSubBuild, mExtra);
+ }else
+#endif
+ {
+ rc = whereLoopAddBtree(&sSubBuild, mExtra);
+ }
+ assert( rc==SQLITE_OK || sCur.n==0 );
+ if( sCur.n==0 ){
+ sSum.n = 0;
+ break;
+ }else if( once ){
+ whereOrMove(&sSum, &sCur);
+ once = 0;
+ }else{
+ whereOrMove(&sPrev, &sSum);
+ sSum.n = 0;
+ for(i=0; i<sPrev.n; i++){
+ for(j=0; j<sCur.n; j++){
+ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
+ sqlite3LogEstAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
+ sqlite3LogEstAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
+ }
+ }
+ }
+ }
+ pNew->nLTerm = 1;
+ pNew->aLTerm[0] = pTerm;
+ pNew->wsFlags = WHERE_MULTI_OR;
+ pNew->rSetup = 0;
+ pNew->iSortIdx = 0;
+ memset(&pNew->u, 0, sizeof(pNew->u));
+ for(i=0; rc==SQLITE_OK && i<sSum.n; i++){
+ /* TUNING: Multiple by 3.5 for the secondary table lookup */
+ pNew->rRun = sSum.a[i].rRun + 18;
+ pNew->nOut = sSum.a[i].nOut;
+ pNew->prereq = sSum.a[i].prereq;
+ rc = whereLoopInsert(pBuilder, pNew);
+ }
+ }
+ }
+ return rc;
+}
+
+/*
+** Add all WhereLoop objects for all tables
+*/
+static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
+ WhereInfo *pWInfo = pBuilder->pWInfo;
+ Bitmask mExtra = 0;
+ Bitmask mPrior = 0;
+ int iTab;
+ SrcList *pTabList = pWInfo->pTabList;
+ struct SrcList_item *pItem;
+ sqlite3 *db = pWInfo->pParse->db;
+ int nTabList = pWInfo->nLevel;
+ int rc = SQLITE_OK;
+ u8 priorJoinType = 0;
+ WhereLoop *pNew;
+
+ /* Loop over the tables in the join, from left to right */
+ pNew = pBuilder->pNew;
+ whereLoopInit(pNew);
+ for(iTab=0, pItem=pTabList->a; iTab<nTabList; iTab++, pItem++){
+ pNew->iTab = iTab;
+ pNew->maskSelf = getMask(&pWInfo->sMaskSet, pItem->iCursor);
+ if( ((pItem->jointype|priorJoinType) & (JT_LEFT|JT_CROSS))!=0 ){
+ mExtra = mPrior;
+ }
+ priorJoinType = pItem->jointype;
+ if( IsVirtual(pItem->pTab) ){
+ rc = whereLoopAddVirtual(pBuilder, mExtra);
+ }else{
+ rc = whereLoopAddBtree(pBuilder, mExtra);
+ }
+ if( rc==SQLITE_OK ){
+ rc = whereLoopAddOr(pBuilder, mExtra);
+ }
+ mPrior |= pNew->maskSelf;
+ if( rc || db->mallocFailed ) break;
+ }
+ whereLoopClear(db, pNew);
+ return rc;
+}
+
+/*
+** Examine a WherePath (with the addition of the extra WhereLoop of the 5th
+** parameters) to see if it outputs rows in the requested ORDER BY
+** (or GROUP BY) without requiring a separate sort operation. Return:
+**
+** 0: ORDER BY is not satisfied. Sorting required
+** 1: ORDER BY is satisfied. Omit sorting
+** -1: Unknown at this time
+**
+** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as
+** strict. With GROUP BY and DISTINCT the only requirement is that
+** equivalent rows appear immediately adjacent to one another. GROUP BY
+** and DISTINT do not require rows to appear in any particular order as long
+** as equivelent rows are grouped together. Thus for GROUP BY and DISTINCT
+** the pOrderBy terms can be matched in any order. With ORDER BY, the
+** pOrderBy terms must be matched in strict left-to-right order.
+*/
+static int wherePathSatisfiesOrderBy(
+ WhereInfo *pWInfo, /* The WHERE clause */
+ ExprList *pOrderBy, /* ORDER BY or GROUP BY or DISTINCT clause to check */
+ WherePath *pPath, /* The WherePath to check */
+ u16 wctrlFlags, /* Might contain WHERE_GROUPBY or WHERE_DISTINCTBY */
+ u16 nLoop, /* Number of entries in pPath->aLoop[] */
+ WhereLoop *pLast, /* Add this WhereLoop to the end of pPath->aLoop[] */
+ Bitmask *pRevMask /* OUT: Mask of WhereLoops to run in reverse order */
+){
+ u8 revSet; /* True if rev is known */
+ u8 rev; /* Composite sort order */
+ u8 revIdx; /* Index sort order */
+ u8 isOrderDistinct; /* All prior WhereLoops are order-distinct */
+ u8 distinctColumns; /* True if the loop has UNIQUE NOT NULL columns */
+ u8 isMatch; /* iColumn matches a term of the ORDER BY clause */
+ u16 nKeyCol; /* Number of key columns in pIndex */
+ u16 nColumn; /* Total number of ordered columns in the index */
+ u16 nOrderBy; /* Number terms in the ORDER BY clause */
+ int iLoop; /* Index of WhereLoop in pPath being processed */
+ int i, j; /* Loop counters */
+ int iCur; /* Cursor number for current WhereLoop */
+ int iColumn; /* A column number within table iCur */
+ WhereLoop *pLoop = 0; /* Current WhereLoop being processed. */
+ WhereTerm *pTerm; /* A single term of the WHERE clause */
+ Expr *pOBExpr; /* An expression from the ORDER BY clause */
+ CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */
+ Index *pIndex; /* The index associated with pLoop */
+ sqlite3 *db = pWInfo->pParse->db; /* Database connection */
+ Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */
+ Bitmask obDone; /* Mask of all ORDER BY terms */
+ Bitmask orderDistinctMask; /* Mask of all well-ordered loops */
+ Bitmask ready; /* Mask of inner loops */
+
+ /*
+ ** We say the WhereLoop is "one-row" if it generates no more than one
+ ** row of output. A WhereLoop is one-row if all of the following are true:
+ ** (a) All index columns match with WHERE_COLUMN_EQ.
+ ** (b) The index is unique
+ ** Any WhereLoop with an WHERE_COLUMN_EQ constraint on the rowid is one-row.
+ ** Every one-row WhereLoop will have the WHERE_ONEROW bit set in wsFlags.
+ **
+ ** We say the WhereLoop is "order-distinct" if the set of columns from
+ ** that WhereLoop that are in the ORDER BY clause are different for every
+ ** row of the WhereLoop. Every one-row WhereLoop is automatically
+ ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause
+ ** is not order-distinct. To be order-distinct is not quite the same as being
+ ** UNIQUE since a UNIQUE column or index can have multiple rows that
+ ** are NULL and NULL values are equivalent for the purpose of order-distinct.
+ ** To be order-distinct, the columns must be UNIQUE and NOT NULL.
+ **
+ ** The rowid for a table is always UNIQUE and NOT NULL so whenever the
+ ** rowid appears in the ORDER BY clause, the corresponding WhereLoop is
+ ** automatically order-distinct.
+ */
+
+ assert( pOrderBy!=0 );
+
+ /* Sortability of virtual tables is determined by the xBestIndex method
+ ** of the virtual table itself */
+ if( pLast->wsFlags & WHERE_VIRTUALTABLE ){
+ testcase( nLoop>0 ); /* True when outer loops are one-row and match
+ ** no ORDER BY terms */
+ return pLast->u.vtab.isOrdered;
+ }
+ if( nLoop && OptimizationDisabled(db, SQLITE_OrderByIdxJoin) ) return 0;
+
+ nOrderBy = pOrderBy->nExpr;
+ testcase( nOrderBy==BMS-1 );
+ if( nOrderBy>BMS-1 ) return 0; /* Cannot optimize overly large ORDER BYs */
+ isOrderDistinct = 1;
+ obDone = MASKBIT(nOrderBy)-1;
+ orderDistinctMask = 0;
+ ready = 0;
+ for(iLoop=0; isOrderDistinct && obSat<obDone && iLoop<=nLoop; iLoop++){
+ if( iLoop>0 ) ready |= pLoop->maskSelf;
+ pLoop = iLoop<nLoop ? pPath->aLoop[iLoop] : pLast;
+ assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
+ iCur = pWInfo->pTabList->a[pLoop->iTab].iCursor;
+
+ /* Mark off any ORDER BY term X that is a column in the table of
+ ** the current loop for which there is term in the WHERE
+ ** clause of the form X IS NULL or X=? that reference only outer
+ ** loops.
+ */
+ for(i=0; i<nOrderBy; i++){
+ if( MASKBIT(i) & obSat ) continue;
+ pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+ if( pOBExpr->op!=TK_COLUMN ) continue;
+ if( pOBExpr->iTable!=iCur ) continue;
+ pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
+ ~ready, WO_EQ|WO_ISNULL, 0);
+ if( pTerm==0 ) continue;
+ if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
+ const char *z1, *z2;
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ z1 = pColl->zName;
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ z2 = pColl->zName;
+ if( sqlite3StrICmp(z1, z2)!=0 ) continue;
+ }
+ obSat |= MASKBIT(i);
+ }
+
+ if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
+ if( pLoop->wsFlags & WHERE_IPK ){
+ pIndex = 0;
+ nKeyCol = 0;
+ nColumn = 1;
+ }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
+ return 0;
+ }else{
+ nKeyCol = pIndex->nKeyCol;
+ nColumn = pIndex->nColumn;
+ assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
+ assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable));
+ isOrderDistinct = pIndex->onError!=OE_None;
+ }
+
+ /* Loop through all columns of the index and deal with the ones
+ ** that are not constrained by == or IN.
+ */
+ rev = revSet = 0;
+ distinctColumns = 0;
+ for(j=0; j<nColumn; j++){
+ u8 bOnce; /* True to run the ORDER BY search loop */
+
+ /* Skip over == and IS NULL terms */
+ if( j<pLoop->u.btree.nEq
+ && pLoop->u.btree.nSkip==0
+ && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
+ ){
+ if( i & WO_ISNULL ){
+ testcase( isOrderDistinct );
+ isOrderDistinct = 0;
+ }
+ continue;
+ }
+
+ /* Get the column number in the table (iColumn) and sort order
+ ** (revIdx) for the j-th column of the index.
+ */
+ if( pIndex ){
+ iColumn = pIndex->aiColumn[j];
+ revIdx = pIndex->aSortOrder[j];
+ if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
+ }else{
+ iColumn = -1;
+ revIdx = 0;
+ }
+
+ /* An unconstrained column that might be NULL means that this
+ ** WhereLoop is not well-ordered
+ */
+ if( isOrderDistinct
+ && iColumn>=0
+ && j>=pLoop->u.btree.nEq
+ && pIndex->pTable->aCol[iColumn].notNull==0
+ ){
+ isOrderDistinct = 0;
+ }
+
+ /* Find the ORDER BY term that corresponds to the j-th column
+ ** of the index and and mark that ORDER BY term off
+ */
+ bOnce = 1;
+ isMatch = 0;
+ for(i=0; bOnce && i<nOrderBy; i++){
+ if( MASKBIT(i) & obSat ) continue;
+ pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
+ testcase( wctrlFlags & WHERE_GROUPBY );
+ testcase( wctrlFlags & WHERE_DISTINCTBY );
+ if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
+ if( pOBExpr->op!=TK_COLUMN ) continue;
+ if( pOBExpr->iTable!=iCur ) continue;
+ if( pOBExpr->iColumn!=iColumn ) continue;
+ if( iColumn>=0 ){
+ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
+ if( !pColl ) pColl = db->pDfltColl;
+ if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
+ }
+ isMatch = 1;
+ break;
+ }
+ if( isMatch ){
+ if( iColumn<0 ){
+ testcase( distinctColumns==0 );
+ distinctColumns = 1;
+ }
+ obSat |= MASKBIT(i);
+ if( (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
+ /* Make sure the sort order is compatible in an ORDER BY clause.
+ ** Sort order is irrelevant for a GROUP BY clause. */
+ if( revSet ){
+ if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) return 0;
+ }else{
+ rev = revIdx ^ pOrderBy->a[i].sortOrder;
+ if( rev ) *pRevMask |= MASKBIT(iLoop);
+ revSet = 1;
+ }
+ }
+ }else{
+ /* No match found */
+ if( j==0 || j<nKeyCol ){
+ testcase( isOrderDistinct!=0 );
+ isOrderDistinct = 0;
+ }
+ break;
+ }
+ } /* end Loop over all index columns */
+ if( distinctColumns ){
+ testcase( isOrderDistinct==0 );
+ isOrderDistinct = 1;
+ }
+ } /* end-if not one-row */
+
+ /* Mark off any other ORDER BY terms that reference pLoop */
+ if( isOrderDistinct ){
+ orderDistinctMask |= pLoop->maskSelf;
+ for(i=0; i<nOrderBy; i++){
+ Expr *p;
+ if( MASKBIT(i) & obSat ) continue;
+ p = pOrderBy->a[i].pExpr;
+ if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
+ obSat |= MASKBIT(i);
+ }
+ }
+ }
+ } /* End the loop over all WhereLoops from outer-most down to inner-most */
+ if( obSat==obDone ) return 1;
+ if( !isOrderDistinct ) return 0;
+ return -1;
+}
+
+#ifdef WHERETRACE_ENABLED
+/* For debugging use only: */
+static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
+ static char zName[65];
+ int i;
+ for(i=0; i<nLoop; i++){ zName[i] = pPath->aLoop[i]->cId; }
+ if( pLast ) zName[i++] = pLast->cId;
+ zName[i] = 0;
+ return zName;
+}
+#endif
+
+
+/*
+** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
+** attempts to find the lowest cost path that visits each WhereLoop
+** once. This path is then loaded into the pWInfo->a[].pWLoop fields.
+**
+** Assume that the total number of output rows that will need to be sorted
+** will be nRowEst (in the 10*log2 representation). Or, ignore sorting
+** costs if nRowEst==0.
+**
+** Return SQLITE_OK on success or SQLITE_NOMEM of a memory allocation
+** error occurs.
+*/
+static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
+ int mxChoice; /* Maximum number of simultaneous paths tracked */
+ int nLoop; /* Number of terms in the join */
+ Parse *pParse; /* Parsing context */
+ sqlite3 *db; /* The database connection */
+ int iLoop; /* Loop counter over the terms of the join */
+ int ii, jj; /* Loop counters */
+ int mxI = 0; /* Index of next entry to replace */
+ LogEst rCost; /* Cost of a path */
+ LogEst nOut; /* Number of outputs */
+ LogEst mxCost = 0; /* Maximum cost of a set of paths */
+ LogEst mxOut = 0; /* Maximum nOut value on the set of paths */
+ LogEst rSortCost; /* Cost to do a sort */
+ int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
+ WherePath *aFrom; /* All nFrom paths at the previous level */
+ WherePath *aTo; /* The nTo best paths at the current level */
+ WherePath *pFrom; /* An element of aFrom[] that we are working on */
+ WherePath *pTo; /* An element of aTo[] that we are working on */
+ WhereLoop *pWLoop; /* One of the WhereLoop objects */
+ WhereLoop **pX; /* Used to divy up the pSpace memory */
+ char *pSpace; /* Temporary memory used by this routine */
+
+ pParse = pWInfo->pParse;
+ db = pParse->db;
+ nLoop = pWInfo->nLevel;
+ /* TUNING: For simple queries, only the best path is tracked.
+ ** For 2-way joins, the 5 best paths are followed.
+ ** For joins of 3 or more tables, track the 10 best paths */
+ mxChoice = (nLoop==1) ? 1 : (nLoop==2 ? 5 : 10);
+ assert( nLoop<=pWInfo->pTabList->nSrc );
+ WHERETRACE(0x002, ("---- begin solver\n"));
+
+ /* Allocate and initialize space for aTo and aFrom */
+ ii = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2;
+ pSpace = sqlite3DbMallocRaw(db, ii);
+ if( pSpace==0 ) return SQLITE_NOMEM;
+ aTo = (WherePath*)pSpace;
+ aFrom = aTo+mxChoice;
+ memset(aFrom, 0, sizeof(aFrom[0]));
+ pX = (WhereLoop**)(aFrom+mxChoice);
+ for(ii=mxChoice*2, pFrom=aTo; ii>0; ii--, pFrom++, pX += nLoop){
+ pFrom->aLoop = pX;
+ }
+
+ /* Seed the search with a single WherePath containing zero WhereLoops.
+ **
+ ** TUNING: Do not let the number of iterations go above 25. If the cost
+ ** of computing an automatic index is not paid back within the first 25
+ ** rows, then do not use the automatic index. */
+ aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) );
+ nFrom = 1;
+
+ /* Precompute the cost of sorting the final result set, if the caller
+ ** to sqlite3WhereBegin() was concerned about sorting */
+ rSortCost = 0;
+ if( pWInfo->pOrderBy==0 || nRowEst==0 ){
+ aFrom[0].isOrderedValid = 1;
+ }else{
+ /* TUNING: Estimated cost of sorting is 48*N*log2(N) where N is the
+ ** number of output rows. The 48 is the expected size of a row to sort.
+ ** FIXME: compute a better estimate of the 48 multiplier based on the
+ ** result set expressions. */
+ rSortCost = nRowEst + estLog(nRowEst);
+ WHERETRACE(0x002,("---- sort cost=%-3d\n", rSortCost));
+ }
+
+ /* Compute successively longer WherePaths using the previous generation
+ ** of WherePaths as the basis for the next. Keep track of the mxChoice
+ ** best paths at each generation */
+ for(iLoop=0; iLoop<nLoop; iLoop++){
+ nTo = 0;
+ for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
+ for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
+ Bitmask maskNew;
+ Bitmask revMask = 0;
+ u8 isOrderedValid = pFrom->isOrderedValid;
+ u8 isOrdered = pFrom->isOrdered;
+ if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
+ if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+ /* At this point, pWLoop is a candidate to be the next loop.
+ ** Compute its cost */
+ rCost = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
+ rCost = sqlite3LogEstAdd(rCost, pFrom->rCost);
+ nOut = pFrom->nRow + pWLoop->nOut;
+ maskNew = pFrom->maskLoop | pWLoop->maskSelf;
+ if( !isOrderedValid ){
+ switch( wherePathSatisfiesOrderBy(pWInfo,
+ pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
+ iLoop, pWLoop, &revMask) ){
+ case 1: /* Yes. pFrom+pWLoop does satisfy the ORDER BY clause */
+ isOrdered = 1;
+ isOrderedValid = 1;
+ break;
+ case 0: /* No. pFrom+pWLoop will require a separate sort */
+ isOrdered = 0;
+ isOrderedValid = 1;
+ rCost = sqlite3LogEstAdd(rCost, rSortCost);
+ break;
+ default: /* Cannot tell yet. Try again on the next iteration */
+ break;
+ }
+ }else{
+ revMask = pFrom->revLoop;
+ }
+ /* Check to see if pWLoop should be added to the mxChoice best so far */
+ for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
+ if( pTo->maskLoop==maskNew
+ && pTo->isOrderedValid==isOrderedValid
+ && ((pTo->rCost<=rCost && pTo->nRow<=nOut) ||
+ (pTo->rCost>=rCost && pTo->nRow>=nOut))
+ ){
+ testcase( jj==nTo-1 );
+ break;
+ }
+ }
+ if( jj>=nTo ){
+ if( nTo>=mxChoice && rCost>=mxCost ){
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf("Skip %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+ }
+#endif
+ continue;
+ }
+ /* Add a new Path to the aTo[] set */
+ if( nTo<mxChoice ){
+ /* Increase the size of the aTo set by one */
+ jj = nTo++;
+ }else{
+ /* New path replaces the prior worst to keep count below mxChoice */
+ jj = mxI;
+ }
+ pTo = &aTo[jj];
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf("New %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+ }
+#endif
+ }else{
+ if( pTo->rCost<=rCost && pTo->nRow<=nOut ){
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf(
+ "Skip %s cost=%-3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+ sqlite3DebugPrintf(" vs %s cost=%-3d,%d order=%c\n",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+ }
+#endif
+ testcase( pTo->rCost==rCost );
+ continue;
+ }
+ testcase( pTo->rCost==rCost+1 );
+ /* A new and better score for a previously created equivalent path */
+#ifdef WHERETRACE_ENABLED /* 0x4 */
+ if( sqlite3WhereTrace&0x4 ){
+ sqlite3DebugPrintf(
+ "Update %s cost=%-3d,%3d order=%c",
+ wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
+ isOrderedValid ? (isOrdered ? 'Y' : 'N') : '?');
+ sqlite3DebugPrintf(" was %s cost=%-3d,%3d order=%c\n",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+ }
+#endif
+ }
+ /* pWLoop is a winner. Add it to the set of best so far */
+ pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
+ pTo->revLoop = revMask;
+ pTo->nRow = nOut;
+ pTo->rCost = rCost;
+ pTo->isOrderedValid = isOrderedValid;
+ pTo->isOrdered = isOrdered;
+ memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
+ pTo->aLoop[iLoop] = pWLoop;
+ if( nTo>=mxChoice ){
+ mxI = 0;
+ mxCost = aTo[0].rCost;
+ mxOut = aTo[0].nRow;
+ for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
+ if( pTo->rCost>mxCost || (pTo->rCost==mxCost && pTo->nRow>mxOut) ){
+ mxCost = pTo->rCost;
+ mxOut = pTo->nRow;
+ mxI = jj;
+ }
+ }
+ }
+ }
+ }
+
+#ifdef WHERETRACE_ENABLED /* >=2 */
+ if( sqlite3WhereTrace>=2 ){
+ sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
+ for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
+ sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
+ wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
+ pTo->isOrderedValid ? (pTo->isOrdered ? 'Y' : 'N') : '?');
+ if( pTo->isOrderedValid && pTo->isOrdered ){
+ sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
+ }else{
+ sqlite3DebugPrintf("\n");
+ }
+ }
+ }
+#endif
+
+ /* Swap the roles of aFrom and aTo for the next generation */
+ pFrom = aTo;
+ aTo = aFrom;
+ aFrom = pFrom;
+ nFrom = nTo;
+ }
+
+ if( nFrom==0 ){
+ sqlite3ErrorMsg(pParse, "no query solution");
+ sqlite3DbFree(db, pSpace);
+ return SQLITE_ERROR;
}
+
+ /* Find the lowest cost path. pFrom will be left pointing to that path */
+ pFrom = aFrom;
+ for(ii=1; ii<nFrom; ii++){
+ if( pFrom->rCost>aFrom[ii].rCost ) pFrom = &aFrom[ii];
+ }
+ assert( pWInfo->nLevel==nLoop );
+ /* Load the lowest cost path into pWInfo */
+ for(iLoop=0; iLoop<nLoop; iLoop++){
+ WhereLevel *pLevel = pWInfo->a + iLoop;
+ pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
+ pLevel->iFrom = pWLoop->iTab;
+ pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
+ }
+ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0
+ && (pWInfo->wctrlFlags & WHERE_DISTINCTBY)==0
+ && pWInfo->eDistinct==WHERE_DISTINCT_NOOP
+ && nRowEst
+ ){
+ Bitmask notUsed;
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
+ WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
+ if( rc==1 ) pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+ }
+ if( pFrom->isOrdered ){
+ if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
+ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+ }else{
+ pWInfo->bOBSat = 1;
+ pWInfo->revMask = pFrom->revLoop;
+ }
+ }
+ pWInfo->nRowOut = pFrom->nRow;
+
+ /* Free temporary memory and return success */
+ sqlite3DbFree(db, pSpace);
+ return SQLITE_OK;
}
+/*
+** Most queries use only a single table (they are not joins) and have
+** simple == constraints against indexed fields. This routine attempts
+** to plan those simple cases using much less ceremony than the
+** general-purpose query planner, and thereby yield faster sqlite3_prepare()
+** times for the common case.
+**
+** Return non-zero on success, if this query can be handled by this
+** no-frills query planner. Return zero if this query needs the
+** general-purpose query planner.
+*/
+static int whereShortCut(WhereLoopBuilder *pBuilder){
+ WhereInfo *pWInfo;
+ struct SrcList_item *pItem;
+ WhereClause *pWC;
+ WhereTerm *pTerm;
+ WhereLoop *pLoop;
+ int iCur;
+ int j;
+ Table *pTab;
+ Index *pIdx;
+
+ pWInfo = pBuilder->pWInfo;
+ if( pWInfo->wctrlFlags & WHERE_FORCE_TABLE ) return 0;
+ assert( pWInfo->pTabList->nSrc>=1 );
+ pItem = pWInfo->pTabList->a;
+ pTab = pItem->pTab;
+ if( IsVirtual(pTab) ) return 0;
+ if( pItem->zIndex ) return 0;
+ iCur = pItem->iCursor;
+ pWC = &pWInfo->sWC;
+ pLoop = pBuilder->pNew;
+ pLoop->wsFlags = 0;
+ pLoop->u.btree.nSkip = 0;
+ pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
+ if( pTerm ){
+ pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
+ pLoop->aLTerm[0] = pTerm;
+ pLoop->nLTerm = 1;
+ pLoop->u.btree.nEq = 1;
+ /* TUNING: Cost of a rowid lookup is 10 */
+ pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */
+ }else{
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pLoop->aLTermSpace==pLoop->aLTerm );
+ assert( ArraySize(pLoop->aLTermSpace)==4 );
+ if( pIdx->onError==OE_None
+ || pIdx->pPartIdxWhere!=0
+ || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
+ ) continue;
+ for(j=0; j<pIdx->nKeyCol; j++){
+ pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
+ if( pTerm==0 ) break;
+ pLoop->aLTerm[j] = pTerm;
+ }
+ if( j!=pIdx->nKeyCol ) continue;
+ pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
+ if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
+ pLoop->wsFlags |= WHERE_IDX_ONLY;
+ }
+ pLoop->nLTerm = j;
+ pLoop->u.btree.nEq = j;
+ pLoop->u.btree.pIndex = pIdx;
+ /* TUNING: Cost of a unique index lookup is 15 */
+ pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */
+ break;
+ }
+ }
+ if( pLoop->wsFlags ){
+ pLoop->nOut = (LogEst)1;
+ pWInfo->a[0].pWLoop = pLoop;
+ pLoop->maskSelf = getMask(&pWInfo->sMaskSet, iCur);
+ pWInfo->a[0].iTabCur = iCur;
+ pWInfo->nRowOut = 1;
+ if( pWInfo->pOrderBy ) pWInfo->bOBSat = 1;
+ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }
+#ifdef SQLITE_DEBUG
+ pLoop->cId = '0';
+#endif
+ return 1;
+ }
+ return 0;
+}
/*
** Generate the beginning of the loop used for WHERE clause processing.
@@ -109413,25 +113741,25 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
**
** ORDER BY CLAUSE PROCESSING
**
-** pOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** pOrderBy is a pointer to the ORDER BY clause (or the GROUP BY clause
+** if the WHERE_GROUPBY flag is set in wctrlFlags) of a SELECT statement
** if there is one. If there is no ORDER BY clause or if this routine
** is called from an UPDATE or DELETE statement, then pOrderBy is NULL.
**
-** If an index can be used so that the natural output order of the table
-** scan is correct for the ORDER BY clause, then that index is used and
-** the returned WhereInfo.nOBSat field is set to pOrderBy->nExpr. This
-** is an optimization that prevents an unnecessary sort of the result set
-** if an index appropriate for the ORDER BY clause already exists.
-**
-** If the where clause loops cannot be arranged to provide the correct
-** output order, then WhereInfo.nOBSat is 0.
+** The iIdxCur parameter is the cursor number of an index. If
+** WHERE_ONETABLE_ONLY is set, iIdxCur is the cursor number of an index
+** to use for OR clause processing. The WHERE clause should use this
+** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is
+** the first cursor in an array of cursors for all indices. iIdxCur should
+** be used to compute the appropriate cursor depending on which index is
+** used.
*/
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Parse *pParse, /* The parser context */
- SrcList *pTabList, /* A list of all tables to be scanned */
+ SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY clause, or NULL */
- ExprList *pDistinct, /* The select-list for DISTINCT queries - or NULL */
+ ExprList *pResultSet, /* Result set of the query */
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
int iIdxCur /* If WHERE_ONETABLE_ONLY is set, index cursor number */
){
@@ -109440,18 +113768,25 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
WhereInfo *pWInfo; /* Will become the return value of this function */
Vdbe *v = pParse->pVdbe; /* The virtual database engine */
Bitmask notReady; /* Cursors that are not yet positioned */
- WhereBestIdx sWBI; /* Best index search context */
+ WhereLoopBuilder sWLB; /* The WhereLoop builder */
WhereMaskSet *pMaskSet; /* The expression mask set */
WhereLevel *pLevel; /* A single level in pWInfo->a[] */
- int iFrom; /* First unused FROM clause element */
- int andFlags; /* AND-ed combination of all pWC->a[].wtFlags */
+ WhereLoop *pLoop; /* Pointer to a single WhereLoop object */
int ii; /* Loop counter */
sqlite3 *db; /* Database connection */
+ int rc; /* Return code */
/* Variable initialization */
- memset(&sWBI, 0, sizeof(sWBI));
- sWBI.pParse = pParse;
+ db = pParse->db;
+ memset(&sWLB, 0, sizeof(sWLB));
+ sWLB.pOrderBy = pOrderBy;
+
+ /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
+ ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
+ if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
+ wctrlFlags &= ~WHERE_WANT_DISTINCT;
+ }
/* The number of tables in the FROM clause is limited by the number of
** bits in a Bitmask
@@ -109476,39 +113811,39 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** field (type Bitmask) it must be aligned on an 8-byte boundary on
** some architectures. Hence the ROUND8() below.
*/
- db = pParse->db;
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
- pWInfo = sqlite3DbMallocZero(db,
- nByteWInfo +
- sizeof(WhereClause) +
- sizeof(WhereMaskSet)
- );
+ pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
if( db->mallocFailed ){
sqlite3DbFree(db, pWInfo);
pWInfo = 0;
goto whereBeginError;
}
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
pWInfo->nLevel = nTabList;
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
+ pWInfo->pOrderBy = pOrderBy;
+ pWInfo->pResultSet = pResultSet;
pWInfo->iBreak = sqlite3VdbeMakeLabel(v);
- pWInfo->pWC = sWBI.pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
- pMaskSet = (WhereMaskSet*)&sWBI.pWC[1];
- sWBI.aLevel = pWInfo->a;
-
- /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
- ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
- if( OptimizationDisabled(db, SQLITE_DistinctOpt) ) pDistinct = 0;
+ pMaskSet = &pWInfo->sMaskSet;
+ sWLB.pWInfo = pWInfo;
+ sWLB.pWC = &pWInfo->sWC;
+ sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
+ assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
+ whereLoopInit(sWLB.pNew);
+#ifdef SQLITE_DEBUG
+ sWLB.pNew->cId = '*';
+#endif
/* Split the WHERE clause into separate subexpressions where each
** subexpression is separated by an AND operator.
*/
initMaskSet(pMaskSet);
- whereClauseInit(sWBI.pWC, pParse, pMaskSet, wctrlFlags);
- sqlite3ExprCodeConstants(pParse, pWhere);
- whereSplit(sWBI.pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
+ whereClauseInit(&pWInfo->sWC, pWInfo);
+ whereSplit(&pWInfo->sWC, pWhere, TK_AND);
+ sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
/* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru.
@@ -109518,6 +113853,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pWhere = 0;
}
+ /* Special case: No FROM clause
+ */
+ if( nTabList==0 ){
+ if( pOrderBy ) pWInfo->bOBSat = 1;
+ if( wctrlFlags & WHERE_WANT_DISTINCT ){
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }
+ }
+
/* Assign a bit from the bitmask to every term in the FROM clause.
**
** When assigning bitmask values to FROM clause cursors, it must be
@@ -109553,306 +113897,167 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** want to analyze these virtual terms, so start analyzing at the end
** and work forward so that the added virtual terms are never processed.
*/
- exprAnalyzeAll(pTabList, sWBI.pWC);
+ exprAnalyzeAll(pTabList, &pWInfo->sWC);
if( db->mallocFailed ){
goto whereBeginError;
}
- /* Check if the DISTINCT qualifier, if there is one, is redundant.
- ** If it is, then set pDistinct to NULL and WhereInfo.eDistinct to
- ** WHERE_DISTINCT_UNIQUE to tell the caller to ignore the DISTINCT.
+ /* If the ORDER BY (or GROUP BY) clause contains references to general
+ ** expressions, then we won't be able to satisfy it using indices, so
+ ** go ahead and disable it now.
*/
- if( pDistinct && isDistinctRedundant(pParse, pTabList, sWBI.pWC, pDistinct) ){
- pDistinct = 0;
- pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
+ for(ii=0; ii<pOrderBy->nExpr; ii++){
+ Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
+ if( pExpr->op!=TK_COLUMN ){
+ pWInfo->pOrderBy = pOrderBy = 0;
+ break;
+ }else if( pExpr->iColumn<0 ){
+ break;
+ }
+ }
}
- /* Chose the best index to use for each table in the FROM clause.
- **
- ** This loop fills in the following fields:
- **
- ** pWInfo->a[].pIdx The index to use for this level of the loop.
- ** pWInfo->a[].wsFlags WHERE_xxx flags associated with pIdx
- ** pWInfo->a[].nEq The number of == and IN constraints
- ** pWInfo->a[].iFrom Which term of the FROM clause is being coded
- ** pWInfo->a[].iTabCur The VDBE cursor for the database table
- ** pWInfo->a[].iIdxCur The VDBE cursor for the index
- ** pWInfo->a[].pTerm When wsFlags==WO_OR, the OR-clause term
- **
- ** This loop also figures out the nesting order of tables in the FROM
- ** clause.
- */
- sWBI.notValid = ~(Bitmask)0;
- sWBI.pOrderBy = pOrderBy;
- sWBI.n = nTabList;
- sWBI.pDistinct = pDistinct;
- andFlags = ~0;
- WHERETRACE(("*** Optimizer Start ***\n"));
- for(sWBI.i=iFrom=0, pLevel=pWInfo->a; sWBI.i<nTabList; sWBI.i++, pLevel++){
- WhereCost bestPlan; /* Most efficient plan seen so far */
- Index *pIdx; /* Index for FROM table at pTabItem */
- int j; /* For looping over FROM tables */
- int bestJ = -1; /* The value of j */
- Bitmask m; /* Bitmask value for j or bestJ */
- int isOptimal; /* Iterator for optimal/non-optimal search */
- int ckOptimal; /* Do the optimal scan check */
- int nUnconstrained; /* Number tables without INDEXED BY */
- Bitmask notIndexed; /* Mask of tables that cannot use an index */
-
- memset(&bestPlan, 0, sizeof(bestPlan));
- bestPlan.rCost = SQLITE_BIG_DBL;
- WHERETRACE(("*** Begin search for loop %d ***\n", sWBI.i));
-
- /* Loop through the remaining entries in the FROM clause to find the
- ** next nested loop. The loop tests all FROM clause entries
- ** either once or twice.
- **
- ** The first test is always performed if there are two or more entries
- ** remaining and never performed if there is only one FROM clause entry
- ** to choose from. The first test looks for an "optimal" scan. In
- ** this context an optimal scan is one that uses the same strategy
- ** for the given FROM clause entry as would be selected if the entry
- ** were used as the innermost nested loop. In other words, a table
- ** is chosen such that the cost of running that table cannot be reduced
- ** by waiting for other tables to run first. This "optimal" test works
- ** by first assuming that the FROM clause is on the inner loop and finding
- ** its query plan, then checking to see if that query plan uses any
- ** other FROM clause terms that are sWBI.notValid. If no notValid terms
- ** are used then the "optimal" query plan works.
- **
- ** Note that the WhereCost.nRow parameter for an optimal scan might
- ** not be as small as it would be if the table really were the innermost
- ** join. The nRow value can be reduced by WHERE clause constraints
- ** that do not use indices. But this nRow reduction only happens if the
- ** table really is the innermost join.
- **
- ** The second loop iteration is only performed if no optimal scan
- ** strategies were found by the first iteration. This second iteration
- ** is used to search for the lowest cost scan overall.
- **
- ** Without the optimal scan step (the first iteration) a suboptimal
- ** plan might be chosen for queries like this:
- **
- ** CREATE TABLE t1(a, b);
- ** CREATE TABLE t2(c, d);
- ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a;
- **
- ** The best strategy is to iterate through table t1 first. However it
- ** is not possible to determine this with a simple greedy algorithm.
- ** Since the cost of a linear scan through table t2 is the same
- ** as the cost of a linear scan through table t1, a simple greedy
- ** algorithm may choose to use t2 for the outer loop, which is a much
- ** costlier approach.
- */
- nUnconstrained = 0;
- notIndexed = 0;
-
- /* The optimal scan check only occurs if there are two or more tables
- ** available to be reordered */
- if( iFrom==nTabList-1 ){
- ckOptimal = 0; /* Common case of just one table in the FROM clause */
- }else{
- ckOptimal = -1;
- for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
- m = getMask(pMaskSet, sWBI.pSrc->iCursor);
- if( (m & sWBI.notValid)==0 ){
- if( j==iFrom ) iFrom++;
- continue;
- }
- if( j>iFrom && (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0 ) break;
- if( ++ckOptimal ) break;
- if( (sWBI.pSrc->jointype & JT_LEFT)!=0 ) break;
- }
+ if( wctrlFlags & WHERE_WANT_DISTINCT ){
+ if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
+ /* The DISTINCT marking is pointless. Ignore it. */
+ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
+ }else if( pOrderBy==0 ){
+ /* Try to ORDER BY the result set to make distinct processing easier */
+ pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
+ pWInfo->pOrderBy = pResultSet;
}
- assert( ckOptimal==0 || ckOptimal==1 );
+ }
- for(isOptimal=ckOptimal; isOptimal>=0 && bestJ<0; isOptimal--){
- for(j=iFrom, sWBI.pSrc=&pTabList->a[j]; j<nTabList; j++, sWBI.pSrc++){
- if( j>iFrom && (sWBI.pSrc->jointype & (JT_LEFT|JT_CROSS))!=0 ){
- /* This break and one like it in the ckOptimal computation loop
- ** above prevent table reordering across LEFT and CROSS JOINs.
- ** The LEFT JOIN case is necessary for correctness. The prohibition
- ** against reordering across a CROSS JOIN is an SQLite feature that
- ** allows the developer to control table reordering */
- break;
- }
- m = getMask(pMaskSet, sWBI.pSrc->iCursor);
- if( (m & sWBI.notValid)==0 ){
- assert( j>iFrom );
- continue;
- }
- sWBI.notReady = (isOptimal ? m : sWBI.notValid);
- if( sWBI.pSrc->pIndex==0 ) nUnconstrained++;
-
- WHERETRACE((" === trying table %d (%s) with isOptimal=%d ===\n",
- j, sWBI.pSrc->pTab->zName, isOptimal));
- assert( sWBI.pSrc->pTab );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( IsVirtual(sWBI.pSrc->pTab) ){
- sWBI.ppIdxInfo = &pWInfo->a[j].pIdxInfo;
- bestVirtualIndex(&sWBI);
- }else
-#endif
- {
- bestBtreeIndex(&sWBI);
- }
- assert( isOptimal || (sWBI.cost.used&sWBI.notValid)==0 );
-
- /* If an INDEXED BY clause is present, then the plan must use that
- ** index if it uses any index at all */
- assert( sWBI.pSrc->pIndex==0
- || (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
- || sWBI.cost.plan.u.pIdx==sWBI.pSrc->pIndex );
-
- if( isOptimal && (sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
- notIndexed |= m;
- }
- if( isOptimal ){
- pWInfo->a[j].rOptCost = sWBI.cost.rCost;
- }else if( ckOptimal ){
- /* If two or more tables have nearly the same outer loop cost, but
- ** very different inner loop (optimal) cost, we want to choose
- ** for the outer loop that table which benefits the least from
- ** being in the inner loop. The following code scales the
- ** outer loop cost estimate to accomplish that. */
- WHERETRACE((" scaling cost from %.1f to %.1f\n",
- sWBI.cost.rCost,
- sWBI.cost.rCost/pWInfo->a[j].rOptCost));
- sWBI.cost.rCost /= pWInfo->a[j].rOptCost;
- }
-
- /* Conditions under which this table becomes the best so far:
- **
- ** (1) The table must not depend on other tables that have not
- ** yet run. (In other words, it must not depend on tables
- ** in inner loops.)
- **
- ** (2) (This rule was removed on 2012-11-09. The scaling of the
- ** cost using the optimal scan cost made this rule obsolete.)
- **
- ** (3) All tables have an INDEXED BY clause or this table lacks an
- ** INDEXED BY clause or this table uses the specific
- ** index specified by its INDEXED BY clause. This rule ensures
- ** that a best-so-far is always selected even if an impossible
- ** combination of INDEXED BY clauses are given. The error
- ** will be detected and relayed back to the application later.
- ** The NEVER() comes about because rule (2) above prevents
- ** An indexable full-table-scan from reaching rule (3).
- **
- ** (4) The plan cost must be lower than prior plans, where "cost"
- ** is defined by the compareCost() function above.
- */
- if( (sWBI.cost.used&sWBI.notValid)==0 /* (1) */
- && (nUnconstrained==0 || sWBI.pSrc->pIndex==0 /* (3) */
- || NEVER((sWBI.cost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
- && (bestJ<0 || compareCost(&sWBI.cost, &bestPlan)) /* (4) */
- ){
- WHERETRACE((" === table %d (%s) is best so far\n"
- " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=%08x\n",
- j, sWBI.pSrc->pTab->zName,
- sWBI.cost.rCost, sWBI.cost.plan.nRow,
- sWBI.cost.plan.nOBSat, sWBI.cost.plan.wsFlags));
- bestPlan = sWBI.cost;
- bestJ = j;
- }
-
- /* In a join like "w JOIN x LEFT JOIN y JOIN z" make sure that
- ** table y (and not table z) is always the next inner loop inside
- ** of table x. */
- if( (sWBI.pSrc->jointype & JT_LEFT)!=0 ) break;
- }
- }
- assert( bestJ>=0 );
- assert( sWBI.notValid & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
- assert( bestJ==iFrom || (pTabList->a[iFrom].jointype & JT_LEFT)==0 );
- testcase( bestJ>iFrom && (pTabList->a[iFrom].jointype & JT_CROSS)!=0 );
- testcase( bestJ>iFrom && bestJ<nTabList-1
- && (pTabList->a[bestJ+1].jointype & JT_LEFT)!=0 );
- WHERETRACE(("*** Optimizer selects table %d (%s) for loop %d with:\n"
- " cost=%.1f, nRow=%.1f, nOBSat=%d, wsFlags=0x%08x\n",
- bestJ, pTabList->a[bestJ].pTab->zName,
- pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow,
- bestPlan.plan.nOBSat, bestPlan.plan.wsFlags));
- if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
- assert( pWInfo->eDistinct==0 );
- pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
+ /* Construct the WhereLoop objects */
+ WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
+ /* Display all terms of the WHERE clause */
+#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
+ if( sqlite3WhereTrace & 0x100 ){
+ int i;
+ Vdbe *v = pParse->pVdbe;
+ sqlite3ExplainBegin(v);
+ for(i=0; i<sWLB.pWC->nTerm; i++){
+ sqlite3ExplainPrintf(v, "#%-2d ", i);
+ sqlite3ExplainPush(v);
+ whereExplainTerm(v, &sWLB.pWC->a[i]);
+ sqlite3ExplainPop(v);
+ sqlite3ExplainNL(v);
}
- andFlags &= bestPlan.plan.wsFlags;
- pLevel->plan = bestPlan.plan;
- pLevel->iTabCur = pTabList->a[bestJ].iCursor;
- testcase( bestPlan.plan.wsFlags & WHERE_INDEXED );
- testcase( bestPlan.plan.wsFlags & WHERE_TEMP_INDEX );
- if( bestPlan.plan.wsFlags & (WHERE_INDEXED|WHERE_TEMP_INDEX) ){
- if( (wctrlFlags & WHERE_ONETABLE_ONLY)
- && (bestPlan.plan.wsFlags & WHERE_TEMP_INDEX)==0
- ){
- pLevel->iIdxCur = iIdxCur;
- }else{
- pLevel->iIdxCur = pParse->nTab++;
+ sqlite3ExplainFinish(v);
+ sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
+ }
+#endif
+ if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
+ rc = whereLoopAddAll(&sWLB);
+ if( rc ) goto whereBeginError;
+
+ /* Display all of the WhereLoop objects if wheretrace is enabled */
+#ifdef WHERETRACE_ENABLED /* !=0 */
+ if( sqlite3WhereTrace ){
+ WhereLoop *p;
+ int i;
+ static char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz"
+ "ABCDEFGHIJKLMNOPQRSTUVWYXZ";
+ for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){
+ p->cId = zLabel[i%sizeof(zLabel)];
+ whereLoopPrint(p, sWLB.pWC);
}
- }else{
- pLevel->iIdxCur = -1;
}
- sWBI.notValid &= ~getMask(pMaskSet, pTabList->a[bestJ].iCursor);
- pLevel->iFrom = (u8)bestJ;
- if( bestPlan.plan.nRow>=(double)1 ){
- pParse->nQueryLoop *= bestPlan.plan.nRow;
- }
-
- /* Check that if the table scanned by this loop iteration had an
- ** INDEXED BY clause attached to it, that the named index is being
- ** used for the scan. If not, then query compilation has failed.
- ** Return an error.
- */
- pIdx = pTabList->a[bestJ].pIndex;
- if( pIdx ){
- if( (bestPlan.plan.wsFlags & WHERE_INDEXED)==0 ){
- sqlite3ErrorMsg(pParse, "cannot use index: %s", pIdx->zName);
- goto whereBeginError;
- }else{
- /* If an INDEXED BY clause is used, the bestIndex() function is
- ** guaranteed to find the index specified in the INDEXED BY clause
- ** if it find an index at all. */
- assert( bestPlan.plan.u.pIdx==pIdx );
- }
+#endif
+
+ wherePathSolver(pWInfo, 0);
+ if( db->mallocFailed ) goto whereBeginError;
+ if( pWInfo->pOrderBy ){
+ wherePathSolver(pWInfo, pWInfo->nRowOut+1);
+ if( db->mallocFailed ) goto whereBeginError;
}
}
- WHERETRACE(("*** Optimizer Finished ***\n"));
- if( pParse->nErr || db->mallocFailed ){
+ if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){
+ pWInfo->revMask = (Bitmask)(-1);
+ }
+ if( pParse->nErr || NEVER(db->mallocFailed) ){
goto whereBeginError;
}
- if( nTabList ){
- pLevel--;
- pWInfo->nOBSat = pLevel->plan.nOBSat;
- }else{
- pWInfo->nOBSat = 0;
+#ifdef WHERETRACE_ENABLED /* !=0 */
+ if( sqlite3WhereTrace ){
+ int ii;
+ sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
+ if( pWInfo->bOBSat ){
+ sqlite3DebugPrintf(" ORDERBY=0x%llx", pWInfo->revMask);
+ }
+ switch( pWInfo->eDistinct ){
+ case WHERE_DISTINCT_UNIQUE: {
+ sqlite3DebugPrintf(" DISTINCT=unique");
+ break;
+ }
+ case WHERE_DISTINCT_ORDERED: {
+ sqlite3DebugPrintf(" DISTINCT=ordered");
+ break;
+ }
+ case WHERE_DISTINCT_UNORDERED: {
+ sqlite3DebugPrintf(" DISTINCT=unordered");
+ break;
+ }
+ }
+ sqlite3DebugPrintf("\n");
+ for(ii=0; ii<pWInfo->nLevel; ii++){
+ whereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
+ }
}
-
- /* If the total query only selects a single row, then the ORDER BY
- ** clause is irrelevant.
- */
- if( (andFlags & WHERE_UNIQUE)!=0 && pOrderBy ){
- assert( nTabList==0 || (pLevel->plan.wsFlags & WHERE_ALL_UNIQUE)!=0 );
- pWInfo->nOBSat = pOrderBy->nExpr;
+#endif
+ /* Attempt to omit tables from the join that do not effect the result */
+ if( pWInfo->nLevel>=2
+ && pResultSet!=0
+ && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
+ ){
+ Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet);
+ if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy);
+ while( pWInfo->nLevel>=2 ){
+ WhereTerm *pTerm, *pEnd;
+ pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
+ if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break;
+ if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
+ && (pLoop->wsFlags & WHERE_ONEROW)==0
+ ){
+ break;
+ }
+ if( (tabUsed & pLoop->maskSelf)!=0 ) break;
+ pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0
+ && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ ){
+ break;
+ }
+ }
+ if( pTerm<pEnd ) break;
+ WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+ pWInfo->nLevel--;
+ nTabList--;
+ }
}
+ WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
+ pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
- ** The one-pass algorithm only works if the WHERE clause constraints
+ ** The one-pass algorithm only works if the WHERE clause constrains
** the statement to update a single row.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
- if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 && (andFlags & WHERE_UNIQUE)!=0 ){
+ if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0
+ && (pWInfo->a[0].pWLoop->wsFlags & WHERE_ONEROW)!=0 ){
pWInfo->okOnePass = 1;
- pWInfo->a[0].plan.wsFlags &= ~WHERE_IDX_ONLY;
+ if( HasRowid(pTabList->a[0].pTab) ){
+ pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY;
+ }
}
/* Open all tables in the pTabList and any indices selected for
** searching those tables.
*/
- sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
notReady = ~(Bitmask)0;
- pWInfo->nRowOut = (double)1;
for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){
Table *pTab; /* Table to open */
int iDb; /* Index of database containing table/index */
@@ -109860,13 +114065,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
pTabItem = &pTabList->a[pLevel->iFrom];
pTab = pTabItem->pTab;
- pWInfo->nRowOut *= pLevel->plan.nRow;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+ pLoop = pLevel->pWLoop;
if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){
/* Do nothing */
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){
+ if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
int iCur = pTabItem->iCursor;
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
@@ -109874,13 +114079,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* noop */
}else
#endif
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
+ if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
&& (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
- int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
+ int op = OP_OpenRead;
+ if( pWInfo->okOnePass ){
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[0] = pTabItem->iCursor;
+ };
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
- testcase( pTab->nCol==BMS-1 );
- testcase( pTab->nCol==BMS );
- if( !pWInfo->okOnePass && pTab->nCol<BMS ){
+ assert( pTabItem->iCursor==pLevel->iTabCur );
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS-1 );
+ testcase( !pWInfo->okOnePass && pTab->nCol==BMS );
+ if( !pWInfo->okOnePass && pTab->nCol<BMS && HasRowid(pTab) ){
Bitmask b = pTabItem->colUsed;
int n = 0;
for(; b; b=b>>1, n++){}
@@ -109891,23 +114101,36 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}else{
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
}
-#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
- if( (pLevel->plan.wsFlags & WHERE_TEMP_INDEX)!=0 ){
- constructAutomaticIndex(pParse, sWBI.pWC, pTabItem, notReady, pLevel);
- }else
-#endif
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
- Index *pIx = pLevel->plan.u.pIdx;
- KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIx);
- int iIndexCur = pLevel->iIdxCur;
+ if( pLoop->wsFlags & WHERE_INDEXED ){
+ Index *pIx = pLoop->u.btree.pIndex;
+ int iIndexCur;
+ int op = OP_OpenRead;
+ /* iIdxCur is always set if to a positive value if ONEPASS is possible */
+ assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ if( pWInfo->okOnePass ){
+ Index *pJ = pTabItem->pTab->pIndex;
+ iIndexCur = iIdxCur;
+ assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
+ while( ALWAYS(pJ) && pJ!=pIx ){
+ iIndexCur++;
+ pJ = pJ->pNext;
+ }
+ op = OP_OpenWrite;
+ pWInfo->aiCurOnePass[1] = iIndexCur;
+ }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+ iIndexCur = iIdxCur;
+ }else{
+ iIndexCur = pParse->nTab++;
+ }
+ pLevel->iIdxCur = iIndexCur;
assert( pIx->pSchema==pTab->pSchema );
assert( iIndexCur>=0 );
- sqlite3VdbeAddOp4(v, OP_OpenRead, iIndexCur, pIx->tnum, iDb,
- (char*)pKey, P4_KEYINFO_HANDOFF);
+ sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIx);
VdbeComment((v, "%s", pIx->zName));
}
sqlite3CodeVerifySchema(pParse, iDb);
- notReady &= ~getMask(sWBI.pWC->pMaskSet, pTabItem->iCursor);
+ notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
}
pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
if( db->mallocFailed ) goto whereBeginError;
@@ -109919,67 +114142,21 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
pLevel = &pWInfo->a[ii];
+#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+ if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
+ constructAutomaticIndex(pParse, &pWInfo->sWC,
+ &pTabList->a[pLevel->iFrom], notReady, pLevel);
+ if( db->mallocFailed ) goto whereBeginError;
+ }
+#endif
explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
- notReady = codeOneLoopStart(pWInfo, ii, wctrlFlags, notReady);
+ pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
+ notReady = codeOneLoopStart(pWInfo, ii, notReady);
pWInfo->iContinue = pLevel->addrCont;
}
-#ifdef SQLITE_TEST /* For testing and debugging use only */
- /* Record in the query plan information about the current table
- ** and the index used to access it (if any). If the table itself
- ** is not used, its name is just '{}'. If no index is used
- ** the index is listed as "{}". If the primary key is used the
- ** index name is '*'.
- */
- for(ii=0; ii<nTabList; ii++){
- char *z;
- int n;
- int w;
- struct SrcList_item *pTabItem;
-
- pLevel = &pWInfo->a[ii];
- w = pLevel->plan.wsFlags;
- pTabItem = &pTabList->a[pLevel->iFrom];
- z = pTabItem->zAlias;
- if( z==0 ) z = pTabItem->pTab->zName;
- n = sqlite3Strlen30(z);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-10 ){
- if( (w & WHERE_IDX_ONLY)!=0 && (w & WHERE_COVER_SCAN)==0 ){
- memcpy(&sqlite3_query_plan[nQPlan], "{}", 2);
- nQPlan += 2;
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], z, n);
- nQPlan += n;
- }
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- testcase( w & WHERE_ROWID_EQ );
- testcase( w & WHERE_ROWID_RANGE );
- if( w & (WHERE_ROWID_EQ|WHERE_ROWID_RANGE) ){
- memcpy(&sqlite3_query_plan[nQPlan], "* ", 2);
- nQPlan += 2;
- }else if( (w & WHERE_INDEXED)!=0 && (w & WHERE_COVER_SCAN)==0 ){
- n = sqlite3Strlen30(pLevel->plan.u.pIdx->zName);
- if( n+nQPlan < sizeof(sqlite3_query_plan)-2 ){
- memcpy(&sqlite3_query_plan[nQPlan], pLevel->plan.u.pIdx->zName, n);
- nQPlan += n;
- sqlite3_query_plan[nQPlan++] = ' ';
- }
- }else{
- memcpy(&sqlite3_query_plan[nQPlan], "{} ", 3);
- nQPlan += 3;
- }
- }
- while( nQPlan>0 && sqlite3_query_plan[nQPlan-1]==' ' ){
- sqlite3_query_plan[--nQPlan] = 0;
- }
- sqlite3_query_plan[nQPlan] = 0;
- nQPlan = 0;
-#endif /* SQLITE_TEST // Testing and debugging use only */
-
- /* Record the continuation address in the WhereInfo structure. Then
- ** clean up and return.
- */
+ /* Done. */
+ VdbeModuleComment((v, "Begin WHERE-core"));
return pWInfo;
/* Jump here if malloc fails */
@@ -110000,20 +114177,24 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
Vdbe *v = pParse->pVdbe;
int i;
WhereLevel *pLevel;
+ WhereLoop *pLoop;
SrcList *pTabList = pWInfo->pTabList;
sqlite3 *db = pParse->db;
/* Generate loop termination code.
*/
+ VdbeModuleComment((v, "End WHERE-core"));
sqlite3ExprCacheClear(pParse);
for(i=pWInfo->nLevel-1; i>=0; i--){
+ int addr;
pLevel = &pWInfo->a[i];
+ pLoop = pLevel->pWLoop;
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
sqlite3VdbeChangeP5(v, pLevel->p5);
}
- if( pLevel->plan.wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
+ if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
int j;
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
@@ -110025,15 +114206,20 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
+ if( pLevel->addrSkip ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrSkip);
+ VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip);
+ sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
+ }
if( pLevel->iLeftJoin ){
- int addr;
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
- assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- || (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 );
- if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 ){
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
+ || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
+ if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
}
- if( pLevel->iIdxCur>=0 ){
+ if( pLoop->wsFlags & WHERE_INDEXED ){
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
}
if( pLevel->op==OP_Return ){
@@ -110043,6 +114229,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
}
sqlite3VdbeJumpHere(v, addr);
}
+ VdbeModuleComment((v, "End WHERE-loop%d: %s", i,
+ pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
}
/* The "break" point is here, just past the end of the outer loop.
@@ -110050,33 +114238,39 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
*/
sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- */
- assert( pWInfo->nLevel==1 || pWInfo->nLevel==pTabList->nSrc );
+ assert( pWInfo->nLevel<=pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
Index *pIdx = 0;
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
Table *pTab = pTabItem->pTab;
assert( pTab!=0 );
+ pLoop = pLevel->pWLoop;
+
+ /* Close all of the cursors that were opened by sqlite3WhereBegin.
+ ** Except, do not close cursors that will be reused by the OR optimization
+ ** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors
+ ** created for the ONEPASS optimization.
+ */
if( (pTab->tabFlags & TF_Ephemeral)==0
&& pTab->pSelect==0
&& (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
){
- int ws = pLevel->plan.wsFlags;
+ int ws = pLoop->wsFlags;
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
}
- if( (ws & WHERE_INDEXED)!=0 && (ws & WHERE_TEMP_INDEX)==0 ){
+ if( (ws & WHERE_INDEXED)!=0
+ && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
+ && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
+ ){
sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
}
}
- /* If this scan uses an index, make code substitutions to read data
- ** from the index in preference to the table. Sometimes, this means
- ** the table need never be read from. This is a performance boost,
- ** as the vdbe level waits until the table is read before actually
- ** seeking the table cursor to the record corresponding to the current
- ** position in the index.
+ /* If this scan uses an index, make VDBE code substitutions to read data
+ ** from the index instead of from the table where possible. In some cases
+ ** this optimization prevents the table from ever being read, which can
+ ** yield a significant performance boost.
**
** Calls to the code generator in between sqlite3WhereBegin and
** sqlite3WhereEnd will have created code that references the table
@@ -110084,29 +114278,33 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** that reference the table and converts them into opcodes that
** reference the index.
*/
- if( pLevel->plan.wsFlags & WHERE_INDEXED ){
- pIdx = pLevel->plan.u.pIdx;
- }else if( pLevel->plan.wsFlags & WHERE_MULTI_OR ){
+ if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
+ pIdx = pLoop->u.btree.pIndex;
+ }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
pIdx = pLevel->u.pCovidx;
}
- if( pIdx && !db->mallocFailed){
- int k, j, last;
+ if( pIdx && !db->mallocFailed ){
+ int k, last;
VdbeOp *pOp;
- pOp = sqlite3VdbeGetOp(v, pWInfo->iTop);
last = sqlite3VdbeCurrentAddr(v);
- for(k=pWInfo->iTop; k<last; k++, pOp++){
+ k = pLevel->addrBody;
+ pOp = sqlite3VdbeGetOp(v, k);
+ for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue;
if( pOp->opcode==OP_Column ){
- for(j=0; j<pIdx->nColumn; j++){
- if( pOp->p2==pIdx->aiColumn[j] ){
- pOp->p2 = j;
- pOp->p1 = pLevel->iIdxCur;
- break;
- }
+ int x = pOp->p2;
+ assert( pIdx->pTable==pTab );
+ if( !HasRowid(pTab) ){
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ x = pPk->aiColumn[x];
+ }
+ x = sqlite3ColumnOfIndex(pIdx, x);
+ if( x>=0 ){
+ pOp->p2 = x;
+ pOp->p1 = pLevel->iIdxCur;
}
- assert( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
- || j<pIdx->nColumn );
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
@@ -110314,28 +114512,28 @@ struct ValueList {
** defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
-#define YYNOCODE 251
+#define YYNOCODE 253
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 67
+#define YYWILDCARD 68
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- struct LimitVal yy64;
- Expr* yy122;
- Select* yy159;
- IdList* yy180;
- struct {int value; int mask;} yy207;
- u8 yy258;
- u16 yy305;
- struct LikeOp yy318;
- TriggerStep* yy327;
- ExprSpan yy342;
- SrcList* yy347;
- int yy392;
- struct TrigEvent yy410;
- ExprList* yy442;
- struct ValueList yy487;
+ int yy4;
+ struct TrigEvent yy90;
+ ExprSpan yy118;
+ u16 yy177;
+ TriggerStep* yy203;
+ u8 yy210;
+ struct {int value; int mask;} yy215;
+ SrcList* yy259;
+ struct ValueList yy260;
+ struct LimitVal yy292;
+ Expr* yy314;
+ ExprList* yy322;
+ struct LikeOp yy342;
+ IdList* yy384;
+ Select* yy387;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -110344,8 +114542,8 @@ typedef union {
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 627
-#define YYNRULE 327
+#define YYNSTATE 631
+#define YYNRULE 329
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
@@ -110415,474 +114613,480 @@ static const YYMINORTYPE yyzerominor = { 0 };
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
-#define YY_ACTTAB_COUNT (1564)
+#define YY_ACTTAB_COUNT (1582)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
- /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
- /* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
- /* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
- /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
- /* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
- /* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
- /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
- /* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
- /* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
- /* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
- /* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
- /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
- /* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
- /* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
- /* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
- /* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
- /* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
- /* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
- /* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
- /* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
- /* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
- /* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
- /* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
- /* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
- /* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
- /* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
- /* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
- /* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
- /* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
- /* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
- /* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
- /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
- /* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
- /* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
- /* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
- /* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
- /* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
- /* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
- /* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
- /* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
- /* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
- /* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
- /* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
- /* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
- /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
- /* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
- /* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
- /* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
- /* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
- /* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
- /* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
- /* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
- /* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
- /* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
- /* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
- /* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
- /* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
- /* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
- /* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
- /* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
- /* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
- /* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
- /* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
- /* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
- /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
- /* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
- /* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
- /* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
- /* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
- /* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
- /* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
- /* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
- /* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
- /* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
- /* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
- /* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
- /* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
- /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
- /* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
- /* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
- /* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
- /* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
- /* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
- /* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
- /* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
- /* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
- /* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
- /* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
- /* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
- /* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
- /* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
- /* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
- /* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
- /* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
- /* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
- /* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
- /* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
- /* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
- /* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
- /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
- /* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
- /* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
- /* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
- /* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
- /* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
- /* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
- /* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
- /* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
- /* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
- /* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
- /* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
- /* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
- /* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
- /* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
- /* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
- /* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
- /* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
- /* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
- /* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
- /* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
- /* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
- /* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
- /* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
- /* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
- /* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
- /* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
- /* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
- /* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
- /* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
- /* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
- /* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
- /* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
- /* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
- /* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
- /* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
- /* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
- /* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
- /* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
- /* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
- /* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
- /* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
- /* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
- /* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
- /* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
- /* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
- /* 1560 */ 295, 498, 956, 488,
+ /* 0 */ 312, 961, 185, 420, 2, 171, 516, 515, 597, 56,
+ /* 10 */ 56, 56, 56, 49, 54, 54, 54, 54, 53, 53,
+ /* 20 */ 52, 52, 52, 51, 234, 197, 196, 195, 624, 623,
+ /* 30 */ 301, 590, 584, 56, 56, 56, 56, 156, 54, 54,
+ /* 40 */ 54, 54, 53, 53, 52, 52, 52, 51, 234, 628,
+ /* 50 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 60 */ 56, 56, 56, 466, 54, 54, 54, 54, 53, 53,
+ /* 70 */ 52, 52, 52, 51, 234, 312, 597, 52, 52, 52,
+ /* 80 */ 51, 234, 33, 54, 54, 54, 54, 53, 53, 52,
+ /* 90 */ 52, 52, 51, 234, 624, 623, 621, 620, 165, 624,
+ /* 100 */ 623, 383, 380, 379, 214, 328, 590, 584, 624, 623,
+ /* 110 */ 467, 59, 378, 619, 618, 617, 53, 53, 52, 52,
+ /* 120 */ 52, 51, 234, 506, 507, 57, 58, 48, 582, 581,
+ /* 130 */ 583, 583, 55, 55, 56, 56, 56, 56, 30, 54,
+ /* 140 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 150 */ 312, 50, 47, 146, 233, 232, 207, 474, 256, 349,
+ /* 160 */ 255, 475, 621, 620, 554, 438, 298, 621, 620, 236,
+ /* 170 */ 674, 435, 440, 553, 439, 366, 621, 620, 540, 224,
+ /* 180 */ 551, 590, 584, 176, 138, 282, 386, 277, 385, 168,
+ /* 190 */ 600, 422, 951, 548, 622, 951, 273, 572, 572, 566,
+ /* 200 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 210 */ 56, 56, 56, 354, 54, 54, 54, 54, 53, 53,
+ /* 220 */ 52, 52, 52, 51, 234, 312, 561, 526, 62, 675,
+ /* 230 */ 132, 595, 410, 348, 579, 579, 492, 426, 577, 419,
+ /* 240 */ 627, 65, 329, 560, 441, 237, 676, 123, 607, 67,
+ /* 250 */ 542, 532, 622, 170, 205, 500, 590, 584, 166, 559,
+ /* 260 */ 622, 403, 593, 593, 593, 442, 443, 271, 422, 950,
+ /* 270 */ 166, 223, 950, 483, 190, 57, 58, 48, 582, 581,
+ /* 280 */ 583, 583, 55, 55, 56, 56, 56, 56, 600, 54,
+ /* 290 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 300 */ 312, 441, 412, 376, 175, 165, 166, 391, 383, 380,
+ /* 310 */ 379, 342, 412, 203, 426, 66, 392, 622, 415, 378,
+ /* 320 */ 597, 166, 442, 338, 444, 571, 601, 74, 415, 624,
+ /* 330 */ 623, 590, 584, 624, 623, 174, 601, 92, 333, 171,
+ /* 340 */ 1, 410, 597, 579, 579, 624, 623, 600, 306, 425,
+ /* 350 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 360 */ 56, 56, 56, 580, 54, 54, 54, 54, 53, 53,
+ /* 370 */ 52, 52, 52, 51, 234, 312, 472, 262, 399, 68,
+ /* 380 */ 412, 339, 571, 389, 624, 623, 578, 602, 597, 589,
+ /* 390 */ 588, 603, 412, 622, 423, 533, 415, 621, 620, 513,
+ /* 400 */ 257, 621, 620, 166, 601, 91, 590, 584, 415, 45,
+ /* 410 */ 597, 586, 585, 621, 620, 250, 601, 92, 39, 347,
+ /* 420 */ 576, 336, 597, 547, 567, 57, 58, 48, 582, 581,
+ /* 430 */ 583, 583, 55, 55, 56, 56, 56, 56, 587, 54,
+ /* 440 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 450 */ 312, 561, 621, 620, 531, 291, 470, 188, 399, 375,
+ /* 460 */ 247, 492, 249, 350, 412, 476, 476, 368, 560, 299,
+ /* 470 */ 334, 412, 281, 482, 67, 565, 410, 622, 579, 579,
+ /* 480 */ 415, 590, 584, 280, 559, 467, 520, 415, 601, 92,
+ /* 490 */ 597, 167, 544, 36, 877, 601, 16, 519, 564, 6,
+ /* 500 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 510 */ 56, 56, 56, 200, 54, 54, 54, 54, 53, 53,
+ /* 520 */ 52, 52, 52, 51, 234, 312, 183, 412, 236, 528,
+ /* 530 */ 395, 535, 358, 256, 349, 255, 397, 412, 248, 182,
+ /* 540 */ 353, 359, 549, 415, 236, 317, 563, 50, 47, 146,
+ /* 550 */ 273, 601, 73, 415, 7, 311, 590, 584, 568, 493,
+ /* 560 */ 213, 601, 92, 233, 232, 410, 173, 579, 579, 330,
+ /* 570 */ 575, 574, 631, 629, 332, 57, 58, 48, 582, 581,
+ /* 580 */ 583, 583, 55, 55, 56, 56, 56, 56, 199, 54,
+ /* 590 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 600 */ 312, 492, 340, 320, 511, 505, 572, 572, 460, 562,
+ /* 610 */ 549, 170, 145, 430, 67, 558, 410, 622, 579, 579,
+ /* 620 */ 384, 236, 600, 412, 408, 575, 574, 504, 572, 572,
+ /* 630 */ 571, 590, 584, 353, 198, 143, 268, 549, 316, 415,
+ /* 640 */ 306, 424, 207, 50, 47, 146, 167, 601, 69, 546,
+ /* 650 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 660 */ 56, 56, 56, 555, 54, 54, 54, 54, 53, 53,
+ /* 670 */ 52, 52, 52, 51, 234, 312, 600, 326, 412, 270,
+ /* 680 */ 145, 264, 274, 266, 459, 571, 423, 35, 412, 568,
+ /* 690 */ 407, 213, 428, 388, 415, 308, 212, 143, 622, 354,
+ /* 700 */ 317, 12, 601, 94, 415, 549, 590, 584, 50, 47,
+ /* 710 */ 146, 365, 601, 97, 552, 362, 318, 147, 602, 361,
+ /* 720 */ 325, 15, 603, 187, 206, 57, 58, 48, 582, 581,
+ /* 730 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 740 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 750 */ 312, 412, 35, 412, 415, 22, 630, 2, 600, 50,
+ /* 760 */ 47, 146, 601, 95, 412, 485, 510, 415, 412, 415,
+ /* 770 */ 412, 11, 235, 486, 412, 601, 104, 601, 103, 19,
+ /* 780 */ 415, 590, 584, 352, 415, 40, 415, 38, 601, 105,
+ /* 790 */ 415, 32, 601, 106, 601, 133, 544, 169, 601, 134,
+ /* 800 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 810 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 820 */ 52, 52, 52, 51, 234, 312, 412, 274, 412, 415,
+ /* 830 */ 412, 274, 274, 274, 201, 230, 721, 601, 98, 484,
+ /* 840 */ 427, 307, 415, 622, 415, 540, 415, 622, 622, 622,
+ /* 850 */ 601, 102, 601, 101, 601, 93, 590, 584, 262, 21,
+ /* 860 */ 129, 622, 522, 521, 554, 222, 469, 521, 600, 324,
+ /* 870 */ 323, 322, 211, 553, 622, 57, 58, 48, 582, 581,
+ /* 880 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 890 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 900 */ 312, 412, 261, 412, 415, 412, 600, 210, 625, 367,
+ /* 910 */ 51, 234, 601, 100, 538, 606, 142, 415, 355, 415,
+ /* 920 */ 412, 415, 412, 496, 622, 601, 77, 601, 96, 601,
+ /* 930 */ 137, 590, 584, 530, 622, 529, 415, 141, 415, 28,
+ /* 940 */ 524, 600, 229, 544, 601, 136, 601, 135, 604, 204,
+ /* 950 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 960 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 970 */ 52, 52, 52, 51, 234, 312, 412, 360, 412, 415,
+ /* 980 */ 412, 360, 286, 600, 503, 220, 127, 601, 76, 629,
+ /* 990 */ 332, 382, 415, 622, 415, 540, 415, 622, 412, 613,
+ /* 1000 */ 601, 90, 601, 89, 601, 75, 590, 584, 341, 272,
+ /* 1010 */ 377, 622, 126, 27, 415, 622, 164, 544, 125, 280,
+ /* 1020 */ 373, 122, 601, 88, 480, 57, 46, 48, 582, 581,
+ /* 1030 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 1040 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 1050 */ 312, 412, 360, 412, 415, 412, 284, 186, 369, 321,
+ /* 1060 */ 477, 170, 601, 87, 121, 473, 221, 415, 622, 415,
+ /* 1070 */ 254, 415, 412, 355, 412, 601, 99, 601, 86, 601,
+ /* 1080 */ 17, 590, 584, 259, 612, 120, 159, 158, 415, 622,
+ /* 1090 */ 415, 14, 465, 157, 462, 25, 601, 85, 601, 84,
+ /* 1100 */ 622, 58, 48, 582, 581, 583, 583, 55, 55, 56,
+ /* 1110 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
+ /* 1120 */ 52, 52, 52, 51, 234, 312, 412, 262, 412, 415,
+ /* 1130 */ 412, 262, 118, 611, 117, 24, 10, 601, 83, 351,
+ /* 1140 */ 216, 219, 415, 622, 415, 608, 415, 622, 412, 622,
+ /* 1150 */ 601, 72, 601, 71, 601, 82, 590, 584, 262, 4,
+ /* 1160 */ 605, 622, 458, 115, 415, 456, 252, 154, 452, 110,
+ /* 1170 */ 108, 453, 601, 81, 622, 451, 622, 48, 582, 581,
+ /* 1180 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
+ /* 1190 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
+ /* 1200 */ 44, 406, 450, 3, 415, 412, 262, 107, 416, 623,
+ /* 1210 */ 446, 437, 601, 80, 436, 335, 238, 189, 411, 409,
+ /* 1220 */ 594, 415, 622, 44, 406, 401, 3, 412, 557, 601,
+ /* 1230 */ 70, 416, 623, 412, 622, 149, 622, 421, 404, 64,
+ /* 1240 */ 412, 622, 409, 415, 622, 331, 139, 148, 566, 415,
+ /* 1250 */ 449, 601, 18, 228, 124, 626, 415, 601, 79, 315,
+ /* 1260 */ 181, 404, 412, 545, 601, 78, 262, 541, 41, 42,
+ /* 1270 */ 534, 566, 390, 202, 262, 43, 414, 413, 415, 622,
+ /* 1280 */ 595, 314, 622, 622, 180, 539, 601, 92, 415, 276,
+ /* 1290 */ 622, 41, 42, 509, 616, 615, 601, 9, 43, 414,
+ /* 1300 */ 413, 622, 418, 595, 262, 622, 275, 600, 614, 622,
+ /* 1310 */ 218, 593, 593, 593, 592, 591, 13, 178, 217, 417,
+ /* 1320 */ 622, 236, 622, 44, 406, 490, 3, 269, 399, 267,
+ /* 1330 */ 609, 416, 623, 400, 593, 593, 593, 592, 591, 13,
+ /* 1340 */ 265, 622, 409, 622, 263, 622, 34, 406, 244, 3,
+ /* 1350 */ 258, 363, 464, 463, 416, 623, 622, 356, 251, 8,
+ /* 1360 */ 622, 404, 177, 599, 455, 409, 622, 622, 622, 622,
+ /* 1370 */ 445, 566, 243, 622, 622, 236, 295, 240, 31, 239,
+ /* 1380 */ 622, 431, 30, 396, 404, 290, 622, 294, 622, 293,
+ /* 1390 */ 144, 41, 42, 622, 566, 622, 394, 622, 43, 414,
+ /* 1400 */ 413, 622, 289, 595, 398, 60, 622, 292, 37, 231,
+ /* 1410 */ 598, 172, 622, 29, 41, 42, 393, 523, 622, 556,
+ /* 1420 */ 184, 43, 414, 413, 287, 387, 595, 543, 285, 518,
+ /* 1430 */ 537, 536, 517, 327, 593, 593, 593, 592, 591, 13,
+ /* 1440 */ 215, 283, 278, 514, 513, 304, 303, 302, 179, 300,
+ /* 1450 */ 512, 310, 454, 128, 227, 226, 309, 593, 593, 593,
+ /* 1460 */ 592, 591, 13, 494, 489, 225, 488, 150, 487, 242,
+ /* 1470 */ 163, 61, 374, 481, 162, 161, 624, 623, 241, 372,
+ /* 1480 */ 209, 479, 370, 260, 26, 160, 478, 364, 468, 471,
+ /* 1490 */ 140, 152, 119, 467, 131, 116, 155, 153, 345, 457,
+ /* 1500 */ 151, 346, 130, 114, 113, 112, 111, 448, 319, 23,
+ /* 1510 */ 109, 434, 20, 433, 432, 429, 566, 610, 573, 596,
+ /* 1520 */ 63, 405, 191, 279, 510, 296, 498, 288, 570, 495,
+ /* 1530 */ 499, 497, 461, 194, 5, 305, 193, 192, 381, 569,
+ /* 1540 */ 357, 256, 344, 245, 526, 246, 253, 313, 595, 343,
+ /* 1550 */ 447, 297, 236, 402, 550, 491, 508, 502, 501, 527,
+ /* 1560 */ 234, 208, 525, 962, 962, 962, 371, 962, 962, 962,
+ /* 1570 */ 962, 962, 962, 962, 962, 337, 962, 962, 962, 593,
+ /* 1580 */ 593, 593,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
+ /* 0 */ 19, 143, 144, 145, 146, 24, 7, 8, 27, 78,
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
- /* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
- /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
+ /* 20 */ 89, 90, 91, 92, 93, 106, 107, 108, 27, 28,
+ /* 30 */ 15, 50, 51, 78, 79, 80, 81, 26, 83, 84,
+ /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 1,
/* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 166, 82, 83, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 19, 94, 19, 105, 106, 107,
- /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 90 */ 91, 92, 94, 95, 96, 94, 95, 99, 100, 101,
- /* 100 */ 112, 205, 114, 115, 49, 50, 22, 23, 110, 54,
- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 221, 222, 223,
- /* 120 */ 23, 120, 25, 68, 69, 70, 71, 72, 73, 74,
- /* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84,
- /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92,
- /* 150 */ 23, 67, 25, 96, 97, 98, 99, 100, 101, 102,
- /* 160 */ 150, 32, 150, 118, 26, 27, 109, 150, 150, 150,
- /* 170 */ 41, 161, 162, 180, 181, 165, 113, 165, 49, 50,
- /* 180 */ 117, 188, 165, 165, 165, 173, 174, 170, 171, 170,
- /* 190 */ 171, 173, 174, 118, 184, 16, 186, 68, 69, 70,
- /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 220 */ 91, 92, 19, 98, 86, 87, 22, 24, 160, 88,
- /* 230 */ 26, 27, 94, 95, 109, 97, 224, 66, 118, 60,
- /* 240 */ 150, 62, 104, 23, 106, 25, 229, 230, 229, 230,
- /* 250 */ 160, 150, 49, 50, 113, 165, 96, 26, 117, 99,
- /* 260 */ 100, 101, 194, 173, 174, 94, 165, 129, 130, 98,
- /* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86,
- /* 290 */ 87, 88, 89, 90, 91, 92, 19, 11, 94, 95,
- /* 300 */ 129, 130, 131, 118, 150, 215, 150, 150, 150, 25,
- /* 310 */ 220, 26, 27, 22, 213, 26, 27, 26, 27, 165,
- /* 320 */ 25, 165, 165, 165, 30, 94, 49, 50, 34, 173,
- /* 330 */ 174, 173, 174, 88, 89, 90, 91, 92, 7, 8,
- /* 340 */ 160, 187, 48, 57, 187, 68, 69, 70, 71, 72,
- /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82,
- /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 370 */ 19, 215, 150, 215, 194, 19, 220, 88, 220, 94,
- /* 380 */ 95, 23, 160, 94, 95, 94, 95, 165, 26, 27,
- /* 390 */ 95, 105, 106, 107, 113, 173, 174, 217, 22, 150,
- /* 400 */ 49, 50, 116, 119, 57, 120, 50, 158, 22, 21,
- /* 410 */ 161, 162, 232, 136, 165, 120, 194, 237, 23, 68,
- /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 430 */ 79, 80, 22, 82, 83, 84, 85, 86, 87, 88,
- /* 440 */ 89, 90, 91, 92, 19, 23, 12, 112, 23, 114,
- /* 450 */ 115, 63, 105, 106, 107, 23, 94, 95, 97, 98,
- /* 460 */ 104, 150, 28, 116, 25, 109, 150, 150, 23, 23,
- /* 470 */ 112, 25, 114, 115, 49, 50, 165, 150, 44, 11,
- /* 480 */ 46, 165, 165, 16, 173, 174, 76, 136, 100, 173,
- /* 490 */ 174, 57, 165, 68, 69, 70, 71, 72, 73, 74,
- /* 500 */ 75, 76, 77, 78, 79, 80, 166, 82, 83, 84,
- /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 169,
- /* 520 */ 170, 171, 23, 12, 23, 214, 138, 60, 150, 62,
- /* 530 */ 24, 215, 26, 216, 112, 150, 114, 115, 36, 28,
- /* 540 */ 213, 95, 103, 165, 112, 205, 114, 115, 49, 50,
- /* 550 */ 165, 173, 174, 51, 23, 44, 25, 46, 173, 174,
- /* 560 */ 58, 22, 23, 22, 25, 160, 120, 68, 69, 70,
- /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 580 */ 230, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 590 */ 91, 92, 19, 215, 22, 23, 23, 25, 163, 194,
- /* 600 */ 94, 166, 167, 168, 25, 138, 67, 7, 8, 9,
- /* 610 */ 108, 206, 207, 169, 170, 171, 150, 22, 221, 222,
- /* 620 */ 223, 26, 49, 50, 86, 87, 23, 161, 162, 23,
- /* 630 */ 22, 165, 24, 120, 22, 23, 25, 160, 241, 67,
- /* 640 */ 176, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 650 */ 77, 78, 79, 80, 160, 82, 83, 84, 85, 86,
- /* 660 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 150,
- /* 670 */ 23, 194, 35, 23, 230, 25, 150, 155, 150, 67,
- /* 680 */ 150, 105, 106, 107, 165, 221, 222, 223, 194, 94,
- /* 690 */ 23, 165, 25, 165, 217, 165, 49, 50, 25, 173,
- /* 700 */ 174, 173, 174, 173, 174, 0, 1, 2, 118, 221,
- /* 710 */ 222, 223, 193, 219, 237, 68, 69, 70, 71, 72,
- /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 740 */ 19, 150, 19, 165, 150, 24, 166, 167, 168, 227,
- /* 750 */ 27, 173, 174, 231, 150, 25, 165, 150, 172, 165,
- /* 760 */ 150, 242, 129, 130, 173, 174, 180, 173, 174, 165,
- /* 770 */ 49, 50, 165, 150, 176, 165, 35, 173, 174, 165,
- /* 780 */ 173, 174, 35, 23, 23, 25, 25, 173, 165, 68,
- /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88,
- /* 810 */ 89, 90, 91, 92, 19, 150, 193, 165, 150, 221,
- /* 820 */ 222, 223, 150, 213, 19, 173, 174, 23, 150, 97,
- /* 830 */ 165, 150, 27, 165, 150, 150, 150, 165, 173, 174,
- /* 840 */ 22, 173, 174, 165, 49, 50, 165, 52, 116, 165,
- /* 850 */ 165, 165, 206, 207, 173, 174, 126, 50, 173, 174,
- /* 860 */ 128, 27, 160, 68, 69, 70, 71, 72, 73, 74,
- /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84,
- /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150,
- /* 890 */ 23, 165, 150, 23, 216, 25, 194, 32, 39, 173,
- /* 900 */ 174, 135, 150, 137, 165, 150, 41, 165, 150, 52,
- /* 910 */ 238, 104, 173, 174, 29, 173, 174, 165, 49, 50,
- /* 920 */ 165, 219, 238, 165, 238, 173, 174, 52, 173, 174,
- /* 930 */ 22, 173, 174, 23, 23, 160, 25, 68, 69, 70,
- /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 960 */ 91, 92, 19, 150, 150, 165, 150, 245, 246, 194,
- /* 970 */ 150, 144, 145, 173, 174, 160, 150, 22, 165, 165,
- /* 980 */ 22, 165, 150, 150, 116, 165, 173, 174, 52, 173,
- /* 990 */ 174, 165, 49, 50, 22, 150, 128, 165, 165, 173,
- /* 1000 */ 174, 187, 166, 166, 22, 173, 174, 187, 109, 194,
- /* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86,
- /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165,
- /* 1040 */ 102, 205, 205, 150, 150, 247, 248, 173, 174, 19,
- /* 1050 */ 150, 20, 165, 150, 150, 150, 150, 150, 165, 165,
- /* 1060 */ 173, 174, 49, 50, 104, 165, 49, 50, 165, 165,
- /* 1070 */ 165, 165, 165, 173, 174, 43, 173, 174, 173, 174,
- /* 1080 */ 187, 24, 190, 191, 71, 72, 69, 70, 71, 72,
- /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
- /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 1110 */ 19, 98, 150, 165, 150, 150, 150, 150, 150, 150,
- /* 1120 */ 59, 173, 174, 25, 150, 190, 191, 165, 53, 165,
- /* 1130 */ 165, 165, 165, 165, 165, 173, 174, 173, 174, 165,
- /* 1140 */ 49, 50, 91, 92, 1, 2, 53, 173, 174, 138,
- /* 1150 */ 104, 22, 5, 1, 35, 118, 127, 150, 193, 193,
- /* 1160 */ 193, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1170 */ 79, 80, 165, 82, 83, 84, 85, 86, 87, 88,
- /* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 27,
- /* 1190 */ 150, 26, 27, 108, 150, 22, 76, 76, 150, 25,
- /* 1200 */ 193, 165, 37, 165, 150, 165, 22, 19, 20, 165,
- /* 1210 */ 22, 173, 174, 165, 26, 27, 23, 150, 119, 165,
- /* 1220 */ 150, 56, 150, 150, 150, 37, 16, 173, 174, 193,
- /* 1230 */ 150, 66, 165, 193, 1, 165, 121, 165, 165, 165,
- /* 1240 */ 20, 146, 147, 119, 56, 165, 150, 152, 16, 154,
- /* 1250 */ 150, 86, 87, 88, 66, 160, 150, 150, 93, 94,
- /* 1260 */ 95, 165, 150, 98, 108, 165, 127, 23, 65, 173,
- /* 1270 */ 174, 165, 165, 150, 86, 87, 128, 165, 150, 173,
- /* 1280 */ 174, 93, 94, 95, 23, 150, 98, 15, 165, 194,
- /* 1290 */ 150, 140, 22, 165, 129, 130, 131, 132, 133, 134,
- /* 1300 */ 165, 173, 174, 3, 116, 165, 19, 20, 150, 22,
- /* 1310 */ 4, 150, 217, 26, 27, 179, 179, 129, 130, 131,
- /* 1320 */ 132, 133, 134, 165, 37, 150, 165, 150, 164, 19,
- /* 1330 */ 20, 150, 22, 246, 149, 249, 26, 27, 249, 244,
- /* 1340 */ 165, 150, 165, 56, 6, 150, 165, 37, 173, 174,
- /* 1350 */ 173, 174, 150, 66, 173, 174, 165, 149, 149, 13,
- /* 1360 */ 165, 25, 150, 150, 150, 149, 56, 165, 150, 116,
- /* 1370 */ 151, 150, 150, 86, 87, 150, 66, 165, 165, 165,
- /* 1380 */ 93, 94, 95, 165, 150, 98, 165, 165, 151, 22,
- /* 1390 */ 165, 194, 150, 26, 27, 150, 86, 87, 159, 165,
- /* 1400 */ 199, 126, 123, 93, 94, 95, 200, 165, 98, 124,
- /* 1410 */ 165, 122, 201, 125, 225, 135, 129, 130, 131, 132,
- /* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
- /* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
- /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
- /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
- /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
- /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
- /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
- /* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
- /* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
- /* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
- /* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
- /* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
- /* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
- /* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
- /* 1560 */ 195, 182, 250, 186,
+ /* 60 */ 79, 80, 81, 11, 83, 84, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 19, 95, 89, 90, 91,
+ /* 80 */ 92, 93, 26, 83, 84, 85, 86, 87, 88, 89,
+ /* 90 */ 90, 91, 92, 93, 27, 28, 95, 96, 97, 27,
+ /* 100 */ 28, 100, 101, 102, 22, 19, 50, 51, 27, 28,
+ /* 110 */ 58, 55, 111, 7, 8, 9, 87, 88, 89, 90,
+ /* 120 */ 91, 92, 93, 98, 99, 69, 70, 71, 72, 73,
+ /* 130 */ 74, 75, 76, 77, 78, 79, 80, 81, 127, 83,
+ /* 140 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 150 */ 19, 223, 224, 225, 87, 88, 162, 31, 106, 107,
+ /* 160 */ 108, 35, 95, 96, 33, 98, 23, 95, 96, 117,
+ /* 170 */ 119, 243, 105, 42, 107, 49, 95, 96, 151, 93,
+ /* 180 */ 26, 50, 51, 97, 98, 99, 100, 101, 102, 103,
+ /* 190 */ 196, 22, 23, 121, 167, 26, 110, 130, 131, 67,
+ /* 200 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 210 */ 79, 80, 81, 219, 83, 84, 85, 86, 87, 88,
+ /* 220 */ 89, 90, 91, 92, 93, 19, 12, 95, 234, 119,
+ /* 230 */ 24, 99, 113, 239, 115, 116, 151, 68, 23, 147,
+ /* 240 */ 148, 26, 215, 29, 151, 153, 119, 155, 163, 164,
+ /* 250 */ 23, 23, 167, 26, 162, 23, 50, 51, 26, 45,
+ /* 260 */ 167, 47, 130, 131, 132, 172, 173, 23, 22, 23,
+ /* 270 */ 26, 186, 26, 188, 120, 69, 70, 71, 72, 73,
+ /* 280 */ 74, 75, 76, 77, 78, 79, 80, 81, 196, 83,
+ /* 290 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 300 */ 19, 151, 151, 23, 119, 97, 26, 19, 100, 101,
+ /* 310 */ 102, 219, 151, 162, 68, 22, 28, 167, 167, 111,
+ /* 320 */ 27, 26, 172, 173, 231, 232, 175, 176, 167, 27,
+ /* 330 */ 28, 50, 51, 27, 28, 119, 175, 176, 246, 24,
+ /* 340 */ 22, 113, 27, 115, 116, 27, 28, 196, 22, 23,
+ /* 350 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 360 */ 79, 80, 81, 114, 83, 84, 85, 86, 87, 88,
+ /* 370 */ 89, 90, 91, 92, 93, 19, 21, 151, 217, 22,
+ /* 380 */ 151, 231, 232, 222, 27, 28, 23, 114, 95, 50,
+ /* 390 */ 51, 118, 151, 167, 68, 89, 167, 95, 96, 104,
+ /* 400 */ 23, 95, 96, 26, 175, 176, 50, 51, 167, 22,
+ /* 410 */ 95, 72, 73, 95, 96, 16, 175, 176, 137, 64,
+ /* 420 */ 23, 195, 27, 121, 23, 69, 70, 71, 72, 73,
+ /* 430 */ 74, 75, 76, 77, 78, 79, 80, 81, 99, 83,
+ /* 440 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 450 */ 19, 12, 95, 96, 23, 226, 101, 22, 217, 19,
+ /* 460 */ 61, 151, 63, 222, 151, 106, 107, 108, 29, 159,
+ /* 470 */ 244, 151, 99, 163, 164, 23, 113, 167, 115, 116,
+ /* 480 */ 167, 50, 51, 110, 45, 58, 47, 167, 175, 176,
+ /* 490 */ 95, 51, 168, 137, 139, 175, 176, 58, 11, 22,
+ /* 500 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 510 */ 79, 80, 81, 22, 83, 84, 85, 86, 87, 88,
+ /* 520 */ 89, 90, 91, 92, 93, 19, 23, 151, 117, 23,
+ /* 530 */ 217, 207, 19, 106, 107, 108, 216, 151, 139, 23,
+ /* 540 */ 129, 28, 26, 167, 117, 105, 23, 223, 224, 225,
+ /* 550 */ 110, 175, 176, 167, 77, 165, 50, 51, 168, 169,
+ /* 560 */ 170, 175, 176, 87, 88, 113, 26, 115, 116, 171,
+ /* 570 */ 172, 173, 0, 1, 2, 69, 70, 71, 72, 73,
+ /* 580 */ 74, 75, 76, 77, 78, 79, 80, 81, 162, 83,
+ /* 590 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 600 */ 19, 151, 98, 217, 23, 37, 130, 131, 23, 23,
+ /* 610 */ 26, 26, 96, 163, 164, 23, 113, 167, 115, 116,
+ /* 620 */ 52, 117, 196, 151, 171, 172, 173, 59, 130, 131,
+ /* 630 */ 232, 50, 51, 129, 208, 209, 16, 121, 156, 167,
+ /* 640 */ 22, 23, 162, 223, 224, 225, 51, 175, 176, 121,
+ /* 650 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 660 */ 79, 80, 81, 178, 83, 84, 85, 86, 87, 88,
+ /* 670 */ 89, 90, 91, 92, 93, 19, 196, 109, 151, 23,
+ /* 680 */ 96, 61, 151, 63, 23, 232, 68, 26, 151, 168,
+ /* 690 */ 169, 170, 23, 89, 167, 26, 208, 209, 167, 219,
+ /* 700 */ 105, 36, 175, 176, 167, 121, 50, 51, 223, 224,
+ /* 710 */ 225, 229, 175, 176, 178, 233, 247, 248, 114, 239,
+ /* 720 */ 189, 22, 118, 24, 162, 69, 70, 71, 72, 73,
+ /* 730 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 740 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 750 */ 19, 151, 26, 151, 167, 24, 145, 146, 196, 223,
+ /* 760 */ 224, 225, 175, 176, 151, 182, 183, 167, 151, 167,
+ /* 770 */ 151, 36, 199, 190, 151, 175, 176, 175, 176, 206,
+ /* 780 */ 167, 50, 51, 221, 167, 136, 167, 138, 175, 176,
+ /* 790 */ 167, 26, 175, 176, 175, 176, 168, 36, 175, 176,
+ /* 800 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 810 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 820 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 830 */ 151, 151, 151, 151, 162, 207, 23, 175, 176, 26,
+ /* 840 */ 249, 250, 167, 167, 167, 151, 167, 167, 167, 167,
+ /* 850 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 53,
+ /* 860 */ 22, 167, 192, 193, 33, 189, 192, 193, 196, 189,
+ /* 870 */ 189, 189, 162, 42, 167, 69, 70, 71, 72, 73,
+ /* 880 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 890 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 900 */ 19, 151, 195, 151, 167, 151, 196, 162, 151, 215,
+ /* 910 */ 92, 93, 175, 176, 28, 174, 119, 167, 151, 167,
+ /* 920 */ 151, 167, 151, 182, 167, 175, 176, 175, 176, 175,
+ /* 930 */ 176, 50, 51, 23, 167, 23, 167, 40, 167, 22,
+ /* 940 */ 167, 196, 53, 168, 175, 176, 175, 176, 175, 162,
+ /* 950 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 960 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 970 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 980 */ 151, 151, 207, 196, 30, 218, 22, 175, 176, 1,
+ /* 990 */ 2, 53, 167, 167, 167, 151, 167, 167, 151, 151,
+ /* 1000 */ 175, 176, 175, 176, 175, 176, 50, 51, 221, 23,
+ /* 1010 */ 53, 167, 22, 22, 167, 167, 103, 168, 22, 110,
+ /* 1020 */ 19, 105, 175, 176, 20, 69, 70, 71, 72, 73,
+ /* 1030 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 1040 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 1050 */ 19, 151, 151, 151, 167, 151, 207, 24, 44, 215,
+ /* 1060 */ 60, 26, 175, 176, 54, 54, 240, 167, 167, 167,
+ /* 1070 */ 240, 167, 151, 151, 151, 175, 176, 175, 176, 175,
+ /* 1080 */ 176, 50, 51, 139, 151, 22, 105, 119, 167, 167,
+ /* 1090 */ 167, 5, 1, 36, 28, 77, 175, 176, 175, 176,
+ /* 1100 */ 167, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 1110 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
+ /* 1120 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
+ /* 1130 */ 151, 151, 109, 151, 128, 77, 22, 175, 176, 26,
+ /* 1140 */ 218, 240, 167, 167, 167, 151, 167, 167, 151, 167,
+ /* 1150 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 22,
+ /* 1160 */ 151, 167, 23, 120, 167, 1, 16, 122, 20, 120,
+ /* 1170 */ 109, 195, 175, 176, 167, 195, 167, 71, 72, 73,
+ /* 1180 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
+ /* 1190 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 1200 */ 19, 20, 195, 22, 167, 151, 151, 128, 27, 28,
+ /* 1210 */ 129, 23, 175, 176, 23, 66, 141, 22, 151, 38,
+ /* 1220 */ 151, 167, 167, 19, 20, 151, 22, 151, 151, 175,
+ /* 1230 */ 176, 27, 28, 151, 167, 15, 167, 4, 57, 16,
+ /* 1240 */ 151, 167, 38, 167, 167, 3, 166, 248, 67, 167,
+ /* 1250 */ 195, 175, 176, 181, 181, 150, 167, 175, 176, 251,
+ /* 1260 */ 6, 57, 151, 151, 175, 176, 151, 151, 87, 88,
+ /* 1270 */ 89, 67, 151, 162, 151, 94, 95, 96, 167, 167,
+ /* 1280 */ 99, 251, 167, 167, 152, 151, 175, 176, 167, 151,
+ /* 1290 */ 167, 87, 88, 151, 150, 150, 175, 176, 94, 95,
+ /* 1300 */ 96, 167, 150, 99, 151, 167, 151, 196, 13, 167,
+ /* 1310 */ 195, 130, 131, 132, 133, 134, 135, 152, 195, 160,
+ /* 1320 */ 167, 117, 167, 19, 20, 151, 22, 151, 217, 151,
+ /* 1330 */ 161, 27, 28, 222, 130, 131, 132, 133, 134, 135,
+ /* 1340 */ 151, 167, 38, 167, 151, 167, 19, 20, 195, 22,
+ /* 1350 */ 151, 151, 151, 151, 27, 28, 167, 151, 151, 26,
+ /* 1360 */ 167, 57, 25, 196, 151, 38, 167, 167, 167, 167,
+ /* 1370 */ 151, 67, 151, 167, 167, 117, 201, 151, 125, 151,
+ /* 1380 */ 167, 151, 127, 124, 57, 151, 167, 202, 167, 203,
+ /* 1390 */ 151, 87, 88, 167, 67, 167, 151, 167, 94, 95,
+ /* 1400 */ 96, 167, 151, 99, 123, 126, 167, 204, 136, 227,
+ /* 1410 */ 205, 119, 167, 105, 87, 88, 122, 177, 167, 158,
+ /* 1420 */ 158, 94, 95, 96, 212, 105, 99, 213, 212, 177,
+ /* 1430 */ 213, 213, 185, 48, 130, 131, 132, 133, 134, 135,
+ /* 1440 */ 5, 212, 177, 179, 104, 10, 11, 12, 13, 14,
+ /* 1450 */ 177, 180, 17, 22, 230, 93, 180, 130, 131, 132,
+ /* 1460 */ 133, 134, 135, 185, 177, 230, 177, 32, 177, 34,
+ /* 1470 */ 157, 22, 18, 158, 157, 157, 27, 28, 43, 158,
+ /* 1480 */ 158, 158, 46, 237, 136, 157, 238, 158, 191, 201,
+ /* 1490 */ 69, 56, 191, 58, 220, 22, 157, 62, 18, 201,
+ /* 1500 */ 65, 158, 220, 194, 194, 194, 194, 201, 158, 242,
+ /* 1510 */ 191, 41, 242, 158, 158, 39, 67, 154, 232, 168,
+ /* 1520 */ 245, 228, 198, 178, 183, 200, 168, 211, 232, 168,
+ /* 1530 */ 178, 178, 201, 187, 198, 149, 87, 88, 179, 168,
+ /* 1540 */ 241, 106, 107, 108, 95, 211, 241, 112, 99, 211,
+ /* 1550 */ 201, 197, 117, 193, 210, 188, 184, 184, 184, 175,
+ /* 1560 */ 93, 235, 175, 252, 252, 252, 236, 252, 252, 252,
+ /* 1570 */ 252, 252, 252, 252, 252, 140, 252, 252, 252, 130,
+ /* 1580 */ 131, 132,
};
-#define YY_SHIFT_USE_DFLT (-70)
-#define YY_SHIFT_COUNT (416)
-#define YY_SHIFT_MIN (-69)
-#define YY_SHIFT_MAX (1487)
+#define YY_SHIFT_USE_DFLT (-82)
+#define YY_SHIFT_COUNT (419)
+#define YY_SHIFT_MIN (-81)
+#define YY_SHIFT_MAX (1480)
static const short yy_shift_ofst[] = {
- /* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
- /* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
- /* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
- /* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
- /* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
- /* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
- /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
- /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
- /* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
- /* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
- /* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
- /* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
- /* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
- /* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
- /* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
- /* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
- /* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
- /* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
- /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
- /* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
- /* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
- /* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
- /* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
- /* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
- /* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
- /* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
- /* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
- /* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
- /* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
- /* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
- /* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
- /* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
- /* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
- /* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
- /* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
- /* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
- /* 410 */ 92, 75, 45, 114, 25, 11, 5,
+ /* 0 */ 988, 1204, 1435, 1204, 1304, 1304, 67, 67, 1, -19,
+ /* 10 */ 1304, 1304, 1304, 1304, 427, 81, 131, 131, 806, 1181,
+ /* 20 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 30 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 40 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1327, 1304,
+ /* 50 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
+ /* 60 */ 1304, 1304, 52, 81, 81, 476, 476, 395, 1258, 56,
+ /* 70 */ 731, 656, 581, 506, 431, 356, 281, 206, 881, 881,
+ /* 80 */ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
+ /* 90 */ 881, 881, 881, 956, 881, 1031, 1106, 1106, -69, -45,
+ /* 100 */ -45, -45, -45, -45, 0, 29, -12, 81, 81, 81,
+ /* 110 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 120 */ 81, 81, 81, 355, 440, 81, 81, 81, 81, 81,
+ /* 130 */ 504, 411, 395, 818, 1467, -82, -82, -82, 1449, 86,
+ /* 140 */ 439, 439, 306, 357, 302, 72, 318, 246, 169, 81,
+ /* 150 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 160 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 170 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+ /* 180 */ 81, 81, 315, 315, 315, 572, 1258, 1258, 1258, -82,
+ /* 190 */ -82, -82, 132, 132, 208, 568, 568, 568, 516, 503,
+ /* 200 */ 214, 452, 363, 228, 119, 119, 119, 119, 359, 126,
+ /* 210 */ 119, 119, 584, 293, 604, 106, 11, 288, 288, 513,
+ /* 220 */ 11, 513, 295, 813, 395, 831, 395, 831, 595, 831,
+ /* 230 */ 288, 649, 498, 498, 395, 154, 273, 699, 1476, 1292,
+ /* 240 */ 1292, 1470, 1470, 1292, 1473, 1421, 1255, 1480, 1480, 1480,
+ /* 250 */ 1480, 1292, 1454, 1255, 1473, 1421, 1421, 1255, 1292, 1454,
+ /* 260 */ 1348, 1436, 1292, 1292, 1454, 1292, 1454, 1292, 1454, 1431,
+ /* 270 */ 1320, 1320, 1320, 1385, 1362, 1362, 1431, 1320, 1340, 1320,
+ /* 280 */ 1385, 1320, 1320, 1294, 1308, 1294, 1308, 1294, 1308, 1292,
+ /* 290 */ 1292, 1272, 1279, 1281, 1253, 1259, 1255, 1258, 1337, 1333,
+ /* 300 */ 1295, 1295, 1254, 1254, 1254, 1254, -82, -82, -82, -82,
+ /* 310 */ -82, -82, 339, 399, 618, 326, 620, -81, 669, 477,
+ /* 320 */ 661, 585, 377, 280, 244, 232, 25, -1, 373, 227,
+ /* 330 */ 215, 1233, 1242, 1195, 1075, 1220, 1149, 1223, 1191, 1188,
+ /* 340 */ 1081, 1113, 1079, 1061, 1049, 1148, 1045, 1150, 1164, 1043,
+ /* 350 */ 1139, 1137, 1113, 1114, 1006, 1058, 1018, 1023, 1066, 1057,
+ /* 360 */ 968, 1091, 1086, 1063, 981, 944, 1011, 1035, 1010, 1000,
+ /* 370 */ 1014, 916, 1033, 1004, 1001, 909, 913, 996, 957, 991,
+ /* 380 */ 990, 986, 964, 938, 954, 917, 889, 897, 912, 910,
+ /* 390 */ 797, 886, 761, 838, 528, 726, 735, 765, 665, 726,
+ /* 400 */ 592, 586, 540, 523, 491, 487, 435, 401, 397, 387,
+ /* 410 */ 249, 216, 185, 127, 110, 51, 82, 143, 15, 48,
};
-#define YY_REDUCE_USE_DFLT (-169)
-#define YY_REDUCE_COUNT (308)
-#define YY_REDUCE_MIN (-168)
-#define YY_REDUCE_MAX (1391)
+#define YY_REDUCE_USE_DFLT (-143)
+#define YY_REDUCE_COUNT (311)
+#define YY_REDUCE_MIN (-142)
+#define YY_REDUCE_MAX (1387)
static const short yy_reduce_ofst[] = {
- /* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
- /* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
- /* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
- /* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
- /* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
- /* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
- /* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
- /* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
- /* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
- /* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
- /* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
- /* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
- /* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
- /* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
- /* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
- /* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
- /* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
- /* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
- /* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
- /* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
- /* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
- /* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
- /* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
- /* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
- /* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
- /* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
- /* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
- /* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
- /* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
+ /* 0 */ -142, 1111, 92, 151, 241, 161, 150, 93, 85, 324,
+ /* 10 */ 386, 313, 320, 229, -6, 310, 536, 485, -72, 1121,
+ /* 20 */ 1089, 1082, 1076, 1054, 1037, 997, 979, 977, 975, 962,
+ /* 30 */ 923, 921, 904, 902, 900, 887, 847, 829, 827, 825,
+ /* 40 */ 812, 771, 769, 754, 752, 750, 737, 679, 677, 675,
+ /* 50 */ 662, 623, 619, 617, 613, 602, 600, 587, 537, 527,
+ /* 60 */ 472, 376, 480, 450, 226, 453, 398, 390, 426, 420,
+ /* 70 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 80 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 90 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
+ /* 100 */ 420, 420, 420, 420, 420, 420, 420, 1153, 922, 1123,
+ /* 110 */ 1115, 1055, 1007, 980, 976, 901, 844, 830, 767, 826,
+ /* 120 */ 682, 694, 707, 482, 583, 681, 680, 676, 531, 27,
+ /* 130 */ 787, 562, 521, 420, 420, 420, 420, 420, 773, 741,
+ /* 140 */ 674, 670, 1067, 1251, 1245, 1239, 1234, 591, 591, 1230,
+ /* 150 */ 1228, 1226, 1221, 1219, 1213, 1207, 1206, 1202, 1201, 1200,
+ /* 160 */ 1199, 1193, 1189, 1178, 1176, 1174, 1155, 1142, 1138, 1134,
+ /* 170 */ 1116, 1112, 1077, 1074, 1069, 1067, 1009, 994, 982, 933,
+ /* 180 */ 848, 757, 849, 775, 628, 611, 745, 710, 672, 469,
+ /* 190 */ 488, 573, 1387, 1384, 1367, 1374, 1373, 1372, 1344, 1354,
+ /* 200 */ 1360, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1330, 1326,
+ /* 210 */ 1354, 1354, 1344, 1371, 1336, 1386, 1349, 1338, 1334, 1305,
+ /* 220 */ 1331, 1299, 1359, 1346, 1361, 1353, 1358, 1352, 1341, 1345,
+ /* 230 */ 1316, 1293, 1296, 1286, 1351, 1325, 1324, 1363, 1275, 1356,
+ /* 240 */ 1355, 1270, 1267, 1350, 1282, 1319, 1306, 1312, 1311, 1310,
+ /* 250 */ 1309, 1343, 1339, 1298, 1274, 1301, 1297, 1288, 1329, 1328,
+ /* 260 */ 1248, 1246, 1323, 1322, 1318, 1321, 1317, 1315, 1313, 1276,
+ /* 270 */ 1291, 1289, 1287, 1278, 1235, 1224, 1271, 1273, 1264, 1265,
+ /* 280 */ 1247, 1252, 1240, 1218, 1229, 1217, 1216, 1214, 1212, 1262,
+ /* 290 */ 1261, 1182, 1205, 1203, 1186, 1185, 1175, 1167, 1169, 1159,
+ /* 300 */ 1165, 1132, 1152, 1145, 1144, 1105, 1030, 1008, 999, 1073,
+ /* 310 */ 1072, 1080,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
- /* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
- /* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
- /* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
- /* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
- /* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
- /* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
- /* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
- /* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
- /* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
- /* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
- /* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
- /* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
- /* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
- /* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
- /* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
- /* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
- /* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
- /* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
- /* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
- /* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
- /* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
- /* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
- /* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
- /* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
- /* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
- /* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
- /* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
- /* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
- /* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
- /* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
- /* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
- /* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
- /* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
- /* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
- /* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
- /* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
- /* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
- /* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
- /* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
- /* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
- /* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
- /* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
- /* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
- /* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
- /* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
- /* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
- /* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
- /* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
- /* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
- /* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
- /* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
- /* 620 */ 665, 639, 636, 635, 631, 630, 628,
+ /* 0 */ 636, 872, 960, 960, 872, 872, 960, 960, 960, 762,
+ /* 10 */ 960, 960, 960, 870, 960, 960, 790, 790, 934, 960,
+ /* 20 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 30 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 40 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 50 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 60 */ 960, 960, 960, 960, 960, 960, 960, 677, 766, 796,
+ /* 70 */ 960, 960, 960, 960, 960, 960, 960, 960, 933, 935,
+ /* 80 */ 804, 803, 913, 777, 801, 794, 798, 873, 866, 867,
+ /* 90 */ 865, 869, 874, 960, 797, 833, 850, 832, 844, 849,
+ /* 100 */ 856, 848, 845, 835, 834, 836, 837, 960, 960, 960,
+ /* 110 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 120 */ 960, 960, 960, 662, 731, 960, 960, 960, 960, 960,
+ /* 130 */ 960, 960, 960, 838, 839, 853, 852, 851, 960, 669,
+ /* 140 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 150 */ 940, 938, 960, 885, 960, 960, 960, 960, 960, 960,
+ /* 160 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 170 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 180 */ 960, 642, 762, 762, 762, 636, 960, 960, 960, 952,
+ /* 190 */ 766, 756, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 200 */ 960, 960, 960, 960, 806, 745, 923, 925, 960, 906,
+ /* 210 */ 743, 664, 764, 679, 754, 644, 800, 779, 779, 918,
+ /* 220 */ 800, 918, 702, 725, 960, 790, 960, 790, 699, 790,
+ /* 230 */ 779, 868, 960, 960, 960, 763, 754, 960, 945, 770,
+ /* 240 */ 770, 937, 937, 770, 812, 735, 800, 742, 742, 742,
+ /* 250 */ 742, 770, 659, 800, 812, 735, 735, 800, 770, 659,
+ /* 260 */ 912, 910, 770, 770, 659, 770, 659, 770, 659, 878,
+ /* 270 */ 733, 733, 733, 717, 882, 882, 878, 733, 702, 733,
+ /* 280 */ 717, 733, 733, 783, 778, 783, 778, 783, 778, 770,
+ /* 290 */ 770, 960, 795, 784, 793, 791, 800, 960, 665, 720,
+ /* 300 */ 652, 652, 641, 641, 641, 641, 957, 957, 952, 704,
+ /* 310 */ 704, 687, 960, 960, 960, 960, 960, 960, 960, 887,
+ /* 320 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 330 */ 960, 960, 637, 947, 960, 960, 944, 960, 960, 960,
+ /* 340 */ 960, 805, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 350 */ 960, 960, 922, 960, 960, 960, 960, 960, 960, 960,
+ /* 360 */ 916, 960, 960, 960, 960, 960, 960, 909, 908, 960,
+ /* 370 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 380 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 390 */ 960, 960, 960, 960, 960, 792, 960, 785, 960, 871,
+ /* 400 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
+ /* 410 */ 748, 821, 960, 820, 824, 819, 671, 960, 650, 960,
+ /* 420 */ 633, 638, 956, 959, 958, 955, 954, 953, 948, 946,
+ /* 430 */ 943, 942, 941, 939, 936, 932, 891, 889, 896, 895,
+ /* 440 */ 894, 893, 892, 890, 888, 886, 807, 802, 799, 931,
+ /* 450 */ 884, 744, 741, 740, 658, 949, 915, 924, 811, 810,
+ /* 460 */ 813, 921, 920, 919, 917, 914, 901, 809, 808, 736,
+ /* 470 */ 876, 875, 661, 905, 904, 903, 907, 911, 902, 772,
+ /* 480 */ 660, 657, 668, 723, 724, 732, 730, 729, 728, 727,
+ /* 490 */ 726, 722, 670, 678, 716, 701, 700, 881, 883, 880,
+ /* 500 */ 879, 709, 708, 714, 713, 712, 711, 710, 707, 706,
+ /* 510 */ 705, 698, 697, 703, 696, 719, 718, 715, 695, 739,
+ /* 520 */ 738, 737, 734, 694, 693, 692, 824, 691, 690, 830,
+ /* 530 */ 829, 817, 860, 759, 758, 757, 769, 768, 781, 780,
+ /* 540 */ 815, 814, 782, 767, 761, 760, 776, 775, 774, 773,
+ /* 550 */ 765, 755, 787, 789, 788, 786, 862, 771, 859, 930,
+ /* 560 */ 929, 928, 927, 926, 864, 863, 831, 828, 682, 683,
+ /* 570 */ 899, 898, 900, 897, 685, 684, 681, 680, 861, 750,
+ /* 580 */ 749, 857, 854, 846, 842, 858, 855, 847, 843, 841,
+ /* 590 */ 840, 826, 825, 823, 822, 818, 827, 673, 751, 747,
+ /* 600 */ 746, 816, 753, 752, 689, 688, 686, 667, 666, 663,
+ /* 610 */ 656, 654, 653, 655, 651, 649, 648, 647, 646, 645,
+ /* 620 */ 676, 675, 674, 672, 671, 643, 640, 639, 635, 634,
+ /* 630 */ 632,
};
/* The next table maps tokens into fallback tokens. If a construct
@@ -110899,71 +115103,72 @@ static const YYACTIONTYPE yy_default[] = {
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 26, /* EXPLAIN => ID */
- 26, /* QUERY => ID */
- 26, /* PLAN => ID */
- 26, /* BEGIN => ID */
+ 27, /* EXPLAIN => ID */
+ 27, /* QUERY => ID */
+ 27, /* PLAN => ID */
+ 27, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 26, /* DEFERRED => ID */
- 26, /* IMMEDIATE => ID */
- 26, /* EXCLUSIVE => ID */
+ 27, /* DEFERRED => ID */
+ 27, /* IMMEDIATE => ID */
+ 27, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 26, /* END => ID */
- 26, /* ROLLBACK => ID */
- 26, /* SAVEPOINT => ID */
- 26, /* RELEASE => ID */
+ 27, /* END => ID */
+ 27, /* ROLLBACK => ID */
+ 27, /* SAVEPOINT => ID */
+ 27, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 26, /* IF => ID */
+ 27, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 26, /* TEMP => ID */
+ 27, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
+ 27, /* WITHOUT => ID */
0, /* COMMA => nothing */
0, /* ID => nothing */
0, /* INDEXED => nothing */
- 26, /* ABORT => ID */
- 26, /* ACTION => ID */
- 26, /* AFTER => ID */
- 26, /* ANALYZE => ID */
- 26, /* ASC => ID */
- 26, /* ATTACH => ID */
- 26, /* BEFORE => ID */
- 26, /* BY => ID */
- 26, /* CASCADE => ID */
- 26, /* CAST => ID */
- 26, /* COLUMNKW => ID */
- 26, /* CONFLICT => ID */
- 26, /* DATABASE => ID */
- 26, /* DESC => ID */
- 26, /* DETACH => ID */
- 26, /* EACH => ID */
- 26, /* FAIL => ID */
- 26, /* FOR => ID */
- 26, /* IGNORE => ID */
- 26, /* INITIALLY => ID */
- 26, /* INSTEAD => ID */
- 26, /* LIKE_KW => ID */
- 26, /* MATCH => ID */
- 26, /* NO => ID */
- 26, /* KEY => ID */
- 26, /* OF => ID */
- 26, /* OFFSET => ID */
- 26, /* PRAGMA => ID */
- 26, /* RAISE => ID */
- 26, /* REPLACE => ID */
- 26, /* RESTRICT => ID */
- 26, /* ROW => ID */
- 26, /* TRIGGER => ID */
- 26, /* VACUUM => ID */
- 26, /* VIEW => ID */
- 26, /* VIRTUAL => ID */
- 26, /* REINDEX => ID */
- 26, /* RENAME => ID */
- 26, /* CTIME_KW => ID */
+ 27, /* ABORT => ID */
+ 27, /* ACTION => ID */
+ 27, /* AFTER => ID */
+ 27, /* ANALYZE => ID */
+ 27, /* ASC => ID */
+ 27, /* ATTACH => ID */
+ 27, /* BEFORE => ID */
+ 27, /* BY => ID */
+ 27, /* CASCADE => ID */
+ 27, /* CAST => ID */
+ 27, /* COLUMNKW => ID */
+ 27, /* CONFLICT => ID */
+ 27, /* DATABASE => ID */
+ 27, /* DESC => ID */
+ 27, /* DETACH => ID */
+ 27, /* EACH => ID */
+ 27, /* FAIL => ID */
+ 27, /* FOR => ID */
+ 27, /* IGNORE => ID */
+ 27, /* INITIALLY => ID */
+ 27, /* INSTEAD => ID */
+ 27, /* LIKE_KW => ID */
+ 27, /* MATCH => ID */
+ 27, /* NO => ID */
+ 27, /* KEY => ID */
+ 27, /* OF => ID */
+ 27, /* OFFSET => ID */
+ 27, /* PRAGMA => ID */
+ 27, /* RAISE => ID */
+ 27, /* REPLACE => ID */
+ 27, /* RESTRICT => ID */
+ 27, /* ROW => ID */
+ 27, /* TRIGGER => ID */
+ 27, /* VACUUM => ID */
+ 27, /* VIEW => ID */
+ 27, /* VIRTUAL => ID */
+ 27, /* REINDEX => ID */
+ 27, /* RENAME => ID */
+ 27, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
@@ -111048,63 +115253,63 @@ static const char *const yyTokenName[] = {
"ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
"TABLE", "CREATE", "IF", "NOT",
"EXISTS", "TEMP", "LP", "RP",
- "AS", "COMMA", "ID", "INDEXED",
- "ABORT", "ACTION", "AFTER", "ANALYZE",
- "ASC", "ATTACH", "BEFORE", "BY",
- "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "NO",
- "KEY", "OF", "OFFSET", "PRAGMA",
- "RAISE", "REPLACE", "RESTRICT", "ROW",
- "TRIGGER", "VACUUM", "VIEW", "VIRTUAL",
- "REINDEX", "RENAME", "CTIME_KW", "ANY",
- "OR", "AND", "IS", "BETWEEN",
- "IN", "ISNULL", "NOTNULL", "NE",
- "EQ", "GT", "LE", "LT",
- "GE", "ESCAPE", "BITAND", "BITOR",
- "LSHIFT", "RSHIFT", "PLUS", "MINUS",
- "STAR", "SLASH", "REM", "CONCAT",
- "COLLATE", "BITNOT", "STRING", "JOIN_KW",
- "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY",
- "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR",
- "ON", "INSERT", "DELETE", "UPDATE",
- "SET", "DEFERRABLE", "FOREIGN", "DROP",
- "UNION", "ALL", "EXCEPT", "INTERSECT",
- "SELECT", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "VALUES", "INTEGER", "FLOAT", "BLOB",
- "REGISTER", "VARIABLE", "CASE", "WHEN",
- "THEN", "ELSE", "INDEX", "ALTER",
- "ADD", "error", "input", "cmdlist",
- "ecmd", "explain", "cmdx", "cmd",
- "transtype", "trans_opt", "nm", "savepoint_opt",
- "create_table", "create_table_args", "createkw", "temp",
- "ifnotexists", "dbnm", "columnlist", "conslist_opt",
- "select", "column", "columnid", "type",
- "carglist", "id", "ids", "typetoken",
- "typename", "signed", "plus_num", "minus_num",
- "ccons", "term", "expr", "onconf",
- "sortorder", "autoinc", "idxlist_opt", "refargs",
- "defer_subclause", "refarg", "refact", "init_deferred_pred_opt",
- "conslist", "tconscomma", "tcons", "idxlist",
- "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
- "ifexists", "fullname", "oneselect", "multiselect_op",
- "distinct", "selcollist", "from", "where_opt",
- "groupby_opt", "having_opt", "orderby_opt", "limit_opt",
- "sclp", "as", "seltablist", "stl_prefix",
- "joinop", "indexed_opt", "on_opt", "using_opt",
- "joinop2", "inscollist", "sortlist", "nexprlist",
- "setlist", "insert_cmd", "inscollist_opt", "valuelist",
- "exprlist", "likeop", "between_op", "in_op",
- "case_operand", "case_exprlist", "case_else", "uniqueflag",
- "collate", "nmnum", "number", "trigger_decl",
- "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause",
- "when_clause", "trigger_cmd", "trnm", "tridxby",
- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt",
- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken",
- "lp", "anylist",
+ "AS", "WITHOUT", "COMMA", "ID",
+ "INDEXED", "ABORT", "ACTION", "AFTER",
+ "ANALYZE", "ASC", "ATTACH", "BEFORE",
+ "BY", "CASCADE", "CAST", "COLUMNKW",
+ "CONFLICT", "DATABASE", "DESC", "DETACH",
+ "EACH", "FAIL", "FOR", "IGNORE",
+ "INITIALLY", "INSTEAD", "LIKE_KW", "MATCH",
+ "NO", "KEY", "OF", "OFFSET",
+ "PRAGMA", "RAISE", "REPLACE", "RESTRICT",
+ "ROW", "TRIGGER", "VACUUM", "VIEW",
+ "VIRTUAL", "REINDEX", "RENAME", "CTIME_KW",
+ "ANY", "OR", "AND", "IS",
+ "BETWEEN", "IN", "ISNULL", "NOTNULL",
+ "NE", "EQ", "GT", "LE",
+ "LT", "GE", "ESCAPE", "BITAND",
+ "BITOR", "LSHIFT", "RSHIFT", "PLUS",
+ "MINUS", "STAR", "SLASH", "REM",
+ "CONCAT", "COLLATE", "BITNOT", "STRING",
+ "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL",
+ "PRIMARY", "UNIQUE", "CHECK", "REFERENCES",
+ "AUTOINCR", "ON", "INSERT", "DELETE",
+ "UPDATE", "SET", "DEFERRABLE", "FOREIGN",
+ "DROP", "UNION", "ALL", "EXCEPT",
+ "INTERSECT", "SELECT", "DISTINCT", "DOT",
+ "FROM", "JOIN", "USING", "ORDER",
+ "GROUP", "HAVING", "LIMIT", "WHERE",
+ "INTO", "VALUES", "INTEGER", "FLOAT",
+ "BLOB", "REGISTER", "VARIABLE", "CASE",
+ "WHEN", "THEN", "ELSE", "INDEX",
+ "ALTER", "ADD", "error", "input",
+ "cmdlist", "ecmd", "explain", "cmdx",
+ "cmd", "transtype", "trans_opt", "nm",
+ "savepoint_opt", "create_table", "create_table_args", "createkw",
+ "temp", "ifnotexists", "dbnm", "columnlist",
+ "conslist_opt", "table_options", "select", "column",
+ "columnid", "type", "carglist", "id",
+ "ids", "typetoken", "typename", "signed",
+ "plus_num", "minus_num", "ccons", "term",
+ "expr", "onconf", "sortorder", "autoinc",
+ "idxlist_opt", "refargs", "defer_subclause", "refarg",
+ "refact", "init_deferred_pred_opt", "conslist", "tconscomma",
+ "tcons", "idxlist", "defer_subclause_opt", "orconf",
+ "resolvetype", "raisetype", "ifexists", "fullname",
+ "oneselect", "multiselect_op", "distinct", "selcollist",
+ "from", "where_opt", "groupby_opt", "having_opt",
+ "orderby_opt", "limit_opt", "sclp", "as",
+ "seltablist", "stl_prefix", "joinop", "indexed_opt",
+ "on_opt", "using_opt", "joinop2", "idlist",
+ "sortlist", "nexprlist", "setlist", "insert_cmd",
+ "inscollist_opt", "valuelist", "exprlist", "likeop",
+ "between_op", "in_op", "case_operand", "case_exprlist",
+ "case_else", "uniqueflag", "collate", "nmnum",
+ "number", "trigger_decl", "trigger_cmd_list", "trigger_time",
+ "trigger_event", "foreach_clause", "when_clause", "trigger_cmd",
+ "trnm", "tridxby", "database_kw_opt", "key_opt",
+ "add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist",
+ "vtabarg", "vtabargtoken", "lp", "anylist",
};
#endif /* NDEBUG */
@@ -111144,301 +115349,303 @@ static const char *const yyRuleName[] = {
/* 29 */ "ifnotexists ::= IF NOT EXISTS",
/* 30 */ "temp ::= TEMP",
/* 31 */ "temp ::=",
- /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 32 */ "create_table_args ::= LP columnlist conslist_opt RP table_options",
/* 33 */ "create_table_args ::= AS select",
- /* 34 */ "columnlist ::= columnlist COMMA column",
- /* 35 */ "columnlist ::= column",
- /* 36 */ "column ::= columnid type carglist",
- /* 37 */ "columnid ::= nm",
- /* 38 */ "id ::= ID",
- /* 39 */ "id ::= INDEXED",
- /* 40 */ "ids ::= ID|STRING",
- /* 41 */ "nm ::= id",
- /* 42 */ "nm ::= STRING",
- /* 43 */ "nm ::= JOIN_KW",
- /* 44 */ "type ::=",
- /* 45 */ "type ::= typetoken",
- /* 46 */ "typetoken ::= typename",
- /* 47 */ "typetoken ::= typename LP signed RP",
- /* 48 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 49 */ "typename ::= ids",
- /* 50 */ "typename ::= typename ids",
- /* 51 */ "signed ::= plus_num",
- /* 52 */ "signed ::= minus_num",
- /* 53 */ "carglist ::= carglist ccons",
- /* 54 */ "carglist ::=",
- /* 55 */ "ccons ::= CONSTRAINT nm",
- /* 56 */ "ccons ::= DEFAULT term",
- /* 57 */ "ccons ::= DEFAULT LP expr RP",
- /* 58 */ "ccons ::= DEFAULT PLUS term",
- /* 59 */ "ccons ::= DEFAULT MINUS term",
- /* 60 */ "ccons ::= DEFAULT id",
- /* 61 */ "ccons ::= NULL onconf",
- /* 62 */ "ccons ::= NOT NULL onconf",
- /* 63 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 64 */ "ccons ::= UNIQUE onconf",
- /* 65 */ "ccons ::= CHECK LP expr RP",
- /* 66 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 67 */ "ccons ::= defer_subclause",
- /* 68 */ "ccons ::= COLLATE ids",
- /* 69 */ "autoinc ::=",
- /* 70 */ "autoinc ::= AUTOINCR",
- /* 71 */ "refargs ::=",
- /* 72 */ "refargs ::= refargs refarg",
- /* 73 */ "refarg ::= MATCH nm",
- /* 74 */ "refarg ::= ON INSERT refact",
- /* 75 */ "refarg ::= ON DELETE refact",
- /* 76 */ "refarg ::= ON UPDATE refact",
- /* 77 */ "refact ::= SET NULL",
- /* 78 */ "refact ::= SET DEFAULT",
- /* 79 */ "refact ::= CASCADE",
- /* 80 */ "refact ::= RESTRICT",
- /* 81 */ "refact ::= NO ACTION",
- /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 84 */ "init_deferred_pred_opt ::=",
- /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 87 */ "conslist_opt ::=",
- /* 88 */ "conslist_opt ::= COMMA conslist",
- /* 89 */ "conslist ::= conslist tconscomma tcons",
- /* 90 */ "conslist ::= tcons",
- /* 91 */ "tconscomma ::= COMMA",
- /* 92 */ "tconscomma ::=",
- /* 93 */ "tcons ::= CONSTRAINT nm",
- /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 96 */ "tcons ::= CHECK LP expr RP onconf",
- /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 98 */ "defer_subclause_opt ::=",
- /* 99 */ "defer_subclause_opt ::= defer_subclause",
- /* 100 */ "onconf ::=",
- /* 101 */ "onconf ::= ON CONFLICT resolvetype",
- /* 102 */ "orconf ::=",
- /* 103 */ "orconf ::= OR resolvetype",
- /* 104 */ "resolvetype ::= raisetype",
- /* 105 */ "resolvetype ::= IGNORE",
- /* 106 */ "resolvetype ::= REPLACE",
- /* 107 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 108 */ "ifexists ::= IF EXISTS",
- /* 109 */ "ifexists ::=",
- /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
- /* 111 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 112 */ "cmd ::= select",
- /* 113 */ "select ::= oneselect",
- /* 114 */ "select ::= select multiselect_op oneselect",
- /* 115 */ "multiselect_op ::= UNION",
- /* 116 */ "multiselect_op ::= UNION ALL",
- /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 119 */ "distinct ::= DISTINCT",
- /* 120 */ "distinct ::= ALL",
- /* 121 */ "distinct ::=",
- /* 122 */ "sclp ::= selcollist COMMA",
- /* 123 */ "sclp ::=",
- /* 124 */ "selcollist ::= sclp expr as",
- /* 125 */ "selcollist ::= sclp STAR",
- /* 126 */ "selcollist ::= sclp nm DOT STAR",
- /* 127 */ "as ::= AS nm",
- /* 128 */ "as ::= ids",
- /* 129 */ "as ::=",
- /* 130 */ "from ::=",
- /* 131 */ "from ::= FROM seltablist",
- /* 132 */ "stl_prefix ::= seltablist joinop",
- /* 133 */ "stl_prefix ::=",
- /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 137 */ "dbnm ::=",
- /* 138 */ "dbnm ::= DOT nm",
- /* 139 */ "fullname ::= nm dbnm",
- /* 140 */ "joinop ::= COMMA|JOIN",
- /* 141 */ "joinop ::= JOIN_KW JOIN",
- /* 142 */ "joinop ::= JOIN_KW nm JOIN",
- /* 143 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 144 */ "on_opt ::= ON expr",
- /* 145 */ "on_opt ::=",
- /* 146 */ "indexed_opt ::=",
- /* 147 */ "indexed_opt ::= INDEXED BY nm",
- /* 148 */ "indexed_opt ::= NOT INDEXED",
- /* 149 */ "using_opt ::= USING LP inscollist RP",
- /* 150 */ "using_opt ::=",
- /* 151 */ "orderby_opt ::=",
- /* 152 */ "orderby_opt ::= ORDER BY sortlist",
- /* 153 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 154 */ "sortlist ::= expr sortorder",
- /* 155 */ "sortorder ::= ASC",
- /* 156 */ "sortorder ::= DESC",
- /* 157 */ "sortorder ::=",
- /* 158 */ "groupby_opt ::=",
- /* 159 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 160 */ "having_opt ::=",
- /* 161 */ "having_opt ::= HAVING expr",
- /* 162 */ "limit_opt ::=",
- /* 163 */ "limit_opt ::= LIMIT expr",
- /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 165 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 167 */ "where_opt ::=",
- /* 168 */ "where_opt ::= WHERE expr",
- /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 170 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 171 */ "setlist ::= nm EQ expr",
- /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
- /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
- /* 175 */ "insert_cmd ::= INSERT orconf",
- /* 176 */ "insert_cmd ::= REPLACE",
- /* 177 */ "valuelist ::= VALUES LP nexprlist RP",
- /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP",
- /* 179 */ "inscollist_opt ::=",
- /* 180 */ "inscollist_opt ::= LP inscollist RP",
- /* 181 */ "inscollist ::= inscollist COMMA nm",
- /* 182 */ "inscollist ::= nm",
- /* 183 */ "expr ::= term",
- /* 184 */ "expr ::= LP expr RP",
- /* 185 */ "term ::= NULL",
- /* 186 */ "expr ::= id",
- /* 187 */ "expr ::= JOIN_KW",
- /* 188 */ "expr ::= nm DOT nm",
- /* 189 */ "expr ::= nm DOT nm DOT nm",
- /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 191 */ "term ::= STRING",
- /* 192 */ "expr ::= REGISTER",
- /* 193 */ "expr ::= VARIABLE",
- /* 194 */ "expr ::= expr COLLATE ids",
- /* 195 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 196 */ "expr ::= ID LP distinct exprlist RP",
- /* 197 */ "expr ::= ID LP STAR RP",
- /* 198 */ "term ::= CTIME_KW",
- /* 199 */ "expr ::= expr AND expr",
- /* 200 */ "expr ::= expr OR expr",
- /* 201 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 202 */ "expr ::= expr EQ|NE expr",
- /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 204 */ "expr ::= expr PLUS|MINUS expr",
- /* 205 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 206 */ "expr ::= expr CONCAT expr",
- /* 207 */ "likeop ::= LIKE_KW",
- /* 208 */ "likeop ::= NOT LIKE_KW",
- /* 209 */ "likeop ::= MATCH",
- /* 210 */ "likeop ::= NOT MATCH",
- /* 211 */ "expr ::= expr likeop expr",
- /* 212 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 213 */ "expr ::= expr ISNULL|NOTNULL",
- /* 214 */ "expr ::= expr NOT NULL",
- /* 215 */ "expr ::= expr IS expr",
- /* 216 */ "expr ::= expr IS NOT expr",
- /* 217 */ "expr ::= NOT expr",
- /* 218 */ "expr ::= BITNOT expr",
- /* 219 */ "expr ::= MINUS expr",
- /* 220 */ "expr ::= PLUS expr",
- /* 221 */ "between_op ::= BETWEEN",
- /* 222 */ "between_op ::= NOT BETWEEN",
- /* 223 */ "expr ::= expr between_op expr AND expr",
- /* 224 */ "in_op ::= IN",
- /* 225 */ "in_op ::= NOT IN",
- /* 226 */ "expr ::= expr in_op LP exprlist RP",
- /* 227 */ "expr ::= LP select RP",
- /* 228 */ "expr ::= expr in_op LP select RP",
- /* 229 */ "expr ::= expr in_op nm dbnm",
- /* 230 */ "expr ::= EXISTS LP select RP",
- /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 233 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 234 */ "case_else ::= ELSE expr",
- /* 235 */ "case_else ::=",
- /* 236 */ "case_operand ::= expr",
- /* 237 */ "case_operand ::=",
- /* 238 */ "exprlist ::= nexprlist",
- /* 239 */ "exprlist ::=",
- /* 240 */ "nexprlist ::= nexprlist COMMA expr",
- /* 241 */ "nexprlist ::= expr",
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 243 */ "uniqueflag ::= UNIQUE",
- /* 244 */ "uniqueflag ::=",
- /* 245 */ "idxlist_opt ::=",
- /* 246 */ "idxlist_opt ::= LP idxlist RP",
- /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 248 */ "idxlist ::= nm collate sortorder",
- /* 249 */ "collate ::=",
- /* 250 */ "collate ::= COLLATE ids",
- /* 251 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 252 */ "cmd ::= VACUUM",
- /* 253 */ "cmd ::= VACUUM nm",
- /* 254 */ "cmd ::= PRAGMA nm dbnm",
- /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 259 */ "nmnum ::= plus_num",
- /* 260 */ "nmnum ::= nm",
- /* 261 */ "nmnum ::= ON",
- /* 262 */ "nmnum ::= DELETE",
- /* 263 */ "nmnum ::= DEFAULT",
- /* 264 */ "plus_num ::= PLUS number",
- /* 265 */ "plus_num ::= number",
- /* 266 */ "minus_num ::= MINUS number",
- /* 267 */ "number ::= INTEGER|FLOAT",
- /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 270 */ "trigger_time ::= BEFORE",
- /* 271 */ "trigger_time ::= AFTER",
- /* 272 */ "trigger_time ::= INSTEAD OF",
- /* 273 */ "trigger_time ::=",
- /* 274 */ "trigger_event ::= DELETE|INSERT",
- /* 275 */ "trigger_event ::= UPDATE",
- /* 276 */ "trigger_event ::= UPDATE OF inscollist",
- /* 277 */ "foreach_clause ::=",
- /* 278 */ "foreach_clause ::= FOR EACH ROW",
- /* 279 */ "when_clause ::=",
- /* 280 */ "when_clause ::= WHEN expr",
- /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 283 */ "trnm ::= nm",
- /* 284 */ "trnm ::= nm DOT nm",
- /* 285 */ "tridxby ::=",
- /* 286 */ "tridxby ::= INDEXED BY nm",
- /* 287 */ "tridxby ::= NOT INDEXED",
- /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
- /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 292 */ "trigger_cmd ::= select",
- /* 293 */ "expr ::= RAISE LP IGNORE RP",
- /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 295 */ "raisetype ::= ROLLBACK",
- /* 296 */ "raisetype ::= ABORT",
- /* 297 */ "raisetype ::= FAIL",
- /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 300 */ "cmd ::= DETACH database_kw_opt expr",
- /* 301 */ "key_opt ::=",
- /* 302 */ "key_opt ::= KEY expr",
- /* 303 */ "database_kw_opt ::= DATABASE",
- /* 304 */ "database_kw_opt ::=",
- /* 305 */ "cmd ::= REINDEX",
- /* 306 */ "cmd ::= REINDEX nm dbnm",
- /* 307 */ "cmd ::= ANALYZE",
- /* 308 */ "cmd ::= ANALYZE nm dbnm",
- /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 311 */ "add_column_fullname ::= fullname",
- /* 312 */ "kwcolumn_opt ::=",
- /* 313 */ "kwcolumn_opt ::= COLUMNKW",
- /* 314 */ "cmd ::= create_vtab",
- /* 315 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 317 */ "vtabarglist ::= vtabarg",
- /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 319 */ "vtabarg ::=",
- /* 320 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 321 */ "vtabargtoken ::= ANY",
- /* 322 */ "vtabargtoken ::= lp anylist RP",
- /* 323 */ "lp ::= LP",
- /* 324 */ "anylist ::=",
- /* 325 */ "anylist ::= anylist LP anylist RP",
- /* 326 */ "anylist ::= anylist ANY",
+ /* 34 */ "table_options ::=",
+ /* 35 */ "table_options ::= WITHOUT nm",
+ /* 36 */ "columnlist ::= columnlist COMMA column",
+ /* 37 */ "columnlist ::= column",
+ /* 38 */ "column ::= columnid type carglist",
+ /* 39 */ "columnid ::= nm",
+ /* 40 */ "id ::= ID",
+ /* 41 */ "id ::= INDEXED",
+ /* 42 */ "ids ::= ID|STRING",
+ /* 43 */ "nm ::= id",
+ /* 44 */ "nm ::= STRING",
+ /* 45 */ "nm ::= JOIN_KW",
+ /* 46 */ "type ::=",
+ /* 47 */ "type ::= typetoken",
+ /* 48 */ "typetoken ::= typename",
+ /* 49 */ "typetoken ::= typename LP signed RP",
+ /* 50 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /* 51 */ "typename ::= ids",
+ /* 52 */ "typename ::= typename ids",
+ /* 53 */ "signed ::= plus_num",
+ /* 54 */ "signed ::= minus_num",
+ /* 55 */ "carglist ::= carglist ccons",
+ /* 56 */ "carglist ::=",
+ /* 57 */ "ccons ::= CONSTRAINT nm",
+ /* 58 */ "ccons ::= DEFAULT term",
+ /* 59 */ "ccons ::= DEFAULT LP expr RP",
+ /* 60 */ "ccons ::= DEFAULT PLUS term",
+ /* 61 */ "ccons ::= DEFAULT MINUS term",
+ /* 62 */ "ccons ::= DEFAULT id",
+ /* 63 */ "ccons ::= NULL onconf",
+ /* 64 */ "ccons ::= NOT NULL onconf",
+ /* 65 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 66 */ "ccons ::= UNIQUE onconf",
+ /* 67 */ "ccons ::= CHECK LP expr RP",
+ /* 68 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 69 */ "ccons ::= defer_subclause",
+ /* 70 */ "ccons ::= COLLATE ids",
+ /* 71 */ "autoinc ::=",
+ /* 72 */ "autoinc ::= AUTOINCR",
+ /* 73 */ "refargs ::=",
+ /* 74 */ "refargs ::= refargs refarg",
+ /* 75 */ "refarg ::= MATCH nm",
+ /* 76 */ "refarg ::= ON INSERT refact",
+ /* 77 */ "refarg ::= ON DELETE refact",
+ /* 78 */ "refarg ::= ON UPDATE refact",
+ /* 79 */ "refact ::= SET NULL",
+ /* 80 */ "refact ::= SET DEFAULT",
+ /* 81 */ "refact ::= CASCADE",
+ /* 82 */ "refact ::= RESTRICT",
+ /* 83 */ "refact ::= NO ACTION",
+ /* 84 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 85 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 86 */ "init_deferred_pred_opt ::=",
+ /* 87 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 88 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 89 */ "conslist_opt ::=",
+ /* 90 */ "conslist_opt ::= COMMA conslist",
+ /* 91 */ "conslist ::= conslist tconscomma tcons",
+ /* 92 */ "conslist ::= tcons",
+ /* 93 */ "tconscomma ::= COMMA",
+ /* 94 */ "tconscomma ::=",
+ /* 95 */ "tcons ::= CONSTRAINT nm",
+ /* 96 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+ /* 97 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /* 98 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 99 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 100 */ "defer_subclause_opt ::=",
+ /* 101 */ "defer_subclause_opt ::= defer_subclause",
+ /* 102 */ "onconf ::=",
+ /* 103 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 104 */ "orconf ::=",
+ /* 105 */ "orconf ::= OR resolvetype",
+ /* 106 */ "resolvetype ::= raisetype",
+ /* 107 */ "resolvetype ::= IGNORE",
+ /* 108 */ "resolvetype ::= REPLACE",
+ /* 109 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 110 */ "ifexists ::= IF EXISTS",
+ /* 111 */ "ifexists ::=",
+ /* 112 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+ /* 113 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 114 */ "cmd ::= select",
+ /* 115 */ "select ::= oneselect",
+ /* 116 */ "select ::= select multiselect_op oneselect",
+ /* 117 */ "multiselect_op ::= UNION",
+ /* 118 */ "multiselect_op ::= UNION ALL",
+ /* 119 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 120 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 121 */ "distinct ::= DISTINCT",
+ /* 122 */ "distinct ::= ALL",
+ /* 123 */ "distinct ::=",
+ /* 124 */ "sclp ::= selcollist COMMA",
+ /* 125 */ "sclp ::=",
+ /* 126 */ "selcollist ::= sclp expr as",
+ /* 127 */ "selcollist ::= sclp STAR",
+ /* 128 */ "selcollist ::= sclp nm DOT STAR",
+ /* 129 */ "as ::= AS nm",
+ /* 130 */ "as ::= ids",
+ /* 131 */ "as ::=",
+ /* 132 */ "from ::=",
+ /* 133 */ "from ::= FROM seltablist",
+ /* 134 */ "stl_prefix ::= seltablist joinop",
+ /* 135 */ "stl_prefix ::=",
+ /* 136 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 137 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 138 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 139 */ "dbnm ::=",
+ /* 140 */ "dbnm ::= DOT nm",
+ /* 141 */ "fullname ::= nm dbnm",
+ /* 142 */ "joinop ::= COMMA|JOIN",
+ /* 143 */ "joinop ::= JOIN_KW JOIN",
+ /* 144 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 145 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 146 */ "on_opt ::= ON expr",
+ /* 147 */ "on_opt ::=",
+ /* 148 */ "indexed_opt ::=",
+ /* 149 */ "indexed_opt ::= INDEXED BY nm",
+ /* 150 */ "indexed_opt ::= NOT INDEXED",
+ /* 151 */ "using_opt ::= USING LP idlist RP",
+ /* 152 */ "using_opt ::=",
+ /* 153 */ "orderby_opt ::=",
+ /* 154 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 155 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 156 */ "sortlist ::= expr sortorder",
+ /* 157 */ "sortorder ::= ASC",
+ /* 158 */ "sortorder ::= DESC",
+ /* 159 */ "sortorder ::=",
+ /* 160 */ "groupby_opt ::=",
+ /* 161 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 162 */ "having_opt ::=",
+ /* 163 */ "having_opt ::= HAVING expr",
+ /* 164 */ "limit_opt ::=",
+ /* 165 */ "limit_opt ::= LIMIT expr",
+ /* 166 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 167 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 168 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
+ /* 169 */ "where_opt ::=",
+ /* 170 */ "where_opt ::= WHERE expr",
+ /* 171 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 172 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 173 */ "setlist ::= nm EQ expr",
+ /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
+ /* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
+ /* 176 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 177 */ "insert_cmd ::= INSERT orconf",
+ /* 178 */ "insert_cmd ::= REPLACE",
+ /* 179 */ "valuelist ::= VALUES LP nexprlist RP",
+ /* 180 */ "valuelist ::= valuelist COMMA LP exprlist RP",
+ /* 181 */ "inscollist_opt ::=",
+ /* 182 */ "inscollist_opt ::= LP idlist RP",
+ /* 183 */ "idlist ::= idlist COMMA nm",
+ /* 184 */ "idlist ::= nm",
+ /* 185 */ "expr ::= term",
+ /* 186 */ "expr ::= LP expr RP",
+ /* 187 */ "term ::= NULL",
+ /* 188 */ "expr ::= id",
+ /* 189 */ "expr ::= JOIN_KW",
+ /* 190 */ "expr ::= nm DOT nm",
+ /* 191 */ "expr ::= nm DOT nm DOT nm",
+ /* 192 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 193 */ "term ::= STRING",
+ /* 194 */ "expr ::= REGISTER",
+ /* 195 */ "expr ::= VARIABLE",
+ /* 196 */ "expr ::= expr COLLATE ids",
+ /* 197 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 198 */ "expr ::= ID LP distinct exprlist RP",
+ /* 199 */ "expr ::= ID LP STAR RP",
+ /* 200 */ "term ::= CTIME_KW",
+ /* 201 */ "expr ::= expr AND expr",
+ /* 202 */ "expr ::= expr OR expr",
+ /* 203 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 204 */ "expr ::= expr EQ|NE expr",
+ /* 205 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 206 */ "expr ::= expr PLUS|MINUS expr",
+ /* 207 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 208 */ "expr ::= expr CONCAT expr",
+ /* 209 */ "likeop ::= LIKE_KW",
+ /* 210 */ "likeop ::= NOT LIKE_KW",
+ /* 211 */ "likeop ::= MATCH",
+ /* 212 */ "likeop ::= NOT MATCH",
+ /* 213 */ "expr ::= expr likeop expr",
+ /* 214 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 215 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 216 */ "expr ::= expr NOT NULL",
+ /* 217 */ "expr ::= expr IS expr",
+ /* 218 */ "expr ::= expr IS NOT expr",
+ /* 219 */ "expr ::= NOT expr",
+ /* 220 */ "expr ::= BITNOT expr",
+ /* 221 */ "expr ::= MINUS expr",
+ /* 222 */ "expr ::= PLUS expr",
+ /* 223 */ "between_op ::= BETWEEN",
+ /* 224 */ "between_op ::= NOT BETWEEN",
+ /* 225 */ "expr ::= expr between_op expr AND expr",
+ /* 226 */ "in_op ::= IN",
+ /* 227 */ "in_op ::= NOT IN",
+ /* 228 */ "expr ::= expr in_op LP exprlist RP",
+ /* 229 */ "expr ::= LP select RP",
+ /* 230 */ "expr ::= expr in_op LP select RP",
+ /* 231 */ "expr ::= expr in_op nm dbnm",
+ /* 232 */ "expr ::= EXISTS LP select RP",
+ /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 236 */ "case_else ::= ELSE expr",
+ /* 237 */ "case_else ::=",
+ /* 238 */ "case_operand ::= expr",
+ /* 239 */ "case_operand ::=",
+ /* 240 */ "exprlist ::= nexprlist",
+ /* 241 */ "exprlist ::=",
+ /* 242 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 243 */ "nexprlist ::= expr",
+ /* 244 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
+ /* 245 */ "uniqueflag ::= UNIQUE",
+ /* 246 */ "uniqueflag ::=",
+ /* 247 */ "idxlist_opt ::=",
+ /* 248 */ "idxlist_opt ::= LP idxlist RP",
+ /* 249 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+ /* 250 */ "idxlist ::= nm collate sortorder",
+ /* 251 */ "collate ::=",
+ /* 252 */ "collate ::= COLLATE ids",
+ /* 253 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 254 */ "cmd ::= VACUUM",
+ /* 255 */ "cmd ::= VACUUM nm",
+ /* 256 */ "cmd ::= PRAGMA nm dbnm",
+ /* 257 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 258 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 259 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 260 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 261 */ "nmnum ::= plus_num",
+ /* 262 */ "nmnum ::= nm",
+ /* 263 */ "nmnum ::= ON",
+ /* 264 */ "nmnum ::= DELETE",
+ /* 265 */ "nmnum ::= DEFAULT",
+ /* 266 */ "plus_num ::= PLUS number",
+ /* 267 */ "plus_num ::= number",
+ /* 268 */ "minus_num ::= MINUS number",
+ /* 269 */ "number ::= INTEGER|FLOAT",
+ /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 272 */ "trigger_time ::= BEFORE",
+ /* 273 */ "trigger_time ::= AFTER",
+ /* 274 */ "trigger_time ::= INSTEAD OF",
+ /* 275 */ "trigger_time ::=",
+ /* 276 */ "trigger_event ::= DELETE|INSERT",
+ /* 277 */ "trigger_event ::= UPDATE",
+ /* 278 */ "trigger_event ::= UPDATE OF idlist",
+ /* 279 */ "foreach_clause ::=",
+ /* 280 */ "foreach_clause ::= FOR EACH ROW",
+ /* 281 */ "when_clause ::=",
+ /* 282 */ "when_clause ::= WHEN expr",
+ /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 285 */ "trnm ::= nm",
+ /* 286 */ "trnm ::= nm DOT nm",
+ /* 287 */ "tridxby ::=",
+ /* 288 */ "tridxby ::= INDEXED BY nm",
+ /* 289 */ "tridxby ::= NOT INDEXED",
+ /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
+ /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
+ /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 294 */ "trigger_cmd ::= select",
+ /* 295 */ "expr ::= RAISE LP IGNORE RP",
+ /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 297 */ "raisetype ::= ROLLBACK",
+ /* 298 */ "raisetype ::= ABORT",
+ /* 299 */ "raisetype ::= FAIL",
+ /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 302 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 303 */ "key_opt ::=",
+ /* 304 */ "key_opt ::= KEY expr",
+ /* 305 */ "database_kw_opt ::= DATABASE",
+ /* 306 */ "database_kw_opt ::=",
+ /* 307 */ "cmd ::= REINDEX",
+ /* 308 */ "cmd ::= REINDEX nm dbnm",
+ /* 309 */ "cmd ::= ANALYZE",
+ /* 310 */ "cmd ::= ANALYZE nm dbnm",
+ /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 313 */ "add_column_fullname ::= fullname",
+ /* 314 */ "kwcolumn_opt ::=",
+ /* 315 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 316 */ "cmd ::= create_vtab",
+ /* 317 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 319 */ "vtabarglist ::= vtabarg",
+ /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 321 */ "vtabarg ::=",
+ /* 322 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 323 */ "vtabargtoken ::= ANY",
+ /* 324 */ "vtabargtoken ::= lp anylist RP",
+ /* 325 */ "lp ::= LP",
+ /* 326 */ "anylist ::=",
+ /* 327 */ "anylist ::= anylist LP anylist RP",
+ /* 328 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -111517,76 +115724,76 @@ static void yy_destructor(
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
- case 160: /* select */
- case 194: /* oneselect */
+ case 162: /* select */
+ case 196: /* oneselect */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy159));
+sqlite3SelectDelete(pParse->db, (yypminor->yy387));
}
break;
- case 173: /* term */
- case 174: /* expr */
+ case 175: /* term */
+ case 176: /* expr */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr);
}
break;
- case 178: /* idxlist_opt */
- case 187: /* idxlist */
- case 197: /* selcollist */
- case 200: /* groupby_opt */
- case 202: /* orderby_opt */
- case 204: /* sclp */
- case 214: /* sortlist */
- case 215: /* nexprlist */
- case 216: /* setlist */
- case 220: /* exprlist */
- case 225: /* case_exprlist */
+ case 180: /* idxlist_opt */
+ case 189: /* idxlist */
+ case 199: /* selcollist */
+ case 202: /* groupby_opt */
+ case 204: /* orderby_opt */
+ case 206: /* sclp */
+ case 216: /* sortlist */
+ case 217: /* nexprlist */
+ case 218: /* setlist */
+ case 222: /* exprlist */
+ case 227: /* case_exprlist */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy442));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
}
break;
- case 193: /* fullname */
- case 198: /* from */
- case 206: /* seltablist */
- case 207: /* stl_prefix */
+ case 195: /* fullname */
+ case 200: /* from */
+ case 208: /* seltablist */
+ case 209: /* stl_prefix */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy347));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
}
break;
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 224: /* case_operand */
- case 226: /* case_else */
- case 236: /* when_clause */
- case 241: /* key_opt */
+ case 201: /* where_opt */
+ case 203: /* having_opt */
+ case 212: /* on_opt */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 238: /* when_clause */
+ case 243: /* key_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy122));
+sqlite3ExprDelete(pParse->db, (yypminor->yy314));
}
break;
- case 211: /* using_opt */
- case 213: /* inscollist */
- case 218: /* inscollist_opt */
+ case 213: /* using_opt */
+ case 215: /* idlist */
+ case 220: /* inscollist_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy180));
+sqlite3IdListDelete(pParse->db, (yypminor->yy384));
}
break;
- case 219: /* valuelist */
+ case 221: /* valuelist */
{
- sqlite3ExprListDelete(pParse->db, (yypminor->yy487).pList);
- sqlite3SelectDelete(pParse->db, (yypminor->yy487).pSelect);
+ sqlite3ExprListDelete(pParse->db, (yypminor->yy260).pList);
+ sqlite3SelectDelete(pParse->db, (yypminor->yy260).pSelect);
}
break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
+ case 234: /* trigger_cmd_list */
+ case 239: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy327));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
}
break;
- case 234: /* trigger_event */
+ case 236: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy410).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
}
break;
default: break; /* If no destructor action specified: do nothing */
@@ -111831,333 +116038,335 @@ static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
- { 142, 1 },
- { 143, 2 },
{ 143, 1 },
+ { 144, 2 },
{ 144, 1 },
- { 144, 3 },
- { 145, 0 },
{ 145, 1 },
{ 145, 3 },
+ { 146, 0 },
{ 146, 1 },
- { 147, 3 },
+ { 146, 3 },
+ { 147, 1 },
+ { 148, 3 },
+ { 150, 0 },
+ { 150, 1 },
+ { 150, 2 },
{ 149, 0 },
{ 149, 1 },
- { 149, 2 },
- { 148, 0 },
- { 148, 1 },
- { 148, 1 },
- { 148, 1 },
- { 147, 2 },
- { 147, 2 },
- { 147, 2 },
- { 151, 1 },
- { 151, 0 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 2 },
- { 152, 6 },
- { 154, 1 },
- { 156, 0 },
- { 156, 3 },
+ { 149, 1 },
+ { 149, 1 },
+ { 148, 2 },
+ { 148, 2 },
+ { 148, 2 },
+ { 152, 1 },
+ { 152, 0 },
+ { 148, 2 },
+ { 148, 3 },
+ { 148, 5 },
+ { 148, 2 },
+ { 153, 6 },
{ 155, 1 },
- { 155, 0 },
- { 153, 4 },
- { 153, 2 },
- { 158, 3 },
- { 158, 1 },
- { 161, 3 },
- { 162, 1 },
- { 165, 1 },
- { 165, 1 },
- { 166, 1 },
- { 150, 1 },
- { 150, 1 },
- { 150, 1 },
- { 163, 0 },
- { 163, 1 },
+ { 157, 0 },
+ { 157, 3 },
+ { 156, 1 },
+ { 156, 0 },
+ { 154, 5 },
+ { 154, 2 },
+ { 161, 0 },
+ { 161, 2 },
+ { 159, 3 },
+ { 159, 1 },
+ { 163, 3 },
+ { 164, 1 },
+ { 167, 1 },
{ 167, 1 },
- { 167, 4 },
- { 167, 6 },
{ 168, 1 },
- { 168, 2 },
- { 169, 1 },
+ { 151, 1 },
+ { 151, 1 },
+ { 151, 1 },
+ { 165, 0 },
+ { 165, 1 },
{ 169, 1 },
- { 164, 2 },
- { 164, 0 },
- { 172, 2 },
- { 172, 2 },
- { 172, 4 },
- { 172, 3 },
- { 172, 3 },
- { 172, 2 },
- { 172, 2 },
- { 172, 3 },
- { 172, 5 },
- { 172, 2 },
- { 172, 4 },
- { 172, 4 },
- { 172, 1 },
- { 172, 2 },
- { 177, 0 },
- { 177, 1 },
+ { 169, 4 },
+ { 169, 6 },
+ { 170, 1 },
+ { 170, 2 },
+ { 171, 1 },
+ { 171, 1 },
+ { 166, 2 },
+ { 166, 0 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 4 },
+ { 174, 3 },
+ { 174, 3 },
+ { 174, 2 },
+ { 174, 2 },
+ { 174, 3 },
+ { 174, 5 },
+ { 174, 2 },
+ { 174, 4 },
+ { 174, 4 },
+ { 174, 1 },
+ { 174, 2 },
{ 179, 0 },
- { 179, 2 },
+ { 179, 1 },
+ { 181, 0 },
{ 181, 2 },
- { 181, 3 },
- { 181, 3 },
- { 181, 3 },
- { 182, 2 },
- { 182, 2 },
- { 182, 1 },
- { 182, 1 },
- { 182, 2 },
- { 180, 3 },
- { 180, 2 },
- { 183, 0 },
- { 183, 2 },
{ 183, 2 },
- { 159, 0 },
- { 159, 2 },
- { 184, 3 },
+ { 183, 3 },
+ { 183, 3 },
+ { 183, 3 },
+ { 184, 2 },
+ { 184, 2 },
{ 184, 1 },
- { 185, 1 },
+ { 184, 1 },
+ { 184, 2 },
+ { 182, 3 },
+ { 182, 2 },
{ 185, 0 },
- { 186, 2 },
- { 186, 7 },
- { 186, 5 },
- { 186, 5 },
- { 186, 10 },
- { 188, 0 },
- { 188, 1 },
- { 175, 0 },
- { 175, 3 },
- { 189, 0 },
- { 189, 2 },
- { 190, 1 },
+ { 185, 2 },
+ { 185, 2 },
+ { 160, 0 },
+ { 160, 2 },
+ { 186, 3 },
+ { 186, 1 },
+ { 187, 1 },
+ { 187, 0 },
+ { 188, 2 },
+ { 188, 7 },
+ { 188, 5 },
+ { 188, 5 },
+ { 188, 10 },
+ { 190, 0 },
{ 190, 1 },
- { 190, 1 },
- { 147, 4 },
- { 192, 2 },
- { 192, 0 },
- { 147, 8 },
- { 147, 4 },
- { 147, 1 },
- { 160, 1 },
- { 160, 3 },
- { 195, 1 },
- { 195, 2 },
- { 195, 1 },
- { 194, 9 },
- { 196, 1 },
- { 196, 1 },
- { 196, 0 },
- { 204, 2 },
- { 204, 0 },
- { 197, 3 },
+ { 177, 0 },
+ { 177, 3 },
+ { 191, 0 },
+ { 191, 2 },
+ { 192, 1 },
+ { 192, 1 },
+ { 192, 1 },
+ { 148, 4 },
+ { 194, 2 },
+ { 194, 0 },
+ { 148, 8 },
+ { 148, 4 },
+ { 148, 1 },
+ { 162, 1 },
+ { 162, 3 },
+ { 197, 1 },
{ 197, 2 },
- { 197, 4 },
- { 205, 2 },
- { 205, 1 },
- { 205, 0 },
+ { 197, 1 },
+ { 196, 9 },
+ { 198, 1 },
+ { 198, 1 },
{ 198, 0 },
- { 198, 2 },
+ { 206, 2 },
+ { 206, 0 },
+ { 199, 3 },
+ { 199, 2 },
+ { 199, 4 },
{ 207, 2 },
+ { 207, 1 },
{ 207, 0 },
- { 206, 7 },
- { 206, 7 },
- { 206, 7 },
- { 157, 0 },
- { 157, 2 },
- { 193, 2 },
- { 208, 1 },
- { 208, 2 },
- { 208, 3 },
- { 208, 4 },
- { 210, 2 },
- { 210, 0 },
- { 209, 0 },
- { 209, 3 },
+ { 200, 0 },
+ { 200, 2 },
{ 209, 2 },
- { 211, 4 },
+ { 209, 0 },
+ { 208, 7 },
+ { 208, 7 },
+ { 208, 7 },
+ { 158, 0 },
+ { 158, 2 },
+ { 195, 2 },
+ { 210, 1 },
+ { 210, 2 },
+ { 210, 3 },
+ { 210, 4 },
+ { 212, 2 },
+ { 212, 0 },
{ 211, 0 },
+ { 211, 3 },
+ { 211, 2 },
+ { 213, 4 },
+ { 213, 0 },
+ { 204, 0 },
+ { 204, 3 },
+ { 216, 4 },
+ { 216, 2 },
+ { 178, 1 },
+ { 178, 1 },
+ { 178, 0 },
{ 202, 0 },
{ 202, 3 },
- { 214, 4 },
- { 214, 2 },
- { 176, 1 },
- { 176, 1 },
- { 176, 0 },
- { 200, 0 },
- { 200, 3 },
- { 201, 0 },
- { 201, 2 },
{ 203, 0 },
{ 203, 2 },
- { 203, 4 },
- { 203, 4 },
- { 147, 5 },
- { 199, 0 },
- { 199, 2 },
- { 147, 7 },
- { 216, 5 },
- { 216, 3 },
- { 147, 5 },
- { 147, 5 },
- { 147, 6 },
- { 217, 2 },
- { 217, 1 },
- { 219, 4 },
- { 219, 5 },
- { 218, 0 },
+ { 205, 0 },
+ { 205, 2 },
+ { 205, 4 },
+ { 205, 4 },
+ { 148, 5 },
+ { 201, 0 },
+ { 201, 2 },
+ { 148, 7 },
+ { 218, 5 },
{ 218, 3 },
- { 213, 3 },
- { 213, 1 },
- { 174, 1 },
- { 174, 3 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 5 },
- { 173, 1 },
- { 173, 1 },
- { 174, 1 },
- { 174, 1 },
- { 174, 3 },
- { 174, 6 },
- { 174, 5 },
- { 174, 4 },
- { 173, 1 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 174, 3 },
- { 221, 1 },
- { 221, 2 },
- { 221, 1 },
- { 221, 2 },
- { 174, 3 },
- { 174, 5 },
- { 174, 2 },
- { 174, 3 },
- { 174, 3 },
- { 174, 4 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 174, 2 },
- { 222, 1 },
- { 222, 2 },
- { 174, 5 },
- { 223, 1 },
- { 223, 2 },
- { 174, 5 },
- { 174, 3 },
- { 174, 5 },
- { 174, 4 },
- { 174, 4 },
- { 174, 5 },
- { 225, 5 },
- { 225, 4 },
- { 226, 2 },
- { 226, 0 },
- { 224, 1 },
- { 224, 0 },
- { 220, 1 },
+ { 148, 5 },
+ { 148, 5 },
+ { 148, 6 },
+ { 219, 2 },
+ { 219, 1 },
+ { 221, 4 },
+ { 221, 5 },
{ 220, 0 },
+ { 220, 3 },
{ 215, 3 },
{ 215, 1 },
- { 147, 11 },
- { 227, 1 },
- { 227, 0 },
- { 178, 0 },
- { 178, 3 },
- { 187, 5 },
- { 187, 3 },
- { 228, 0 },
+ { 176, 1 },
+ { 176, 3 },
+ { 175, 1 },
+ { 176, 1 },
+ { 176, 1 },
+ { 176, 3 },
+ { 176, 5 },
+ { 175, 1 },
+ { 175, 1 },
+ { 176, 1 },
+ { 176, 1 },
+ { 176, 3 },
+ { 176, 6 },
+ { 176, 5 },
+ { 176, 4 },
+ { 175, 1 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 3 },
+ { 223, 1 },
+ { 223, 2 },
+ { 223, 1 },
+ { 223, 2 },
+ { 176, 3 },
+ { 176, 5 },
+ { 176, 2 },
+ { 176, 3 },
+ { 176, 3 },
+ { 176, 4 },
+ { 176, 2 },
+ { 176, 2 },
+ { 176, 2 },
+ { 176, 2 },
+ { 224, 1 },
+ { 224, 2 },
+ { 176, 5 },
+ { 225, 1 },
+ { 225, 2 },
+ { 176, 5 },
+ { 176, 3 },
+ { 176, 5 },
+ { 176, 4 },
+ { 176, 4 },
+ { 176, 5 },
+ { 227, 5 },
+ { 227, 4 },
{ 228, 2 },
- { 147, 4 },
- { 147, 1 },
- { 147, 2 },
- { 147, 3 },
- { 147, 5 },
- { 147, 6 },
- { 147, 5 },
- { 147, 6 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
- { 229, 1 },
+ { 228, 0 },
+ { 226, 1 },
+ { 226, 0 },
+ { 222, 1 },
+ { 222, 0 },
+ { 217, 3 },
+ { 217, 1 },
+ { 148, 12 },
{ 229, 1 },
- { 170, 2 },
- { 170, 1 },
- { 171, 2 },
- { 230, 1 },
- { 147, 5 },
- { 231, 11 },
- { 233, 1 },
- { 233, 1 },
- { 233, 2 },
- { 233, 0 },
- { 234, 1 },
- { 234, 1 },
- { 234, 3 },
+ { 229, 0 },
+ { 180, 0 },
+ { 180, 3 },
+ { 189, 5 },
+ { 189, 3 },
+ { 230, 0 },
+ { 230, 2 },
+ { 148, 4 },
+ { 148, 1 },
+ { 148, 2 },
+ { 148, 3 },
+ { 148, 5 },
+ { 148, 6 },
+ { 148, 5 },
+ { 148, 6 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 231, 1 },
+ { 172, 2 },
+ { 172, 1 },
+ { 173, 2 },
+ { 232, 1 },
+ { 148, 5 },
+ { 233, 11 },
+ { 235, 1 },
+ { 235, 1 },
+ { 235, 2 },
{ 235, 0 },
- { 235, 3 },
- { 236, 0 },
- { 236, 2 },
- { 232, 3 },
- { 232, 2 },
- { 238, 1 },
- { 238, 3 },
- { 239, 0 },
- { 239, 3 },
- { 239, 2 },
- { 237, 7 },
- { 237, 5 },
- { 237, 5 },
- { 237, 5 },
- { 237, 1 },
- { 174, 4 },
- { 174, 6 },
- { 191, 1 },
- { 191, 1 },
- { 191, 1 },
- { 147, 4 },
- { 147, 6 },
- { 147, 3 },
+ { 236, 1 },
+ { 236, 1 },
+ { 236, 3 },
+ { 237, 0 },
+ { 237, 3 },
+ { 238, 0 },
+ { 238, 2 },
+ { 234, 3 },
+ { 234, 2 },
+ { 240, 1 },
+ { 240, 3 },
{ 241, 0 },
+ { 241, 3 },
{ 241, 2 },
- { 240, 1 },
- { 240, 0 },
- { 147, 1 },
- { 147, 3 },
- { 147, 1 },
- { 147, 3 },
- { 147, 6 },
- { 147, 6 },
- { 242, 1 },
+ { 239, 7 },
+ { 239, 5 },
+ { 239, 5 },
+ { 239, 5 },
+ { 239, 1 },
+ { 176, 4 },
+ { 176, 6 },
+ { 193, 1 },
+ { 193, 1 },
+ { 193, 1 },
+ { 148, 4 },
+ { 148, 6 },
+ { 148, 3 },
{ 243, 0 },
- { 243, 1 },
- { 147, 1 },
- { 147, 4 },
- { 244, 8 },
+ { 243, 2 },
+ { 242, 1 },
+ { 242, 0 },
+ { 148, 1 },
+ { 148, 3 },
+ { 148, 1 },
+ { 148, 3 },
+ { 148, 6 },
+ { 148, 6 },
+ { 244, 1 },
+ { 245, 0 },
{ 245, 1 },
- { 245, 3 },
- { 246, 0 },
- { 246, 2 },
+ { 148, 1 },
+ { 148, 4 },
+ { 246, 8 },
{ 247, 1 },
{ 247, 3 },
- { 248, 1 },
- { 249, 0 },
- { 249, 4 },
- { 249, 2 },
+ { 248, 0 },
+ { 248, 2 },
+ { 249, 1 },
+ { 249, 3 },
+ { 250, 1 },
+ { 251, 0 },
+ { 251, 4 },
+ { 251, 2 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -112225,17 +116434,17 @@ static void yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy392);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
break;
case 13: /* transtype ::= */
-{yygotominor.yy392 = TK_DEFERRED;}
+{yygotominor.yy4 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
- case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
- case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
-{yygotominor.yy392 = yymsp[0].major;}
+ case 117: /* multiselect_op ::= UNION */ yytestcase(yyruleno==117);
+ case 119: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==119);
+{yygotominor.yy4 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
@@ -112261,7 +116470,7 @@ static void yy_reduce(
break;
case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy392,0,0,yymsp[-2].minor.yy392);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
}
break;
case 27: /* createkw ::= CREATE */
@@ -112272,697 +116481,706 @@ static void yy_reduce(
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
- case 69: /* autoinc ::= */ yytestcase(yyruleno==69);
- case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
- case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
- case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
- case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
- case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
- case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
- case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
-{yygotominor.yy392 = 0;}
+ case 71: /* autoinc ::= */ yytestcase(yyruleno==71);
+ case 84: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==84);
+ case 86: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==86);
+ case 88: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==88);
+ case 100: /* defer_subclause_opt ::= */ yytestcase(yyruleno==100);
+ case 111: /* ifexists ::= */ yytestcase(yyruleno==111);
+ case 223: /* between_op ::= BETWEEN */ yytestcase(yyruleno==223);
+ case 226: /* in_op ::= IN */ yytestcase(yyruleno==226);
+{yygotominor.yy4 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
- case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
- case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
- case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
- case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
- case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
-{yygotominor.yy392 = 1;}
+ case 72: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==72);
+ case 87: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==87);
+ case 110: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==110);
+ case 224: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==224);
+ case 227: /* in_op ::= NOT IN */ yytestcase(yyruleno==227);
+{yygotominor.yy4 = 1;}
break;
- case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
+ case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy210,0);
}
break;
case 33: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy159);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+}
+ break;
+ case 34: /* table_options ::= */
+{yygotominor.yy210 = 0;}
+ break;
+ case 35: /* table_options ::= WITHOUT nm */
+{
+ if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
+ yygotominor.yy210 = TF_WithoutRowid;
+ }else{
+ yygotominor.yy210 = 0;
+ sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
+ }
}
break;
- case 36: /* column ::= columnid type carglist */
+ case 38: /* column ::= columnid type carglist */
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
- case 37: /* columnid ::= nm */
+ case 39: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
pParse->constraintName.n = 0;
}
break;
- case 38: /* id ::= ID */
- case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
- case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
- case 41: /* nm ::= id */ yytestcase(yyruleno==41);
- case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
- case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
- case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
- case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
- case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
- case 128: /* as ::= ids */ yytestcase(yyruleno==128);
- case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
- case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
- case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250);
- case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259);
- case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260);
- case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261);
- case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262);
- case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263);
- case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264);
- case 265: /* plus_num ::= number */ yytestcase(yyruleno==265);
- case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
- case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
- case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
+ case 40: /* id ::= ID */
+ case 41: /* id ::= INDEXED */ yytestcase(yyruleno==41);
+ case 42: /* ids ::= ID|STRING */ yytestcase(yyruleno==42);
+ case 43: /* nm ::= id */ yytestcase(yyruleno==43);
+ case 44: /* nm ::= STRING */ yytestcase(yyruleno==44);
+ case 45: /* nm ::= JOIN_KW */ yytestcase(yyruleno==45);
+ case 48: /* typetoken ::= typename */ yytestcase(yyruleno==48);
+ case 51: /* typename ::= ids */ yytestcase(yyruleno==51);
+ case 129: /* as ::= AS nm */ yytestcase(yyruleno==129);
+ case 130: /* as ::= ids */ yytestcase(yyruleno==130);
+ case 140: /* dbnm ::= DOT nm */ yytestcase(yyruleno==140);
+ case 149: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==149);
+ case 252: /* collate ::= COLLATE ids */ yytestcase(yyruleno==252);
+ case 261: /* nmnum ::= plus_num */ yytestcase(yyruleno==261);
+ case 262: /* nmnum ::= nm */ yytestcase(yyruleno==262);
+ case 263: /* nmnum ::= ON */ yytestcase(yyruleno==263);
+ case 264: /* nmnum ::= DELETE */ yytestcase(yyruleno==264);
+ case 265: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==265);
+ case 266: /* plus_num ::= PLUS number */ yytestcase(yyruleno==266);
+ case 267: /* plus_num ::= number */ yytestcase(yyruleno==267);
+ case 268: /* minus_num ::= MINUS number */ yytestcase(yyruleno==268);
+ case 269: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==269);
+ case 285: /* trnm ::= nm */ yytestcase(yyruleno==285);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
- case 45: /* type ::= typetoken */
+ case 47: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
- case 47: /* typetoken ::= typename LP signed RP */
+ case 49: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
- case 48: /* typetoken ::= typename LP signed COMMA signed RP */
+ case 50: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
- case 50: /* typename ::= typename ids */
+ case 52: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
- case 55: /* ccons ::= CONSTRAINT nm */
- case 93: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
+ case 57: /* ccons ::= CONSTRAINT nm */
+ case 95: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==95);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 56: /* ccons ::= DEFAULT term */
- case 58: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==58);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
+ case 58: /* ccons ::= DEFAULT term */
+ case 60: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==60);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);}
break;
- case 57: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
+ case 59: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);}
break;
- case 59: /* ccons ::= DEFAULT MINUS term */
+ case 61: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy342.zEnd;
+ v.zEnd = yymsp[0].minor.yy118.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 60: /* ccons ::= DEFAULT id */
+ case 62: /* ccons ::= DEFAULT id */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 62: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
+ case 64: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
break;
- case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
+ case 65: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
break;
- case 64: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
+ case 66: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);}
break;
- case 65: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
+ case 67: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);}
break;
- case 66: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
+ case 68: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
break;
- case 67: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
+ case 69: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
break;
- case 68: /* ccons ::= COLLATE ids */
+ case 70: /* ccons ::= COLLATE ids */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 71: /* refargs ::= */
-{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 73: /* refargs ::= */
+{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 72: /* refargs ::= refargs refarg */
-{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
+ case 74: /* refargs ::= refargs refarg */
+{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
break;
- case 73: /* refarg ::= MATCH nm */
- case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
-{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
+ case 75: /* refarg ::= MATCH nm */
+ case 76: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==76);
+{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; }
break;
- case 75: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
+ case 77: /* refarg ::= ON DELETE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; }
break;
- case 76: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
+ case 78: /* refarg ::= ON UPDATE refact */
+{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; }
break;
- case 77: /* refact ::= SET NULL */
-{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 79: /* refact ::= SET NULL */
+{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 78: /* refact ::= SET DEFAULT */
-{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 80: /* refact ::= SET DEFAULT */
+{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 79: /* refact ::= CASCADE */
-{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 81: /* refact ::= CASCADE */
+{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 80: /* refact ::= RESTRICT */
-{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 82: /* refact ::= RESTRICT */
+{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 81: /* refact ::= NO ACTION */
-{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
+ case 83: /* refact ::= NO ACTION */
+{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */}
break;
- case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
- case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
- case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
-{yygotominor.yy392 = yymsp[0].minor.yy392;}
+ case 85: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 101: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==101);
+ case 103: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==103);
+ case 106: /* resolvetype ::= raisetype */ yytestcase(yyruleno==106);
+{yygotominor.yy4 = yymsp[0].minor.yy4;}
break;
- case 87: /* conslist_opt ::= */
+ case 89: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
- case 88: /* conslist_opt ::= COMMA conslist */
+ case 90: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
- case 91: /* tconscomma ::= COMMA */
+ case 93: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
+ case 96: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
break;
- case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
+ case 97: /* tcons ::= UNIQUE LP idxlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);}
break;
- case 96: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
+ case 98: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);}
break;
- case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+ case 99: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
}
break;
- case 100: /* onconf ::= */
-{yygotominor.yy392 = OE_Default;}
+ case 102: /* onconf ::= */
+{yygotominor.yy4 = OE_Default;}
break;
- case 102: /* orconf ::= */
-{yygotominor.yy258 = OE_Default;}
+ case 104: /* orconf ::= */
+{yygotominor.yy210 = OE_Default;}
break;
- case 103: /* orconf ::= OR resolvetype */
-{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
+ case 105: /* orconf ::= OR resolvetype */
+{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;}
break;
- case 105: /* resolvetype ::= IGNORE */
-{yygotominor.yy392 = OE_Ignore;}
+ case 107: /* resolvetype ::= IGNORE */
+{yygotominor.yy4 = OE_Ignore;}
break;
- case 106: /* resolvetype ::= REPLACE */
-{yygotominor.yy392 = OE_Replace;}
+ case 108: /* resolvetype ::= REPLACE */
+{yygotominor.yy4 = OE_Replace;}
break;
- case 107: /* cmd ::= DROP TABLE ifexists fullname */
+ case 109: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
}
break;
- case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+ case 112: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
+ sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4);
}
break;
- case 111: /* cmd ::= DROP VIEW ifexists fullname */
+ case 113: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
}
break;
- case 112: /* cmd ::= select */
+ case 114: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
+ sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
- sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159);
+ sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy387);
sqlite3ExplainFinish(pParse->pVdbe);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
- case 113: /* select ::= oneselect */
-{yygotominor.yy159 = yymsp[0].minor.yy159;}
+ case 115: /* select ::= oneselect */
+{yygotominor.yy387 = yymsp[0].minor.yy387;}
break;
- case 114: /* select ::= select multiselect_op oneselect */
+ case 116: /* select ::= select multiselect_op oneselect */
{
- if( yymsp[0].minor.yy159 ){
- yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
- yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
+ if( yymsp[0].minor.yy387 ){
+ yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4;
+ yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387;
+ if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387);
}
- yygotominor.yy159 = yymsp[0].minor.yy159;
+ yygotominor.yy387 = yymsp[0].minor.yy387;
}
break;
- case 116: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy392 = TK_ALL;}
+ case 118: /* multiselect_op ::= UNION ALL */
+{yygotominor.yy4 = TK_ALL;}
break;
- case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 120: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy305,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
+ yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy177,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset);
}
break;
- case 119: /* distinct ::= DISTINCT */
-{yygotominor.yy305 = SF_Distinct;}
+ case 121: /* distinct ::= DISTINCT */
+{yygotominor.yy177 = SF_Distinct;}
break;
- case 120: /* distinct ::= ALL */
- case 121: /* distinct ::= */ yytestcase(yyruleno==121);
-{yygotominor.yy305 = 0;}
+ case 122: /* distinct ::= ALL */
+ case 123: /* distinct ::= */ yytestcase(yyruleno==123);
+{yygotominor.yy177 = 0;}
break;
- case 122: /* sclp ::= selcollist COMMA */
- case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
-{yygotominor.yy442 = yymsp[-1].minor.yy442;}
+ case 124: /* sclp ::= selcollist COMMA */
+ case 248: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==248);
+{yygotominor.yy322 = yymsp[-1].minor.yy322;}
break;
- case 123: /* sclp ::= */
- case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
- case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
- case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
- case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245);
-{yygotominor.yy442 = 0;}
+ case 125: /* sclp ::= */
+ case 153: /* orderby_opt ::= */ yytestcase(yyruleno==153);
+ case 160: /* groupby_opt ::= */ yytestcase(yyruleno==160);
+ case 241: /* exprlist ::= */ yytestcase(yyruleno==241);
+ case 247: /* idxlist_opt ::= */ yytestcase(yyruleno==247);
+{yygotominor.yy322 = 0;}
break;
- case 124: /* selcollist ::= sclp expr as */
+ case 126: /* selcollist ::= sclp expr as */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118);
}
break;
- case 125: /* selcollist ::= sclp STAR */
+ case 127: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p);
}
break;
- case 126: /* selcollist ::= sclp nm DOT STAR */
+ case 128: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot);
}
break;
- case 129: /* as ::= */
+ case 131: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
- case 130: /* from ::= */
-{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
+ case 132: /* from ::= */
+{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));}
break;
- case 131: /* from ::= FROM seltablist */
+ case 133: /* from ::= FROM seltablist */
{
- yygotominor.yy347 = yymsp[0].minor.yy347;
- sqlite3SrcListShiftJoinType(yygotominor.yy347);
+ yygotominor.yy259 = yymsp[0].minor.yy259;
+ sqlite3SrcListShiftJoinType(yygotominor.yy259);
}
break;
- case 132: /* stl_prefix ::= seltablist joinop */
+ case 134: /* stl_prefix ::= seltablist joinop */
{
- yygotominor.yy347 = yymsp[-1].minor.yy347;
- if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
+ yygotominor.yy259 = yymsp[-1].minor.yy259;
+ if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4;
}
break;
- case 133: /* stl_prefix ::= */
-{yygotominor.yy347 = 0;}
+ case 135: /* stl_prefix ::= */
+{yygotominor.yy259 = 0;}
break;
- case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 136: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0);
}
break;
- case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 137: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
break;
- case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 138: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
- yygotominor.yy347 = yymsp[-4].minor.yy347;
- }else if( yymsp[-4].minor.yy347->nSrc==1 ){
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
- if( yygotominor.yy347 ){
- struct SrcList_item *pNew = &yygotominor.yy347->a[yygotominor.yy347->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy347->a;
+ if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
+ yygotominor.yy259 = yymsp[-4].minor.yy259;
+ }else if( yymsp[-4].minor.yy259->nSrc==1 ){
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ if( yygotominor.yy259 ){
+ struct SrcList_item *pNew = &yygotominor.yy259->a[yygotominor.yy259->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy347);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,SF_NestedFrom,0,0);
- yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0,0);
+ yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
}
break;
- case 137: /* dbnm ::= */
- case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
+ case 139: /* dbnm ::= */
+ case 148: /* indexed_opt ::= */ yytestcase(yyruleno==148);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
- case 139: /* fullname ::= nm dbnm */
-{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+ case 141: /* fullname ::= nm dbnm */
+{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 140: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy392 = JT_INNER; }
+ case 142: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy4 = JT_INNER; }
break;
- case 141: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+ case 143: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
- case 142: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+ case 144: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
- case 143: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+ case 145: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
- case 144: /* on_opt ::= ON expr */
- case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
- case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
- case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
- case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236);
-{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;}
+ case 146: /* on_opt ::= ON expr */
+ case 163: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==163);
+ case 170: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==170);
+ case 236: /* case_else ::= ELSE expr */ yytestcase(yyruleno==236);
+ case 238: /* case_operand ::= expr */ yytestcase(yyruleno==238);
+{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;}
break;
- case 145: /* on_opt ::= */
- case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
- case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
- case 235: /* case_else ::= */ yytestcase(yyruleno==235);
- case 237: /* case_operand ::= */ yytestcase(yyruleno==237);
-{yygotominor.yy122 = 0;}
+ case 147: /* on_opt ::= */
+ case 162: /* having_opt ::= */ yytestcase(yyruleno==162);
+ case 169: /* where_opt ::= */ yytestcase(yyruleno==169);
+ case 237: /* case_else ::= */ yytestcase(yyruleno==237);
+ case 239: /* case_operand ::= */ yytestcase(yyruleno==239);
+{yygotominor.yy314 = 0;}
break;
- case 148: /* indexed_opt ::= NOT INDEXED */
+ case 150: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
- case 149: /* using_opt ::= USING LP inscollist RP */
- case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
-{yygotominor.yy180 = yymsp[-1].minor.yy180;}
+ case 151: /* using_opt ::= USING LP idlist RP */
+ case 182: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==182);
+{yygotominor.yy384 = yymsp[-1].minor.yy384;}
break;
- case 150: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
-{yygotominor.yy180 = 0;}
+ case 152: /* using_opt ::= */
+ case 181: /* inscollist_opt ::= */ yytestcase(yyruleno==181);
+{yygotominor.yy384 = 0;}
break;
- case 152: /* orderby_opt ::= ORDER BY sortlist */
- case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
- case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238);
-{yygotominor.yy442 = yymsp[0].minor.yy442;}
+ case 154: /* orderby_opt ::= ORDER BY sortlist */
+ case 161: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==161);
+ case 240: /* exprlist ::= nexprlist */ yytestcase(yyruleno==240);
+{yygotominor.yy322 = yymsp[0].minor.yy322;}
break;
- case 153: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 155: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy118.pExpr);
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
}
break;
- case 154: /* sortlist ::= expr sortorder */
+ case 156: /* sortlist ::= expr sortorder */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr);
- if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy118.pExpr);
+ if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4;
}
break;
- case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
-{yygotominor.yy392 = SQLITE_SO_ASC;}
+ case 157: /* sortorder ::= ASC */
+ case 159: /* sortorder ::= */ yytestcase(yyruleno==159);
+{yygotominor.yy4 = SQLITE_SO_ASC;}
break;
- case 156: /* sortorder ::= DESC */
-{yygotominor.yy392 = SQLITE_SO_DESC;}
+ case 158: /* sortorder ::= DESC */
+{yygotominor.yy4 = SQLITE_SO_DESC;}
break;
- case 162: /* limit_opt ::= */
-{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
+ case 164: /* limit_opt ::= */
+{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;}
break;
- case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
+ case 165: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;}
break;
- case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
+ case 166: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;}
break;
- case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
+ case 167: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;}
break;
- case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+ case 168: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314);
}
break;
- case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ case 171: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210);
}
break;
- case 170: /* setlist ::= setlist COMMA nm EQ expr */
+ case 172: /* setlist ::= setlist COMMA nm EQ expr */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
}
break;
- case 171: /* setlist ::= nm EQ expr */
+ case 173: /* setlist ::= nm EQ expr */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
}
break;
- case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
+ case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
break;
- case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
+ case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
+{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
break;
- case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);}
+ case 176: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
+{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);}
break;
- case 175: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy258 = yymsp[0].minor.yy258;}
+ case 177: /* insert_cmd ::= INSERT orconf */
+{yygotominor.yy210 = yymsp[0].minor.yy210;}
break;
- case 176: /* insert_cmd ::= REPLACE */
-{yygotominor.yy258 = OE_Replace;}
+ case 178: /* insert_cmd ::= REPLACE */
+{yygotominor.yy210 = OE_Replace;}
break;
- case 177: /* valuelist ::= VALUES LP nexprlist RP */
+ case 179: /* valuelist ::= VALUES LP nexprlist RP */
{
- yygotominor.yy487.pList = yymsp[-1].minor.yy442;
- yygotominor.yy487.pSelect = 0;
+ yygotominor.yy260.pList = yymsp[-1].minor.yy322;
+ yygotominor.yy260.pSelect = 0;
}
break;
- case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
+ case 180: /* valuelist ::= valuelist COMMA LP exprlist RP */
{
- Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0);
- if( yymsp[-4].minor.yy487.pList ){
- yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0);
- yymsp[-4].minor.yy487.pList = 0;
+ Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy322, 0, 0, 0, 0, 0, 0, 0, 0);
+ if( yymsp[-4].minor.yy260.pList ){
+ yymsp[-4].minor.yy260.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy260.pList, 0, 0, 0, 0, 0, 0, 0, 0);
+ yymsp[-4].minor.yy260.pList = 0;
}
- yygotominor.yy487.pList = 0;
- if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){
+ yygotominor.yy260.pList = 0;
+ if( yymsp[-4].minor.yy260.pSelect==0 || pRight==0 ){
sqlite3SelectDelete(pParse->db, pRight);
- sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect);
- yygotominor.yy487.pSelect = 0;
+ sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy260.pSelect);
+ yygotominor.yy260.pSelect = 0;
}else{
pRight->op = TK_ALL;
- pRight->pPrior = yymsp[-4].minor.yy487.pSelect;
+ pRight->pPrior = yymsp[-4].minor.yy260.pSelect;
pRight->selFlags |= SF_Values;
pRight->pPrior->selFlags |= SF_Values;
- yygotominor.yy487.pSelect = pRight;
+ yygotominor.yy260.pSelect = pRight;
}
}
break;
- case 181: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
+ case 183: /* idlist ::= idlist COMMA nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
break;
- case 182: /* inscollist ::= nm */
-{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+ case 184: /* idlist ::= nm */
+{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
- case 183: /* expr ::= term */
-{yygotominor.yy342 = yymsp[0].minor.yy342;}
+ case 185: /* expr ::= term */
+{yygotominor.yy118 = yymsp[0].minor.yy118;}
break;
- case 184: /* expr ::= LP expr RP */
-{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
+ case 186: /* expr ::= LP expr RP */
+{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
- case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
-{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
+ case 187: /* term ::= NULL */
+ case 192: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==192);
+ case 193: /* term ::= STRING */ yytestcase(yyruleno==193);
+{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
- case 186: /* expr ::= id */
- case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
-{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);}
+ case 188: /* expr ::= id */
+ case 189: /* expr ::= JOIN_KW */ yytestcase(yyruleno==189);
+{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
- case 188: /* expr ::= nm DOT nm */
+ case 190: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 189: /* expr ::= nm DOT nm DOT nm */
+ case 191: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 192: /* expr ::= REGISTER */
+ case 194: /* expr ::= REGISTER */
{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = 0;
+ yygotominor.yy118.pExpr = 0;
}else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable);
}
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 193: /* expr ::= VARIABLE */
+ case 195: /* expr ::= VARIABLE */
{
- spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 194: /* expr ::= expr COLLATE ids */
+ case 196: /* expr ::= expr COLLATE ids */
{
- yygotominor.yy342.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 195: /* expr ::= CAST LP expr AS typetoken RP */
+ case 197: /* expr ::= CAST LP expr AS typetoken RP */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 196: /* expr ::= ID LP distinct exprlist RP */
+ case 198: /* expr ::= ID LP distinct exprlist RP */
{
- if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy305 && yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->flags |= EP_Distinct;
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy177 && yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->flags |= EP_Distinct;
}
}
break;
- case 197: /* expr ::= ID LP STAR RP */
+ case 199: /* expr ::= ID LP STAR RP */
{
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 198: /* term ::= CTIME_KW */
+ case 200: /* term ::= CTIME_KW */
{
- /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
- ** treated as functions that return constants */
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->op = TK_CONST_FUNC;
- }
- spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+ spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 199: /* expr ::= expr AND expr */
- case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
- case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
- case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
-{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
+ case 201: /* expr ::= expr AND expr */
+ case 202: /* expr ::= expr OR expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==205);
+ case 206: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==206);
+ case 207: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==207);
+ case 208: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==208);
+{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);}
break;
- case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
+ case 209: /* likeop ::= LIKE_KW */
+ case 211: /* likeop ::= MATCH */ yytestcase(yyruleno==211);
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 0;}
break;
- case 208: /* likeop ::= NOT LIKE_KW */
- case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
-{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;}
+ case 210: /* likeop ::= NOT LIKE_KW */
+ case 212: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==212);
+{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 1;}
break;
- case 211: /* expr ::= expr likeop expr */
+ case 213: /* expr ::= expr likeop expr */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
- if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator);
+ if( yymsp[-1].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
}
break;
- case 212: /* expr ::= expr likeop expr ESCAPE expr */
+ case 214: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
- if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
- if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator);
+ if( yymsp[-3].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
}
break;
- case 213: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
+ case 215: /* expr ::= expr ISNULL|NOTNULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);}
break;
- case 214: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
+ case 216: /* expr ::= expr NOT NULL */
+{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);}
break;
- case 215: /* expr ::= expr IS expr */
+ case 217: /* expr ::= expr IS expr */
{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL);
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL);
}
break;
- case 216: /* expr ::= expr IS NOT expr */
+ case 218: /* expr ::= expr IS NOT expr */
{
- spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL);
+ spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL);
}
break;
- case 217: /* expr ::= NOT expr */
- case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
-{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
+ case 219: /* expr ::= NOT expr */
+ case 220: /* expr ::= BITNOT expr */ yytestcase(yyruleno==220);
+{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 219: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
+ case 221: /* expr ::= MINUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 220: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
+ case 222: /* expr ::= PLUS expr */
+{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
break;
- case 223: /* expr ::= expr between_op expr AND expr */
+ case 225: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
}
break;
- case 226: /* expr ::= expr in_op LP exprlist RP */
+ case 228: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy442==0 ){
+ if( yymsp[-1].minor.yy322==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -112971,224 +117189,225 @@ static void yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy392]);
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]);
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr);
}else{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-1].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy442);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
}
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 227: /* expr ::= LP select RP */
+ case 229: /* expr ::= LP select RP */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 228: /* expr ::= expr in_op LP select RP */
+ case 230: /* expr ::= expr in_op LP select RP */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 229: /* expr ::= expr in_op nm dbnm */
+ case 231: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
- yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart;
- yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
+ if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart;
+ yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
- case 230: /* expr ::= EXISTS LP select RP */
+ case 232: /* expr ::= EXISTS LP select RP */
{
- Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
- p->x.pSelect = yymsp[-1].minor.yy159;
+ p->x.pSelect = yymsp[-1].minor.yy387;
ExprSetProperty(p, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, p);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
}
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 233: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442;
- sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
}
- yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 234: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
}
break;
- case 233: /* case_exprlist ::= WHEN expr THEN expr */
+ case 235: /* case_exprlist ::= WHEN expr THEN expr */
{
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
}
break;
- case 240: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
+ case 242: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);}
break;
- case 241: /* nexprlist ::= expr */
-{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
+ case 243: /* nexprlist ::= expr */
+{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);}
break;
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
+ case 244: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
{
- sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
- &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
+ sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4);
}
break;
- case 243: /* uniqueflag ::= UNIQUE */
- case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
-{yygotominor.yy392 = OE_Abort;}
+ case 245: /* uniqueflag ::= UNIQUE */
+ case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298);
+{yygotominor.yy4 = OE_Abort;}
break;
- case 244: /* uniqueflag ::= */
-{yygotominor.yy392 = OE_None;}
+ case 246: /* uniqueflag ::= */
+{yygotominor.yy4 = OE_None;}
break;
- case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
+ case 249: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p);
+ sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
}
break;
- case 248: /* idxlist ::= nm collate sortorder */
+ case 250: /* idxlist ::= nm collate sortorder */
{
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
- if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
+ yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p);
+ sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
}
break;
- case 249: /* collate ::= */
+ case 251: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
- case 251: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
+ case 253: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
break;
- case 252: /* cmd ::= VACUUM */
- case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253);
+ case 254: /* cmd ::= VACUUM */
+ case 255: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==255);
{sqlite3Vacuum(pParse);}
break;
- case 254: /* cmd ::= PRAGMA nm dbnm */
+ case 256: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 257: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 258: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 259: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 260: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
}
break;
- case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
- case 270: /* trigger_time ::= BEFORE */
- case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
-{ yygotominor.yy392 = TK_BEFORE; }
+ case 272: /* trigger_time ::= BEFORE */
+ case 275: /* trigger_time ::= */ yytestcase(yyruleno==275);
+{ yygotominor.yy4 = TK_BEFORE; }
break;
- case 271: /* trigger_time ::= AFTER */
-{ yygotominor.yy392 = TK_AFTER; }
+ case 273: /* trigger_time ::= AFTER */
+{ yygotominor.yy4 = TK_AFTER; }
break;
- case 272: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy392 = TK_INSTEAD;}
+ case 274: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy4 = TK_INSTEAD;}
break;
- case 274: /* trigger_event ::= DELETE|INSERT */
- case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
-{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
+ case 276: /* trigger_event ::= DELETE|INSERT */
+ case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277);
+{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;}
break;
- case 276: /* trigger_event ::= UPDATE OF inscollist */
-{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
+ case 278: /* trigger_event ::= UPDATE OF idlist */
+{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;}
break;
- case 279: /* when_clause ::= */
- case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
-{ yygotominor.yy122 = 0; }
+ case 281: /* when_clause ::= */
+ case 303: /* key_opt ::= */ yytestcase(yyruleno==303);
+{ yygotominor.yy314 = 0; }
break;
- case 280: /* when_clause ::= WHEN expr */
- case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
-{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
+ case 282: /* when_clause ::= WHEN expr */
+ case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304);
+{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; }
break;
- case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy327!=0 );
- yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
- yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-2].minor.yy327;
+ assert( yymsp[-2].minor.yy203!=0 );
+ yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
+ yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-2].minor.yy203;
}
break;
- case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy327!=0 );
- yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
- yygotominor.yy327 = yymsp[-1].minor.yy327;
+ assert( yymsp[-1].minor.yy203!=0 );
+ yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
+ yygotominor.yy203 = yymsp[-1].minor.yy203;
}
break;
- case 284: /* trnm ::= nm DOT nm */
+ case 286: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -113196,121 +117415,121 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 286: /* tridxby ::= INDEXED BY nm */
+ case 288: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 287: /* tridxby ::= NOT INDEXED */
+ case 289: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); }
+ case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); }
break;
- case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);}
+ case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
+{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-4].minor.yy210);}
break;
- case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
-{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);}
+ case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
+{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);}
break;
- case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
+ case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);}
break;
- case 292: /* trigger_cmd ::= select */
-{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
+ case 294: /* trigger_cmd ::= select */
+{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); }
break;
- case 293: /* expr ::= RAISE LP IGNORE RP */
+ case 295: /* expr ::= RAISE LP IGNORE RP */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy342.pExpr ){
- yygotominor.yy342.pExpr->affinity = OE_Ignore;
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy118.pExpr ){
+ yygotominor.yy118.pExpr->affinity = OE_Ignore;
}
- yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy342.pExpr ) {
- yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
+ yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy118.pExpr ) {
+ yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4;
}
- yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 295: /* raisetype ::= ROLLBACK */
-{yygotominor.yy392 = OE_Rollback;}
+ case 297: /* raisetype ::= ROLLBACK */
+{yygotominor.yy4 = OE_Rollback;}
break;
- case 297: /* raisetype ::= FAIL */
-{yygotominor.yy392 = OE_Fail;}
+ case 299: /* raisetype ::= FAIL */
+{yygotominor.yy4 = OE_Fail;}
break;
- case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 300: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
}
break;
- case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314);
}
break;
- case 300: /* cmd ::= DETACH database_kw_opt expr */
+ case 302: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
+ sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr);
}
break;
- case 305: /* cmd ::= REINDEX */
+ case 307: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 306: /* cmd ::= REINDEX nm dbnm */
+ case 308: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 307: /* cmd ::= ANALYZE */
+ case 309: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 308: /* cmd ::= ANALYZE nm dbnm */
+ case 310: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
}
break;
- case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 311: /* add_column_fullname ::= fullname */
+ case 313: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
}
break;
- case 314: /* cmd ::= create_vtab */
+ case 316: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 315: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 317: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 318: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
}
break;
- case 319: /* vtabarg ::= */
+ case 321: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 321: /* vtabargtoken ::= ANY */
- case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
- case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
+ case 323: /* vtabargtoken ::= ANY */
+ case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324);
+ case 325: /* lp ::= LP */ yytestcase(yyruleno==325);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
default:
@@ -113325,30 +117544,30 @@ static void yy_reduce(
/* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
/* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
- /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
- /* (35) columnlist ::= column */ yytestcase(yyruleno==35);
- /* (44) type ::= */ yytestcase(yyruleno==44);
- /* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
- /* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
- /* (53) carglist ::= carglist ccons */ yytestcase(yyruleno==53);
- /* (54) carglist ::= */ yytestcase(yyruleno==54);
- /* (61) ccons ::= NULL onconf */ yytestcase(yyruleno==61);
- /* (89) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==89);
- /* (90) conslist ::= tcons */ yytestcase(yyruleno==90);
- /* (92) tconscomma ::= */ yytestcase(yyruleno==92);
- /* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
- /* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
- /* (285) tridxby ::= */ yytestcase(yyruleno==285);
- /* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
- /* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
- /* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312);
- /* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313);
- /* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317);
- /* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
- /* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
- /* (324) anylist ::= */ yytestcase(yyruleno==324);
- /* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
- /* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
+ /* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
+ /* (37) columnlist ::= column */ yytestcase(yyruleno==37);
+ /* (46) type ::= */ yytestcase(yyruleno==46);
+ /* (53) signed ::= plus_num */ yytestcase(yyruleno==53);
+ /* (54) signed ::= minus_num */ yytestcase(yyruleno==54);
+ /* (55) carglist ::= carglist ccons */ yytestcase(yyruleno==55);
+ /* (56) carglist ::= */ yytestcase(yyruleno==56);
+ /* (63) ccons ::= NULL onconf */ yytestcase(yyruleno==63);
+ /* (91) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==91);
+ /* (92) conslist ::= tcons */ yytestcase(yyruleno==92);
+ /* (94) tconscomma ::= */ yytestcase(yyruleno==94);
+ /* (279) foreach_clause ::= */ yytestcase(yyruleno==279);
+ /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280);
+ /* (287) tridxby ::= */ yytestcase(yyruleno==287);
+ /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305);
+ /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306);
+ /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314);
+ /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315);
+ /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319);
+ /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320);
+ /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322);
+ /* (326) anylist ::= */ yytestcase(yyruleno==326);
+ /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
+ /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
break;
};
assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
@@ -113687,20 +117906,20 @@ const unsigned char ebcdicToAscii[] = {
** is substantially reduced. This is important for embedded applications
** on platforms with limited memory.
*/
-/* Hash score: 175 */
+/* Hash score: 177 */
static int keywordCode(const char *z, int n){
- /* zText[] encodes 811 bytes of keywords in 541 bytes */
+ /* zText[] encodes 819 bytes of keywords in 545 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
- /* UNIQUERYATTACHAVINGROUPDATEBEGINNERELEASEBETWEENOTNULLIKE */
- /* CASCADELETECASECOLLATECREATECURRENT_DATEDETACHIMMEDIATEJOIN */
- /* SERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHENWHERENAME */
- /* AFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */
- /* CURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAILFROMFULLGLOBYIF */
- /* ISNULLORDERESTRICTOUTERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
+ /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERENAMEBETWEEN */
+ /* OTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
+ /* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */
+ /* WHEREPLACEAFTERESTRICTANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */
+ /* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */
+ /* FROMFULLGLOBYIFISNULLORDERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
/* INITIALLY */
- static const char zText[540] = {
+ static const char zText[544] = {
'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
@@ -113711,76 +117930,77 @@ static int keywordCode(const char *z, int n){
'P','O','I','N','T','E','R','S','E','C','T','R','I','G','G','E','R','E',
'F','E','R','E','N','C','E','S','C','O','N','S','T','R','A','I','N','T',
'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
- 'U','E','R','Y','A','T','T','A','C','H','A','V','I','N','G','R','O','U',
- 'P','D','A','T','E','B','E','G','I','N','N','E','R','E','L','E','A','S',
- 'E','B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C',
- 'A','S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L',
- 'A','T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D',
- 'A','T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E',
- 'J','O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A',
- 'L','Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U',
- 'E','S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W',
- 'H','E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C',
- 'E','A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R',
- 'E','M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M',
- 'M','I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U',
- 'R','R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M',
- 'A','R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T',
- 'D','R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L',
- 'O','B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S',
- 'T','R','I','C','T','O','U','T','E','R','I','G','H','T','R','O','L','L',
- 'B','A','C','K','R','O','W','U','N','I','O','N','U','S','I','N','G','V',
- 'A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L','L','Y',
+ 'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
+ 'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
+ 'T','E','B','E','G','I','N','N','E','R','E','N','A','M','E','B','E','T',
+ 'W','E','E','N','O','T','N','U','L','L','I','K','E','C','A','S','C','A',
+ 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
+ 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
+ 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
+ 'S','E','R','T','M','A','T','C','H','P','L','A','N','A','L','Y','Z','E',
+ 'P','R','A','G','M','A','B','O','R','T','V','A','L','U','E','S','V','I',
+ 'R','T','U','A','L','I','M','I','T','W','H','E','N','W','H','E','R','E',
+ 'P','L','A','C','E','A','F','T','E','R','E','S','T','R','I','C','T','A',
+ 'N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E','M',
+ 'E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M','I',
+ 'T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R','R',
+ 'E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A','R',
+ 'Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D','R',
+ 'O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O','B',
+ 'Y','I','F','I','S','N','U','L','L','O','R','D','E','R','I','G','H','T',
+ 'R','O','L','L','B','A','C','K','R','O','W','U','N','I','O','N','U','S',
+ 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','I','T','I',
+ 'A','L','L','Y',
};
static const unsigned char aHash[127] = {
- 72, 101, 114, 70, 0, 45, 0, 0, 78, 0, 73, 0, 0,
- 42, 12, 74, 15, 0, 113, 81, 50, 108, 0, 19, 0, 0,
- 118, 0, 116, 111, 0, 22, 89, 0, 9, 0, 0, 66, 67,
- 0, 65, 6, 0, 48, 86, 98, 0, 115, 97, 0, 0, 44,
- 0, 99, 24, 0, 17, 0, 119, 49, 23, 0, 5, 106, 25,
- 92, 0, 0, 121, 102, 56, 120, 53, 28, 51, 0, 87, 0,
- 96, 26, 0, 95, 0, 0, 0, 91, 88, 93, 84, 105, 14,
- 39, 104, 0, 77, 0, 18, 85, 107, 32, 0, 117, 76, 109,
- 58, 46, 80, 0, 0, 90, 40, 0, 112, 0, 36, 0, 0,
- 29, 0, 82, 59, 60, 0, 20, 57, 0, 52,
+ 75, 104, 115, 73, 0, 45, 0, 0, 81, 0, 76, 0, 0,
+ 42, 12, 77, 15, 0, 114, 84, 53, 111, 0, 19, 0, 0,
+ 119, 0, 117, 88, 0, 22, 92, 0, 9, 0, 0, 69, 70,
+ 0, 68, 6, 0, 48, 89, 101, 0, 116, 100, 0, 0, 44,
+ 0, 102, 24, 0, 17, 0, 120, 52, 23, 0, 5, 109, 25,
+ 95, 0, 0, 122, 105, 59, 121, 56, 28, 54, 0, 90, 0,
+ 99, 26, 0, 98, 0, 0, 0, 94, 91, 96, 87, 108, 14,
+ 39, 107, 0, 80, 0, 18, 86, 110, 32, 0, 118, 79, 112,
+ 61, 46, 83, 0, 0, 93, 40, 0, 113, 0, 36, 0, 0,
+ 29, 0, 85, 62, 63, 0, 20, 60, 0, 55,
};
- static const unsigned char aNext[121] = {
+ static const unsigned char aNext[122] = {
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 43, 3, 47,
- 0, 0, 0, 0, 30, 0, 54, 0, 38, 0, 0, 0, 1,
- 62, 0, 0, 63, 0, 41, 0, 0, 0, 0, 0, 0, 0,
- 61, 0, 0, 0, 0, 31, 55, 16, 34, 10, 0, 0, 0,
- 0, 0, 0, 0, 11, 68, 75, 0, 8, 0, 100, 94, 0,
- 103, 0, 83, 0, 71, 0, 0, 110, 27, 37, 69, 79, 0,
- 35, 64, 0, 0,
+ 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 0,
+ 43, 3, 47, 0, 0, 0, 0, 30, 0, 57, 0, 38, 0,
+ 0, 0, 1, 65, 0, 0, 66, 0, 41, 0, 0, 0, 0,
+ 0, 0, 49, 64, 0, 0, 0, 51, 31, 0, 16, 34, 10,
+ 0, 0, 0, 0, 0, 0, 0, 11, 71, 78, 0, 8, 0,
+ 103, 97, 0, 106, 0, 58, 0, 74, 50, 27, 37, 72, 82,
+ 0, 35, 67, 0, 0,
};
- static const unsigned char aLen[121] = {
+ static const unsigned char aLen[122] = {
7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
- 4, 6, 2, 3, 9, 4, 2, 6, 5, 6, 6, 5, 6,
- 5, 5, 7, 7, 7, 3, 2, 4, 4, 7, 3, 6, 4,
- 7, 6, 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6,
- 7, 5, 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4,
- 6, 6, 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4,
- 4, 4, 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5,
- 6, 4, 9, 3,
+ 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 5, 7, 6,
+ 6, 5, 6, 5, 5, 6, 7, 7, 3, 2, 4, 4, 7,
+ 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4, 7,
+ 6, 5, 6, 7, 5, 4, 5, 7, 5, 8, 3, 7, 13,
+ 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, 2,
+ 4, 4, 4, 4, 4, 2, 2, 6, 5, 5, 8, 3, 5,
+ 5, 6, 4, 9, 3,
};
- static const unsigned short int aOffset[121] = {
+ static const unsigned short int aOffset[122] = {
0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
- 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197,
- 203, 206, 210, 217, 223, 223, 223, 226, 229, 233, 234, 238, 244,
- 248, 255, 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320,
- 326, 332, 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383,
- 387, 393, 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458,
- 462, 466, 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516,
- 521, 527, 531, 536,
+ 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 188, 192, 199,
+ 204, 209, 212, 218, 221, 225, 231, 237, 237, 237, 240, 243, 247,
+ 248, 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 315, 317,
+ 324, 329, 334, 340, 346, 351, 355, 358, 365, 369, 377, 379, 386,
+ 388, 390, 399, 403, 409, 415, 423, 428, 428, 444, 451, 458, 459,
+ 466, 470, 474, 478, 482, 485, 487, 489, 495, 499, 504, 512, 515,
+ 520, 525, 531, 535, 540,
};
- static const unsigned char aCode[121] = {
+ static const unsigned char aCode[122] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
@@ -113790,22 +118010,22 @@ static int keywordCode(const char *z, int n){
TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT,
TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO,
TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
- TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING,
- TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE,
- TK_BETWEEN, TK_NOTNULL, TK_NOT, TK_NO, TK_NULL,
- TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE,
- TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE,
- TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE,
- TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT,
- TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE,
- TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN,
- TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW,
- TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT,
- TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW,
- TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER,
- TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW,
- TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY,
- TK_ALL,
+ TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_JOIN_KW,
+ TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, TK_UPDATE,
+ TK_BEGIN, TK_JOIN_KW, TK_RENAME, TK_BETWEEN, TK_NOTNULL,
+ TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, TK_CASCADE,
+ TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE,
+ TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT,
+ TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT,
+ TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_WHERE,
+ TK_REPLACE, TK_AFTER, TK_RESTRICT, TK_AND, TK_DEFAULT,
+ TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW,
+ TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW,
+ TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP,
+ TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY,
+ TK_IF, TK_ISNULL, TK_ORDER, TK_JOIN_KW, TK_ROLLBACK,
+ TK_ROW, TK_UNION, TK_USING, TK_VACUUM, TK_VIEW,
+ TK_INITIALLY, TK_ALL,
};
int h, i;
if( n<2 ) return TK_ID;
@@ -113862,79 +118082,80 @@ static int keywordCode(const char *z, int n){
testcase( i==45 ); /* OR */
testcase( i==46 ); /* UNIQUE */
testcase( i==47 ); /* QUERY */
- testcase( i==48 ); /* ATTACH */
- testcase( i==49 ); /* HAVING */
- testcase( i==50 ); /* GROUP */
- testcase( i==51 ); /* UPDATE */
- testcase( i==52 ); /* BEGIN */
- testcase( i==53 ); /* INNER */
- testcase( i==54 ); /* RELEASE */
- testcase( i==55 ); /* BETWEEN */
- testcase( i==56 ); /* NOTNULL */
- testcase( i==57 ); /* NOT */
- testcase( i==58 ); /* NO */
- testcase( i==59 ); /* NULL */
- testcase( i==60 ); /* LIKE */
- testcase( i==61 ); /* CASCADE */
- testcase( i==62 ); /* ASC */
- testcase( i==63 ); /* DELETE */
- testcase( i==64 ); /* CASE */
- testcase( i==65 ); /* COLLATE */
- testcase( i==66 ); /* CREATE */
- testcase( i==67 ); /* CURRENT_DATE */
- testcase( i==68 ); /* DETACH */
- testcase( i==69 ); /* IMMEDIATE */
- testcase( i==70 ); /* JOIN */
- testcase( i==71 ); /* INSERT */
- testcase( i==72 ); /* MATCH */
- testcase( i==73 ); /* PLAN */
- testcase( i==74 ); /* ANALYZE */
- testcase( i==75 ); /* PRAGMA */
- testcase( i==76 ); /* ABORT */
- testcase( i==77 ); /* VALUES */
- testcase( i==78 ); /* VIRTUAL */
- testcase( i==79 ); /* LIMIT */
- testcase( i==80 ); /* WHEN */
- testcase( i==81 ); /* WHERE */
- testcase( i==82 ); /* RENAME */
- testcase( i==83 ); /* AFTER */
- testcase( i==84 ); /* REPLACE */
- testcase( i==85 ); /* AND */
- testcase( i==86 ); /* DEFAULT */
- testcase( i==87 ); /* AUTOINCREMENT */
- testcase( i==88 ); /* TO */
- testcase( i==89 ); /* IN */
- testcase( i==90 ); /* CAST */
- testcase( i==91 ); /* COLUMN */
- testcase( i==92 ); /* COMMIT */
- testcase( i==93 ); /* CONFLICT */
- testcase( i==94 ); /* CROSS */
- testcase( i==95 ); /* CURRENT_TIMESTAMP */
- testcase( i==96 ); /* CURRENT_TIME */
- testcase( i==97 ); /* PRIMARY */
- testcase( i==98 ); /* DEFERRED */
- testcase( i==99 ); /* DISTINCT */
- testcase( i==100 ); /* IS */
- testcase( i==101 ); /* DROP */
- testcase( i==102 ); /* FAIL */
- testcase( i==103 ); /* FROM */
- testcase( i==104 ); /* FULL */
- testcase( i==105 ); /* GLOB */
- testcase( i==106 ); /* BY */
- testcase( i==107 ); /* IF */
- testcase( i==108 ); /* ISNULL */
- testcase( i==109 ); /* ORDER */
- testcase( i==110 ); /* RESTRICT */
- testcase( i==111 ); /* OUTER */
- testcase( i==112 ); /* RIGHT */
- testcase( i==113 ); /* ROLLBACK */
- testcase( i==114 ); /* ROW */
- testcase( i==115 ); /* UNION */
- testcase( i==116 ); /* USING */
- testcase( i==117 ); /* VACUUM */
- testcase( i==118 ); /* VIEW */
- testcase( i==119 ); /* INITIALLY */
- testcase( i==120 ); /* ALL */
+ testcase( i==48 ); /* WITHOUT */
+ testcase( i==49 ); /* OUTER */
+ testcase( i==50 ); /* RELEASE */
+ testcase( i==51 ); /* ATTACH */
+ testcase( i==52 ); /* HAVING */
+ testcase( i==53 ); /* GROUP */
+ testcase( i==54 ); /* UPDATE */
+ testcase( i==55 ); /* BEGIN */
+ testcase( i==56 ); /* INNER */
+ testcase( i==57 ); /* RENAME */
+ testcase( i==58 ); /* BETWEEN */
+ testcase( i==59 ); /* NOTNULL */
+ testcase( i==60 ); /* NOT */
+ testcase( i==61 ); /* NO */
+ testcase( i==62 ); /* NULL */
+ testcase( i==63 ); /* LIKE */
+ testcase( i==64 ); /* CASCADE */
+ testcase( i==65 ); /* ASC */
+ testcase( i==66 ); /* DELETE */
+ testcase( i==67 ); /* CASE */
+ testcase( i==68 ); /* COLLATE */
+ testcase( i==69 ); /* CREATE */
+ testcase( i==70 ); /* CURRENT_DATE */
+ testcase( i==71 ); /* DETACH */
+ testcase( i==72 ); /* IMMEDIATE */
+ testcase( i==73 ); /* JOIN */
+ testcase( i==74 ); /* INSERT */
+ testcase( i==75 ); /* MATCH */
+ testcase( i==76 ); /* PLAN */
+ testcase( i==77 ); /* ANALYZE */
+ testcase( i==78 ); /* PRAGMA */
+ testcase( i==79 ); /* ABORT */
+ testcase( i==80 ); /* VALUES */
+ testcase( i==81 ); /* VIRTUAL */
+ testcase( i==82 ); /* LIMIT */
+ testcase( i==83 ); /* WHEN */
+ testcase( i==84 ); /* WHERE */
+ testcase( i==85 ); /* REPLACE */
+ testcase( i==86 ); /* AFTER */
+ testcase( i==87 ); /* RESTRICT */
+ testcase( i==88 ); /* AND */
+ testcase( i==89 ); /* DEFAULT */
+ testcase( i==90 ); /* AUTOINCREMENT */
+ testcase( i==91 ); /* TO */
+ testcase( i==92 ); /* IN */
+ testcase( i==93 ); /* CAST */
+ testcase( i==94 ); /* COLUMN */
+ testcase( i==95 ); /* COMMIT */
+ testcase( i==96 ); /* CONFLICT */
+ testcase( i==97 ); /* CROSS */
+ testcase( i==98 ); /* CURRENT_TIMESTAMP */
+ testcase( i==99 ); /* CURRENT_TIME */
+ testcase( i==100 ); /* PRIMARY */
+ testcase( i==101 ); /* DEFERRED */
+ testcase( i==102 ); /* DISTINCT */
+ testcase( i==103 ); /* IS */
+ testcase( i==104 ); /* DROP */
+ testcase( i==105 ); /* FAIL */
+ testcase( i==106 ); /* FROM */
+ testcase( i==107 ); /* FULL */
+ testcase( i==108 ); /* GLOB */
+ testcase( i==109 ); /* BY */
+ testcase( i==110 ); /* IF */
+ testcase( i==111 ); /* ISNULL */
+ testcase( i==112 ); /* ORDER */
+ testcase( i==113 ); /* RIGHT */
+ testcase( i==114 ); /* ROLLBACK */
+ testcase( i==115 ); /* ROW */
+ testcase( i==116 ); /* UNION */
+ testcase( i==117 ); /* USING */
+ testcase( i==118 ); /* VACUUM */
+ testcase( i==119 ); /* VIEW */
+ testcase( i==120 ); /* INITIALLY */
+ testcase( i==121 ); /* ALL */
return aCode[i];
}
}
@@ -113943,7 +118164,7 @@ static int keywordCode(const char *z, int n){
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
return keywordCode((char*)z, n);
}
-#define SQLITE_N_KEYWORD 121
+#define SQLITE_N_KEYWORD 122
/************** End of keywordhash.h *****************************************/
/************** Continuing where we left off in tokenize.c *******************/
@@ -114007,7 +118228,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
case '-': {
if( z[1]=='-' ){
- /* IMP: R-50417-27976 -- syntax diagram for comments */
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
@@ -114040,7 +118260,6 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_SLASH;
return 1;
}
- /* IMP: R-50417-27976 -- syntax diagram for comments */
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
@@ -114280,7 +118499,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
- if( db->activeVdbeCnt==0 ){
+ if( db->nVdbeActive==0 ){
db->u1.isInterrupted = 0;
}
pParse->rc = SQLITE_OK;
@@ -114392,7 +118611,6 @@ abort_parse:
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);
- sqlite3DbFree(db, pParse->aAlias);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
@@ -114902,6 +119120,9 @@ SQLITE_API char *sqlite3_data_directory = 0;
SQLITE_API int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
+#ifdef SQLITE_EXTRA_INIT
+ int bRunExtraInit = 0; /* Extra initialization needed */
+#endif
#ifdef SQLITE_OMIT_WSD
rc = sqlite3_wsd_init(4096, 24);
@@ -114999,6 +119220,9 @@ SQLITE_API int sqlite3_initialize(void){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
sqlite3GlobalConfig.isInit = 1;
+#ifdef SQLITE_EXTRA_INIT
+ bRunExtraInit = 1;
+#endif
}
sqlite3GlobalConfig.inProgress = 0;
}
@@ -115039,7 +119263,7 @@ SQLITE_API int sqlite3_initialize(void){
** compile-time option.
*/
#ifdef SQLITE_EXTRA_INIT
- if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
+ if( bRunExtraInit ){
int SQLITE_EXTRA_INIT(const char*);
rc = SQLITE_EXTRA_INIT(0);
}
@@ -115227,8 +119451,8 @@ SQLITE_API int sqlite3_config(int op, ...){
memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
}else{
/* The heap pointer is not NULL, then install one of the
- ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
- ** ENABLE_MEMSYS5 is defined, return an error.
+ ** mem5.c/mem3.c methods. The enclosing #if guarantees at
+ ** least one of these methods is currently enabled.
*/
#ifdef SQLITE_ENABLE_MEMSYS3
sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
@@ -115247,7 +119471,7 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
- /* Record a pointer to the logger funcction and its first argument.
+ /* Record a pointer to the logger function and its first argument.
** The default is NULL. Logging is disabled if the function pointer is
** NULL.
*/
@@ -115294,6 +119518,13 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
+#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
+ case SQLITE_CONFIG_WIN32_HEAPSIZE: {
+ sqlite3GlobalConfig.nHeap = va_arg(ap, int);
+ break;
+ }
+#endif
+
default: {
rc = SQLITE_ERROR;
break;
@@ -115486,7 +119717,7 @@ static int binCollFunc(
/*
** Another built-in collating sequence: NOCASE.
**
-** This collating sequence is intended to be used for "case independant
+** This collating sequence is intended to be used for "case independent
** comparison". SQLite's knowledge of upper and lower case equivalents
** extends only to the 26 characters used in the English language.
**
@@ -115809,7 +120040,6 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
inTrans = 1;
}
sqlite3BtreeRollback(p, tripCode);
- db->aDb[i].inTrans = 0;
}
}
sqlite3VtabRollback(db);
@@ -115823,6 +120053,8 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
+ db->nDeferredImmCons = 0;
+ db->flags &= ~SQLITE_DeferFKs;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
@@ -115849,6 +120081,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break;
case SQLITE_BUSY: zName = "SQLITE_BUSY"; break;
case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break;
+ case SQLITE_BUSY_SNAPSHOT: zName = "SQLITE_BUSY_SNAPSHOT"; break;
case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break;
case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
@@ -115883,6 +120116,8 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
+ case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
+ case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
@@ -115891,6 +120126,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break;
+ case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break;
case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break;
case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break;
case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break;
@@ -115909,6 +120145,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break;
case SQLITE_CONSTRAINT_FUNCTION:
zName = "SQLITE_CONSTRAINT_FUNCTION"; break;
+ case SQLITE_CONSTRAINT_ROWID: zName = "SQLITE_CONSTRAINT_ROWID"; break;
case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break;
case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break;
case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break;
@@ -115922,6 +120159,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_NOTICE_RECOVER_ROLLBACK:
zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
case SQLITE_WARNING: zName = "SQLITE_WARNING"; break;
+ case SQLITE_WARNING_AUTOINDEX: zName = "SQLITE_WARNING_AUTOINDEX"; break;
case SQLITE_DONE: zName = "SQLITE_DONE"; break;
}
}
@@ -116082,7 +120320,7 @@ SQLITE_API void sqlite3_progress_handler(
sqlite3_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
- db->nProgressOps = nOps;
+ db->nProgressOps = (unsigned)nOps;
db->pProgressArg = pArg;
}else{
db->xProgress = 0;
@@ -116179,8 +120417,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
** operation to continue but invalidate all precompiled statements.
*/
p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
- if( p && p->iPrefEnc==enc && p->nArg==nArg ){
- if( db->activeVdbeCnt ){
+ if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
+ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify user-function due to active statements");
assert( !db->mallocFailed );
@@ -116204,7 +120442,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
pDestructor->nRef++;
}
p->pDestructor = pDestructor;
- p->flags = 0;
+ p->funcFlags &= SQLITE_FUNC_ENCMASK;
p->xFunc = xFunc;
p->xStep = xStep;
p->xFinalize = xFinal;
@@ -116724,6 +120962,32 @@ SQLITE_API const char *sqlite3_errstr(int rc){
}
/*
+** Invalidate all cached KeyInfo objects for database connection "db"
+*/
+static void invalidateCachedKeyInfo(sqlite3 *db){
+ Db *pDb; /* A single database */
+ int iDb; /* The database index number */
+ HashElem *k; /* For looping over tables in pDb */
+ Table *pTab; /* A table in the database */
+ Index *pIdx; /* Each index */
+
+ for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
+ if( pDb->pBt==0 ) continue;
+ sqlite3BtreeEnter(pDb->pBt);
+ for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){
+ sqlite3KeyInfoUnref(pIdx->pKeyInfo);
+ pIdx->pKeyInfo = 0;
+ }
+ }
+ }
+ sqlite3BtreeLeave(pDb->pBt);
+ }
+}
+
+/*
** Create a new collating function for database "db". The name is zName
** and the encoding is enc.
*/
@@ -116761,12 +121025,13 @@ static int createCollation(
*/
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
- if( db->activeVdbeCnt ){
+ if( db->nVdbeActive ){
sqlite3Error(db, SQLITE_BUSY,
"unable to delete/modify collation sequence due to active statements");
return SQLITE_BUSY;
}
sqlite3ExpirePreparedStatements(db);
+ invalidateCachedKeyInfo(db);
/* If collation sequence pColl was created directly by a call to
** sqlite3_create_collation, and not generated by synthCollSeq(),
@@ -116959,20 +121224,20 @@ SQLITE_PRIVATE int sqlite3ParseUri(
zFile = sqlite3_malloc(nByte);
if( !zFile ) return SQLITE_NOMEM;
+ iIn = 5;
+#ifndef SQLITE_ALLOW_URI_AUTHORITY
/* Discard the scheme and authority segments of the URI. */
if( zUri[5]=='/' && zUri[6]=='/' ){
iIn = 7;
while( zUri[iIn] && zUri[iIn]!='/' ) iIn++;
-
if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){
*pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s",
iIn-7, &zUri[7]);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
- }else{
- iIn = 5;
}
+#endif
/* Copy the filename and any query parameters into the zFile buffer.
** Decode %HH escape codes along the way.
@@ -117236,7 +121501,10 @@ static int openDatabase(
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
- db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger
+ db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill
+#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
+ | SQLITE_AutoIndex
+#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
@@ -117576,8 +121844,6 @@ SQLITE_API int sqlite3_global_recover(void){
** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
-**
-******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
return db->autoCommit;
@@ -118033,6 +122299,19 @@ SQLITE_API int sqlite3_test_control(int op, ...){
}
#endif
+ /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
+ **
+ ** Set or clear a flag that indicates that the database file is always well-
+ ** formed and never corrupt. This flag is clear by default, indicating that
+ ** database files might have arbitrary corruption. Setting the flag during
+ ** testing causes certain assert() statements in the code to be activated
+ ** that demonstrat invariants on well-formed database files.
+ */
+ case SQLITE_TESTCTRL_NEVER_CORRUPT: {
+ sqlite3Config.neverCorrupt = va_arg(ap, int);
+ break;
+ }
+
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
@@ -118780,7 +123059,7 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){
/* If not building as part of the core, include sqlite3ext.h. */
#ifndef SQLITE_CORE
-SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
+SQLITE_EXTENSION_INIT3
#endif
/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
@@ -119067,6 +123346,18 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
/************** Continuing where we left off in fts3Int.h ********************/
/*
+** This constant determines the maximum depth of an FTS expression tree
+** that the library will create and use. FTS uses recursion to perform
+** various operations on the query tree, so the disadvantage of a large
+** limit is that it may allow very large queries to use large amounts
+** of stack space (perhaps causing a stack overflow).
+*/
+#ifndef SQLITE_FTS3_MAX_EXPR_DEPTH
+# define SQLITE_FTS3_MAX_EXPR_DEPTH 12
+#endif
+
+
+/*
** This constant controls how often segments are merged. Once there are
** FTS3_MERGE_COUNT segments of level N, they are merged into a single
** segment of level N+1.
@@ -119221,6 +123512,7 @@ struct Fts3Table {
const char *zName; /* virtual table name */
int nColumn; /* number of named columns in virtual table */
char **azColumn; /* column names. malloced */
+ u8 *abNotindexed; /* True for 'notindexed' columns */
sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
char *zContentTbl; /* content=xxx option, or NULL */
char *zLanguageid; /* languageid=xxx option, or NULL */
@@ -119281,6 +123573,12 @@ struct Fts3Table {
int inTransaction; /* True after xBegin but before xCommit/xRollback */
int mxSavepoint; /* Largest valid xSavepoint integer */
#endif
+
+#ifdef SQLITE_TEST
+ /* True to disable the incremental doclist optimization. This is controled
+ ** by special insert command 'test-no-incr-doclist'. */
+ int bNoIncrDoclist;
+#endif
};
/*
@@ -119306,7 +123604,8 @@ struct Fts3Cursor {
int eEvalmode; /* An FTS3_EVAL_XX constant */
int nRowAvg; /* Average size of database rows, in pages */
sqlite3_int64 nDoc; /* Documents in table */
-
+ i64 iMinDocid; /* Minimum docid to return */
+ i64 iMaxDocid; /* Maximum docid to return */
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
u32 *aMatchinfo; /* Information about most recent match */
int nMatchinfo; /* Number of elements in aMatchinfo[] */
@@ -119336,6 +123635,15 @@ struct Fts3Cursor {
#define FTS3_DOCID_SEARCH 1 /* Lookup by rowid on %_content table */
#define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */
+/*
+** The lower 16-bits of the sqlite3_index_info.idxNum value set by
+** the xBestIndex() method contains the Fts3Cursor.eSearch value described
+** above. The upper 16-bits contain a combination of the following
+** bits, used to describe extra constraints on full-text searches.
+*/
+#define FTS3_HAVE_LANGID 0x00010000 /* languageid=? */
+#define FTS3_HAVE_DOCID_GE 0x00020000 /* docid>=? */
+#define FTS3_HAVE_DOCID_LE 0x00040000 /* docid<=? */
struct Fts3Doclist {
char *aAll; /* Array containing doclist (or NULL) */
@@ -119448,7 +123756,6 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderPending(
Fts3Table*,int,const char*,int,int,Fts3SegReader**);
SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *);
SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **);
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *);
SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
@@ -119523,6 +123830,10 @@ struct Fts3MultiSegReader {
SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
+#define fts3GetVarint32(p, piVal) ( \
+ (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
+)
+
/* fts3.c */
SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64);
SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
@@ -119630,21 +123941,37 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
return (int) (q - (unsigned char *)p);
}
+#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
+ v = (v & mask1) | ( (*ptr++) << shift ); \
+ if( (v & mask2)==0 ){ var = v; return ret; }
+#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
+ v = (*ptr++); \
+ if( (v & mask2)==0 ){ var = v; return ret; }
+
/*
** Read a 64-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
- const unsigned char *q = (const unsigned char *) p;
- sqlite_uint64 x = 0, y = 1;
- while( (*q&0x80)==0x80 && q-(unsigned char *)p<FTS3_VARINT_MAX ){
- x += y * (*q++ & 0x7f);
- y <<= 7;
- }
- x += y * (*q++);
- *v = (sqlite_int64) x;
- return (int) (q - (unsigned char *)p);
+ const char *pStart = p;
+ u32 a;
+ u64 b;
+ int shift;
+
+ GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1);
+ GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2);
+ GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3);
+ GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4);
+ b = (a & 0x0FFFFFFF );
+
+ for(shift=28; shift<=63; shift+=7){
+ u64 c = *p++;
+ b += (c&0x7F) << shift;
+ if( (c & 0x80)==0 ) break;
+ }
+ *v = b;
+ return (int)(p - pStart);
}
/*
@@ -119652,10 +123979,21 @@ SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
** 32-bit integer before it is returned.
*/
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){
- sqlite_int64 i;
- int ret = sqlite3Fts3GetVarint(p, &i);
- *pi = (int) i;
- return ret;
+ u32 a;
+
+#ifndef fts3GetVarint32
+ GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1);
+#else
+ a = (*p++);
+ assert( a & 0x80 );
+#endif
+
+ GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *pi, 2);
+ GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *pi, 3);
+ GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
+ a = (a & 0x0FFFFFFF );
+ *pi = (int)(a | ((u32)(*p & 0x0F) << 28));
+ return 5;
}
/*
@@ -120381,6 +124719,8 @@ static int fts3InitVtab(
char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
char *zContent = 0; /* content=? parameter (or NULL) */
char *zLanguageid = 0; /* languageid=? parameter (or NULL) */
+ char **azNotindexed = 0; /* The set of notindexed= columns */
+ int nNotindexed = 0; /* Size of azNotindexed[] array */
assert( strlen(argv[0])==4 );
assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
@@ -120390,9 +124730,19 @@ static int fts3InitVtab(
nDb = (int)strlen(argv[1]) + 1;
nName = (int)strlen(argv[2]) + 1;
- aCol = (const char **)sqlite3_malloc(sizeof(const char *) * (argc-2) );
- if( !aCol ) return SQLITE_NOMEM;
- memset((void *)aCol, 0, sizeof(const char *) * (argc-2));
+ nByte = sizeof(const char *) * (argc-2);
+ aCol = (const char **)sqlite3_malloc(nByte);
+ if( aCol ){
+ memset((void*)aCol, 0, nByte);
+ azNotindexed = (char **)sqlite3_malloc(nByte);
+ }
+ if( azNotindexed ){
+ memset(azNotindexed, 0, nByte);
+ }
+ if( !aCol || !azNotindexed ){
+ rc = SQLITE_NOMEM;
+ goto fts3_init_out;
+ }
/* Loop through all of the arguments passed by the user to the FTS3/4
** module (i.e. all the column names and special arguments). This loop
@@ -120431,7 +124781,8 @@ static int fts3InitVtab(
{ "uncompress", 10 }, /* 3 -> UNCOMPRESS */
{ "order", 5 }, /* 4 -> ORDER */
{ "content", 7 }, /* 5 -> CONTENT */
- { "languageid", 10 } /* 6 -> LANGUAGEID */
+ { "languageid", 10 }, /* 6 -> LANGUAGEID */
+ { "notindexed", 10 } /* 7 -> NOTINDEXED */
};
int iOpt;
@@ -120497,6 +124848,11 @@ static int fts3InitVtab(
zLanguageid = zVal;
zVal = 0;
break;
+
+ case 7: /* NOTINDEXED */
+ azNotindexed[nNotindexed++] = zVal;
+ zVal = 0;
+ break;
}
}
sqlite3_free(zVal);
@@ -120568,6 +124924,7 @@ static int fts3InitVtab(
nByte = sizeof(Fts3Table) + /* Fts3Table */
nCol * sizeof(char *) + /* azColumn */
nIndex * sizeof(struct Fts3Index) + /* aIndex */
+ nCol * sizeof(u8) + /* abNotindexed */
nName + /* zName */
nDb + /* zDb */
nString; /* Space for azColumn strings */
@@ -120601,9 +124958,10 @@ static int fts3InitVtab(
for(i=0; i<nIndex; i++){
fts3HashInit(&p->aIndex[i].hPending, FTS3_HASH_STRING, 1);
}
+ p->abNotindexed = (u8 *)&p->aIndex[nIndex];
/* Fill in the zName and zDb fields of the vtab structure. */
- zCsr = (char *)&p->aIndex[nIndex];
+ zCsr = (char *)&p->abNotindexed[nCol];
p->zName = zCsr;
memcpy(zCsr, argv[2], nName);
zCsr += nName;
@@ -120624,7 +124982,26 @@ static int fts3InitVtab(
assert( zCsr <= &((char *)p)[nByte] );
}
- if( (zCompress==0)!=(zUncompress==0) ){
+ /* Fill in the abNotindexed array */
+ for(iCol=0; iCol<nCol; iCol++){
+ int n = (int)strlen(p->azColumn[iCol]);
+ for(i=0; i<nNotindexed; i++){
+ char *zNot = azNotindexed[i];
+ if( zNot && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){
+ p->abNotindexed[iCol] = 1;
+ sqlite3_free(zNot);
+ azNotindexed[i] = 0;
+ }
+ }
+ }
+ for(i=0; i<nNotindexed; i++){
+ if( azNotindexed[i] ){
+ *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
+ rc = SQLITE_ERROR;
+ }
+ }
+
+ if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
rc = SQLITE_ERROR;
*pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
@@ -120665,7 +125042,9 @@ fts3_init_out:
sqlite3_free(zUncompress);
sqlite3_free(zContent);
sqlite3_free(zLanguageid);
+ for(i=0; i<nNotindexed; i++) sqlite3_free(azNotindexed[i]);
sqlite3_free((void *)aCol);
+ sqlite3_free((void *)azNotindexed);
if( rc!=SQLITE_OK ){
if( p ){
fts3DisconnectMethod((sqlite3_vtab *)p);
@@ -120716,23 +125095,27 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
Fts3Table *p = (Fts3Table *)pVTab;
int i; /* Iterator variable */
int iCons = -1; /* Index of constraint to use */
+
int iLangidCons = -1; /* Index of langid=x constraint, if present */
+ int iDocidGe = -1; /* Index of docid>=x constraint, if present */
+ int iDocidLe = -1; /* Index of docid<=x constraint, if present */
+ int iIdx;
/* By default use a full table scan. This is an expensive option,
** so search through the constraints to see if a more efficient
** strategy is possible.
*/
pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
- pInfo->estimatedCost = 500000;
+ pInfo->estimatedCost = 5000000;
for(i=0; i<pInfo->nConstraint; i++){
+ int bDocid; /* True if this constraint is on docid */
struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
if( pCons->usable==0 ) continue;
+ bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1);
+
/* A direct lookup on the rowid or docid column. Assign a cost of 1.0. */
- if( iCons<0
- && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ
- && (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1 )
- ){
+ if( iCons<0 && pCons->op==SQLITE_INDEX_CONSTRAINT_EQ && bDocid ){
pInfo->idxNum = FTS3_DOCID_SEARCH;
pInfo->estimatedCost = 1.0;
iCons = i;
@@ -120761,14 +125144,38 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
){
iLangidCons = i;
}
+
+ if( bDocid ){
+ switch( pCons->op ){
+ case SQLITE_INDEX_CONSTRAINT_GE:
+ case SQLITE_INDEX_CONSTRAINT_GT:
+ iDocidGe = i;
+ break;
+
+ case SQLITE_INDEX_CONSTRAINT_LE:
+ case SQLITE_INDEX_CONSTRAINT_LT:
+ iDocidLe = i;
+ break;
+ }
+ }
}
+ iIdx = 1;
if( iCons>=0 ){
- pInfo->aConstraintUsage[iCons].argvIndex = 1;
+ pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
pInfo->aConstraintUsage[iCons].omit = 1;
}
if( iLangidCons>=0 ){
- pInfo->aConstraintUsage[iLangidCons].argvIndex = 2;
+ pInfo->idxNum |= FTS3_HAVE_LANGID;
+ pInfo->aConstraintUsage[iLangidCons].argvIndex = iIdx++;
+ }
+ if( iDocidGe>=0 ){
+ pInfo->idxNum |= FTS3_HAVE_DOCID_GE;
+ pInfo->aConstraintUsage[iDocidGe].argvIndex = iIdx++;
+ }
+ if( iDocidLe>=0 ){
+ pInfo->idxNum |= FTS3_HAVE_DOCID_LE;
+ pInfo->aConstraintUsage[iDocidLe].argvIndex = iIdx++;
}
/* Regardless of the strategy selected, FTS can deliver rows in rowid (or
@@ -120946,10 +125353,10 @@ static int fts3ScanInteriorNode(
/* Load the next term on the node into zBuffer. Use realloc() to expand
** the size of zBuffer if required. */
if( !isFirstTerm ){
- zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix);
+ zCsr += fts3GetVarint32(zCsr, &nPrefix);
}
isFirstTerm = 0;
- zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
+ zCsr += fts3GetVarint32(zCsr, &nSuffix);
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
@@ -121037,7 +125444,7 @@ static int fts3SelectLeaf(
assert( piLeaf || piLeaf2 );
- sqlite3Fts3GetVarint32(zNode, &iHeight);
+ fts3GetVarint32(zNode, &iHeight);
rc = fts3ScanInteriorNode(zTerm, nTerm, zNode, nNode, piLeaf, piLeaf2);
assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
@@ -121239,11 +125646,11 @@ static void fts3PoslistMerge(
int iCol1; /* The current column index in pp1 */
int iCol2; /* The current column index in pp2 */
- if( *p1==POS_COLUMN ) sqlite3Fts3GetVarint32(&p1[1], &iCol1);
+ if( *p1==POS_COLUMN ) fts3GetVarint32(&p1[1], &iCol1);
else if( *p1==POS_END ) iCol1 = POSITION_LIST_END;
else iCol1 = 0;
- if( *p2==POS_COLUMN ) sqlite3Fts3GetVarint32(&p2[1], &iCol2);
+ if( *p2==POS_COLUMN ) fts3GetVarint32(&p2[1], &iCol2);
else if( *p2==POS_END ) iCol2 = POSITION_LIST_END;
else iCol2 = 0;
@@ -121336,11 +125743,11 @@ static int fts3PoslistPhraseMerge(
assert( p!=0 && *p1!=0 && *p2!=0 );
if( *p1==POS_COLUMN ){
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
}
if( *p2==POS_COLUMN ){
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
while( 1 ){
@@ -121390,9 +125797,9 @@ static int fts3PoslistPhraseMerge(
if( 0==*p1 || 0==*p2 ) break;
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
/* Advance pointer p1 or p2 (whichever corresponds to the smaller of
@@ -121404,12 +125811,12 @@ static int fts3PoslistPhraseMerge(
fts3ColumnlistCopy(0, &p1);
if( 0==*p1 ) break;
p1++;
- p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
+ p1 += fts3GetVarint32(p1, &iCol1);
}else{
fts3ColumnlistCopy(0, &p2);
if( 0==*p2 ) break;
p2++;
- p2 += sqlite3Fts3GetVarint32(p2, &iCol2);
+ p2 += fts3GetVarint32(p2, &iCol2);
}
}
@@ -122216,6 +126623,33 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
}
/*
+** The following are copied from sqliteInt.h.
+**
+** Constants for the largest and smallest possible 64-bit signed integers.
+** These macros are designed to work correctly on both 32-bit and 64-bit
+** compilers.
+*/
+#ifndef SQLITE_AMALGAMATION
+# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
+# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
+#endif
+
+/*
+** If the numeric type of argument pVal is "integer", then return it
+** converted to a 64-bit signed integer. Otherwise, return a copy of
+** the second parameter, iDefault.
+*/
+static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){
+ if( pVal ){
+ int eType = sqlite3_value_numeric_type(pVal);
+ if( eType==SQLITE_INTEGER ){
+ return sqlite3_value_int64(pVal);
+ }
+ }
+ return iDefault;
+}
+
+/*
** This is the xFilter interface for the virtual table. See
** the virtual table xFilter method documentation for additional
** information.
@@ -122240,40 +126674,58 @@ static int fts3FilterMethod(
){
int rc;
char *zSql; /* SQL statement used to access %_content */
+ int eSearch;
Fts3Table *p = (Fts3Table *)pCursor->pVtab;
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
+ sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */
+ sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */
+ sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */
+ sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */
+ int iIdx;
+
UNUSED_PARAMETER(idxStr);
UNUSED_PARAMETER(nVal);
- assert( idxNum>=0 && idxNum<=(FTS3_FULLTEXT_SEARCH+p->nColumn) );
- assert( nVal==0 || nVal==1 || nVal==2 );
- assert( (nVal==0)==(idxNum==FTS3_FULLSCAN_SEARCH) );
+ eSearch = (idxNum & 0x0000FFFF);
+ assert( eSearch>=0 && eSearch<=(FTS3_FULLTEXT_SEARCH+p->nColumn) );
assert( p->pSegments==0 );
+ /* Collect arguments into local variables */
+ iIdx = 0;
+ if( eSearch!=FTS3_FULLSCAN_SEARCH ) pCons = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_LANGID ) pLangid = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_DOCID_GE ) pDocidGe = apVal[iIdx++];
+ if( idxNum & FTS3_HAVE_DOCID_LE ) pDocidLe = apVal[iIdx++];
+ assert( iIdx==nVal );
+
/* In case the cursor has been used before, clear it now. */
sqlite3_finalize(pCsr->pStmt);
sqlite3_free(pCsr->aDoclist);
sqlite3Fts3ExprFree(pCsr->pExpr);
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
+ /* Set the lower and upper bounds on docids to return */
+ pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
+ pCsr->iMaxDocid = fts3DocidRange(pDocidLe, LARGEST_INT64);
+
if( idxStr ){
pCsr->bDesc = (idxStr[0]=='D');
}else{
pCsr->bDesc = p->bDescIdx;
}
- pCsr->eSearch = (i16)idxNum;
+ pCsr->eSearch = (i16)eSearch;
- if( idxNum!=FTS3_DOCID_SEARCH && idxNum!=FTS3_FULLSCAN_SEARCH ){
- int iCol = idxNum-FTS3_FULLTEXT_SEARCH;
- const char *zQuery = (const char *)sqlite3_value_text(apVal[0]);
+ if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){
+ int iCol = eSearch-FTS3_FULLTEXT_SEARCH;
+ const char *zQuery = (const char *)sqlite3_value_text(pCons);
- if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
+ if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){
return SQLITE_NOMEM;
}
pCsr->iLangid = 0;
- if( nVal==2 ) pCsr->iLangid = sqlite3_value_int(apVal[1]);
+ if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid);
assert( p->base.zErrMsg==0 );
rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid,
@@ -122284,11 +126736,7 @@ static int fts3FilterMethod(
return rc;
}
- rc = sqlite3Fts3ReadLock(p);
- if( rc!=SQLITE_OK ) return rc;
-
rc = fts3EvalStart(pCsr);
-
sqlite3Fts3SegmentsClose(p);
if( rc!=SQLITE_OK ) return rc;
pCsr->pNextId = pCsr->aDoclist;
@@ -122300,7 +126748,7 @@ static int fts3FilterMethod(
** full-text query or docid lookup, the statement retrieves a single
** row by docid.
*/
- if( idxNum==FTS3_FULLSCAN_SEARCH ){
+ if( eSearch==FTS3_FULLSCAN_SEARCH ){
zSql = sqlite3_mprintf(
"SELECT %s ORDER BY rowid %s",
p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
@@ -122311,10 +126759,10 @@ static int fts3FilterMethod(
}else{
rc = SQLITE_NOMEM;
}
- }else if( idxNum==FTS3_DOCID_SEARCH ){
+ }else if( eSearch==FTS3_DOCID_SEARCH ){
rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
if( rc==SQLITE_OK ){
- rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
+ rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
}
}
if( rc!=SQLITE_OK ) return rc;
@@ -123206,6 +127654,12 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
}
/*
+** Maximum number of tokens a phrase may have to be considered for the
+** incremental doclists strategy.
+*/
+#define MAX_INCR_PHRASE_TOKENS 4
+
+/*
** This function is called for each Fts3Phrase in a full-text query
** expression to initialize the mechanism for returning rows. Once this
** function has been called successfully on an Fts3Phrase, it may be
@@ -123218,23 +127672,43 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
*/
static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){
- int rc; /* Error code */
- Fts3PhraseToken *pFirst = &p->aToken[0];
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
+ int rc = SQLITE_OK; /* Error code */
+ int i;
- if( pCsr->bDesc==pTab->bDescIdx
- && bOptOk==1
- && p->nToken==1
- && pFirst->pSegcsr
- && pFirst->pSegcsr->bLookup
- && pFirst->bFirst==0
- ){
+ /* Determine if doclists may be loaded from disk incrementally. This is
+ ** possible if the bOptOk argument is true, the FTS doclists will be
+ ** scanned in forward order, and the phrase consists of
+ ** MAX_INCR_PHRASE_TOKENS or fewer tokens, none of which are are "^first"
+ ** tokens or prefix tokens that cannot use a prefix-index. */
+ int bHaveIncr = 0;
+ int bIncrOk = (bOptOk
+ && pCsr->bDesc==pTab->bDescIdx
+ && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
+ && p->nToken<=MAX_INCR_PHRASE_TOKENS && p->nToken>0
+#ifdef SQLITE_TEST
+ && pTab->bNoIncrDoclist==0
+#endif
+ );
+ for(i=0; bIncrOk==1 && i<p->nToken; i++){
+ Fts3PhraseToken *pToken = &p->aToken[i];
+ if( pToken->bFirst || (pToken->pSegcsr!=0 && !pToken->pSegcsr->bLookup) ){
+ bIncrOk = 0;
+ }
+ if( pToken->pSegcsr ) bHaveIncr = 1;
+ }
+
+ if( bIncrOk && bHaveIncr ){
/* Use the incremental approach. */
int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
- rc = sqlite3Fts3MsrIncrStart(
- pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
+ for(i=0; rc==SQLITE_OK && i<p->nToken; i++){
+ Fts3PhraseToken *pToken = &p->aToken[i];
+ Fts3MultiSegReader *pSegcsr = pToken->pSegcsr;
+ if( pSegcsr ){
+ rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n);
+ }
+ }
p->bIncr = 1;
-
}else{
/* Load the full doclist for the phrase into memory. */
rc = fts3EvalPhraseLoad(pCsr, p);
@@ -123344,15 +127818,125 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
}
/*
-** Attempt to move the phrase iterator to point to the next matching docid.
+** Advance the iterator pDL to the next entry in pDL->aAll/nAll. Set *pbEof
+** to true if EOF is reached.
+*/
+static void fts3EvalDlPhraseNext(
+ Fts3Table *pTab,
+ Fts3Doclist *pDL,
+ u8 *pbEof
+){
+ char *pIter; /* Used to iterate through aAll */
+ char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */
+
+ if( pDL->pNextDocid ){
+ pIter = pDL->pNextDocid;
+ }else{
+ pIter = pDL->aAll;
+ }
+
+ if( pIter>=pEnd ){
+ /* We have already reached the end of this doclist. EOF. */
+ *pbEof = 1;
+ }else{
+ sqlite3_int64 iDelta;
+ pIter += sqlite3Fts3GetVarint(pIter, &iDelta);
+ if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){
+ pDL->iDocid += iDelta;
+ }else{
+ pDL->iDocid -= iDelta;
+ }
+ pDL->pList = pIter;
+ fts3PoslistCopy(0, &pIter);
+ pDL->nList = (int)(pIter - pDL->pList);
+
+ /* pIter now points just past the 0x00 that terminates the position-
+ ** list for document pDL->iDocid. However, if this position-list was
+ ** edited in place by fts3EvalNearTrim(), then pIter may not actually
+ ** point to the start of the next docid value. The following line deals
+ ** with this case by advancing pIter past the zero-padding added by
+ ** fts3EvalNearTrim(). */
+ while( pIter<pEnd && *pIter==0 ) pIter++;
+
+ pDL->pNextDocid = pIter;
+ assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter );
+ *pbEof = 0;
+ }
+}
+
+/*
+** Helper type used by fts3EvalIncrPhraseNext() and incrPhraseTokenNext().
+*/
+typedef struct TokenDoclist TokenDoclist;
+struct TokenDoclist {
+ int bIgnore;
+ sqlite3_int64 iDocid;
+ char *pList;
+ int nList;
+};
+
+/*
+** Token pToken is an incrementally loaded token that is part of a
+** multi-token phrase. Advance it to the next matching document in the
+** database and populate output variable *p with the details of the new
+** entry. Or, if the iterator has reached EOF, set *pbEof to true.
+**
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
+*/
+static int incrPhraseTokenNext(
+ Fts3Table *pTab, /* Virtual table handle */
+ Fts3Phrase *pPhrase, /* Phrase to advance token of */
+ int iToken, /* Specific token to advance */
+ TokenDoclist *p, /* OUT: Docid and doclist for new entry */
+ u8 *pbEof /* OUT: True if iterator is at EOF */
+){
+ int rc = SQLITE_OK;
+
+ if( pPhrase->iDoclistToken==iToken ){
+ assert( p->bIgnore==0 );
+ assert( pPhrase->aToken[iToken].pSegcsr==0 );
+ fts3EvalDlPhraseNext(pTab, &pPhrase->doclist, pbEof);
+ p->pList = pPhrase->doclist.pList;
+ p->nList = pPhrase->doclist.nList;
+ p->iDocid = pPhrase->doclist.iDocid;
+ }else{
+ Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
+ assert( pToken->pDeferred==0 );
+ assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 );
+ if( pToken->pSegcsr ){
+ assert( p->bIgnore==0 );
+ rc = sqlite3Fts3MsrIncrNext(
+ pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList
+ );
+ if( p->pList==0 ) *pbEof = 1;
+ }else{
+ p->bIgnore = 1;
+ }
+ }
+
+ return rc;
+}
+
+
+/*
+** The phrase iterator passed as the second argument:
+**
+** * features at least one token that uses an incremental doclist, and
+**
+** * does not contain any deferred tokens.
+**
+** Advance it to the next matching documnent in the database and populate
+** the Fts3Doclist.pList and nList fields.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
** 1 before returning. Otherwise, if no error occurs and the iterator is
** successfully advanced, *pbEof is set to 0.
+**
+** If an error occurs, return an SQLite error code. Otherwise, return
+** SQLITE_OK.
*/
-static int fts3EvalPhraseNext(
+static int fts3EvalIncrPhraseNext(
Fts3Cursor *pCsr, /* FTS Cursor handle */
Fts3Phrase *p, /* Phrase object to advance to next docid */
u8 *pbEof /* OUT: Set to 1 if EOF */
@@ -123360,57 +127944,116 @@ static int fts3EvalPhraseNext(
int rc = SQLITE_OK;
Fts3Doclist *pDL = &p->doclist;
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
+ u8 bEof = 0;
- if( p->bIncr ){
- assert( p->nToken==1 );
- assert( pDL->pNextDocid==0 );
+ /* This is only called if it is guaranteed that the phrase has at least
+ ** one incremental token. In which case the bIncr flag is set. */
+ assert( p->bIncr==1 );
+
+ if( p->nToken==1 && p->bIncr ){
rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr,
&pDL->iDocid, &pDL->pList, &pDL->nList
);
- if( rc==SQLITE_OK && !pDL->pList ){
- *pbEof = 1;
+ if( pDL->pList==0 ) bEof = 1;
+ }else{
+ int bDescDoclist = pCsr->bDesc;
+ struct TokenDoclist a[MAX_INCR_PHRASE_TOKENS];
+
+ memset(a, 0, sizeof(a));
+ assert( p->nToken<=MAX_INCR_PHRASE_TOKENS );
+ assert( p->iDoclistToken<MAX_INCR_PHRASE_TOKENS );
+
+ while( bEof==0 ){
+ int bMaxSet = 0;
+ sqlite3_int64 iMax = 0; /* Largest docid for all iterators */
+ int i; /* Used to iterate through tokens */
+
+ /* Advance the iterator for each token in the phrase once. */
+ for(i=0; rc==SQLITE_OK && i<p->nToken && bEof==0; i++){
+ rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
+ if( a[i].bIgnore==0 && (bMaxSet==0 || DOCID_CMP(iMax, a[i].iDocid)<0) ){
+ iMax = a[i].iDocid;
+ bMaxSet = 1;
+ }
+ }
+ assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
+ assert( rc!=SQLITE_OK || bMaxSet );
+
+ /* Keep advancing iterators until they all point to the same document */
+ for(i=0; i<p->nToken; i++){
+ while( rc==SQLITE_OK && bEof==0
+ && a[i].bIgnore==0 && DOCID_CMP(a[i].iDocid, iMax)<0
+ ){
+ rc = incrPhraseTokenNext(pTab, p, i, &a[i], &bEof);
+ if( DOCID_CMP(a[i].iDocid, iMax)>0 ){
+ iMax = a[i].iDocid;
+ i = 0;
+ }
+ }
+ }
+
+ /* Check if the current entries really are a phrase match */
+ if( bEof==0 ){
+ int nList = 0;
+ int nByte = a[p->nToken-1].nList;
+ char *aDoclist = sqlite3_malloc(nByte+1);
+ if( !aDoclist ) return SQLITE_NOMEM;
+ memcpy(aDoclist, a[p->nToken-1].pList, nByte+1);
+
+ for(i=0; i<(p->nToken-1); i++){
+ if( a[i].bIgnore==0 ){
+ char *pL = a[i].pList;
+ char *pR = aDoclist;
+ char *pOut = aDoclist;
+ int nDist = p->nToken-1-i;
+ int res = fts3PoslistPhraseMerge(&pOut, nDist, 0, 1, &pL, &pR);
+ if( res==0 ) break;
+ nList = (int)(pOut - aDoclist);
+ }
+ }
+ if( i==(p->nToken-1) ){
+ pDL->iDocid = iMax;
+ pDL->pList = aDoclist;
+ pDL->nList = nList;
+ pDL->bFreeList = 1;
+ break;
+ }
+ sqlite3_free(aDoclist);
+ }
}
+ }
+
+ *pbEof = bEof;
+ return rc;
+}
+
+/*
+** Attempt to move the phrase iterator to point to the next matching docid.
+** If an error occurs, return an SQLite error code. Otherwise, return
+** SQLITE_OK.
+**
+** If there is no "next" entry and no error occurs, then *pbEof is set to
+** 1 before returning. Otherwise, if no error occurs and the iterator is
+** successfully advanced, *pbEof is set to 0.
+*/
+static int fts3EvalPhraseNext(
+ Fts3Cursor *pCsr, /* FTS Cursor handle */
+ Fts3Phrase *p, /* Phrase object to advance to next docid */
+ u8 *pbEof /* OUT: Set to 1 if EOF */
+){
+ int rc = SQLITE_OK;
+ Fts3Doclist *pDL = &p->doclist;
+ Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
+
+ if( p->bIncr ){
+ rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof);
}else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){
sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll,
&pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof
);
pDL->pList = pDL->pNextDocid;
}else{
- char *pIter; /* Used to iterate through aAll */
- char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */
- if( pDL->pNextDocid ){
- pIter = pDL->pNextDocid;
- }else{
- pIter = pDL->aAll;
- }
-
- if( pIter>=pEnd ){
- /* We have already reached the end of this doclist. EOF. */
- *pbEof = 1;
- }else{
- sqlite3_int64 iDelta;
- pIter += sqlite3Fts3GetVarint(pIter, &iDelta);
- if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){
- pDL->iDocid += iDelta;
- }else{
- pDL->iDocid -= iDelta;
- }
- pDL->pList = pIter;
- fts3PoslistCopy(0, &pIter);
- pDL->nList = (int)(pIter - pDL->pList);
-
- /* pIter now points just past the 0x00 that terminates the position-
- ** list for document pDL->iDocid. However, if this position-list was
- ** edited in place by fts3EvalNearTrim(), then pIter may not actually
- ** point to the start of the next docid value. The following line deals
- ** with this case by advancing pIter past the zero-padding added by
- ** fts3EvalNearTrim(). */
- while( pIter<pEnd && *pIter==0 ) pIter++;
-
- pDL->pNextDocid = pIter;
- assert( pIter>=&pDL->aAll[pDL->nAll] || *pIter );
- *pbEof = 0;
- }
+ fts3EvalDlPhraseNext(pTab, pDL, pbEof);
}
return rc;
@@ -123435,7 +128078,6 @@ static int fts3EvalPhraseNext(
static void fts3EvalStartReaders(
Fts3Cursor *pCsr, /* FTS Cursor handle */
Fts3Expr *pExpr, /* Expression to initialize phrases in */
- int bOptOk, /* True to enable incremental loading */
int *pRc /* IN/OUT: Error code */
){
if( pExpr && SQLITE_OK==*pRc ){
@@ -123446,10 +128088,10 @@ static void fts3EvalStartReaders(
if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
}
pExpr->bDeferred = (i==nToken);
- *pRc = fts3EvalPhraseStart(pCsr, bOptOk, pExpr->pPhrase);
+ *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
}else{
- fts3EvalStartReaders(pCsr, pExpr->pLeft, bOptOk, pRc);
- fts3EvalStartReaders(pCsr, pExpr->pRight, bOptOk, pRc);
+ fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
+ fts3EvalStartReaders(pCsr, pExpr->pRight, pRc);
pExpr->bDeferred = (pExpr->pLeft->bDeferred && pExpr->pRight->bDeferred);
}
}
@@ -123691,7 +128333,7 @@ static int fts3EvalSelectDeferred(
** overflowing the 32-bit integer it is stored in. */
if( ii<12 ) nLoad4 = nLoad4*4;
- if( ii==0 || pTC->pPhrase->nToken>1 ){
+ if( ii==0 || (pTC->pPhrase->nToken>1 && ii!=nToken-1) ){
/* Either this is the cheapest token in the entire query, or it is
** part of a multi-token phrase. Either way, the entire doclist will
** (eventually) be loaded into memory. It may as well be now. */
@@ -123771,7 +128413,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){
}
#endif
- fts3EvalStartReaders(pCsr, pCsr->pExpr, 1, &rc);
+ fts3EvalStartReaders(pCsr, pCsr->pExpr, &rc);
return rc;
}
@@ -124254,6 +128896,16 @@ static int fts3EvalNext(Fts3Cursor *pCsr){
pCsr->iPrevId = pExpr->iDocid;
}while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
}
+
+ /* Check if the cursor is past the end of the docid range specified
+ ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */
+ if( rc==SQLITE_OK && (
+ (pCsr->bDesc==0 && pCsr->iPrevId>pCsr->iMaxDocid)
+ || (pCsr->bDesc!=0 && pCsr->iPrevId<pCsr->iMinDocid)
+ )){
+ pCsr->isEof = 1;
+ }
+
return rc;
}
@@ -124277,12 +128929,16 @@ static void fts3EvalRestart(
if( pPhrase ){
fts3EvalInvalidatePoslist(pPhrase);
if( pPhrase->bIncr ){
- assert( pPhrase->nToken==1 );
- assert( pPhrase->aToken[0].pSegcsr );
- sqlite3Fts3MsrIncrRestart(pPhrase->aToken[0].pSegcsr);
+ int i;
+ for(i=0; i<pPhrase->nToken; i++){
+ Fts3PhraseToken *pToken = &pPhrase->aToken[i];
+ assert( pToken->pDeferred==0 );
+ if( pToken->pSegcsr ){
+ sqlite3Fts3MsrIncrRestart(pToken->pSegcsr);
+ }
+ }
*pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase);
}
-
pPhrase->doclist.pNextDocid = 0;
pPhrase->doclist.iDocid = 0;
}
@@ -124327,7 +128983,7 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
pExpr->aMI[iCol*3 + 2] += (iCnt>0);
if( *p==0x00 ) break;
p++;
- p += sqlite3Fts3GetVarint32(p, &iCol);
+ p += fts3GetVarint32(p, &iCol);
}
}
@@ -124531,15 +129187,23 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
pIter = pPhrase->doclist.pList;
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
+ int iMul; /* +1 if csr dir matches index dir, else -1 */
int bOr = 0;
u8 bEof = 0;
- Fts3Expr *p;
+ u8 bTreeEof = 0;
+ Fts3Expr *p; /* Used to iterate from pExpr to root */
+ Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */
/* Check if this phrase descends from an OR expression node. If not,
** return NULL. Otherwise, the entry that corresponds to docid
- ** pCsr->iPrevId may lie earlier in the doclist buffer. */
+ ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the
+ ** tree that the node is part of has been marked as EOF, but the node
+ ** itself is not EOF, then it may point to an earlier entry. */
+ pNear = pExpr;
for(p=pExpr->pParent; p; p=p->pParent){
if( p->eType==FTSQUERY_OR ) bOr = 1;
+ if( p->eType==FTSQUERY_NEAR ) pNear = p;
+ if( p->bEof ) bTreeEof = 1;
}
if( bOr==0 ) return SQLITE_OK;
@@ -124558,29 +129222,59 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
if( rc!=SQLITE_OK ) return rc;
}
-
- if( pExpr->bEof ){
- pIter = 0;
- iDocid = 0;
+
+ iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1);
+ while( bTreeEof==1
+ && pNear->bEof==0
+ && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0
+ ){
+ int rc = SQLITE_OK;
+ fts3EvalNextRow(pCsr, pExpr, &rc);
+ if( rc!=SQLITE_OK ) return rc;
+ iDocid = pExpr->iDocid;
+ pIter = pPhrase->doclist.pList;
}
+
bEof = (pPhrase->doclist.nAll==0);
assert( bDescDoclist==0 || bDescDoclist==1 );
assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
- if( pCsr->bDesc==bDescDoclist ){
- int dummy;
- while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
- sqlite3Fts3DoclistPrev(
- bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
- &pIter, &iDocid, &dummy, &bEof
- );
- }
- }else{
- while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
- sqlite3Fts3DoclistNext(
- bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
- &pIter, &iDocid, &bEof
- );
+ if( bEof==0 ){
+ if( pCsr->bDesc==bDescDoclist ){
+ int dummy;
+ if( pNear->bEof ){
+ /* This expression is already at EOF. So position it to point to the
+ ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable
+ ** iDocid is already set for this entry, so all that is required is
+ ** to set pIter to point to the first byte of the last position-list
+ ** in the doclist.
+ **
+ ** It would also be correct to set pIter and iDocid to zero. In
+ ** this case, the first call to sqltie3Fts4DoclistPrev() below
+ ** would also move the iterator to point to the last entry in the
+ ** doclist. However, this is expensive, as to do so it has to
+ ** iterate through the entire doclist from start to finish (since
+ ** it does not know the docid for the last entry). */
+ pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1];
+ fts3ReversePoslist(pPhrase->doclist.aAll, &pIter);
+ }
+ while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
+ sqlite3Fts3DoclistPrev(
+ bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
+ &pIter, &iDocid, &dummy, &bEof
+ );
+ }
+ }else{
+ if( pNear->bEof ){
+ pIter = 0;
+ iDocid = 0;
+ }
+ while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
+ sqlite3Fts3DoclistNext(
+ bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
+ &pIter, &iDocid, &bEof
+ );
+ }
}
}
@@ -124590,7 +129284,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
if( *pIter==0x01 ){
pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
+ pIter += fts3GetVarint32(pIter, &iThis);
}else{
iThis = 0;
}
@@ -124598,7 +129292,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
fts3ColumnlistCopy(0, &pIter);
if( *pIter==0x00 ) return 0;
pIter++;
- pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
+ pIter += fts3GetVarint32(pIter, &iThis);
}
*ppOut = ((iCol==iThis)?pIter:0);
@@ -124639,7 +129333,10 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
/*
** Initialize API pointer table, if required.
*/
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -124685,6 +129382,7 @@ struct Fts3auxCursor {
Fts3SegFilter filter;
char *zStop;
int nStop; /* Byte-length of string zStop */
+ int iLangid; /* Language id to query */
int isEof; /* True if cursor is at EOF */
sqlite3_int64 iRowid; /* Current rowid */
@@ -124699,7 +129397,8 @@ struct Fts3auxCursor {
/*
** Schema of the terms table.
*/
-#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, col, documents, occurrences)"
+#define FTS3_AUX_SCHEMA \
+ "CREATE TABLE x(term, col, documents, occurrences, languageid HIDDEN)"
/*
** This function does all the work for both the xConnect and xCreate methods.
@@ -124746,7 +129445,7 @@ static int fts3auxConnectMethod(
}
nFts3 = (int)strlen(zFts3);
- rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
+ rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA);
if( rc!=SQLITE_OK ) return rc;
nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
@@ -124806,6 +129505,8 @@ static int fts3auxBestIndexMethod(
int iEq = -1;
int iGe = -1;
int iLe = -1;
+ int iLangid = -1;
+ int iNext = 1; /* Next free argvIndex value */
UNUSED_PARAMETER(pVTab);
@@ -124817,36 +129518,48 @@ static int fts3auxBestIndexMethod(
pInfo->orderByConsumed = 1;
}
- /* Search for equality and range constraints on the "term" column. */
+ /* Search for equality and range constraints on the "term" column.
+ ** And equality constraints on the hidden "languageid" column. */
for(i=0; i<pInfo->nConstraint; i++){
- if( pInfo->aConstraint[i].usable && pInfo->aConstraint[i].iColumn==0 ){
+ if( pInfo->aConstraint[i].usable ){
int op = pInfo->aConstraint[i].op;
- if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i;
- if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i;
- if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i;
+ int iCol = pInfo->aConstraint[i].iColumn;
+
+ if( iCol==0 ){
+ if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iEq = i;
+ if( op==SQLITE_INDEX_CONSTRAINT_LT ) iLe = i;
+ if( op==SQLITE_INDEX_CONSTRAINT_LE ) iLe = i;
+ if( op==SQLITE_INDEX_CONSTRAINT_GT ) iGe = i;
+ if( op==SQLITE_INDEX_CONSTRAINT_GE ) iGe = i;
+ }
+ if( iCol==4 ){
+ if( op==SQLITE_INDEX_CONSTRAINT_EQ ) iLangid = i;
+ }
}
}
if( iEq>=0 ){
pInfo->idxNum = FTS4AUX_EQ_CONSTRAINT;
- pInfo->aConstraintUsage[iEq].argvIndex = 1;
+ pInfo->aConstraintUsage[iEq].argvIndex = iNext++;
pInfo->estimatedCost = 5;
}else{
pInfo->idxNum = 0;
pInfo->estimatedCost = 20000;
if( iGe>=0 ){
pInfo->idxNum += FTS4AUX_GE_CONSTRAINT;
- pInfo->aConstraintUsage[iGe].argvIndex = 1;
+ pInfo->aConstraintUsage[iGe].argvIndex = iNext++;
pInfo->estimatedCost /= 2;
}
if( iLe>=0 ){
pInfo->idxNum += FTS4AUX_LE_CONSTRAINT;
- pInfo->aConstraintUsage[iLe].argvIndex = 1 + (iGe>=0);
+ pInfo->aConstraintUsage[iLe].argvIndex = iNext++;
pInfo->estimatedCost /= 2;
}
}
+ if( iLangid>=0 ){
+ pInfo->aConstraintUsage[iLangid].argvIndex = iNext++;
+ pInfo->estimatedCost--;
+ }
return SQLITE_OK;
}
@@ -125006,7 +129719,14 @@ static int fts3auxFilterMethod(
Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
int rc;
- int isScan;
+ int isScan = 0;
+ int iLangVal = 0; /* Language id to query */
+
+ int iEq = -1; /* Index of term=? value in apVal */
+ int iGe = -1; /* Index of term>=? value in apVal */
+ int iLe = -1; /* Index of term<=? value in apVal */
+ int iLangid = -1; /* Index of languageid=? value in apVal */
+ int iNext = 0;
UNUSED_PARAMETER(nVal);
UNUSED_PARAMETER(idxStr);
@@ -125016,7 +129736,21 @@ static int fts3auxFilterMethod(
|| idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT
|| idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT)
);
- isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT);
+
+ if( idxNum==FTS4AUX_EQ_CONSTRAINT ){
+ iEq = iNext++;
+ }else{
+ isScan = 1;
+ if( idxNum & FTS4AUX_GE_CONSTRAINT ){
+ iGe = iNext++;
+ }
+ if( idxNum & FTS4AUX_LE_CONSTRAINT ){
+ iLe = iNext++;
+ }
+ }
+ if( iNext<nVal ){
+ iLangid = iNext++;
+ }
/* In case this cursor is being reused, close and zero it. */
testcase(pCsr->filter.zTerm);
@@ -125028,22 +129762,35 @@ static int fts3auxFilterMethod(
pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY;
if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN;
- if( idxNum&(FTS4AUX_EQ_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ){
+ if( iEq>=0 || iGe>=0 ){
const unsigned char *zStr = sqlite3_value_text(apVal[0]);
+ assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) );
if( zStr ){
pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr);
pCsr->filter.nTerm = sqlite3_value_bytes(apVal[0]);
if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM;
}
}
- if( idxNum&FTS4AUX_LE_CONSTRAINT ){
- int iIdx = (idxNum&FTS4AUX_GE_CONSTRAINT) ? 1 : 0;
- pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iIdx]));
- pCsr->nStop = sqlite3_value_bytes(apVal[iIdx]);
+
+ if( iLe>=0 ){
+ pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe]));
+ pCsr->nStop = sqlite3_value_bytes(apVal[iLe]);
if( pCsr->zStop==0 ) return SQLITE_NOMEM;
}
+
+ if( iLangid>=0 ){
+ iLangVal = sqlite3_value_int(apVal[iLangid]);
+
+ /* If the user specified a negative value for the languageid, use zero
+ ** instead. This works, as the "languageid=?" constraint will also
+ ** be tested by the VDBE layer. The test will always be false (since
+ ** this module will not return a row with a negative languageid), and
+ ** so the overall query will return zero rows. */
+ if( iLangVal<0 ) iLangVal = 0;
+ }
+ pCsr->iLangid = iLangVal;
- rc = sqlite3Fts3SegReaderCursor(pFts3, 0, 0, FTS3_SEGCURSOR_ALL,
+ rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL,
pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr
);
if( rc==SQLITE_OK ){
@@ -125067,24 +129814,37 @@ static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){
*/
static int fts3auxColumnMethod(
sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */
- sqlite3_context *pContext, /* Context for sqlite3_result_xxx() calls */
+ sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */
int iCol /* Index of column to read value from */
){
Fts3auxCursor *p = (Fts3auxCursor *)pCursor;
assert( p->isEof==0 );
- if( iCol==0 ){ /* Column "term" */
- sqlite3_result_text(pContext, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT);
- }else if( iCol==1 ){ /* Column "col" */
- if( p->iCol ){
- sqlite3_result_int(pContext, p->iCol-1);
- }else{
- sqlite3_result_text(pContext, "*", -1, SQLITE_STATIC);
- }
- }else if( iCol==2 ){ /* Column "documents" */
- sqlite3_result_int64(pContext, p->aStat[p->iCol].nDoc);
- }else{ /* Column "occurrences" */
- sqlite3_result_int64(pContext, p->aStat[p->iCol].nOcc);
+ switch( iCol ){
+ case 0: /* term */
+ sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT);
+ break;
+
+ case 1: /* col */
+ if( p->iCol ){
+ sqlite3_result_int(pCtx, p->iCol-1);
+ }else{
+ sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC);
+ }
+ break;
+
+ case 2: /* documents */
+ sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc);
+ break;
+
+ case 3: /* occurrences */
+ sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc);
+ break;
+
+ default: /* languageid */
+ assert( iCol==4 );
+ sqlite3_result_int(pCtx, p->iLangid);
+ break;
}
return SQLITE_OK;
@@ -125298,6 +130058,11 @@ SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(
return rc;
}
+/*
+** Function getNextNode(), which is called by fts3ExprParse(), may itself
+** call fts3ExprParse(). So this forward declaration is required.
+*/
+static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
/*
** Extract the next token from buffer z (length n) using the tokenizer
@@ -125332,7 +130097,31 @@ static int getNextToken(
int nByte; /* total space to allocate */
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
- if( rc==SQLITE_OK ){
+
+ if( (rc==SQLITE_OK || rc==SQLITE_DONE) && sqlite3_fts3_enable_parentheses ){
+ int i;
+ if( rc==SQLITE_DONE ) iStart = n;
+ for(i=0; i<iStart; i++){
+ if( z[i]=='(' ){
+ pParse->nNest++;
+ rc = fts3ExprParse(pParse, &z[i+1], n-i-1, &pRet, &nConsumed);
+ if( rc==SQLITE_OK && !pRet ){
+ rc = SQLITE_DONE;
+ }
+ nConsumed = (int)(i + 1 + nConsumed);
+ break;
+ }
+
+ if( z[i]==')' ){
+ rc = SQLITE_DONE;
+ pParse->nNest--;
+ nConsumed = i+1;
+ break;
+ }
+ }
+ }
+
+ if( nConsumed==0 && rc==SQLITE_OK ){
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
pRet = (Fts3Expr *)fts3MallocZero(nByte);
if( !pRet ){
@@ -125513,12 +130302,6 @@ no_mem:
}
/*
-** Function getNextNode(), which is called by fts3ExprParse(), may itself
-** call fts3ExprParse(). So this forward declaration is required.
-*/
-static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
-
-/*
** The output variable *ppExpr is populated with an allocated Fts3Expr
** structure, or set to 0 if the end of the input buffer is reached.
**
@@ -125614,27 +130397,6 @@ static int getNextNode(
}
}
- /* Check for an open bracket. */
- if( sqlite3_fts3_enable_parentheses ){
- if( *zInput=='(' ){
- int nConsumed;
- pParse->nNest++;
- rc = fts3ExprParse(pParse, &zInput[1], nInput-1, ppExpr, &nConsumed);
- if( rc==SQLITE_OK && !*ppExpr ){
- rc = SQLITE_DONE;
- }
- *pnConsumed = (int)((zInput - z) + 1 + nConsumed);
- return rc;
- }
-
- /* Check for a close bracket. */
- if( *zInput==')' ){
- pParse->nNest--;
- *pnConsumed = (int)((zInput - z) + 1);
- return SQLITE_DONE;
- }
- }
-
/* See if we are dealing with a quoted phrase. If this is the case, then
** search for the closing quote and pass the whole string to getNextString()
** for processing. This is easy to do, as fts3 has no syntax for escaping
@@ -126143,17 +130905,16 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
Fts3Expr **ppExpr, /* OUT: Parsed query structure */
char **pzErr /* OUT: Error message (sqlite3_malloc) */
){
- static const int MAX_EXPR_DEPTH = 12;
int rc = fts3ExprParseUnbalanced(
pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr
);
/* Rebalance the expression. And check that its depth does not exceed
- ** MAX_EXPR_DEPTH. */
+ ** SQLITE_FTS3_MAX_EXPR_DEPTH. */
if( rc==SQLITE_OK && *ppExpr ){
- rc = fts3ExprBalance(ppExpr, MAX_EXPR_DEPTH);
+ rc = fts3ExprBalance(ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
if( rc==SQLITE_OK ){
- rc = fts3ExprCheckDepth(*ppExpr, MAX_EXPR_DEPTH);
+ rc = fts3ExprCheckDepth(*ppExpr, SQLITE_FTS3_MAX_EXPR_DEPTH);
}
}
@@ -126162,7 +130923,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
*ppExpr = 0;
if( rc==SQLITE_TOOBIG ){
*pzErr = sqlite3_mprintf(
- "FTS expression tree is too large (maximum depth %d)", MAX_EXPR_DEPTH
+ "FTS expression tree is too large (maximum depth %d)",
+ SQLITE_FTS3_MAX_EXPR_DEPTH
);
rc = SQLITE_ERROR;
}else if( rc==SQLITE_ERROR ){
@@ -127657,7 +132419,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
#ifdef SQLITE_TEST
-/* #include <tcl.h> */
+#include <tcl.h>
/* #include <string.h> */
/*
@@ -129124,37 +133886,30 @@ static void fts3SqlExec(
/*
-** This function ensures that the caller has obtained a shared-cache
-** table-lock on the %_content table. This is required before reading
-** data from the fts3 table. If this lock is not acquired first, then
-** the caller may end up holding read-locks on the %_segments and %_segdir
-** tables, but no read-lock on the %_content table. If this happens
-** a second connection will be able to write to the fts3 table, but
-** attempting to commit those writes might return SQLITE_LOCKED or
-** SQLITE_LOCKED_SHAREDCACHE (because the commit attempts to obtain
-** write-locks on the %_segments and %_segdir ** tables).
-**
-** We try to avoid this because if FTS3 returns any error when committing
-** a transaction, the whole transaction will be rolled back. And this is
-** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
-** still happen if the user reads data directly from the %_segments or
-** %_segdir tables instead of going through FTS3 though.
+** This function ensures that the caller has obtained an exclusive
+** shared-cache table-lock on the %_segdir table. This is required before
+** writing data to the fts3 table. If this lock is not acquired first, then
+** the caller may end up attempting to take this lock as part of committing
+** a transaction, causing SQLite to return SQLITE_LOCKED or
+** LOCKED_SHAREDCACHEto a COMMIT command.
**
-** This reasoning does not apply to a content=xxx table.
+** It is best to avoid this because if FTS3 returns any error when
+** committing a transaction, the whole transaction will be rolled back.
+** And this is not what users expect when they get SQLITE_LOCKED_SHAREDCACHE.
+** It can still happen if the user locks the underlying tables directly
+** instead of accessing them via FTS.
*/
-SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
- int rc; /* Return code */
- sqlite3_stmt *pStmt; /* Statement used to obtain lock */
-
- if( p->zContentTbl==0 ){
- rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
+static int fts3Writelock(Fts3Table *p){
+ int rc = SQLITE_OK;
+
+ if( p->nPendingData==0 ){
+ sqlite3_stmt *pStmt;
+ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0);
if( rc==SQLITE_OK ){
sqlite3_bind_null(pStmt, 1);
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
}
- }else{
- rc = SQLITE_OK;
}
return rc;
@@ -129542,12 +134297,15 @@ static int fts3InsertTerms(
){
int i; /* Iterator variable */
for(i=2; i<p->nColumn+2; i++){
- const char *zText = (const char *)sqlite3_value_text(apVal[i]);
- int rc = fts3PendingTermsAdd(p, iLangid, zText, i-2, &aSz[i-2]);
- if( rc!=SQLITE_OK ){
- return rc;
+ int iCol = i-2;
+ if( p->abNotindexed[iCol]==0 ){
+ const char *zText = (const char *)sqlite3_value_text(apVal[i]);
+ int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
}
- aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]);
}
return SQLITE_OK;
}
@@ -129694,9 +134452,12 @@ static void fts3DeleteTerms(
int iLangid = langidFromSelect(p, pSelect);
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
- const char *zText = (const char *)sqlite3_column_text(pSelect, i);
- rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[i-1]);
- aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
+ int iCol = i-1;
+ if( p->abNotindexed[iCol]==0 ){
+ const char *zText = (const char *)sqlite3_column_text(pSelect, i);
+ rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]);
+ aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
+ }
}
if( rc!=SQLITE_OK ){
sqlite3_reset(pSelect);
@@ -129980,8 +134741,8 @@ static int fts3SegReaderNext(
/* Because of the FTS3_NODE_PADDING bytes of padding, the following is
** safe (no risk of overread) even if the node data is corrupted. */
- pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
- pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
+ pNext += fts3GetVarint32(pNext, &nPrefix);
+ pNext += fts3GetVarint32(pNext, &nSuffix);
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
@@ -130004,7 +134765,7 @@ static int fts3SegReaderNext(
memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix);
pReader->nTerm = nPrefix+nSuffix;
pNext += nSuffix;
- pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
+ pNext += fts3GetVarint32(pNext, &pReader->nDoclist);
pReader->aDoclist = pNext;
pReader->pOffsetList = 0;
@@ -130097,7 +134858,7 @@ static int fts3SegReaderNextDocid(
/* The following line of code (and the "p++" below the while() loop) is
** normally all that is required to move pointer p to the desired
** position. The exception is if this node is being loaded from disk
- ** incrementally and pointer "p" now points to the first byte passed
+ ** incrementally and pointer "p" now points to the first byte past
** the populated part of pReader->aNode[].
*/
while( *p | c ) c = *p++ & 0x80;
@@ -131165,7 +135926,7 @@ static void fts3ColumnFilter(
break;
}
p = &pList[1];
- p += sqlite3Fts3GetVarint32(p, &iCurrent);
+ p += fts3GetVarint32(p, &iCurrent);
}
if( bZero && &pList[nList]!=pEnd ){
@@ -131484,8 +136245,8 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(
fts3SegReaderSort(apSegment, nMerge, nMerge, xCmp);
while( apSegment[0]->pOffsetList ){
int j; /* Number of segments that share a docid */
- char *pList;
- int nList;
+ char *pList = 0;
+ int nList = 0;
int nByte;
sqlite3_int64 iDocid = apSegment[0]->iDocid;
fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList);
@@ -131938,9 +136699,11 @@ static int fts3DoRebuild(Fts3Table *p){
rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
- const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
- rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
- aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
+ if( p->abNotindexed[iCol]==0 ){
+ const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
+ rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
+ aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
+ }
}
if( p->bHasDocsize ){
fts3InsertDocsize(&rc, p, aSz);
@@ -132128,9 +136891,9 @@ static int nodeReaderNext(NodeReader *p){
p->aNode = 0;
}else{
if( bFirst==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nPrefix);
}
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix);
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
if( rc==SQLITE_OK ){
@@ -132138,7 +136901,7 @@ static int nodeReaderNext(NodeReader *p){
p->term.n = nPrefix+nSuffix;
p->iOff += nSuffix;
if( p->iChild==0 ){
- p->iOff += sqlite3Fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
+ p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
p->aDoclist = &p->aNode[p->iOff];
p->iOff += p->nDoclist;
}
@@ -133190,7 +137953,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
pHint->n = i;
i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
- i += sqlite3Fts3GetVarint32(&pHint->a[i], pnInput);
+ i += fts3GetVarint32(&pHint->a[i], pnInput);
if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
return SQLITE_OK;
@@ -133414,7 +138177,7 @@ static int fts3DoAutoincrmerge(
if( rc ) return rc;
}
rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0);
- if( rc ) return rc;;
+ if( rc ) return rc;
sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE);
sqlite3_bind_int(pStmt, 2, p->bAutoincrmerge);
sqlite3_step(pStmt);
@@ -133684,6 +138447,9 @@ static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
p->nMaxPendingData = atoi(&zVal[11]);
rc = SQLITE_OK;
+ }else if( nVal>21 && 0==sqlite3_strnicmp(zVal, "test-no-incr-doclist=", 21) ){
+ p->bNoIncrDoclist = atoi(&zVal[21]);
+ rc = SQLITE_OK;
#endif
}else{
rc = SQLITE_ERROR;
@@ -133743,32 +138509,34 @@ SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){
iDocid = sqlite3_column_int64(pCsr->pStmt, 0);
for(i=0; i<p->nColumn && rc==SQLITE_OK; i++){
- const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
- sqlite3_tokenizer_cursor *pTC = 0;
-
- rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
- while( rc==SQLITE_OK ){
- char const *zToken; /* Buffer containing token */
- int nToken = 0; /* Number of bytes in token */
- int iDum1 = 0, iDum2 = 0; /* Dummy variables */
- int iPos = 0; /* Position of token in zText */
-
- rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
- for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
- Fts3PhraseToken *pPT = pDef->pToken;
- if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
- && (pPT->bFirst==0 || iPos==0)
- && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
- && (0==memcmp(zToken, pPT->z, pPT->n))
- ){
- fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
+ if( p->abNotindexed[i]==0 ){
+ const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1);
+ sqlite3_tokenizer_cursor *pTC = 0;
+
+ rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC);
+ while( rc==SQLITE_OK ){
+ char const *zToken; /* Buffer containing token */
+ int nToken = 0; /* Number of bytes in token */
+ int iDum1 = 0, iDum2 = 0; /* Dummy variables */
+ int iPos = 0; /* Position of token in zText */
+
+ rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
+ for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
+ Fts3PhraseToken *pPT = pDef->pToken;
+ if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
+ && (pPT->bFirst==0 || iPos==0)
+ && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
+ && (0==memcmp(zToken, pPT->z, pPT->n))
+ ){
+ fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
+ }
}
}
+ if( pTC ) pModule->xClose(pTC);
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
}
- if( pTC ) pModule->xClose(pTC);
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
}
-
+
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
if( pDef->pList ){
rc = fts3PendingListAppendVarint(&pDef->pList, 0);
@@ -133932,6 +138700,9 @@ SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(
aSzIns = &aSzDel[p->nColumn+1];
memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
+ rc = fts3Writelock(p);
+ if( rc!=SQLITE_OK ) goto update_out;
+
/* If this is an INSERT operation, or an UPDATE that modifies the rowid
** value, then this operation requires constraint handling.
**
@@ -134175,7 +138946,7 @@ struct StrBuffer {
*/
static void fts3GetDeltaPosition(char **pp, int *piPos){
int iVal;
- *pp += sqlite3Fts3GetVarint32(*pp, &iVal);
+ *pp += fts3GetVarint32(*pp, &iVal);
*piPos += (iVal-2);
}
@@ -134551,6 +139322,7 @@ static int fts3StringAppend(
pStr->z = zNew;
pStr->nAlloc = nAlloc;
}
+ assert( pStr->z!=0 && (pStr->nAlloc >= pStr->n+nAppend+1) );
/* Append the data to the string buffer. */
memcpy(&pStr->z[pStr->n], zAppend, nAppend);
@@ -136065,28 +140837,27 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
- 0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
- 0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
- 0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
- 0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
- 0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
- 0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
- 0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
- 0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
- 0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
- 0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
- 0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
- 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
- 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
- 0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
- 0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
- 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
- 0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
- 0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
- 0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
- 0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
- 0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
- 0x43FFF401,
+ 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
+ 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
+ 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
+ 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
+ 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
+ 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
+ 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
+ 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
+ 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
+ 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
+ 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
+ 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
+ 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
+ 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
+ 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
+ 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
+ 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
+ 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
+ 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
+ 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
+ 0x380400F0,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
@@ -136468,6 +141239,16 @@ typedef union RtreeCoord RtreeCoord;
*/
#define HASHSIZE 128
+/* The xBestIndex method of this virtual table requires an estimate of
+** the number of rows in the virtual table to calculate the costs of
+** various strategies. If possible, this estimate is loaded from the
+** sqlite_stat1 table (with RTREE_MIN_ROWEST as a hard-coded minimum).
+** Otherwise, if no sqlite_stat1 entry is available, use
+** RTREE_DEFAULT_ROWEST.
+*/
+#define RTREE_DEFAULT_ROWEST 1048576
+#define RTREE_MIN_ROWEST 100
+
/*
** An rtree virtual-table object.
*/
@@ -136482,6 +141263,7 @@ struct Rtree {
char *zName; /* Name of r-tree table */
RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */
int nBusy; /* Current number of users of this structure */
+ i64 nRowEst; /* Estimated number of rows in this table */
/* List of nodes removed during a CondenseTree operation. List is
** linked together via the pointer normally used for hash chains -
@@ -137675,6 +142457,19 @@ static int rtreeFilter(
}
/*
+** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support estimatedRows. In that case this function is a no-op.
+*/
+static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+#if SQLITE_VERSION_NUMBER>=3008002
+ if( sqlite3_libversion_number()>=3008002 ){
+ pIdxInfo->estimatedRows = nRow;
+ }
+#endif
+}
+
+/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to
** least desirable):
@@ -137709,13 +142504,14 @@ static int rtreeFilter(
** is 'a', the second from the left 'b' etc.
*/
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ Rtree *pRtree = (Rtree*)tab;
int rc = SQLITE_OK;
int ii;
+ i64 nRow; /* Estimated rows returned by this scan */
int iIdx = 0;
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
memset(zIdxStr, 0, sizeof(zIdxStr));
- UNUSED_PARAMETER(tab);
assert( pIdxInfo->idxStr==0 );
for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
@@ -137735,9 +142531,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
/* This strategy involves a two rowid lookups on an B-Tree structures
** and then a linear search of an R-Tree node. This should be
** considered almost as quick as a direct rowid lookup (for which
- ** sqlite uses an internal cost of 0.0).
+ ** sqlite uses an internal cost of 0.0). It is expected to return
+ ** a single row.
*/
- pIdxInfo->estimatedCost = 10.0;
+ pIdxInfo->estimatedCost = 30.0;
+ setEstimatedRows(pIdxInfo, 1);
return SQLITE_OK;
}
@@ -137766,8 +142564,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
return SQLITE_NOMEM;
}
- assert( iIdx>=0 );
- pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
+
+ nRow = pRtree->nRowEst / (iIdx + 1);
+ pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
+ setEstimatedRows(pIdxInfo, nRow);
+
return rc;
}
@@ -139242,6 +144043,37 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
return rc;
}
+/*
+** This function populates the pRtree->nRowEst variable with an estimate
+** of the number of rows in the virtual table. If possible, this is based
+** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
+*/
+static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
+ const char *zSql = "SELECT stat FROM sqlite_stat1 WHERE tbl= ? || '_rowid'";
+ sqlite3_stmt *p;
+ int rc;
+ i64 nRow = 0;
+
+ rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_bind_text(p, 1, pRtree->zName, -1, SQLITE_STATIC);
+ if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
+ rc = sqlite3_finalize(p);
+ }else if( rc!=SQLITE_NOMEM ){
+ rc = SQLITE_OK;
+ }
+
+ if( rc==SQLITE_OK ){
+ if( nRow==0 ){
+ pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
+ }else{
+ pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
+ }
+ }
+
+ return rc;
+}
+
static sqlite3_module rtreeModule = {
0, /* iVersion */
rtreeCreate, /* xCreate - create a table */
@@ -139327,6 +144159,7 @@ static int rtreeSqlInit(
appStmt[7] = &pRtree->pWriteParent;
appStmt[8] = &pRtree->pDeleteParent;
+ rc = rtreeQueryStat1(db, pRtree);
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
if( zSql ){
@@ -139681,7 +144514,10 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
}
#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -139719,7 +144555,7 @@ SQLITE_API int sqlite3_extension_init(
** * Implementations of the SQL scalar upper() and lower() functions
** for case mapping.
**
-** * Integration of ICU and SQLite collation seqences.
+** * Integration of ICU and SQLite collation sequences.
**
** * An implementation of the LIKE operator that uses ICU to
** provide case-independent matching.
@@ -140183,7 +145019,10 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
}
#if !SQLITE_CORE
-SQLITE_API int sqlite3_extension_init(
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+SQLITE_API int sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index e398838287..59b9570b85 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.7.17"
-#define SQLITE_VERSION_NUMBER 3007017
-#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
+#define SQLITE_VERSION "3.8.2"
+#define SQLITE_VERSION_NUMBER 3008002
+#define SQLITE_SOURCE_ID "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -370,7 +370,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** <ul>
** <li> The application must insure that the 1st parameter to sqlite3_exec()
** is a valid and open [database connection].
-** <li> The application must not close [database connection] specified by
+** <li> The application must not close the [database connection] specified by
** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running.
** <li> The application must not modify the SQL statement text passed into
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
@@ -447,7 +447,7 @@ SQLITE_API int sqlite3_exec(
** [sqlite3_extended_result_codes()] API.
**
** Some of the available extended result codes are listed here.
-** One may expect the number of extended result codes will be expand
+** One may expect the number of extended result codes will increase
** over time. Software that uses extended result codes should expect
** to see new result codes in future releases of SQLite.
**
@@ -478,11 +478,15 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
+#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
+#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
+#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -497,8 +501,10 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
+#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -907,6 +913,14 @@ struct sqlite3_io_methods {
** can be queried by passing in a pointer to a negative number. This
** file-control is used internally to implement [PRAGMA mmap_size].
**
+** <li>[[SQLITE_FCNTL_TRACE]]
+** The [SQLITE_FCNTL_TRACE] file control provides advisory information
+** to the VFS about what the higher layers of the SQLite stack are doing.
+** This file control is used by some VFS activity tracing [shims].
+** The argument is a zero-terminated string. Higher layers in the
+** SQLite stack may generate instances of this file control if
+** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
+**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -926,6 +940,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_BUSYHANDLER 15
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
+#define SQLITE_FCNTL_TRACE 19
/*
** CAPI3REF: Mutex Handle
@@ -1370,7 +1385,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0,
** that causes the corresponding memory allocation to fail.
**
-** The xInit method initializes the memory allocator. (For example,
+** The xInit method initializes the memory allocator. For example,
** it might allocate any require mutexes or initialize internal data
** structures. The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
@@ -1612,27 +1627,27 @@ struct sqlite3_mem_methods {
** function must be threadsafe. </dd>
**
** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd> This option takes a single argument of type int. If non-zero, then
+** <dd>^(This option takes a single argument of type int. If non-zero, then
** URI handling is globally enabled. If the parameter is zero, then URI handling
-** is globally disabled. If URI handling is globally enabled, all filenames
+** is globally disabled.)^ ^If URI handling is globally enabled, all filenames
** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
** specified as part of [ATTACH] commands are interpreted as URIs, regardless
** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
-** connection is opened. If it is globally disabled, filenames are
+** connection is opened. ^If it is globally disabled, filenames are
** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the
-** database connection is opened. By default, URI handling is globally
+** database connection is opened. ^(By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
-** [SQLITE_USE_URI] symbol defined.
+** [SQLITE_USE_URI] symbol defined.)^
**
** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd> This option takes a single integer argument which is interpreted as
+** <dd>^This option takes a single integer argument which is interpreted as
** a boolean in order to enable or disable the use of covering indices for
-** full table scans in the query optimizer. The default setting is determined
+** full table scans in the query optimizer. ^The default setting is determined
** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
** if that compile-time option is omitted.
** The ability to disable the use of covering indices for full table scans
** is because some incorrectly coded legacy applications might malfunction
-** malfunction when the optimization is enabled. Providing the ability to
+** when the optimization is enabled. Providing the ability to
** disable the optimization allows the older, buggy application code to work
** without change even with newer versions of SQLite.
**
@@ -1661,17 +1676,24 @@ struct sqlite3_mem_methods {
**
** [[SQLITE_CONFIG_MMAP_SIZE]]
** <dt>SQLITE_CONFIG_MMAP_SIZE
-** <dd>SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
+** <dd>^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values
** that are the default mmap size limit (the default setting for
** [PRAGMA mmap_size]) and the maximum allowed mmap size limit.
-** The default setting can be overridden by each database connection using
+** ^The default setting can be overridden by each database connection using
** either the [PRAGMA mmap_size] command, or by using the
-** [SQLITE_FCNTL_MMAP_SIZE] file control. The maximum allowed mmap size
+** [SQLITE_FCNTL_MMAP_SIZE] file control. ^(The maximum allowed mmap size
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
-** [SQLITE_MAX_MMAP_SIZE] compile-time option.
-** If either argument to this option is negative, then that argument is
+** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
+** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
+** <dd>^This option is only available if SQLite is compiled for Windows
+** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
+** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
** </dl>
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@@ -1696,6 +1718,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -1772,19 +1795,21 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
**
-** ^Each entry in an SQLite table has a unique 64-bit signed
+** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
+** has a unique 64-bit signed
** integer key called the [ROWID | "rowid"]. ^The rowid is always available
** as an undeclared column named ROWID, OID, or _ROWID_ as long as those
** names are not also used by explicitly declared columns. ^If
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^This routine returns the [rowid] of the most recent
-** successful [INSERT] into the database from the [database connection]
-** in the first argument. ^As of SQLite version 3.7.7, this routines
-** records the last insert rowid of both ordinary tables and [virtual tables].
-** ^If no successful [INSERT]s
-** have ever occurred on that database connection, zero is returned.
+** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
+** most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D.
+** ^Inserts into [WITHOUT ROWID] tables are not recorded.
+** ^If no successful [INSERT]s into rowid tables
+** have ever occurred on the database connection D,
+** then sqlite3_last_insert_rowid(D) returns zero.
**
** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
** method, then this routine will return the [rowid] of the inserted
@@ -2557,9 +2582,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
** interface is to keep a GUI updated during a large query.
**
** ^The parameter P is passed through as the only parameter to the
-** callback function X. ^The parameter N is the number of
+** callback function X. ^The parameter N is the approximate number of
** [virtual machine instructions] that are evaluated between successive
-** invocations of the callback X.
+** invocations of the callback X. ^If N is less than one then the progress
+** handler is disabled.
**
** ^Only a single progress handler may be defined at one time per
** [database connection]; setting a new progress handler cancels the
@@ -3093,7 +3119,6 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
-** the
** </li>
** </ol>
*/
@@ -3755,19 +3780,19 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
**
** <tr><td> NULL <td> INTEGER <td> Result is 0
** <tr><td> NULL <td> FLOAT <td> Result is 0.0
-** <tr><td> NULL <td> TEXT <td> Result is NULL pointer
-** <tr><td> NULL <td> BLOB <td> Result is NULL pointer
+** <tr><td> NULL <td> TEXT <td> Result is a NULL pointer
+** <tr><td> NULL <td> BLOB <td> Result is a NULL pointer
** <tr><td> INTEGER <td> FLOAT <td> Convert from integer to float
** <tr><td> INTEGER <td> TEXT <td> ASCII rendering of the integer
** <tr><td> INTEGER <td> BLOB <td> Same as INTEGER->TEXT
-** <tr><td> FLOAT <td> INTEGER <td> Convert from float to integer
+** <tr><td> FLOAT <td> INTEGER <td> [CAST] to INTEGER
** <tr><td> FLOAT <td> TEXT <td> ASCII rendering of the float
-** <tr><td> FLOAT <td> BLOB <td> Same as FLOAT->TEXT
-** <tr><td> TEXT <td> INTEGER <td> Use atoi()
-** <tr><td> TEXT <td> FLOAT <td> Use atof()
+** <tr><td> FLOAT <td> BLOB <td> [CAST] to BLOB
+** <tr><td> TEXT <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> TEXT <td> FLOAT <td> [CAST] to REAL
** <tr><td> TEXT <td> BLOB <td> No change
-** <tr><td> BLOB <td> INTEGER <td> Convert to TEXT then use atoi()
-** <tr><td> BLOB <td> FLOAT <td> Convert to TEXT then use atof()
+** <tr><td> BLOB <td> INTEGER <td> [CAST] to INTEGER
+** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
** </table>
** </blockquote>)^
@@ -3823,7 +3848,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
+** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
** [sqlite3_free()].
**
** ^(If a memory allocation error occurs during the evaluation of any
@@ -4179,41 +4204,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
**
-** The following two functions may be used by scalar SQL functions to
+** These functions may be used by (non-aggregate) SQL functions to
** associate metadata with argument values. If the same value is passed to
** multiple invocations of the same SQL function during query execution, under
-** some circumstances the associated metadata may be preserved. This may
-** be used, for example, to add a regular-expression matching scalar
-** function. The compiled version of the regular expression is stored as
-** metadata associated with the SQL value passed as the regular expression
-** pattern. The compiled regular expression can be reused on multiple
-** invocations of the same function so that the original pattern string
-** does not need to be recompiled on each invocation.
+** some circumstances the associated metadata may be preserved. An example
+** of where this might be useful is in a regular-expression matching
+** function. The compiled version of the regular expression can be stored as
+** metadata associated with the pattern string.
+** Then as long as the pattern string remains the same,
+** the compiled regular expression can be reused on multiple
+** invocations of the same function.
**
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function. ^If no metadata has been ever
-** been set for the Nth argument of the function, or if the corresponding
-** function parameter has changed since the meta-data was set,
-** then sqlite3_get_auxdata() returns a NULL pointer.
-**
-** ^The sqlite3_set_auxdata() interface saves the metadata
-** pointed to by its 3rd parameter as the metadata for the N-th
-** argument of the application-defined function. Subsequent
-** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed.
-** ^If it is not NULL, SQLite will invoke the destructor
-** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the metadata when the corresponding function parameter changes
-** or when the SQL statement completes, whichever comes first.
-**
-** SQLite is free to call the destructor and drop metadata on any
-** parameter of any function at any time. ^The only guarantee is that
-** the destructor will be called before the metadata is dropped.
+** value to the application-defined function. ^If there is no metadata
+** associated with the function argument, this sqlite3_get_auxdata() interface
+** returns a NULL pointer.
+**
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
+** argument of the application-defined function. ^Subsequent
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
+** NULL if the metadata has been discarded.
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
+** SQLite will invoke the destructor function X with parameter P exactly
+** once, when the metadata is discarded.
+** SQLite is free to discard the metadata at any time, including: <ul>
+** <li> when the corresponding function parameter changes, or
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
+** SQL statement, or
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
+** <li> during the original sqlite3_set_auxdata() call when a memory
+** allocation error occurs. </ul>)^
+**
+** Note the last bullet in particular. The destructor X in
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
+** should be called near the end of the function implementation and the
+** function implementation should not make any use of P after
+** sqlite3_set_auxdata() has been called.
**
** ^(In practice, metadata is preserved between function calls for
-** expressions that are constant at compile time. This includes literal
-** values and [parameters].)^
+** function parameters that are compile-time constants, including literal
+** values and [parameters] and expressions composed from the same.)^
**
** These routines must be called from the same thread in which
** the SQL function is running.
@@ -4518,6 +4551,11 @@ SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
+SQLITE_API int sqlite3_key_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The key */
+);
/*
** Change the key on an open database. If the current database is not
@@ -4531,6 +4569,11 @@ SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
+SQLITE_API int sqlite3_rekey_v2(
+ sqlite3 *db, /* Database to be rekeyed */
+ const char *zDbName, /* Name of the database */
+ const void *pKey, int nKey /* The new key */
+);
/*
** Specify the activation key for a SEE database. Unless
@@ -4782,12 +4825,13 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
-** to be invoked whenever a row is updated, inserted or deleted.
+** to be invoked whenever a row is updated, inserted or deleted in
+** a rowid table.
** ^Any callback set by a previous call to this function
** for the same database connection is overridden.
**
** ^The second argument is a pointer to the function to invoke when a
-** row is updated, inserted or deleted.
+** row is updated, inserted or deleted in a rowid table.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
@@ -4800,6 +4844,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
**
** ^(The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).)^
+** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
** is not invoked when duplication rows are deleted because of an
@@ -4881,8 +4926,8 @@ SQLITE_API int sqlite3_release_memory(int);
**
** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
** memory as possible from database connection D. Unlike the
-** [sqlite3_release_memory()] interface, this interface is effect even
-** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
+** [sqlite3_release_memory()] interface, this interface is in effect even
+** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
** omitted.
**
** See also: [sqlite3_release_memory()]
@@ -5116,11 +5161,24 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
** on the list of automatic extensions is a harmless no-op. ^No entry point
** will be called more than once for each database connection that is opened.
**
-** See also: [sqlite3_reset_auto_extension()].
+** See also: [sqlite3_reset_auto_extension()]
+** and [sqlite3_cancel_auto_extension()]
*/
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
/*
+** CAPI3REF: Cancel Automatic Extension Loading
+**
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
+** initialization routine X that was registered using a prior call to
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
+** routine returns 1 if initialization routine X was successfully
+** unregistered and it returns 0 if X was not on the list of initialization
+** routines.
+*/
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+
+/*
** CAPI3REF: Reset Automatic Extension Loading
**
** ^This interface disables all automatic extensions previously
@@ -5244,10 +5302,22 @@ struct sqlite3_module {
** the correct order to satisfy the ORDER BY clause so that no separate
** sorting step is required.
**
-** ^The estimatedCost value is an estimate of the cost of doing the
-** particular lookup. A full scan of a table with N entries should have
-** a cost of N. A binary search of a table of N entries should have a
-** cost of approximately log(N).
+** ^The estimatedCost value is an estimate of the cost of a particular
+** strategy. A cost of N indicates that the cost of the strategy is similar
+** to a linear scan of an SQLite table with N rows. A cost of log(N)
+** indicates that the expense of the operation is similar to that of a
+** binary search on a unique indexed field of an SQLite table with N rows.
+**
+** ^The estimatedRows value is an estimate of the number of rows that
+** will be returned by the strategy.
+**
+** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
+** structure for SQLite version 3.8.2. If a virtual table extension is
+** used with an SQLite version earlier than 3.8.2, the results of attempting
+** to read or write the estimatedRows field are undefined (but are likely
+** to included crashing the application). The estimatedRows field should
+** therefore only be used if [sqlite3_libversion_number()] returns a
+** value greater than or equal to 3008002.
*/
struct sqlite3_index_info {
/* Inputs */
@@ -5272,7 +5342,9 @@ struct sqlite3_index_info {
char *idxStr; /* String, possibly obtained from sqlite3_malloc */
int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */
int orderByConsumed; /* True if output is already ordered */
- double estimatedCost; /* Estimated cost of using this index */
+ double estimatedCost; /* Estimated cost of using this index */
+ /* Fields below are only available in SQLite 3.8.2 and later */
+ sqlite3_int64 estimatedRows; /* Estimated number of rows returned */
};
/*
@@ -5476,6 +5548,9 @@ typedef struct sqlite3_blob sqlite3_blob;
** interface. Use the [UPDATE] SQL command to change the size of a
** blob.
**
+** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
+** table. Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
+**
** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
** and the built-in [zeroblob] SQL function can be used, if desired,
** to create an empty, zero-filled blob in which to read or write using
@@ -5999,7 +6074,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
-#define SQLITE_TESTCTRL_LAST 19
+#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
+#define SQLITE_TESTCTRL_LAST 20
/*
** CAPI3REF: SQLite Runtime Status
@@ -6232,6 +6308,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
** </dd>
+**
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
+** <dd>This parameter returns zero for the current value if and only if
+** all foreign key constraints (deferred or immediate) have been
+** resolved.)^ ^The highwater mark is always 0.
+** </dd>
** </dl>
*/
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
@@ -6244,7 +6326,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
#define SQLITE_DBSTATUS_CACHE_HIT 7
#define SQLITE_DBSTATUS_CACHE_MISS 8
#define SQLITE_DBSTATUS_CACHE_WRITE 9
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
/*
@@ -6298,11 +6381,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
** A non-zero value in this counter may indicate an opportunity to
** improvement performance by adding permanent indices that do not
** need to be reinitialized each time the statement is run.</dd>
+**
+** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
+** <dd>^This is the number of virtual machine operations executed
+** by the prepared statement if that number is less than or equal
+** to 2147483647. The number of virtual machine operations can be
+** used as a proxy for the total work done by the prepared statement.
+** If the number of virtual machine operations exceeds 2147483647
+** then the value returned by this statement status code is undefined.
+** </dd>
** </dl>
*/
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
#define SQLITE_STMTSTATUS_SORT 2
#define SQLITE_STMTSTATUS_AUTOINDEX 3
+#define SQLITE_STMTSTATUS_VM_STEP 4
/*
** CAPI3REF: Custom Page Cache Object
@@ -7181,7 +7274,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
#endif
-#endif
+#endif /* _SQLITE3_H_ */
/*
** 2010 August 30
diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri
index d437c6b8b6..21a3e78e1c 100644
--- a/src/3rdparty/xkbcommon.pri
+++ b/src/3rdparty/xkbcommon.pri
@@ -1,7 +1,7 @@
QMAKE_CFLAGS += -std=gnu99 -w
INCLUDEPATH += $$PWD/xkbcommon $$PWD/xkbcommon/src $$PWD/xkbcommon/src/xkbcomp
-DEFINES += DFLT_XKB_CONFIG_ROOT='\\"/usr/share/X11/xkb\\"'
+DEFINES += DFLT_XKB_CONFIG_ROOT='\\"$$QMAKE_X11_PREFIX/share/X11/xkb\\"'
### RMLVO names can be overwritten with environmental variables (See libxkbcommon documentation)
DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"'
diff --git a/src/3rdparty/zlib_dependency.pri b/src/3rdparty/zlib_dependency.pri
index 029bb9e637..0bcb9f9e5e 100644
--- a/src/3rdparty/zlib_dependency.pri
+++ b/src/3rdparty/zlib_dependency.pri
@@ -1,6 +1,6 @@
# zlib dependency satisfied by bundled 3rd party zlib or system zlib
contains(QT_CONFIG, system-zlib) {
- if(unix|win32-g++*):LIBS_PRIVATE += -lz
+ if(unix|mingw):LIBS_PRIVATE += -lz
else {
isEmpty(ZLIB_LIBS): LIBS += zdll.lib
else: LIBS += $$ZLIB_LIBS
diff --git a/src/android/jar/AndroidManifest.xml b/src/android/jar/AndroidManifest.xml
index ebc6fcfea7..cef88f7f19 100644
--- a/src/android/jar/AndroidManifest.xml
+++ b/src/android/jar/AndroidManifest.xml
@@ -1,4 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="org.qtproject.qt5.android">
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
+ <uses-sdk android:minSdkVersion="9" />
</manifest>
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index d8c560933f..4b80d68761 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Android port of the Qt Toolkit.
@@ -44,6 +44,7 @@ package org.qtproject.qt5.android;
import android.app.Activity;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
@@ -73,6 +74,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
public class QtActivityDelegate
@@ -85,6 +87,7 @@ public class QtActivityDelegate
private Method m_super_onKeyDown = null;
private Method m_super_onKeyUp = null;
private Method m_super_onConfigurationChanged = null;
+ private Method m_super_onActivityResult = null;
private static final String NATIVE_LIBRARIES_KEY = "native.libraries";
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
@@ -105,7 +108,8 @@ public class QtActivityDelegate
private int m_lastChar = 0;
private boolean m_fullScreen = false;
private boolean m_started = false;
- private QtSurface m_surface = null;
+ private HashMap<Integer, QtSurface> m_surfaces = null;
+ private HashMap<Integer, View> m_nativeViews = null;
private QtLayout m_layout = null;
private QtEditText m_editText = null;
private InputMethodManager m_imm = null;
@@ -116,21 +120,6 @@ public class QtActivityDelegate
public boolean m_backKeyPressedSent = false;
- public QtLayout getQtLayout()
- {
- return m_layout;
- }
-
- public QtSurface getQtSurface()
- {
- return m_surface;
- }
-
- public void redrawWindow(int left, int top, int right, int bottom)
- {
- m_surface.drawBitmap(new Rect(left, top, right, bottom));
- }
-
public void setFullScreen(boolean enterFullScreen)
{
if (m_fullScreen == enterFullScreen)
@@ -175,6 +164,7 @@ public class QtActivityDelegate
}
}
}
+ m_layout.requestLayout();
}
@@ -233,7 +223,8 @@ public class QtActivityDelegate
{
if (m_imm == null)
return;
- if (height > m_surface.getHeight()*2/3)
+
+ if (height > m_layout.getHeight() * 2 / 3)
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
else
m_activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
@@ -330,7 +321,7 @@ public class QtActivityDelegate
{
if (m_imm == null)
return;
- m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0, new ResultReceiver( new Handler()){
+ m_imm.hideSoftInputFromWindow(m_editText.getWindowToken(), 0, new ResultReceiver(new Handler()) {
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
@@ -358,7 +349,7 @@ public class QtActivityDelegate
if (size < 36 || size > 512) { // check size sanity
DisplayMetrics metrics = new DisplayMetrics();
a.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- size = metrics.densityDpi/10*3;
+ size = metrics.densityDpi / 10 * 3;
if (size < 36)
size = 36;
@@ -421,6 +412,7 @@ public class QtActivityDelegate
m_super_onKeyDown = m_activity.getClass().getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class);
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
+ m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
} catch (Exception e) {
e.printStackTrace();
return false;
@@ -626,13 +618,13 @@ public class QtActivityDelegate
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
}
- if (null == m_surface)
+ if (null == m_surfaces)
onCreate(null);
String nativeLibraryDir = QtNativeLibrariesDir.nativeLibrariesDir(m_activity);
- m_surface.applicationStarted( QtNative.startApplication(m_applicationParameters,
- m_environmentVariables,
- m_mainLib,
- nativeLibraryDir));
+ QtNative.startApplication(m_applicationParameters,
+ m_environmentVariables,
+ m_mainLib,
+ nativeLibraryDir);
m_started = true;
return true;
} catch (Exception e) {
@@ -657,14 +649,13 @@ public class QtActivityDelegate
metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
}
m_layout = new QtLayout(m_activity);
- m_surface = new QtSurface(m_activity, 0);
m_editText = new QtEditText(m_activity, this);
m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE);
- m_layout.addView(m_surface, 0);
+ m_surfaces = new HashMap<Integer, QtSurface>();
+ m_nativeViews = new HashMap<Integer, View>();
m_activity.setContentView(m_layout,
- new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT));
- m_layout.bringChildToFront(m_surface);
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
m_activity.registerForContextMenu(m_layout);
int orientation = m_activity.getResources().getConfiguration().orientation;
@@ -704,18 +695,6 @@ public class QtActivityDelegate
}
}
- public void onRestoreInstanceState(Bundle savedInstanceState)
- {
- try {
- m_super_onRestoreInstanceState.invoke(m_activity, savedInstanceState);
- } catch (Exception e) {
- e.printStackTrace();
- }
- m_started = savedInstanceState.getBoolean("Started");
- if (m_started)
- m_surface.applicationStarted(true);
- }
-
public void onPause()
{
QtNative.updateApplicationState(ApplicationInactive);
@@ -744,6 +723,18 @@ public class QtActivityDelegate
}
}
+ public void onActivityResult(int requestCode, int resultCode, Intent data)
+ {
+ try {
+ m_super_onActivityResult.invoke(m_activity, requestCode, resultCode, data);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ QtNative.onActivityResult(requestCode, resultCode, data);
+ }
+
+
public void onStop()
{
QtNative.updateApplicationState(ApplicationSuspended);
@@ -768,6 +759,19 @@ public class QtActivityDelegate
}
outState.putBoolean("FullScreen", m_fullScreen);
outState.putBoolean("Started", m_started);
+ // It should never
+ }
+
+ public void onRestoreInstanceState(Bundle savedInstanceState)
+ {
+ try {
+ m_super_onRestoreInstanceState.invoke(m_activity, savedInstanceState);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ m_started = savedInstanceState.getBoolean("Started");
+ // FIXME restore all surfaces
+
}
public boolean onKeyDown(int keyCode, KeyEvent event)
@@ -967,4 +971,64 @@ public class QtActivityDelegate
}
}
}
+
+ public void insertNativeView(int id, View view, int x, int y, int w, int h) {
+ if (m_nativeViews.containsKey(id))
+ m_layout.removeView(m_nativeViews.remove(id));
+
+ if (w < 0 || h < 0) {
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ } else {
+ view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ }
+
+ m_layout.addView(view);
+ m_layout.bringChildToFront(view);
+ m_nativeViews.put(id, view);
+ }
+
+ public void createSurface(int id, boolean onTop, int x, int y, int w, int h) {
+ if (m_surfaces.containsKey(id))
+ m_layout.removeView(m_surfaces.remove(id));
+
+ QtSurface surface = new QtSurface(m_activity, id, onTop);
+ if (w < 0 || h < 0) {
+ surface.setLayoutParams( new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ } else {
+ surface.setLayoutParams( new QtLayout.LayoutParams(w, h, x, y));
+ }
+
+ m_layout.addView(surface);
+ if (onTop)
+ m_layout.bringChildToFront(surface);
+ m_surfaces.put(id, surface);
+ }
+
+ public void setSurfaceGeometry(int id, int x, int y, int w, int h) {
+ if (m_surfaces.containsKey(id)) {
+ QtSurface surface = m_surfaces.get(id);
+ surface.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ } else if (m_nativeViews.containsKey(id)) {
+ View view = m_nativeViews.get(id);
+ view.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ m_layout.bringChildToFront(view);
+ } else {
+ Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
+ return;
+ }
+
+ m_layout.requestLayout();
+ }
+
+ public void destroySurface(int id) {
+ if (m_surfaces.containsKey(id)) {
+ m_layout.removeView(m_surfaces.remove(id));
+ } else if (m_nativeViews.containsKey(id)) {
+ m_layout.removeView(m_nativeViews.remove(id));
+ } else {
+ Log.e(QtNative.QtTAG, "Surface " + id +" not found!");
+ }
+ }
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
index 043dab5ce8..058b10750f 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtLayout.java
@@ -42,8 +42,10 @@
package org.qtproject.qt5.android;
+import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
@@ -65,6 +67,15 @@ public class QtLayout extends ViewGroup
}
@Override
+ protected void onSizeChanged (int w, int h, int oldw, int oldh)
+ {
+ DisplayMetrics metrics = new DisplayMetrics();
+ ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
+ QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
+ metrics.heightPixels, w, h, metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int count = getChildCount();
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 57f3642b56..9b716f74e5 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Android port of the Qt Toolkit.
@@ -55,6 +55,7 @@ import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MotionEvent;
+import android.view.View;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
@@ -250,29 +251,10 @@ public class QtNative
}
}
- public static void pauseApplication()
- {
- synchronized (m_mainActivityMutex) {
- if (m_started)
- pauseQtApp();
- }
- }
- public static void resumeApplication()
- {
- synchronized (m_mainActivityMutex) {
- if (m_started) {
- resumeQtApp();
- updateWindow();
- }
- }
- }
// application methods
public static native void startQtApplication(String params, String env);
- public static native void startQtApp(String params, String env);
- public static native void pauseQtApp();
- public static native void resumeQtApp();
public static native boolean startQtAndroidPlugin();
public static native void quitQtAndroidPlugin();
public static native void terminateQt();
@@ -283,16 +265,6 @@ public class QtNative
m_activity.finish();
}
- private static void redrawSurface(final int left, final int top, final int right, final int bottom )
- {
- runAction(new Runnable() {
- @Override
- public void run() {
- m_activityDelegate.redrawWindow(left, top, right, bottom);
- }
- });
- }
-
//@ANDROID-9
static private int getAction(int index, MotionEvent event)
{
@@ -539,6 +511,46 @@ public class QtNative
return certificateArray;
}
+ private static void createSurface(final int id, final boolean onTop, final int x, final int y, final int w, final int h)
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activityDelegate.createSurface(id, onTop, x, y, w, h);
+ }
+ });
+ }
+
+ private static void insertNativeView(final int id, final View view, final int x, final int y, final int w, final int h)
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activityDelegate.insertNativeView(id, view, x, y, w, h);
+ }
+ });
+ }
+
+ private static void setSurfaceGeometry(final int id, final int x, final int y, final int w, final int h)
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activityDelegate.setSurfaceGeometry(id, x, y, w, h);
+ }
+ });
+ }
+
+ private static void destroySurface(final int id)
+ {
+ runAction(new Runnable() {
+ @Override
+ public void run() {
+ m_activityDelegate.destroySurface(id);
+ }
+ });
+ }
+
// screen methods
public static native void setDisplayMetrics(int screenWidthPixels,
int screenHeightPixels,
@@ -567,10 +579,7 @@ public class QtNative
// keyboard methods
// surface methods
- public static native void destroySurface();
- public static native void setSurface(Object surface);
- public static native void lockSurface();
- public static native void unlockSurface();
+ public static native void setSurface(int id, Object surface, int w, int h);
// surface methods
// window methods
@@ -589,4 +598,7 @@ public class QtNative
public static native boolean onContextItemSelected(int itemId, boolean checked);
public static native void onContextMenuClosed(Menu menu);
// menu methods
+
+ // activity methods
+ public static native void onActivityResult(int requestCode, int resultCode, Intent data);
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index c499dc3898..1454c30638 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Android port of the Qt Toolkit.
@@ -44,11 +44,7 @@ package org.qtproject.qt5.android;
import android.app.Activity;
import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Rect;
import android.graphics.PixelFormat;
-import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
@@ -60,61 +56,34 @@ import java.lang.reflect.Method;
public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
{
- private Bitmap m_bitmap = null;
- private boolean m_started = false;
- private boolean m_usesGL = false;
private GestureDetector m_gestureDetector;
private Object m_accessibilityDelegate = null;
- public QtSurface(Context context, int id)
+ public QtSurface(Context context, int id, boolean onTop)
{
super(context);
setFocusable(false);
setFocusableInTouchMode(false);
-
+ setZOrderMediaOverlay(onTop);
getHolder().addCallback(this);
- getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
+ getHolder().setFormat(PixelFormat.RGBA_8888);
+ if (android.os.Build.VERSION.SDK_INT < 11)
+ getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
+
setId(id);
m_gestureDetector =
new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
public void onLongPress(MotionEvent event) {
- if (!m_started)
- return;
QtNative.longPress(getId(), (int) event.getX(), (int) event.getY());
}
});
m_gestureDetector.setIsLongpressEnabled(true);
}
- public void applicationStarted(boolean usesGL)
- {
- m_started = true;
- m_usesGL = usesGL;
- if (getWidth() < 1 || getHeight() < 1)
- return;
- if (m_usesGL) {
- QtNative.setSurface(getHolder().getSurface());
- } else {
- QtNative.lockSurface();
- QtNative.setSurface(null);
- m_bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.RGB_565);
- QtNative.setSurface(m_bitmap);
- QtNative.unlockSurface();
- }
- }
-
@Override
public void surfaceCreated(SurfaceHolder holder)
{
- DisplayMetrics metrics = new DisplayMetrics();
- ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
- QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
- metrics.heightPixels, getWidth(), getHeight(), metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
-
- if (m_usesGL)
- holder.setFormat(PixelFormat.RGBA_8888);
-
-
+ QtNative.setSurface(getId(), holder.getSurface(), getWidth(), getHeight());
// Initialize Accessibility
// The accessibility code depends on android API level 16, so dynamically resolve it
if (android.os.Build.VERSION.SDK_INT >= 16) {
@@ -158,71 +127,21 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
- if (width<1 || height<1)
- return;
-
- DisplayMetrics metrics = new DisplayMetrics();
- ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
- QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
- metrics.heightPixels,
- width,
- height,
- metrics.xdpi,
- metrics.ydpi,
- metrics.scaledDensity);
-
- if (!m_started)
+ if (width < 1 || height < 1)
return;
- if (m_usesGL) {
- QtNative.setSurface(holder.getSurface());
- } else {
- QtNative.lockSurface();
- QtNative.setSurface(null);
- m_bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
- QtNative.setSurface(m_bitmap);
- QtNative.unlockSurface();
- QtNative.updateWindow();
- }
+ QtNative.setSurface(getId(), holder.getSurface(), width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
- if (m_usesGL) {
- QtNative.destroySurface();
- } else {
- if (!m_started)
- return;
-
- QtNative.lockSurface();
- QtNative.setSurface(null);
- QtNative.unlockSurface();
- }
- }
-
- public void drawBitmap(Rect rect)
- {
- if (!m_started)
- return;
- QtNative.lockSurface();
- if (null != m_bitmap) {
- try {
- Canvas cv = getHolder().lockCanvas(rect);
- cv.drawBitmap(m_bitmap, rect, rect, null);
- getHolder().unlockCanvasAndPost(cv);
- } catch (Exception e) {
- Log.e(QtNative.QtTAG, "Can't create main activity", e);
- }
- }
- QtNative.unlockSurface();
+ QtNative.setSurface(getId(), null, 0, 0);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
- if (!m_started)
- return false;
QtNative.sendTouchEvent(event, getId());
m_gestureDetector.onTouchEvent(event);
return true;
@@ -231,8 +150,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
@Override
public boolean onTrackballEvent(MotionEvent event)
{
- if (!m_started)
- return false;
QtNative.sendTrackballEvent(event, getId());
return true;
}
diff --git a/src/angle/patches/0012-ANGLE-Support-WinRT.patch b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
new file mode 100644
index 0000000000..8a5b96c7c0
--- /dev/null
+++ b/src/angle/patches/0012-ANGLE-Support-WinRT.patch
@@ -0,0 +1,1131 @@
+From 67c318c7b9c6d95d3170d11956dbec56494511ca Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Tue, 1 Oct 2013 09:43:29 +0300
+Subject: [PATCH] ANGLE: Support WinRT
+
+This enables EGL for WinRT's native types, and adjusts some codepaths
+to accommodate differences in between desktop Windows and WinRT.
+
+- WinRT native handles added to eglplatform.h
+- References to native handles in libEGL/libGLESv2 follow eglplatform.h
+- D3D 11.1 structures and methods used when necessary
+- TLS replaced with thread attribute
+- LocalAlloc/Free replaced with Heap API
+
+Change-Id: Ia90377e700d335a1c569c2145008dd4b0dfd84d3
+Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
+---
+ src/3rdparty/angle/include/EGL/eglplatform.h | 10 ++-
+ src/3rdparty/angle/src/compiler/osinclude.h | 35 ++++------
+ src/3rdparty/angle/src/compiler/ossource_posix.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_win.cpp | 8 +++
+ src/3rdparty/angle/src/compiler/ossource_winrt.cpp | 75 ++++++++++++++++++++++
+ src/3rdparty/angle/src/libEGL/Display.cpp | 8 ++-
+ src/3rdparty/angle/src/libEGL/Display.h | 4 +-
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 35 +++++++++-
+ src/3rdparty/angle/src/libEGL/Surface.h | 7 +-
+ src/3rdparty/angle/src/libEGL/libEGL.cpp | 4 +-
+ src/3rdparty/angle/src/libEGL/main.cpp | 40 ++++++++++--
+ src/3rdparty/angle/src/libGLESv2/main.cpp | 39 +++++++++--
+ src/3rdparty/angle/src/libGLESv2/precompiled.h | 15 +++++
+ .../angle/src/libGLESv2/renderer/Renderer.cpp | 23 ++++---
+ .../angle/src/libGLESv2/renderer/Renderer.h | 27 +++++++-
+ .../angle/src/libGLESv2/renderer/Renderer11.cpp | 10 ++-
+ .../angle/src/libGLESv2/renderer/Renderer11.h | 2 +-
+ .../angle/src/libGLESv2/renderer/SwapChain.h | 4 +-
+ .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 29 +++++++--
+ .../angle/src/libGLESv2/renderer/SwapChain11.h | 2 +-
+ src/3rdparty/angle/src/libGLESv2/utilities.cpp | 53 +++++++++++++++
+ src/angle/src/common/common.pri | 2 +-
+ src/angle/src/compiler/translator_common.pro | 7 +-
+ src/angle/src/config.pri | 5 +-
+ 24 files changed, 386 insertions(+), 66 deletions(-)
+ create mode 100644 src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+
+diff --git a/src/3rdparty/angle/include/EGL/eglplatform.h b/src/3rdparty/angle/include/EGL/eglplatform.h
+index 34283f2..eb15ae5 100644
+--- a/src/3rdparty/angle/include/EGL/eglplatform.h
++++ b/src/3rdparty/angle/include/EGL/eglplatform.h
+@@ -67,7 +67,15 @@
+ * implementations.
+ */
+
+-#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) /* Windows Runtime */
++
++struct IUnknown;
++
++typedef int EGLNativeDisplayType;
++typedef void *EGLNativePixmapType;
++typedef IUnknown *EGLNativeWindowType;
++
++#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN 1
+ #endif
+diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
+index d8bb1a7..60177d5 100644
+--- a/src/3rdparty/angle/src/compiler/osinclude.h
++++ b/src/3rdparty/angle/src/compiler/osinclude.h
+@@ -13,27 +13,26 @@
+ //
+
+ #if defined(_WIN32) || defined(_WIN64)
++#define STRICT
++#define VC_EXTRALEAN 1
++#include <windows.h>
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#else
+ #define ANGLE_OS_WIN
++#endif
+ #elif defined(__APPLE__) || defined(__linux__) || \
+ defined(__FreeBSD__) || defined(__OpenBSD__) || \
+ defined(__sun) || defined(ANDROID) || \
+ defined(__GLIBC__) || defined(__GNU__) || \
+ defined(__QNX__)
+ #define ANGLE_OS_POSIX
+-#else
+-#error Unsupported platform.
+-#endif
+-
+-#if defined(ANGLE_OS_WIN)
+-#define STRICT
+-#define VC_EXTRALEAN 1
+-#include <windows.h>
+-#elif defined(ANGLE_OS_POSIX)
+ #include <pthread.h>
+ #include <semaphore.h>
+ #include <errno.h>
+-#endif // ANGLE_OS_WIN
+-
++#else
++#error Unsupported platform.
++#endif
+
+ #include "compiler/debug.h"
+
+@@ -43,23 +42,17 @@
+ #if defined(ANGLE_OS_WIN)
+ typedef DWORD OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
++#elif defined(ANGLE_OS_WINRT)
++typedef size_t OS_TLSIndex;
++#define OS_INVALID_TLS_INDEX ((DWORD)0xFFFFFF)
+ #elif defined(ANGLE_OS_POSIX)
+ typedef pthread_key_t OS_TLSIndex;
+ #define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
+ #endif // ANGLE_OS_WIN
+
+ OS_TLSIndex OS_AllocTLSIndex();
++void *OS_GetTLSValue(OS_TLSIndex nIndex);
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+ bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
+
+-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
+-{
+- ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+-#if defined(ANGLE_OS_WIN)
+- return TlsGetValue(nIndex);
+-#elif defined(ANGLE_OS_POSIX)
+- return pthread_getspecific(nIndex);
+-#endif // ANGLE_OS_WIN
+-}
+-
+ #endif // __OSINCLUDE_H
+diff --git a/src/3rdparty/angle/src/compiler/ossource_posix.cpp b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+index 1e1e699..35510c1 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_posix.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_posix.cpp
+@@ -33,6 +33,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return pthread_getspecific(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_win.cpp b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+index 89922fe..708a1ad 100644
+--- a/src/3rdparty/angle/src/compiler/ossource_win.cpp
++++ b/src/3rdparty/angle/src/compiler/ossource_win.cpp
+@@ -29,6 +29,14 @@ OS_TLSIndex OS_AllocTLSIndex()
+ }
+
+
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++
++ return TlsGetValue(nIndex);
++}
++
++
+ bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+ {
+ if (nIndex == OS_INVALID_TLS_INDEX) {
+diff --git a/src/3rdparty/angle/src/compiler/ossource_winrt.cpp b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+new file mode 100644
+index 0000000..84443ab
+--- /dev/null
++++ b/src/3rdparty/angle/src/compiler/ossource_winrt.cpp
+@@ -0,0 +1,75 @@
++//
++// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++//
++
++#include "compiler/osinclude.h"
++//
++// This file contains contains Windows Runtime specific functions
++//
++
++#if !defined(ANGLE_OS_WINRT)
++#error Trying to build a WinRT specific file in a non-WinRT build.
++#endif
++
++#include <vector>
++
++
++//
++// Thread Local Storage Operations
++//
++__declspec(thread) std::vector<void *> *tls = nullptr;
++__declspec(thread) std::vector<OS_TLSIndex> *freeIndices = nullptr;
++
++OS_TLSIndex OS_AllocTLSIndex()
++{
++ if (!tls)
++ tls = new std::vector<void*>;
++
++ if (freeIndices && !freeIndices->empty()) {
++ OS_TLSIndex index = freeIndices->back();
++ freeIndices->pop_back();
++ return index;
++ } else {
++ tls->push_back(nullptr);
++ return tls->size() - 1;
++ }
++}
++
++
++void *OS_GetTLSValue(OS_TLSIndex nIndex)
++{
++ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
++ ASSERT(tls);
++
++ return tls->at(nIndex);
++}
++
++
++bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ tls->at(nIndex) = lpvValue;
++ return true;
++}
++
++
++bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
++{
++ if (!tls || nIndex >= tls->size() || nIndex == OS_INVALID_TLS_INDEX) {
++ ASSERT(0 && "OS_SetTLSValue(): Invalid TLS Index");
++ return false;
++ }
++
++ if (!freeIndices)
++ freeIndices = new std::vector<OS_TLSIndex>;
++
++ freeIndices->push_back(nIndex);
++
++ return true;
++}
+diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
+index a382c3b..14973af 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.cpp
++++ b/src/3rdparty/angle/src/libEGL/Display.cpp
+@@ -186,7 +186,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
+
+
+
+-EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
++EGLSurface Display::createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList)
+ {
+ const Config *configuration = mConfigSet.get(config);
+ EGLint postSubBufferSupported = EGL_FALSE;
+@@ -456,7 +456,7 @@ bool Display::isValidSurface(egl::Surface *surface)
+ return mSurfaceSet.find(surface) != mSurfaceSet.end();
+ }
+
+-bool Display::hasExistingWindowSurface(HWND window)
++bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
+ {
+ for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ {
+@@ -471,7 +471,6 @@ bool Display::hasExistingWindowSurface(HWND window)
+
+ void Display::initExtensionString()
+ {
+- HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ bool shareHandleSupported = mRenderer->getShareHandleSupport();
+
+ mExtensionString = "";
+@@ -487,10 +486,13 @@ void Display::initExtensionString()
+
+ mExtensionString += "EGL_ANGLE_query_surface_pointer ";
+
++#if !defined(ANGLE_OS_WINRT)
++ HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ if (swiftShader)
+ {
+ mExtensionString += "EGL_ANGLE_software_display ";
+ }
++#endif
+
+ if (shareHandleSupported)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
+index 58c3940..5d55410 100644
+--- a/src/3rdparty/angle/src/libEGL/Display.h
++++ b/src/3rdparty/angle/src/libEGL/Display.h
+@@ -40,7 +40,7 @@ class Display
+ bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
+ bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
+
+- EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
++ EGLSurface createWindowSurface(EGLNativeWindowType window, EGLConfig config, const EGLint *attribList);
+ EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
+ EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+
+@@ -51,7 +51,7 @@ class Display
+ bool isValidConfig(EGLConfig config);
+ bool isValidContext(gl::Context *context);
+ bool isValidSurface(egl::Surface *surface);
+- bool hasExistingWindowSurface(HWND window);
++ bool hasExistingWindowSurface(EGLNativeWindowType window);
+
+ rx::Renderer *getRenderer() { return mRenderer; };
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index b47a7bc..abc6d7d 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -20,10 +20,15 @@
+ #include "libEGL/main.h"
+ #include "libEGL/Display.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <windows.foundation.h>
++#include <windows.ui.core.h>
++#endif
++
+ namespace egl
+ {
+
+-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
++Surface::Surface(Display *display, const Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported)
+ : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
+ {
+ mRenderer = mDisplay->getRenderer();
+@@ -96,6 +101,7 @@ bool Surface::resetSwapChain()
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+@@ -107,6 +113,14 @@ bool Surface::resetSwapChain()
+
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ width = windowRect.Width;
++ height = windowRect.Height;
++#endif
+ }
+ else
+ {
+@@ -226,7 +240,7 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+ return true;
+ }
+
+-HWND Surface::getWindowHandle()
++EGLNativeWindowType Surface::getWindowHandle()
+ {
+ return mWindow;
+ }
+@@ -235,6 +249,7 @@ HWND Surface::getWindowHandle()
+ #define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+ #define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+
++#if !defined(ANGLE_OS_WINRT)
+ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
+ {
+ if (message == WM_SIZE)
+@@ -248,9 +263,13 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+ }
++#endif
+
+ void Surface::subclassWindow()
+ {
++#if defined(ANGLE_OS_WINRT)
++ mWindowSubclassed = false;
++#else
+ if (!mWindow)
+ {
+ return;
+@@ -274,10 +293,12 @@ void Surface::subclassWindow()
+ SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
++#endif
+ }
+
+ void Surface::unsubclassWindow()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ if(!mWindowSubclassed)
+ {
+ return;
+@@ -300,10 +321,12 @@ void Surface::unsubclassWindow()
+ RemoveProp(mWindow, kSurfaceProperty);
+ RemoveProp(mWindow, kParentWndProc);
+ mWindowSubclassed = false;
++#endif
+ }
+
+ bool Surface::checkForOutOfDateSwapChain()
+ {
++#if !defined(ANGLE_OS_WINRT)
+ RECT client;
+ if (!GetClientRect(getWindowHandle(), &client))
+ {
+@@ -314,6 +337,14 @@ bool Surface::checkForOutOfDateSwapChain()
+ // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
+ int clientWidth = client.right - client.left;
+ int clientHeight = client.bottom - client.top;
++#else
++ ABI::Windows::Foundation::Rect windowRect;
++ ABI::Windows::UI::Core::ICoreWindow *window;
++ ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ window->get_Bounds(&windowRect);
++ int clientWidth = windowRect.Width;
++ int clientHeight = windowRect.Height;
++#endif
+ bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+
+ if (mSwapIntervalDirty)
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.h b/src/3rdparty/angle/src/libEGL/Surface.h
+index 938b800..ae9a380 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.h
++++ b/src/3rdparty/angle/src/libEGL/Surface.h
+@@ -15,6 +15,7 @@
+ #include <EGL/egl.h>
+
+ #include "common/angleutils.h"
++#include "windows.h"
+
+ namespace gl
+ {
+@@ -34,7 +35,7 @@ class Config;
+ class Surface
+ {
+ public:
+- Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported);
++ Surface(Display *display, const egl::Config *config, EGLNativeWindowType window, EGLint postSubBufferSupported);
+ Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget);
+
+ ~Surface();
+@@ -43,7 +44,7 @@ class Surface
+ void release();
+ bool resetSwapChain();
+
+- HWND getWindowHandle();
++ EGLNativeWindowType getWindowHandle();
+ bool swap();
+ bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height);
+
+@@ -79,7 +80,7 @@ private:
+ bool resetSwapChain(int backbufferWidth, int backbufferHeight);
+ bool swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+
+- const HWND mWindow; // Window that the surface is created for.
++ const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
+ const egl::Config *mConfig; // EGL config surface was created with
+ EGLint mHeight; // Height of surface
+diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+index 6e10c39..5bcb5d5 100644
+--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
++++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
+@@ -308,14 +308,16 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
+ return EGL_NO_SURFACE;
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ HWND window = (HWND)win;
+
+ if (!IsWindow(window))
+ {
+ return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ }
++#endif
+
+- return display->createWindowSurface(window, config, attrib_list);
++ return display->createWindowSurface(win, config, attrib_list);
+ }
+ catch(std::bad_alloc&)
+ {
+diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
+index 7dea5fc..964b4b2 100644
+--- a/src/3rdparty/angle/src/libEGL/main.cpp
++++ b/src/3rdparty/angle/src/libEGL/main.cpp
+@@ -1,3 +1,4 @@
++#include "../libGLESv2/precompiled.h"
+ //
+ // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -12,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace egl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -35,22 +42,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ }
+ #endif
+
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- egl::Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->error = EGL_SUCCESS;
+ current->API = EGL_OPENGL_ES_API;
+ current->display = EGL_NO_DISPLAY;
+@@ -61,24 +71,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ egl::Current *current = egl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -95,7 +116,16 @@ namespace egl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static Current curr = { EGL_SUCCESS, EGL_OPENGL_ES_API, EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE };
+diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
+index 730a6ac..defdf35 100644
+--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
+@@ -13,7 +13,13 @@
+
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
++#if !defined(ANGLE_OS_WINRT)
+ static DWORD currentTLS = TLS_OUT_OF_INDEXES;
++#else
++static __declspec(thread) void *currentTLS = 0;
++#endif
++
++namespace gl { Current *getCurrent(); }
+
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+@@ -21,22 +27,25 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ {
+ case DLL_PROCESS_ATTACH:
+ {
++#if !defined(ANGLE_OS_WINRT)
+ currentTLS = TlsAlloc();
+
+ if (currentTLS == TLS_OUT_OF_INDEXES)
+ {
+ return FALSE;
+ }
++#endif
+ }
+ // Fall throught to initialize index
+ case DLL_THREAD_ATTACH:
+ {
+- gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ TlsSetValue(currentTLS, current);
+-
++#endif
+ current->context = NULL;
+ current->display = NULL;
+ }
+@@ -44,24 +53,35 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ break;
+ case DLL_THREAD_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++#endif
+ }
+ }
+ break;
+ case DLL_PROCESS_DETACH:
+ {
+- void *current = TlsGetValue(currentTLS);
++ gl::Current *current = gl::getCurrent();
+
+ if (current)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ LocalFree((HLOCAL)current);
+ }
+
+ TlsFree(currentTLS);
++#else
++ HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current);
++ currentTLS = 0;
++ }
++#endif
+ }
+ break;
+ default:
+@@ -78,7 +98,16 @@ namespace gl
+ Current *getCurrent()
+ {
+ #ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+- return (Current*)TlsGetValue(currentTLS);
++#if !defined(ANGLE_OS_WINRT)
++ Current *current = (Current*)TlsGetValue(currentTLS);
++ if (!current)
++ current = (Current*)LocalAlloc(LPTR, sizeof(Current));
++ return current;
++#else
++ if (!currentTLS)
++ currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current));
++ return (Current*)currentTLS;
++#endif
+ #else
+ // No precautions for thread safety taken as ANGLE is used single-threaded in Qt.
+ static gl::Current curr = { 0, 0 };
+diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+index 50dec6b..823d27b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
++++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+@@ -32,13 +32,28 @@
+ #include <unordered_map>
+ #include <vector>
+
++#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
++#define ANGLE_OS_WINRT
++#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP
++#define ANGLE_OS_WINPHONE
++#endif
++#endif
++
+ #ifndef ANGLE_ENABLE_D3D11
+ #include <d3d9.h>
+ #else
++#if !defined(ANGLE_OS_WINRT)
+ #include <D3D11.h>
++#else
++#include <d3d11_1.h>
++#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE)
++#define GetVersion() WINVER
++#endif
+ #include <dxgi.h>
+ #endif
++#ifndef ANGLE_OS_WINPHONE
+ #include <D3Dcompiler.h>
++#endif
+
+ #ifdef _MSC_VER
+ #include <hash_map>
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 21ad223..7ba183d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -28,13 +28,18 @@
+ #define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380)
+ #endif
+
+-#ifdef __MINGW32__
+-
+ #ifndef D3DCOMPILER_DLL
++#ifndef ANGLE_OS_WINPHONE
++#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
++#else
++#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
++#endif // ANGLE_OS_WINPHONE
++#endif // D3DCOMPILER_DLL
+
+-//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+-#define D3DCOMPILER_DLL L"d3dcompiler_43.dll"
++//Add define + typedefs for older MinGW-w64 headers (pre 5783)
++//Also define these on Windows Phone, which doesn't have a shader compiler
+
+ HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+@@ -43,9 +48,7 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+
+-#endif // D3DCOMPILER_DLL
+-
+-#endif // __MINGW32__
++#endif // __MINGW32__ || ANGLE_OS_WINPHONE
+
+ namespace rx
+ {
+@@ -81,7 +84,11 @@ bool Renderer::initializeCompiler()
+ }
+ #else
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
++#if !defined(ANGLE_OS_WINRT)
+ mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++#else
++ mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
++#endif
+ #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+@@ -225,4 +232,4 @@ void glDestroyRenderer(rx::Renderer *renderer)
+ delete renderer;
+ }
+
+-}
+\ No newline at end of file
++}
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+index 04e877b..ac67c27 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
+@@ -1,3 +1,4 @@
++#include "../precompiled.h"
+ //
+ // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+@@ -13,6 +14,30 @@
+ #include "libGLESv2/Uniform.h"
+ #include "libGLESv2/angletypes.h"
+
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0
++#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14)
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1
++#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2
++#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15))
++#endif
++#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3
++#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15)
++#endif
++#ifndef D3DCOMPILE_DEBUG
++#define D3DCOMPILE_DEBUG (1 << 0)
++#endif
++#ifndef D3DCOMPILE_SKIP_OPTIMIZATION
++#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2)
++#endif
++#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL
++#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9)
++#endif
++#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL
++#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10)
++#endif
+ #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+ #endif
+@@ -107,7 +132,7 @@ class Renderer
+
+ virtual void sync(bool block) = 0;
+
+- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
++ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+index a431018..d04467b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+@@ -137,6 +137,7 @@ EGLint Renderer11::initialize()
+ return EGL_NOT_INITIALIZED;
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+
+@@ -155,6 +156,7 @@ EGLint Renderer11::initialize()
+ ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
++#endif
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+@@ -203,8 +205,12 @@ EGLint Renderer11::initialize()
+ }
+ }
+
++#if !defined(ANGLE_OS_WINRT)
+ IDXGIDevice *dxgiDevice = NULL;
+- result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
++#else
++ IDXGIDevice1 *dxgiDevice = NULL;
++#endif
++ result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice));
+
+ if (FAILED(result))
+ {
+@@ -524,7 +530,7 @@ void Renderer11::sync(bool block)
+ }
+ }
+
+-SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
++SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ {
+ return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+ }
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+index f024855..a7f5a39 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+@@ -52,7 +52,7 @@ class Renderer11 : public Renderer
+
+ virtual void sync(bool block);
+
+- virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
++ virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+index 14c0515..a6870eb 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
+@@ -18,7 +18,7 @@ namespace rx
+ class SwapChain
+ {
+ public:
+- SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
++ SwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
+ {
+ }
+@@ -33,7 +33,7 @@ class SwapChain
+ virtual HANDLE getShareHandle() {return mShareHandle;};
+
+ protected:
+- const HWND mWindow; // Window that the surface is created for.
++ const EGLNativeWindowType mWindow; // Window that the surface is created for.
+ const GLenum mBackBufferFormat;
+ const GLenum mDepthBufferFormat;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 0da58cb..0797fd7 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -17,7 +17,7 @@
+ namespace rx
+ {
+
+-SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
++SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+ {
+@@ -468,6 +468,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+
+ if (mWindow)
+ {
++#if !defined(ANGLE_OS_WINRT)
+ // We cannot create a swap chain for an HWND that is owned by a different process
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+@@ -491,14 +492,34 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
++ swapChainDesc.Windowed = TRUE;
++ swapChainDesc.OutputWindow = mWindow;
++#else
++ IDXGIFactory2 *factory;
++ HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory));
++ ASSERT(SUCCEEDED(result));
++
++ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
++ swapChainDesc.BufferCount = 2;
++ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
++ swapChainDesc.Width = backbufferWidth;
++ swapChainDesc.Height = backbufferHeight;
++ swapChainDesc.Stereo = FALSE;
++ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
++#endif
++
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.Flags = 0;
+- swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+- swapChainDesc.Windowed = TRUE;
+
+- HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#if !defined(ANGLE_OS_WINRT)
++ result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++#else
++ IDXGISwapChain1 *swapChain;
++ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
++ mSwapChain = swapChain;
++#endif
+
+ if (FAILED(result))
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+index 8001046..2a030c8 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
+@@ -19,7 +19,7 @@ class Renderer11;
+ class SwapChain11 : public SwapChain
+ {
+ public:
+- SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
++ SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual ~SwapChain11();
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+index 32df49e..8fd193b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+@@ -10,6 +10,14 @@
+ #include "libGLESv2/utilities.h"
+ #include "libGLESv2/mathutil.h"
+
++#if defined(ANGLE_OS_WINRT)
++#include <locale>
++#include <codecvt>
++#include <wrl.h>
++#include <windows.storage.h>
++using namespace ABI::Windows::Storage;
++#endif
++
+ namespace gl
+ {
+
+@@ -737,7 +745,50 @@ bool IsTriangleMode(GLenum drawMode)
+
+ std::string getTempPath()
+ {
++#if defined(ANGLE_OS_WINRT)
++
++ static std::string path;
++
++ while (path.empty()) {
++ IApplicationDataStatics *applicationDataFactory;
++ HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(),
++ IID_PPV_ARGS(&applicationDataFactory));
++ if (FAILED(result))
++ break;
++
++ IApplicationData *applicationData;
++ result = applicationDataFactory->get_Current(&applicationData);
++ if (FAILED(result))
++ break;
++
++ IStorageFolder *storageFolder;
++ result = applicationData->get_LocalFolder(&storageFolder);
++ if (FAILED(result))
++ break;
++
++ IStorageItem *localFolder;
++ result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder));
++ if (FAILED(result))
++ break;
++
++ HSTRING localFolderPath;
++ result = localFolder->get_Path(&localFolderPath);
++ if (FAILED(result))
++ break;
++
++ std::wstring_convert< std::codecvt_utf8<wchar_t> > converter;
++ path = converter.to_bytes(WindowsGetStringRawBuffer(localFolderPath, NULL));
++ if (path.empty())
++ {
++ UNREACHABLE();
++ break;
++ }
++ }
++
++#else
++
+ char path[MAX_PATH];
++
+ DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
+ if (pathLen == 0)
+ {
+@@ -751,6 +802,8 @@ std::string getTempPath()
+ UNREACHABLE();
+ return std::string();
+ }
++
++#endif
+
+ return path;
+ }
+diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
+index a94b9a6..12e26a9 100644
+--- a/src/angle/src/common/common.pri
++++ b/src/angle/src/common/common.pri
+@@ -7,7 +7,7 @@ INCLUDEPATH += \
+ LIBS = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI
+
+ # DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK.
+-win32-msvc2012 {
++win32-msvc2012|winrt {
+ FXC = fxc.exe
+ } else {
+ DX_DIR = $$(DXSDK_DIR)
+diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
+index b281215..5581c9d 100644
+--- a/src/angle/src/compiler/translator_common.pro
++++ b/src/angle/src/compiler/translator_common.pro
+@@ -78,7 +78,6 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/intermOut.cpp \
+ $$ANGLE_DIR/src/compiler/IntermTraverse.cpp \
+ $$ANGLE_DIR/src/compiler/MapLongVariableNames.cpp \
+- $$ANGLE_DIR/src/compiler/ossource_win.cpp \
+ $$ANGLE_DIR/src/compiler/parseConst.cpp \
+ $$ANGLE_DIR/src/compiler/ParseHelper.cpp \
+ $$ANGLE_DIR/src/compiler/PoolAlloc.cpp \
+@@ -98,6 +97,12 @@ SOURCES += \
+ $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
+ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
+
++winrt {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_winrt.cpp
++} else {
++ SOURCES += $$ANGLE_DIR/src/compiler/ossource_win.cpp
++}
++
+ # NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
+ flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
+ flex.output = ${QMAKE_FILE_BASE}_lex.cpp
+diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
+index 1c6d8b0..ed25581 100644
+--- a/src/angle/src/config.pri
++++ b/src/angle/src/config.pri
+@@ -37,8 +37,9 @@ DEFINES += _WINDOWS \
+ NOMINMAX \
+ WIN32_LEAN_AND_MEAN=1
+
+-# Defines specifying the API version (0x0600 = Vista)
+-DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
++# Defines specifying the API version (0x0600 = Vista, 0x0602 = Win8))
++winrt: DEFINES += _WIN32_WINNT=0x0602 WINVER=0x0602
++else: DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
+
+ # ANGLE specific defines
+ DEFINES += ANGLE_DISABLE_TRACE \
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch b/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
new file mode 100644
index 0000000000..0a8e403e8d
--- /dev/null
+++ b/src/angle/patches/0013-ANGLE-Enable-D3D11-for-feature-level-9-cards.patch
@@ -0,0 +1,990 @@
+From a71ccc033fe2cf1c3c58633d3bd220c52b744478 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Fri, 8 Nov 2013 09:04:59 +0200
+Subject: [PATCH] ANGLE: Enable D3D11 for feature level 9 cards
+
+Enable use of ANGLE on lower-end hardware, such as Surface RT and
+Windows Phone 8.
+
+Based on https://codereview.appspot.com/12917046/
+
+Change-Id: Ice536802e4eedc1d264abd0dd65960638fce59e4
+---
+ src/3rdparty/angle/src/libGLESv2/Buffer.cpp | 8 +-
+ src/3rdparty/angle/src/libGLESv2/Buffer.h | 4 +-
+ src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 4 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage.h | 2 +-
+ .../src/libGLESv2/renderer/BufferStorage11.cpp | 9 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage11.h | 2 +-
+ .../src/libGLESv2/renderer/BufferStorage9.cpp | 2 +-
+ .../angle/src/libGLESv2/renderer/BufferStorage9.h | 2 +-
+ .../angle/src/libGLESv2/renderer/Image11.cpp | 7 +-
+ .../angle/src/libGLESv2/renderer/IndexBuffer11.cpp | 4 +-
+ .../src/libGLESv2/renderer/RenderStateCache.cpp | 3 +-
+ .../angle/src/libGLESv2/renderer/Renderer11.cpp | 288 +++++++++++++++------
+ .../angle/src/libGLESv2/renderer/Renderer11.h | 2 +
+ .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 7 +-
+ .../src/libGLESv2/renderer/TextureStorage11.cpp | 8 +-
+ .../src/libGLESv2/renderer/renderer11_utils.cpp | 4 +-
+ .../src/libGLESv2/renderer/renderer11_utils.h | 2 +-
+ .../src/libGLESv2/renderer/shaders/Clear11.hlsl | 4 +
+ src/angle/src/libGLESv2/libGLESv2.pro | 8 +-
+ 19 files changed, 260 insertions(+), 110 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+index c007d5d..40baa95 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+@@ -37,11 +37,11 @@ Buffer::~Buffer()
+ delete mStaticIndexBuffer;
+ }
+
+-void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
++void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target)
+ {
+ mBufferStorage->clear();
+ mIndexRangeCache.clear();
+- mBufferStorage->setData(data, size, 0);
++ mBufferStorage->setData(data, size, 0, target);
+
+ mUsage = usage;
+
+@@ -54,9 +54,9 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
+ }
+ }
+
+-void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
++void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target)
+ {
+- mBufferStorage->setData(data, size, offset);
++ mBufferStorage->setData(data, size, offset, target);
+ mIndexRangeCache.invalidateRange(offset, size);
+
+ if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
+diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
+index 4048f4b..9b86b97 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
++++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
+@@ -33,8 +33,8 @@ class Buffer : public RefCountObject
+
+ virtual ~Buffer();
+
+- void bufferData(const void *data, GLsizeiptr size, GLenum usage);
+- void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
++ void bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target);
++ void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target);
+
+ GLenum usage() const;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+index 320bbcc..91719f8 100644
+--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+@@ -758,7 +758,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+- buffer->bufferData(data, size, usage);
++ buffer->bufferData(data, size, usage, target);
+ }
+ }
+ catch(std::bad_alloc&)
+@@ -812,7 +812,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
+ return gl::error(GL_INVALID_VALUE);
+ }
+
+- buffer->bufferSubData(data, size, offset);
++ buffer->bufferSubData(data, size, offset, target);
+ }
+ }
+ catch(std::bad_alloc&)
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
+index ace1a11..14a8c27 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
+@@ -22,7 +22,7 @@ class BufferStorage
+
+ // The data returned is only guaranteed valid until next non-const method.
+ virtual void *getData() = 0;
+- virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0;
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target) = 0;
+ virtual void clear() = 0;
+ virtual unsigned int getSize() const = 0;
+ virtual bool supportsDirectBinding() const = 0;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+index 3647d8a..2f694db 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+@@ -131,7 +131,7 @@ void *BufferStorage11::getData()
+ return mResolvedData;
+ }
+
+-void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
++void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset, unsigned int target)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+@@ -201,7 +201,10 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = requiredBufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+- bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
++ if (mRenderer->getFeatureLevel() > D3D_FEATURE_LEVEL_9_3)
++ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
++ else
++ bufferDesc.BindFlags = target == GL_ARRAY_BUFFER ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+@@ -324,7 +327,7 @@ unsigned int BufferStorage11::getSize() const
+
+ bool BufferStorage11::supportsDirectBinding() const
+ {
+- return true;
++ return mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0;
+ }
+
+ void BufferStorage11::markBufferUsage()
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
+index b62348b..c948962 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
+@@ -24,7 +24,7 @@ class BufferStorage11 : public BufferStorage
+ static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+- virtual void setData(const void* data, unsigned int size, unsigned int offset);
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+index e69e7a8..57fd29b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+@@ -36,7 +36,7 @@ void *BufferStorage9::getData()
+ return mMemory;
+ }
+
+-void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset)
++void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset, unsigned int)
+ {
+ if (!mMemory || offset + size > mAllocatedSize)
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
+index 3e80396..82ae577 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
+@@ -23,7 +23,7 @@ class BufferStorage9 : public BufferStorage
+ static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+- virtual void setData(const void* data, unsigned int size, unsigned int offset);
++ virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target = 0);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
+index 09c8922..81e9e9e 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
+@@ -136,7 +136,7 @@ bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width,
+ mHeight = height;
+ mInternalFormat = internalformat;
+ // compute the d3d format that will be used
+- mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel());
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
+
+ if (mStagingTexture)
+@@ -185,7 +185,10 @@ void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
+ switch (mInternalFormat)
+ {
+ case GL_ALPHA8_EXT:
+- loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
++ if (mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0)
++ loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
++ else
++ loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE8_EXT:
+ loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
+index 66604c4..36a62ad 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
+@@ -170,7 +170,7 @@ DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+ {
+ case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT;
+ case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT;
+- case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT;
++ case GL_UNSIGNED_INT: return mRenderer->get32BitIndexSupport() ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT;
+ default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
+ }
+ }
+@@ -180,4 +180,4 @@ ID3D11Buffer *IndexBuffer11::getBuffer() const
+ return mBuffer;
+ }
+
+-}
+\ No newline at end of file
++}
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
+index b3111af..fd388df 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
+@@ -387,7 +387,8 @@ ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &sa
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
+- samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
++ samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0
++ ? gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset) : FLT_MAX;
+
+ ID3D11SamplerState *dx11SamplerState = NULL;
+ HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+index d04467b..f83e9e9 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
+@@ -160,9 +160,13 @@ EGLint Renderer11::initialize()
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
++ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
++ D3D_FEATURE_LEVEL_9_3,
++ D3D_FEATURE_LEVEL_9_2,
++ D3D_FEATURE_LEVEL_9_1,
+ };
+
+ HRESULT result = S_OK;
+@@ -1114,6 +1118,43 @@ void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLv
+ }
+ }
+
++template <typename T>
++static void drawLineLoopIndexed(T *data, GLenum type, const GLvoid *indices, GLsizei count)
++{
++ switch (type)
++ {
++ case GL_NONE: // Non-indexed draw
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = i;
++ }
++ data[count] = 0;
++ break;
++ case GL_UNSIGNED_BYTE:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLubyte*>(indices)[i];
++ }
++ data[count] = static_cast<const GLubyte*>(indices)[0];
++ break;
++ case GL_UNSIGNED_SHORT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLushort*>(indices)[i];
++ }
++ data[count] = static_cast<const GLushort*>(indices)[0];
++ break;
++ case GL_UNSIGNED_INT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLuint*>(indices)[i];
++ }
++ data[count] = static_cast<const GLuint*>(indices)[0];
++ break;
++ default: UNREACHABLE();
++ }
++}
++
+ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+ {
+ // Get the raw indices for an indexed draw
+@@ -1162,59 +1203,71 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
++ if (get32BitIndexSupport())
++ drawLineLoopIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, count);
++ else
++ drawLineLoopIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, count);
++
+ unsigned int indexBufferOffset = offset;
+
++ if (!mLineLoopIB->unmapBuffer())
++ {
++ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
++ return gl::error(GL_OUT_OF_MEMORY);
++ }
++
++ if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
++ {
++ IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
++
++ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
++ mAppliedIBSerial = mLineLoopIB->getSerial();
++ mAppliedStorageIBSerial = 0;
++ mAppliedIBOffset = indexBufferOffset;
++ }
++
++ mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
++}
++
++template <typename T>
++static void drawTriangleFanIndexed(T *data, GLenum type, const GLvoid *indices, unsigned int numTris)
++{
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = i;
++ data[i*3 + 0] = 0;
++ data[i*3 + 1] = i + 1;
++ data[i*3 + 2] = i + 2;
+ }
+- data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLubyte*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLushort*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+- for (int i = 0; i < count; i++)
++ for (unsigned int i = 0; i < numTris; i++)
+ {
+- data[i] = static_cast<const GLuint*>(indices)[i];
++ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+ }
+- data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+-
+- if (!mLineLoopIB->unmapBuffer())
+- {
+- ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+- return gl::error(GL_OUT_OF_MEMORY);
+- }
+-
+- if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
+- {
+- IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
+-
+- mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
+- mAppliedIBSerial = mLineLoopIB->getSerial();
+- mAppliedStorageIBSerial = 0;
+- mAppliedIBOffset = indexBufferOffset;
+- }
+-
+- mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
+ }
+
+ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
+@@ -1267,45 +1320,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+- unsigned int indexBufferOffset = offset;
++ if (get32BitIndexSupport())
++ drawTriangleFanIndexed(reinterpret_cast<unsigned int*>(mappedMemory), type, indices, numTris);
++ else
++ drawTriangleFanIndexed(reinterpret_cast<unsigned short*>(mappedMemory), type, indices, numTris);
+
+- switch (type)
+- {
+- case GL_NONE: // Non-indexed draw
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = 0;
+- data[i*3 + 1] = i + 1;
+- data[i*3 + 2] = i + 2;
+- }
+- break;
+- case GL_UNSIGNED_BYTE:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_SHORT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_INT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+- }
+- break;
+- default: UNREACHABLE();
+- }
++ unsigned int indexBufferOffset = offset;
+
+ if (!mTriangleFanIB->unmapBuffer())
+ {
+@@ -1515,7 +1535,7 @@ void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArra
+ }
+
+ // needed for the point sprite geometry shader
+- if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
++ if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+ {
+ mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+ mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+@@ -1929,9 +1949,13 @@ bool Renderer11::testDeviceResettable()
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
++ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
++ D3D_FEATURE_LEVEL_9_3,
++ D3D_FEATURE_LEVEL_9_2,
++ D3D_FEATURE_LEVEL_9_1,
+ };
+
+ ID3D11Device* dummyDevice;
+@@ -2110,11 +2134,17 @@ float Renderer11::getTextureMaxAnisotropy() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_MAX_MAXANISOTROPY;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_MAX_MAXANISOTROPY;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ return 16;
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2129,11 +2159,17 @@ Range Renderer11::getViewportBounds() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
++ case D3D_FEATURE_LEVEL_9_3:
++ return Range(D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return Range(D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2);
+ default: UNREACHABLE();
+ return Range(0, 0);
+ }
+@@ -2144,10 +2180,15 @@ unsigned int Renderer11::getMaxVertexTextureImageUnits() const
+ META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 0;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2171,15 +2212,41 @@ unsigned int Renderer11::getReservedFragmentUniformVectors() const
+ unsigned int Renderer11::getMaxVertexUniformVectors() const
+ {
+ META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+- return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
++ switch (mFeatureLevel)
++ {
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_10_1:
++ case D3D_FEATURE_LEVEL_10_0:
++ return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return MAX_VERTEX_UNIFORM_VECTORS_D3D9;
++ default:
++ UNIMPLEMENTED();
++ return 0;
++ }
+ }
+
+ unsigned int Renderer11::getMaxFragmentUniformVectors() const
+ {
+ META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+- ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+- return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
++ switch (mFeatureLevel)
++ {
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_10_1:
++ case D3D_FEATURE_LEVEL_10_0:
++ return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
++ case D3D_FEATURE_LEVEL_9_3:
++ return 221;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 29;
++ default: UNREACHABLE();
++ return 0;
++ }
+ }
+
+ unsigned int Renderer11::getMaxVaryingVectors() const
+@@ -2187,11 +2254,17 @@ unsigned int Renderer11::getMaxVaryingVectors() const
+ META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_10_1:
++ return D3D10_1_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_VS_OUTPUT_REGISTER_COUNT;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return 8;
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2201,10 +2274,15 @@ bool Renderer11::getNonPower2TextureSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2214,10 +2292,15 @@ bool Renderer11::getOcclusionQuerySupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
+ return true;
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2227,10 +2310,15 @@ bool Renderer11::getInstancingSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
+ return true;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2248,10 +2336,15 @@ bool Renderer11::getDerivativeInstructionSupport() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
++ case D3D_FEATURE_LEVEL_9_3:
+ return true;
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return false;
+ default: UNREACHABLE();
+ return false;
+ }
+@@ -2267,9 +2360,13 @@ int Renderer11::getMajorShaderModel() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
+ case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return 4; // SM4 level 9, but treat as 4
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2278,9 +2375,13 @@ int Renderer11::getMinorShaderModel() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
+ case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return 0;
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2301,11 +2402,17 @@ int Renderer11::getMaxViewportDimension() const
+
+ switch (mFeatureLevel)
+ {
+- case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3:
++ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE();
+ return 0;
+ }
+@@ -2315,9 +2422,13 @@ int Renderer11::getMaxTextureWidth() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2326,9 +2437,13 @@ int Renderer11::getMaxTextureHeight() const
+ {
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
++ case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048
+ default: UNREACHABLE(); return 0;
+ }
+ }
+@@ -2337,9 +2452,13 @@ bool Renderer11::get32BitIndexSupport() const
+ {
+ switch (mFeatureLevel)
+ {
+- case D3D_FEATURE_LEVEL_11_0:
++ case D3D_FEATURE_LEVEL_11_1:
++ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
++ case D3D_FEATURE_LEVEL_9_3:
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1: return false;
+ default: UNREACHABLE(); return false;
+ }
+ }
+@@ -2386,14 +2505,22 @@ unsigned int Renderer11::getMaxRenderTargets() const
+ {
+ META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
++ META_ASSERT(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
++ META_ASSERT(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ switch (mFeatureLevel)
+ {
++ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
++ case D3D_FEATURE_LEVEL_9_3:
++ return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; // 4
++ case D3D_FEATURE_LEVEL_9_2:
++ case D3D_FEATURE_LEVEL_9_1:
++ return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; // 1
+ default:
+ UNREACHABLE();
+ return 1;
+@@ -2821,7 +2948,7 @@ ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length
+
+ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
+ {
+- const char *profile = NULL;
++ std::string profile;
+
+ switch (type)
+ {
+@@ -2839,7 +2966,12 @@ ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const ch
+ return NULL;
+ }
+
+- ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
++ if (mFeatureLevel == D3D_FEATURE_LEVEL_9_3)
++ profile += "_level_9_3";
++ else if (mFeatureLevel == D3D_FEATURE_LEVEL_9_2 || mFeatureLevel == D3D_FEATURE_LEVEL_9_1)
++ profile += "_level_9_1";
++
++ ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile.c_str(), D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+ if (!binary)
+ return NULL;
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+index a7f5a39..433945d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
+@@ -32,6 +32,7 @@ class StreamingIndexBufferInterface;
+
+ enum
+ {
++ MAX_VERTEX_UNIFORM_VECTORS_D3D9 = 254,
+ MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
+ MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
+ };
+@@ -177,6 +178,7 @@ class Renderer11 : public Renderer
+ ID3D11Device *getDevice() { return mDevice; }
+ ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+ IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
++ D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }
+
+ bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
+ void unapplyRenderTargets();
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 0797fd7..9770772 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -500,12 +500,17 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ ASSERT(SUCCEEDED(result));
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
+- swapChainDesc.BufferCount = 2;
+ swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ swapChainDesc.Width = backbufferWidth;
+ swapChainDesc.Height = backbufferHeight;
+ swapChainDesc.Stereo = FALSE;
++#if !defined(ANGLE_OS_WINPHONE)
++ swapChainDesc.BufferCount = 2;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
++#else
++ swapChainDesc.BufferCount = 1;
++ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
++#endif
+ #endif
+
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
+index 408b48e..32a407a 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
+@@ -222,14 +222,14 @@ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapch
+ }
+
+ TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
++ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
+ {
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mRenderTarget[i] = NULL;
+ }
+
+- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+@@ -440,7 +440,7 @@ void TextureStorage11_2D::generateMipmap(int level)
+ }
+
+ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+- : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
++ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable))
+ {
+ for (unsigned int i = 0; i < 6; i++)
+ {
+@@ -450,7 +450,7 @@ TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLe
+ }
+ }
+
+- DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
++ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel());
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
+index 13800da..0624a61 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
+@@ -329,7 +329,7 @@ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ }
+
+-DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
++DXGI_FORMAT ConvertTextureFormat(GLenum internalformat, D3D_FEATURE_LEVEL featureLevel)
+ {
+ switch (internalformat)
+ {
+@@ -342,7 +342,7 @@ DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case GL_ALPHA8_EXT:
+- return DXGI_FORMAT_A8_UNORM;
++ return featureLevel >= D3D_FEATURE_LEVEL_10_0 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return DXGI_FORMAT_BC1_UNORM;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
+index 1bc48c1..70ad4fe 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
+@@ -32,7 +32,7 @@ FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
+ FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
+
+ DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
+-DXGI_FORMAT ConvertTextureFormat(GLenum format);
++DXGI_FORMAT ConvertTextureFormat(GLenum format, D3D_FEATURE_LEVEL featureLevel);
+ }
+
+ namespace d3d11_gl
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
+index 042ac69..cb132dc 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
+@@ -12,10 +12,12 @@ struct PS_OutputMultiple
+ float4 color1 : SV_TARGET1;
+ float4 color2 : SV_TARGET2;
+ float4 color3 : SV_TARGET3;
++#ifdef SM4
+ float4 color4 : SV_TARGET4;
+ float4 color5 : SV_TARGET5;
+ float4 color6 : SV_TARGET6;
+ float4 color7 : SV_TARGET7;
++#endif
+ };
+
+ PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
+@@ -25,10 +27,12 @@ PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4
+ outColor.color1 = inColor;
+ outColor.color2 = inColor;
+ outColor.color3 = inColor;
++#ifdef SM4
+ outColor.color4 = inColor;
+ outColor.color5 = inColor;
+ outColor.color6 = inColor;
+ outColor.color7 = inColor;
++#endif
+ return outColor;
+ }
+
+diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
+index ff2f888..b39ce78 100644
+--- a/src/angle/src/libGLESv2/libGLESv2.pro
++++ b/src/angle/src/libGLESv2/libGLESv2.pro
+@@ -190,7 +190,7 @@ for (ps, PIXEL_SHADERS_BLIT) {
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+ }
+ for (ps, PIXEL_SHADERS_PASSTHROUGH) {
+- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = PASSTHROUGH_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+@@ -199,7 +199,7 @@ for (ps, PIXEL_SHADERS_PASSTHROUGH) {
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+ }
+ for (ps, PIXEL_SHADERS_CLEAR) {
+- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = CLEAR_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+@@ -217,7 +217,7 @@ for (vs, VERTEX_SHADERS_BLIT) {
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+ }
+ for (vs, VERTEX_SHADERS_PASSTHROUGH) {
+- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = PASSTHROUGH_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+@@ -226,7 +226,7 @@ for (vs, VERTEX_SHADERS_PASSTHROUGH) {
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+ }
+ for (vs, VERTEX_SHADERS_CLEAR) {
+- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
++ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = CLEAR_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch b/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch
new file mode 100644
index 0000000000..dbe618102e
--- /dev/null
+++ b/src/angle/patches/0014-ANGLE-D3D11-Always-execute-QueryInterface.patch
@@ -0,0 +1,51 @@
+From 4d1906f0b81f2b61adf9640ae6cef9d503c33209 Mon Sep 17 00:00:00 2001
+From: Maurice Kalinowski <maurice.kalinowski@digia.com>
+Date: Tue, 3 Dec 2013 14:52:18 +0100
+Subject: [PATCH] ANGLE D3D11: Always execute QueryInterface
+
+ASSERT removes the condition when building for release mode. However,
+QueryInterface must be called in any case. Adopt to using ASSERT(false)
+like in other occurrences in angle.
+
+This is a follow-up patch to 331bc16afd23414493b842819e0b747e8f364243
+
+Change-Id: I4413bab06b5a529fcbd09bbc20828fcdcf4e4fc6
+---
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index ee8d480..99d0c1d 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -118,7 +118,12 @@ bool Surface::resetSwapChain()
+ #else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+- ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
++ if (FAILED(result))
++ {
++ ASSERT(false);
++ return false;
++ }
+ window->get_Bounds(&windowRect);
+ width = windowRect.Width;
+ height = windowRect.Height;
+@@ -342,7 +347,12 @@ bool Surface::checkForOutOfDateSwapChain()
+ #else
+ ABI::Windows::Foundation::Rect windowRect;
+ ABI::Windows::UI::Core::ICoreWindow *window;
+- ASSERT(SUCCEEDED(mWindow->QueryInterface(IID_PPV_ARGS(&window))));
++ HRESULT result = mWindow->QueryInterface(IID_PPV_ARGS(&window));
++ if (FAILED(result))
++ {
++ ASSERT(false);
++ return false;
++ }
+ window->get_Bounds(&windowRect);
+ int clientWidth = windowRect.Width;
+ int clientHeight = windowRect.Height;
+--
+1.7.11.msysgit.0
+
diff --git a/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch b/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch
new file mode 100644
index 0000000000..1955e12bf3
--- /dev/null
+++ b/src/angle/patches/0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch
@@ -0,0 +1,85 @@
+From 806fbe22a3515792b6716b5072a2131e2ce3437a Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Sat, 7 Dec 2013 23:57:39 +0200
+Subject: [PATCH] ANGLE: Dynamically load D3D compiler from a list or the
+ environment
+
+If the default compiler cannot be found, load it from a list of DLL names,
+including a non-versioned proxy DLL provided by Qt. On Desktop Windows,
+the default compiler can also be specified by an environment variable,
+QT_D3DCOMPILER_DLL.
+
+Change-Id: I0d7a8a8a36cc571836f8fa59ea14513b9b19c19b
+---
+ .../angle/src/libGLESv2/renderer/Renderer.cpp | 44 ++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 8 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 7ba183d..39fd0f4 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -29,12 +29,12 @@
+ #endif
+
+ #ifndef D3DCOMPILER_DLL
+-#ifndef ANGLE_OS_WINPHONE
+ #define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator
+-#else
+-#define D3DCOMPILER_DLL L"qtd3dcompiler.dll" // Placeholder DLL for phone
+-#endif // ANGLE_OS_WINPHONE
+-#endif // D3DCOMPILER_DLL
++#endif
++
++#ifndef QT_D3DCOMPILER_DLL
++#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL
++#endif
+
+ #if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE)
+
+@@ -83,12 +83,40 @@ bool Renderer::initializeCompiler()
+ }
+ }
+ #else
+- // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
++ // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL
++#if !defined(ANGLE_OS_WINRT)
++ const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL");
++ if (!defaultCompiler)
++ defaultCompiler = QT_D3DCOMPILER_DLL;
++#else // !ANGLE_OS_WINRT
++# ifdef _DEBUG
++ const wchar_t *defaultCompiler = L"d3dcompiler_qtd.dll";
++# else
++ const wchar_t *defaultCompiler = L"d3dcompiler_qt.dll";
++# endif
++#endif // ANGLE_OS_WINRT
++
++ const wchar_t *compilerDlls[] = {
++ defaultCompiler,
++ L"d3dcompiler_47.dll",
++ L"d3dcompiler_46.dll",
++ L"d3dcompiler_45.dll",
++ L"d3dcompiler_44.dll",
++ L"d3dcompiler_43.dll",
++ 0
++ };
++
++ // Load the first available known compiler DLL
++ for (int i = 0; compilerDlls[i]; ++i)
++ {
+ #if !defined(ANGLE_OS_WINRT)
+- mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
++ mD3dCompilerModule = LoadLibrary(compilerDlls[i]);
+ #else
+- mD3dCompilerModule = LoadPackagedLibrary(D3DCOMPILER_DLL, NULL);
++ mD3dCompilerModule = LoadPackagedLibrary(compilerDlls[i], NULL);
+ #endif
++ if (mD3dCompilerModule)
++ break;
++ }
+ #endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch b/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch
new file mode 100644
index 0000000000..99f458bc28
--- /dev/null
+++ b/src/angle/patches/0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch
@@ -0,0 +1,28 @@
+From 8229b84ddf0134ac11412262d23515dfb7ddb177 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Sun, 8 Dec 2013 22:50:38 +0200
+Subject: [PATCH] ANGLE D3D11: Fix build on desktop Windows
+
+This fixes a missing declaration caused by 11a2226c
+
+Change-Id: I4b8092c6b9592e886353af9193686238105a1512
+---
+ src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 9770772..2fe15ff 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -519,7 +519,7 @@ EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swap
+ swapChainDesc.SampleDesc.Quality = 0;
+
+ #if !defined(ANGLE_OS_WINRT)
+- result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
++ HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+ #else
+ IDXGISwapChain1 *swapChain;
+ result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain);
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/src/common/common.pri b/src/angle/src/common/common.pri
index 514c80dbd1..58ad88673a 100644
--- a/src/angle/src/common/common.pri
+++ b/src/angle/src/common/common.pri
@@ -7,7 +7,7 @@ INCLUDEPATH += \
LIBS_PRIVATE = $$QMAKE_LIBS_CORE $$QMAKE_LIBS_GUI
# DirectX is included in the Windows 8 Kit, but everything else requires the DX SDK.
-win32-msvc2012|win32-msvc2013 {
+win32-msvc2012|win32-msvc2013|winrt {
FXC = fxc.exe
} else {
DX_DIR = $$(DXSDK_DIR)
diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
index b2812158e1..c8f86d6b10 100644
--- a/src/angle/src/compiler/translator_common.pro
+++ b/src/angle/src/compiler/translator_common.pro
@@ -5,7 +5,7 @@ TARGET = $$qtLibraryTarget(translator_common)
include(../config.pri)
# Mingw 4.7 chokes on implicit move semantics, so disable C++11 here
-win32-g++*: CONFIG -= c++11
+mingw: CONFIG -= c++11
INCLUDEPATH += \
$$ANGLE_DIR/src \
@@ -78,7 +78,6 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/intermOut.cpp \
$$ANGLE_DIR/src/compiler/IntermTraverse.cpp \
$$ANGLE_DIR/src/compiler/MapLongVariableNames.cpp \
- $$ANGLE_DIR/src/compiler/ossource_win.cpp \
$$ANGLE_DIR/src/compiler/parseConst.cpp \
$$ANGLE_DIR/src/compiler/ParseHelper.cpp \
$$ANGLE_DIR/src/compiler/PoolAlloc.cpp \
@@ -98,6 +97,12 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
$$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
+winrt {
+ SOURCES += $$ANGLE_DIR/src/compiler/ossource_winrt.cpp
+} else {
+ SOURCES += $$ANGLE_DIR/src/compiler/ossource_win.cpp
+}
+
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
flex.output = ${QMAKE_FILE_BASE}_lex.cpp
diff --git a/src/angle/src/compiler/translator_hlsl.pro b/src/angle/src/compiler/translator_hlsl.pro
index 1c31cad297..f19d33a530 100644
--- a/src/angle/src/compiler/translator_hlsl.pro
+++ b/src/angle/src/compiler/translator_hlsl.pro
@@ -5,7 +5,7 @@ TARGET = $$qtLibraryTarget(translator_hlsl)
include(../config.pri)
# Mingw 4.7 chokes on implicit move semantics, so disable C++11 here
-win32-g++*: CONFIG -= c++11
+mingw: CONFIG -= c++11
INCLUDEPATH += $$ANGLE_DIR/src \
$$ANGLE_DIR/include
diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
index 1c6d8b0167..ed2558117e 100644
--- a/src/angle/src/config.pri
+++ b/src/angle/src/config.pri
@@ -37,8 +37,9 @@ DEFINES += _WINDOWS \
NOMINMAX \
WIN32_LEAN_AND_MEAN=1
-# Defines specifying the API version (0x0600 = Vista)
-DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
+# Defines specifying the API version (0x0600 = Vista, 0x0602 = Win8))
+winrt: DEFINES += _WIN32_WINNT=0x0602 WINVER=0x0602
+else: DEFINES += _WIN32_WINNT=0x0600 WINVER=0x0600
# ANGLE specific defines
DEFINES += ANGLE_DISABLE_TRACE \
diff --git a/src/angle/src/d3dcompiler/d3dcompiler.pro b/src/angle/src/d3dcompiler/d3dcompiler.pro
new file mode 100644
index 0000000000..5a10187279
--- /dev/null
+++ b/src/angle/src/d3dcompiler/d3dcompiler.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+TARGET = $$qtLibraryTarget(d3dcompiler_qt)
+
+include(../config.pri)
+CONFIG += qt
+
+QT = core
+DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
+SOURCES += main.cpp
+win32:!winrt: LIBS += -lole32
+
+# __stdcall exports get mangled, so use a def file
+DEF_FILE += $${TARGET}.def
+
+load(qt_installs)
diff --git a/src/angle/src/d3dcompiler/d3dcompiler_qt.def b/src/angle/src/d3dcompiler/d3dcompiler_qt.def
new file mode 100644
index 0000000000..0b8679c8e0
--- /dev/null
+++ b/src/angle/src/d3dcompiler/d3dcompiler_qt.def
@@ -0,0 +1,3 @@
+LIBRARY d3dcompiler_qt
+EXPORTS
+ D3DCompile @1
diff --git a/src/angle/src/d3dcompiler/d3dcompiler_qtd.def b/src/angle/src/d3dcompiler/d3dcompiler_qtd.def
new file mode 100644
index 0000000000..0bdd0a1ffd
--- /dev/null
+++ b/src/angle/src/d3dcompiler/d3dcompiler_qtd.def
@@ -0,0 +1,3 @@
+LIBRARY d3dcompiler_qtd
+EXPORTS
+ D3DCompile @1
diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp
new file mode 100644
index 0000000000..d2bb43ea9f
--- /dev/null
+++ b/src/angle/src/d3dcompiler/main.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+#include <QCryptographicHash>
+#include <QDateTime>
+#include <QDir>
+#include <QElapsedTimer>
+#include <QFile>
+#include <QLoggingCategory>
+#include <QStandardPaths>
+#include <QThread>
+
+#include <qt_windows.h>
+#include <d3dcommon.h>
+
+Q_LOGGING_CATEGORY(QT_D3DCOMPILER, "qt.angle.d3dcompiler")
+
+namespace D3DCompiler {
+
+typedef HRESULT (WINAPI *D3DCompileFunc)(const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+static D3DCompileFunc compile;
+
+class Blob : public ID3DBlob
+{
+public:
+ Blob(const QByteArray &data) : m_data(data)
+ {
+ IIDFromString(L"00000000-0000-0000-C000-000000000046", &IID_IUnknown);
+ IIDFromString(L"8BA5FB08-5195-40e2-AC58-0D989C3A0102", &IID_ID3DBlob);
+ }
+
+ virtual ~Blob()
+ {
+ }
+
+ // ID3DBlob
+ LPVOID __stdcall GetBufferPointer()
+ {
+ return m_data.data();
+ }
+
+ SIZE_T __stdcall GetBufferSize()
+ {
+ return m_data.size();
+ }
+
+ // IUnknown
+ HRESULT __stdcall QueryInterface(REFIID riid, void **ppv)
+ {
+ IUnknown *out = 0;
+ if (riid == IID_IUnknown)
+ out = static_cast<IUnknown*>(this);
+ else if (riid == IID_ID3DBlob)
+ out = this;
+
+ *ppv = out;
+ if (!out)
+ return E_NOINTERFACE;
+
+ out->AddRef();
+ return S_OK;
+ }
+
+ ULONG __stdcall AddRef()
+ {
+ return ++m_ref;
+ }
+
+ ULONG __stdcall Release()
+ {
+ ULONG ref = --m_ref;
+ if (!m_ref)
+ delete this;
+
+ return ref;
+ }
+
+private:
+ QByteArray m_data;
+ ULONG m_ref;
+
+ // These symbols might be missing, so define them here
+ IID IID_IUnknown;
+ IID IID_ID3DBlob;
+};
+
+static bool loadCompiler()
+{
+ static HMODULE d3dcompiler = 0;
+ if (!d3dcompiler) {
+ const wchar_t *dllNames[] = {
+ L"d3dcompiler_47.dll",
+ L"d3dcompiler_46.dll",
+ L"d3dcompiler_45.dll",
+ L"d3dcompiler_44.dll",
+ L"d3dcompiler_43.dll",
+ 0
+ };
+ for (int i = 0; const wchar_t *name = dllNames[i]; ++i) {
+#ifndef Q_OS_WINRT
+ d3dcompiler = LoadLibrary(name);
+#else
+ d3dcompiler = LoadPackagedLibrary(name, NULL);
+#endif
+ if (d3dcompiler) {
+ qCDebug(QT_D3DCOMPILER) << "Found" << QString::fromWCharArray(name);
+ D3DCompiler::compile = reinterpret_cast<D3DCompiler::D3DCompileFunc>(GetProcAddress(d3dcompiler, "D3DCompile"));
+ if (D3DCompiler::compile) {
+ qCDebug(QT_D3DCOMPILER) << "Loaded" << QString::fromWCharArray(name);
+ break;
+ }
+ qCDebug(QT_D3DCOMPILER) << "Failed to load" << QString::fromWCharArray(name);
+ }
+ }
+
+ if (!d3dcompiler)
+ qCDebug(QT_D3DCOMPILER) << "Unable to load D3D shader compiler.";
+ }
+
+ return bool(compile);
+}
+
+static QString cacheKeyFor(const void *data)
+{
+ return QString::fromUtf8(QCryptographicHash::hash(reinterpret_cast<const char *>(data), QCryptographicHash::Sha1).toHex());
+}
+
+} // namespace D3DCompiler
+
+#ifdef __MINGW32__
+extern "C"
+#endif
+__declspec(dllexport) HRESULT WINAPI D3DCompile(
+ const void *, SIZE_T, const char *, const D3D_SHADER_MACRO *, ID3DInclude *,
+ const char *, const char *, UINT, UINT, ID3DBlob **, ID3DBlob **);
+
+HRESULT WINAPI D3DCompile(
+ const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **errorMsgs)
+{
+ static bool initialized = false;
+ static bool serviceAvailable = false;
+ static QString binaryPath;
+ static QString sourcePath;
+ if (!initialized) {
+ QString base;
+ if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) {
+ base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
+ } else {
+ const QString location = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
+ if (!location.isEmpty())
+ base = location + QStringLiteral("/d3dcompiler");
+ }
+
+ QDir baseDir(base);
+ if (!base.isEmpty() && baseDir.exists()) {
+ // Check if we have can read/write blobs
+ if (baseDir.exists(QStringLiteral("binary"))) {
+ binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/"));
+ } else {
+ qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the binary directory does not.\n"
+ "Check the compiler service.";
+ }
+
+ // Check if we can write shader source
+ if (baseDir.exists(QStringLiteral("source"))) {
+ sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/"));
+ } else {
+ qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n"
+ "Check the compiler service.";
+ }
+
+ // Look for a file, "control", and check if it has been touched in the last 60 seconds
+ QFileInfo control(baseDir.absoluteFilePath(QStringLiteral("control")));
+ serviceAvailable = control.exists() && control.lastModified().secsTo(QDateTime::currentDateTime()) < 60;
+ } else {
+ qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:"
+ << QDir::toNativeSeparators(base)
+ << "\nThe compiler service won't be used.";
+ }
+
+ initialized = true;
+ }
+
+ QByteArray macros;
+ if (const D3D_SHADER_MACRO *macro = defines) {
+ while (macro) {
+ macros.append('#').append(macro->Name).append(' ').append(macro->Definition).append('\n');
+ ++macro;
+ }
+ }
+
+ const QByteArray sourceData = macros + QByteArray::fromRawData(reinterpret_cast<const char *>(data), data_size);
+ const QString fileName = D3DCompiler::cacheKeyFor(sourceData)
+ + QLatin1Char('!') + QString::fromUtf8(entrypoint)
+ + QLatin1Char('!') + QString::fromUtf8(target)
+ + QLatin1Char('!') + QString::number(sflags);
+
+ // Check if pre-compiled shader blob is available
+ if (!binaryPath.isEmpty()) {
+ QString blobName = binaryPath + fileName;
+ QFile blob(blobName);
+ while (!blob.exists()) {
+ // Progressively drop optional parts
+ blobName.truncate(blobName.lastIndexOf(QLatin1Char('!')));
+ if (blobName.isEmpty())
+ break;
+ blob.setFileName(blobName);
+ }
+ if (blob.exists()) {
+ if (blob.open(QFile::ReadOnly)) {
+ qCDebug(QT_D3DCOMPILER) << "Opening precompiled shader blob at" << blob.fileName();
+ *shader = new D3DCompiler::Blob(blob.readAll());
+ return S_FALSE;
+ }
+ qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName();
+ }
+ }
+
+ // Shader blob is not available, compile with compilation service if possible
+ if (!sourcePath.isEmpty() && serviceAvailable) {
+ // Dump source to source path; wait for blob to appear
+ QFile source(sourcePath + fileName);
+ if (!source.open(QFile::WriteOnly)) {
+ qCDebug(QT_D3DCOMPILER) << "Unable to write shader source to file:" << source.fileName() << source.errorString();
+ return E_ACCESSDENIED;
+ }
+
+ source.write(sourceData);
+ qCDebug(QT_D3DCOMPILER) << "Wrote shader source, waiting for blob:" << source.fileName();
+ source.close();
+
+ qint64 timeout = qgetenv("QT_D3DCOMPILER_TIMEOUT").toLong();
+ if (!timeout)
+ timeout = 3000;
+
+ QElapsedTimer timer;
+ timer.start();
+ QFile blob(binaryPath + fileName);
+ while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout)
+ QThread::msleep(100);
+
+ if (blob.isOpen()) {
+ *shader = new D3DCompiler::Blob(blob.readAll());
+ return S_FALSE;
+ }
+
+ qCDebug(QT_D3DCOMPILER) << "Shader blob failed to materialize after" << timeout << "ms.";
+ *errorMsgs = new D3DCompiler::Blob("Shader compilation timeout.");
+ return E_ABORT;
+ }
+
+ // Fall back to compiler DLL
+ if (D3DCompiler::loadCompiler()) {
+ HRESULT hr = D3DCompiler::compile(data, data_size, filename, defines, include, entrypoint,
+ target, sflags, eflags, shader, errorMsgs);
+ // Cache shader
+ if (SUCCEEDED(hr) && !binaryPath.isEmpty()) {
+ const QByteArray blobContents = QByteArray::fromRawData(
+ reinterpret_cast<const char *>((*shader)->GetBufferPointer()), (*shader)->GetBufferSize());
+
+ QFile blob(binaryPath + fileName);
+ if (blob.open(QFile::WriteOnly) && blob.write(blobContents))
+ qCDebug(QT_D3DCOMPILER) << "Cached shader blob at" << blob.fileName();
+ else
+ qCDebug(QT_D3DCOMPILER) << "Unable to write shader blob at" << blob.fileName();
+ }
+ return hr;
+ }
+
+ *errorMsgs = new D3DCompiler::Blob("Unable to load D3D compiler DLL.");
+ return E_FAIL;
+}
diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro
index b5854189f9..f51bc8ee83 100644
--- a/src/angle/src/libEGL/libEGL.pro
+++ b/src/angle/src/libEGL/libEGL.pro
@@ -27,7 +27,7 @@ SOURCES += \
!static {
DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}.def
- win32-g++*:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}_mingw32.def
+ mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libEGL/$${TARGET}_mingw32.def
}
load(qt_installs)
diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
index 5d54c0f86a..75853e219e 100644
--- a/src/angle/src/libGLESv2/libGLESv2.pro
+++ b/src/angle/src/libGLESv2/libGLESv2.pro
@@ -158,7 +158,7 @@ angle_d3d11 {
!static {
DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}.def
- win32-g++*:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}_mingw32.def
+ mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}_mingw32.def
}
float_converter.target = float_converter
@@ -190,7 +190,7 @@ for (ps, PIXEL_SHADERS_BLIT) {
QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
}
for (ps, PIXEL_SHADERS_PASSTHROUGH) {
- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
fxc_ps_$${ps}.input = PASSTHROUGH_INPUT
fxc_ps_$${ps}.dependency_type = TYPE_C
@@ -199,7 +199,7 @@ for (ps, PIXEL_SHADERS_PASSTHROUGH) {
QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
}
for (ps, PIXEL_SHADERS_CLEAR) {
- fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
fxc_ps_$${ps}.input = CLEAR_INPUT
fxc_ps_$${ps}.dependency_type = TYPE_C
@@ -217,7 +217,7 @@ for (vs, VERTEX_SHADERS_BLIT) {
QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
}
for (vs, VERTEX_SHADERS_PASSTHROUGH) {
- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
fxc_vs_$${vs}.input = PASSTHROUGH_INPUT
fxc_vs_$${vs}.dependency_type = TYPE_C
@@ -226,7 +226,7 @@ for (vs, VERTEX_SHADERS_PASSTHROUGH) {
QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
}
for (vs, VERTEX_SHADERS_CLEAR) {
- fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0_level_9_1 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
fxc_vs_$${vs}.input = CLEAR_INPUT
fxc_vs_$${vs}.dependency_type = TYPE_C
diff --git a/src/angle/src/src.pro b/src/angle/src/src.pro
index d1f5f57591..2b7d523207 100644
--- a/src/angle/src/src.pro
+++ b/src/angle/src/src.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
SUBDIRS += compiler libGLESv2 libEGL
+angle_d3d11: SUBDIRS += d3dcompiler
CONFIG += ordered
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index 9869d7e500..8b4685948e 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -121,7 +121,7 @@ void QPropertyAnimationPrivate::updateMetaProperty()
qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData());
} else if (!targetValue->metaObject()->property(propertyIndex).isWritable()) {
qWarning("QPropertyAnimation: you're trying to animate the non-writable property %s of your QObject", propertyName.constData());
- }
+ }
}
void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue)
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
index 51e67abfd4..5c3b0b78c2 100644
--- a/src/corelib/arch/arch.pri
+++ b/src/corelib/arch/arch.pri
@@ -1,20 +1,12 @@
win32|wince:HEADERS += arch/qatomic_msvc.h
-vxworks:HEADERS += arch/qatomic_vxworks.h
-integrity:HEADERS += arch/qatomic_integrity.h
HEADERS += \
- arch/qatomic_alpha.h \
arch/qatomic_armv5.h \
arch/qatomic_armv6.h \
arch/qatomic_armv7.h \
- arch/qatomic_bfin.h \
arch/qatomic_bootstrap.h \
arch/qatomic_ia64.h \
arch/qatomic_mips.h \
- arch/qatomic_power.h \
- arch/qatomic_s390.h \
- arch/qatomic_sh4a.h \
- arch/qatomic_sparc.h \
arch/qatomic_x86.h \
arch/qatomic_gcc.h \
arch/qatomic_cxx11.h
diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h
deleted file mode 100644
index 5008a1acda..0000000000
--- a/src/corelib/arch/qatomic_alpha.h
+++ /dev/null
@@ -1,527 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_ALPHA_H
-#define QATOMIC_ALPHA_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return true; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-#if defined(Q_CC_GNU)
-
-inline bool QBasicAtomicInt::ref()
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "addl %0,1,%1\n" /* tmp=old+1; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- :
- : "memory");
- return old != -1;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "subl %0,1,%1\n" /* tmp=old-1; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- :
- : "memory");
- return old != 1;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- int ret;
- asm volatile("1:\n"
- "ldl_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
- "beq %0,3f\n" /* if (ret==0) goto 3; */
- "mov %3,%0\n" /* ret=newval; */
- "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- int ret;
- asm volatile("1:\n"
- "ldl_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
- "beq %0,3f\n" /* if (ret==0) goto 3; */
- "mov %3,%0\n" /* ret=newval; */
- "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- int ret;
- asm volatile("mb\n"
- "1:\n"
- "ldl_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
- "beq %0,3f\n" /* if (ret==0) goto 3; */
- "mov %3,%0\n" /* ret=newval; */
- "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- int old, tmp;
- asm volatile("mb\n"
- "1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "addl %0,%3,%1\n"/* tmp=old+value; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return old;
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- int old, tmp;
- asm volatile("1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "addl %0,%3,%1\n"/* tmp=old+value; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return old;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- int old, tmp;
- asm volatile("mb\n"
- "1:\n"
- "ldl_l %0,%2\n" /* old=*ptr; */
- "addl %0,%3,%1\n"/* tmp=old+value; */
- "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return old;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- void *ret;
- asm volatile("1:\n"
- "ldq_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
- "beq %0,3f\n" /* if (tmp==0) goto 3; */
- "mov %3,%0\n" /* tmp=newval; */
- "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- void *ret;
- asm volatile("1:\n"
- "ldq_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
- "beq %0,3f\n" /* if (tmp==0) goto 3; */
- "mov %3,%0\n" /* tmp=newval; */
- "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- void *ret;
- asm volatile("mb\n"
- "1:\n"
- "ldq_l %0,%1\n" /* ret=*ptr; */
- "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
- "beq %0,3f\n" /* if (tmp==0) goto 3; */
- "mov %3,%0\n" /* tmp=newval; */
- "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %0,2f\n" /* if (ret==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (ret), "+m" (_q_value)
- : "r" (expectedValue), "r" (newValue)
- : "memory");
- return ret != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- T *old, *tmp;
- asm volatile("1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- T *old, *tmp;
- asm volatile("1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- T *old, *tmp;
- asm volatile("mb\n"
- "1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "mov %3,%1\n" /* tmp=newval; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp==0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
- : "r" (newValue)
- : "memory");
- return old;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- T *old, *tmp;
- asm volatile("1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "addq %0,%3,%1\n"/* tmp=old+value; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return reinterpret_cast<T *>(old);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- T *old, *tmp;
- asm volatile("1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "addq %0,%3,%1\n"/* tmp=old+value; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- "mb\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return reinterpret_cast<T *>(old);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- T *old, *tmp;
- asm volatile("mb\n"
- "1:\n"
- "ldq_l %0,%2\n" /* old=*ptr; */
- "addq %0,%3,%1\n"/* tmp=old+value; */
- "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
- "beq %1,2f\n" /* if (tmp == 0) goto 2; */
- "br 3f\n" /* goto 3; */
- "2: br 1b\n" /* goto 1; */
- "3:\n"
- : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
- : "r" (valueToAdd)
- : "memory");
- return reinterpret_cast<T *>(old);
-}
-
-#else
-# error "This compiler for Alpha is not supported"
-#endif // Q_CC_GNU
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_ALPHA_H
diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h
index b583ec662c..6939650c54 100644
--- a/src/corelib/arch/qatomic_armv5.h
+++ b/src/corelib/arch/qatomic_armv5.h
@@ -72,9 +72,6 @@ QT_END_NAMESPACE
# error "Qt is misconfigured: this ARMv5 implementation is only possible on Linux"
#endif
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
{
// kernel places a restartable cmpxchg implementation at a fixed address
@@ -136,13 +133,16 @@ bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW
}
template<> template <typename T> inline
-bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T originalValue;
do {
originalValue = _q_value;
- if (originalValue != expectedValue)
+ if (originalValue != expectedValue) {
+ if (currentValue)
+ *currentValue = originalValue;
return false;
+ }
} while (_q_cmpxchg(expectedValue, newValue, &_q_value) != 0);
return true;
}
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h
index 08b2b02133..4f1c758ded 100644
--- a/src/corelib/arch/qatomic_armv6.h
+++ b/src/corelib/arch/qatomic_armv6.h
@@ -69,16 +69,6 @@ QT_END_NAMESPACE
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-#if defined(Q_COMPILER_UNICODE_STRINGS) && !defined(Q_PROCESSOR_ARM_V6)
-// for ARMv5, ensure that char32_t (an uint_least32_t), is 32-bit
-// it's extremely unlikely it won't be on a 32-bit ARM, but just to be sure
-// For ARMv6 and up, we're sure it works, but the definition is below
-template<> struct QAtomicIntegerTraits<char32_t>
-{ enum { IsInteger = sizeof(char32_t) == sizeof(int) ? 1 : -1 }; };
-#endif
-
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
{
template <typename T>
@@ -91,6 +81,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue,
+ T newValue, T *currentValue) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW;
@@ -173,6 +165,29 @@ bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
}
template<> template <typename T> inline
+bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ register T tempValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[tempValue], [%[_q_value]]\n"
+ "eors %[result], %[tempValue], %[expectedValue]\n"
+ "itt eq\n"
+ "strexeq %[result], %[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ *currentValue = tempValue;
+ return result == 0;
+}
+
+template<> template <typename T> inline
T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
T originalValue;
@@ -220,20 +235,9 @@ T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy
|| defined(__ARM_ARCH_6K__)
// LDREXB, LDREXH and LDREXD are available on ARMv6K or higher
-template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
-
-# ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-# endif
+template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
#define Q_ATOMIC_INT8_IS_SUPPORTED
#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
@@ -312,6 +316,29 @@ bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
}
template<> template <typename T> inline
+bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ register T tempValue;
+ register T result;
+ asm volatile("0:\n"
+ "ldrexb %[tempValue], [%[_q_value]]\n"
+ "eors %[result], %[tempValue], %[expectedValue]\n"
+ "itt eq\n"
+ "strexbeq %[result], %[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ *currentValue = tempValue;
+ return result == 0;
+}
+
+template<> template <typename T> inline
T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
T originalValue;
@@ -411,6 +438,29 @@ bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
}
template<> template <typename T> inline
+bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ register T tempValue;
+ register T result;
+ asm volatile("0:\n"
+ "ldrexh %[tempValue], [%[_q_value]]\n"
+ "eors %[result], %[tempValue], %[expectedValue]\n"
+ "itt eq\n"
+ "strexheq %[result], %[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ *currentValue = tempValue;
+ return result == 0;
+}
+
+template<> template <typename T> inline
T QBasicAtomicOps<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
T originalValue;
@@ -522,6 +572,31 @@ bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
}
template<> template <typename T> inline
+bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ register T tempValue;
+ register T result;
+ asm volatile("0:\n"
+ "ldrexd %[tempValue], %H[tempValue], [%[_q_value]]\n"
+ "eor %[result], %[tempValue], %[expectedValue]\n"
+ "eor %H[result], %H[tempValue], %H[expectedValue]\n"
+ "orrs %[result], %[result], %H[result]\n"
+ "itt eq\n"
+ "strexdeq %[result], %[newValue], %H[newValue], [%[_q_value]]\n"
+ "teqeq %[result], #1\n"
+ "beq 0b\n"
+ : [result] "=&r" (result),
+ [tempValue] "=&r" (tempValue),
+ "+m" (_q_value)
+ : [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ *currentValue = tempValue;
+ return quint32(result) == 0;
+}
+
+template<> template <typename T> inline
T QBasicAtomicOps<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
T originalValue;
diff --git a/src/corelib/arch/qatomic_bfin.h b/src/corelib/arch/qatomic_bfin.h
deleted file mode 100644
index 79519308a4..0000000000
--- a/src/corelib/arch/qatomic_bfin.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_BFIN_H
-#define QATOMIC_BFIN_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return false; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return false; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <asm/fixed_code.h>
-QT_END_INCLUDE_NAMESPACE
-
-inline bool QBasicAtomicInt::ref()
-{
- int ret;
- asm volatile("R0 = 1;\n\t"
- "P0 = %3;\n\t"
- "CALL (%2);\n\t"
- "%0 = R0;"
- : "=da" (ret), "=m" (_q_value)
- : "a" (ATOMIC_ADD32), "da" (&_q_value), "m" (_q_value)
- : "R0", "R1", "P0", "RETS", "memory");
- return ret != 0;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- int ret;
- asm volatile("R0 = 1;\n\t"
- "P0 = %3;\n\t"
- "CALL (%2);\n\t"
- "%0 = R0;"
- : "=da" (ret), "=m" (_q_value)
- : "a" (ATOMIC_SUB32), "da" (&_q_value), "m" (_q_value)
- : "R0", "R1", "P0", "RETS", "memory");
- return ret != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- long int readval;
- asm volatile ("P0 = %2;\n\t"
- "R1 = %3;\n\t"
- "R2 = %4;\n\t"
- "CALL (%5);\n\t"
- "%0 = R0;\n\t"
- : "=da" (readval), "=m" (_q_value)
- : "da" (&_q_value),
- "da" (expectedValue),
- "da" (newValue),
- "a" (ATOMIC_CAS32),
- "m" (_q_value)
- : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
- return readval == expectedValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- asm volatile("R1 = %2;\n\t"
- "P0 = %4;\n\t"
- "CALL (%3);\n\t"
- "%0 = R0;"
- : "=da" (newValue), "=m" (_q_value)
- : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
- : "R0", "R1", "P0", "RETS", "memory");
- return newValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- int ret;
- asm volatile("R0 = %[val];\n\t"
- "P0 = %[qvalp];\n\t"
- "CALL (%[addr]);\n\t"
- "%[ret] = R1;"
- : [ret] "=da" (ret), "=m" (_q_value)
- : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd)
- : "R0", "R1", "P0", "RETS", "memory");
- return ret;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- T *readval;
- asm volatile ("P0 = %2;\n\t"
- "R1 = %3;\n\t"
- "R2 = %4;\n\t"
- "CALL (%5);\n\t"
- "%0 = R0;\n\t"
- : "=da" (readval), "=m" (_q_value)
- : "da" (&_q_value),
- "da" (expectedValue),
- "da" (newValue),
- "a" (ATOMIC_CAS32),
- "m" (_q_value)
- : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
- return readval == expectedValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- asm volatile("R1 = %2;\n\t"
- "P0 = %4;\n\t"
- "CALL (%3);\n\t"
- "%0 = R0;"
- : "=da" (newValue), "=m" (_q_value)
- : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
- : "R0", "R1", "P0", "RETS", "memory");
- return newValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- T* ret;
- asm volatile("R0 = %[val];\n\t"
- "P0 = %[qvalp];\n\t"
- "CALL (%[addr]);\n\t"
- "%[ret] = R1;"
- : [ret] "=da" (ret), "=m" (_q_value)
- : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd * sizeof(T))
- : "R0", "R1", "P0", "RETS", "memory");
- return ret;
-}
-
-
-#endif // Q_OS_LINUX && Q_CC_GNU
-
-// Test and set for integers
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for integers
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for integers
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-// Test and set for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_BFIN_H
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h
index 160e0abdf3..7f17387c9c 100644
--- a/src/corelib/arch/qatomic_bootstrap.h
+++ b/src/corelib/arch/qatomic_bootstrap.h
@@ -54,7 +54,6 @@ QT_END_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
{
typedef T Type;
diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h
index 55e71e1e88..b07e470484 100644
--- a/src/corelib/arch/qatomic_cxx11.h
+++ b/src/corelib/arch/qatomic_cxx11.h
@@ -70,22 +70,9 @@ QT_END_NAMESPACE
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
-
-# ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-# endif
+template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
#define Q_ATOMIC_INT8_IS_SUPPORTED
#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
@@ -162,28 +149,40 @@ template <typename X> struct QAtomicOps
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T> static
- bool testAndSetRelaxed(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+ template <typename T>
+ static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
{
- return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed);
+ if (currentValue)
+ *currentValue = expectedValue;
+ return tmp;
}
template <typename T>
- static bool testAndSetAcquire(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+ static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
{
- return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire);
+ if (currentValue)
+ *currentValue = expectedValue;
+ return tmp;
}
template <typename T>
- static bool testAndSetRelease(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+ static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
{
- return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release);
+ if (currentValue)
+ *currentValue = expectedValue;
+ return tmp;
}
template <typename T>
- static bool testAndSetOrdered(Type &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+ static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
{
- return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel);
+ bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel);
+ if (currentValue)
+ *currentValue = expectedValue;
+ return tmp;
}
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h
index 61e709655d..5184293465 100644
--- a/src/corelib/arch/qatomic_gcc.h
+++ b/src/corelib/arch/qatomic_gcc.h
@@ -53,12 +53,6 @@ QT_END_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-#ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-#endif
-
#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
@@ -75,6 +69,15 @@ template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+#if QT_POINTER_SIZE == 8
+# define Q_ATOMIC_INT64_IS_SUPPORTED
+# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_TEST_AND_SET_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
+#endif
+
template <typename X> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<X> >
{
// The GCC intrinsics all have fully-ordered memory semantics, so we define
@@ -110,6 +113,17 @@ template <typename X> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<X> >
}
template <typename T>
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+ {
+ bool tmp = __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue);
+ if (tmp)
+ *currentValue = expectedValue;
+ else
+ *currentValue = _q_value;
+ return tmp;
+ }
+
+ template <typename T>
static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
return __sync_lock_test_and_set(&_q_value, newValue);
diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h
index 98937c7551..e5e93ec2b7 100644
--- a/src/corelib/arch/qatomic_ia64.h
+++ b/src/corelib/arch/qatomic_ia64.h
@@ -123,22 +123,9 @@ QT_END_NAMESPACE
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
-
-# ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-# endif
+template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
{
@@ -163,10 +150,10 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
- template <typename T> static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
- template <typename T> static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
- template <typename T> static bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
@@ -302,7 +289,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValu
x = &_q_value;
T *expectedValueCopy = expectedValue;
return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy))
- == quintptr(expectedValue));
+ == quintptr(expectedValue));
}
template <typename T>
@@ -315,7 +302,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValu
x = &_q_value;
T *expectedValueCopy = expectedValue;
return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy))
- == quintptr(expectedValue));
+ == quintptr(expectedValue));
}
template <typename T>
@@ -386,7 +373,7 @@ bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW
}
template<> template <typename T> inline
-bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -395,11 +382,13 @@ bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -408,11 +397,13 @@ bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -421,11 +412,13 @@ bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -434,11 +427,13 @@ bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -447,11 +442,13 @@ bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -460,11 +457,13 @@ bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -473,11 +472,13 @@ bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
template<> template <typename T> inline
-bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T ret;
asm volatile("mov ar.ccv=%2\n"
@@ -486,6 +487,8 @@ bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newVa
: "=r" (ret), "+m" (_q_value)
: "r" (expectedValue), "r" (newValue)
: "memory");
+ if (currentValue)
+ *currentValue = ret;
return ret == expectedValue;
}
diff --git a/src/corelib/arch/qatomic_integrity.h b/src/corelib/arch/qatomic_integrity.h
deleted file mode 100644
index f8cfc8ce5b..0000000000
--- a/src/corelib/arch/qatomic_integrity.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_INTEGRITY_H
-#define QATOMIC_INTEGRITY_H
-
-#include <QtCore/qoldbasicatomic.h>
-#include <INTEGRITY.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define qt_i2addr(a) reinterpret_cast<Address *>(const_cast<int *>(a))
-#define qt_p2addr(a) reinterpret_cast<Address *>(const_cast<void *>(a))
-#define qt_addr(a) reinterpret_cast<Address>(a)
-
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return false; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return true; }
-
-// Reference counting
-
-inline bool QBasicAtomicInt::ref()
-{
- int oldval;
- AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, 1);
- return _q_value != -1;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- int oldval;
- AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, -1U);
- return _q_value != 0;
-}
-
-// Test and set for integers
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return TestAndSet(qt_i2addr(&_q_value), expectedValue, newValue) == Success;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for integers
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- int old_val;
- do {
- old_val = _q_value;
- } while (TestAndSet(qt_i2addr(&_q_value), old_val, newValue) != Success);
- return old_val;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for integers
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- int old_val;
- do {
- old_val = _q_value;
- } while (TestAndSet(qt_i2addr(&_q_value), old_val, old_val + valueToAdd) != Success);
- return old_val;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-// Test and set for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return TestAndSet((Address*)&_q_value, qt_addr(expectedValue), qt_addr(newValue)) == Success;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- Address old_val;
- do {
- old_val = *reinterpret_cast<Address *>(const_cast<T *>(newValue));
- } while (TestAndSet(reinterpret_cast<Address *>(const_cast<T **>(&_q_value)), old_val, qt_addr(newValue)) != Success);
- return reinterpret_cast<T *>(old_val);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- AtomicModify(qt_p2addr(&_q_value), qt_addr(_q_value), qt_addr(_q_value) + valueToAdd * sizeof(T));
- return _q_value;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_INTEGRITY_H
-
diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h
index 6eb9613e31..463612212b 100644
--- a/src/corelib/arch/qatomic_mips.h
+++ b/src/corelib/arch/qatomic_mips.h
@@ -69,16 +69,6 @@ QT_END_NAMESPACE
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-#if defined(Q_COMPILER_UNICODE_STRINGS) && !defined(Q_PROCESSOR_MIPS_64)
-// for MIPS32, ensure that char32_t (an uint_least32_t), is 32-bit
-// it's extremely unlikely it won't be on a 32-bit MIPS, but just to be sure
-// For MIPS64, we're sure it works, but the definition is below
-template<> struct QAtomicIntegerTraits<char32_t>
-{ enum { IsInteger = sizeof(char32_t) == sizeof(int) ? 1 : -1 }; };
-#endif
-
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
{
template <typename T>
@@ -94,7 +84,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
- template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ template <typename T> static bool
+ testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW;
@@ -173,13 +164,13 @@ bool QBasicAtomicOps<4>::deref(T &_q_value) Q_DECL_NOTHROW
}
template<> template <typename T> inline
-bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T result;
T tempValue;
asm volatile("0:\n"
- "ll %[result], %[_q_value]\n"
- "xor %[result], %[result], %[expectedValue]\n"
+ "ll %[tempValue], %[_q_value]\n"
+ "xor %[result], %[tempValue], %[expectedValue]\n"
"bnez %[result], 0f\n"
"nop\n"
"move %[tempValue], %[newValue]\n"
@@ -193,6 +184,8 @@ bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
: [expectedValue] "r" (expectedValue),
[newValue] "r" (newValue)
: "cc", "memory");
+ if (currentValue)
+ *currentValue = tempValue;
return result == 0;
}
@@ -242,14 +235,7 @@ T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy
#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long long > { enum { IsInteger = 1 }; };
-
-#ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char16_t>
-{ enum { IsInteger = sizeof(char16_t) == sizeof(int) ? 1 : -1 }; };
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-#endif
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
template<> template<typename T> inline
bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW
@@ -290,13 +276,13 @@ bool QBasicAtomicOps<8>::deref(T &_q_value) Q_DECL_NOTHROW
}
template<> template <typename T> inline
-bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
T result;
T tempValue;
asm volatile("0:\n"
- "lld %[result], %[_q_value]\n"
- "xor %[result], %[result], %[expectedValue]\n"
+ "lld %[tempValue], %[_q_value]\n"
+ "xor %[result], %[tempValue], %[expectedValue]\n"
"bnez %[result], 0f\n"
"nop\n"
"move %[tempValue], %[newValue]\n"
@@ -310,6 +296,8 @@ bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
: [expectedValue] "r" (expectedValue),
[newValue] "r" (newValue)
: "cc", "memory");
+ if (currentValue)
+ *currentValue = tempValue;
return result == 0;
}
diff --git a/src/corelib/arch/qatomic_msvc.h b/src/corelib/arch/qatomic_msvc.h
index 4f91e3d9da..c660f78888 100644
--- a/src/corelib/arch/qatomic_msvc.h
+++ b/src/corelib/arch/qatomic_msvc.h
@@ -53,6 +53,11 @@
# define QT_INTERLOCKED_PROTOTYPE __cdecl
# define QT_INTERLOCKED_DECLARE_PROTOTYPES
# define QT_INTERLOCKED_INTRINSIC
+# define Q_ATOMIC_INT16_IS_SUPPORTED
+
+# ifdef _WIN64
+# define Q_ATOMIC_INT64_IS_SUPPORTED
+# endif
#else // Q_OS_WINCE
@@ -130,6 +135,20 @@ extern "C" {
__int64 QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
# endif
+# ifdef Q_ATOMIC_INT16_IS_SUPPORTED
+ short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment16 )(short QT_INTERLOCKED_VOLATILE *);
+ short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement16 )(short QT_INTERLOCKED_VOLATILE *);
+ short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange16 )(short QT_INTERLOCKED_VOLATILE *, short, short);
+ short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange16 )(short QT_INTERLOCKED_VOLATILE *, short);
+ short QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd16 )(short QT_INTERLOCKED_VOLATILE *, short);
+# endif
+# ifdef Q_ATOMIC_INT64_IS_SUPPORTED
+ __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Increment64 )(__int64 QT_INTERLOCKED_VOLATILE *);
+ __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Decrement64 )(__int64 QT_INTERLOCKED_VOLATILE *);
+ __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( CompareExchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64, __int64);
+ __int64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( Exchange64 )(__int64 QT_INTERLOCKED_VOLATILE *, __int64);
+ //above already: qint64 QT_INTERLOCKED_PROTOTYPE QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )(qint64 QT_INTERLOCKED_VOLATILE *, qint64);
+# endif
}
#endif // QT_INTERLOCKED_DECLARE_PROTOTYPES
@@ -158,21 +177,6 @@ extern "C" {
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interlocked* replacement macros
-#define QT_INTERLOCKED_INCREMENT(value) \
- QT_INTERLOCKED_FUNCTION(Increment)(value)
-
-#define QT_INTERLOCKED_DECREMENT(value) \
- QT_INTERLOCKED_FUNCTION(Decrement)(value)
-
-#define QT_INTERLOCKED_COMPARE_EXCHANGE(value, newValue, expectedValue) \
- QT_INTERLOCKED_FUNCTION(CompareExchange)((value), (newValue), (expectedValue))
-
-#define QT_INTERLOCKED_EXCHANGE(value, newValue) \
- QT_INTERLOCKED_FUNCTION(Exchange)((value), (newValue))
-
-#define QT_INTERLOCKED_EXCHANGE_ADD(value, valueToAdd) \
- QT_INTERLOCKED_FUNCTION(ExchangeAdd)((value), (valueToAdd))
-
#if defined(Q_OS_WINCE) || defined(__i386__) || defined(_M_IX86)
# define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \
@@ -258,72 +262,194 @@ QT_END_NAMESPACE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
-////////////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE
+
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE
+
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
-#ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE
+
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
#endif
-// No definition, needs specialization
-template <int N> struct QAtomicOpsBySize;
+#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
+# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE
-template <>
-struct QAtomicOpsBySize<4> : QGenericAtomicOps<QAtomicOpsBySize<4> >
-{
- // The 32-bit Interlocked*() API takes parameters as longs.
- typedef long Type;
+# define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE
+
+# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_WAIT_FREE
+
+# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+# define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE
+
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
+#endif
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+template <int N> struct QAtomicWindowsType { typedef typename QIntegerForSize<N>::Signed Type; };
+template <> struct QAtomicWindowsType<4> { typedef long Type; };
+
+
+template <int N> struct QAtomicOpsBySize : QGenericAtomicOps<QAtomicOpsBySize<N> >
+{
static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return true; }
- static bool ref(long &_q_value) Q_DECL_NOTHROW;
- static bool deref(long &_q_value) Q_DECL_NOTHROW;
+ template <typename T> static bool ref(T &_q_value) Q_DECL_NOTHROW;
+ template <typename T> static bool deref(T &_q_value) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
- static bool testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) Q_DECL_NOTHROW;
+ template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ template <typename T>
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
- static long fetchAndStoreRelaxed(long &_q_value, long newValue) Q_DECL_NOTHROW;
+ template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return true; }
- static long fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) Q_DECL_NOTHROW;
+ template <typename T> static T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW;
+
+private:
+ typedef typename QAtomicWindowsType<N>::Type Type;
+ template <typename T> static inline Type *atomic(T *t)
+ { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return reinterpret_cast<Type *>(t); }
+ template <typename T> static inline Type value(T t)
+ { Q_STATIC_ASSERT(sizeof(T) == sizeof(Type)); return Type(t); }
};
template <typename T>
struct QAtomicOps : QAtomicOpsBySize<sizeof(T)>
-{ };
+{
+ typedef T Type;
+};
+
+template<> template<typename T>
+inline bool QAtomicOpsBySize<4>::ref(T &_q_value) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Increment)(atomic(&_q_value)) != 0;
+}
+
+template<> template<typename T>
+inline bool QAtomicOpsBySize<4>::deref(T &_q_value) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Decrement)(atomic(&_q_value)) != 0;
+}
+
+template<> template<typename T>
+inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
+}
+
+template<> template <typename T>
+inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange)(atomic(&_q_value), newValue, expectedValue));
+ return *currentValue == expectedValue;
+}
+
+template<> template<typename T>
+inline T QAtomicOpsBySize<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Exchange)(atomic(&_q_value), value(newValue));
+}
+
+template<> template<typename T>
+inline T QAtomicOpsBySize<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(ExchangeAdd)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
+}
+
+#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
+template<> template<typename T>
+inline bool QAtomicOpsBySize<2>::ref(T &_q_value) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Increment16)(atomic(&_q_value)) != 0;
+}
+
+template<> template<typename T>
+inline bool QAtomicOpsBySize<2>::deref(T &_q_value) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Decrement16)(atomic(&_q_value)) != 0;
+}
-inline bool QAtomicOpsBySize<4>::ref(long &_q_value) Q_DECL_NOTHROW
+template<> template<typename T>
+inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
{
- return QT_INTERLOCKED_INCREMENT(&_q_value) != 0;
+ return QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
}
-inline bool QAtomicOpsBySize<4>::deref(long &_q_value) Q_DECL_NOTHROW
+template<> template <typename T>
+inline bool QAtomicOpsBySize<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
- return QT_INTERLOCKED_DECREMENT(&_q_value) != 0;
+ *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange16)(atomic(&_q_value), newValue, expectedValue));
+ return *currentValue == expectedValue;
}
-inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) Q_DECL_NOTHROW
+template<> template<typename T>
+inline T QAtomicOpsBySize<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
- return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) == expectedValue;
+ return QT_INTERLOCKED_FUNCTION(Exchange16)(atomic(&_q_value), value(newValue));
}
-inline long QAtomicOpsBySize<4>::fetchAndStoreRelaxed(long &_q_value, long newValue) Q_DECL_NOTHROW
+template<> template<typename T>
+inline T QAtomicOpsBySize<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(ExchangeAdd16)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
+}
+#endif
+
+#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
+template<> template<typename T>
+inline bool QAtomicOpsBySize<8>::ref(T &_q_value) Q_DECL_NOTHROW
{
- return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue);
+ return QT_INTERLOCKED_FUNCTION(Increment64)(atomic(&_q_value)) != 0;
}
-inline long QAtomicOpsBySize<4>::fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+template<> template<typename T>
+inline bool QAtomicOpsBySize<8>::deref(T &_q_value) Q_DECL_NOTHROW
{
- return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd * QAtomicAdditiveType<long>::AddScale);
+ return QT_INTERLOCKED_FUNCTION(Decrement64)(atomic(&_q_value)) != 0;
}
+template<> template<typename T>
+inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), value(newValue), value(expectedValue)) == value(expectedValue);
+}
+
+template<> template <typename T>
+inline bool QAtomicOpsBySize<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ *currentValue = T(QT_INTERLOCKED_FUNCTION(CompareExchange64)(atomic(&_q_value), newValue, expectedValue));
+ return *currentValue == expectedValue;
+}
+
+template<> template<typename T>
+inline T QAtomicOpsBySize<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(Exchange64)(atomic(&_q_value), value(newValue));
+}
+
+template<> template<typename T>
+inline T QAtomicOpsBySize<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+{
+ return QT_INTERLOCKED_FUNCTION(ExchangeAdd64)(atomic(&_q_value), value<T>(valueToAdd * QAtomicAdditiveType<T>::AddScale));
+}
+#endif
+
// Specialization for pointer types, since we have Interlocked*Pointer() variants in some configurations
template <typename T>
struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
@@ -333,6 +459,7 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) Q_DECL_NOTHROW;
+ static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
@@ -350,6 +477,13 @@ inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T
}
template <typename T>
+inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue, T **currentValue) Q_DECL_NOTHROW
+{
+ *currentValue = reinterpret_cast<T *>(QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue));
+ return *currentValue == expectedValue;
+}
+
+template <typename T>
inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) Q_DECL_NOTHROW
{
return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue));
diff --git a/src/corelib/arch/qatomic_power.h b/src/corelib/arch/qatomic_power.h
deleted file mode 100644
index 3ddd303795..0000000000
--- a/src/corelib/arch/qatomic_power.h
+++ /dev/null
@@ -1,521 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_POWER_H
-#define QATOMIC_POWER_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return true; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-#if defined(Q_CC_GNU)
-
-#ifdef Q_PROCESSOR_POWER_32
-# define _Q_VALUE "0, %[_q_value]"
-# define _Q_VALUE_MEMORY_OPERAND "+m" (_q_value)
-# define _Q_VALUE_REGISTER_OPERAND [_q_value] "r" (&_q_value),
-#else // Q_PROCESSOR_POWER_64
-# define _Q_VALUE "%y[_q_value]"
-# define _Q_VALUE_MEMORY_OPERAND [_q_value] "+Z" (_q_value)
-# define _Q_VALUE_REGISTER_OPERAND
-#endif
-
-inline bool QBasicAtomicInt::ref()
-{
- int originalValue;
- int newValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "addi %[newValue], %[originalValue], %[one]\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&b" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [one] "i" (1)
- : "cc", "memory");
- return newValue != 0;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- int originalValue;
- int newValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "addi %[newValue], %[originalValue], %[minusOne]\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&b" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [minusOne] "i" (-1)
- : "cc", "memory");
- return newValue != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- int result;
- asm volatile("lwarx %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+12\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- int result;
- asm volatile("lwarx %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+16\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- "isync\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- int result;
- asm volatile("eieio\n"
- "lwarx %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+12\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- int originalValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- int originalValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- "isync\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- int originalValue;
- asm volatile("eieio\n"
- "lwarx %[originalValue]," _Q_VALUE "\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- int originalValue;
- int newValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd)
- : "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- int originalValue;
- int newValue;
- asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- "isync\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd)
- : "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- int originalValue;
- int newValue;
- asm volatile("eieio\n"
- "lwarx %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- "stwcx. %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd)
- : "cc", "memory");
- return originalValue;
-}
-
-#ifdef Q_PROCESSOR_POWER_64
-# define LPARX "ldarx"
-# define STPCX "stdcx."
-#else
-# define LPARX "lwarx"
-# define STPCX "stwcx."
-#endif
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- void *result;
- asm volatile(LPARX" %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+12\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- void *result;
- asm volatile(LPARX" %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+16\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- "isync\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- void *result;
- asm volatile("eieio\n"
- LPARX" %[result]," _Q_VALUE "\n"
- "xor. %[result], %[result], %[expectedValue]\n"
- "bne $+12\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-16\n"
- : [result] "=&r" (result),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- T *originalValue;
- asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- T *originalValue;
- asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- "isync\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- T *originalValue;
- asm volatile("eieio\n"
- LPARX" %[originalValue]," _Q_VALUE "\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-8\n"
- : [originalValue] "=&r" (originalValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [newValue] "r" (newValue)
- : "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- T *originalValue;
- T *newValue;
- asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- T *originalValue;
- T *newValue;
- asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- "isync\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- T *originalValue;
- T *newValue;
- asm volatile("eieio\n"
- LPARX" %[originalValue]," _Q_VALUE "\n"
- "add %[newValue], %[originalValue], %[valueToAdd]\n"
- STPCX" %[newValue]," _Q_VALUE "\n"
- "bne- $-12\n"
- : [originalValue] "=&r" (originalValue),
- [newValue] "=&r" (newValue),
- _Q_VALUE_MEMORY_OPERAND
- : _Q_VALUE_REGISTER_OPERAND
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "cc", "memory");
- return originalValue;
-}
-
-#undef LPARX
-#undef STPCX
-#undef _Q_VALUE
-#undef _Q_VALUE_MEMORY_OPERAND
-#undef _Q_VALUE_REGISTER_OPERAND
-
-#else
-# error "This compiler for Power/PowerPC is not supported"
-#endif
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_POWER_H
diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h
deleted file mode 100644
index 0469f44e5f..0000000000
--- a/src/corelib/arch/qatomic_s390.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_S390_H
-#define QATOMIC_S390_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return true; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-#ifdef __GNUC__
-#define __GNU_EXTENSION __extension__
-#else
-#define __GNU_EXTENSION
-#endif
-
-#define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
- volatile int old_val, new_val; \
- __asm__ __volatile__(pre \
- " l %0,0(%3)\n" \
- "0: lr %1,%0\n" \
- op_string " %1,%4\n" \
- " cs %0,%1,0(%3)\n" \
- " jl 0b\n" \
- post \
- : "=&d" (old_val), "=&d" (new_val), \
- "=m" (*ptr) \
- : "a" (ptr), "d" (op_val), \
- "m" (*ptr) \
- : "cc", "memory" ); \
- new_val; \
-})
-
-#define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ \
- volatile int old_val, new_val; \
- __asm__ __volatile__(pre \
- " l %0,0(%3)\n" \
- "0: lr %1,%0\n" \
- op_string " %1,%4\n" \
- " cs %0,%1,0(%3)\n" \
- " jl 0b\n" \
- post \
- : "=&d" (old_val), "=&d" (new_val), \
- "=m" (*ptr) \
- : "a" (ptr), "d" (op_val), \
- "m" (*ptr) \
- : "cc", "memory" ); \
- old_val; \
-})
-
-#ifdef __s390x__
-#define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
- long old_val, new_val; \
- __asm__ __volatile__(pre \
- " lg %0,0(%3)\n" \
- "0: lgr %1,%0\n" \
- op_string " %1,%4\n" \
- " csg %0,%1,0(%3)\n" \
- " jl 0b\n" \
- post \
- : "=&d" (old_val), "=&d" (new_val), \
- "=m" (*ptr) \
- : "a" (ptr), "d" (op_val), \
- "m" (*ptr) \
- : "cc", "memory" ); \
- old_val; \
-})
-#endif
-
-inline bool QBasicAtomicInt::ref()
-{
- return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- int retval;
- __asm__ __volatile__(
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
- return retval == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- int retval;
- __asm__ __volatile__(
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:\n"
- " bcr 15,0\n"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
- return retval == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- int retval;
- __asm__ __volatile__(
- " bcr 15,0\n"
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
- return retval == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "");
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0\n");
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0\n", "");
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0\n");
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- int retval;
-
-#ifndef __s390x__
- __asm__ __volatile__(
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#else
- __asm__ __volatile__(
- " lgr %0,%3\n"
- " csg %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#endif
-
- return retval == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- int retval;
-
-#ifndef __s390x__
- __asm__ __volatile__(
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:\n"
- " bcr 15,0\n"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#else
- __asm__ __volatile__(
- " lgr %0,%3\n"
- " csg %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:\n"
- " bcr 15,0\n"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#endif
-
- return retval == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- int retval;
-
-#ifndef __s390x__
- __asm__ __volatile__(
- " bcr 15,0\n"
- " lr %0,%3\n"
- " cs %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#else
- __asm__ __volatile__(
- " bcr 15,0\n"
- " lgr %0,%3\n"
- " csg %0,%4,0(%2)\n"
- " ipm %0\n"
- " srl %0,28\n"
- "0:"
- : "=&d" (retval), "=m" (_q_value)
- : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
- "m" (_q_value) : "cc", "memory" );
-#endif
-
- return retval == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
-#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "");
-#else
- return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "");
-#endif
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
-#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n");
-#else
- return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n");
-#endif
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
-#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", "");
-#else
- return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", "");
-#endif
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-#undef __GNU_EXTENSION
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_S390_H
diff --git a/src/corelib/arch/qatomic_sh4a.h b/src/corelib/arch/qatomic_sh4a.h
deleted file mode 100644
index 6e59279f3e..0000000000
--- a/src/corelib/arch/qatomic_sh4a.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_SH4A_H
-#define QATOMIC_SH4A_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-
-QT_END_NAMESPACE
-
-#if 0
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return true; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-QT_BEGIN_NAMESPACE
-
-#if !defined(Q_CC_GNU)
-# error "SH-4A support has not been added for this compiler"
-#else
-
-inline bool QBasicAtomicInt::ref()
-{
- register int newValue asm("r0");
- asm volatile("0:\n"
- "movli.l @%[_q_value], %[newValue]\n"
- "add #1,%[newValue]\n"
- "movco.l %[newValue], @%[_q_value]\n"
- "bf 0b\n"
- : [newValue] "=&r" (newValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value)
- : "cc", "memory");
- return newValue != 0;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- register int newValue asm("r0");
- asm volatile("0:\n"
- "movli.l @%[_q_value], %[newValue]\n"
- "add #-1,%[newValue]\n"
- "movco.l %[newValue], @%[_q_value]\n"
- "bf 0b\n"
- : [newValue] "=&r" (newValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value)
- : "cc", "memory");
- return newValue != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- int result;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- int result;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- int result;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- int originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- int originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- int originalValue;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- int originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- int originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- int originalValue;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- T *result;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- T *result;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- T *result;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "xor %[expectedValue], r0\n"
- "cmp/eq #0, r0\n"
- "bf/s 0f\n"
- "mov r0, %[result]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "0:\n"
- : [result] "=&r" (result),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [expectedValue] "r" (expectedValue),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return result == 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return testAndSetAcquire(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- T *originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- T *originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- T *originalValue;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "mov %[newValue], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [newValue] "r" (newValue)
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return fetchAndStoreAcquire(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- T *originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- T *originalValue;
- asm volatile("0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- "synco\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- T *originalValue;
- asm volatile("synco\n"
- "0:\n"
- "movli.l @%[_q_value], r0\n"
- "mov r0, %[originalValue]\n"
- "add %[valueToAdd], r0\n"
- "movco.l r0, @%[_q_value]\n"
- "bf 0b\n"
- : [originalValue] "=&r" (originalValue),
- "+m" (_q_value)
- : [_q_value] "r" (&_q_value),
- [valueToAdd] "r" (valueToAdd * sizeof(T))
- : "r0", "cc", "memory");
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- return fetchAndAddAcquire(valueToAdd);
-}
-
-#endif // Q_CC_GNU
-
-#endif // QATOMIC_SH4A_H
diff --git a/src/corelib/arch/qatomic_sparc.h b/src/corelib/arch/qatomic_sparc.h
deleted file mode 100644
index 8aea33ce85..0000000000
--- a/src/corelib/arch/qatomic_sparc.h
+++ /dev/null
@@ -1,532 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_SPARC_H
-#define QATOMIC_SPARC_H
-
-#include <QtCore/qoldbasicatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#if defined(_LP64)
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return true; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return true; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-extern "C" {
- Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
- Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
-
- Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
- Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr,
- int expected,
- int newval);
- Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr,
- int expected,
- int newval);
-
- Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
- Q_CORE_EXPORT int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newval);
- Q_CORE_EXPORT int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newval);
-
- Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
- Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
- Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
-
- Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, const void *expected, const void *newval);
- Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr,
- const void *expected,
- const void *newval);
- Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr,
- const void *expected,
- const void *newval);
-
- Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, const void *newval);
- Q_CORE_EXPORT void *q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, const void *newval);
- Q_CORE_EXPORT void *q_atomic_fetch_and_store_release_ptr(volatile void *ptr, const void *newval);
-
- Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value);
- Q_CORE_EXPORT void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, int value);
- Q_CORE_EXPORT void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, int value);
-}
-
-inline bool QBasicAtomicInt::ref()
-{
- return fetchAndAddRelaxed(1) != -1;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- return fetchAndAddRelaxed(-1) != 1;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
-}
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return q_atomic_set_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int newValue)
-{
- return q_atomic_fetch_and_add_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int newValue)
-{
- return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int newValue)
-{
- return q_atomic_fetch_and_add_release_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int newValue)
-{
- return q_atomic_fetch_and_add_acquire_int(&_q_value, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE
-T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T)));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
-}
-
-#else
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return false; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return false; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return true; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return true; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return true; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-extern "C" {
- Q_CORE_EXPORT int q_atomic_lock_int(volatile int *addr);
- Q_CORE_EXPORT int q_atomic_lock_ptr(volatile void *addr);
- Q_CORE_EXPORT void q_atomic_unlock(volatile void *addr, int value);
- Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
- Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
-} // extern "C"
-
-inline bool QBasicAtomicInt::ref()
-{
- const int val = q_atomic_lock_int(&_q_value);
- q_atomic_unlock(&_q_value, val + 1);
- return val != -1;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- const int val = q_atomic_lock_int(&_q_value);
- q_atomic_unlock(&_q_value, val - 1);
- return val != 1;
-}
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- int val = q_atomic_lock_int(&_q_value);
- if (val == expectedValue) {
- q_atomic_unlock(&_q_value, newValue);
- return true;
- }
- q_atomic_unlock(&_q_value, val);
- return false;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- return q_atomic_set_int(&_q_value, newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- const int originalValue = q_atomic_lock_int(&_q_value);
- q_atomic_unlock(&_q_value, originalValue + valueToAdd);
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- T *val = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
- if (val == expectedValue) {
- q_atomic_unlock(&_q_value, reinterpret_cast<int>(newValue));
- return true;
- }
- q_atomic_unlock(&_q_value, reinterpret_cast<int>(val));
- return false;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- T *originalValue = reinterpret_cast<T *>(q_atomic_lock_ptr(&_q_value));
- q_atomic_unlock(&_q_value, int(originalValue + valueToAdd));
- return originalValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-#endif // _LP64
-
-QT_END_NAMESPACE
-
-#endif // QATOMIC_SPARC_H
diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp
index 4acf43d6a5..7a5c48c235 100644
--- a/src/corelib/arch/qatomic_unix.cpp
+++ b/src/corelib/arch/qatomic_unix.cpp
@@ -65,6 +65,19 @@ bool QAtomicOps<int>::testAndSetRelaxed(int &_q_value, int expectedValue, int ne
}
Q_CORE_EXPORT
+bool QAtomicOps<long long>::testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
bool QAtomicOps<void *>::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue) Q_DECL_NOTHROW
{
bool returnValue = false;
diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h
index 03c7d2eee8..6ed9864073 100644
--- a/src/corelib/arch/qatomic_unix.h
+++ b/src/corelib/arch/qatomic_unix.h
@@ -59,16 +59,25 @@ QT_END_NAMESPACE
#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
#define Q_ATOMIC_INT32_IS_SUPPORTED
+#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NOT_NATIVE
+#define Q_ATOMIC_INT32_TEST_AND_SET_IS_NOT_NATIVE
+#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NOT_NATIVE
+#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NOT_NATIVE
+
+#define Q_ATOMIC_INT64_IS_SUPPORTED
+#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_TEST_AND_SET_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NOT_NATIVE
+#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NOT_NATIVE
#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-
// No definition, needs specialization
template <typename T> struct QAtomicOps;
+// 32-bit version
template <>
struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> >
{
@@ -79,6 +88,18 @@ struct QAtomicOps<int> : QGenericAtomicOps<QAtomicOps<int> >
Q_CORE_EXPORT static bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue) Q_DECL_NOTHROW;
};
+// 64-bit version
+template <>
+struct QAtomicOps<long long> : QGenericAtomicOps<QAtomicOps<long long> >
+{
+ typedef long long Type;
+
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return false; }
+ static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW;
+};
+
+// pointer version
template <>
struct QAtomicOps<void *> : QGenericAtomicOps<QAtomicOps<void *> >
{
@@ -109,5 +130,23 @@ struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> >
}
};
+// 32- and 64-bit unsigned versions
+template <> struct QAtomicOps<unsigned> : QAtomicOps<int>
+{
+ typedef unsigned Type;
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ {
+ return QAtomicOps<int>::testAndSetRelaxed(reinterpret_cast<int &>(_q_value), int(expectedValue), int(newValue));
+ }
+};
+template <> struct QAtomicOps<unsigned long long> : QAtomicOps<long long>
+{
+ typedef unsigned long longType;
+ Q_CORE_EXPORT static bool testAndSetRelaxed(Type &_q_value, Type expectedValue, Type newValue) Q_DECL_NOTHROW
+ {
+ return QAtomicOps<long long>::testAndSetRelaxed(reinterpret_cast<long long &>(_q_value), int(expectedValue), int(newValue));
+ }
+};
+
QT_END_NAMESPACE
#endif // QATOMIC_UNIX_H
diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h
deleted file mode 100644
index 57e3b6a32b..0000000000
--- a/src/corelib/arch/qatomic_vxworks.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the qmake spec of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QATOMIC_VXWORKS_H
-#define QATOMIC_VXWORKS_H
-
-#if defined(__ppc)
-# include <QtCore/qatomic_power.h>
-#else // generic implementation with taskLock()
-
-#include <QtCore/qoldbasicatomic.h>
-
-#if 0
-// we don't want to include the system header here for two function prototypes,
-// because it pulls in a _lot_ of stuff that pollutes the global namespace
-# include <vxWorksCommon.h>
-# include <taskLib.h>
-#else
-#if defined(_WRS_KERNEL)
-extern "C" int taskLock();
-extern "C" int taskUnlock();
-#else
-inline int taskLock() { return 0; }
-inline int taskUnlock() { return 0; }
-#endif
-#endif
-
-
-
-QT_BEGIN_NAMESPACE
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-QT_END_HEADER
-
-#pragma qt_sync_skip_header_check
-#pragma qt_sync_stop_processing
-#endif
-
-#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isReferenceCountingNative()
-{ return false; }
-inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isTestAndSetNative()
-{ return false; }
-inline bool QBasicAtomicInt::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndStoreNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
-
-inline bool QBasicAtomicInt::isFetchAndAddNative()
-{ return false; }
-inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
-{ return false; }
-
-#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
-{ return false; }
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
-{ return false; }
-
-// Reference counting
-
-inline bool QBasicAtomicInt::ref()
-{
- taskLock();
- bool ret = (++_q_value != 0);
- taskUnlock();
- return ret;
-}
-
-inline bool QBasicAtomicInt::deref()
-{
- taskLock();
- bool ret = (--_q_value != 0);
- taskUnlock();
- return ret;
-}
-
-// Test-and-set for integers
-
-inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
-{
- taskLock();
- if (_q_value == expectedValue) {
- _q_value = newValue;
- taskUnlock();
- return true;
- }
- taskUnlock();
- return false;
-}
-
-inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch-and-store for integers
-
-inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
-{
- taskLock();
- int returnValue = _q_value;
- _q_value = newValue;
- taskUnlock();
- return returnValue;
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch-and-add for integers
-
-inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
-{
- taskLock();
- int originalValue = _q_value;
- _q_value += valueToAdd;
- taskUnlock();
- return originalValue;
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-// Test and set for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
-{
- taskLock();
- if (_q_value == expectedValue) {
- _q_value = newValue;
- taskUnlock();
- return true;
- }
- taskUnlock();
- return false;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
-{
- return testAndSetOrdered(expectedValue, newValue);
-}
-
-// Fetch and store for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
-{
- taskLock();
- T *returnValue = (_q_value);
- _q_value = newValue;
- taskUnlock();
- return returnValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
-{
- return fetchAndStoreOrdered(newValue);
-}
-
-// Fetch and add for pointers
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
-{
- taskLock();
- T *returnValue = (_q_value);
- _q_value += valueToAdd;
- taskUnlock();
- return returnValue;
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-template <typename T>
-Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
-{
- return fetchAndAddOrdered(valueToAdd);
-}
-
-QT_END_NAMESPACE
-
-#endif // generic implementation with taskLock()
-
-#endif // QATOMIC_VXWORKS_H
diff --git a/src/corelib/arch/qatomic_x86.h b/src/corelib/arch/qatomic_x86.h
index f8180ad9d6..e3cb296527 100644
--- a/src/corelib/arch/qatomic_x86.h
+++ b/src/corelib/arch/qatomic_x86.h
@@ -89,9 +89,6 @@ QT_END_NAMESPACE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE
-template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; };
-
template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> >
{
static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return true; }
@@ -102,6 +99,8 @@ template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<si
static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return true; }
template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW;
+ template <typename T> static bool
+ testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW;
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return true; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return true; }
@@ -120,21 +119,9 @@ template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)>
#if defined(Q_CC_GNU)
-template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; };
-
-# ifdef Q_COMPILER_UNICODE_STRINGS
-template<> struct QAtomicIntegerTraits<char16_t> { enum { IsInteger = 1 }; };
-template<> struct QAtomicIntegerTraits<char32_t> { enum { IsInteger = 1 }; };
-# endif
-
+template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
+template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
/*
* Guide for the inline assembly below:
@@ -268,6 +255,36 @@ bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
}
template<int size> template <typename T> inline
+bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue,
+ T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchg %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "r" (newValue), "0" (expectedValue)
+ : "memory");
+ *currentValue = newValue;
+ return ret != 0;
+}
+
+template<> template <typename T> inline
+bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue,
+ T newValue, T *currentValue) Q_DECL_NOTHROW
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "cmpxchg %3,%2\n"
+ "sete %1\n"
+ : "=a" (newValue), "=qm" (ret), "+m" (_q_value)
+ : "q" (newValue), "0" (expectedValue)
+ : "memory");
+ *currentValue = newValue;
+ return ret != 0;
+}
+
+template<int size> template <typename T> inline
T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue) Q_DECL_NOTHROW
{
asm volatile("xchg %0,%1"
@@ -339,6 +356,8 @@ T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy
#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE
+#ifdef Q_PROCESSOR_X86_64
+
#define Q_ATOMIC_INT64_IS_SUPPORTED
#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
@@ -353,7 +372,6 @@ T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveTy
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE
-#ifdef Q_PROCESSOR_X86_64
// native support for 64-bit types
template<> template<typename T> inline
bool QBasicAtomicOps<8>::ref(T &_q_value) Q_DECL_NOTHROW
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index e425f8634c..a5d16b0b54 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -44,10 +45,125 @@
#include "qendian.h"
#include "qchar.h"
+#include "private/qsimd_p.h"
+#include "private/qstringiterator_p.h"
+
QT_BEGIN_NAMESPACE
enum { Endian = 0, Data = 1 };
+#if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSE2)
+static inline bool simdEncodeAscii(uchar *&dst, const ushort *&nextAscii, const ushort *&src, const ushort *end)
+{
+ // do sixteen characters at a time
+ for ( ; end - src >= 16; src += 16, dst += 16) {
+ __m128i data1 = _mm_loadu_si128((__m128i*)src);
+ __m128i data2 = _mm_loadu_si128(1+(__m128i*)src);
+
+
+ // check if everything is ASCII
+ // the highest ASCII value is U+007F
+ // Do the packing directly:
+ // The PACKUSWB instruction has packs a signed 16-bit integer to an unsigned 8-bit
+ // with saturation. That is, anything from 0x0100 to 0x7fff is saturated to 0xff,
+ // while all negatives (0x8000 to 0xffff) get saturated to 0x00. To detect non-ASCII,
+ // we simply do a signed greater-than comparison to 0x00. That means we detect NULs as
+ // "non-ASCII", but it's an acceptable compromise.
+ __m128i packed = _mm_packus_epi16(data1, data2);
+ __m128i nonAscii = _mm_cmpgt_epi8(packed, _mm_setzero_si128());
+
+ // n will contain 1 bit set per character in [data1, data2] that is non-ASCII (or NUL)
+ ushort n = ~_mm_movemask_epi8(nonAscii);
+ if (n) {
+ // copy the front part that is still ASCII
+ while (!(n & 1)) {
+ *dst++ = *src++;
+ n >>= 1;
+ }
+
+ // find the next probable ASCII character
+ // we don't want to load 32 bytes again in this loop if we know there are non-ASCII
+ // characters still coming
+ n = _bit_scan_reverse(n);
+ nextAscii = src + n;
+ return false;
+ }
+
+ // pack
+ _mm_storeu_si128((__m128i*)dst, packed);
+ }
+ return src == end;
+}
+
+static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const uchar *&src, const uchar *end)
+{
+ // do sixteen characters at a time
+ for ( ; end - src >= 16; src += 16, dst += 16) {
+ __m128i data = _mm_loadu_si128((__m128i*)src);
+
+ // check if everything is ASCII
+ // movemask extracts the high bit of every byte, so n is non-zero if something isn't ASCII
+ uint n = _mm_movemask_epi8(data);
+ if (n) {
+ // copy the front part that is still ASCII
+ while (!(n & 1)) {
+ *dst++ = *src++;
+ n >>= 1;
+ }
+
+ // find the next probable ASCII character
+ // we don't want to load 16 bytes again in this loop if we know there are non-ASCII
+ // characters still coming
+ n = _bit_scan_reverse(n);
+ nextAscii = src + n;
+ return false;
+ }
+
+ // unpack
+ _mm_storeu_si128((__m128i*)dst, _mm_unpacklo_epi8(data, _mm_setzero_si128()));
+ _mm_storeu_si128(1+(__m128i*)dst, _mm_unpackhi_epi8(data, _mm_setzero_si128()));
+ }
+ return src == end;
+}
+#else
+static inline bool simdEncodeAscii(uchar *, const ushort *, const ushort *, const ushort *)
+{
+ return false;
+}
+
+static inline bool simdDecodeAscii(ushort *, const uchar *, const uchar *, const uchar *)
+{
+ return false;
+}
+#endif
+
+QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len)
+{
+ // create a QByteArray with the worst case scenario size
+ QByteArray result(len * 3, Qt::Uninitialized);
+ uchar *dst = reinterpret_cast<uchar *>(const_cast<char *>(result.constData()));
+ const ushort *src = reinterpret_cast<const ushort *>(uc);
+ const ushort *const end = src + len;
+
+ while (src != end) {
+ const ushort *nextAscii = end;
+ if (simdEncodeAscii(dst, nextAscii, src, end))
+ break;
+
+ do {
+ ushort uc = *src++;
+ int res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, dst, src, end);
+ if (res < 0) {
+ // encoding error - append '?'
+ *dst++ = '?';
+ }
+ } while (src < nextAscii);
+ }
+
+ result.truncate(dst - reinterpret_cast<uchar *>(const_cast<char *>(result.constData())));
+ return result;
+}
+
QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::ConverterState *state)
{
uchar replacement = '?';
@@ -62,61 +178,46 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve
surrogate_high = state->state_data[0];
}
- QByteArray rstr;
- rstr.resize(rlen);
- uchar* cursor = (uchar*)rstr.data();
- const QChar *ch = uc;
+
+ QByteArray rstr(rlen, Qt::Uninitialized);
+ uchar *cursor = reinterpret_cast<uchar *>(const_cast<char *>(rstr.constData()));
+ const ushort *src = reinterpret_cast<const ushort *>(uc);
+ const ushort *const end = src + len;
+
int invalid = 0;
if (state && !(state->flags & QTextCodec::IgnoreHeader)) {
+ // append UTF-8 BOM
*cursor++ = 0xef;
*cursor++ = 0xbb;
*cursor++ = 0xbf;
}
- const QChar *end = ch + len;
- while (ch < end) {
- uint u = ch->unicode();
- if (surrogate_high >= 0) {
- if (ch->isLowSurrogate()) {
- u = QChar::surrogateToUcs4(surrogate_high, u);
- surrogate_high = -1;
- } else {
- // high surrogate without low
- *cursor = replacement;
- ++ch;
- ++invalid;
- surrogate_high = -1;
- continue;
- }
- } else if (ch->isLowSurrogate()) {
- // low surrogate without high
- *cursor = replacement;
- ++ch;
- ++invalid;
- continue;
- } else if (ch->isHighSurrogate()) {
- surrogate_high = u;
- ++ch;
- continue;
+ const ushort *nextAscii = src;
+ while (src != end) {
+ int res;
+ ushort uc;
+ if (surrogate_high != -1) {
+ uc = surrogate_high;
+ surrogate_high = -1;
+ res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, cursor, src, end);
+ } else {
+ if (src >= nextAscii && simdEncodeAscii(cursor, nextAscii, src, end))
+ break;
+
+ uc = *src++;
+ res = QUtf8Functions::toUtf8<QUtf8BaseTraits>(uc, cursor, src, end);
}
+ if (Q_LIKELY(res >= 0))
+ continue;
- if (u < 0x80) {
- *cursor++ = (uchar)u;
- } else {
- if (u < 0x0800) {
- *cursor++ = 0xc0 | ((uchar) (u >> 6));
- } else {
- if (QChar::requiresSurrogates(u)) {
- *cursor++ = 0xf0 | ((uchar) (u >> 18));
- *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
- } else {
- *cursor++ = 0xe0 | (((uchar) (u >> 12)) & 0x3f);
- }
- *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
- }
- *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ if (res == QUtf8BaseTraits::Error) {
+ // encoding error
+ ++invalid;
+ *cursor++ = replacement;
+ } else if (res == QUtf8BaseTraits::EndOfString) {
+ surrogate_high = uc;
+ break;
}
- ++ch;
}
rstr.resize(cursor - (const uchar*)rstr.constData());
@@ -132,114 +233,127 @@ QByteArray QUtf8::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conve
return rstr;
}
+QString QUtf8::convertToUnicode(const char *chars, int len)
+{
+ QString result(len + 1, Qt::Uninitialized); // worst case
+ ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData()));
+ const uchar *src = reinterpret_cast<const uchar *>(chars);
+ const uchar *end = src + len;
+
+ while (src < end) {
+ const uchar *nextAscii = end;
+ if (simdDecodeAscii(dst, nextAscii, src, end))
+ break;
+
+ do {
+ uchar b = *src++;
+ int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, dst, src, end);
+ if (res < 0) {
+ // decoding error
+ *dst++ = QChar::ReplacementCharacter;
+ }
+ } while (src < nextAscii);
+ }
+
+ result.truncate(dst - reinterpret_cast<const ushort *>(result.constData()));
+ return result;
+}
+
QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::ConverterState *state)
{
bool headerdone = false;
ushort replacement = QChar::ReplacementCharacter;
int need = 0;
- int error = -1;
- uint uc = 0;
- uint min_uc = 0;
+ int invalid = 0;
+ int res;
+ uchar ch = 0;
+
+ QString result(need + len + 1, Qt::Uninitialized); // worst case
+ ushort *dst = reinterpret_cast<ushort *>(const_cast<QChar *>(result.constData()));
+ const uchar *src = reinterpret_cast<const uchar *>(chars);
+ const uchar *end = src + len;
+
if (state) {
if (state->flags & QTextCodec::IgnoreHeader)
headerdone = true;
if (state->flags & QTextCodec::ConvertInvalidToNull)
replacement = QChar::Null;
- need = state->remainingChars;
- if (need) {
- uc = state->state_data[0];
- min_uc = state->state_data[1];
- }
- }
- if (!headerdone && len > 3
- && (uchar)chars[0] == 0xef && (uchar)chars[1] == 0xbb && (uchar)chars[2] == 0xbf) {
- // starts with a byte order mark
- chars += 3;
- len -= 3;
- headerdone = true;
- }
-
- QString result(need + len + 1, Qt::Uninitialized); // worst case
- ushort *qch = (ushort *)result.unicode();
- uchar ch;
- int invalid = 0;
-
- for (int i = 0; i < len; ++i) {
- ch = chars[i];
- if (need) {
- if ((ch&0xc0) == 0x80) {
- uc = (uc << 6) | (ch & 0x3f);
- --need;
- if (!need) {
- // utf-8 bom composes into 0xfeff code point
- if (!headerdone && uc == 0xfeff) {
- // don't do anything, just skip the BOM
- } else if (QChar::requiresSurrogates(uc) && uc <= QChar::LastValidCodePoint) {
- // surrogate pair
- Q_ASSERT((qch - (ushort*)result.unicode()) + 2 < result.length());
- *qch++ = QChar::highSurrogate(uc);
- *qch++ = QChar::lowSurrogate(uc);
- } else if ((uc < min_uc) || QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
- // error: overlong sequence, UTF16 surrogate or non-character
- *qch++ = replacement;
- ++invalid;
- } else {
- *qch++ = uc;
- }
- headerdone = true;
- }
- } else {
- // error
- i = error;
- *qch++ = replacement;
- ++invalid;
- need = 0;
- headerdone = true;
- }
- } else {
- if (ch < 128) {
- *qch++ = ushort(ch);
- headerdone = true;
- } else if ((ch & 0xe0) == 0xc0) {
- uc = ch & 0x1f;
- need = 1;
- error = i;
- min_uc = 0x80;
- headerdone = true;
- } else if ((ch & 0xf0) == 0xe0) {
- uc = ch & 0x0f;
- need = 2;
- error = i;
- min_uc = 0x800;
- } else if ((ch&0xf8) == 0xf0) {
- uc = ch & 0x07;
- need = 3;
- error = i;
- min_uc = 0x10000;
- headerdone = true;
- } else {
- // error
- *qch++ = replacement;
+ if (state->remainingChars) {
+ // handle incoming state first
+ uchar remainingCharsData[4]; // longest UTF-8 sequence possible
+ int remainingCharsCount = state->remainingChars;
+ int newCharsToCopy = qMin<int>(sizeof(remainingCharsData) - remainingCharsCount, end - src);
+
+ memset(remainingCharsData, 0, sizeof(remainingCharsData));
+ memcpy(remainingCharsData, &state->state_data[0], remainingCharsCount);
+ memcpy(remainingCharsData + remainingCharsCount, src, newCharsToCopy);
+
+ const uchar *begin = &remainingCharsData[1];
+ res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(remainingCharsData[0], dst, begin,
+ static_cast<const uchar *>(remainingCharsData) + remainingCharsCount + newCharsToCopy);
+ if (res == QUtf8BaseTraits::EndOfString) {
+ // if we got EndOfString again, then there were too few bytes in src;
+ // copy to our state and return
+ state->remainingChars = remainingCharsCount + newCharsToCopy;
+ memcpy(&state->state_data[0], remainingCharsData, state->remainingChars);
+ return QString();
+ } else if (res == QUtf8BaseTraits::Error) {
++invalid;
+ *dst++ = replacement;
+ } else if (!headerdone && res >= 0) {
+ // eat the UTF-8 BOM
headerdone = true;
+ if (dst[-1] == 0xfeff)
+ --dst;
}
+
+ // adjust src now that we have maybe consumed a few chars
+ //Q_ASSERT(res > remainingCharsCount)
+ src += res - remainingCharsCount;
}
}
- if (!state && need > 0) {
- // unterminated UTF sequence
- for (int i = error; i < len; ++i) {
- *qch++ = replacement;
+
+ // main body, stateless decoding
+ res = 0;
+ const uchar *nextAscii = src;
+ while (res >= 0 && src < end) {
+ if (src >= nextAscii && simdDecodeAscii(dst, nextAscii, src, end))
+ break;
+
+ ch = *src++;
+ res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(ch, dst, src, end);
+ if (!headerdone && res >= 0) {
+ headerdone = true;
+ // eat the UTF-8 BOM
+ if (dst[-1] == 0xfeff)
+ --dst;
+ }
+ if (res == QUtf8BaseTraits::Error) {
+ res = 0;
++invalid;
+ *dst++ = replacement;
}
}
- result.truncate(qch - (ushort *)result.unicode());
+
+ if (!state && res == QUtf8BaseTraits::EndOfString) {
+ // unterminated UTF sequence
+ *dst++ = QChar::ReplacementCharacter;
+ while (src++ < end)
+ *dst++ = QChar::ReplacementCharacter;
+ }
+
+ result.truncate(dst - (ushort *)result.unicode());
if (state) {
state->invalidChars += invalid;
- state->remainingChars = need;
if (headerdone)
state->flags |= QTextCodec::IgnoreHeader;
- state->state_data[0] = need ? uc : 0;
- state->state_data[1] = need ? min_uc : 0;
+ if (res == QUtf8BaseTraits::EndOfString) {
+ --src; // unread the byte in ch
+ state->remainingChars = end - src;
+ memcpy(&state->state_data[0], src, end - src);
+ } else {
+ state->remainingChars = 0;
+ }
}
return result;
}
@@ -390,21 +504,21 @@ QByteArray QUtf32::convertFromUnicode(const QChar *uc, int len, QTextCodec::Conv
}
data += 4;
}
+
+ QStringIterator i(uc, uc + len);
if (endian == BigEndianness) {
- for (int i = 0; i < len; ++i) {
- uint cp = uc[i].unicode();
- if (uc[i].isHighSurrogate() && i < len - 1)
- cp = QChar::surrogateToUcs4(cp, uc[++i].unicode());
+ while (i.hasNext()) {
+ uint cp = i.next();
+
*(data++) = cp >> 24;
*(data++) = (cp >> 16) & 0xff;
*(data++) = (cp >> 8) & 0xff;
*(data++) = cp & 0xff;
}
} else {
- for (int i = 0; i < len; ++i) {
- uint cp = uc[i].unicode();
- if (uc[i].isHighSurrogate() && i < len - 1)
- cp = QChar::surrogateToUcs4(cp, uc[++i].unicode());
+ while (i.hasNext()) {
+ uint cp = i.next();
+
*(data++) = cp & 0xff;
*(data++) = (cp >> 8) & 0xff;
*(data++) = (cp >> 16) & 0xff;
diff --git a/src/corelib/codecs/qutfcodec_p.h b/src/corelib/codecs/qutfcodec_p.h
index e1214d50bc..c252edede7 100644
--- a/src/corelib/codecs/qutfcodec_p.h
+++ b/src/corelib/codecs/qutfcodec_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -58,6 +59,227 @@
QT_BEGIN_NAMESPACE
+struct QUtf8BaseTraits
+{
+ static const bool isTrusted = false;
+ static const bool allowNonCharacters = true;
+ static const bool skipAsciiHandling = false;
+ static const int Error = -1;
+ static const int EndOfString = -2;
+
+ static bool isValidCharacter(uint u)
+ { return int(u) >= 0; }
+
+ static void appendByte(uchar *&ptr, uchar b)
+ { *ptr++ = b; }
+
+ static uchar peekByte(const uchar *ptr, int n = 0)
+ { return ptr[n]; }
+
+ static qptrdiff availableBytes(const uchar *ptr, const uchar *end)
+ { return end - ptr; }
+
+ static void advanceByte(const uchar *&ptr, int n = 1)
+ { ptr += n; }
+
+ static void appendUtf16(ushort *&ptr, ushort uc)
+ { *ptr++ = uc; }
+
+ static void appendUcs4(ushort *&ptr, uint uc)
+ {
+ appendUtf16(ptr, QChar::highSurrogate(uc));
+ appendUtf16(ptr, QChar::lowSurrogate(uc));
+ }
+
+ static ushort peekUtf16(const ushort *ptr, int n = 0)
+ { return ptr[n]; }
+
+ static qptrdiff availableUtf16(const ushort *ptr, const ushort *end)
+ { return end - ptr; }
+
+ static void advanceUtf16(const ushort *&ptr, int n = 1)
+ { ptr += n; }
+
+ // it's possible to output to UCS-4 too
+ static void appendUtf16(uint *&ptr, ushort uc)
+ { *ptr++ = uc; }
+
+ static void appendUcs4(uint *&ptr, uint uc)
+ { *ptr++ = uc; }
+};
+
+struct QUtf8BaseTraitsNoAscii : public QUtf8BaseTraits
+{
+ static const bool skipAsciiHandling = true;
+};
+
+namespace QUtf8Functions
+{
+ /// returns 0 on success; errors can only happen if \a u is a surrogate:
+ /// Error if \a u is a low surrogate;
+ /// if \a u is a high surrogate, Error if the next isn't a low one,
+ /// EndOfString if we run into the end of the string.
+ template <typename Traits, typename OutputPtr, typename InputPtr> inline
+ int toUtf8(ushort u, OutputPtr &dst, InputPtr &src, InputPtr end)
+ {
+ if (!Traits::skipAsciiHandling && u < 0x80) {
+ // U+0000 to U+007F (US-ASCII) - one byte
+ Traits::appendByte(dst, uchar(u));
+ return 0;
+ } else if (u < 0x0800) {
+ // U+0080 to U+07FF - two bytes
+ // first of two bytes
+ Traits::appendByte(dst, 0xc0 | uchar(u >> 6));
+ } else {
+ if (!QChar::isSurrogate(u)) {
+ // U+0800 to U+FFFF (except U+D800-U+DFFF) - three bytes
+ if (!Traits::allowNonCharacters && QChar::isNonCharacter(u))
+ return Traits::Error;
+
+ // first of three bytes
+ Traits::appendByte(dst, 0xe0 | uchar(u >> 12));
+ } else {
+ // U+10000 to U+10FFFF - four bytes
+ // need to get one extra codepoint
+ if (Traits::availableUtf16(src, end) == 0)
+ return Traits::EndOfString;
+
+ ushort low = Traits::peekUtf16(src);
+ if (!QChar::isHighSurrogate(u))
+ return Traits::Error;
+ if (!QChar::isLowSurrogate(low))
+ return Traits::Error;
+
+ Traits::advanceUtf16(src);
+ uint ucs4 = QChar::surrogateToUcs4(u, low);
+
+ if (!Traits::allowNonCharacters && QChar::isNonCharacter(ucs4))
+ return Traits::Error;
+
+ // first byte
+ Traits::appendByte(dst, 0xf0 | (uchar(ucs4 >> 18) & 0xf));
+
+ // second of four bytes
+ Traits::appendByte(dst, 0x80 | (uchar(ucs4 >> 12) & 0x3f));
+
+ // for the rest of the bytes
+ u = ushort(ucs4);
+ }
+
+ // second to last byte
+ Traits::appendByte(dst, 0x80 | (uchar(u >> 6) & 0x3f));
+ }
+
+ // last byte
+ Traits::appendByte(dst, 0x80 | (u & 0x3f));
+ return 0;
+ }
+
+ inline bool isContinuationByte(uchar b)
+ {
+ return (b & 0xc0) == 0x80;
+ }
+
+ /// returns the number of characters consumed (including \a b) in case of success;
+ /// returns negative in case of error: Traits::Error or Traits::EndOfString
+ template <typename Traits, typename OutputPtr, typename InputPtr> inline
+ int fromUtf8(uchar b, OutputPtr &dst, InputPtr &src, InputPtr end)
+ {
+ int charsNeeded;
+ uint min_uc;
+ uint uc;
+
+ if (!Traits::skipAsciiHandling && b < 0x80) {
+ // US-ASCII
+ Traits::appendUtf16(dst, b);
+ return 1;
+ }
+
+ if (!Traits::isTrusted && Q_UNLIKELY(b <= 0xC1)) {
+ // an UTF-8 first character must be at least 0xC0
+ // however, all 0xC0 and 0xC1 first bytes can only produce overlong sequences
+ return Traits::Error;
+ } else if (b < 0xe0) {
+ charsNeeded = 2;
+ min_uc = 0x80;
+ uc = b & 0x1f;
+ } else if (b < 0xf0) {
+ charsNeeded = 3;
+ min_uc = 0x800;
+ uc = b & 0x0f;
+ } else if (b < 0xf5) {
+ charsNeeded = 4;
+ min_uc = 0x10000;
+ uc = b & 0x07;
+ } else {
+ // the last Unicode character is U+10FFFF
+ // it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF"
+ // therefore, a byte higher than 0xF4 is not the UTF-8 first byte
+ return Traits::Error;
+ }
+
+ int bytesAvailable = Traits::availableBytes(src, end);
+ if (Q_UNLIKELY(bytesAvailable < charsNeeded - 1)) {
+ // it's possible that we have an error instead of just unfinished bytes
+ if (bytesAvailable > 0 && !isContinuationByte(Traits::peekByte(src, 0)))
+ return Traits::Error;
+ if (bytesAvailable > 1 && !isContinuationByte(Traits::peekByte(src, 1)))
+ return Traits::Error;
+ if (bytesAvailable > 2 && !isContinuationByte(Traits::peekByte(src, 2)))
+ return Traits::Error;
+ return Traits::EndOfString;
+ }
+
+ // first continuation character
+ b = Traits::peekByte(src, 0);
+ if (!isContinuationByte(b))
+ return Traits::Error;
+ uc <<= 6;
+ uc |= b & 0x3f;
+
+ if (charsNeeded > 2) {
+ // second continuation character
+ b = Traits::peekByte(src, 1);
+ if (!isContinuationByte(b))
+ return Traits::Error;
+ uc <<= 6;
+ uc |= b & 0x3f;
+
+ if (charsNeeded > 3) {
+ // third continuation character
+ b = Traits::peekByte(src, 2);
+ if (!isContinuationByte(b))
+ return Traits::Error;
+ uc <<= 6;
+ uc |= b & 0x3f;
+ }
+ }
+
+ // we've decoded something; safety-check it
+ if (!Traits::isTrusted) {
+ if (uc < min_uc)
+ return Traits::Error;
+ if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
+ return Traits::Error;
+ if (!Traits::allowNonCharacters && QChar::isNonCharacter(uc))
+ return Traits::Error;
+ }
+
+ // write the UTF-16 sequence
+ if (!QChar::requiresSurrogates(uc)) {
+ // UTF-8 decoded and no surrogates are required
+ // detach if necessary
+ Traits::appendUtf16(dst, ushort(uc));
+ } else {
+ // UTF-8 decoded to something that requires a surrogate pair
+ Traits::appendUcs4(dst, uc);
+ }
+
+ Traits::advanceByte(src, charsNeeded - 1);
+ return charsNeeded;
+ }
+}
+
enum DataEndianness
{
DetectEndianness,
@@ -67,7 +289,9 @@ enum DataEndianness
struct QUtf8
{
+ static QString convertToUnicode(const char *, int);
static QString convertToUnicode(const char *, int, QTextCodec::ConverterState *);
+ static QByteArray convertFromUnicode(const QChar *, int);
static QByteArray convertFromUnicode(const QChar *, int, QTextCodec::ConverterState *);
};
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index df28183fdc..373b3f148d 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -12,7 +12,7 @@ win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000
irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
# otherwise mingw headers do not declare common functions like putenv
-win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
+mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
QMAKE_DOCS = $$PWD/doc/qtcore.qdocconf
diff --git a/src/corelib/doc/snippets/code/doc_src_properties.cpp b/src/corelib/doc/snippets/code/doc_src_properties.cpp
index 7a70200cce..f76fef6ebd 100644
--- a/src/corelib/doc/snippets/code/doc_src_properties.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_properties.cpp
@@ -48,7 +48,7 @@ Q_PROPERTY(type name
[DESIGNABLE bool]
[SCRIPTABLE bool]
[STORED bool]
- [USER bool]
+ [USER bool]
[CONSTANT]
[FINAL])
//! [0]
diff --git a/src/corelib/doc/snippets/code/doc_src_qalgorithms.cpp b/src/corelib/doc/snippets/code/doc_src_qalgorithms.cpp
index 4ff7e87b16..54d9f01cc4 100644
--- a/src/corelib/doc/snippets/code/doc_src_qalgorithms.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_qalgorithms.cpp
@@ -274,9 +274,9 @@ list.insert(i, 12);
QVector<int> vect;
vect << 3 << 3 << 6 << 6 << 6 << 8;
QVector<int>::iterator begin6 =
- qLowerBound(vect.begin(), vect.end(), 6);
+ qLowerBound(vect.begin(), vect.end(), 6);
QVector<int>::iterator end6 =
- qUpperBound(begin6, vect.end(), 6);
+ qUpperBound(begin6, vect.end(), 6);
QVector<int>::iterator i = begin6;
while (i != end6) {
@@ -305,9 +305,9 @@ list.insert(i, 12);
QVector<int> vect;
vect << 3 << 3 << 6 << 6 << 6 << 8;
QVector<int>::iterator begin6 =
- qLowerBound(vect.begin(), vect.end(), 6);
+ qLowerBound(vect.begin(), vect.end(), 6);
QVector<int>::iterator end6 =
- qUpperBound(vect.begin(), vect.end(), 6);
+ qUpperBound(vect.begin(), vect.end(), 6);
QVector<int>::iterator i = begin6;
while (i != end6) {
@@ -323,7 +323,7 @@ QVector<int> vect;
vect << 3 << 3 << 6 << 6 << 6 << 8;
QVector<int>::iterator i =
- qBinaryFind(vect.begin(), vect.end(), 6);
+ qBinaryFind(vect.begin(), vect.end(), 6);
// i == vect.begin() + 2 (or 3 or 4)
//! [22]
diff --git a/src/corelib/doc/snippets/code/doc_src_qiterator.cpp b/src/corelib/doc/snippets/code/doc_src_qiterator.cpp
index af8f87b1c6..eec7a96a38 100644
--- a/src/corelib/doc/snippets/code/doc_src_qiterator.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_qiterator.cpp
@@ -218,7 +218,7 @@ QMutableListIterator<int> i(list);
while (i.hasNext()) {
int val = i.next();
if (val < -32768 || val > 32767)
- i.remove();
+ i.remove();
}
//! [19]
@@ -228,7 +228,7 @@ QMutableLinkedListIterator<int> i(list);
while (i.hasNext()) {
int val = i.next();
if (val < -32768 || val > 32767)
- i.remove();
+ i.remove();
}
//! [20]
@@ -238,7 +238,7 @@ QMutableVectorIterator<int> i(vector);
while (i.hasNext()) {
int val = i.next();
if (val < -32768 || val > 32767)
- i.remove();
+ i.remove();
}
//! [21]
@@ -248,7 +248,7 @@ QMutableSetIterator<int> i(set);
while (i.hasNext()) {
int val = i.next();
if (val < -32768 || val > 32767)
- i.remove();
+ i.remove();
}
//! [22]
@@ -305,7 +305,7 @@ while (i.hasPrevious()) {
QMapIterator<int, QWidget *> i(map);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
- << i.key();
+ << i.key();
}
//! [28]
@@ -335,7 +335,7 @@ while (i.hasPrevious()) {
QHashIterator<int, QWidget *> i(hash);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
- << i.key();
+ << i.key();
}
//! [31]
@@ -365,7 +365,7 @@ while (i.hasPrevious()) {
QMutableMapIterator<int, QWidget *> i(map);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
- << i.key();
+ << i.key();
}
//! [34]
@@ -405,7 +405,7 @@ while (i.hasPrevious()) {
QMutableHashIterator<int, QWidget *> i(hash);
while (i.findNext(widget)) {
qDebug() << "Found widget " << widget << " under key "
- << i.key();
+ << i.key();
}
//! [38]
diff --git a/src/corelib/doc/snippets/code/qlogging/qlogging.cpp b/src/corelib/doc/snippets/code/qlogging/qlogging.cpp
index 774610a3c0..ff5ce23eff 100644
--- a/src/corelib/doc/snippets/code/qlogging/qlogging.cpp
+++ b/src/corelib/doc/snippets/code/qlogging/qlogging.cpp
@@ -52,3 +52,7 @@
}
}
//! [1]
+
+//! [2]
+ const QLoggingCategory &category();
+//! [2]
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index 59f05592be..3a18eb8007 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -523,10 +523,10 @@ class MyClass : public QObject
//! [45]
//! [46]
- // Instead of comparing with 0.0
- qFuzzyCompare(0.0,1.0e-200); // This will return false
- // Compare adding 1 to both values will fix the problem
- qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true
+ // Instead of comparing with 0.0
+ qFuzzyCompare(0.0,1.0e-200); // This will return false
+ // Compare adding 1 to both values will fix the problem
+ qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true
//! [46]
//! [47]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qstringiterator.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qstringiterator.cpp
new file mode 100644
index 0000000000..178c6feb0a
--- /dev/null
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qstringiterator.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "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 Digia Plc and its Subsidiary(-ies) 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."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QString>
+#include <QStringIterator>
+#include <QDebug>
+
+int main()
+{
+
+{
+//! [0]
+QString string(QStringLiteral("a string"));
+QStringIterator i(string);
+//! [0]
+
+//! [1]
+// will print 97, 32, 115, 116, etc.;
+// that is, the decimal value of the code points in the Unicode string "a string"
+while (i.hasNext())
+ qDebug() << i.next();
+//! [1]
+}
+
+{
+//! [2]
+QString string(QStringLiteral("𝄞 is the G clef"));
+QStringIterator i(string);
+qDebug() << hex << i.next(); // will print 1d11e (U+1D11E, MUSICAL SYMBOL G CLEF)
+qDebug() << hex << i.next(); // will print 20 (U+0020, SPACE)
+qDebug() << hex << i.next(); // will print 69 (U+0069, LATIN SMALL LETTER I)
+//! [2]
+}
+
+}
diff --git a/src/corelib/doc/snippets/qbytearraylist/main.cpp b/src/corelib/doc/snippets/qbytearraylist/main.cpp
new file mode 100644
index 0000000000..59f7af52e2
--- /dev/null
+++ b/src/corelib/doc/snippets/qbytearraylist/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 by Southwest Research Institute (R)
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QByteArrayList>
+
+int main(int, char **)
+{
+ QByteArray ba1, ba2, ba3;
+//! [0]
+ QByteArrayList longerList = (QByteArrayList() << ba1 << ba2 << ba3);
+//! [0]
+}
diff --git a/src/corelib/doc/snippets/qbytearraylist/qbytearraylist.pro b/src/corelib/doc/snippets/qbytearraylist/qbytearraylist.pro
new file mode 100644
index 0000000000..87397b491d
--- /dev/null
+++ b/src/corelib/doc/snippets/qbytearraylist/qbytearraylist.pro
@@ -0,0 +1,2 @@
+QT = core
+SOURCES = main.cpp
diff --git a/src/corelib/doc/snippets/qloggingcategory/main.cpp b/src/corelib/doc/snippets/qloggingcategory/main.cpp
index c1dad7f43a..628243dbdd 100644
--- a/src/corelib/doc/snippets/qloggingcategory/main.cpp
+++ b/src/corelib/doc/snippets/qloggingcategory/main.cpp
@@ -128,6 +128,27 @@ oldCategoryFilter = QLoggingCategory::installFilter(myCategoryFilter);
//![12]
}
+ {
+//![13]
+ QLoggingCategory category("qt.driver.usb");
+ qCDebug(category, "a debug message logged into category %s", category.categoryName());
+//![13]
+ }
+
+ {
+//![14]
+ QLoggingCategory category("qt.driver.usb");
+ qCWarning(category, "a warning message logged into category %s", category.categoryName());
+//![14]
+ }
+
+ {
+//![15]
+ QLoggingCategory category("qt.driver.usb");
+ qCCritical(category, "a critical message logged into category %s", category.categoryName());
+//![15]
+ }
+
return 0;
}
diff --git a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
index 1711d4d599..67abe6573c 100644
--- a/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
+++ b/src/corelib/doc/snippets/qsignalmapper/buttonwidget.cpp
@@ -50,11 +50,11 @@ ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
- QPushButton *button = new QPushButton(texts[i]);
- connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
+ QPushButton *button = new QPushButton(texts[i]);
+ connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
//! [0] //! [1]
- signalMapper->setMapping(button, texts[i]);
- gridLayout->addWidget(button, i / 3, i % 3);
+ signalMapper->setMapping(button, texts[i]);
+ gridLayout->addWidget(button, i / 3, i % 3);
}
connect(signalMapper, SIGNAL(mapped(QString)),
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index fd031469f6..789f500cab 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -51,3 +51,9 @@ slog2 {
LIBS_PRIVATE += -lslog2
DEFINES += QT_USE_SLOG2
}
+
+journald {
+ CONFIG += link_pkgconfig
+ PKGCONFIG_PRIVATE += libsystemd-journal
+ DEFINES += QT_USE_JOURNALD
+}
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index d526d40398..70f45345c6 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -98,6 +98,7 @@
# define Q_UNREACHABLE_IMPL() __assume(0)
# define Q_NORETURN __declspec(noreturn)
# define Q_DECL_DEPRECATED __declspec(deprecated)
+# define Q_DECL_DEPRECATED_X(text) __declspec(deprecated(text))
# define Q_DECL_EXPORT __declspec(dllexport)
# define Q_DECL_IMPORT __declspec(dllimport)
/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
@@ -152,6 +153,9 @@
# define Q_CC_INTEL
# define Q_ASSUME_IMPL(expr) __assume(expr)
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
+# if __INTEL_COMPILER >= 1300 && !defined(__APPLE__)
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
+# endif
# elif defined(__clang__)
/* Clang also masquerades as GCC */
# define Q_CC_CLANG
@@ -173,6 +177,7 @@
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
# define Q_ASSUME_IMPL(expr) if (expr){} else __builtin_unreachable()
# define Q_UNREACHABLE_IMPL() __builtin_unreachable()
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
# endif
# endif
@@ -469,12 +474,29 @@
* N2544 Q_COMPILER_UNRESTRICTED_UNIONS
* N1653 Q_COMPILER_VARIADIC_MACROS
* N2242 N2555 Q_COMPILER_VARIADIC_TEMPLATES
+ *
+ * C++1y proposed features
+ *
+ * N3472 Q_COMPILER_BINARY_LITERALS
+ * N3649 Q_COMPILER_GENERIC_LAMBDA
+ * N3638 Q_COMPILER_LAMBDA_CAPTURES
+ * N3652 Q_COMPILER_RELAXED_CONSTEXPR_FUNCTIONS
+ * N3386 N3638 Q_COMPILER_RETURN_TYPE_DEDUCTION
+ * N3651 Q_COMPILER_VARIABLE_TEMPLATES
+ * N3639 Q_COMPILER_VLA (see also Q_COMPILER_RESTRICTED_VLA)
+ *
*/
#ifdef Q_CC_INTEL
+# define Q_COMPILER_RESTRICTED_VLA
# if __INTEL_COMPILER < 1200
# define Q_NO_TEMPLATE_FRIENDS
# endif
+# if __INTEL_COMPILER >= 1310 && !defined(_WIN32)
+// ICC supports C++14 binary literals in C, C++98, and C++11 modes
+// at least since 13.1, but I can't test further back
+# define Q_COMPILER_BINARY_LITERALS
+# endif
# if __cplusplus >= 201103L
# define Q_COMPILER_VARIADIC_MACROS
# if __INTEL_COMPILER >= 1200
@@ -487,7 +509,6 @@
# define Q_COMPILER_LAMBDA
# define Q_COMPILER_RVALUE_REFS
# define Q_COMPILER_STATIC_ASSERT
-# define Q_COMPILER_THREAD_LOCAL
# define Q_COMPILER_VARIADIC_MACROS
# endif
# if __INTEL_COMPILER >= 1210
@@ -518,8 +539,9 @@
# endif
#endif
-#ifdef Q_CC_CLANG
+#if defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
/* General C++ features */
+# define Q_COMPILER_RESTRICTED_VLA
# if !__has_feature(cxx_exceptions)
# ifndef QT_NO_EXCEPTIONS
# define QT_NO_EXCEPTIONS
@@ -528,6 +550,15 @@
# if !__has_feature(cxx_rtti)
# define QT_NO_RTTI
# endif
+# if __has_feature(attribute_deprecated_with_message)
+# define Q_DECL_DEPRECATED_X(text) __attribute__ ((__deprecated__(text)))
+# endif
+
+// Clang supports binary literals in C, C++98 and C++11 modes
+// It's been supported "since the dawn of time itself" (cf. commit 179883)
+# if __has_extension(cxx_binary_literals)
+# define Q_COMPILER_BINARY_LITERALS
+# endif
/* C++11 features, see http://clang.llvm.org/cxx_status.html */
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
@@ -628,9 +659,40 @@
# define Q_COMPILER_VARIADIC_MACROS
# endif
# endif
+
+/* C++1y features, see http://clang.llvm.org/cxx_status.html and
+ * http://clang.llvm.org/docs/LanguageExtensions.html#checks-for-standard-language-features */
+# if __cplusplus > 201103L
+//# if __has_feature(cxx_binary_literals)
+//# define Q_COMPILER_BINARY_LITERALS // see above
+//# endif
+# if __has_feature(cxx_generic_lambda)
+# define Q_COMPILER_GENERIC_LAMBDA
+# endif
+# if __has_feature(cxx_init_capture)
+# define Q_COMPILER_LAMBDA_CAPTURES
+# endif
+# if __has_feature(cxx_relaxed_constexpr)
+# define Q_COMPILER_RELAXED_CONSTEXPR_FUNCTIONS
+# endif
+# if __has_feature(cxx_decltype_auto) && __has_feature(cxx_return_type_deduction)
+# define Q_COMPILER_RETURN_TYPE_DEDUCTION
+# endif
+# if __has_feature(cxx_variable_templates)
+# define Q_COMPILER_VARIABLE_TEMPLATES
+# endif
+# if __has_feature(cxx_runtime_array)
+# define Q_COMPILER_VLA
+# endif
+# endif
#endif // Q_CC_CLANG
#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_CLANG)
+# define Q_COMPILER_RESTRICTED_VLA
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+// GCC supports binary literals in C, C++98 and C++11 modes
+# define Q_COMPILER_BINARY_LITERALS
+# endif
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
/* C++11 features supported in GCC 4.3: */
@@ -693,6 +755,15 @@
# endif
/* C++11 features are complete as of GCC 4.8.1 */
# endif
+# if __cplusplus > 201103L
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409
+ /* C++1y features in GCC 4.9 */
+//# define Q_COMPILER_BINARY_LITERALS // already supported since GCC 4.3 as an extension
+# define Q_COMPILER_LAMBDA_CAPTURES
+# define Q_COMPILER_RETURN_TYPE_DEDUCTION
+# define Q_COMPILER_VLA
+# endif
+# endif
#endif
#if defined(Q_CC_MSVC) && !defined(Q_CC_INTEL)
@@ -796,8 +867,10 @@
#ifdef Q_COMPILER_CONSTEXPR
# define Q_DECL_CONSTEXPR constexpr
+# define Q_CONSTEXPR constexpr
#else
# define Q_DECL_CONSTEXPR
+# define Q_CONSTEXPR const
#endif
#ifdef Q_COMPILER_EXPLICIT_OVERRIDES
@@ -861,6 +934,9 @@
#ifndef Q_DECL_VARIABLE_DEPRECATED
# define Q_DECL_VARIABLE_DEPRECATED Q_DECL_DEPRECATED
#endif
+#ifndef Q_DECL_DEPRECATED_X
+# define Q_DECL_DEPRECATED_X(text) Q_DECL_DEPRECATED
+#endif
#ifndef Q_DECL_EXPORT
# define Q_DECL_EXPORT
#endif
@@ -943,7 +1019,6 @@
#endif
#if !defined(Q_PROCESSOR_ARM)
# undef QT_COMPILER_SUPPORTS_IWMMXT
-# undef QT_COMPILER_SUPPORTS_NEON
#endif
#if !defined(Q_PROCESSOR_MIPS)
# undef QT_COMPILER_SUPPORTS_MIPS_DSP
diff --git a/src/corelib/global/qflags.h b/src/corelib/global/qflags.h
index dd4222b89f..9e97724fec 100644
--- a/src/corelib/global/qflags.h
+++ b/src/corelib/global/qflags.h
@@ -53,13 +53,19 @@ class QFlag
{
int i;
public:
- Q_DECL_CONSTEXPR inline QFlag(int i);
+#if !defined(__LP64__) && !defined(Q_QDOC)
+ Q_DECL_CONSTEXPR inline QFlag(long ai) : i(int(ai)) {}
+ Q_DECL_CONSTEXPR inline QFlag(ulong ai) : i(int(long(ai))) {}
+#endif
+ Q_DECL_CONSTEXPR inline QFlag(int ai) : i(ai) {}
+ Q_DECL_CONSTEXPR inline QFlag(uint ai) : i(int(ai)) {}
+ Q_DECL_CONSTEXPR inline QFlag(short ai) : i(int(ai)) {}
+ Q_DECL_CONSTEXPR inline QFlag(ushort ai) : i(int(uint(ai))) {}
Q_DECL_CONSTEXPR inline operator int() const { return i; }
+ Q_DECL_CONSTEXPR inline operator uint() const { return uint(i); }
};
Q_DECLARE_TYPEINFO(QFlag, Q_PRIMITIVE_TYPE);
-Q_DECL_CONSTEXPR inline QFlag::QFlag(int ai) : i(ai) {}
-
class QIncompatibleFlag
{
int i;
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index a9f6df6291..fe10c493a7 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -115,12 +115,40 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
*/
/*!
+ \fn QFlag::QFlag(uint value)
+ \since Qt 5.3
+
+ Constructs a QFlag object that stores the given \a value.
+*/
+
+/*!
+ \fn QFlag::QFlag(short value)
+ \since 5.3
+
+ Constructs a QFlag object that stores the given \a value.
+*/
+
+/*!
+ \fn QFlag::QFlag(ushort value)
+ \since Qt 5.3
+
+ Constructs a QFlag object that stores the given \a value.
+*/
+
+/*!
\fn QFlag::operator int() const
Returns the value stored by the QFlag object.
*/
/*!
+ \fn QFlag::operator uint() const
+ \since Qt 5.3
+
+ Returns the value stored by the QFlag object.
+*/
+
+/*!
\class QFlags
\inmodule QtCore
\brief The QFlags class provides a type-safe way of storing
@@ -2186,7 +2214,9 @@ QString qt_error_string(int errorCode)
s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device");
break;
default: {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN)
+ // Retrieve the system error message for the last-error code.
+# ifndef Q_OS_WINRT
wchar_t *string = 0;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
@@ -2197,6 +2227,17 @@ QString qt_error_string(int errorCode)
NULL);
ret = QString::fromWCharArray(string);
LocalFree((HLOCAL)string);
+# else // !Q_OS_WINRT
+ __declspec(thread) static wchar_t errorString[4096];
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ errorCode,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ errorString,
+ ARRAYSIZE(errorString),
+ NULL);
+ ret = QString::fromWCharArray(errorString);
+# endif // Q_OS_WINRT
if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
ret = QString::fromLatin1("The specified module could not be found.");
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index cd7899021d..b2f9e29b44 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -45,11 +45,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "5.2.2"
+#define QT_VERSION_STR "5.3.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x050202
+#define QT_VERSION 0x050300
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -191,7 +191,7 @@ typedef qint64 qlonglong;
typedef quint64 qulonglong;
#ifndef QT_POINTER_SIZE
-# if defined(Q_OS_WIN64)
+# if defined(Q_OS_WIN64) || (defined(Q_OS_WINRT) && defined(_M_X64))
# define QT_POINTER_SIZE 8
# elif defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# define QT_POINTER_SIZE 4
@@ -221,11 +221,14 @@ typedef double qreal;
#if defined(QT_NO_DEPRECATED)
# undef QT_DEPRECATED
+# undef QT_DEPRECATED_X
# undef QT_DEPRECATED_VARIABLE
# undef QT_DEPRECATED_CONSTRUCTOR
#elif defined(QT_DEPRECATED_WARNINGS)
# undef QT_DEPRECATED
# define QT_DEPRECATED Q_DECL_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text) Q_DECL_DEPRECATED_X(text)
# undef QT_DEPRECATED_VARIABLE
# define QT_DEPRECATED_VARIABLE Q_DECL_VARIABLE_DEPRECATED
# undef QT_DEPRECATED_CONSTRUCTOR
@@ -233,6 +236,8 @@ typedef double qreal;
#else
# undef QT_DEPRECATED
# define QT_DEPRECATED
+# undef QT_DEPRECATED_X
+# define QT_DEPRECATED_X(text)
# undef QT_DEPRECATED_VARIABLE
# define QT_DEPRECATED_VARIABLE
# undef QT_DEPRECATED_CONSTRUCTOR
@@ -432,6 +437,8 @@ template <> struct QIntegerForSize<2> { typedef quint16 Unsigned; typedef qin
template <> struct QIntegerForSize<4> { typedef quint32 Unsigned; typedef qint32 Signed; };
template <> struct QIntegerForSize<8> { typedef quint64 Unsigned; typedef qint64 Signed; };
template <class T> struct QIntegerForSizeof: QIntegerForSize<sizeof(T)> { };
+typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Signed qregisterint;
+typedef QIntegerForSize<Q_PROCESSOR_WORDSIZE>::Unsigned qregisteruint;
typedef QIntegerForSizeof<void*>::Unsigned quintptr;
typedef QIntegerForSizeof<void*>::Signed qptrdiff;
typedef qptrdiff qintptr;
@@ -527,12 +534,12 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
#ifdef Q_OS_DARWIN
# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) \
- (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \
- (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios)
+ ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios))
# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) \
- (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \
- (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios)
+ ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \
+ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MIN_REQUIRED < ios))
# define QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(ios) \
QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_NA, ios)
@@ -559,7 +566,12 @@ class QDataStream;
#endif
#if defined(Q_OS_WINRT)
+# define QT_NO_FILESYSTEMWATCHER
+# define QT_NO_GETADDRINFO
+# define QT_NO_NETWORKPROXY
# define QT_NO_PROCESS
+# define QT_NO_SOCKETNOTIFIER
+# define QT_NO_SOCKS5
#endif
inline void qt_noop(void) {}
@@ -1017,6 +1029,9 @@ namespace QtPrivate {
//like std::enable_if
template <bool B, typename T = void> struct QEnableIf;
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
+
+template <bool B, typename T, typename F> struct QConditional { typedef T Type; };
+template <typename T, typename F> struct QConditional<false, T, F> { typedef F Type; };
}
#ifndef Q_FORWARD_DECLARE_OBJC_CLASS
@@ -1034,14 +1049,17 @@ template <typename T> struct QEnableIf<true, T> { typedef T Type; };
#endif
QT_END_NAMESPACE
-// Q_GLOBAL_STATIC
-#include <QtCore/qglobalstatic.h>
-// qDebug and friends
+// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.
+// Be careful when changing the order of these files.
+#include <QtCore/qtypeinfo.h>
+#include <QtCore/qsysinfo.h>
#include <QtCore/qlogging.h>
+
#include <QtCore/qflags.h>
-#include <QtCore/qsysinfo.h>
-#include <QtCore/qtypeinfo.h>
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qglobalstatic.h>
#include <QtCore/qnumeric.h>
#endif /* __cplusplus */
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 1c3b09f602..ed1715ddb5 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qdir.h"
+#include "qstringlist.h"
#include "qfile.h"
#include "qsettings.h"
#include "qlibraryinfo.h"
@@ -113,6 +114,8 @@ public:
}
};
+static const char platformsSection[] = "Platforms";
+
QLibrarySettings::QLibrarySettings()
: settings(QLibraryInfoPrivate::findConfiguration())
{
@@ -132,7 +135,8 @@ QLibrarySettings::QLibrarySettings()
haveEffectivePaths = children.contains(QLatin1String("EffectivePaths"));
#endif
// Backwards compat: an existing but empty file is claimed to contain the Paths section.
- havePaths = !haveEffectivePaths || children.contains(QLatin1String("Paths"));
+ havePaths = (!haveEffectivePaths && !children.contains(QLatin1String(platformsSection)))
+ || children.contains(QLatin1String("Paths"));
#ifndef QT_BOOTSTRAPPED
if (!havePaths)
settings.reset(0);
@@ -156,23 +160,23 @@ QSettings *QLibraryInfoPrivate::findConfiguration()
#else
if (!QFile::exists(qtconfig) && QCoreApplication::instance()) {
#ifdef Q_OS_MAC
- CFBundleRef bundleRef = CFBundleGetMainBundle();
+ CFBundleRef bundleRef = CFBundleGetMainBundle();
if (bundleRef) {
- QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
- QCFString(QLatin1String("qt.conf")),
- 0,
- 0);
- if (urlRef) {
- QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
- qtconfig = QDir::cleanPath(path);
- }
- }
- if (qtconfig.isEmpty())
+ QCFType<CFURLRef> urlRef = CFBundleCopyResourceURL(bundleRef,
+ QCFString(QLatin1String("qt.conf")),
+ 0,
+ 0);
+ if (urlRef) {
+ QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
+ qtconfig = QDir::cleanPath(path);
+ }
+ }
+ if (qtconfig.isEmpty())
#endif
{
QDir pwd(QCoreApplication::applicationDirPath());
qtconfig = pwd.filePath(QLatin1String("qt.conf"));
- }
+ }
}
#endif
if (QFile::exists(qtconfig))
@@ -251,6 +255,57 @@ QLibraryInfo::buildDate()
}
#endif //QT_NO_DATESTRING
+#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
+# ifdef __apple_build_version__ // Apple clang has other version numbers
+# define COMPILER_STRING __clang_version__ " (Apple)"
+# else
+# define COMPILER_STRING __clang_version__
+# endif
+#elif defined(Q_CC_GNU)
+# define COMPILER_STRING "GCC " __VERSION__
+#elif defined(Q_CC_MSVC)
+# if _MSC_VER < 1600
+# define COMPILER_STRING "MSVC 2008"
+# elif _MSC_VER < 1700
+# define COMPILER_STRING "MSVC 2010"
+# elif _MSC_VER < 1800
+# define COMPILER_STRING "MSVC 2012"
+# elif _MSC_VER < 1900
+# define COMPILER_STRING "MSVC 2013"
+# else
+# define COMPILER_STRING "MSVC <unknown version>"
+# endif
+#else
+# define COMPILER_STRING "<unknown compiler>"
+#endif
+
+/*!
+ Returns a string describing how this version of Qt was built.
+
+ \internal
+
+ \since 5.3
+*/
+
+const char *QLibraryInfo::build()
+{
+ static const char data[] = "Qt " QT_VERSION_STR " (" __DATE__ "), "
+ COMPILER_STRING ", "
+#if QT_POINTER_SIZE == 4
+ "32"
+#else
+ "64"
+#endif
+ " bit, "
+#ifdef QT_NO_DEBUG
+ "release"
+#else
+ "debug"
+#endif
+ " build)";
+ return data;
+}
+
/*!
\since 5.0
Returns \c true if this build of Qt was built with debugging enabled, or
@@ -466,6 +521,33 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
}
/*!
+ Returns additional arguments to the platform plugin matching
+ \a platformName which can be specified as a string list using
+ the key \c Arguments in a group called \c Platforms of the
+ \c qt.conf file.
+
+ sa {Using qt.conf}
+
+ \internal
+
+ \since 5.3
+*/
+
+QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
+{
+#ifndef QT_BOOTSTRAPPED
+ if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) {
+ QString key = QLatin1String(platformsSection);
+ key += QLatin1Char('/');
+ key += platformName;
+ key += QLatin1String("Arguments");
+ return settings->value(key).toStringList();
+ }
+#endif // !QT_BOOTSTRAPPED
+ return QStringList();
+}
+
+/*!
\enum QLibraryInfo::LibraryLocation
\keyword library location
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 17864b555b..2a8a3b84b9 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -47,6 +47,8 @@
QT_BEGIN_NAMESPACE
+class QStringList;
+
class Q_CORE_EXPORT QLibraryInfo
{
public:
@@ -57,6 +59,8 @@ public:
static QDate buildDate();
#endif //QT_NO_DATESTRING
+ static const char * build();
+
static bool isDebugBuild();
enum LibraryLocation
@@ -96,6 +100,8 @@ public:
static QString rawLocation(LibraryLocation, PathGroup);
#endif
+ static QStringList platformPluginArguments(const QString &platformName);
+
private:
QLibraryInfo();
};
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index cff8846cdc..64dd544cf0 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -46,10 +46,10 @@
#include "qvarlengtharray.h"
#include "qdebug.h"
#include "qmutex.h"
+#include "qloggingcategory.h"
#ifndef QT_BOOTSTRAPPED
#include "qcoreapplication.h"
#include "qthread.h"
-#include "qloggingcategory.h"
#include "private/qloggingregistry_p.h"
#endif
#ifdef Q_OS_WIN
@@ -63,6 +63,11 @@
#include <android/log.h>
#endif
+#if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+# include <systemd/sd-journal.h>
+# include <unistd.h>
+#endif
+
#include <stdio.h>
QT_BEGIN_NAMESPACE
@@ -265,6 +270,76 @@ void QMessageLogger::debug(const char *msg, ...) const
qt_message_fatal(QtDebugMsg, context, message);
}
+/*!
+ \typedef QMessageLogger::CategoryFunction
+
+ This is a typedef for a pointer to a function with the following
+ signature:
+
+ \snippet code/qlogging/qlogging.cpp 2
+
+ A function which this signature is generated by Q_DECLARE_LOGGING_CATEGORY,
+ Q_LOGGING_CATEGORY.
+
+ \since 5.3
+*/
+
+/*!
+ Logs a debug message specified with format \a msg for the context \a cat.
+ Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCDebug()
+*/
+void QMessageLogger::debug(const QLoggingCategory &cat, const char *msg, ...) const
+{
+ if (!cat.isDebugEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtDebugMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtDebugMsg))
+ qt_message_fatal(QtDebugMsg, ctxt, message);
+}
+
+/*!
+ Logs a debug message specified with format \a msg for the context returned
+ by \a catFunc. Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCDebug()
+*/
+void QMessageLogger::debug(QMessageLogger::CategoryFunction catFunc,
+ const char *msg, ...) const
+{
+ const QLoggingCategory &cat = (*catFunc)();
+ if (!cat.isDebugEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtDebugMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtDebugMsg))
+ qt_message_fatal(QtDebugMsg, ctxt, message);
+}
+
#ifndef QT_NO_DEBUG_STREAM
/*!
@@ -281,6 +356,36 @@ QDebug QMessageLogger::debug() const
}
/*!
+ Logs a debug message into category \a cat using a QDebug stream.
+
+ \since 5.3
+ \sa qCDebug(), QDebug
+*/
+QDebug QMessageLogger::debug(const QLoggingCategory &cat) const
+{
+ QDebug dbg = QDebug(QtDebugMsg);
+ if (!cat.isDebugEnabled())
+ dbg.stream->message_output = false;
+
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ return dbg;
+}
+
+/*!
+ Logs a debug message into category returned by \a catFunc using a QDebug stream.
+
+ \since 5.3
+ \sa qCDebug(), QDebug
+*/
+QDebug QMessageLogger::debug(QMessageLogger::CategoryFunction catFunc) const
+{
+ return debug((*catFunc)());
+}
+
+/*!
\internal
Returns a QNoDebug object, which is used to ignore debugging output.
@@ -314,9 +419,65 @@ void QMessageLogger::warning(const char *msg, ...) const
qt_message_fatal(QtWarningMsg, context, message);
}
+/*!
+ Logs a warning message specified with format \a msg for the context \a cat.
+ Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCWarning()
+*/
+void QMessageLogger::warning(const QLoggingCategory &cat, const char *msg, ...) const
+{
+ if (!cat.isWarningEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtWarningMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtWarningMsg))
+ qt_message_fatal(QtWarningMsg, ctxt, message);
+}
+
+/*!
+ Logs a warning message specified with format \a msg for the context returned
+ by \a catFunc. Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCWarning()
+*/
+void QMessageLogger::warning(QMessageLogger::CategoryFunction catFunc,
+ const char *msg, ...) const
+{
+ const QLoggingCategory &cat = (*catFunc)();
+ if (!cat.isWarningEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtWarningMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtWarningMsg))
+ qt_message_fatal(QtWarningMsg, ctxt, message);
+}
+
#ifndef QT_NO_DEBUG_STREAM
/*!
- Logs a debug message using a QDebug stream
+ Logs a warning message using a QDebug stream
\sa qWarning(), QDebug
*/
@@ -327,6 +488,36 @@ QDebug QMessageLogger::warning() const
ctxt.copy(context);
return dbg;
}
+
+/*!
+ Logs a warning message into category \a cat using a QDebug stream.
+
+ \sa qCWarning(), QDebug
+*/
+QDebug QMessageLogger::warning(const QLoggingCategory &cat) const
+{
+ QDebug dbg = QDebug(QtWarningMsg);
+ if (!cat.isWarningEnabled())
+ dbg.stream->message_output = false;
+
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ return dbg;
+}
+
+/*!
+ Logs a warning message into category returned by \a catFunc using a QDebug stream.
+
+ \since 5.3
+ \sa qCWarning(), QDebug
+*/
+QDebug QMessageLogger::warning(QMessageLogger::CategoryFunction catFunc) const
+{
+ return warning((*catFunc)());
+}
+
#endif
#undef qCritical
@@ -350,6 +541,62 @@ void QMessageLogger::critical(const char *msg, ...) const
qt_message_fatal(QtCriticalMsg, context, message);
}
+/*!
+ Logs a critical message specified with format \a msg for the context \a cat.
+ Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCCritical()
+*/
+void QMessageLogger::critical(const QLoggingCategory &cat, const char *msg, ...) const
+{
+ if (!cat.isCriticalEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtCriticalMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtCriticalMsg))
+ qt_message_fatal(QtCriticalMsg, ctxt, message);
+}
+
+/*!
+ Logs a critical message specified with format \a msg for the context returned
+ by \a catFunc. Additional parameters, specified by \a msg, may be used.
+
+ \since 5.3
+ \sa qCCritical()
+*/
+void QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc,
+ const char *msg, ...) const
+{
+ const QLoggingCategory &cat = (*catFunc)();
+ if (!cat.isCriticalEnabled())
+ return;
+
+ QMessageLogContext ctxt;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ qt_message(QtCriticalMsg, ctxt, msg, ap, message);
+ va_end(ap);
+
+ if (isFatal(QtCriticalMsg))
+ qt_message_fatal(QtCriticalMsg, ctxt, message);
+}
+
#ifndef QT_NO_DEBUG_STREAM
/*!
Logs a critical message using a QDebug stream
@@ -363,6 +610,37 @@ QDebug QMessageLogger::critical() const
ctxt.copy(context);
return dbg;
}
+
+/*!
+ Logs a critical message into category \a cat using a QDebug stream.
+
+ \since 5.3
+ \sa qCCritical(), QDebug
+*/
+QDebug QMessageLogger::critical(const QLoggingCategory &cat) const
+{
+ QDebug dbg = QDebug(QtCriticalMsg);
+ if (!cat.isCriticalEnabled())
+ dbg.stream->message_output = false;
+
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copy(context);
+ ctxt.category = cat.categoryName();
+
+ return dbg;
+}
+
+/*!
+ Logs a critical message into category returned by \a catFunc using a QDebug stream.
+
+ \since 5.3
+ \sa qCCritical(), QDebug
+*/
+QDebug QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc) const
+{
+ return critical((*catFunc)());
+}
+
#endif
#undef qFatal
@@ -866,12 +1144,43 @@ Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context)
static QtMessageHandler messageHandler = 0; // pointer to debug handler (with context)
+#if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+static void systemd_default_message_handler(QtMsgType type,
+ const QMessageLogContext &context,
+ const QString &message)
+{
+ int priority = LOG_INFO; // Informational
+ switch (type) {
+ case QtDebugMsg:
+ priority = LOG_DEBUG; // Debug-level messages
+ break;
+ case QtWarningMsg:
+ priority = LOG_WARNING; // Warning conditions
+ break;
+ case QtCriticalMsg:
+ priority = LOG_CRIT; // Critical conditions
+ break;
+ case QtFatalMsg:
+ priority = LOG_ALERT; // Action must be taken immediately
+ break;
+ }
+
+ char filebuf[PATH_MAX + sizeof("CODE_FILE=")];
+ snprintf(filebuf, sizeof(filebuf), "CODE_FILE=%s", context.file ? context.file : "unknown");
+
+ char linebuf[20];
+ snprintf(linebuf, sizeof(linebuf), "CODE_LINE=%d", context.line);
+
+ sd_journal_print_with_location(priority, filebuf, linebuf, context.function ? context.function : "unknown", "%s", message.toUtf8().constData());
+}
+#endif
+
#ifdef Q_OS_ANDROID
static void android_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
const QString &message)
{
- android_LogPriority priority;
+ android_LogPriority priority = ANDROID_LOG_DEBUG;
switch (type) {
case QtDebugMsg: priority = ANDROID_LOG_DEBUG; break;
case QtWarningMsg: priority = ANDROID_LOG_WARN; break;
@@ -902,6 +1211,18 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
#if defined(QT_USE_SLOG2)
slog2_default_handler(type, logMessage.toLocal8Bit().constData());
+#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+ // We use isatty to catch the obvious case of someone running something interactively.
+ // We also support an environment variable for Qt Creator use, or more complicated cases like subprocesses.
+ static bool logToConsole = isatty(fileno(stdin)) || !qEnvironmentVariableIsEmpty("QT_NO_JOURNALD_LOG");
+ if (Q_LIKELY(!logToConsole)) {
+ // remove trailing \n, systemd appears to want them newline-less
+ logMessage.chop(1);
+ systemd_default_message_handler(type, context, logMessage);
+ } else {
+ fprintf(stderr, "%s", logMessage.toUtf8().constData());
+ fflush(stderr);
+ }
#elif defined(Q_OS_ANDROID)
static bool logToAndroid = qEnvironmentVariableIsEmpty("QT_ANDROID_PLAIN_LOG");
if (logToAndroid) {
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 5ae1fb3205..6ebffa3ba1 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -82,6 +82,8 @@ private:
friend class QDebug;
};
+class QLoggingCategory;
+
class Q_CORE_EXPORT QMessageLogger
{
Q_DISABLE_COPY(QMessageLogger)
@@ -98,6 +100,15 @@ public:
void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ typedef const QLoggingCategory &(*CategoryFunction)();
+
+ void debug(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ void debug(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ void warning(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ void warning(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ void critical(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ void critical(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+
#ifndef Q_CC_MSVC
Q_NORETURN
#endif
@@ -105,8 +116,14 @@ public:
#ifndef QT_NO_DEBUG_STREAM
QDebug debug() const;
+ QDebug debug(const QLoggingCategory &cat) const;
+ QDebug debug(CategoryFunction catFunc) const;
QDebug warning() const;
+ QDebug warning(const QLoggingCategory &cat) const;
+ QDebug warning(CategoryFunction catFunc) const;
QDebug critical() const;
+ QDebug critical(const QLoggingCategory &cat) const;
+ QDebug critical(CategoryFunction catFunc) const;
QNoDebug noDebug() const Q_DECL_NOTHROW;
#endif // QT_NO_DEBUG_STREAM
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 8a46f3a6ab..d7ae97e911 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -44,6 +44,10 @@
#include <QtCore/qglobal.h>
+#if defined(__OBJC__) && !defined(__cplusplus)
+# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
+#endif
+
QT_BEGIN_NAMESPACE
@@ -64,7 +68,7 @@ Qt {
Q_ENUMS(ArrowType ToolButtonStyle PenStyle PenCapStyle PenJoinStyle BrushStyle)
Q_ENUMS(FillRule MaskMode BGMode ClipOperation SizeMode)
Q_ENUMS(Axis Corner Edge LayoutDirection SizeHint Orientation DropAction)
- Q_FLAGS(Alignment Orientations DropActions)
+ Q_FLAGS(Alignment Orientations DropActions Edges)
Q_FLAGS(DockWidgetAreas ToolBarAreas)
Q_ENUMS(DockWidgetArea ToolBarArea)
Q_ENUMS(TextFormat)
@@ -512,6 +516,9 @@ public:
AA_SynthesizeTouchForUnhandledMouseEvents = 11,
AA_SynthesizeMouseForUnhandledTouchEvents = 12,
AA_UseHighDpiPixmaps = 13,
+ AA_ForceRasterWidgets = 14,
+ AA_UseDesktopOpenGL = 15,
+ AA_UseOpenGLES = 16,
// Add new attributes before this line
AA_AttributeCount
@@ -998,6 +1005,10 @@ public:
Key_ChannelUp = 0x01000118,
Key_ChannelDown = 0x01000119,
+ Key_Guide = 0x0100011a,
+ Key_Info = 0x0100011b,
+ Key_Settings = 0x0100011c,
+
Key_MediaLast = 0x0100ffff,
// Keypad navigation keys
@@ -1015,6 +1026,7 @@ public:
//Key_Jisho = 0x01020007, // IME: Dictionary key
//Key_Oyayubi_Left = 0x01020008, // IME: Left Oyayubi key
//Key_Oyayubi_Right = 0x01020009, // IME: Right Oyayubi key
+ Key_Exit = 0x0102000a,
// Device keys
Key_Context1 = 0x01100000,
@@ -1235,6 +1247,8 @@ public:
BottomEdge = 0x00008
};
+ Q_DECLARE_FLAGS(Edges, Edge)
+
enum ConnectionType {
AutoConnection,
DirectConnection,
@@ -1318,6 +1332,10 @@ public:
ImHints = 0x100,
ImPreferredLanguage = 0x200,
+ ImAbsolutePosition = 0x400,
+ ImTextBeforeCursor = 0x800,
+ ImTextAfterCursor = 0x1000,
+
ImPlatformData = 0x80000000,
ImQueryInput = ImCursorRectangle | ImCursorPosition | ImSurroundingText |
ImCurrentSelection | ImAnchorPosition,
@@ -1596,6 +1614,19 @@ public:
ScrollUpdate,
ScrollEnd
};
+
+ enum MouseEventSource {
+ MouseEventNotSynthesized,
+ MouseEventSynthesizedBySystem,
+ MouseEventSynthesizedByQt
+ };
+
+ enum MouseEventFlag {
+ MouseEventCreatedDoubleClick = 0x01,
+ MouseEventFlagMask = 0xFF
+ };
+ Q_DECLARE_FLAGS(MouseEventFlags, MouseEventFlag)
+
}
#ifdef Q_MOC_RUN
;
@@ -1606,6 +1637,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Orientations)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::KeyboardModifiers)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::WindowFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Alignment)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Edges)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ImageConversionFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::DockWidgetAreas)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::ToolBarAreas)
@@ -1618,6 +1650,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodQueries)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints)
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates)
+Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseEventFlags)
#ifndef QT_NO_GESTURES
Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags)
#endif
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index ae377e124b..31bc18749b 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -106,17 +106,6 @@
QCoreApplication::setAttribute(), and can be tested for with
QCoreApplication::testAttribute().
- \value AA_ImmediateWidgetCreation Ensures that widgets are created
- as soon as they are constructed. By default, resources for
- widgets are allocated on demand to improve efficiency and
- minimize resource usage. Setting or clearing this attribute
- affects widgets constructed after the change. Setting it
- tells Qt to create toplevel windows immediately.
- Therefore, if it is important to minimize resource
- consumption, do not set this attribute.
-
- \value AA_MSWindowsUseDirect3DByDefault This value is obsolete and
- has no effect.
\value AA_DontShowIconsInMenus Actions with the Icon property won't be
shown in any menus unless specifically set by the
@@ -176,6 +165,32 @@
sizes in layout geometry calculations should typically divide by
QPixmap::devicePixelRatio() to get device-independent layout geometry.
+ \value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces,
+ and do not support non-native GL-based child widgets.
+
+ \value AA_UseDesktopOpenGL Forces the usage of the desktop OpenGL on
+ platforms that use dynamic loading of the OpenGL implementation.
+ This value has been added in Qt 5.3.
+
+ \value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 on platforms that
+ use dynamic loading of the OpenGL implementation.
+ This value has been added in Qt 5.3.
+
+ The following values are obsolete:
+
+ \value AA_ImmediateWidgetCreation This attribute is no longer fully
+ supported in Qt 5. It ensures that widgets are created
+ as soon as they are constructed. By default, resources for
+ widgets are allocated on demand to improve efficiency and
+ minimize resource usage. Setting or clearing this attribute
+ affects widgets constructed after the change. Setting it
+ tells Qt to create toplevel windows immediately.
+ Therefore, if it is important to minimize resource
+ consumption, do not set this attribute.
+
+ \value AA_MSWindowsUseDirect3DByDefault This value is obsolete and
+ has no effect.
+
\omitvalue AA_AttributeCount
*/
@@ -699,9 +714,10 @@
retain an alpha channel for some other reason. If the image has no
alpha channel this flag has no effect.
- \omitvalue NoFormatConversion Don't do any format conversions on the image.
+ \value NoFormatConversion Don't do any format conversions on the image.
Can be useful when converting a QImage to a QPixmap for a one-time
- rendering operation for example.
+ rendering operation for example. Note that a QPixmap not in the
+ preferred format will be much slower as a paint device.
*/
/*!
@@ -2430,6 +2446,11 @@
\value ImHints The hints for input method on expected input. (See Qt::InputMethodHints)
\value ImPreferredLanguage The preferred input language.
\value ImPlatformData Platform specific data for input method.
+ \value ImAbsolutePosition The logical position of the cursor within the entire document.
+ \value ImTextBeforeCursor The plain text before the cursor. The widget can decide how much text to return,
+ but \b{must} not return an empty string unless the cursor is at the start of the document.
+ \value ImTextAfterCursor The plain text after the cursor. The widget can decide how much text to return,
+ but \b{must} not return an empty string unless the cursor is at the end of the document.
Masks:
@@ -2895,3 +2916,38 @@
\value ScrollEnd Scrolling has ended, but the scrolling distance
did not change anymore.
*/
+
+/*!
+ \enum Qt::MouseEventSource
+ \since 5.3
+
+ This enum describes the source of a mouse event and can be useful
+ to determine if the event is an artificial mouse event originating
+ from another device such as a touchscreen.
+
+ \value MouseEventNotSynthesized The most common value. On
+ platforms where such information is available this value indicates
+ that the event was generated in response to a genuine mouse event
+ in the system.
+
+ \value MouseEventSynthesizedBySystem Indicates that the mouse
+ event was synthesized from a touch event by the platform.
+
+ \value MouseEventSynthesizedByQt Indicates that the mouse event was
+ synthesized from an unhandled touch event by Qt.
+
+ \sa Qt::AA_SynthesizeMouseForUnhandledTouchEvents
+*/
+
+/*!
+ \enum Qt::MouseEventFlag
+ \since 5.3
+
+ This enum provides additional information concerning a QMouseEvent.
+
+ \value MouseEventCreatedDoubleClick Indicates that Qt has created a
+ MouseButtonDblClick event from this event. The flag is set in the causing
+ MouseButtonPress, and not in the resulting MouseButtonDblCLick.
+
+ \omitvalue MouseEventFlagMask
+*/
diff --git a/src/corelib/global/qnumeric.cpp b/src/corelib/global/qnumeric.cpp
index d09357c26c..7d8bd8c3c6 100644
--- a/src/corelib/global/qnumeric.cpp
+++ b/src/corelib/global/qnumeric.cpp
@@ -41,6 +41,7 @@
#include "qnumeric.h"
#include "qnumeric_p.h"
+#include <string.h>
QT_BEGIN_NAMESPACE
@@ -99,4 +100,139 @@ Q_CORE_EXPORT double qQNaN() { return qt_qnan(); }
Q_CORE_EXPORT double qInf() { return qt_inf(); }
+
+/*!
+ \internal
+ */
+static inline quint32 f2i(float f)
+{
+ quint32 i;
+ memcpy(&i, &f, sizeof(f));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function provides an alternative way of doing approximated comparisons of floating-point
+ numbers similar to qFuzzyCompare(). However, it returns the distance between two numbers, which
+ gives the caller a possibility to choose the accepted error. Errors are relative, so for
+ instance the distance between 1.0E-5 and 1.00001E-5 will give 110, while the distance between
+ 1.0E36 and 1.00001E36 will give 127.
+
+ This function is useful if a floating point comparison requires a certain precision.
+ Therefore, if \a a and \a b are equal it will return 0. The maximum value it will return for 32-bit
+ floating point numbers is 4,278,190,078. This is the distance between \c{-FLT_MAX} and
+ \c{+FLT_MAX}.
+
+ The function does not give meaningful results if any of the arguments are \c Infinite or \c NaN.
+ You can check for this by calling qIsFinite().
+
+ The return value can be considered as the "error", so if you for instance want to compare
+ two 32-bit floating point numbers and all you need is an approximated 24-bit precision, you can
+ use this function like this:
+
+ \code
+ if (qFloatDistance(a, b) < (1 << 7)) { // The last 7 bits are not
+ // significant
+ // precise enough
+ }
+ \endcode
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b)
+{
+ static const quint32 smallestPositiveFloatAsBits = 0x00000001; // denormalized, (SMALLEST), (1.4E-45)
+ /* Assumes:
+ * IEE754 format.
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint32) == sizeof(float));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0F, a) + qFloatDistance(0.0F, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return f2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return f2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? f2i(a) - f2i(b) : f2i(b) - f2i(a);
+}
+
+
+/*!
+ \internal
+ */
+static inline quint64 d2i(double d)
+{
+ quint64 i;
+ memcpy(&i, &d, sizeof(d));
+ return i;
+}
+
+/*!
+ Returns the number of representable floating-point numbers between \a a and \a b.
+
+ This function serves the same purpose as \c{qFloatDistance(float, float)}, but
+ returns the distance between two \c double numbers. Since the range is larger
+ than for two \c float numbers (\c{[-DBL_MAX,DBL_MAX]}), the return type is quint64.
+
+
+ \sa qFuzzyCompare()
+ \relates <QtGlobal>
+*/
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b)
+{
+ static const quint64 smallestPositiveFloatAsBits = 0x1; // denormalized, (SMALLEST)
+ /* Assumes:
+ * IEE754 format double precision
+ * Integers and floats have the same endian
+ */
+ Q_STATIC_ASSERT(sizeof(quint64) == sizeof(double));
+ Q_ASSERT(qIsFinite(a) && qIsFinite(b));
+ if (a == b)
+ return 0;
+ if ((a < 0) != (b < 0)) {
+ // if they have different signs
+ if (a < 0)
+ a = -a;
+ else /*if (b < 0)*/
+ b = -b;
+ return qFloatDistance(0.0, a) + qFloatDistance(0.0, b);
+ }
+ if (a < 0) {
+ a = -a;
+ b = -b;
+ }
+ // at this point a and b should not be negative
+
+ // 0 is special
+ if (!a)
+ return d2i(b) - smallestPositiveFloatAsBits + 1;
+ if (!b)
+ return d2i(a) - smallestPositiveFloatAsBits + 1;
+
+ // finally do the common integer subtraction
+ return a > b ? d2i(a) - d2i(b) : d2i(b) - d2i(a);
+}
+
+
QT_END_NAMESPACE
diff --git a/src/corelib/global/qnumeric.h b/src/corelib/global/qnumeric.h
index 25db5443eb..633486dff1 100644
--- a/src/corelib/global/qnumeric.h
+++ b/src/corelib/global/qnumeric.h
@@ -57,6 +57,9 @@ Q_CORE_EXPORT double qSNaN();
Q_CORE_EXPORT double qQNaN();
Q_CORE_EXPORT double qInf();
+Q_CORE_EXPORT quint32 qFloatDistance(float a, float b);
+Q_CORE_EXPORT quint64 qFloatDistance(double a, double b);
+
#define Q_INFINITY (QT_PREPEND_NAMESPACE(qInf)())
#define Q_SNAN (QT_PREPEND_NAMESPACE(qSNaN)())
#define Q_QNAN (QT_PREPEND_NAMESPACE(qQNaN)())
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index 623e30aa06..cf7ee1b7aa 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -196,6 +196,7 @@
# define Q_PROCESSOR_X86 6
# define Q_PROCESSOR_X86_64
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
+# define Q_PROCESSOR_WORDSIZE 8
/*
Itanium (IA-64) family, no revisions or variants
@@ -204,6 +205,7 @@
*/
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
# define Q_PROCESSOR_IA64
+# define Q_PROCESSOR_WORDSIZE 8
// Q_BYTE_ORDER not defined, use endianness auto-detection
/*
@@ -324,4 +326,22 @@
# endif
#endif
+/*
+ Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually,
+ the size of the register). On some architectures where a pointer could be
+ smaller than the register, the macro is defined above.
+
+ Falls back to QT_POINTER_SIZE if not set explicitly for the platform.
+*/
+#ifndef Q_PROCESSOR_WORDSIZE
+# ifdef __SIZEOF_POINTER__
+ /* GCC & friends define this */
+# define Q_PROCESSOR_WORDSIZE __SIZEOF_POINTER__
+# elif defined(_LP64) || defined(__LP64__) || defined(WIN64) || defined(_WIN64)
+# define Q_PROCESSOR_WORDSIZE 8
+# else
+# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE
+# endif
+#endif
+
#endif // QPROCESSORDETECTION_H
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 5837c8d94e..8478e08416 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include <QtCore/qglobal.h>
+#include <QtCore/qtypetraits.h>
#ifndef QTYPEINFO_H
#define QTYPEINFO_H
@@ -60,6 +60,7 @@ class QTypeInfo
public:
enum {
isPointer = false,
+ isIntegral = QtPrivate::is_integral<T>::value,
isComplex = true,
isStatic = true,
isLarge = (sizeof(T)>sizeof(void*)),
@@ -74,6 +75,7 @@ class QTypeInfo<void>
public:
enum {
isPointer = false,
+ isIntegral = false,
isComplex = false,
isStatic = false,
isLarge = false,
@@ -88,6 +90,7 @@ class QTypeInfo<T*>
public:
enum {
isPointer = true,
+ isIntegral = false,
isComplex = false,
isStatic = false,
isLarge = false,
@@ -125,6 +128,7 @@ public:
isStatic = QTypeInfo<T1>::isStatic || QTypeInfo<T2>::isStatic || QTypeInfo<T3>::isStatic || QTypeInfo<T4>::isStatic,
isLarge = sizeof(T) > sizeof(void*),
isPointer = false,
+ isIntegral = false,
isDummy = false,
sizeOf = sizeof(T)
};
@@ -138,6 +142,7 @@ class QTypeInfo< CONTAINER<T> > \
public: \
enum { \
isPointer = false, \
+ isIntegral = false, \
isComplex = true, \
isStatic = false, \
isLarge = (sizeof(CONTAINER<T>) > sizeof(void*)), \
@@ -180,6 +185,7 @@ public: \
isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \
isLarge = (sizeof(TYPE)>sizeof(void*)), \
isPointer = false, \
+ isIntegral = QtPrivate::is_integral< TYPE >::value, \
isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0), \
sizeOf = sizeof(TYPE) \
}; \
@@ -239,5 +245,14 @@ Q_DECLARE_TYPEINFO(double, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(long double, Q_PRIMITIVE_TYPE);
#endif
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+// We can't do it now because it would break BC on QList<char32_t>
+Q_DECLARE_TYPEINFO(char16_t, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(char32_t, Q_PRIMITIVE_TYPE);
+# if !defined(Q_CC_MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+Q_DECLARE_TYPEINFO(wchar_t, Q_PRIMITIVE_TYPE);
+# endif
+#endif // Qt 6
+
QT_END_NAMESPACE
#endif // QTYPEINFO_H
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 649493f8b7..989e4644c7 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -94,7 +94,6 @@ SOURCES += \
io/qloggingregistry.cpp
win32 {
- SOURCES += io/qsettings_win.cpp
SOURCES += io/qfsfileengine_win.cpp
SOURCES += io/qlockfile_win.cpp
@@ -102,11 +101,12 @@ win32 {
HEADERS += io/qfilesystemwatcher_win_p.h
SOURCES += io/qfilesystemengine_win.cpp
SOURCES += io/qfilesystemiterator_win.cpp
- SOURCES += io/qstandardpaths_win.cpp
!winrt {
+ SOURCES += io/qsettings_win.cpp
HEADERS += io/qwindowspipewriter_p.h
SOURCES += io/qwindowspipewriter.cpp
+ SOURCES += io/qstandardpaths_win.cpp
wince* {
SOURCES += io/qprocess_wince.cpp
@@ -119,6 +119,8 @@ win32 {
io/qwinoverlappedionotifier.cpp \
io/qwindowspipereader.cpp
}
+ } else {
+ SOURCES += io/qstandardpaths_winrt.cpp
}
} else:unix|integrity {
SOURCES += \
@@ -133,6 +135,10 @@ win32 {
OBJECTIVE_SOURCES += io/qurl_mac.mm
}
mac {
+ osx {
+ OBJECTIVE_SOURCES += io/qfilesystemwatcher_fsevents.mm
+ HEADERS += io/qfilesystemwatcher_fsevents_p.h
+ }
macx {
SOURCES += io/qstandardpaths_mac.cpp
} else:ios {
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index af5605f8c7..a6fbffee7e 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -251,7 +251,7 @@ QT_BEGIN_NAMESPACE
return retVal;
enum {
- DefaultStreamVersion = QDataStream::Qt_5_2
+ DefaultStreamVersion = QDataStream::Qt_5_3
};
/*!
@@ -541,6 +541,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_0 Version 13 (Qt 5.0)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
+ \value Qt_5_3 Same as Qt_5_2
\sa setVersion(), version()
*/
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index f107e801b6..28f1d51a12 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -87,8 +87,9 @@ public:
Qt_4_9 = Qt_4_8,
Qt_5_0 = 13,
Qt_5_1 = 14,
- Qt_5_2 = 15
-#if QT_VERSION >= 0x050300
+ Qt_5_2 = 15,
+ Qt_5_3 = Qt_5_2
+#if QT_VERSION >= 0x050400
#error Add the datastream version for this Qt version
#endif
};
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 9ed5f6e951..00177b659e 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -80,7 +80,9 @@ public:
inline QDebug &operator=(const QDebug &other);
inline ~QDebug() {
if (!--stream->ref) {
- if(stream->message_output) {
+ if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
+ stream->buffer.chop(1);
+ if (stream->message_output) {
QT_TRY {
qt_message_output(stream->type,
stream->context,
@@ -172,6 +174,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QList<T> &list)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << '(';
for (typename QList<T>::size_type i = 0; i < list.count(); ++i) {
if (i)
@@ -179,7 +182,8 @@ inline QDebug operator<<(QDebug debug, const QList<T> &list)
debug << list.at(i);
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -190,7 +194,9 @@ template <typename T>
inline QDebug operator<<(QDebug debug, const QVector<T> &vec)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QVector";
+ debug.setAutoInsertSpaces(oldSetting);
return operator<<(debug, vec.toList());
}
@@ -202,13 +208,15 @@ template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QMap<aKey, aT> &map)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QMap(";
for (typename QMap<aKey, aT>::const_iterator it = map.constBegin();
it != map.constEnd(); ++it) {
debug << '(' << it.key() << ", " << it.value() << ')';
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -219,12 +227,14 @@ template <class aKey, class aT>
inline QDebug operator<<(QDebug debug, const QHash<aKey, aT> &hash)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QHash(";
for (typename QHash<aKey, aT>::const_iterator it = hash.constBegin();
it != hash.constEnd(); ++it)
debug << '(' << it.key() << ", " << it.value() << ')';
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -235,14 +245,18 @@ template <class T1, class T2>
inline QDebug operator<<(QDebug debug, const QPair<T1, T2> &pair)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QPair(" << pair.first << ',' << pair.second << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
template <typename T>
inline QDebug operator<<(QDebug debug, const QSet<T> &set)
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QSet";
+ debug.setAutoInsertSpaces(oldSetting);
return operator<<(debug, set.toList());
}
@@ -254,6 +268,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QContiguousCache(";
for (int i = cache.firstIndex(); i <= cache.lastIndex(); ++i) {
debug << cache[i];
@@ -261,7 +276,8 @@ inline QDebug operator<<(QDebug debug, const QContiguousCache<T> &cache)
debug << ", ";
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
#if defined(FORCE_UREF)
@@ -272,6 +288,7 @@ template <class T>
inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
#endif
{
+ const bool oldSetting = debug.autoInsertSpaces();
debug.nospace() << "QFlags(";
bool needSeparator = false;
for (uint i = 0; i < sizeof(T) * 8; ++i) {
@@ -284,7 +301,8 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
}
}
debug << ')';
- return debug.space();
+ debug.setAutoInsertSpaces(oldSetting);
+ return debug.maybeSpace();
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index c5a0db310a..ec7d89fa87 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2146,7 +2146,7 @@ QString QDir::cleanPath(const QString &path)
name.replace(dir_separator, QLatin1Char('/'));
bool allowUncPaths = false;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //allow unc paths
allowUncPaths = true;
#endif
diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp
index 5b48c4c7db..79cdec9674 100644
--- a/src/corelib/io/qdiriterator.cpp
+++ b/src/corelib/io/qdiriterator.cpp
@@ -477,7 +477,7 @@ QDirIterator::~QDirIterator()
/*!
Advances the iterator to the next entry, and returns the file path of this
new entry. If hasNext() returns \c false, this function does nothing, and
- returns a null QString.
+ returns an empty QString.
You can call fileName() or filePath() to get the current entry file name
or path, or fileInfo() to get a QFileInfo for the current entry.
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 257f18a6bb..dbc6d28846 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -63,13 +63,28 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#else // !Q_OS_WINRT
+# include <wrl.h>
+# include <windows.foundation.h>
+# include <windows.storage.h>
+# include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+#endif // Q_OS_WINRT
#ifndef SPI_GETPLATFORMTYPE
#define SPI_GETPLATFORMTYPE 257
@@ -141,7 +156,7 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
-#if defined(Q_OS_WINCE)
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
static QString qfsPrivateCurrentDir = QLatin1String("");
// As none of the functions we try to resolve do exist on Windows CE
// we use QT_NO_LIBRARY to shorten everything up a little bit.
@@ -289,14 +304,14 @@ static bool resolveUNCLibs()
}
#endif
triedResolve = true;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HINSTANCE hLib = QSystemLibrary::load(L"Netapi32");
if (hLib) {
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
if (ptrNetShareEnum)
ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree");
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
return ptrNetShareEnum && ptrNetApiBufferFree;
}
@@ -304,7 +319,7 @@ static bool resolveUNCLibs()
static QString readSymLink(const QFileSystemEntry &link)
{
QString result;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(),
FILE_READ_EA,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
@@ -347,11 +362,11 @@ static QString readSymLink(const QFileSystemEntry &link)
result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer));
}
}
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
}
#else
Q_UNUSED(link);
-#endif // Q_OS_WINCE
+#endif // Q_OS_WINCE || Q_OS_WINRT
return result;
}
@@ -432,7 +447,11 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
// can't handle drives
if (!path.endsWith(QLatin1Char(':'))) {
+#ifndef Q_OS_WINRT
HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData);
+#else
+ HANDLE hFind = ::FindFirstFileEx((const wchar_t*)path.utf16(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
+#endif
if (hFind != INVALID_HANDLE_VALUE) {
::FindClose(hFind);
return true;
@@ -506,7 +525,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
{
// can be //server or //server/share
QString absPath;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QVarLengthArray<wchar_t, MAX_PATH> buf(qMax(MAX_PATH, path.size() + 1));
wchar_t *fileName = 0;
DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName);
@@ -516,12 +535,17 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
}
if (retLen != 0)
absPath = QString::fromWCharArray(buf.data(), retLen);
-#else
+#elif !defined(Q_OS_WINCE)
+ if (QDir::isRelativePath(path))
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path));
+ else
+ absPath = QDir::toNativeSeparators(QDir::cleanPath(path));
+#else // Q_OS_WINRT
if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\')))
absPath = QDir::toNativeSeparators(path);
else
absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path));
-#endif
+#endif // Q_OS_WINCE
// This is really ugly, but GetFullPathName strips off whitespace at the end.
// If you for instance write ". " in the lineedit of QFileDialog,
// (which is an invalid filename) this function will strip the space off and viola,
@@ -548,9 +572,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
ret = entry.filePath();
#endif
} else {
+#ifndef Q_OS_WINRT
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath());
+#else
+ // Some WinRT APIs do not support absolute paths (due to sandboxing).
+ // Thus the port uses the executable's directory as its root directory
+ // and treats paths relative to that as absolute paths.
+ ret = QDir::cleanPath(QDir::current().relativeFilePath(entry.filePath()));
+#endif
}
+#ifndef Q_OS_WINRT
// The path should be absolute at this point.
// From the docs :
// Absolute paths begin with the directory separator "/"
@@ -563,6 +595,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
// Force uppercase drive letters.
ret[0] = ret.at(0).toUpper();
}
+#endif // !Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
}
@@ -590,18 +623,24 @@ typedef struct _FILE_ID_INFO {
static inline QByteArray fileId(HANDLE handle)
{
QByteArray result;
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION info;
if (GetFileInformationByHandle(handle, &info)) {
result = QByteArray::number(uint(info.nFileIndexLow), 16);
result += ':';
result += QByteArray::number(uint(info.nFileIndexHigh), 16);
}
+#else // !Q_OS_WINRT
+ Q_UNUSED(handle);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINRT
return result;
}
// File ID for Windows starting from version 8.
QByteArray fileIdWin8(HANDLE handle)
{
+#ifndef Q_OS_WINRT
typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD);
// Dynamically resolve GetFileInformationByHandleEx (Vista onwards).
@@ -621,6 +660,16 @@ QByteArray fileIdWin8(HANDLE handle)
result += QByteArray((char *)&infoEx.FileId, sizeof(infoEx.FileId)).toHex();
}
}
+#else // !Q_OS_WINRT
+ QByteArray result;
+ FILE_ID_INFO infoEx;
+ if (GetFileInformationByHandleEx(handle, FileIdInfo,
+ &infoEx, sizeof(FILE_ID_INFO))) {
+ result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
+ result += ':';
+ result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex();
+ }
+#endif // Q_OS_WINRT
return result;
}
#endif // !Q_OS_WINCE
@@ -631,8 +680,13 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
#ifndef Q_OS_WINCE
QByteArray result;
const HANDLE handle =
+#ifndef Q_OS_WINRT
CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#else // !Q_OS_WINRT
+ CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
+ FILE_SHARE_READ, OPEN_EXISTING, NULL);
+#endif // Q_OS_WINRT
if (handle) {
result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ?
fileIdWin8(handle) : fileId(handle);
@@ -810,7 +864,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
{
bool entryExists = false;
DWORD fileAttrib = 0;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
if (fname.isDriveRoot()) {
// a valid drive ??
DWORD drivesBitmask = ::GetLogicalDrives();
@@ -851,7 +905,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
fileAttrib = FILE_ATTRIBUTE_DIRECTORY;
entryExists = true;
}
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
}
#endif
if (entryExists)
@@ -894,12 +948,32 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
{
data.entryFlags &= ~what;
clearWinStatData(data);
+#ifndef Q_OS_WINRT
BY_HANDLE_FILE_INFORMATION fileInfo;
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
if (GetFileInformationByHandle(fHandle , &fileInfo)) {
data.fillFromFindInfo(fileInfo);
}
SetErrorMode(oldmode);
+#else // !Q_OS_WINRT
+ FILE_BASIC_INFO fileBasicInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileBasicInfo, &fileBasicInfo, sizeof(fileBasicInfo))) {
+ data.fillFromFileAttribute(fileBasicInfo.FileAttributes);
+ data.creationTime_.dwHighDateTime = fileBasicInfo.CreationTime.HighPart;
+ data.creationTime_.dwLowDateTime = fileBasicInfo.CreationTime.LowPart;
+ data.lastAccessTime_.dwHighDateTime = fileBasicInfo.LastAccessTime.HighPart;
+ data.lastAccessTime_.dwLowDateTime = fileBasicInfo.LastAccessTime.LowPart;
+ data.lastWriteTime_.dwHighDateTime = fileBasicInfo.LastWriteTime.HighPart;
+ data.lastWriteTime_.dwLowDateTime = fileBasicInfo.LastWriteTime.LowPart;
+ if (!(data.fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY)) {
+ FILE_STANDARD_INFO fileStandardInfo;
+ if (GetFileInformationByHandleEx(fHandle, FileStandardInfo, &fileStandardInfo, sizeof(fileStandardInfo)))
+ data.size_ = fileStandardInfo.EndOfFile.QuadPart;
+ } else
+ data.size_ = 0;
+ data.knownFlagsMask |= QFileSystemMetaData::Times | QFileSystemMetaData::SizeAttribute;
+ }
+#endif // Q_OS_WINRT
return data.hasFlags(what);
}
@@ -931,7 +1005,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
}
if (what & QFileSystemMetaData::WinStatFlags) {
+#ifndef Q_OS_WINRT
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+#endif
clearWinStatData(data);
WIN32_FIND_DATA findData;
// The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA
@@ -943,11 +1019,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
} else {
if (!tryFindFallback(fname, data))
if (!tryDriveUNCFallback(fname, data)) {
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
return false;
}
}
+#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
+#endif
}
if (what & QFileSystemMetaData::Permissions)
@@ -1006,7 +1086,14 @@ static bool isDirPath(const QString &dirPath, bool *existed)
if (path.length() == 2 && path.at(1) == QLatin1Char(':'))
path += QLatin1Char('\\');
+#ifndef Q_OS_WINRT
DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
+#else // Q_OS_WINRT
+ DWORD fileAttrib = INVALID_FILE_ATTRIBUTES;
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data))
+ fileAttrib = data.dwFileAttributes;
+#endif // Q_OS_WINRT
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
int errorCode = GetLastError();
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
@@ -1100,6 +1187,30 @@ QString QFileSystemEngine::rootPath()
{
#if defined(Q_OS_WINCE)
QString ret = QLatin1String("/");
+#elif defined(Q_OS_WINRT)
+ // We specify the package root as root directory
+ QString ret = QLatin1String("/");
+ // Get package location
+ ComPtr<IPackageStatics> statics;
+ if (FAILED(GetActivationFactory(HStringReference(RuntimeClass_Windows_ApplicationModel_Package).Get(), &statics)))
+ return ret;
+ ComPtr<IPackage> package;
+ if (FAILED(statics->get_Current(&package)))
+ return ret;
+ ComPtr<IStorageFolder> installedLocation;
+ if (FAILED(package->get_InstalledLocation(&installedLocation)))
+ return ret;
+
+ ComPtr<IStorageItem> item;
+ if (FAILED(installedLocation.As(&item)))
+ return ret;
+
+ HSTRING finalWinPath;
+ if (FAILED(item->get_Path(&finalWinPath)))
+ return ret;
+
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(finalWinPath, nullptr)));
+
#else
QString ret = QString::fromLatin1(qgetenv("SystemDrive").constData());
if (ret.isEmpty())
@@ -1158,12 +1269,13 @@ QString QFileSystemEngine::homePath()
QString QFileSystemEngine::tempPath()
{
QString ret;
+#ifndef Q_OS_WINRT
wchar_t tempPath[MAX_PATH];
const DWORD len = GetTempPath(MAX_PATH, tempPath);
#ifdef Q_OS_WINCE
if (len)
ret = QString::fromWCharArray(tempPath, len);
-#else
+#else // Q_OS_WINCE
if (len) { // GetTempPath() can return short names, expand.
wchar_t longTempPath[MAX_PATH];
const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH);
@@ -1171,12 +1283,33 @@ QString QFileSystemEngine::tempPath()
QString::fromWCharArray(longTempPath, longLen) :
QString::fromWCharArray(tempPath, len);
}
-#endif
+#endif // !Q_OS_WINCE
if (!ret.isEmpty()) {
while (ret.endsWith(QLatin1Char('\\')))
ret.chop(1);
ret = QDir::fromNativeSeparators(ret);
}
+#else // !Q_OS_WINRT
+ // According to http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.temporaryfolder.aspx
+ // the API is not available on winphone which should cause one of the functions
+ // below to fail
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return ret;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return ret;
+ ComPtr<IStorageFolder> tempFolder;
+ if (FAILED(applicationData->get_TemporaryFolder(&tempFolder)))
+ return ret;
+ ComPtr<IStorageItem> tempFolderItem;
+ if (FAILED(tempFolder.As(&tempFolderItem)))
+ return ret;
+ HSTRING path;
+ if (FAILED(tempFolderItem->get_Path(&path)))
+ return ret;
+ ret = QDir::fromNativeSeparators(QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr)));
+#endif // Q_OS_WINRT
if (ret.isEmpty()) {
#if !defined(Q_OS_WINCE)
ret = QLatin1String("C:/tmp");
@@ -1195,7 +1328,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
if(!(meta.exists() && meta.isDirectory()))
return false;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo
//which causes many problems later on when it's returned through currentPath()
return ::SetCurrentDirectory(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0;
@@ -1208,7 +1341,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
QFileSystemEntry QFileSystemEngine::currentPath()
{
QString ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
DWORD size = 0;
wchar_t currentName[PATH_MAX];
size = ::GetCurrentDirectory(PATH_MAX, currentName);
@@ -1224,13 +1357,17 @@ QFileSystemEntry QFileSystemEngine::currentPath()
}
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
//TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads
if (qfsPrivateCurrentDir.isEmpty())
+#ifndef Q_OS_WINRT
qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
+#else
+ qfsPrivateCurrentDir = QDir::rootPath();
+#endif
ret = qfsPrivateCurrentDir;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath());
}
@@ -1248,8 +1385,16 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
//static
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16(), true) != 0;
+#else // !Q_OS_WINRT
+ COPYFILE2_EXTENDED_PARAMETERS copyParams = {
+ sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
+ };
+ bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), &copyParams) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
@@ -1258,8 +1403,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
//static
bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
{
+#ifndef Q_OS_WINRT
bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(),
(wchar_t*)target.nativeFilePath().utf16()) != 0;
+#else // !Q_OS_WINRT
+ bool ret = ::MoveFileEx((const wchar_t*)source.nativeFilePath().utf16(),
+ (const wchar_t*)target.nativeFilePath().utf16(), 0) != 0;
+#endif // Q_OS_WINRT
if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError);
return ret;
diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp
index 3934c6a673..42a724670e 100644
--- a/src/corelib/io/qfilesystementry.cpp
+++ b/src/corelib/io/qfilesystementry.cpp
@@ -170,6 +170,12 @@ void QFileSystemEntry::resolveNativeFilePath() const
#else
m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath));
#endif
+#ifdef Q_OS_WINRT
+ while (m_nativeFilePath.startsWith(QLatin1Char('\\')))
+ m_nativeFilePath.remove(0,1);
+ if (m_nativeFilePath.isEmpty())
+ m_nativeFilePath.append(QLatin1Char('.'));
+#endif
}
}
diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp
index bfedd3f70c..0b59aa169a 100644
--- a/src/corelib/io/qfilesystemiterator_unix.cpp
+++ b/src/corelib/io/qfilesystemiterator_unix.cpp
@@ -105,8 +105,8 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa
if (!dir)
return false;
-#if defined(Q_OS_QNX) && defined(__EXT_QNX__READDIR_R)
- lastError = _readdir_r(dir, mt_file.data(), &dirEntry, direntSize);
+#if defined(Q_OS_QNX) && defined(QT_EXT_QNX_READDIR_R)
+ lastError = QT_EXT_QNX_READDIR_R(dir, mt_file.data(), &dirEntry, direntSize);
if (lastError)
return false;
#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN)
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp
index 90232f7cfc..dda96bd45a 100644
--- a/src/corelib/io/qfilesystemiterator_win.cpp
+++ b/src/corelib/io/qfilesystemiterator_win.cpp
@@ -39,10 +39,12 @@
**
****************************************************************************/
-#if _WIN32_WINNT < 0x0500
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0500
-#endif
+#if !defined(WINAPI_FAMILY)
+# if _WIN32_WINNT < 0x0500
+# undef _WIN32_WINNT
+# define _WIN32_WINNT 0x0500
+# endif // _WIN32_WINNT < 0x500
+#endif // !WINAPI_FAMILY
#include "qfilesystemiterator_p.h"
#include "qfilesystemengine_p.h"
@@ -73,6 +75,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
if (!nativePath.endsWith(QLatin1Char('\\')))
nativePath.append(QLatin1Char('\\'));
nativePath.append(QLatin1Char('*'));
+#ifdef Q_OS_WINRT
+ if (nativePath.startsWith(QLatin1Char('\\')))
+ nativePath.remove(0, 1);
+#endif
if (!dirPath.endsWith(QLatin1Char('/')))
dirPath.append(QLatin1Char('/'));
if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files))))
diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h
index 1abc9b7ec4..de79ec32d3 100644
--- a/src/corelib/io/qfilesystemmetadata_p.h
+++ b/src/corelib/io/qfilesystemmetadata_p.h
@@ -219,7 +219,9 @@ public:
#if defined(Q_OS_WIN)
inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
+# ifndef Q_OS_WINRT
inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
+# endif
#endif
private:
friend class QFileSystemEngine;
@@ -340,6 +342,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo
}
}
+#ifndef Q_OS_WINRT
inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
{
fillFromFileAttribute(fileInfo.dwFileAttributes);
@@ -355,7 +358,8 @@ inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fi
}
knownFlagsMask |= Times | SizeAttribute;
}
-#endif
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index d1deae2d7b..8cc6ad0552 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -60,8 +60,10 @@
# include "qfilesystemwatcher_win_p.h"
#elif defined(USE_INOTIFY)
# include "qfilesystemwatcher_inotify_p.h"
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) || (defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
# include "qfilesystemwatcher_kqueue_p.h"
+#elif defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
+# include "qfilesystemwatcher_fsevents_p.h"
#endif
QT_BEGIN_NAMESPACE
@@ -74,8 +76,10 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
// there is a chance that inotify may fail on Linux pre-2.6.13 (August
// 2005), so we can't just new inotify directly.
return QInotifyFileSystemWatcherEngine::create(parent);
-#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
+#elif defined(Q_OS_FREEBSD) || defined(Q_OS_IOS) || (defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7)
return QKqueueFileSystemWatcherEngine::create(parent);
+#elif defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
+ return QFseventsFileSystemWatcherEngine::create(parent);
#else
Q_UNUSED(parent);
return 0;
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
new file mode 100644
index 0000000000..cb6ddd913e
--- /dev/null
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -0,0 +1,507 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qplatformdefs.h>
+
+#include "qdiriterator.h"
+#include "qfilesystemwatcher.h"
+#include "qfilesystemwatcher_fsevents_p.h"
+#include "private/qcore_unix_p.h"
+#include "kernel/qcore_mac_p.h"
+
+#ifndef QT_NO_FILESYSTEMWATCHER
+
+#include <qdebug.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qvarlengtharray.h>
+
+//#define FSEVENT_DEBUG
+#ifdef FSEVENT_DEBUG
+# define DEBUG if (true) qDebug
+#else
+# define DEBUG if (false) qDebug
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static void callBackFunction(ConstFSEventStreamRef streamRef,
+ void *clientCallBackInfo,
+ size_t numEvents,
+ void *eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[])
+{
+ char **paths = static_cast<char **>(eventPaths);
+ QFseventsFileSystemWatcherEngine *engine = static_cast<QFseventsFileSystemWatcherEngine *>(clientCallBackInfo);
+ engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds);
+}
+
+void QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
+{
+ QT_STATBUF st;
+ const QString &name = it.key();
+ Info &info = it->dirInfo;
+ const int res = QT_STAT(QFile::encodeName(name), &st);
+ if (res == -1) {
+ derefPath(info.watchedPath);
+ emit emitDirectoryChanged(info.origPath, true);
+ it = watchedDirectories.erase(it);
+ } else if (st.st_ctimespec != info.ctime || st.st_mode != info.mode) {
+ info.ctime = st.st_ctimespec;
+ info.mode = st.st_mode;
+ emit emitDirectoryChanged(info.origPath, false);
+ ++it;
+ } else {
+ bool dirChanged = false;
+ InfoByName &entries = it->entries;
+ // check known entries:
+ for (InfoByName::iterator i = entries.begin(); i != entries.end(); ) {
+ if (QT_STAT(QFile::encodeName(i.key()), &st) == -1) {
+ // entry disappeared
+ dirChanged = true;
+ i = entries.erase(i);
+ } else {
+ if (i->ctime != st.st_ctimespec || i->mode != st.st_mode) {
+ // entry changed
+ dirChanged = true;
+ i->ctime = st.st_ctimespec;
+ i->mode = st.st_mode;
+ }
+ ++i;
+ }
+ }
+ // check for new entries:
+ QDirIterator dirIt(name);
+ while (dirIt.hasNext()) {
+ dirIt.next();
+ QString entryName = dirIt.filePath();
+ if (!entries.contains(entryName)) {
+ dirChanged = true;
+ QT_STATBUF st;
+ if (QT_STAT(QFile::encodeName(entryName), &st) == -1)
+ continue;
+ entries.insert(entryName, Info(QString(), st.st_ctimespec, st.st_mode, QString()));
+
+ }
+ }
+ if (dirChanged)
+ emit emitDirectoryChanged(info.origPath, false);
+ }
+}
+
+void QFseventsFileSystemWatcherEngine::rescanDirs(const QString &path)
+{
+ for (DirsByName::iterator it = watchedDirectories.begin(); it != watchedDirectories.end(); ) {
+ if (it.key().startsWith(path))
+ checkDir(it);
+ else
+ ++it;
+ }
+}
+
+void QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
+{
+ for (InfoByName::iterator it = filesInPath.begin(); it != filesInPath.end(); ) {
+ QT_STATBUF st;
+ QString name = it.key();
+ const int res = QT_STAT(QFile::encodeName(name), &st);
+ if (res == -1) {
+ derefPath(it->watchedPath);
+ emit emitFileChanged(it.value().origPath, true);
+ it = filesInPath.erase(it);
+ continue;
+ } else if (st.st_ctimespec != it->ctime || st.st_mode != it->mode) {
+ it->ctime = st.st_ctimespec;
+ it->mode = st.st_mode;
+ emit emitFileChanged(it.value().origPath, false);
+ }
+
+ ++it;
+ }
+}
+
+void QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
+{
+ for (FilesByPath::iterator i = watchedFiles.begin(); i != watchedFiles.end(); ) {
+ if (i.key().startsWith(path)) {
+ rescanFiles(i.value());
+ if (i.value().isEmpty()) {
+ i = watchedFiles.erase(i);
+ continue;
+ }
+ }
+
+ ++i;
+ }
+}
+
+void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef streamRef,
+ size_t numEvents,
+ char **eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[])
+{
+#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
+ Q_UNUSED(streamRef);
+
+ QMutexLocker locker(&lock);
+
+ for (size_t i = 0; i < numEvents; ++i) {
+ FSEventStreamEventFlags eFlags = eventFlags[i];
+ DEBUG("Change %llu in %s, flags %x", eventIds[i], eventPaths[i], (unsigned int)eFlags);
+ QString path = QFile::decodeName(eventPaths[i]);
+ if (path.endsWith(QDir::separator()))
+ path = path.mid(0, path.size() - 1);
+
+ if (eFlags & kFSEventStreamEventFlagMustScanSubDirs) {
+ DEBUG("\tmust rescan directory because of coalesced events");
+ if (eFlags & kFSEventStreamEventFlagUserDropped)
+ DEBUG("\t\t... user dropped.");
+ if (eFlags & kFSEventStreamEventFlagKernelDropped)
+ DEBUG("\t\t... kernel dropped.");
+ rescanDirs(path);
+ rescanFiles(path);
+ continue;
+ }
+
+ if (eFlags & kFSEventStreamEventFlagEventIdsWrapped) {
+ DEBUG("\tthe event ids wrapped");
+ // TODO: verify if we need to do something
+ }
+
+ if (eFlags & kFSEventStreamEventFlagRootChanged) {
+ // re-check everything:
+ DirsByName::iterator dirIt = watchedDirectories.find(path);
+ if (dirIt != watchedDirectories.end())
+ checkDir(dirIt);
+ rescanFiles(path);
+ continue;
+ }
+
+ if ((eFlags & kFSEventStreamEventFlagItemIsDir) && (eFlags & kFSEventStreamEventFlagItemRemoved))
+ rescanDirs(path);
+
+ // check watched directories:
+ DirsByName::iterator dirIt = watchedDirectories.find(path);
+ if (dirIt != watchedDirectories.end())
+ checkDir(dirIt);
+
+ // check watched files:
+ FilesByPath::iterator pIt = watchedFiles.find(path);
+ if (pIt != watchedFiles.end())
+ rescanFiles(pIt.value());
+ }
+#else
+ // This is a work-around for moc: when we put the version check at the top of the header file,
+ // moc will still see the Q_OBJECT macro and generate a meta-object when compiling for 10.6,
+ // which obviously won't link.
+ //
+ // So the trick is to still compile this class on 10.6, but never instantiate it.
+
+ Q_UNUSED(streamRef);
+ Q_UNUSED(numEvents);
+ Q_UNUSED(eventPaths);
+ Q_UNUSED(eventFlags);
+ Q_UNUSED(eventIds);
+#endif
+}
+
+void QFseventsFileSystemWatcherEngine::doEmitFileChanged(const QString path, bool removed)
+{
+ emit fileChanged(path, removed);
+}
+
+void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path, bool removed)
+{
+ emit directoryChanged(path, removed);
+}
+
+QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObject *parent)
+{
+ return new QFseventsFileSystemWatcherEngine(parent);
+}
+
+QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *parent)
+ : QFileSystemWatcherEngine(parent)
+ , stream(0)
+{
+
+ // We cannot use signal-to-signal queued connections, because the
+ // QSignalSpy cannot spot signals fired from other/alien threads.
+ connect(this, SIGNAL(emitDirectoryChanged(const QString, bool)),
+ this, SLOT(doEmitDirectoryChanged(const QString, bool)), Qt::QueuedConnection);
+ connect(this, SIGNAL(emitFileChanged(const QString, bool)),
+ this, SLOT(doEmitFileChanged(const QString, bool)), Qt::QueuedConnection);
+
+ queue = dispatch_queue_create("org.qt-project.QFseventsFileSystemWatcherEngine", NULL);
+}
+
+QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
+{
+ if (stream)
+ FSEventStreamStop(stream);
+
+ // The assumption with the locking strategy is that this class cannot and will not be subclassed!
+ QMutexLocker locker(&lock);
+
+ stopStream();
+ dispatch_release(queue);
+}
+
+QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
+ QStringList *files,
+ QStringList *directories)
+{
+ if (stream)
+ FSEventStreamFlushSync(stream);
+
+ QMutexLocker locker(&lock);
+
+ bool newWatchPathsFound = false;
+
+ QStringList p = paths;
+ QMutableListIterator<QString> it(p);
+ while (it.hasNext()) {
+ QString origPath = it.next();
+ QString realPath = origPath;
+ if (realPath.endsWith(QDir::separator()))
+ realPath = realPath.mid(0, realPath.size() - 1);
+ QString watchedPath, parentPath;
+
+ realPath = QFileInfo(realPath).canonicalFilePath();
+ QFileInfo fi(realPath);
+ if (realPath.isEmpty())
+ continue;
+
+ QT_STATBUF st;
+ if (QT_STAT(QFile::encodeName(realPath), &st) == -1)
+ continue;
+
+ const bool isDir = S_ISDIR(st.st_mode);
+ if (isDir) {
+ if (watchedDirectories.contains(realPath))
+ continue;
+ directories->append(origPath);
+ watchedPath = realPath;
+ it.remove();
+ } else {
+ if (files->contains(origPath))
+ continue;
+ files->append(origPath);
+ it.remove();
+
+ watchedPath = fi.path();
+ parentPath = watchedPath;
+ }
+
+ for (PathRefCounts::const_iterator i = watchedPaths.begin(), ei = watchedPaths.end(); i != ei; ++i) {
+ if (watchedPath.startsWith(i.key())) {
+ watchedPath = i.key();
+ break;
+ }
+ }
+
+ PathRefCounts::iterator it = watchedPaths.find(watchedPath);
+ if (it == watchedPaths.end()) {
+ newWatchPathsFound = true;
+ watchedPaths.insert(watchedPath, 1);
+ } else {
+ ++it.value();
+ }
+
+ Info info(origPath, st.st_ctimespec, st.st_mode, watchedPath);
+ if (isDir) {
+ DirInfo dirInfo;
+ dirInfo.dirInfo = info;
+ dirInfo.entries = scanForDirEntries(realPath);
+ watchedDirectories.insert(realPath, dirInfo);
+ } else {
+ watchedFiles[parentPath].insert(realPath, info);
+ }
+ }
+
+ if (newWatchPathsFound) {
+ stopStream();
+ if (!startStream())
+ p = paths;
+ }
+
+ return p;
+}
+
+QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &paths,
+ QStringList *files,
+ QStringList *directories)
+{
+ QMutexLocker locker(&lock);
+
+ QStringList p = paths;
+ QMutableListIterator<QString> it(p);
+ while (it.hasNext()) {
+ QString origPath = it.next();
+ QString realPath = origPath;
+ if (realPath.endsWith(QDir::separator()))
+ realPath = realPath.mid(0, realPath.size() - 1);
+
+ QFileInfo fi(realPath);
+ realPath = fi.canonicalFilePath();
+
+ if (fi.isDir()) {
+ DirsByName::iterator dirIt = watchedDirectories.find(realPath);
+ if (dirIt != watchedDirectories.end()) {
+ derefPath(dirIt->dirInfo.watchedPath);
+ watchedDirectories.erase(dirIt);
+ directories->removeAll(origPath);
+ it.remove();
+ }
+ } else {
+ QFileInfo fi(realPath);
+ QString parentPath = fi.path();
+ FilesByPath::iterator pIt = watchedFiles.find(parentPath);
+ if (pIt != watchedFiles.end()) {
+ InfoByName &filesInDir = pIt.value();
+ InfoByName::iterator fIt = filesInDir.find(realPath);
+ if (fIt != filesInDir.end()) {
+ derefPath(fIt->watchedPath);
+ filesInDir.erase(fIt);
+ if (filesInDir.isEmpty())
+ watchedFiles.erase(pIt);
+ files->removeAll(origPath);
+ it.remove();
+ }
+ }
+ }
+ }
+
+ return p;
+}
+
+bool QFseventsFileSystemWatcherEngine::startStream()
+{
+ if (watchedPaths.isEmpty())
+ return false;
+
+ DEBUG() << "Starting stream with paths" << watchedPaths.keys();
+
+ NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchedPaths.size()];
+ for (PathRefCounts::const_iterator i = watchedPaths.begin(), ei = watchedPaths.end(); i != ei; ++i)
+ [pathsToWatch addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(i.key()))];
+
+ struct FSEventStreamContext callBackInfo = {
+ 0,
+ this,
+ NULL,
+ NULL,
+ NULL
+ };
+ const CFAbsoluteTime latency = .5; // in seconds
+ FSEventStreamCreateFlags flags = kFSEventStreamCreateFlagWatchRoot;
+
+ stream = FSEventStreamCreate(NULL,
+ &callBackFunction,
+ &callBackInfo,
+ reinterpret_cast<CFArrayRef>(pathsToWatch),
+ kFSEventStreamEventIdSinceNow,
+ latency,
+ flags);
+
+ if (!stream) {
+ DEBUG() << "Failed to create stream!";
+ return false;
+ }
+
+ FSEventStreamSetDispatchQueue(stream, queue);
+
+ if (FSEventStreamStart(stream)) {
+ DEBUG() << "Stream started successfully.";
+ return true;
+ } else {
+ DEBUG() << "Stream failed to start!";
+ return false;
+ }
+}
+
+void QFseventsFileSystemWatcherEngine::stopStream(bool isStopped)
+{
+ if (stream) {
+ if (!isStopped)
+ FSEventStreamStop(stream);
+ FSEventStreamInvalidate(stream);
+ FSEventStreamRelease(stream);
+ stream = 0;
+ DEBUG() << "Stream stopped.";
+ }
+}
+
+QFseventsFileSystemWatcherEngine::InfoByName QFseventsFileSystemWatcherEngine::scanForDirEntries(const QString &path)
+{
+ InfoByName entries;
+
+ QDirIterator it(path);
+ while (it.hasNext()) {
+ it.next();
+ QString entryName = it.filePath();
+ QT_STATBUF st;
+ if (QT_STAT(QFile::encodeName(entryName), &st) == -1)
+ continue;
+ entries.insert(entryName, Info(QString(), st.st_ctimespec, st.st_mode, QString()));
+ }
+
+ return entries;
+}
+
+void QFseventsFileSystemWatcherEngine::derefPath(const QString &watchedPath)
+{
+ PathRefCounts::iterator it = watchedPaths.find(watchedPath);
+ if (it == watchedPaths.end())
+ return;
+ if (--it.value() < 1) {
+ watchedPaths.erase(it);
+ stopStream();
+ startStream();
+ }
+}
+
+#endif //QT_NO_FILESYSTEMWATCHER
+
+QT_END_NAMESPACE
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
new file mode 100644
index 0000000000..c899c556c8
--- /dev/null
+++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFILESYSTEMWATCHER_FSEVENTS_P_H
+#define QFILESYSTEMWATCHER_FSEVENTS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qfilesystemwatcher_p.h"
+
+#include <QtCore/qmutex.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qthread.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qsocketnotifier.h>
+
+#include <dispatch/dispatch.h>
+#include <CoreServices/CoreServices.h>
+
+#ifndef QT_NO_FILESYSTEMWATCHER
+
+QT_BEGIN_NAMESPACE
+
+class QFseventsFileSystemWatcherEngine : public QFileSystemWatcherEngine
+{
+ Q_OBJECT
+public:
+ ~QFseventsFileSystemWatcherEngine();
+
+ static QFseventsFileSystemWatcherEngine *create(QObject *parent);
+
+ QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories);
+ QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories);
+
+ void processEvent(ConstFSEventStreamRef streamRef, size_t numEvents, char **eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]);
+
+Q_SIGNALS:
+ void emitFileChanged(const QString path, bool removed);
+ void emitDirectoryChanged(const QString path, bool removed);
+
+private slots:
+ void doEmitFileChanged(const QString path, bool removed);
+ void doEmitDirectoryChanged(const QString path, bool removed);
+
+private:
+ struct Info {
+ QString origPath;
+ timespec ctime;
+ mode_t mode;
+ QString watchedPath;
+
+ Info(): mode(0)
+ {
+ ctime.tv_sec = 0;
+ ctime.tv_nsec = 0;
+ }
+
+ Info(const QString &origPath, const timespec &ctime, mode_t mode, const QString &watchedPath)
+ : origPath(origPath)
+ , ctime(ctime)
+ , mode(mode)
+ , watchedPath(watchedPath)
+ {}
+ };
+ typedef QHash<QString, Info> InfoByName;
+ typedef QHash<QString, InfoByName> FilesByPath;
+ struct DirInfo {
+ Info dirInfo;
+ InfoByName entries;
+ };
+ typedef QHash<QString, DirInfo> DirsByName;
+ typedef QHash<QString, qint64> PathRefCounts;
+
+ QFseventsFileSystemWatcherEngine(QObject *parent);
+ bool startStream();
+ void stopStream(bool isStopped = false);
+ InfoByName scanForDirEntries(const QString &path);
+ void derefPath(const QString &watchedPath);
+ void checkDir(DirsByName::iterator &it);
+ void rescanDirs(const QString &path);
+ void rescanFiles(InfoByName &filesInPath);
+ void rescanFiles(const QString &path);
+
+ QMutex lock;
+ dispatch_queue_t queue;
+ FSEventStreamRef stream;
+ FilesByPath watchedFiles;
+ DirsByName watchedDirectories;
+ PathRefCounts watchedPaths;
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_FILESYSTEMWATCHER
+#endif // QFILESYSTEMWATCHER_FSEVENTS_P_H
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index c731f3d417..5fd20c6d74 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -129,9 +129,9 @@
# define __NR_inotify_rm_watch 271
# define __NR_inotify_init1 314
#elif defined (__avr32__)
-# define __NR_inotify_init 240
-# define __NR_inotify_add_watch 241
-# define __NR_inotify_rm_watch 242
+# define __NR_inotify_init 240
+# define __NR_inotify_add_watch 241
+# define __NR_inotify_rm_watch 242
// no inotify_init1 for AVR32
#elif defined (__mc68000__)
# define __NR_inotify_init 284
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index a5f077bd0b..064a1a511f 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -45,6 +45,7 @@
#include "private/qcore_unix_p.h"
#include "qfilesystementry_p.h"
#include "qfilesystemengine_p.h"
+#include "qcoreapplication.h"
#ifndef QT_NO_FSFILEENGINE
@@ -142,6 +143,16 @@ static inline bool setCloseOnExec(int fd)
return fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) != -1;
}
+static inline QString msgOpenDirectory()
+{
+ const char message[] = QT_TRANSLATE_NOOP("QIODevice", "file to open is a directory");
+#ifndef QT_BOOTSTRAPPED
+ return QIODevice::tr(message);
+#else
+ return QLatin1String(message);
+#endif
+}
+
/*!
\internal
*/
@@ -169,7 +180,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
// we had received EISDIR anyway.
if (QFileSystemEngine::fillMetaData(fd, metaData)
&& metaData.isDirectory()) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ q->setError(QFile::OpenError, msgOpenDirectory());
QT_CLOSE(fd);
return false;
}
@@ -210,7 +221,7 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
// we had received EISDIR anyway.
if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData)
&& metaData.isDirectory()) {
- q->setError(QFile::OpenError, QLatin1String("file to open is a directory"));
+ q->setError(QFile::OpenError, msgOpenDirectory());
fclose(fh);
return false;
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index 2b38019674..c974daab06 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -60,14 +60,18 @@
# include <types.h>
#endif
#include <objbase.h>
-#include <shlobj.h>
+#ifndef Q_OS_WINRT
+# include <shlobj.h>
+# include <accctrl.h>
+#endif
#include <initguid.h>
-#include <accctrl.h>
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
-#define SECURITY_WIN32
-#include <security.h>
+#ifndef Q_OS_WINRT
+# define SECURITY_WIN32
+# include <security.h>
+#endif
#ifndef PATH_MAX
#define PATH_MAX FILENAME_MAX
@@ -93,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
return path;
QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path);
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString prefix = QLatin1String("\\\\?\\");
if (isUncPath(absPath)) {
prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\"
@@ -121,11 +125,12 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
if (openMode & QIODevice::WriteOnly)
accessRights |= GENERIC_WRITE;
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
// WriteOnly can create files, ReadOnly cannot.
DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING;
// Create the file handle.
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
accessRights,
shareMode,
@@ -133,6 +138,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
creationDisp,
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ fileHandle = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ accessRights,
+ shareMode,
+ creationDisp,
+ NULL);
+#endif // Q_OS_WINRT
// Bail out on error.
if (fileHandle == INVALID_HANDLE_VALUE) {
@@ -473,7 +485,7 @@ int QFSFileEnginePrivate::nativeHandle() const
*/
bool QFSFileEnginePrivate::nativeIsSequential() const
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
HANDLE handle = fileHandle;
if (fh || fd != -1)
handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
@@ -577,7 +589,7 @@ bool QFSFileEngine::setCurrentPath(const QString &path)
QString QFSFileEngine::currentPath(const QString &fileName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString ret;
//if filename is a drive: then get the pwd of that drive
if (fileName.length() >= 2 &&
@@ -596,10 +608,10 @@ QString QFSFileEngine::currentPath(const QString &fileName)
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
Q_UNUSED(fileName);
return QFileSystemEngine::currentPath().filePath();
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
QString QFSFileEngine::homePath()
@@ -620,7 +632,7 @@ QString QFSFileEngine::tempPath()
QFileInfoList QFSFileEngine::drives()
{
QFileInfoList ret;
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if defined(Q_OS_WIN32)
quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
#endif
@@ -633,10 +645,10 @@ QFileInfoList QFSFileEngine::drives()
driveBits = driveBits >> 1;
}
return ret;
-#else
+#else // !Q_OS_WINCE && !Q_OS_WINRT
ret.append(QFileInfo(QLatin1String("/")));
return ret;
-#endif
+#endif // Q_OS_WINCE || Q_OS_WINRT
}
bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
@@ -661,7 +673,7 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
bool QFSFileEngine::link(const QString &newName)
{
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if !defined(QT_NO_LIBRARY)
bool ret = false;
@@ -707,7 +719,7 @@ bool QFSFileEngine::link(const QString &newName)
Q_UNUSED(newName);
return false;
#endif // QT_NO_LIBRARY
-#else
+#elif defined(Q_OS_WINCE)
QString linkName = newName;
linkName.replace(QLatin1Char('/'), QLatin1Char('\\'));
if (!linkName.endsWith(QLatin1String(".lnk")))
@@ -720,7 +732,11 @@ bool QFSFileEngine::link(const QString &newName)
if (!ret)
setError(QFile::RenameError, qt_error_string());
return ret;
-#endif // Q_OS_WINCE
+#else // Q_OS_WINCE
+ Q_UNUSED(newName);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINRT
}
/*!
@@ -937,6 +953,7 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
QFile::MemoryMapFlags flags)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
Q_UNUSED(flags);
if (openMode == QFile::NotOpen) {
@@ -980,7 +997,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
// first create the file mapping handle
DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
+#ifndef Q_OS_WINRT
mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
+#else
+ mapHandle = ::CreateFileMappingFromApp(handle, 0, protection, 0, 0);
+#endif
if (mapHandle == NULL) {
q->setError(QFile::PermissionsError, qt_error_string());
#ifdef Q_USE_DEPRECATED_MAP_API
@@ -998,15 +1019,23 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
DWORD offsetHi = offset >> 32;
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
::GetSystemInfo(&sysinfo);
+#else
+ ::GetNativeSystemInfo(&sysinfo);
+#endif
DWORD mask = sysinfo.dwAllocationGranularity - 1;
DWORD extra = offset & mask;
if (extra)
offsetLo &= ~mask;
// attempt to create the map
+#ifndef Q_OS_WINRT
LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
offsetHi, offsetLo, size + extra);
+#else
+ LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size);
+#endif
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
maps[address] = extra;
@@ -1025,11 +1054,18 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
::CloseHandle(mapHandle);
mapHandle = NULL;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(offset);
+ Q_UNUSED(size);
+ Q_UNUSED(flags);
+ Q_UNIMPLEMENTED();
+#endif // Q_OS_WINPHONE
return 0;
}
bool QFSFileEnginePrivate::unmap(uchar *ptr)
{
+#ifndef Q_OS_WINPHONE
Q_Q(QFSFileEngine);
if (!maps.contains(ptr)) {
q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
@@ -1048,6 +1084,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
}
return true;
+#else // !Q_OS_WINPHONE
+ Q_UNUSED(ptr);
+ Q_UNIMPLEMENTED();
+ return false;
+#endif // Q_OS_WINPHONE
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp
index b5f6d9f3da..28f6b02a64 100644
--- a/src/corelib/io/qlockfile_win.cpp
+++ b/src/corelib/io/qlockfile_win.cpp
@@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
QLockFile::LockError QLockFilePrivate::tryLock_sys()
{
- SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
const QFileSystemEntry fileEntry(fileName);
// When writing, allow others to read.
// When reading, QFile will allow others to read and write, all good.
@@ -60,6 +59,8 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
// but Windows doesn't allow recreating it while this handle is open anyway,
// so this would only create confusion (can't lock, but no lock file to read from).
const DWORD dwShareMode = FILE_SHARE_READ;
+#ifndef Q_OS_WINRT
+ SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
GENERIC_WRITE,
dwShareMode,
@@ -67,6 +68,13 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
CREATE_NEW, // error if already exists
FILE_ATTRIBUTE_NORMAL,
NULL);
+#else // !Q_OS_WINRT
+ HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
+ GENERIC_WRITE,
+ dwShareMode,
+ CREATE_NEW, // error if already exists
+ NULL);
+#endif // Q_OS_WINRT
if (fh == INVALID_HANDLE_VALUE) {
const DWORD lastError = GetLastError();
switch (lastError) {
@@ -112,6 +120,9 @@ bool QLockFilePrivate::isApparentlyStale() const
if (!getLockInfo(&pid, &hostname, &appname))
return false;
+ // On WinRT there seems to be no way of obtaining information about other
+ // processes due to sandboxing
+#ifndef Q_OS_WINRT
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!procHandle)
return true;
@@ -120,6 +131,7 @@ bool QLockFilePrivate::isApparentlyStale() const
::CloseHandle(procHandle);
if (dwR == WAIT_TIMEOUT)
return true;
+#endif // !Q_OS_WINRT
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
return staleLockTime > 0 && age > staleLockTime;
}
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 4924ac89c6..f37b9575aa 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -83,16 +83,65 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
\section1 Default category configuration
- In the default configuration \l isWarningEnabled() and \l isCriticalEnabled()
- will return \c true. \l isDebugEnabled() will return \c true only
- for the \c "default" category.
+ In the default configuration \l isWarningEnabled() , \l isDebugEnabled() and
+ \l isCriticalEnabled() will return \c true.
- \section1 Changing the configuration of a category
+ \section1 Configuring Categories
- Use either \l setFilterRules() or \l installFilter() to
- configure categories, for example
+ Categories can be centrally configured by either setting logging rules,
+ or by installing a custom filter.
- \snippet qloggingcategory/main.cpp 2
+ \section2 Logging Rules
+
+ Logging rules allow to enable or disable logging for categories in a flexible
+ way. Rules are specified in text, where every line must have the format
+
+ \code
+ <category>[.<type>] = true|false
+ \endcode
+
+ \c <category> is the name of the category, potentially with \c{*} as a
+ wildcard symbol as the first or last character (or at both positions).
+ The optional \c <type> must be either \c debug, \c warning, or \c critical.
+ Lines that do not fit to his scheme are ignored.
+
+ Rules are evaluated in text order, from first to last. That is, if two rules
+ apply to a category/type, the rule that comes later is applied.
+
+ Rules can be set via \l setFilterRules(). Since Qt 5.3 logging rules
+ are also automatically loaded from the \c [rules] section of a logging
+ configuration file. Such configuration files are looked up in the QtProject
+ configuration directory, or explicitly set in a \c QT_LOGGING_CONF
+ environment variable.
+
+ Rules set by \l setFilterRules() take precedence over rules specified
+ in the QtProject configuration directory, and can, in turn, be
+ overwritten by rules from the configuration file specified by
+ \c QT_LOGGING_CONF.
+
+ Order of evaluation:
+ \list
+ \li Rules from QtProject/qlogging.ini
+ \li Rules set by \l setFilterRules()
+ \li Rules from file in \c QT_LOGGING_CONF
+ \endlist
+
+ The \c QtProject/qlogging.ini file is looked up in all directories returned
+ by QStandardPaths::GenericConfigLocation, e.g.
+
+ \list
+ \li on Mac OS X: \c ~/Library/Preferences
+ \li on Unix: \c ~/.config, \c /etc/xdg
+ \li on Windows: \c %LOCALAPPDATA%, \c %ProgramData%,
+ \l QCoreApplication::applicationDirPath(),
+ QCoreApplication::applicationDirPath() + \c "/data"
+ \endlist
+
+ \section2 Installing a Custom Filter
+
+ As a lower-level alternative to the text rules you can also implement a
+ custom filter via \l installFilter(). All filter rules are ignored in this
+ case.
\section1 Printing the category
@@ -111,21 +160,20 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
QLoggingCategory::QLoggingCategory(const char *category)
: d(0),
name(0),
- enabledDebug(false),
+ enabledDebug(true),
enabledWarning(true),
enabledCritical(true)
{
Q_UNUSED(d);
Q_UNUSED(placeholder);
- bool isDefaultCategory
+ const bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
+ // normalize "default" category name, so that we can just do
+ // pointer comparison in QLoggingRegistry::updateCategory
if (isDefaultCategory) {
- // normalize default category names, so that we can just do
- // pointer comparison in QLoggingRegistry::updateCategory
name = qtDefaultCategoryName;
- enabledDebug = true;
} else {
name = category;
}
@@ -226,6 +274,14 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
*/
/*!
+ \fn const QLoggingCategory &QLoggingCategory::operator()() const
+
+ Returns the object itself. This allows both a QLoggingCategory variable, and
+ a factory method returning a QLoggingCategory, to be used in \l qCDebug(),
+ \l qCWarning(), \l qCCritical() macros.
+ */
+
+/*!
Returns a pointer to the global category \c "default" that
is used e.g. by qDebug(), qWarning(), qCritical(), qFatal().
@@ -280,27 +336,18 @@ QLoggingCategory::installFilter(QLoggingCategory::CategoryFilter filter)
Configures which categories and message types should be enabled through a
a set of \a rules.
- Each line in \a rules must have the format
-
- \code
- <category>[.<type>] = true|false
- \endcode
-
- where \c <category> is the name of the category, potentially with \c{*} as a
- wildcard symbol at the start and/or the end. The optional \c <type> must
- be either \c debug, \c warning, or \c critical.
-
Example:
\snippet qloggingcategory/main.cpp 2
\note The rules might be ignored if a custom category filter is installed
- with \l installFilter().
+ with \l installFilter(), or if the user defined a custom logging
+ configuration file in the \c QT_LOGGING_CONF environment variable.
*/
void QLoggingCategory::setFilterRules(const QString &rules)
{
- QLoggingRegistry::instance()->rulesParser.setRules(rules);
+ QLoggingRegistry::instance()->setApiRules(rules);
}
/*!
@@ -326,6 +373,25 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
+ \macro qCDebug(category, const char *message, ...)
+ \relates QLoggingCategory
+ \since 5.3
+
+ Logs a debug message \a message in the logging category \a category.
+ \a message might contain place holders that are replaced by additional
+ arguments, similar to the C printf() function.
+
+ Example:
+
+ \snippet qloggingcategory/main.cpp 13
+
+ \note Arguments might not be processed if debug output for the category is
+ not enabled, so do not rely on any side effects.
+
+ \sa qDebug()
+*/
+
+/*!
\macro qCWarning(category)
\relates QLoggingCategory
\since 5.2
@@ -348,6 +414,25 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
+ \macro qCWarning(category, const char *message, ...)
+ \relates QLoggingCategory
+ \since 5.3
+
+ Logs a warning message \a message in the logging category \a category.
+ \a message might contain place holders that are replaced by additional
+ arguments, similar to the C printf() function.
+
+ Example:
+
+ \snippet qloggingcategory/main.cpp 14
+
+ \note Arguments might not be processed if warning output for the category is
+ not enabled, so do not rely on any side effects.
+
+ \sa qWarning()
+*/
+
+/*!
\macro qCCritical(category)
\relates QLoggingCategory
\since 5.2
@@ -370,6 +455,24 @@ void QLoggingCategory::setFilterRules(const QString &rules)
*/
/*!
+ \macro qCCritical(category, const char *message, ...)
+ \relates QLoggingCategory
+ \since 5.3
+
+ Logs a critical message \a message in the logging category \a category.
+ \a message might contain place holders that are replaced by additional
+ arguments, similar to the C printf() function.
+
+ Example:
+
+ \snippet qloggingcategory/main.cpp 15
+
+ \note Arguments might not be processed if critical output for the category
+ is not enabled, so do not rely on any side effects.
+
+ \sa qCritical()
+*/
+/*!
\macro Q_DECLARE_LOGGING_CATEGORY(name)
\relates QLoggingCategory
\since 5.2
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 15c0519827..4aec8e63bf 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -65,6 +65,7 @@ public:
// allows usage of both factory method and variable in qCX macros
QLoggingCategory &operator()() { return *this; }
+ const QLoggingCategory &operator()() const { return *this; }
static QLoggingCategory *defaultCategory();
@@ -84,25 +85,36 @@ private:
};
#define Q_DECLARE_LOGGING_CATEGORY(name) \
- extern QLoggingCategory &name();
+ extern const QLoggingCategory &name();
// relies on QLoggingCategory(QString) being thread safe!
#define Q_LOGGING_CATEGORY(name, string) \
- QLoggingCategory &name() \
+ const QLoggingCategory &name() \
{ \
- static QLoggingCategory category(string); \
+ static const QLoggingCategory category(string); \
return category; \
}
-#define qCDebug(category) \
- for (bool enabled = category().isDebugEnabled(); Q_UNLIKELY(enabled); enabled = false) \
- QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug()
-#define qCWarning(category) \
- for (bool enabled = category().isWarningEnabled(); enabled; enabled = false) \
- QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).warning()
-#define qCCritical(category) \
- for (bool enabled = category().isCriticalEnabled(); enabled; enabled = false) \
- QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical()
+#ifdef Q_COMPILER_VARIADIC_MACROS
+
+#define qCDebug(category, ...) \
+ for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
+ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).debug(__VA_ARGS__)
+#define qCWarning(category, ...) \
+ for (bool qt_category_enabled = category().isWarningEnabled(); qt_category_enabled; qt_category_enabled = false) \
+ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).warning(__VA_ARGS__)
+#define qCCritical(category, ...) \
+ for (bool qt_category_enabled = category().isCriticalEnabled(); qt_category_enabled; qt_category_enabled = false) \
+ QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical(__VA_ARGS__)
+
+#else
+
+// check for enabled category inside QMessageLogger.
+#define qCDebug qDebug
+#define qCWarning qWarning
+#define qCCritical qCritical
+
+#endif // Q_COMPILER_VARIADIC_MACROS
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qCDebug
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index a82e6f65f4..b8fef16c0e 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -42,6 +42,10 @@
#include "qloggingregistry_p.h"
#include "qloggingcategory_p.h"
+#include <QtCore/qfile.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qtextstream.h>
+
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QLoggingRegistry, qtLoggingRegistry)
@@ -150,33 +154,38 @@ void QLoggingRule::parse()
}
/*!
+ \class QLoggingSettingsParser
+ \since 5.3
\internal
- Creates a new QLoggingRules object.
+
+ Parses a .ini file with the following format:
+
+ [rules]
+ rule1=[true|false]
+ rule2=[true|false]
+ ...
+
+ [rules] is the default section, and therefore optional.
*/
-QLoggingRulesParser::QLoggingRulesParser(QLoggingRegistry *registry) :
- registry(registry)
-{
-}
/*!
\internal
- Sets logging rules string.
+ Parses configuration from \a content.
*/
-void QLoggingRulesParser::setRules(const QString &content)
+void QLoggingSettingsParser::setContent(const QString &content)
{
QString content_ = content;
QTextStream stream(&content_, QIODevice::ReadOnly);
- parseRules(stream);
+ setContent(stream);
}
/*!
\internal
- Parses rules out of a QTextStream.
+ Parses configuration from \a stream.
*/
-void QLoggingRulesParser::parseRules(QTextStream &stream)
+void QLoggingSettingsParser::setContent(QTextStream &stream)
{
- QVector<QLoggingRule> rules;
-
+ _rules.clear();
while (!stream.atEnd()) {
QString line = stream.readLine();
@@ -184,31 +193,79 @@ void QLoggingRulesParser::parseRules(QTextStream &stream)
line = line.simplified();
line.remove(QLatin1Char(' '));
- const QStringList pair = line.split(QLatin1Char('='));
- if (pair.count() == 2) {
- const QString pattern = pair.at(0);
- bool enabled = (QString::compare(pair.at(1),
- QLatin1String("true"),
- Qt::CaseInsensitive) == 0);
- rules.append(QLoggingRule(pattern, enabled));
+ // comment
+ if (line.startsWith(QLatin1Char(';')))
+ continue;
+
+ if (line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) {
+ // new section
+ _section = line.mid(1, line.size() - 2);
+ continue;
}
- }
- registry->setRules(rules);
+ if (_section == QLatin1String("rules")) {
+ int equalPos = line.indexOf(QLatin1Char('='));
+ if ((equalPos != -1)
+ && (line.lastIndexOf(QLatin1Char('=')) == equalPos)) {
+ const QString pattern = line.left(equalPos);
+ const QStringRef value = line.midRef(equalPos + 1);
+ bool enabled = (value.compare(QLatin1String("true"),
+ Qt::CaseInsensitive) == 0);
+ _rules.append(QLoggingRule(pattern, enabled));
+ }
+ }
+ }
}
/*!
\internal
- QLoggingPrivate constructor
+ QLoggingRegistry constructor
*/
QLoggingRegistry::QLoggingRegistry()
- : rulesParser(this),
- categoryFilter(defaultCategoryFilter)
+ : categoryFilter(defaultCategoryFilter)
{
}
/*!
\internal
+ Initializes the rules database by loading
+ .config/QtProject/qtlogging.ini and $QT_LOGGING_CONF.
+ */
+void QLoggingRegistry::init()
+{
+ // get rules from environment
+ const QByteArray rulesFilePath = qgetenv("QT_LOGGING_CONF");
+ if (!rulesFilePath.isEmpty()) {
+ QFile file(QFile::decodeName(rulesFilePath));
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream stream(&file);
+ QLoggingSettingsParser parser;
+ parser.setContent(stream);
+ envRules = parser.rules();
+ }
+ }
+
+ // get rules from qt configuration
+ QString envPath = QStandardPaths::locate(QStandardPaths::GenericConfigLocation,
+ QStringLiteral("QtProject/qtlogging.ini"));
+ if (!envPath.isEmpty()) {
+ QFile file(envPath);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream stream(&file);
+ QLoggingSettingsParser parser;
+ parser.setContent(stream);
+ configRules = parser.rules();
+ }
+ }
+
+ if (!envRules.isEmpty() || !configRules.isEmpty()) {
+ QMutexLocker locker(&registryMutex);
+ updateRules();
+ }
+}
+
+/*!
+ \internal
Registers a category object.
This method might be called concurrently for the same category object.
@@ -236,17 +293,33 @@ void QLoggingRegistry::unregisterCategory(QLoggingCategory *cat)
/*!
\internal
- Activates a new set of logging rules for the default filter.
-*/
-void QLoggingRegistry::setRules(const QVector<QLoggingRule> &rules_)
+ Installs logging rules as specified in \a content.
+ */
+void QLoggingRegistry::setApiRules(const QString &content)
{
+ QLoggingSettingsParser parser;
+ parser.setSection(QStringLiteral("rules"));
+ parser.setContent(content);
+
QMutexLocker locker(&registryMutex);
+ apiRules = parser.rules();
- rules = rules_;
+ updateRules();
+}
+
+/*!
+ \internal
+ Activates a new set of logging rules for the default filter.
+ (The caller must lock registryMutex to make sure the API is thread safe.)
+*/
+void QLoggingRegistry::updateRules()
+{
if (categoryFilter != defaultCategoryFilter)
return;
+ rules = configRules + apiRules + envRules;
+
foreach (QLoggingCategory *cat, categories)
(*categoryFilter)(cat);
}
@@ -283,9 +356,13 @@ QLoggingRegistry *QLoggingRegistry::instance()
*/
void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
{
- // QLoggingCategory() normalizes all "default" strings
+ // QLoggingCategory() normalizes "default" strings
// to qtDefaultCategoryName
- bool debug = (cat->categoryName() == qtDefaultCategoryName);
+ bool debug = true;
+ char c;
+ if (!memcmp(cat->categoryName(), "qt", 2) && (!(c = cat->categoryName()[2]) || c == '.'))
+ debug = false;
+
bool warning = true;
bool critical = true;
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index cbf7aecc4f..d4b97d42b8 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -60,6 +60,8 @@
#include <QtCore/qtextstream.h>
#include <QtCore/qvector.h>
+class tst_QLoggingRegistry;
+
QT_BEGIN_NAMESPACE
class QLoggingRule
@@ -89,45 +91,53 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QLoggingRule::PatternFlags)
Q_DECLARE_TYPEINFO(QLoggingRule, Q_MOVABLE_TYPE);
-class QLoggingRulesParser
+class Q_AUTOTEST_EXPORT QLoggingSettingsParser
{
-private:
- explicit QLoggingRulesParser(class QLoggingRegistry *logging);
-
public:
- void setRules(const QString &content);
+ void setSection(const QString &section) { _section = section; }
-private:
- void parseRules(QTextStream &stream);
- QLoggingRegistry *registry;
+ void setContent(const QString &content);
+ void setContent(QTextStream &stream);
+
+ QVector<QLoggingRule> rules() const { return _rules; }
- friend class QLoggingRegistry;
+private:
+ QString _section;
+ QVector<QLoggingRule> _rules;
};
-class QLoggingRegistry
+class Q_AUTOTEST_EXPORT QLoggingRegistry
{
public:
QLoggingRegistry();
+ void init();
+
void registerCategory(QLoggingCategory *category);
void unregisterCategory(QLoggingCategory *category);
- void setRules(const QVector<QLoggingRule> &rules);
+ void setApiRules(const QString &content);
QLoggingCategory::CategoryFilter
installFilter(QLoggingCategory::CategoryFilter filter);
static QLoggingRegistry *instance();
- QLoggingRulesParser rulesParser;
-
private:
+ void updateRules();
+
static void defaultCategoryFilter(QLoggingCategory *category);
QMutex registryMutex;
+
+ QVector<QLoggingRule> configRules;
+ QVector<QLoggingRule> envRules;
+ QVector<QLoggingRule> apiRules;
QVector<QLoggingRule> rules;
QList<QLoggingCategory*> categories;
QLoggingCategory::CategoryFilter categoryFilter;
+
+ friend class ::tst_QLoggingRegistry;
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index ab2a69d054..3b78351809 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1545,16 +1545,40 @@ void QProcess::setWorkingDirectory(const QString &dir)
d->workingDirectory = dir;
}
+
/*!
+ \deprecated
+ Use processId() instead.
+
Returns the native process identifier for the running process, if
- available. If no process is currently running, 0 is returned.
+ available. If no process is currently running, \c 0 is returned.
+
+ \note Unlike \l processId(), pid() returns an integer on Unix and a pointer on Windows.
+
+ \sa Q_PID, processId()
*/
-Q_PID QProcess::pid() const
+Q_PID QProcess::pid() const // ### Qt 6 remove or rename this method to processInformation()
{
Q_D(const QProcess);
return d->pid;
}
+/*!
+ \since 5.3
+
+ Returns the native process identifier for the running process, if
+ available. If no process is currently running, \c 0 is returned.
+ */
+qint64 QProcess::processId() const
+{
+ Q_D(const QProcess);
+#ifdef Q_OS_WIN
+ return d->pid ? d->pid->dwProcessId : 0;
+#else
+ return d->pid;
+#endif
+}
+
/*! \reimp
This function operates on the current read channel.
@@ -2388,14 +2412,14 @@ int QProcess::execute(const QString &program)
identifier of the started process.
*/
bool QProcess::startDetached(const QString &program,
- const QStringList &arguments,
- const QString &workingDirectory,
+ const QStringList &arguments,
+ const QString &workingDirectory,
qint64 *pid)
{
return QProcessPrivate::startDetached(program,
- arguments,
- workingDirectory,
- pid);
+ arguments,
+ workingDirectory,
+ pid);
}
/*!
@@ -2414,7 +2438,7 @@ bool QProcess::startDetached(const QString &program,
The started process will run as a regular standalone process.
*/
bool QProcess::startDetached(const QString &program,
- const QStringList &arguments)
+ const QStringList &arguments)
{
return QProcessPrivate::startDetached(program, arguments);
}
diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h
index c0b3ab945e..6be267f15f 100644
--- a/src/corelib/io/qprocess.h
+++ b/src/corelib/io/qprocess.h
@@ -187,6 +187,7 @@ public:
// #### Qt 5: Q_PID is a pointer on Windows and a value on Unix
Q_PID pid() const;
+ qint64 processId() const;
bool waitForStarted(int msecs = 30000);
bool waitForReadyRead(int msecs = 30000);
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 3c6d294916..4076ec5855 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1107,7 +1107,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
#if defined (QPROCESS_DEBUG)
qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs,
- childStartedPipe[0]);
+ childStartedPipe[0]);
#endif
fd_set fds;
@@ -1172,32 +1172,32 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (ret == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
+ return false;
+ }
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
- }
+ }
bool readyReadEmitted = false;
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
- bool canRead = _q_canReadStandardOutput();
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
+ bool canRead = _q_canReadStandardOutput();
if (processChannel == QProcess::StandardOutput && canRead)
readyReadEmitted = true;
- }
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) {
- bool canRead = _q_canReadStandardError();
+ }
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) {
+ bool canRead = _q_canReadStandardError();
if (processChannel == QProcess::StandardError && canRead)
readyReadEmitted = true;
- }
+ }
if (readyReadEmitted)
return true;
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- _q_canWrite();
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ _q_canWrite();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return false;
}
@@ -1248,26 +1248,26 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
}
if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
+ processError = QProcess::Timedout;
+ q->setErrorString(QProcess::tr("Process operation timed out"));
+ return false;
+ }
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
- if (!_q_startupNotification())
- return false;
- }
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (!_q_startupNotification())
+ return false;
+ }
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- return _q_canWrite();
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ return _q_canWrite();
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
- _q_canReadStandardOutput();
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
+ _q_canReadStandardOutput();
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
- _q_canReadStandardError();
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
+ _q_canReadStandardError();
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return false;
}
@@ -1317,29 +1317,29 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (ret < 0) {
break;
}
- if (ret == 0) {
- processError = QProcess::Timedout;
- q->setErrorString(QProcess::tr("Process operation timed out"));
- return false;
- }
-
- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
- if (!_q_startupNotification())
- return false;
- }
- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
- _q_canWrite();
-
- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
- _q_canReadStandardOutput();
-
- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
- _q_canReadStandardError();
-
- if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
+ if (ret == 0) {
+ processError = QProcess::Timedout;
+ q->setErrorString(QProcess::tr("Process operation timed out"));
+ return false;
+ }
+
+ if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
+ if (!_q_startupNotification())
+ return false;
+ }
+ if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
+ _q_canWrite();
+
+ if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread))
+ _q_canReadStandardOutput();
+
+ if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread))
+ _q_canReadStandardError();
+
+ if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) {
if (_q_processDied())
return true;
- }
+ }
}
return false;
}
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index fc2adb783e..d7050034bd 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -623,7 +623,7 @@ static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
DWORD currentProcId = 0;
GetWindowThreadProcessId(hwnd, &currentProcId);
if (currentProcId == (DWORD)procId)
- PostMessage(hwnd, WM_CLOSE, 0, 0);
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
return TRUE;
}
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index c16b8d79a2..bfd0eef64f 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -1092,8 +1092,8 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc
for(int i = 0; i < list->size(); ++i) {
QResourceRoot *res = list->at(i);
if(res->type() == QResourceRoot::Resource_File) {
- QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
- if(root->mappingFile() == rccFilename && root->mappingRoot() == r) {
+ QDynamicFileResourceRoot *root = reinterpret_cast<QDynamicFileResourceRoot*>(res);
+ if (root->mappingFile() == rccFilename && root->mappingRoot() == r) {
resourceList()->removeAt(i);
if(!root->ref.deref()) {
delete root;
@@ -1101,7 +1101,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc
}
return false;
}
- }
+ }
}
return false;
}
@@ -1163,16 +1163,16 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot)
for(int i = 0; i < list->size(); ++i) {
QResourceRoot *res = list->at(i);
if(res->type() == QResourceRoot::Resource_Buffer) {
- QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);
- if(root->mappingBuffer() == rccData && root->mappingRoot() == r) {
+ QDynamicBufferResourceRoot *root = reinterpret_cast<QDynamicBufferResourceRoot*>(res);
+ if (root->mappingBuffer() == rccData && root->mappingRoot() == r) {
resourceList()->removeAt(i);
if(!root->ref.deref()) {
delete root;
return true;
}
- return false;
+ return false;
}
- }
+ }
}
return false;
}
@@ -1381,13 +1381,13 @@ QString QResourceFileEngine::fileName(FileName file) const
{
Q_D(const QResourceFileEngine);
if(file == BaseName) {
- int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));
- if (slash == -1)
- return d->resource.fileName();
- return d->resource.fileName().mid(slash + 1);
+ int slash = d->resource.fileName().lastIndexOf(QLatin1Char('/'));
+ if (slash == -1)
+ return d->resource.fileName();
+ return d->resource.fileName().mid(slash + 1);
} else if(file == PathName || file == AbsolutePathName) {
const QString path = (file == AbsolutePathName) ? d->resource.absoluteFilePath() : d->resource.fileName();
- const int slash = path.lastIndexOf(QLatin1Char('/'));
+ const int slash = path.lastIndexOf(QLatin1Char('/'));
if (slash == -1)
return QLatin1String(":");
else if (slash <= 1)
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 35b3ed4e3d..a3727a6a4b 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -78,14 +78,27 @@
#ifdef Q_OS_WIN // for homedirpath reading from registry
# include <private/qsystemlibrary_p.h>
# include <qt_windows.h>
+# ifndef Q_OS_WINRT
+# include <shlobj.h>
+# endif
+#endif
+
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
#endif
#ifndef CSIDL_COMMON_APPDATA
-#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
+#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
#endif
#ifndef CSIDL_APPDATA
-#define CSIDL_APPDATA 0x001a // <username>\Application Data
+#define CSIDL_APPDATA 0x001a // <username>\Application Data
#endif
#ifdef Q_AUTOTEST_EXPORT
@@ -365,7 +378,7 @@ after_loop:
// see also qsettings_win.cpp and qsettings_mac.cpp
-#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#if defined(Q_OS_WINRT) || (!defined(Q_OS_WIN) && !defined(Q_OS_MAC))
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope,
const QString &organization, const QString &application)
{
@@ -373,7 +386,7 @@ QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::
}
#endif
-#if !defined(Q_OS_WIN)
+#if defined(Q_OS_WINRT) || !defined(Q_OS_WIN)
QSettingsPrivate *QSettingsPrivate::create(const QString &fileName, QSettings::Format format)
{
return new QConfFileSettingsPrivate(fileName, format);
@@ -1021,23 +1034,14 @@ void QConfFileSettingsPrivate::initAccess()
sync(); // loads the files the first time
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QString windowsConfigPath(int type)
{
QString result;
-#ifndef Q_OS_WINCE
- QSystemLibrary library(QLatin1String("shell32"));
-#else
- QSystemLibrary library(QLatin1String("coredll"));
-#endif // Q_OS_WINCE
- typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
- GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
- if (SHGetSpecialFolderPath) {
- wchar_t path[MAX_PATH];
- SHGetSpecialFolderPath(0, path, type, false);
+ wchar_t path[MAX_PATH];
+ if (SHGetSpecialFolderPath(0, path, type, false))
result = QString::fromWCharArray(path);
- }
if (result.isEmpty()) {
switch (type) {
@@ -1063,7 +1067,40 @@ static QString windowsConfigPath(int type)
return result;
}
-#endif // Q_OS_WIN
+#elif defined(Q_OS_WINRT) // Q_OS_WIN && !Q_OS_WINRT
+static QString windowsConfigPath(int type)
+{
+ static QString result;
+ while (result.isEmpty()) {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ return result;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ return result;
+ ComPtr<IStorageFolder> localFolder;
+ if (FAILED(applicationData->get_LocalFolder(&localFolder)))
+ return result;
+ ComPtr<IStorageItem> localFolderItem;
+ if (FAILED(localFolder.As(&localFolderItem)))
+ return result;
+ HSTRING path;
+ if (FAILED(localFolderItem->get_Path(&path)))
+ return result;
+ result = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ }
+
+ switch (type) {
+ case CSIDL_COMMON_APPDATA:
+ return result + QLatin1String("\\qt-common");
+ case CSIDL_APPDATA:
+ return result + QLatin1String("\\qt-user");
+ default:
+ break;
+ }
+ return result;
+}
+#endif // Q_OS_WINRT
static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
{
@@ -1449,10 +1486,18 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString writeSemName = QLatin1String("QSettingsWriteSem ");
writeSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
+#else
+ writeSemaphore = CreateSemaphoreEx(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (writeSemaphore) {
+#ifndef Q_OS_WINRT
WaitForSingleObject(writeSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(writeSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
return;
@@ -1465,11 +1510,19 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QString readSemName(QLatin1String("QSettingsReadSem "));
readSemName.append(file.fileName());
+#ifndef Q_OS_WINRT
readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
+#else
+ readSemaphore = CreateSemaphoreEx(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()), 0, SEMAPHORE_ALL_ACCESS);
+#endif
if (readSemaphore) {
for (int i = 0; i < numReadLocks; ++i)
+#ifndef Q_OS_WINRT
WaitForSingleObject(readSemaphore, INFINITE);
+#else
+ WaitForSingleObjectEx(readSemaphore, INFINITE, FALSE);
+#endif
} else {
setStatus(QSettings::AccessError);
if (writeSemaphore != 0) {
diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h
index a720b3d709..f44b99d009 100644
--- a/src/corelib/io/qsettings.h
+++ b/src/corelib/io/qsettings.h
@@ -117,7 +117,7 @@ public:
QSettings(Scope scope, const QString &organization,
const QString &application = QString(), QObject *parent = 0);
QSettings(Format format, Scope scope, const QString &organization,
- const QString &application = QString(), QObject *parent = 0);
+ const QString &application = QString(), QObject *parent = 0);
QSettings(const QString &fileName, Format format, QObject *parent = 0);
explicit QSettings(QObject *parent = 0);
#else
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 2207b8c43e..bd9fa68d93 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -72,34 +72,240 @@ QT_BEGIN_NAMESPACE
methods such as QStandardPaths::writableLocation, QStandardPaths::standardLocations,
and QStandardPaths::displayName.
- \value DesktopLocation Returns the user's desktop directory.
- \value DocumentsLocation Returns the user's document.
- \value FontsLocation Returns the user's fonts.
- \value ApplicationsLocation Returns the user's applications.
- \value MusicLocation Returns the user's music.
- \value MoviesLocation Returns the user's movies.
- \value PicturesLocation Returns the user's pictures.
- \value TempLocation Returns the system's temporary directory.
- \value HomeLocation Returns the user's home directory.
+ Some of the values in this enum represent a user configuration. Such enum
+ values will return the same paths in different applications, so they could
+ be used to share data with other applications. Other values are specific to
+ this application. Each enum value in the table below describes whether it's
+ application-specific or generic.
+
+ Application-specific directories should be assumed to be unreachable by
+ other applications. Therefore, files placed there might not be readable by
+ other applications, even if run by the same user. On the other hand, generic
+ directories should be assumed to be accessible by all applications run by
+ this user, but should still be assumed to be unreachable by applications by
+ other users.
+
+ The only exception is QStandardPaths::TempLocation (which is the same as
+ QDir::tempPath()): the path returned may be application-specific, but files
+ stored there may be accessed by other applications run by the same user.
+
+ Data interchange with other users is out of the scope of QStandardPaths.
+
+ \value DesktopLocation Returns the user's desktop directory. This is a generic value.
+ On systems with no concept of a desktop, this is the same as
+ QStandardPaths::HomeLocation.
+ \value DocumentsLocation Returns the directory containing user document files.
+ This is a generic value. The returned path is never empty.
+ \value FontsLocation Returns the directory containing user's fonts. This is a generic value.
+ Note that installing fonts may require additional, platform-specific operations.
+ \value ApplicationsLocation Returns the directory containing the user applications
+ (either executables, application bundles, or shortcuts to them). This is a generic value.
+ Note that installing applications may require additional, platform-specific operations.
+ Files, folders or shortcuts in this directory are platform-specific.
+ \value MusicLocation Returns the directory containing the user's music or other audio files.
+ This is a generic value. If no directory specific for music files exists, a sensible
+ fallback for storing user documents is returned.
+ \value MoviesLocation Returns the directory containing the user's movies and videos.
+ This is a generic value. If no directory specific for movie files exists, a sensible
+ fallback for storing user documents is returned.
+ \value PicturesLocation Returns the directory containing the user's pictures or photos.
+ This is a generic value. If no directory specific for picture files exists, a sensible
+ fallback for storing user documents is returned.
+ \value TempLocation Returns a directory where temporary files can be stored. The returned value
+ might be application-specific, shared among other applications for this user, or even
+ system-wide. The returned path is never empty.
+ \value HomeLocation Returns the user's home directory (the same as QDir::homePath()). On Unix
+ systems, this is equal to the HOME environment variable. This value might be
+ generic or application-specific, but the returned path is never empty.
\value DataLocation Returns a directory location where persistent
- application data can be stored. QCoreApplication::organizationName
- and QCoreApplication::applicationName are appended to the directory location
- returned for GenericDataLocation.
+ application data can be stored. This is an application-specific directory. To obtain a
+ path to store data to be shared with other applications, use
+ QStandardPaths::GenericDataLocation. The returned path is never empty.
\value CacheLocation Returns a directory location where user-specific
- non-essential (cached) data should be written.
- \value GenericCacheLocation Returns a directory location where user-specific
- non-essential (cached) data, shared across applications, should be written.
+ non-essential (cached) data should be written. This is an application-specific directory.
+ The returned path is never empty.
+ \value GenericCacheLocation Returns a directory location where user-specific non-essential
+ (cached) data, shared across applications, should be written. This is a generic value.
+ Note that the returned path may be empty if the system has no concept of shared cache.
\value GenericDataLocation Returns a directory location where persistent
- data shared across applications can be stored.
+ data shared across applications can be stored. This is a generic value. The returned
+ path is never empty.
\value RuntimeLocation Returns a directory location where runtime communication
- files should be written. For instance unix local sockets.
+ files should be written, like Unix local sockets. This is a generic value.
+ The returned path may be empty on some systems.
\value ConfigLocation Returns a directory location where user-specific
- configuration files should be written.
+ configuration files should be written. This may be either a generic value
+ or application-specific, and the returned path is never empty.
+ \value DownloadLocation Returns a directory for user's downloaded files. This is a generic value.
+ If no directory specific for downloads exists, a sensible fallback for storing user
+ documents is returned.
\value GenericConfigLocation Returns a directory location where user-specific
configuration files shared between multiple applications should be written.
This is a generic value and the returned path is never empty.
- \value DownloadLocation Returns a directory for user's downloaded files.
+ The following table gives examples of paths on different operating systems.
+ The first path is the writable path (unless noted). Other, additional
+ paths, if any, represent non-writable locations.
+
+ \table
+ \header \li Path type \li OS X \li Windows
+ \row \li DesktopLocation
+ \li "~/Desktop"
+ \li "C:/Users/<USER>/Desktop"
+ \row \li DocumentsLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li FontsLocation
+ \li "/System/Library/Fonts" (not writable)
+ \li "C:/Windows/Fonts" (not writable)
+ \row \li ApplicationsLocation
+ \li "/Applications" (not writable)
+ \li "C:/Users/<USER>/AppData/Roaming/Microsoft/Windows/Start Menu/Programs"
+ \row \li MusicLocation
+ \li "~/Music"
+ \li "C:/Users/<USER>/Music"
+ \row \li MoviesLocation
+ \li "~/Movies"
+ \li "C:/Users/<USER>/Videos"
+ \row \li PicturesLocation
+ \li "~/Pictures"
+ \li "C:/Users/<USER>/Pictures"
+ \row \li TempLocation
+ \li randomly generated by the OS
+ \li "C:/Users/<USER>/AppData/Local/Temp"
+ \row \li HomeLocation
+ \li "~"
+ \li "C:/Users/<USER>"
+ \row \li DataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
+ \row \li CacheLocation
+ \li "~/Library/Caches/<APPNAME>", "/Library/Caches/<APPNAME>"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>/cache"
+ \row \li GenericDataLocation
+ \li "~/Library/Application Support", "/Library/Application Support"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li RuntimeLocation
+ \li "~/Library/Application Support"
+ \li "C:/Users/<USER>"
+ \row \li ConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>"
+ \row \li GenericConfigLocation
+ \li "~/Library/Preferences"
+ \li "C:/Users/<USER>/AppData/Local", "C:/ProgramData"
+ \row \li DownloadLocation
+ \li "~/Documents"
+ \li "C:/Users/<USER>/Documents"
+ \row \li GenericCacheLocation
+ \li "~/Library/Caches", "/Library/Caches"
+ \li "C:/Users/<USER>/AppData/Local/cache"
+ \endtable
+
+ \table
+ \header \li Path type \li Blackberry \li Linux
+ \row \li DesktopLocation
+ \li "<APPROOT>/data"
+ \li "~/Desktop"
+ \row \li DocumentsLocation
+ \li "<APPROOT>/shared/documents"
+ \li "~/Documents"
+ \row \li FontsLocation
+ \li "/base/usr/fonts" (not writable)
+ \li "~/.fonts"
+ \row \li ApplicationsLocation
+ \li not supported (directory not readable)
+ \li "~/.local/share/applications", "/usr/local/share/applications", "/usr/share/applications"
+ \row \li MusicLocation
+ \li "<APPROOT>/shared/music"
+ \li "~/Music"
+ \row \li MoviesLocation
+ \li "<APPROOT>/shared/videos"
+ \li "~/Videos"
+ \row \li PicturesLocation
+ \li "<APPROOT>/shared/photos"
+ \li "~/Pictures"
+ \row \li TempLocation
+ \li "/var/tmp"
+ \li "/tmp"
+ \row \li HomeLocation
+ \li "<APPROOT>/data"
+ \li "~"
+ \row \li DataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li CacheLocation
+ \li "<APPROOT>/data/Cache"
+ \li "~/.cache/<APPNAME>"
+ \row \li GenericDataLocation
+ \li "<APPROOT>/shared/misc"
+ \li "~/.local/share", "/usr/local/share", "/usr/share"
+ \row \li RuntimeLocation
+ \li "/var/tmp"
+ \li "/run/user/<USER>"
+ \row \li ConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li GenericConfigLocation
+ \li "<APPROOT>/data/Settings"
+ \li "~/.config", "/etc/xdg"
+ \row \li DownloadLocation
+ \li "<APPROOT>/shared/downloads"
+ \li "~/Downloads"
+ \row \li GenericCacheLocation
+ \li "<APPROOT>/data/Cache" (there is no shared cache)
+ \li "~/.cache"
+ \endtable
+
+ \table
+ \header \li Path type \li Android
+ \row \li DesktopLocation
+ \li "<APPROOT>/files"
+ \row \li DocumentsLocation
+ \li "<USER>/Documents", "<USER>/<APPNAME>/Documents"
+ \row \li FontsLocation
+ \li "/system/fonts" (not writable)
+ \row \li ApplicationsLocation
+ \li not supported (directory not readable)
+ \row \li MusicLocation
+ \li "<USER>/Music", "<USER>/<APPNAME>/Music"
+ \row \li MoviesLocation
+ \li "<USER>/Movies", "<USER>/<APPNAME>/Movies"
+ \row \li PicturesLocation
+ \li "<USER>/Pictures", "<USER>/<APPNAME>/Pictures"
+ \row \li TempLocation
+ \li "<APPROOT>/cache"
+ \row \li HomeLocation
+ \li "<APPROOT>/files"
+ \row \li DataLocation
+ \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
+ \row \li CacheLocation
+ \li "<APPROOT>/cache", "<USER>/<APPNAME>/cache"
+ \row \li GenericDataLocation
+ \li "<USER>"
+ \row \li RuntimeLocation
+ \li "<APPROOT>/cache"
+ \row \li ConfigLocation
+ \li "<APPROOT>/files/settings"
+ \row \li GenericConfigLocation
+ \li "<APPROOT>/files/settings" (there is no shared settings)
+ \row \li DownloadLocation
+ \li "<USER>/Downloads", "<USER>/<APPNAME>/Downloads"
+ \row \li GenericCacheLocation
+ \li "<APPROOT>/cache" (there is no shared cache)
+ \endtable
+
+ In the table above, \c <APPNAME> is usually the organization name, the
+ application name, or both, or a unique name generated at packaging.
+ Similarly, <APPROOT> is the location where this application is installed
+ (often a sandbox). <APPDIR> is the directory containing the application
+ executable.
+
+ The paths above should not be relied upon, as they may change according to
+ OS configuration, locale, or they may change in future Qt versions.
+
+ \note On Android, applications with open files on the external storage (<USER> locations),
+ will be killed if the external storage is unmounted.
\sa writableLocation(), standardLocations(), displayName(), locate(), locateAll()
*/
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index 815756ff9a..ec2e61bd15 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -103,10 +103,17 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QStringList QStandardPaths::standardLocations(StandardLocation type)
{
+ QStringList dirs;
+
if (type == FontsLocation)
return QStringList(QLatin1String("/base/usr/fonts"));
- return QStringList(writableLocation(type));
+ if (type == DataLocation)
+ dirs.append(QDir::homePath() + testModeInsert() + QLatin1String("native/assets"));
+
+ const QString localDir = writableLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index 0efdfae253..aff9112fb7 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -47,6 +47,7 @@
#include <qcoreapplication.h>
#endif
+#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
QT_BEGIN_NAMESPACE
@@ -184,6 +185,30 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
dirs.append(path);
}
+ if (type == DataLocation) {
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ if (mainBundle) {
+ CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
+ CFStringRef cfBundlePath = CFURLCopyPath(bundleUrl);
+ QString bundlePath = QCFString::toQString(cfBundlePath);
+ CFRelease(cfBundlePath);
+ CFRelease(bundleUrl);
+
+ CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(mainBundle);
+ CFStringRef cfResourcesPath = CFURLCopyPath(bundleUrl);
+ QString resourcesPath = QCFString::toQString(cfResourcesPath);
+ CFRelease(cfResourcesPath);
+ CFRelease(resourcesUrl);
+
+ // Handle bundled vs unbundled executables. CFBundleGetMainBundle() returns
+ // a valid bundle in both cases. CFBundleCopyResourcesDirectoryURL() returns
+ // an absolute path for unbundled executables.
+ if (resourcesPath.startsWith(QLatin1Char('/')))
+ dirs.append(resourcesPath);
+ else
+ dirs.append(bundlePath + resourcesPath);
+ }
+ }
const QString localDir = writableLocation(type);
dirs.prepend(localDir);
return dirs;
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 6a79c7c00b..a0344a0206 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -68,21 +68,6 @@
QT_BEGIN_NAMESPACE
-typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
-static GetSpecialFolderPath resolveGetSpecialFolderPath()
-{
- static GetSpecialFolderPath gsfp = 0;
- if (!gsfp) {
-#ifndef Q_OS_WINCE
- QSystemLibrary library(QLatin1String("shell32"));
-#else
- QSystemLibrary library(QLatin1String("coredll"));
-#endif // Q_OS_WINCE
- gsfp = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
- }
- return gsfp;
-}
-
static QString convertCharArray(const wchar_t *path)
{
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
@@ -92,10 +77,6 @@ QString QStandardPaths::writableLocation(StandardLocation type)
{
QString result;
- static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
- if (!SHGetSpecialFolderPath)
- return QString();
-
wchar_t path[MAX_PATH];
switch (type) {
@@ -185,8 +166,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
// type-specific handling goes here
#ifndef Q_OS_WINCE
- static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
- if (SHGetSpecialFolderPath) {
+ {
wchar_t path[MAX_PATH];
switch (type) {
case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
@@ -204,6 +184,12 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
#endif
}
dirs.append(result);
+#ifndef QT_BOOTSTRAPPED
+ if (type != GenericDataLocation) {
+ dirs.append(QCoreApplication::applicationDirPath());
+ dirs.append(QCoreApplication::applicationDirPath() + QLatin1String("/data"));
+ }
+#endif
}
break;
default:
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
new file mode 100644
index 0000000000..9b6a088a30
--- /dev/null
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qstandardpaths.h"
+
+#include <qdir.h>
+#include <private/qsystemlibrary_p.h>
+#include <qcoreapplication.h>
+#include <qstringlist.h>
+
+#include <qt_windows.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <Windows.ApplicationModel.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::ApplicationModel;
+
+#ifndef QT_NO_STANDARDPATHS
+
+QT_BEGIN_NAMESPACE
+
+static QString convertCharArray(const wchar_t *path)
+{
+ return QDir::fromNativeSeparators(QString::fromWCharArray(path));
+}
+
+QString QStandardPaths::writableLocation(StandardLocation type)
+{
+ QString result;
+
+ switch (type) {
+ case ConfigLocation: // same as DataLocation, on Windows
+ case DataLocation:
+ case GenericDataLocation: {
+ ComPtr<IApplicationDataStatics> applicationDataStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
+ break;
+ ComPtr<IApplicationData> applicationData;
+ if (FAILED(applicationDataStatics->get_Current(&applicationData)))
+ break;
+ ComPtr<IStorageFolder> settingsFolder;
+ if (FAILED(applicationData->get_LocalFolder(&settingsFolder)))
+ break;
+ ComPtr<IStorageItem> settingsFolderItem;
+ if (FAILED(settingsFolder.As(&settingsFolderItem)))
+ break;
+ HSTRING path;
+ if (FAILED(settingsFolderItem->get_Path(&path)))
+ break;
+ result = convertCharArray(WindowsGetStringRawBuffer(path, nullptr));
+ if (isTestModeEnabled())
+ result += QLatin1String("/qttest");
+ break;
+ }
+ case CacheLocation:
+ return writableLocation(DataLocation) + QLatin1String("/cache");
+
+ case GenericCacheLocation:
+ return writableLocation(GenericDataLocation) + QLatin1String("/cache");
+
+ case RuntimeLocation:
+ case HomeLocation:
+ result = QDir::homePath();
+ break;
+
+ case TempLocation:
+ result = QDir::tempPath();
+ break;
+ default:
+ Q_UNIMPLEMENTED();
+ }
+ return result;
+
+}
+
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ return QStringList(writableLocation(type));
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index b3cb4e43f8..3cade0ed25 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -77,7 +77,7 @@ typedef int NativeFileHandle;
/*
* Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -151,18 +151,27 @@ static bool createFileFromTemplate(NativeFileHandle &file,
for (;;) {
// Atomically create file and obtain handle
#if defined(Q_OS_WIN)
+# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+# else // !Q_OS_WINRT
+ file = CreateFile2((const wchar_t *)path.constData(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
+ NULL);
+# endif // Q_OS_WINRT
if (file != INVALID_HANDLE_VALUE)
return true;
DWORD err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
- DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
- if (attributes == INVALID_FILE_ATTRIBUTES) {
+ WIN32_FILE_ATTRIBUTE_DATA attributes;
+ if (!GetFileAttributesEx((const wchar_t *)path.constData(),
+ GetFileExInfoStandard, &attributes)
+ || attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
// Potential write error (read-only parent directory, etc.).
error = QSystemError(err, QSystemError::NativeError);
return false;
@@ -336,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
-#if !defined(Q_OS_WIN)
+#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
d->closeFileHandle = true;
#endif
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 8188628f57..163b087436 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -2191,20 +2191,20 @@ void QTextStreamPrivate::putNumber(qulonglong number, bool negative)
unsigned flags = 0;
const QTextStream::NumberFlags numberFlags = params.numberFlags;
if (numberFlags & QTextStream::ShowBase)
- flags |= QLocalePrivate::ShowBase;
+ flags |= QLocaleData::ShowBase;
if (numberFlags & QTextStream::ForceSign)
- flags |= QLocalePrivate::AlwaysShowSign;
+ flags |= QLocaleData::AlwaysShowSign;
if (numberFlags & QTextStream::UppercaseBase)
- flags |= QLocalePrivate::UppercaseBase;
+ flags |= QLocaleData::UppercaseBase;
if (numberFlags & QTextStream::UppercaseDigits)
- flags |= QLocalePrivate::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
// add thousands group separators. For backward compatibility we
// don't add a group separator for C locale.
if (locale != QLocale::c())
- flags |= QLocalePrivate::ThousandsGroup;
+ flags |= QLocaleData::ThousandsGroup;
- const QLocalePrivate *dd = locale.d;
+ const QLocaleData *dd = locale.d->m_data;
int base = params.integerBase ? params.integerBase : 10;
if (negative && base == 10) {
result = dd->longLongToString(-static_cast<qlonglong>(number), -1,
@@ -2388,32 +2388,32 @@ QTextStream &QTextStream::operator<<(double f)
Q_D(QTextStream);
CHECK_VALID_STREAM(*this);
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
switch (realNumberNotation()) {
case FixedNotation:
- form = QLocalePrivate::DFDecimal;
+ form = QLocaleData::DFDecimal;
break;
case ScientificNotation:
- form = QLocalePrivate::DFExponent;
+ form = QLocaleData::DFExponent;
break;
case SmartNotation:
- form = QLocalePrivate::DFSignificantDigits;
+ form = QLocaleData::DFSignificantDigits;
break;
}
uint flags = 0;
if (numberFlags() & ShowBase)
- flags |= QLocalePrivate::ShowBase;
+ flags |= QLocaleData::ShowBase;
if (numberFlags() & ForceSign)
- flags |= QLocalePrivate::AlwaysShowSign;
+ flags |= QLocaleData::AlwaysShowSign;
if (numberFlags() & UppercaseBase)
- flags |= QLocalePrivate::UppercaseBase;
+ flags |= QLocaleData::UppercaseBase;
if (numberFlags() & UppercaseDigits)
- flags |= QLocalePrivate::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
if (numberFlags() & ForcePoint)
- flags |= QLocalePrivate::Alternate;
+ flags |= QLocaleData::Alternate;
- const QLocalePrivate *dd = d->locale.d;
+ const QLocaleData *dd = d->locale.d->m_data;
QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags);
d->putString(num, true);
return *this;
diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp
index 890a2260a2..4e9b257c7b 100644
--- a/src/corelib/io/qurlidna.cpp
+++ b/src/corelib/io/qurlidna.cpp
@@ -73,7 +73,7 @@ inline bool operator<(const NameprepCaseFoldingEntry &one, uint other)
{ return one.uc < other; }
static const NameprepCaseFoldingEntry NameprepCaseFolding[] = {
-/* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } },
+/* { 0x0041, { 0x0061, 0x0000, 0x0000, 0x0000 } },
{ 0x0042, { 0x0062, 0x0000, 0x0000, 0x0000 } },
{ 0x0043, { 0x0063, 0x0000, 0x0000, 0x0000 } },
{ 0x0044, { 0x0064, 0x0000, 0x0000, 0x0000 } },
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index 80fc0319fe..74a981b654 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qurl.h"
+#include "private/qutfcodec_p.h"
QT_BEGIN_NAMESPACE
@@ -232,110 +233,73 @@ static void ensureDetached(QString &result, ushort *&output, const ushort *begin
}
}
-// returns true if we performed an UTF-8 decoding
-static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input,
- const ushort *end, ushort decoded)
+namespace {
+struct QUrlUtf8Traits : public QUtf8BaseTraitsNoAscii
{
- int charsNeeded;
- uint min_uc;
- uint uc;
-
- if (decoded <= 0xC1) {
- // an UTF-8 first character must be at least 0xC0
- // however, all 0xC0 and 0xC1 first bytes can only produce overlong sequences
- return false;
- } else if (decoded < 0xe0) {
- charsNeeded = 2;
- min_uc = 0x80;
- uc = decoded & 0x1f;
- } else if (decoded < 0xf0) {
- charsNeeded = 3;
- min_uc = 0x800;
- uc = decoded & 0x0f;
- } else if (decoded < 0xf5) {
- charsNeeded = 4;
- min_uc = 0x10000;
- uc = decoded & 0x07;
- } else {
- // the last Unicode character is U+10FFFF
- // it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF"
- // therefore, a byte higher than 0xF4 is not the UTF-8 first byte
- return false;
+ // override: our "bytes" are three percent-encoded UTF-16 characters
+ static void appendByte(ushort *&ptr, uchar b)
+ {
+ // b >= 0x80, by construction, so percent-encode
+ *ptr++ = '%';
+ *ptr++ = encodeNibble(b >> 4);
+ *ptr++ = encodeNibble(b & 0xf);
}
- // are there enough remaining?
- if (end - input < 3*charsNeeded)
- return false;
+ static uchar peekByte(const ushort *ptr, int n = 0)
+ {
+ // decodePercentEncoding returns ushort(-1) if it can't decode,
+ // which means we return 0xff, which is not a valid continuation byte.
+ // If ptr[i * 3] is not '%', we'll multiply by zero and return 0,
+ // also not a valid continuation byte (if it's '%', we multiply by 1).
+ return uchar(decodePercentEncoding(ptr + n * 3))
+ * uchar(ptr[n * 3] == '%');
+ }
- if (input[3] != '%')
- return false;
+ static qptrdiff availableBytes(const ushort *ptr, const ushort *end)
+ {
+ return (end - ptr) / 3;
+ }
- // first continuation character
- decoded = decodePercentEncoding(input + 3);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
-
- if (charsNeeded > 2) {
- if (input[6] != '%')
- return false;
-
- // second continuation character
- decoded = decodePercentEncoding(input + 6);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
-
- if (charsNeeded > 3) {
- if (input[9] != '%')
- return false;
-
- // third continuation character
- decoded = decodePercentEncoding(input + 9);
- if ((decoded & 0xc0) != 0x80)
- return false;
- uc <<= 6;
- uc |= decoded & 0x3f;
- }
+ static void advanceByte(const ushort *&ptr, int n = 1)
+ {
+ ptr += n * 3;
}
+};
+}
- // we've decoded something; safety-check it
- if (uc < min_uc)
- return false;
- if (QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint)
+// returns true if we performed an UTF-8 decoding
+static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input,
+ const ushort *end, ushort decoded)
+{
+ uint ucs4, *dst = &ucs4;
+ const ushort *src = input + 3;// skip the %XX that yielded \a decoded
+ int charsNeeded = QUtf8Functions::fromUtf8<QUrlUtf8Traits>(decoded, dst, src, end);
+ if (charsNeeded < 0)
return false;
- if (!QChar::requiresSurrogates(uc)) {
+ if (!QChar::requiresSurrogates(ucs4)) {
// UTF-8 decoded and no surrogates are required
// detach if necessary
- ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 1);
- *output++ = uc;
+ // possibilities are: 6 chars (%XX%XX) -> one char; 9 chars (%XX%XX%XX) -> one char
+ ensureDetached(result, output, begin, input, end, -3 * charsNeeded + 1);
+ *output++ = ucs4;
} else {
// UTF-8 decoded to something that requires a surrogate pair
- ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 2);
- *output++ = QChar::highSurrogate(uc);
- *output++ = QChar::lowSurrogate(uc);
+ // compressing from %XX%XX%XX%XX (12 chars) to two
+ ensureDetached(result, output, begin, input, end, -10);
+ *output++ = QChar::highSurrogate(ucs4);
+ *output++ = QChar::lowSurrogate(ucs4);
}
- input += charsNeeded * 3 - 1;
+
+ input = src - 1;
return true;
}
static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort *begin,
const ushort *&input, const ushort *end, ushort decoded)
{
- uint uc = decoded;
- if (QChar::isHighSurrogate(uc)) {
- if (input < end && QChar::isLowSurrogate(input[1]))
- uc = QChar::surrogateToUcs4(uc, input[1]);
- }
-
- // note: we will encode bad UTF-16 to UTF-8
- // but they don't get decoded back
-
- // calculate the utf8 length
- int utf8len = uc >= 0x10000 ? 4 : uc >= 0x800 ? 3 : 2;
+ // calculate the utf8 length and ensure enough space is available
+ int utf8len = QChar::isHighSurrogate(decoded) ? 4 : decoded >= 0x800 ? 3 : 2;
// detach
if (!output) {
@@ -357,50 +321,32 @@ static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort
}
}
- // write the sequence
- if (uc < 0x800) {
- // first of two bytes
- uchar c = 0xc0 | uchar(uc >> 6);
+ ++input;
+ int res = QUtf8Functions::toUtf8<QUrlUtf8Traits>(decoded, output, input, end);
+ --input;
+ if (res < 0) {
+ // bad surrogate pair sequence
+ // we will encode bad UTF-16 to UTF-8
+ // but they don't get decoded back
+
+ // first of three bytes
+ uchar c = 0xe0 | uchar(decoded >> 12);
*output++ = '%';
- *output++ = encodeNibble(c >> 4);
+ *output++ = 'E';
*output++ = encodeNibble(c & 0xf);
- } else {
- uchar c;
- if (uc > 0xFFFF) {
- // first two of four bytes
- c = 0xf0 | uchar(uc >> 18);
- *output++ = '%';
- *output++ = 'F';
- *output++ = encodeNibble(c & 0xf);
- // continuation byte
- c = 0x80 | (uchar(uc >> 12) & 0x3f);
- *output++ = '%';
- *output++ = encodeNibble(c >> 4);
- *output++ = encodeNibble(c & 0xf);
-
- // this was a surrogate pair
- ++input;
- } else {
- // first of three bytes
- c = 0xe0 | uchar(uc >> 12);
- *output++ = '%';
- *output++ = 'E';
- *output++ = encodeNibble(c & 0xf);
- }
+ // second byte
+ c = 0x80 | (uchar(decoded >> 6) & 0x3f);
+ *output++ = '%';
+ *output++ = encodeNibble(c >> 4);
+ *output++ = encodeNibble(c & 0xf);
- // continuation byte
- c = 0x80 | (uchar(uc >> 6) & 0x3f);
+ // third byte
+ c = 0x80 | (decoded & 0x3f);
*output++ = '%';
*output++ = encodeNibble(c >> 4);
*output++ = encodeNibble(c & 0xf);
}
-
- // continuation byte
- uchar c = 0x80 | (uc & 0x3f);
- *output++ = '%';
- *output++ = encodeNibble(c >> 4);
- *output++ = encodeNibble(c & 0xf);
}
static int recode(QString &result, const ushort *begin, const ushort *end, QUrl::ComponentFormattingOptions encoding,
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index fc9d191a90..df65aebcff 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -173,7 +173,8 @@ bool QWindowsPipeReader::canReadLine() const
\internal
Will be called whenever the read operation completes.
*/
-void QWindowsPipeReader::notified(DWORD numberOfBytesRead, DWORD errorCode, OVERLAPPED *notifiedOverlapped)
+void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
+ OVERLAPPED *notifiedOverlapped)
{
if (&overlapped != notifiedOverlapped)
return;
diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h
index ea3d3c271f..78ac8eb76d 100644
--- a/src/corelib/io/qwindowspipereader_p.h
+++ b/src/corelib/io/qwindowspipereader_p.h
@@ -94,7 +94,7 @@ Q_SIGNALS:
void pipeClosed();
private Q_SLOTS:
- void notified(DWORD numberOfBytesRead, DWORD errorCode, OVERLAPPED *notifiedOverlapped);
+ void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
private:
bool completeAsyncRead(DWORD bytesRead, DWORD errorCode);
diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp
index 1808081d01..daa8068734 100644
--- a/src/corelib/io/qwindowspipewriter.cpp
+++ b/src/corelib/io/qwindowspipewriter.cpp
@@ -114,7 +114,7 @@ void QWindowsPipeWriter::run()
if (quitNow) {
lock.unlock();
quitNow = false;
- break;
+ break;
}
QByteArray copy = data;
@@ -153,7 +153,7 @@ void QWindowsPipeWriter::run()
totalWritten += written;
#if defined QPIPEWRITER_DEBUG
qDebug("QWindowsPipeWriter::run() wrote %d %d/%d bytes",
- written, int(totalWritten), int(maxlen));
+ written, int(totalWritten), int(maxlen));
#endif
lock.lock();
data.remove(0, written);
diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp
index 914264e69e..33583afb78 100644
--- a/src/corelib/io/qwinoverlappedionotifier.cpp
+++ b/src/corelib/io/qwinoverlappedionotifier.cpp
@@ -43,8 +43,11 @@
#include <qdebug.h>
#include <qmutex.h>
#include <qpointer.h>
+#include <qqueue.h>
#include <qset.h>
#include <qthread.h>
+#include <qt_windows.h>
+#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +82,46 @@ QT_BEGIN_NAMESPACE
\warning This class is only available on Windows.
*/
+struct IOResult
+{
+ IOResult(DWORD n = 0, DWORD e = 0, OVERLAPPED *p = 0)
+ : numberOfBytes(n), errorCode(e), overlapped(p)
+ {}
+
+ DWORD numberOfBytes;
+ DWORD errorCode;
+ OVERLAPPED *overlapped;
+};
+
+
+class QWinIoCompletionPort;
+
+class QWinOverlappedIoNotifierPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWinOverlappedIoNotifier)
+public:
+ QWinOverlappedIoNotifierPrivate()
+ : hHandle(INVALID_HANDLE_VALUE)
+ {
+ }
+
+ void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
+ OVERLAPPED *_q_notified();
+
+ static QWinIoCompletionPort *iocp;
+ static HANDLE iocpInstanceLock;
+ static unsigned int iocpInstanceRefCount;
+ HANDLE hHandle;
+ HANDLE hSemaphore;
+ HANDLE hResultsMutex;
+ QQueue<IOResult> results;
+};
+
+QWinIoCompletionPort *QWinOverlappedIoNotifierPrivate::iocp = 0;
+HANDLE QWinOverlappedIoNotifierPrivate::iocpInstanceLock = CreateMutex(NULL, FALSE, NULL);
+unsigned int QWinOverlappedIoNotifierPrivate::iocpInstanceRefCount = 0;
+
+
class QWinIoCompletionPort : protected QThread
{
public:
@@ -109,11 +152,13 @@ public:
CloseHandle(hQueueDrainedEvent);
}
- void registerNotifier(QWinOverlappedIoNotifier *notifier)
+ void registerNotifier(QWinOverlappedIoNotifierPrivate *notifier)
{
- HANDLE hIOCP = CreateIoCompletionPort(notifier->hHandle, hPort, reinterpret_cast<ULONG_PTR>(notifier), 0);
+ const HANDLE hHandle = notifier->hHandle;
+ HANDLE hIOCP = CreateIoCompletionPort(hHandle, hPort,
+ reinterpret_cast<ULONG_PTR>(notifier), 0);
if (!hIOCP) {
- qErrnoWarning("Can't associate file handle %x with I/O completion port.", notifier->hHandle);
+ qErrnoWarning("Can't associate file handle %x with I/O completion port.", hHandle);
return;
}
mutex.lock();
@@ -123,7 +168,7 @@ public:
QThread::start();
}
- void unregisterNotifier(QWinOverlappedIoNotifier *notifier)
+ void unregisterNotifier(QWinOverlappedIoNotifierPrivate *notifier)
{
mutex.lock();
notifiers.remove(notifier);
@@ -176,7 +221,8 @@ protected:
continue;
}
- QWinOverlappedIoNotifier *notifier = reinterpret_cast<QWinOverlappedIoNotifier *>(pulCompletionKey);
+ QWinOverlappedIoNotifierPrivate *notifier
+ = reinterpret_cast<QWinOverlappedIoNotifierPrivate *>(pulCompletionKey);
mutex.lock();
if (notifiers.contains(notifier))
notifier->notify(dwBytesRead, errorCode, overlapped);
@@ -188,57 +234,62 @@ private:
const ULONG_PTR finishThreadKey;
const ULONG_PTR drainQueueKey;
HANDLE hPort;
- QSet<QWinOverlappedIoNotifier *> notifiers;
+ QSet<QWinOverlappedIoNotifierPrivate *> notifiers;
QMutex mutex;
QMutex drainQueueMutex;
HANDLE hQueueDrainedEvent;
};
-QWinIoCompletionPort *QWinOverlappedIoNotifier::iocp = 0;
-HANDLE QWinOverlappedIoNotifier::iocpInstanceLock = CreateMutex(NULL, FALSE, NULL);
-unsigned int QWinOverlappedIoNotifier::iocpInstanceRefCount = 0;
QWinOverlappedIoNotifier::QWinOverlappedIoNotifier(QObject *parent)
- : QObject(parent),
- hHandle(INVALID_HANDLE_VALUE)
+ : QObject(*new QWinOverlappedIoNotifierPrivate, parent)
{
- WaitForSingleObject(iocpInstanceLock, INFINITE);
- if (!iocp)
- iocp = new QWinIoCompletionPort;
- iocpInstanceRefCount++;
- ReleaseMutex(iocpInstanceLock);
-
- hSemaphore = CreateSemaphore(NULL, 0, 255, NULL);
- hResultsMutex = CreateMutex(NULL, FALSE, NULL);
- connect(this, &QWinOverlappedIoNotifier::_q_notify,
- this, &QWinOverlappedIoNotifier::_q_notified, Qt::QueuedConnection);
+ Q_D(QWinOverlappedIoNotifier);
+ WaitForSingleObject(d->iocpInstanceLock, INFINITE);
+ if (!d->iocp)
+ d->iocp = new QWinIoCompletionPort;
+ d->iocpInstanceRefCount++;
+ ReleaseMutex(d->iocpInstanceLock);
+
+ d->hSemaphore = CreateSemaphore(NULL, 0, 255, NULL);
+ d->hResultsMutex = CreateMutex(NULL, FALSE, NULL);
+ connect(this, SIGNAL(_q_notify()), this, SLOT(_q_notified()), Qt::QueuedConnection);
}
QWinOverlappedIoNotifier::~QWinOverlappedIoNotifier()
{
+ Q_D(QWinOverlappedIoNotifier);
setEnabled(false);
- CloseHandle(hResultsMutex);
- CloseHandle(hSemaphore);
+ CloseHandle(d->hResultsMutex);
+ CloseHandle(d->hSemaphore);
- WaitForSingleObject(iocpInstanceLock, INFINITE);
- if (!--iocpInstanceRefCount) {
- delete iocp;
- iocp = 0;
+ WaitForSingleObject(d->iocpInstanceLock, INFINITE);
+ if (!--d->iocpInstanceRefCount) {
+ delete d->iocp;
+ d->iocp = 0;
}
- ReleaseMutex(iocpInstanceLock);
+ ReleaseMutex(d->iocpInstanceLock);
}
-void QWinOverlappedIoNotifier::setHandle(HANDLE h)
+void QWinOverlappedIoNotifier::setHandle(Qt::HANDLE h)
{
- hHandle = h;
+ Q_D(QWinOverlappedIoNotifier);
+ d->hHandle = h;
+}
+
+Qt::HANDLE QWinOverlappedIoNotifier::handle() const
+{
+ Q_D(const QWinOverlappedIoNotifier);
+ return d->hHandle;
}
void QWinOverlappedIoNotifier::setEnabled(bool enabled)
{
+ Q_D(QWinOverlappedIoNotifier);
if (enabled)
- iocp->registerNotifier(this);
+ d->iocp->registerNotifier(d);
else
- iocp->unregisterNotifier(this);
+ d->iocp->unregisterNotifier(d);
}
/*!
@@ -249,18 +300,19 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
*/
bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
{
- if (!iocp->isRunning()) {
+ Q_D(QWinOverlappedIoNotifier);
+ if (!d->iocp->isRunning()) {
qWarning("Called QWinOverlappedIoNotifier::waitForNotified on inactive notifier.");
return false;
}
forever {
if (msecs == 0)
- iocp->drainQueue();
- DWORD result = WaitForSingleObject(hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
+ d->iocp->drainQueue();
+ DWORD result = WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
if (result == WAIT_OBJECT_0) {
- ReleaseSemaphore(hSemaphore, 1, NULL);
- if (_q_notified() == overlapped)
+ ReleaseSemaphore(d->hSemaphore, 1, NULL);
+ if (d->_q_notified() == overlapped)
return true;
continue;
} else if (result == WAIT_TIMEOUT) {
@@ -275,25 +327,30 @@ bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped
/*!
* Note: This function runs in the I/O completion port thread.
*/
-void QWinOverlappedIoNotifier::notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped)
+void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCode,
+ OVERLAPPED *overlapped)
{
+ Q_Q(QWinOverlappedIoNotifier);
WaitForSingleObject(hResultsMutex, INFINITE);
results.enqueue(IOResult(numberOfBytes, errorCode, overlapped));
ReleaseMutex(hResultsMutex);
ReleaseSemaphore(hSemaphore, 1, NULL);
- emit _q_notify();
+ emit q->_q_notify();
}
-OVERLAPPED *QWinOverlappedIoNotifier::_q_notified()
+OVERLAPPED *QWinOverlappedIoNotifierPrivate::_q_notified()
{
+ Q_Q(QWinOverlappedIoNotifier);
if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) {
WaitForSingleObject(hResultsMutex, INFINITE);
IOResult ioresult = results.dequeue();
ReleaseMutex(hResultsMutex);
- emit notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped);
+ emit q->notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped);
return ioresult.overlapped;
}
return 0;
}
QT_END_NAMESPACE
+
+#include "moc_qwinoverlappedionotifier_p.cpp"
diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h
index 451bedf7cf..f90fd2e615 100644
--- a/src/corelib/io/qwinoverlappedionotifier_p.h
+++ b/src/corelib/io/qwinoverlappedionotifier_p.h
@@ -54,58 +54,35 @@
//
#include <qobject.h>
-#include <qt_windows.h>
-#include <qqueue.h>
+
+typedef struct _OVERLAPPED OVERLAPPED;
QT_BEGIN_NAMESPACE
-class QWinIoCompletionPort;
+class QWinOverlappedIoNotifierPrivate;
class Q_CORE_EXPORT QWinOverlappedIoNotifier : public QObject
{
Q_OBJECT
+ Q_DISABLE_COPY(QWinOverlappedIoNotifier)
+ Q_DECLARE_PRIVATE(QWinOverlappedIoNotifier)
+ Q_PRIVATE_SLOT(d_func(), OVERLAPPED *_q_notified())
+ friend class QWinIoCompletionPort;
public:
QWinOverlappedIoNotifier(QObject *parent = 0);
~QWinOverlappedIoNotifier();
- void setHandle(HANDLE h);
- HANDLE handle() const { return hHandle; }
+ void setHandle(Qt::HANDLE h);
+ Qt::HANDLE handle() const;
void setEnabled(bool enabled);
bool waitForNotified(int msecs, OVERLAPPED *overlapped);
Q_SIGNALS:
- void notified(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
+ void notified(quint32 numberOfBytes, quint32 errorCode, OVERLAPPED *overlapped);
+#if !defined(Q_QDOC)
void _q_notify();
-
-private Q_SLOTS:
- OVERLAPPED *_q_notified();
-
-private:
- void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped);
-
-private:
- static QWinIoCompletionPort *iocp;
- static HANDLE iocpInstanceLock;
- static unsigned int iocpInstanceRefCount;
- HANDLE hHandle;
- HANDLE hSemaphore;
- HANDLE hResultsMutex;
-
- struct IOResult
- {
- IOResult(DWORD n = 0, DWORD e = 0, OVERLAPPED *p = 0)
- : numberOfBytes(n), errorCode(e), overlapped(p)
- {}
-
- DWORD numberOfBytes;
- DWORD errorCode;
- OVERLAPPED *overlapped;
- };
-
- QQueue<IOResult> results;
-
- friend class QWinIoCompletionPort;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qitemselectionmodel.cpp b/src/corelib/itemmodels/qitemselectionmodel.cpp
index aff9939b87..883aa5b982 100644
--- a/src/corelib/itemmodels/qitemselectionmodel.cpp
+++ b/src/corelib/itemmodels/qitemselectionmodel.cpp
@@ -1271,9 +1271,8 @@ void QItemSelectionModel::clearCurrentIndex()
*/
void QItemSelectionModel::reset()
{
- bool block = blockSignals(true);
+ const QSignalBlocker blocker(this);
clear();
- blockSignals(block);
}
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 930c2871d3..ebc97ca2d9 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -960,8 +960,8 @@ void QSortFilterProxyModelPrivate::updateChildrenMapping(const QModelIndex &sour
// update mapping
Mapping *cm = source_index_mapping.take(source_child_index);
Q_ASSERT(cm);
- // we do not reinsert right away, because the new index might be identical with another, old index
- moved_source_index_mappings.append(QPair<QModelIndex, Mapping*>(new_index, cm));
+ // we do not reinsert right away, because the new index might be identical with another, old index
+ moved_source_index_mappings.append(QPair<QModelIndex, Mapping*>(new_index, cm));
}
}
@@ -1139,7 +1139,7 @@ QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed(
}
void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &source_top_left,
- const QModelIndex &source_bottom_right)
+ const QModelIndex &source_bottom_right)
{
Q_Q(QSortFilterProxyModel);
if (!source_top_left.isValid() || !source_bottom_right.isValid())
@@ -1211,8 +1211,8 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
source_parent, Qt::Vertical, false);
update_persistent_indexes(source_indexes);
emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint);
- // Make sure we also emit dataChanged for the rows
- source_rows_change += source_rows_resort;
+ // Make sure we also emit dataChanged for the rows
+ source_rows_change += source_rows_resort;
}
if (!source_rows_change.isEmpty()) {
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
index d81de89628..61bb158ff5 100644
--- a/src/corelib/json/qjsonarray.cpp
+++ b/src/corelib/json/qjsonarray.cpp
@@ -188,6 +188,31 @@ QJsonArray &QJsonArray::operator =(const QJsonArray &other)
return *this;
}
+/*! \fn QJsonArray &QJsonArray::operator+=(const QJsonValue &value)
+
+ Appends \a value to the array, and returns a reference to the array itself.
+
+ \since 5.3
+ \sa append(), operator<<()
+*/
+
+/*! \fn QJsonArray QJsonArray::operator+(const QJsonValue &value) const
+
+ Returns an array that contains all the items in this array followed
+ by the provided \a value.
+
+ \since 5.3
+ \sa operator+=()
+*/
+
+/*! \fn QJsonArray &QJsonArray::operator<<(const QJsonValue &value)
+
+ Appends \a value to the array, and returns a reference to the array itself.
+
+ \since 5.3
+ \sa operator+=(), append()
+*/
+
/*!
Converts the string list \a list to a QJsonArray.
diff --git a/src/corelib/json/qjsonarray.h b/src/corelib/json/qjsonarray.h
index 562e6accd7..84c162f0a0 100644
--- a/src/corelib/json/qjsonarray.h
+++ b/src/corelib/json/qjsonarray.h
@@ -183,6 +183,14 @@ public:
typedef iterator Iterator;
typedef const_iterator ConstIterator;
+ // convenience
+ inline QJsonArray operator+(const QJsonValue &v) const
+ { QJsonArray n = *this; n += v; return n; }
+ inline QJsonArray &operator+=(const QJsonValue &v)
+ { append(v); return *this; }
+ inline QJsonArray &operator<< (const QJsonValue &v)
+ { append(v); return *this; }
+
// stl compatibility
inline void push_back(const QJsonValue &t) { append(t); }
inline void push_front(const QJsonValue &t) { prepend(t); }
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 516c53775c..0c61718843 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -45,6 +46,7 @@
#include <qdebug.h>
#include "qjsonparser_p.h"
#include "qjson_p.h"
+#include "private/qutfcodec_p.h"
//#define PARSER_DEBUG
#ifdef PARSER_DEBUG
@@ -820,45 +822,16 @@ static inline bool scanEscapeSequence(const char *&json, const char *end, uint *
static inline bool scanUtf8Char(const char *&json, const char *end, uint *result)
{
- int need;
- uint min_uc;
- uint uc;
- uchar ch = *json++;
- if (ch < 128) {
- *result = ch;
- return true;
- } else if ((ch & 0xe0) == 0xc0) {
- uc = ch & 0x1f;
- need = 1;
- min_uc = 0x80;
- } else if ((ch & 0xf0) == 0xe0) {
- uc = ch & 0x0f;
- need = 2;
- min_uc = 0x800;
- } else if ((ch&0xf8) == 0xf0) {
- uc = ch & 0x07;
- need = 3;
- min_uc = 0x10000;
- } else {
- return false;
- }
-
- if (json >= end - need)
- return false;
-
- for (int i = 0; i < need; ++i) {
- ch = *json++;
- if ((ch&0xc0) != 0x80)
- return false;
- uc = (uc << 6) | (ch & 0x3f);
- }
-
- if (uc < min_uc ||
- QChar::isSurrogate(uc) || uc > QChar::LastValidCodePoint) {
+ const uchar *&src = reinterpret_cast<const uchar *&>(json);
+ const uchar *uend = reinterpret_cast<const uchar *>(end);
+ uchar b = *src++;
+ int res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(b, result, src, uend);
+ if (res < 0) {
+ // decoding error, backtrack the character we read above
+ --json;
return false;
}
- *result = uc;
return true;
}
diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp
index 0a603b958a..c16824ebd2 100644
--- a/src/corelib/json/qjsonvalue.cpp
+++ b/src/corelib/json/qjsonvalue.cpp
@@ -175,7 +175,24 @@ QJsonValue::QJsonValue(qint64 n)
QJsonValue::QJsonValue(const QString &s)
: d(0), t(String)
{
- stringData = *(QStringData **)(&s);
+ stringDataFromQStringHelper(s);
+}
+
+/*!
+ \fn QJsonValue::QJsonValue(const char *s)
+
+ Creates a value of type String with value \a s, assuming
+ UTF-8 encoding of the input.
+
+ You can disable this constructor by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications.
+
+ \since 5.3
+ */
+
+void QJsonValue::stringDataFromQStringHelper(const QString &string)
+{
+ stringData = *(QStringData **)(&string);
stringData->ref.ref();
}
@@ -187,8 +204,7 @@ QJsonValue::QJsonValue(QLatin1String s)
{
// ### FIXME: Avoid creating the temp QString below
QString str(s);
- stringData = *(QStringData **)(&str);
- stringData->ref.ref();
+ stringDataFromQStringHelper(str);
}
/*!
diff --git a/src/corelib/json/qjsonvalue.h b/src/corelib/json/qjsonvalue.h
index c0ecdd2b61..fe028990c0 100644
--- a/src/corelib/json/qjsonvalue.h
+++ b/src/corelib/json/qjsonvalue.h
@@ -82,6 +82,10 @@ public:
QJsonValue(qint64 n);
QJsonValue(const QString &s);
QJsonValue(QLatin1String s);
+#ifndef QT_NO_CAST_FROM_ASCII
+ inline QT_ASCII_CAST_WARN QJsonValue(const char *s)
+ : d(0), t(String) { stringDataFromQStringHelper(QString::fromUtf8(s)); }
+#endif
QJsonValue(const QJsonArray &a);
QJsonValue(const QJsonObject &o);
@@ -123,6 +127,7 @@ private:
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
QJsonValue(QJsonPrivate::Data *d, QJsonPrivate::Base *b, const QJsonPrivate::Value& v);
+ void stringDataFromQStringHelper(const QString &string);
void detach();
diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp
index 86cca4bb26..17c22429a5 100644
--- a/src/corelib/json/qjsonwriter.cpp
+++ b/src/corelib/json/qjsonwriter.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -41,6 +42,7 @@
#include "qjsonwriter_p.h"
#include "qjson_p.h"
+#include "private/qutfcodec_p.h"
QT_BEGIN_NAMESPACE
@@ -59,15 +61,12 @@ static QByteArray escapedString(const QString &s)
const uchar replacement = '?';
QByteArray ba(s.length(), Qt::Uninitialized);
- uchar *cursor = (uchar *)ba.data();
+ uchar *cursor = reinterpret_cast<uchar *>(const_cast<char *>(ba.constData()));
const uchar *ba_end = cursor + ba.length();
+ const ushort *src = reinterpret_cast<const ushort *>(s.constBegin());
+ const ushort *const end = reinterpret_cast<const ushort *>(s.constEnd());
- const QChar *ch = (const QChar *)s.constData();
- const QChar *end = ch + s.length();
-
- int surrogate_high = -1;
-
- while (ch < end) {
+ while (src != end) {
if (cursor >= ba_end - 6) {
// ensure we have enough space
int pos = cursor - (const uchar *)ba.constData();
@@ -76,29 +75,7 @@ static QByteArray escapedString(const QString &s)
ba_end = (const uchar *)ba.constData() + ba.length();
}
- uint u = ch->unicode();
- if (surrogate_high >= 0) {
- if (ch->isLowSurrogate()) {
- u = QChar::surrogateToUcs4(surrogate_high, u);
- surrogate_high = -1;
- } else {
- // high surrogate without low
- *cursor = replacement;
- ++ch;
- surrogate_high = -1;
- continue;
- }
- } else if (ch->isLowSurrogate()) {
- // low surrogate without high
- *cursor = replacement;
- ++ch;
- continue;
- } else if (ch->isHighSurrogate()) {
- surrogate_high = u;
- ++ch;
- continue;
- }
-
+ uint u = *src++;
if (u < 0x80) {
if (u < 0x20 || u == 0x22 || u == 0x5c) {
*cursor++ = '\\';
@@ -135,20 +112,9 @@ static QByteArray escapedString(const QString &s)
*cursor++ = (uchar)u;
}
} else {
- if (u < 0x0800) {
- *cursor++ = 0xc0 | ((uchar) (u >> 6));
- } else {
- if (QChar::requiresSurrogates(u)) {
- *cursor++ = 0xf0 | ((uchar) (u >> 18));
- *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
- } else {
- *cursor++ = 0xe0 | (((uchar) (u >> 12)) & 0x3f);
- }
- *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
- }
- *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ if (QUtf8Functions::toUtf8<QUtf8BaseTraits>(u, cursor, src, end) < 0)
+ *cursor++ = replacement;
}
- ++ch;
}
ba.resize(cursor - (const uchar *)ba.constData());
@@ -229,7 +195,7 @@ static void objectContentToJson(const QJsonPrivate::Object *o, QByteArray &json,
json += indentString;
json += '"';
json += escapedString(e->key());
- json += "\": ";
+ json += compact ? "\":" : "\": ";
valueToJson(o, e->value, json, indent, compact);
if (++i == o->length) {
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 7625a74381..1fec528b31 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -68,16 +68,21 @@ SOURCES += \
win32 {
SOURCES += \
- kernel/qeventdispatcher_win.cpp \
kernel/qcoreapplication_win.cpp \
kernel/qwineventnotifier.cpp \
kernel/qsharedmemory_win.cpp \
kernel/qsystemsemaphore_win.cpp
HEADERS += \
- kernel/qeventdispatcher_win_p.h \
kernel/qwineventnotifier.h
-}
+ winrt {
+ SOURCES += kernel/qeventdispatcher_winrt.cpp
+ HEADERS += kernel/qeventdispatcher_winrt_p.h
+ } else {
+ SOURCES += kernel/qeventdispatcher_win.cpp
+ HEADERS += kernel/qeventdispatcher_win_p.h
+ }
+}
wince*: {
SOURCES += \
@@ -86,6 +91,13 @@ wince*: {
kernel/qfunctions_wince.h
}
+winrt {
+ SOURCES += \
+ kernel/qfunctions_winrt.cpp
+ HEADERS += \
+ kernel/qfunctions_winrt.h
+}
+
mac {
SOURCES += \
kernel/qcoreapplication_mac.cpp
@@ -152,9 +164,15 @@ vxworks {
blackberry {
SOURCES += \
- kernel/qeventdispatcher_blackberry.cpp
+ kernel/qeventdispatcher_blackberry.cpp \
+ kernel/qppsattribute.cpp \
+ kernel/qppsobject.cpp
HEADERS += \
- kernel/qeventdispatcher_blackberry_p.h
+ kernel/qeventdispatcher_blackberry_p.h \
+ kernel/qppsattribute_p.h \
+ kernel/qppsattributeprivate_p.h \
+ kernel/qppsobject_p.h \
+ kernel/qppsobjectprivate_p.h
}
android:!android-no-sdk {
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index 54524fa55b..90e3a1e9e1 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -210,9 +210,11 @@ QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
*/
/*! \fn bool QAbstractEventDispatcher::hasPendingEvents()
+ \deprecated
- Returns \c true if there is an event waiting; otherwise returns
- false.
+ Returns \c true if there is an event waiting; otherwise returns false. This
+ function is an implementation detail for
+ QCoreApplication::hasPendingEvents() and must not be called directly.
*/
/*!
diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h
index 6f21cefa4e..d95ebe0ca2 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.h
+++ b/src/corelib/kernel/qabstracteventdispatcher.h
@@ -78,7 +78,7 @@ public:
static QAbstractEventDispatcher *instance(QThread *thread = 0);
virtual bool processEvents(QEventLoop::ProcessEventsFlags flags) = 0;
- virtual bool hasPendingEvents() = 0;
+ virtual bool hasPendingEvents() = 0; // ### Qt6: remove, mark final or make protected
virtual void registerSocketNotifier(QSocketNotifier *notifier) = 0;
virtual void unregisterSocketNotifier(QSocketNotifier *notifier) = 0;
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index f491be9768..e92a2d2978 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -105,13 +105,13 @@ public:
inline operator T() { return type; }
inline QCFType operator =(const QCFType &helper)
{
- if (helper.type)
- CFRetain(helper.type);
- CFTypeRef type2 = type;
- type = helper.type;
- if (type2)
- CFRelease(type2);
- return *this;
+ if (helper.type)
+ CFRetain(helper.type);
+ CFTypeRef type2 = type;
+ type = helper.type;
+ if (type2)
+ CFRelease(type2);
+ return *this;
}
inline T *operator&() { return &type; }
template <typename X> X as() const { return reinterpret_cast<X>(type); }
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 8c0589fdc6..7ab632d7a0 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -117,6 +117,8 @@ inline bool operator<(const timespec &t1, const timespec &t2)
{ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec); }
inline bool operator==(const timespec &t1, const timespec &t2)
{ return t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec; }
+inline bool operator!=(const timespec &t1, const timespec &t2)
+{ return !(t1 == t2); }
inline timespec &operator+=(timespec &t1, const timespec &t2)
{
t1.tv_sec += t2.tv_sec;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e77d6894d0..e8bcc449e9 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -55,6 +55,7 @@
#include <qfileinfo.h>
#include <qhash.h>
#include <qmutex.h>
+#include <private/qloggingregistry_p.h>
#include <private/qprocess_p.h>
#include <qstandardpaths.h>
#include <qtextcodec.h>
@@ -85,7 +86,11 @@
# endif
#endif
#ifdef Q_OS_WIN
+# ifdef Q_OS_WINRT
+# include "qeventdispatcher_winrt_p.h"
+# else
# include "qeventdispatcher_win_p.h"
+# endif
#endif
#endif // QT_NO_QOBJECT
@@ -98,6 +103,7 @@
#ifdef Q_OS_UNIX
# include <locale.h>
# include <unistd.h>
+# include <sys/types.h>
#endif
#ifdef Q_OS_VXWORKS
@@ -134,6 +140,8 @@ extern QString qAppFileName();
#endif
int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exactly, but it's at least 5.0.0
+bool QCoreApplicationPrivate::setuidAllowed = false;
+
#if !defined(Q_OS_WIN)
#ifdef Q_OS_MAC
QString QCoreApplicationPrivate::macMenuBarName()
@@ -179,6 +187,8 @@ void QCoreApplicationPrivate::processCommandLineArguments()
continue;
}
QByteArray arg = argv[i];
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
if (arg.startsWith("-qmljsdebugger=")) {
qmljs_debug_arguments = QString::fromLocal8Bit(arg.right(arg.length() - 15));
} else if (arg == "-qmljsdebugger" && i < argc - 1) {
@@ -410,6 +420,11 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
QCoreApplicationPrivate::is_app_closing = false;
# if defined(Q_OS_UNIX)
+ if (!setuidAllowed && (geteuid() != getuid()))
+ qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
+# endif // Q_OS_UNIX
+
+# if defined(Q_OS_UNIX)
qt_application_thread_id = QThread::currentThreadId();
# endif
@@ -471,6 +486,8 @@ void QCoreApplicationPrivate::createEventDispatcher()
# endif
eventDispatcher = new QEventDispatcherUNIX(q);
# endif
+#elif defined(Q_OS_WINRT)
+ eventDispatcher = new QEventDispatcherWinRT(q);
#elif defined(Q_OS_WIN)
eventDispatcher = new QEventDispatcherWin32(q);
#else
@@ -518,6 +535,10 @@ void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
coreappdata()->app_libpaths = app_libpaths = new QStringList;
QString app_location = QCoreApplication::applicationFilePath();
app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
+#ifdef Q_OS_WINRT
+ if (app_location.isEmpty())
+ app_location.append(QLatin1Char('/'));
+#endif
app_location = QDir(app_location).canonicalPath();
if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
app_libpaths->append(app_location);
@@ -702,6 +723,10 @@ void QCoreApplication::init()
Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = this;
+#ifndef QT_BOOTSTRAPPED
+ QLoggingRegistry::instance()->init();
+#endif
+
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
if (!QCoreApplicationPrivate::eventDispatcher)
@@ -786,18 +811,49 @@ QCoreApplication::~QCoreApplication()
#endif
}
+/*!
+ \since 5.3
+
+ Allows the application to run setuid on UNIX platforms if \a allow
+ is true.
+
+ If \a allow is false (the default) and Qt detects the application is
+ running with an effective user id different than the real user id,
+ the application will be aborted when a QCoreApplication instance is
+ created.
+
+ Qt is not an appropriate solution for setuid programs due to its
+ large attack surface. However some applications may be required
+ to run in this manner for historical reasons. This flag will
+ prevent Qt from aborting the application when this is detected,
+ and must be set before a QCoreApplication instance is created.
+
+ \note It is strongly recommended not to enable this option since
+ it introduces security risks.
+*/
+void QCoreApplication::setSetuidAllowed(bool allow)
+{
+ QCoreApplicationPrivate::setuidAllowed = allow;
+}
+
+/*!
+ \since 5.3
+
+ Returns true if the application is allowed to run setuid on UNIX
+ platforms.
+
+ \sa QCoreApplication::setSetuidAllowed()
+*/
+bool QCoreApplication::isSetuidAllowed()
+{
+ return QCoreApplicationPrivate::setuidAllowed;
+}
+
/*!
Sets the attribute \a attribute if \a on is true;
otherwise clears the attribute.
- One of the attributes that can be set with this method is
- Qt::AA_ImmediateWidgetCreation. It tells Qt to create toplevel
- windows immediately. Normally, resources for widgets are allocated
- on demand to improve efficiency and minimize resource usage.
- Therefore, if it is important to minimize resource consumption, do
- not set this attribute.
-
\sa testAttribute()
*/
void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
@@ -2502,10 +2558,16 @@ void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filte
}
/*!
+ \deprecated
+
This function returns \c true if there are pending events; otherwise
returns \c false. Pending events can be either from the window
system or posted events using postEvent().
+ \note this function is not thread-safe. It may only be called in the main
+ thread and only if there are no other threads running in the application
+ (including threads Qt starts for its own purposes).
+
\sa QAbstractEventDispatcher::hasPendingEvents()
*/
bool QCoreApplication::hasPendingEvents()
@@ -2572,10 +2634,12 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
\fn void qAddPostRoutine(QtCleanUpFunction ptr)
\relates QCoreApplication
- Adds a global routine that will be called from the QApplication
+ Adds a global routine that will be called from the QCoreApplication
destructor. This function is normally used to add cleanup routines
for program-wide functionality.
+ The cleanup routines are called in the reverse order of their addition.
+
The function specified by \a ptr should take no arguments and should
return nothing. For example:
@@ -2584,8 +2648,11 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
Note that for an application- or module-wide cleanup,
qAddPostRoutine() is often not suitable. For example, if the
program is split into dynamically loaded modules, the relevant
- module may be unloaded long before the QApplication destructor is
- called.
+ module may be unloaded long before the QCoreApplication destructor is
+ called. In such cases, if using qAddPostRoutine() is still desirable,
+ qRemovePostRoutine() can be used to prevent a routine from being
+ called by the QCoreApplication destructor. For example, if that
+ routine was called before the module was unloaded.
For modules and libraries, using a reference-counted
initialization manager or Qt's parent-child deletion mechanism may
@@ -2597,6 +2664,21 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
By selecting the right parent object, this can often be made to
clean up the module's data at the right moment.
+
+ \sa qRemovePostRoutine()
+*/
+
+/*!
+ \fn void qRemovePostRoutine(QtCleanUpFunction ptr)
+ \relates QCoreApplication
+ \since 5.3
+
+ Removes the cleanup routine specified by \a ptr from the list of
+ routines called by the QCoreApplication destructor. The routine
+ must have been previously added to the list by a call to
+ qAddPostRoutine(), otherwise this function has no effect.
+
+ \sa qAddPostRoutine()
*/
/*!
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index ae17aeec0e..d8c52fbf1d 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -112,6 +112,9 @@ public:
static void setApplicationVersion(const QString &version);
static QString applicationVersion();
+ static void setSetuidAllowed(bool allow);
+ static bool isSetuidAllowed();
+
static QCoreApplication *instance() { return self; }
#ifndef QT_NO_QOBJECT
@@ -124,7 +127,9 @@ public:
static void postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority);
static void sendPostedEvents(QObject *receiver = 0, int event_type = 0);
static void removePostedEvents(QObject *receiver, int eventType = 0);
- static bool hasPendingEvents();
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED static bool hasPendingEvents();
+#endif
static QAbstractEventDispatcher *eventDispatcher();
static void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher);
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 0c00f396b5..c3d83112ae 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -153,6 +153,7 @@ public:
static bool is_app_closing;
#endif
+ static bool setuidAllowed;
static uint attribs;
static inline bool testAttribute(uint flag) { return attribs & (1 << flag); }
static int app_compile_version;
diff --git a/src/corelib/kernel/qcorecmdlineargs_p.h b/src/corelib/kernel/qcorecmdlineargs_p.h
index bbbee7df25..93c80205ab 100644
--- a/src/corelib/kernel/qcorecmdlineargs_p.h
+++ b/src/corelib/kernel/qcorecmdlineargs_p.h
@@ -154,7 +154,7 @@ static inline QStringList qCmdLineArgs(int argc, char *argv[])
static inline QStringList qCmdLineArgs(int argc, char *argv[])
{
QStringList args;
- for (int i = 0; i != argc; ++i)
+ for (int i = 0; i != argc; ++i)
args += QString::fromLocal8Bit(argv[i]);
return args;
}
diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h
index 933faff5a5..a2e7b6b33e 100644
--- a/src/corelib/kernel/qeventdispatcher_glib_p.h
+++ b/src/corelib/kernel/qeventdispatcher_glib_p.h
@@ -77,19 +77,19 @@ public:
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
- void registerSocketNotifier(QSocketNotifier *socketNotifier);
- void unregisterSocketNotifier(QSocketNotifier *socketNotifier);
+ void registerSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL;
+ void unregisterSocketNotifier(QSocketNotifier *socketNotifier) Q_DECL_FINAL;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL;
+ bool unregisterTimer(int timerId) Q_DECL_FINAL;
+ bool unregisterTimers(QObject *object) Q_DECL_FINAL;
+ QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL;
- int remainingTime(int timerId);
+ int remainingTime(int timerId) Q_DECL_FINAL;
- void wakeUp();
- void interrupt();
- void flush();
+ void wakeUp() Q_DECL_FINAL;
+ void interrupt() Q_DECL_FINAL;
+ void flush() Q_DECL_FINAL;
static bool versionSupported();
diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h
index 5d69d5e396..242aa9e695 100644
--- a/src/corelib/kernel/qeventdispatcher_unix_p.h
+++ b/src/corelib/kernel/qeventdispatcher_unix_p.h
@@ -94,6 +94,12 @@ public:
class QEventDispatcherUNIXPrivate;
+#ifdef Q_OS_QNX
+# define FINAL_EXCEPT_BLACKBERRY
+#else
+# define FINAL_EXCEPT_BLACKBERRY Q_DECL_FINAL
+#endif
+
class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher
{
Q_OBJECT
@@ -106,18 +112,18 @@ public:
bool processEvents(QEventLoop::ProcessEventsFlags flags);
bool hasPendingEvents();
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
+ void registerSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
+ void unregisterSocketNotifier(QSocketNotifier *notifier) FINAL_EXCEPT_BLACKBERRY;
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<TimerInfo> registeredTimers(QObject *object) const;
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object) Q_DECL_FINAL;
+ bool unregisterTimer(int timerId) Q_DECL_FINAL;
+ bool unregisterTimers(QObject *object) Q_DECL_FINAL;
+ QList<TimerInfo> registeredTimers(QObject *object) const Q_DECL_FINAL;
- int remainingTime(int timerId);
+ int remainingTime(int timerId) Q_DECL_FINAL;
- void wakeUp();
- void interrupt();
+ void wakeUp() FINAL_EXCEPT_BLACKBERRY;
+ void interrupt() Q_DECL_FINAL;
void flush();
protected:
@@ -130,7 +136,7 @@ protected:
virtual int select(int nfds,
fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
- timespec *timeout);
+ timespec *timeout) Q_DECL_FINAL;
};
class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate
@@ -142,8 +148,8 @@ public:
~QEventDispatcherUNIXPrivate();
int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout);
- virtual int initThreadWakeUp();
- virtual int processThreadWakeUp(int nsel);
+ virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY;
+ virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY;
bool mainThread;
@@ -165,6 +171,8 @@ public:
QAtomicInt interrupt; // bool
};
+#undef FINAL_EXCEPT_BLACKBERRY
+
QT_END_NAMESPACE
#endif // QEVENTDISPATCHER_UNIX_P_H
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
new file mode 100644
index 0000000000..56f4ac40de
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeventdispatcher_winrt_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QThread>
+#include <QtCore/QHash>
+#include <private/qabstracteventdispatcher_p.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.system.threading.h>
+#include <windows.ui.core.h>
+#include <windows.applicationmodel.core.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::System::Threading;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::ApplicationModel::Core;
+
+QT_BEGIN_NAMESPACE
+
+class QZeroTimerEvent : public QTimerEvent
+{
+public:
+ explicit inline QZeroTimerEvent(int timerId)
+ : QTimerEvent(timerId)
+ { t = QEvent::ZeroTimerEvent; }
+};
+
+struct WinRTTimerInfo // internal timer info
+{
+ WinRTTimerInfo() : timer(0) {}
+
+ int id;
+ int interval;
+ Qt::TimerType timerType;
+ quint64 timeout; // - when to actually fire
+ QObject *obj; // - object to receive events
+ bool inTimerEvent;
+ ComPtr<IThreadPoolTimer> timer;
+};
+
+class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate
+{
+ Q_DECLARE_PUBLIC(QEventDispatcherWinRT)
+
+public:
+ QEventDispatcherWinRTPrivate();
+ ~QEventDispatcherWinRTPrivate();
+
+ void registerTimer(WinRTTimerInfo *t);
+ void unregisterTimer(WinRTTimerInfo *t);
+ void sendTimerEvent(int timerId);
+
+private:
+ static HRESULT timerExpiredCallback(IThreadPoolTimer *timer);
+
+ QHash<int, WinRTTimerInfo*> timerDict;
+ QHash<IThreadPoolTimer *, int> timerIds;
+
+ ComPtr<IThreadPoolTimerStatics> timerFactory;
+ ComPtr<ICoreDispatcher> coreDispatcher;
+
+ bool interrupt;
+};
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
+ : QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
+{
+ Q_D(QEventDispatcherWinRT);
+ ComPtr<ICoreApplication> application;
+ HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application));
+ if (SUCCEEDED(hr)) {
+ ComPtr<ICoreApplicationView> view;
+ hr = application->GetCurrentView(&view);
+ if (SUCCEEDED(hr)) {
+ ComPtr<ICoreWindow> window;
+ hr = view->get_CoreWindow(&window);
+ if (SUCCEEDED(hr)) {
+ hr = window->get_Dispatcher(&d->coreDispatcher);
+ if (SUCCEEDED(hr))
+ return;
+ }
+ }
+ }
+ qCritical("QEventDispatcherWinRT: Unable to capture the core dispatcher. %s",
+ qPrintable(qt_error_string(hr)));
+}
+
+QEventDispatcherWinRT::QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent)
+ : QAbstractEventDispatcher(dd, parent)
+{ }
+
+QEventDispatcherWinRT::~QEventDispatcherWinRT()
+{
+}
+
+bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_D(QEventDispatcherWinRT);
+
+ bool didProcess = false;
+ forever {
+ // Process native events
+ if (d->coreDispatcher)
+ d->coreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
+
+ // Dispatch accumulated user events
+ didProcess = sendPostedEvents(flags);
+ if (didProcess)
+ break;
+
+ if (d->interrupt)
+ break;
+
+ // Short sleep if there is nothing to do
+ if (flags & QEventLoop::WaitForMoreEvents) {
+ emit aboutToBlock();
+ WaitForSingleObjectEx(GetCurrentThread(), 1, FALSE);
+ emit awake();
+ } else {
+ break;
+ }
+ }
+ d->interrupt = false;
+ return didProcess;
+}
+
+bool QEventDispatcherWinRT::sendPostedEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ Q_UNUSED(flags);
+ if (hasPendingEvents()) {
+ QCoreApplication::sendPostedEvents();
+ return true;
+ }
+ return false;
+}
+
+bool QEventDispatcherWinRT::hasPendingEvents()
+{
+ return qGlobalPostedEventsCount();
+}
+
+void QEventDispatcherWinRT::registerSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+void QEventDispatcherWinRT::unregisterSocketNotifier(QSocketNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+void QEventDispatcherWinRT::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
+{
+ Q_UNUSED(timerType);
+
+ if (timerId < 1 || interval < 0 || !object) {
+ qWarning("QEventDispatcherWinRT::registerTimer: invalid arguments");
+ return;
+ } else if (object->thread() != thread() || thread() != QThread::currentThread()) {
+ qWarning("QObject::startTimer: timers cannot be started from another thread");
+ return;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ WinRTTimerInfo *t = new WinRTTimerInfo();
+ t->id = timerId;
+ t->interval = interval;
+ t->timerType = timerType;
+ t->obj = object;
+ t->inTimerEvent = false;
+
+ d->registerTimer(t);
+ d->timerDict.insert(t->id, t);
+}
+
+bool QEventDispatcherWinRT::unregisterTimer(int timerId)
+{
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::unregisterTimer: invalid argument");
+ return false;
+ }
+ if (thread() != QThread::currentThread()) {
+ qWarning("QObject::killTimer: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+
+ WinRTTimerInfo *t = d->timerDict.value(timerId);
+ if (!t)
+ return false;
+
+ d->unregisterTimer(t);
+ return true;
+}
+
+bool QEventDispatcherWinRT::unregisterTimers(QObject *object)
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT::unregisterTimers: invalid argument");
+ return false;
+ }
+ QThread *currentThread = QThread::currentThread();
+ if (object->thread() != thread() || thread() != currentThread) {
+ qWarning("QObject::killTimers: timers cannot be stopped from another thread");
+ return false;
+ }
+
+ Q_D(QEventDispatcherWinRT);
+ foreach (WinRTTimerInfo *t, d->timerDict) {
+ if (t->obj == object)
+ d->unregisterTimer(t);
+ }
+ return true;
+}
+
+QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTimers(QObject *object) const
+{
+ if (!object) {
+ qWarning("QEventDispatcherWinRT:registeredTimers: invalid argument");
+ return QList<TimerInfo>();
+ }
+
+ Q_D(const QEventDispatcherWinRT);
+ QList<TimerInfo> list;
+ foreach (const WinRTTimerInfo *t, d->timerDict) {
+ if (t->obj == object)
+ list.append(TimerInfo(t->id, t->interval, t->timerType));
+ }
+ return list;
+}
+
+bool QEventDispatcherWinRT::registerEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+void QEventDispatcherWinRT::unregisterEventNotifier(QWinEventNotifier *notifier)
+{
+ Q_UNUSED(notifier);
+ Q_UNIMPLEMENTED();
+}
+
+int QEventDispatcherWinRT::remainingTime(int timerId)
+{
+#ifndef QT_NO_DEBUG
+ if (timerId < 1) {
+ qWarning("QEventDispatcherWinRT::remainingTime: invalid argument");
+ return -1;
+ }
+#endif
+
+ Q_D(QEventDispatcherWinRT);
+ if (WinRTTimerInfo *t = d->timerDict.value(timerId)) {
+ const quint64 currentTime = qt_msectime();
+ if (currentTime < t->timeout) {
+ // time to wait
+ return t->timeout - currentTime;
+ } else {
+ return 0;
+ }
+ }
+
+#ifndef QT_NO_DEBUG
+ qWarning("QEventDispatcherWinRT::remainingTime: timer id %d not found", timerId);
+#endif
+ return -1;
+}
+
+void QEventDispatcherWinRT::wakeUp()
+{
+}
+
+void QEventDispatcherWinRT::interrupt()
+{
+ Q_D(QEventDispatcherWinRT);
+ d->interrupt = true;
+}
+
+void QEventDispatcherWinRT::flush()
+{
+}
+
+void QEventDispatcherWinRT::startingUp()
+{
+}
+
+void QEventDispatcherWinRT::closingDown()
+{
+ Q_D(QEventDispatcherWinRT);
+ foreach (WinRTTimerInfo *t, d->timerDict)
+ d->unregisterTimer(t);
+ d->timerDict.clear();
+ d->timerIds.clear();
+}
+
+bool QEventDispatcherWinRT::event(QEvent *e)
+{
+ Q_D(QEventDispatcherWinRT);
+ if (e->type() == QEvent::ZeroTimerEvent) {
+ QZeroTimerEvent *zte = static_cast<QZeroTimerEvent*>(e);
+ WinRTTimerInfo *t = d->timerDict.value(zte->timerId());
+ if (t) {
+ t->inTimerEvent = true;
+
+ QTimerEvent te(zte->timerId());
+ QCoreApplication::sendEvent(t->obj, &te);
+
+ t = d->timerDict.value(zte->timerId());
+ if (t) {
+ if (t->interval == 0 && t->inTimerEvent) {
+ // post the next zero timer event as long as the timer was not restarted
+ QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId()));
+ }
+
+ t->inTimerEvent = false;
+ }
+ }
+ return true;
+ } else if (e->type() == QEvent::Timer) {
+ QTimerEvent *te = static_cast<QTimerEvent*>(e);
+ d->sendTimerEvent(te->timerId());
+ }
+ return QAbstractEventDispatcher::event(e);
+}
+
+QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate()
+ : interrupt(false)
+{
+ CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPoolTimer).Get(), &timerFactory);
+ if (FAILED(hr))
+ qWarning("QEventDispatcherWinRTPrivate::QEventDispatcherWinRTPrivate: Could not obtain timer factory: %lx", hr);
+}
+
+QEventDispatcherWinRTPrivate::~QEventDispatcherWinRTPrivate()
+{
+ CoUninitialize();
+}
+
+void QEventDispatcherWinRTPrivate::registerTimer(WinRTTimerInfo *t)
+{
+ Q_Q(QEventDispatcherWinRT);
+
+ bool ok = false;
+ uint interval = t->interval;
+ if (interval == 0u) {
+ // optimization for single-shot-zero-timer
+ QCoreApplication::postEvent(q, new QZeroTimerEvent(t->id));
+ ok = true;
+ } else {
+ TimeSpan period;
+ period.Duration = interval * 10000; // TimeSpan is based on 100-nanosecond units
+ ok = SUCCEEDED(timerFactory->CreatePeriodicTimer(
+ Callback<ITimerElapsedHandler>(&QEventDispatcherWinRTPrivate::timerExpiredCallback).Get(), period, &t->timer));
+ if (ok)
+ timerIds.insert(t->timer.Get(), t->id);
+ }
+ t->timeout = qt_msectime() + interval;
+ if (!ok)
+ qErrnoWarning("QEventDispatcherWinRT::registerTimer: Failed to create a timer");
+}
+
+void QEventDispatcherWinRTPrivate::unregisterTimer(WinRTTimerInfo *t)
+{
+ if (t->timer) {
+ timerIds.remove(t->timer.Get());
+ t->timer->Cancel();
+ }
+ timerDict.remove(t->id);
+ delete t;
+}
+
+void QEventDispatcherWinRTPrivate::sendTimerEvent(int timerId)
+{
+ WinRTTimerInfo *t = timerDict.value(timerId);
+ if (t && !t->inTimerEvent) {
+ // send event, but don't allow it to recurse
+ t->inTimerEvent = true;
+
+ QTimerEvent e(t->id);
+ QCoreApplication::sendEvent(t->obj, &e);
+
+ // timer could have been removed
+ t = timerDict.value(timerId);
+ if (t)
+ t->inTimerEvent = false;
+ }
+}
+
+HRESULT QEventDispatcherWinRTPrivate::timerExpiredCallback(IThreadPoolTimer *timer)
+{
+ QThread *thread = QThread::currentThread();
+ if (!thread)
+ return E_FAIL;
+
+ QAbstractEventDispatcher *eventDispatcher = thread->eventDispatcher();
+ if (!eventDispatcher)
+ return E_FAIL;
+
+ QEventDispatcherWinRTPrivate *d = static_cast<QEventDispatcherWinRTPrivate *>(get(eventDispatcher));
+ int timerId = d->timerIds.value(timer, -1);
+ if (timerId < 0)
+ return E_FAIL; // A callback was received after the timer was canceled
+
+ QCoreApplication::postEvent(eventDispatcher, new QTimerEvent(timerId));
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h
new file mode 100644
index 0000000000..5cc37fb538
--- /dev/null
+++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QEVENTDISPATCHER_WINRT_P_H
+#define QEVENTDISPATCHER_WINRT_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 "QtCore/qabstracteventdispatcher.h"
+
+#include <qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+int qt_msectime();
+
+class QEventDispatcherWinRTPrivate;
+
+class Q_CORE_EXPORT QEventDispatcherWinRT : public QAbstractEventDispatcher
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QEventDispatcherWinRT)
+
+public:
+ explicit QEventDispatcherWinRT(QObject *parent = 0);
+ ~QEventDispatcherWinRT();
+
+ bool processEvents(QEventLoop::ProcessEventsFlags flags);
+ bool hasPendingEvents();
+
+ void registerSocketNotifier(QSocketNotifier *notifier);
+ void unregisterSocketNotifier(QSocketNotifier *notifier);
+
+ void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
+ bool unregisterTimer(int timerId);
+ bool unregisterTimers(QObject *object);
+ QList<TimerInfo> registeredTimers(QObject *object) const;
+
+ int remainingTime(int timerId);
+
+ bool registerEventNotifier(QWinEventNotifier *notifier);
+ void unregisterEventNotifier(QWinEventNotifier *notifier);
+
+ void wakeUp();
+ void interrupt();
+ void flush();
+
+ void startingUp();
+ void closingDown();
+
+protected:
+ QEventDispatcherWinRT(QEventDispatcherWinRTPrivate &dd, QObject *parent = 0);
+
+ virtual bool sendPostedEvents(QEventLoop::ProcessEventsFlags flags);
+ bool event(QEvent *);
+ int activateTimers();
+};
+
+QT_END_NAMESPACE
+
+#endif // QEVENTDISPATCHER_WINRT_P_H
diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h
index 6e094f1ed3..e3014a0dcf 100644
--- a/src/corelib/kernel/qfunctions_p.h
+++ b/src/corelib/kernel/qfunctions_p.h
@@ -61,6 +61,8 @@
# include "QtCore/qfunctions_vxworks.h"
#elif defined(Q_OS_NACL)
# include "QtCore/qfunctions_nacl.h"
+#elif defined(Q_OS_WINRT)
+# include "QtCore/qfunctions_winrt.h"
#endif
#ifdef Q_CC_RVCT
diff --git a/src/corelib/kernel/qfunctions_winrt.cpp b/src/corelib/kernel/qfunctions_winrt.cpp
new file mode 100644
index 0000000000..1348af2acb
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifdef Q_OS_WINRT
+
+#include "qfunctions_winrt.h"
+#include "qstring.h"
+#include "qbytearray.h"
+#include "qhash.h"
+
+QT_USE_NAMESPACE
+
+// Environment ------------------------------------------------------
+inline QHash<QByteArray, QByteArray> &qt_app_environment()
+{
+ static QHash<QByteArray, QByteArray> internalEnvironment;
+ return internalEnvironment;
+}
+
+errno_t qt_winrt_getenv_s(size_t* sizeNeeded, char* buffer, size_t bufferSize, const char* varName)
+{
+ if (!sizeNeeded)
+ return EINVAL;
+
+ if (!qt_app_environment().contains(varName)) {
+ if (buffer)
+ buffer[0] = '\0';
+ return ENOENT;
+ }
+
+ QByteArray value = qt_app_environment().value(varName);
+ if (!value.endsWith('\0')) // win32 guarantees terminated string
+ value.append('\0');
+
+ if (bufferSize < (size_t)value.size()) {
+ *sizeNeeded = value.size();
+ return ERANGE;
+ }
+
+ strcpy(buffer, value.constData());
+ return 0;
+}
+
+errno_t qt_winrt__putenv_s(const char* varName, const char* value)
+{
+ QByteArray input = value;
+ if (input.isEmpty()) {
+ if (qt_app_environment().contains(varName))
+ qt_app_environment().remove(varName);
+ } else {
+ // win32 on winrt guarantees terminated string
+ if (!input.endsWith('\0'))
+ input.append('\0');
+ qt_app_environment()[varName] = input;
+ }
+
+ return 0;
+}
+
+void qt_winrt_tzset()
+{
+}
+
+void qt_winrt__tzset()
+{
+}
+
+#endif // Q_OS_WINRT
diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h
new file mode 100644
index 0000000000..fa2b2e12ff
--- /dev/null
+++ b/src/corelib/kernel/qfunctions_winrt.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QFUNCTIONS_WINRT_H
+#define QFUNCTIONS_WINRT_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_WINRT
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+#endif
+
+QT_END_NAMESPACE
+
+// Environment ------------------------------------------------------
+errno_t qt_winrt_getenv_s(size_t*, char*, size_t, const char*);
+errno_t qt_winrt__putenv_s(const char*, const char*);
+void qt_winrt_tzset();
+void qt_winrt__tzset();
+
+// As Windows Runtime lacks some standard functions used in Qt, these got
+// reimplemented. Other projects do this as well. Inline functions are used
+// that there is a central place to disable functions for newer versions if
+// they get available. There are no defines used anymore, because this
+// will break member functions of classes which are called like these
+// functions.
+// The other declarations available in this file are being used per
+// define inside qplatformdefs.h of the corresponding WinRT mkspec.
+
+#define generate_inline_return_func0(funcname, returntype) \
+ inline returntype funcname() \
+ { \
+ return qt_winrt_##funcname(); \
+ }
+#define generate_inline_return_func1(funcname, returntype, param1) \
+ inline returntype funcname(param1 p1) \
+ { \
+ return qt_winrt_##funcname(p1); \
+ }
+#define generate_inline_return_func2(funcname, returntype, param1, param2) \
+ inline returntype funcname(param1 p1, param2 p2) \
+ { \
+ return qt_winrt_##funcname(p1, p2); \
+ }
+#define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3); \
+ }
+#define generate_inline_return_func4(funcname, returntype, param1, param2, param3, param4) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4); \
+ }
+#define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5); \
+ }
+#define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6); \
+ }
+#define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \
+ inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \
+ { \
+ return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6, p7); \
+ }
+
+typedef unsigned (__stdcall *StartAdressExFunc)(void *);
+typedef void(*StartAdressFunc)(void *);
+typedef int ( __cdecl *CompareFunc ) (const void *, const void *) ;
+
+generate_inline_return_func4(getenv_s, errno_t, size_t *, char *, size_t, const char *)
+generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *)
+generate_inline_return_func0(tzset, void)
+generate_inline_return_func0(_tzset, void)
+
+#endif // Q_OS_WINRT
+#endif // QFUNCTIONS_WINRT_H
diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h
index ab98aec1bf..b1f0011b94 100644
--- a/src/corelib/kernel/qjni_p.h
+++ b/src/corelib/kernel/qjni_p.h
@@ -178,11 +178,13 @@ public:
jobject jobj = static_cast<jobject>(o);
if (!isSameObject(jobj)) {
d = QSharedPointer<QJNIObjectData>(new QJNIObjectData());
- QJNIEnvironmentPrivate env;
- d->m_jobject = env->NewGlobalRef(jobj);
- jclass objectClass = env->GetObjectClass(jobj);
- d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
- env->DeleteLocalRef(objectClass);
+ if (jobj) {
+ QJNIEnvironmentPrivate env;
+ d->m_jobject = env->NewGlobalRef(jobj);
+ jclass objectClass = env->GetObjectClass(jobj);
+ d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
+ env->DeleteLocalRef(objectClass);
+ }
}
return *this;
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index 74eb6f5b27..311ebaa092 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -40,6 +40,8 @@
****************************************************************************/
#include "qjnihelpers_p.h"
+#include "qmutex.h"
+#include "qlist.h"
QT_BEGIN_NAMESPACE
@@ -48,6 +50,39 @@ static jobject g_jActivity = Q_NULLPTR;
static jobject g_jClassLoader = Q_NULLPTR;
static jint g_androidSdkVersion = 0;
+namespace {
+ class ActivityResultListeners
+ {
+ public:
+ QMutex mutex;
+ QList<QtAndroidPrivate::ActivityResultListener *> listeners;
+ };
+}
+
+Q_GLOBAL_STATIC(ActivityResultListeners, g_activityResultListeners)
+
+void QtAndroidPrivate::registerActivityResultListener(ActivityResultListener *listener)
+{
+ QMutexLocker locker(&g_activityResultListeners()->mutex);
+ g_activityResultListeners()->listeners.append(listener);
+}
+
+void QtAndroidPrivate::unregisterActivityResultListener(ActivityResultListener *listener)
+{
+ QMutexLocker locker(&g_activityResultListeners()->mutex);
+ g_activityResultListeners()->listeners.removeAll(listener);
+}
+
+void QtAndroidPrivate::handleActivityResult(jint requestCode, jint resultCode, jobject data)
+{
+ QMutexLocker locker(&g_activityResultListeners()->mutex);
+ const QList<QtAndroidPrivate::ActivityResultListener *> &listeners = g_activityResultListeners()->listeners;
+ for (int i=0; i<listeners.size(); ++i) {
+ if (listeners.at(i)->handleActivityResult(requestCode, resultCode, data))
+ break;
+ }
+}
+
static inline bool exceptionCheck(JNIEnv *env)
{
if (env->ExceptionCheck()) {
diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h
index c92dbdde7f..6d0d65f489 100644
--- a/src/corelib/kernel/qjnihelpers_p.h
+++ b/src/corelib/kernel/qjnihelpers_p.h
@@ -60,11 +60,22 @@ QT_BEGIN_NAMESPACE
namespace QtAndroidPrivate
{
+ class Q_CORE_EXPORT ActivityResultListener
+ {
+ public:
+ virtual ~ActivityResultListener() {}
+ virtual bool handleActivityResult(jint requestCode, jint resultCode, jobject data) = 0;
+ };
+
Q_CORE_EXPORT jobject activity();
Q_CORE_EXPORT JavaVM *javaVM();
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
jobject classLoader();
- jint androidSdkVersion();
+ Q_CORE_EXPORT jint androidSdkVersion();
+
+ Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data);
+ Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener);
+ Q_CORE_EXPORT void unregisterActivityResultListener(ActivityResultListener *listener);
}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index 1e11887387..5be94429b4 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -942,7 +942,7 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co
return self;
if (self->d.relatedMetaObjects) {
Q_ASSERT(priv(self->d.data)->revision >= 2);
- const QMetaObject **e = self->d.relatedMetaObjects;
+ const QMetaObject * const *e = self->d.relatedMetaObjects;
if (e) {
while (*e) {
if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name))
@@ -2694,10 +2694,14 @@ int QMetaProperty::userType() const
if (type != QMetaType::UnknownType)
return type;
if (isEnumType()) {
- int enumMetaTypeId = QMetaType::type(qualifiedName(menum));
- if (enumMetaTypeId == QMetaType::UnknownType)
- return QVariant::Int; // Match behavior of QMetaType::type()
- return enumMetaTypeId;
+ type = QMetaType::type(qualifiedName(menum));
+ if (type == QMetaType::UnknownType) {
+ void *argv[] = { &type };
+ mobj->static_metacall(QMetaObject::RegisterPropertyMetaType, idx, argv);
+ if (type == -1 || type == QMetaType::UnknownType)
+ return QVariant::Int; // Match behavior of QMetaType::type()
+ }
+ return type;
}
type = QMetaType::type(typeName());
if (type != QMetaType::UnknownType)
diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp
index 11ab39af1a..09d8271413 100644
--- a/src/corelib/kernel/qmetaobjectbuilder.cpp
+++ b/src/corelib/kernel/qmetaobjectbuilder.cpp
@@ -741,7 +741,7 @@ void QMetaObjectBuilder::addMetaObject
if ((members & RelatedMetaObjects) != 0) {
Q_ASSERT(priv(prototype->d.data)->revision >= 2);
- const QMetaObject **objects = prototype->d.relatedMetaObjects;
+ const QMetaObject * const *objects = prototype->d.relatedMetaObjects;
if (objects) {
while (*objects != 0) {
addRelatedMetaObject(*objects);
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 4cbb618233..262d259136 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -491,6 +491,100 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
}
/*!
+ \class QSignalBlocker
+ \brief Exception-safe wrapper around QObject::blockSignals()
+ \since 5.3
+ \ingroup objectmodel
+
+ \reentrant
+
+ QSignalBlocker can be used whereever you would otherwise use a
+ pair of calls to blockSignals(). It blocks signals in its
+ constructor and in the destructor it resets the state to what
+ it was before the constructor ran.
+
+ \code
+ {
+ const QSignalBlocker blocker(someQObject);
+ // no signals here
+ }
+ \endcode
+ is thus equivalent to
+ \code
+ const bool wasBlocked = someQObject->blockSignals(true);
+ // no signals here
+ someQObject->blockSignals(false);
+ \endcode
+
+ except the code using QSignalBlocker is safe in the face of
+ exceptions.
+
+ \sa QMutexLocker, QEventLoopLocker
+*/
+
+/*!
+ \fn QSignalBlocker::QSignalBlocker(QObject *object)
+
+ Constructor. Calls \a{object}->blockSignals(true).
+*/
+
+/*!
+ \fn QSignalBlocker::QSignalBlocker(QObject &object)
+ \overload
+
+ Calls \a{object}.blockSignals(true).
+*/
+
+/*!
+ \fn QSignalBlocker::QSignalBlocker(QSignalBlocker &&other)
+
+ Move-constructs a signal blocker from \a other. \a other will have
+ a no-op destructor, while repsonsibility for restoring the
+ QObject::signalsBlocked() state is transferred to the new object.
+*/
+
+/*!
+ \fn QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other)
+
+ Move-assigns this signal blocker from \a other. \a other will have
+ a no-op destructor, while repsonsibility for restoring the
+ QObject::signalsBlocked() state is transferred to this object.
+
+ The object's signals this signal blocker was blocking prior to
+ being moved to, if any, are unblocked \em except in the case where
+ both instances block the same object's signals and \c *this is
+ unblocked while \a other is not, at the time of the move.
+*/
+
+/*!
+ \fn QSignalBlocker::~QSignalBlocker()
+
+ Destructor. Restores the QObject::signalsBlocked() state to what it
+ was before the constructor ran, unless unblock() has been called
+ without a following reblock(), in which case it does nothing.
+*/
+
+/*!
+ \fn void QSignalBlocker::reblock()
+
+ Re-blocks signals after a previous unblock().
+
+ The numbers of reblock() and unblock() calls are not counted, so
+ every reblock() undoes any number of unblock() calls.
+*/
+
+/*!
+ \fn void QSignalBlocker::unblock()
+
+ Temporarily restores the QObject::signalsBlocked() state to what
+ it was before this QSignaBlocker's constructor ran. To undo, use
+ reblock().
+
+ The numbers of reblock() and unblock() calls are not counted, so
+ every unblock() undoes any number of reblock() calls.
+*/
+
+/*!
\class QObject
\inmodule QtCore
\brief The QObject class is the base class of all Qt objects.
@@ -2235,11 +2329,19 @@ QObject *QObject::sender() const
int QObject::senderSignalIndex() const
{
Q_D(const QObject);
- int signal_index = d->senderSignalIndex();
- if (signal_index < 0)
- return signal_index;
- // Convert from signal range to method range
- return QMetaObjectPrivate::signal(sender()->metaObject(), signal_index).methodIndex();
+
+ QMutexLocker locker(signalSlotLock(this));
+ if (!d->currentSender)
+ return -1;
+
+ for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
+ if (c->sender == d->currentSender->sender) {
+ // Convert from signal range to method range
+ return QMetaObjectPrivate::signal(c->sender->metaObject(), d->currentSender->signal).methodIndex();
+ }
+ }
+
+ return -1;
}
/*!
@@ -3631,25 +3733,6 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
/*!
\internal
- Implementation of QObject::senderSignalIndex()
-*/
-int QObjectPrivate::senderSignalIndex() const
-{
- Q_Q(const QObject);
- QMutexLocker locker(signalSlotLock(q));
- if (!currentSender)
- return -1;
-
- for (QObjectPrivate::Connection *c = senders; c; c = c->next) {
- if (c->sender == currentSender->sender)
- return currentSender->signal;
- }
-
- return -1;
-}
-
-/*!
- \internal
Returns the signal index used in the internal connectionLists vector.
It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
@@ -3726,6 +3809,8 @@ bool QObject::setProperty(const char *name, const QVariant &value)
d->extraData->propertyNames.append(name);
d->extraData->propertyValues.append(value);
} else {
+ if (value == d->extraData->propertyValues.at(idx))
+ return false;
d->extraData->propertyValues[idx] = value;
}
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index c65d54e85a..ee6ef23139 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -549,6 +549,83 @@ template <class T> inline const char * qobject_interface_iid()
Q_CORE_EXPORT QDebug operator<<(QDebug, const QObject *);
#endif
+class Q_CORE_EXPORT QSignalBlocker
+{
+public:
+ inline explicit QSignalBlocker(QObject *o);
+ inline explicit QSignalBlocker(QObject &o);
+ inline ~QSignalBlocker();
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ inline QSignalBlocker(QSignalBlocker &&other);
+ inline QSignalBlocker &operator=(QSignalBlocker &&other);
+#endif
+
+ inline void reblock();
+ inline void unblock();
+private:
+ Q_DISABLE_COPY(QSignalBlocker)
+ QObject * m_o;
+ bool m_blocked;
+ bool m_inhibited;
+};
+
+QSignalBlocker::QSignalBlocker(QObject *o)
+ : m_o(o),
+ m_blocked(o && o->blockSignals(true)),
+ m_inhibited(false)
+{}
+
+QSignalBlocker::QSignalBlocker(QObject &o)
+ : m_o(&o),
+ m_blocked(o.blockSignals(true)),
+ m_inhibited(false)
+{}
+
+#ifdef Q_COMPILER_RVALUE_REFS
+QSignalBlocker::QSignalBlocker(QSignalBlocker &&other)
+ : m_o(other.m_o),
+ m_blocked(other.m_blocked),
+ m_inhibited(other.m_inhibited)
+{
+ other.m_o = 0;
+}
+
+QSignalBlocker &QSignalBlocker::operator=(QSignalBlocker &&other)
+{
+ if (this != &other) {
+ // if both *this and other block the same object's signals:
+ // unblock *this iff our dtor would unblock, but other's wouldn't
+ if (m_o != other.m_o || (!m_inhibited && other.m_inhibited))
+ unblock();
+ m_o = other.m_o;
+ m_blocked = other.m_blocked;
+ m_inhibited = other.m_inhibited;
+ // disable other:
+ other.m_o = 0;
+ }
+ return *this;
+}
+#endif
+
+QSignalBlocker::~QSignalBlocker()
+{
+ if (m_o && !m_inhibited)
+ m_o->blockSignals(m_blocked);
+}
+
+void QSignalBlocker::reblock()
+{
+ if (m_o) m_o->blockSignals(true);
+ m_inhibited = false;
+}
+
+void QSignalBlocker::unblock()
+{
+ if (m_o) m_o->blockSignals(m_blocked);
+ m_inhibited = true;
+}
+
namespace QtPrivate {
inline QObject & deref_for_methodcall(QObject &o) { return o; }
inline QObject & deref_for_methodcall(QObject *o) { return *o; }
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 8cbb244451..180887b370 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -199,7 +199,6 @@ public:
return o->d_func();
}
- int senderSignalIndex() const;
int signalIndex(const char *signalName, const QMetaObject **meta = 0) const;
inline bool isSignalConnected(uint signalIdx) const;
@@ -339,7 +338,7 @@ inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate:
types = QtPrivate::ConnectionTypes<typename SignalType::Arguments>::types();
return QObject::connectImpl(sender, reinterpret_cast<void **>(&signal),
- receiverPrivate->q_func(), reinterpret_cast<void **>(&slot),
+ receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
new QtPrivate::QPrivateSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);
@@ -357,7 +356,7 @@ bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1
Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments<typename SignalType::Arguments, typename SlotType::Arguments>::value),
"Signal and slot arguments are not compatible.");
return QObject::disconnectImpl(sender, reinterpret_cast<void **>(&signal),
- receiverPrivate->q_func(), reinterpret_cast<void **>(&slot),
+ receiverPrivate->q_ptr, reinterpret_cast<void **>(&slot),
&SignalType::Object::staticMetaObject);
}
diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h
index 7354c3f0d0..fe107f1425 100644
--- a/src/corelib/kernel/qobjectdefs.h
+++ b/src/corelib/kernel/qobjectdefs.h
@@ -42,6 +42,10 @@
#ifndef QOBJECTDEFS_H
#define QOBJECTDEFS_H
+#if defined(__OBJC__) && !defined(__cplusplus)
+# warning "File built in Objective-C mode (.m), but using Qt requires Objective-C++ (.mm)"
+#endif
+
#include <QtCore/qnamespace.h>
#include <QtCore/qobjectdefs_impl.h>
@@ -447,7 +451,7 @@ struct Q_CORE_EXPORT QMetaObject
const uint *data;
typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
StaticMetacallFunction static_metacall;
- const QMetaObject **relatedMetaObjects;
+ const QMetaObject * const *relatedMetaObjects;
void *extradata; //reserved for future use
} d;
};
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index fb6601f21b..de6f65ab7d 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -567,9 +567,9 @@ namespace QtPrivate {
Q_STATIC_ASSERT(CheckCompatibleArguments<FunctionPointer<Signal>::Arguments, FunctionPointer<Slot>::Arguments>::value)
*/
template<typename A1, typename A2> struct AreArgumentsCompatible {
- static int test(A2);
+ static int test(const typename RemoveRef<A2>::Type&);
static char test(...);
- static A1 dummy();
+ static const typename RemoveRef<A1>::Type &dummy();
enum { value = sizeof(test(dummy())) == sizeof(int) };
};
template<typename A1, typename A2> struct AreArgumentsCompatible<A1, A2&> { enum { value = false }; };
diff --git a/src/corelib/kernel/qppsattribute.cpp b/src/corelib/kernel/qppsattribute.cpp
new file mode 100644
index 0000000000..f6745d2354
--- /dev/null
+++ b/src/corelib/kernel/qppsattribute.cpp
@@ -0,0 +1,308 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include "qppsattribute_p.h"
+#include "qppsattributeprivate_p.h"
+
+#include <QDebug>
+#include <QVariant>
+
+///////////////////////////
+//
+// QPpsAttributePrivate
+//
+///////////////////////////
+
+QPpsAttributePrivate::QPpsAttributePrivate() : type(QPpsAttribute::None)
+{
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(int value, QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Number;
+ attribute.d->data = value;
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(long long value, QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Number;
+ attribute.d->data = value;
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(double value, QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Number;
+ attribute.d->data = value;
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(bool value, QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Bool;
+ attribute.d->data = value;
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(const QString &value,
+ QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::String;
+ attribute.d->data = value;
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(const QPpsAttributeList &value,
+ QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Array;
+ attribute.d->data = QVariant::fromValue(value);
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+QPpsAttribute QPpsAttributePrivate::createPpsAttribute(const QPpsAttributeMap &value,
+ QPpsAttribute::Flags flags)
+{
+ QPpsAttribute attribute;
+ attribute.d->type = QPpsAttribute::Object;
+ attribute.d->data = QVariant::fromValue(value);
+ attribute.d->flags = flags;
+ return attribute;
+}
+
+///////////////////////////
+//
+// QPpsAttribute
+//
+///////////////////////////
+
+QPpsAttribute::QPpsAttribute():
+ d(new QPpsAttributePrivate())
+{
+}
+
+QPpsAttribute::~QPpsAttribute()
+{
+}
+
+QPpsAttribute::QPpsAttribute(const QPpsAttribute &other): d(other.d)
+{
+}
+
+QPpsAttribute &QPpsAttribute::operator=(const QPpsAttribute &other)
+{
+ d = other.d;
+ return *this;
+}
+
+#ifdef Q_COMPILER_RVALUE_REFS
+QPpsAttribute::QPpsAttribute(QPpsAttribute &&other): d(other.d)
+{
+ other.d->type = QPpsAttribute::None;
+}
+
+QPpsAttribute &QPpsAttribute::operator=(QPpsAttribute &&other)
+{
+ qSwap(d, other.d);
+ return *this;
+}
+#endif
+
+bool QPpsAttribute::operator==(const QPpsAttribute &other) const
+{
+ if (type() != other.type())
+ return false;
+ if (flags() != other.flags())
+ return false;
+
+ switch (type()) {
+ case QPpsAttribute::Number:
+ case QPpsAttribute::Bool:
+ case QPpsAttribute::String:
+ // QVariant can compare double, int, longlong, bool, and QString for us.
+ return d->data == other.d->data;
+ case QPpsAttribute::Array:
+ // QVariant can't compare custom types (like QPpsAttributeList), always returning false.
+ // So we pull the lists out manually and compare them.
+ return toList() == other.toList();
+ case QPpsAttribute::Object:
+ // QVariant can't compare custom types (like QPpsAttributeMap), always returning false.
+ // So we pull the maps out manually and compare them.
+ return toMap() == other.toMap();
+ case QPpsAttribute::None:
+ // Both are "None" type, so the actual content doesn't matter.
+ return true;
+ }
+ return d->data == other.d->data;
+}
+
+bool QPpsAttribute::isValid() const
+{
+ return d->type != QPpsAttribute::None;
+}
+
+QPpsAttribute::Type QPpsAttribute::type() const
+{
+ return d->type;
+}
+
+bool QPpsAttribute::isNumber() const
+{
+ return type() == QPpsAttribute::Number;
+}
+
+bool QPpsAttribute::isBool() const
+{
+ return type() == QPpsAttribute::Bool;
+}
+
+bool QPpsAttribute::isString() const
+{
+ return type() == QPpsAttribute::String;
+}
+
+bool QPpsAttribute::isArray() const
+{
+ return type() == QPpsAttribute::Array;
+}
+
+bool QPpsAttribute::isObject() const
+{
+ return type() == QPpsAttribute::Object;
+}
+
+double QPpsAttribute::toDouble() const
+{
+ return d->data.toDouble();
+}
+
+qlonglong QPpsAttribute::toLongLong() const
+{
+ return d->data.toLongLong();
+}
+
+int QPpsAttribute::toInt() const
+{
+ return d->data.toInt();
+}
+
+bool QPpsAttribute::toBool() const
+{
+ return d->data.toBool();
+}
+
+QString QPpsAttribute::toString() const
+{
+ return d->data.toString();
+}
+
+QPpsAttributeList QPpsAttribute::toList() const
+{
+ return d->data.value< QPpsAttributeList >();
+}
+
+QPpsAttributeMap QPpsAttribute::toMap() const
+{
+ return d->data.value< QPpsAttributeMap >();
+}
+
+QPpsAttribute::Flags QPpsAttribute::flags() const
+{
+ return d->flags;
+}
+
+QVariant QPpsAttribute::toVariant() const
+{
+ return d->data;
+}
+
+QDebug operator<<(QDebug dbg, const QPpsAttribute &attribute)
+{
+ dbg << "QPpsAttribute(";
+
+ switch (attribute.type()) {
+ case QPpsAttribute::Number:
+ switch (attribute.toVariant().type()) {
+ case QVariant::Int:
+ dbg << "Number, " << attribute.flags() << ", " << attribute.toInt();
+ break;
+ case QVariant::LongLong:
+ dbg << "Number, " << attribute.flags() << ", " << attribute.toLongLong();
+ break;
+ default:
+ dbg << "Number, " << attribute.flags() << ", " << attribute.toDouble();
+ break;
+ }
+ break;
+ case QPpsAttribute::Bool:
+ dbg << "Bool, " << attribute.flags() << ", " << attribute.toBool();
+ break;
+ case QPpsAttribute::String:
+ dbg << "String, " << attribute.flags() << ", " << attribute.toString();
+ break;
+ case QPpsAttribute::Array:
+ dbg << "Array, " << attribute.flags() << ", " << attribute.toList();
+ break;
+ case QPpsAttribute::Object:
+ dbg << "Object, " << attribute.flags() << ", " << attribute.toMap();
+ break;
+ case QPpsAttribute::None:
+ dbg << "None";
+ break;
+ }
+
+ dbg << ')';
+
+ return dbg;
+}
diff --git a/src/corelib/kernel/qppsattribute_p.h b/src/corelib/kernel/qppsattribute_p.h
new file mode 100644
index 0000000000..03a0f98a17
--- /dev/null
+++ b/src/corelib/kernel/qppsattribute_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QPPSATTRIBUTE_P_H
+#define QPPSATTRIBUTE_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 <QList>
+#include <QMap>
+#include <QSharedDataPointer>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QPpsAttributePrivate;
+class QPpsAttribute;
+
+typedef QList<QPpsAttribute> QPpsAttributeList;
+typedef QMap<QString, QPpsAttribute> QPpsAttributeMap;
+Q_DECLARE_METATYPE(QPpsAttributeList)
+Q_DECLARE_METATYPE(QPpsAttributeMap)
+
+class Q_CORE_EXPORT QPpsAttribute
+{
+public:
+
+ enum Type {
+ None = 0,
+ Number = 1,
+ Bool = 2,
+ String = 3,
+ Array = 4,
+ Object = 5
+ };
+
+ enum Flag {
+ Incomplete = 0x01,
+ Deleted = 0x02,
+ Created = 0x04,
+ Truncated = 0x08,
+ Purged = 0x10
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ QPpsAttribute();
+ QPpsAttribute(const QPpsAttribute &other);
+ ~QPpsAttribute();
+
+ QPpsAttribute &operator=(const QPpsAttribute &other);
+ bool operator==(const QPpsAttribute &other) const;
+ bool operator!=(const QPpsAttribute &other) const;
+
+#ifdef Q_COMPILER_RVALUE_REFS
+ QPpsAttribute(QPpsAttribute &&other);
+ QPpsAttribute &operator=(QPpsAttribute &&other);
+#endif
+
+ bool isValid() const;
+ Type type() const;
+ QPpsAttribute::Flags flags() const;
+
+ bool isNumber() const;
+ bool isBool() const;
+ bool isString() const;
+ bool isArray() const;
+ bool isObject() const;
+
+ double toDouble() const;
+ qlonglong toLongLong() const;
+ int toInt() const;
+ bool toBool() const;
+ QString toString() const;
+ QPpsAttributeList toList() const;
+ QPpsAttributeMap toMap() const;
+ QVariant toVariant() const;
+
+private:
+ QSharedDataPointer<QPpsAttributePrivate> d;
+ friend class QPpsAttributePrivate;
+};
+
+inline bool QPpsAttribute::operator!=(const QPpsAttribute &other) const
+{
+ return !(*this == other);
+}
+
+Q_CORE_EXPORT QDebug operator<<(QDebug dbg, const QPpsAttribute &attribute);
+
+QT_END_NAMESPACE
+
+#endif // QPPSATTRIBUTE_P_H
diff --git a/src/corelib/kernel/qppsattributeprivate_p.h b/src/corelib/kernel/qppsattributeprivate_p.h
new file mode 100644
index 0000000000..0aa29d0895
--- /dev/null
+++ b/src/corelib/kernel/qppsattributeprivate_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QPPSATTRIBUTEPRIVATE_P_H
+#define QPPSATTRIBUTEPRIVATE_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 "qppsattribute_p.h"
+
+#include <QList>
+#include <QMap>
+#include <QSharedData>
+#include <QString>
+#include <QVariant>
+
+QT_BEGIN_NAMESPACE
+
+class QPpsAttributePrivate : public QSharedData
+{
+public:
+ QPpsAttributePrivate();
+
+ static QPpsAttribute createPpsAttribute(double value, QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(long long value, QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(int value, QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(bool value, QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(const QString &value, QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(const QPpsAttributeList &value,
+ QPpsAttribute::Flags flags);
+ static QPpsAttribute createPpsAttribute(const QPpsAttributeMap &value,
+ QPpsAttribute::Flags flags);
+
+private:
+ friend class QPpsAttribute;
+
+ QVariant data;
+ QPpsAttribute::Type type;
+ QPpsAttribute::Flags flags;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPPSATTRIBUTEPRIVATE_P_H
diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp
new file mode 100644
index 0000000000..eb8e69baff
--- /dev/null
+++ b/src/corelib/kernel/qppsobject.cpp
@@ -0,0 +1,964 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+
+#include "qppsobject_p.h"
+
+#include "qppsobjectprivate_p.h"
+#include "qppsattribute_p.h"
+#include "qppsattributeprivate_p.h"
+#include "qcore_unix_p.h"
+
+#include <QObject>
+#include <QSocketNotifier>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <confname.h>
+
+#include <sys/pps.h>
+
+///////////////////////////////////////////////////////////////////////////////
+static inline void safeAssign(bool *pointer, bool value)
+{
+ if (pointer)
+ *pointer = value;
+}
+
+class QPpsMaxSize
+{
+public:
+ QPpsMaxSize()
+ {
+ int fd = qt_safe_open("/pps/.all", O_RDONLY);
+ if (fd == -1) {
+ qWarning() << "qppsobject.cpp: qt_safe_open failed";
+ value = -1;
+ }
+
+ // This tells us the maximum transfer size across PPS
+ value = ::fpathconf(fd, _PC_REC_MAX_XFER_SIZE);
+
+ qt_safe_close(fd);
+ }
+
+ int value;
+};
+
+Q_GLOBAL_STATIC(QPpsMaxSize, ppsMaxSize)
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// QPpsObjectPrivate
+//
+///////////////////////////////////////////////////////////////////////////////
+
+QPpsObjectPrivate::QPpsObjectPrivate(const QString &path) :
+ notifier(0),
+ path(path),
+ error(EOK),
+ fd(-1),
+ readyReadEnabled(true)
+{
+}
+
+QPpsAttributeMap QPpsObjectPrivate::decode(const QByteArray &rawData, bool *ok)
+{
+ QPpsAttributeMap attributeMap;
+ pps_decoder_t decoder;
+
+ QByteArray mutableData(rawData);
+ pps_decoder_error_t error = pps_decoder_initialize(&decoder, mutableData.data());
+ if (error == PPS_DECODER_OK) {
+ // no need to check ok in this case
+ attributeMap = decodeObject(&decoder, ok);
+ } else {
+ qWarning() << "QPpsObjectPrivate::decode: pps_decoder_initialize failed";
+ *ok = false;
+ }
+
+ pps_decoder_cleanup(&decoder);
+ return attributeMap;
+}
+
+QVariantMap QPpsObjectPrivate::variantMapFromPpsAttributeMap(const QPpsAttributeMap &data)
+{
+ QVariantMap variantMap;
+
+ for (QPpsAttributeMap::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
+ QVariant variant = variantFromPpsAttribute(it.value());
+ if (!variant.isValid())
+ return QVariantMap();
+ variantMap[it.key()] = variant;
+ }
+
+ return variantMap;
+}
+
+QPpsAttribute::Flags QPpsObjectPrivate::readFlags(pps_decoder_t *decoder)
+{
+ int rawFlags = pps_decoder_flags(decoder, 0);
+
+ QPpsAttribute::Flags attributeFlags;
+
+ if (rawFlags & PPS_INCOMPLETE)
+ attributeFlags |= QPpsAttribute::Incomplete;
+ if (rawFlags & PPS_DELETED)
+ attributeFlags |= QPpsAttribute::Deleted;
+ if (rawFlags & PPS_CREATED)
+ attributeFlags |= QPpsAttribute::Created;
+ if (rawFlags & PPS_TRUNCATED)
+ attributeFlags |= QPpsAttribute::Truncated;
+ if (rawFlags & PPS_PURGED)
+ attributeFlags |= QPpsAttribute::Purged;
+
+ return attributeFlags;
+}
+
+QPpsAttribute QPpsObjectPrivate::decodeString(pps_decoder_t *decoder)
+{
+ const char *value = 0;
+ pps_decoder_error_t error = pps_decoder_get_string(decoder, 0, &value);
+
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeString: PPS_DECODER_GET_STRING failed";
+ return QPpsAttribute();
+ }
+
+ QPpsAttribute::Flags flags = readFlags(decoder);
+ return QPpsAttributePrivate::createPpsAttribute(QString::fromUtf8(value), flags);
+}
+
+QPpsAttribute QPpsObjectPrivate::decodeNumber(pps_decoder_t *decoder)
+{
+ // In order to support more number types, we have to do something stupid because the PPS
+ // library won't let us work any other way. Basically, we have to probe the encoded type in
+ // order to try to get exactly what we want.
+ long long llValue;
+ double dValue;
+ int iValue;
+ QPpsAttribute::Flags flags;
+
+ if (pps_decoder_is_integer(decoder, 0)) {
+ pps_decoder_error_t error = pps_decoder_get_int(decoder, 0, &iValue);
+ switch (error) {
+ case PPS_DECODER_OK:
+ flags = readFlags(decoder);
+ return QPpsAttributePrivate::createPpsAttribute(iValue, flags);
+ case PPS_DECODER_CONVERSION_FAILED:
+ error = pps_decoder_get_int64(decoder, 0, &llValue);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeNumber: failed to decode integer";
+ return QPpsAttribute();
+ }
+ flags = readFlags(decoder);
+ return QPpsAttributePrivate::createPpsAttribute(llValue, flags);
+ default:
+ qWarning() << "QPpsObjectPrivate::decodeNumber: pps_decoder_get_int failed";
+ return QPpsAttribute();
+ }
+ } else {
+ pps_decoder_error_t error = pps_decoder_get_double(decoder, 0, &dValue);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeNumber: pps_decoder_get_double failed";
+ return QPpsAttribute();
+ }
+ flags = readFlags(decoder);
+ return QPpsAttributePrivate::createPpsAttribute(dValue, flags);
+ }
+}
+
+QPpsAttribute QPpsObjectPrivate::decodeBool(pps_decoder_t *decoder)
+{
+ bool value;
+ pps_decoder_error_t error = pps_decoder_get_bool(decoder, 0, &value);
+
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeBool: pps_decoder_get_bool failed";
+ return QPpsAttribute();
+ }
+
+ QPpsAttribute::Flags flags = readFlags(decoder);
+ return QPpsAttributePrivate::createPpsAttribute(value, flags);
+}
+
+template<typename T>
+QPpsAttribute QPpsObjectPrivate::decodeNestedData(T (*decodeFunction)(pps_decoder_t *, bool *),
+ pps_decoder_t *decoder)
+{
+ // We must read the flags before we push into the object,
+ // otherwise we'll get the flags for the first element in the object.
+ QPpsAttribute::Flags flags = readFlags(decoder);
+
+ if (!decoderPush(decoder))
+ return QPpsAttribute();
+
+ bool ok = false;
+
+ T attributeContainer = decodeFunction(decoder, &ok);
+
+ if (!ok)
+ return QPpsAttribute();
+
+ QPpsAttribute returnVal = QPpsAttributePrivate::createPpsAttribute(attributeContainer, flags);
+
+ if (!decoderPop(decoder))
+ return QPpsAttribute();
+
+ return returnVal;
+}
+
+QPpsAttribute QPpsObjectPrivate::decodeData(pps_decoder_t *decoder)
+{
+ pps_node_type_t nodeType = pps_decoder_type(decoder, 0);
+ switch (nodeType) {
+ case PPS_TYPE_BOOL:
+ return decodeBool(decoder);
+ case PPS_TYPE_NUMBER:
+ return decodeNumber(decoder);
+ case PPS_TYPE_STRING:
+ return decodeString(decoder);
+ case PPS_TYPE_ARRAY:
+ return decodeNestedData(&QPpsObjectPrivate::decodeArray, decoder);
+ case PPS_TYPE_OBJECT:
+ return decodeNestedData(&QPpsObjectPrivate::decodeObject, decoder);
+ case PPS_TYPE_DELETED: {
+ // This should create an attribute with the flags set to PpsAttribute::Deleted.
+ // However, we need to create a valid QPpsAttribute while doing so. To do this,
+ // I'll create an empty map as a sentinel. Note that the readFlags() call with produce
+ // the correct set of flags. While I suspect that there will never be any other flags
+ // set in conjunction with this one, I'd rather not be surprised later.
+ QPpsAttributeMap emptyMap;
+ QPpsAttribute::Flags flags = readFlags(decoder);
+ QPpsAttribute returnVal = QPpsAttributePrivate::createPpsAttribute(emptyMap, flags);
+ return returnVal;
+ }
+ case PPS_TYPE_NULL:
+ case PPS_TYPE_NONE:
+ case PPS_TYPE_UNKNOWN:
+ default:
+ qWarning() << "QPpsObjectPrivate::decodeData: invalid pps_node_type";
+ return QPpsAttribute();
+ }
+}
+
+QPpsAttributeList QPpsObjectPrivate::decodeArray(pps_decoder_t *decoder, bool *ok)
+{
+ QPpsAttributeList list;
+
+ int length = pps_decoder_length(decoder);
+ for (int i = 0; i < length; ++i) {
+ // Force movement to a specific index.
+ pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeArray: pps_decoder_goto_index failed";
+ *ok = false;
+ return QPpsAttributeList();
+ }
+
+ QPpsAttribute ppsAttribute = decodeData(decoder);
+ if (!ppsAttribute.isValid()) {
+ *ok = false;
+ return QPpsAttributeList();
+ }
+
+ list << ppsAttribute;
+ }
+
+ *ok = true;
+ return list;
+}
+
+QPpsAttributeMap QPpsObjectPrivate::decodeObject(pps_decoder_t *decoder, bool *ok)
+{
+ QPpsAttributeMap map;
+
+ int length = pps_decoder_length(decoder);
+ for (int i = 0; i < length; ++i) {
+ // Force movement to a specific index.
+ pps_decoder_error_t error = pps_decoder_goto_index(decoder, i);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeObject: pps_decoder_goto_index failed";
+ *ok = false;
+ return QPpsAttributeMap();
+ }
+ QString name = QString::fromUtf8(pps_decoder_name(decoder));
+ QPpsAttribute ppsAttribute = decodeData(decoder);
+ if (!ppsAttribute.isValid()) {
+ *ok = false;
+ return QPpsAttributeMap();
+ }
+ map[name] = ppsAttribute;
+ }
+
+ *ok = true;
+ return map;
+}
+
+QVariant QPpsObjectPrivate::variantFromPpsAttribute(const QPpsAttribute &attribute)
+{
+ switch (attribute.type()) {
+ case QPpsAttribute::Number:
+ switch (attribute.toVariant().type()) {
+ case QVariant::Int:
+ return attribute.toInt();
+ case QVariant::LongLong:
+ return attribute.toLongLong();
+ default:
+ return attribute.toDouble();
+ }
+ break;
+ case QPpsAttribute::Bool:
+ return attribute.toBool();
+ case QPpsAttribute::String:
+ return attribute.toString();
+ case QPpsAttribute::Array: {
+ QVariantList variantList;
+ Q_FOREACH (const QPpsAttribute &attr, attribute.toList()) {
+ QVariant variant = variantFromPpsAttribute(attr);
+ if (!variant.isValid())
+ return QVariantList();
+ variantList << variant;
+ }
+ return variantList;
+ }
+ case QPpsAttribute::Object:
+ return variantMapFromPpsAttributeMap(attribute.toMap());
+ case QPpsAttribute::None:
+ default:
+ qWarning() << "QPpsObjectPrivate::variantFromPpsAttribute: invalid attribute parameter";
+ return QVariant();
+ }
+}
+
+QByteArray QPpsObjectPrivate::encode(const QVariantMap &ppsData, bool *ok)
+{
+ pps_encoder_t encoder;
+ pps_encoder_initialize(&encoder, false);
+
+ encodeObject(&encoder, ppsData, ok);
+ const char *rawData = 0;
+ if (*ok) {
+ // rawData points to a memory owned by encoder.
+ // The memory will be freed when pps_encoder_cleanup is called.
+ rawData = pps_encoder_buffer(&encoder);
+ if (!rawData) {
+ qWarning() << "QPpsObjectPrivate::encode: pps_encoder_buffer failed";
+ *ok = false;
+ }
+ }
+
+ pps_encoder_cleanup(&encoder);
+ return QByteArray(rawData);
+}
+
+void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, const QVariant &data,
+ bool *ok)
+{
+ QString errorFunction;
+ pps_encoder_error_t error = PPS_ENCODER_OK;
+ switch (data.type()) {
+ case QVariant::Bool:
+ error = pps_encoder_add_bool(encoder, name, data.toBool());
+ errorFunction = QStringLiteral("pps_encoder_add_bool");
+ break;
+ // We want to support encoding uint even though libpps doesn't support it directly.
+ // We can't encode uint as an int since that will lose precision (e.g. 2^31+1 can't be
+ // encoded that way). However, we can convert uint to double without losing precision.
+ // QVariant.toDouble() conveniently takes care of the conversion for us.
+ case QVariant::UInt:
+ case QVariant::Double:
+ error = pps_encoder_add_double(encoder, name, data.toDouble());
+ errorFunction = QStringLiteral("pps_encoder_add_double");
+ break;
+ case QVariant::Int:
+ error = pps_encoder_add_int(encoder, name, data.toInt());
+ errorFunction = QStringLiteral("pps_encoder_add_int");
+ break;
+ case QVariant::LongLong:
+ error = pps_encoder_add_int64(encoder, name, data.toLongLong());
+ errorFunction = QStringLiteral("pps_encoder_add_int64");
+ break;
+ case QVariant::String:
+ error = pps_encoder_add_string(encoder, name, data.toString().toUtf8().constData());
+ errorFunction = QStringLiteral("pps_encoder_add_string");
+ break;
+ case QVariant::List:
+ error = pps_encoder_start_array(encoder, name);
+ errorFunction = QStringLiteral("pps_encoder_start_array");
+ if (error == PPS_ENCODER_OK) {
+ encodeArray(encoder, data.toList(), ok);
+ error = pps_encoder_end_array(encoder);
+ errorFunction = QStringLiteral("pps_encoder_end_array");
+ }
+ break;
+ case QVariant::Map:
+ error = pps_encoder_start_object(encoder, name);
+ errorFunction = QStringLiteral("pps_encoder_start_object");
+ if (error == PPS_ENCODER_OK) {
+ encodeObject(encoder, data.toMap(), ok);
+ error = pps_encoder_end_object(encoder);
+ errorFunction = QStringLiteral("pps_encoder_end_object");
+ }
+ break;
+ case QVariant::Invalid:
+ error = pps_encoder_add_null(encoder, name);
+ errorFunction = QStringLiteral("pps_encoder_add_null");
+ break;
+ default:
+ qWarning() << "QPpsObjectPrivate::encodeData: the type of the parameter data is invalid";
+ *ok = false;
+ return;
+ }
+
+ if (error != PPS_ENCODER_OK) {
+ qWarning() << "QPpsObjectPrivate::encodeData: " << errorFunction << " failed";
+ *ok = false;
+ } else {
+ *ok = true;
+ }
+}
+
+void QPpsObjectPrivate::encodeArray(pps_encoder_t *encoder, const QVariantList &data, bool *ok)
+{
+ for (QVariantList::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
+ encodeData(encoder, 0, *it, ok);
+ if (!(*ok))
+ return;
+ }
+ // if the passed data is empty, nothing went wrong and ok is set to true
+ *ok = true;
+}
+
+void QPpsObjectPrivate::encodeObject(pps_encoder_t *encoder, const QVariantMap &data, bool *ok)
+{
+ for (QVariantMap::const_iterator it = data.constBegin(); it != data.constEnd(); ++it) {
+ encodeData(encoder, it.key().toUtf8().constData(), it.value(), ok);
+ if (!(*ok))
+ return;
+ }
+ // if the passed data is empty, nothing went wrong and ok is set to true
+ *ok = true;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// QPpsObjectPrivate
+//
+///////////////////////////////////////////////////////////////////////////////
+
+QPpsObject::QPpsObject(const QString &path, QObject *parent) :
+ QObject(parent),
+ d_ptr(new QPpsObjectPrivate(path))
+{
+}
+
+QPpsObject::~QPpsObject()
+{
+ // RAII - ensure file gets closed
+ if (isOpen())
+ close();
+}
+
+int QPpsObject::error() const
+{
+ Q_D(const QPpsObject);
+ return d->error;
+}
+
+QString QPpsObject::errorString() const
+{
+ Q_D(const QPpsObject);
+ return qt_error_string(d->error);
+}
+
+bool QPpsObject::isReadyReadEnabled() const
+{
+ Q_D(const QPpsObject);
+
+ // query state of read ready signal
+ return d->readyReadEnabled;
+}
+
+void QPpsObject::setReadyReadEnabled(bool enable)
+{
+ Q_D(QPpsObject);
+
+ // toggle whether socket notifier will emit a signal on read ready
+ d->readyReadEnabled = enable;
+ if (isOpen())
+ d->notifier->setEnabled(enable);
+}
+
+bool QPpsObject::isBlocking() const
+{
+ Q_D(const QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file not open
+ if (!isOpen()) {
+ d->error = EBADF;
+ return false;
+ }
+
+ // query file status flags
+ int flags = fcntl(d->fd, F_GETFL);
+ if (flags == -1) {
+ d->error = errno;
+ return false;
+ }
+ // check if non-blocking flag is unset
+ return ((flags & O_NONBLOCK) != O_NONBLOCK);
+}
+
+bool QPpsObject::setBlocking(bool enable)
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file not open
+ if (!isOpen()) {
+ d->error = EBADF;
+ return false;
+ }
+
+ // query file status flags
+ int flags = fcntl(d->fd, F_GETFL);
+ if (flags == -1) {
+ d->error = errno;
+ return false;
+ }
+
+ // configure non-blocking flag
+ if (enable)
+ flags &= ~O_NONBLOCK;
+ else
+ flags |= O_NONBLOCK;
+
+ // update file status flags
+ flags = fcntl(d->fd, F_SETFL, flags);
+ if (flags == -1) {
+ d->error = errno;
+ return false;
+ }
+
+ return true;
+}
+
+bool QPpsObject::isOpen() const
+{
+ Q_D(const QPpsObject);
+ return (d->fd != -1);
+}
+
+bool QPpsObject::open(QPpsObject::OpenModes mode)
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file already open
+ if (isOpen()) {
+ d->error = EBUSY;
+ return false;
+ }
+
+ // convert pps flags to open flags
+ int oflags = 0;
+ if ((mode & QPpsObject::Publish) && (mode & QPpsObject::Subscribe))
+ oflags |= O_RDWR;
+ else if (mode & QPpsObject::Publish)
+ oflags |= O_WRONLY;
+ else if (mode & QPpsObject::Subscribe)
+ oflags |= O_RDONLY;
+
+ if (mode & QPpsObject::Create)
+ oflags |= O_CREAT | O_EXCL;
+
+ if (mode & QPpsObject::DeleteContents)
+ oflags |= O_TRUNC;
+
+ // open pps file
+ d->fd = qt_safe_open(d->path.toUtf8().data(), oflags, 0666);
+ if (d->fd == -1) {
+ d->error = errno;
+ return false;
+ }
+ // wire up socket notifier to know when reads are ready
+ d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this);
+ d->notifier->setEnabled(d->readyReadEnabled);
+ QObject::connect(d->notifier, &QSocketNotifier::activated, this, &QPpsObject::readyRead);
+ return true;
+}
+
+bool QPpsObject::close()
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file not open
+ if (!isOpen()) {
+ d->error = EBADF;
+ return false;
+ }
+
+ // shutdown socket notifier
+ delete d->notifier;
+ d->notifier = 0;
+
+ // close pps file
+ const int result = qt_safe_close(d->fd);
+ d->fd = -1;
+
+ // check success of operation
+ if (result != 0) {
+ d->error = errno;
+ return false;
+ }
+ return true;
+}
+
+QByteArray QPpsObject::read(bool *ok)
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file not open
+ if (!isOpen()) {
+ d->error = EBADF;
+ safeAssign(ok, false);
+ return QByteArray();
+ }
+
+ const int maxSize = ppsMaxSize->value;
+ if (maxSize == -1) {
+ qWarning() << "QPpsObject::read: maxSize is equal to -1";
+ safeAssign(ok, false);
+ return QByteArray();
+ }
+
+ QByteArray byteArray;
+ byteArray.resize(maxSize); // resize doesn't initialize the data
+ const int result = qt_safe_read(d->fd, byteArray.data(), byteArray.size());
+
+ if (result == -1) {
+ d->error = errno;
+ qWarning() << "QPpsObject::read failed to read pps data, error " << errorString();
+ safeAssign(ok, false);
+ return QByteArray(); // Specifically return a default-constructed QByteArray.
+ }
+ if (result == 0) {
+ // normalize the behavior of read() when no data is ready so a pps object
+ // put in non-blocking mode via opening w/o wait (read returns 0) looks
+ // the same as a pps object put in non-blocking mode by setting O_NONBLOCK
+ // (read returns EAGAIN)
+ d->error = EAGAIN;
+ safeAssign(ok, false);
+ return QByteArray(); // Specifically return a default-constructed QByteArray.
+ }
+ // resize byte array to amount actually read
+ byteArray.resize(result);
+ safeAssign(ok, true);
+ return byteArray;
+}
+
+bool QPpsObject::write(const QByteArray &byteArray)
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // abort if file not open
+ if (!isOpen()) {
+ d->error = EBADF;
+ return false;
+ }
+
+ // write entire byte array to pps file
+ const int result = qt_safe_write(d->fd, byteArray.data(), byteArray.size());
+ if (result == -1)
+ d->error = errno;
+
+ return (result == byteArray.size());
+}
+
+int QPpsObject::writeMessage(const QString &msg, const QVariantMap &dat)
+{
+ // Treat empty msg as an encoding error
+ if (msg.isEmpty())
+ return -1;
+
+ bool ok;
+ QByteArray byteArray = encodeMessage(msg, dat, &ok);
+
+ if (!ok)
+ return -1;
+
+ ok = write(byteArray);
+ if (!ok)
+ return error();
+
+ return EOK;
+}
+
+int QPpsObject::writeMessage(const QString &msg, const QString &id, const QVariantMap &dat)
+{
+ // Treat empty msg or id as an encoding error
+ if (msg.isEmpty() || id.isEmpty())
+ return -1;
+
+ bool ok;
+ QByteArray byteArray = encodeMessage(msg, id, dat, &ok);
+
+ if (!ok)
+ return -1;
+
+ ok = write(byteArray);
+ if (!ok)
+ return error();
+
+ return EOK;
+}
+
+bool QPpsObject::remove()
+{
+ Q_D(QPpsObject);
+
+ // reset last error
+ d->error = EOK;
+
+ // delete pps file
+ const int result = unlink(d->path.toUtf8().data());
+
+ // check success of operation
+ if (result != 0) {
+ d->error = errno;
+ return false;
+ }
+ return true;
+}
+
+// static
+QVariantMap QPpsObject::decode(const QByteArray &rawData, bool *ok)
+{
+ QPpsAttributeMap mapData = decodeWithFlags(rawData, 0, ok);
+
+ // If *ok is false, then mapData is empty, so the resulting QVariantMap
+ // will also be empty, as desired.
+ return QPpsObjectPrivate::variantMapFromPpsAttributeMap(mapData);
+}
+
+// static
+QPpsAttributeMap QPpsObject::decodeWithFlags(const QByteArray &rawData, bool *ok)
+{
+ return QPpsObject::decodeWithFlags(rawData, 0, ok);
+}
+
+// static
+QPpsAttributeMap QPpsObject::decodeWithFlags(const QByteArray &rawData,
+ QPpsAttribute *objectAttribute, bool *ok)
+{
+ safeAssign(ok, true);
+
+ bool success = false;
+ QPpsAttributeMap mapData = QPpsObjectPrivate::decode(rawData, &success);
+ if (!success) {
+ safeAssign(ok, false);
+ return QPpsAttributeMap();
+ }
+
+ // The object name is the key of the first element, and the flags of that attribute
+ // give the status for the object as a whole.
+ if (!mapData.isEmpty() && objectAttribute) {
+ QString extractedName = mapData.begin().key();
+ QPpsAttribute topmostAttribute = mapData.begin().value();
+ QPpsAttribute::Flags topmostFlags = topmostAttribute.flags();
+ QPpsAttribute toplevelAttribute =
+ QPpsAttributePrivate::createPpsAttribute(extractedName, topmostFlags);
+ *objectAttribute = toplevelAttribute;
+ }
+
+ return mapData;
+}
+
+
+// static
+QByteArray QPpsObject::encode(const QVariantMap &ppsData, bool *ok)
+{
+ safeAssign(ok, true);
+
+ bool success = false;
+ QByteArray byteArray = QPpsObjectPrivate::encode(ppsData, &success);
+ if (!success) {
+ safeAssign(ok, false);
+ return QByteArray();
+ }
+ return byteArray;
+}
+
+// static
+QByteArray QPpsObject::encodeMessage(const QString &msg, const QVariantMap &dat, bool *ok)
+{
+ safeAssign(ok, true);
+
+ // Treat empty msg as an encoding error
+ if (msg.isEmpty()) {
+ safeAssign(ok, false);
+ return QByteArray();
+ }
+
+ QVariantMap ppsData;
+ ppsData[QStringLiteral("msg")] = msg;
+ ppsData[QStringLiteral("dat")] = dat;
+
+ return QPpsObject::encode(ppsData, ok);
+}
+
+// static
+QByteArray QPpsObject::encodeMessage(const QString &msg, const QString &id, const QVariantMap &dat,
+ bool *ok)
+{
+ safeAssign(ok, true);
+
+ // Treat empty msg or id as an encoding error
+ if (msg.isEmpty() || id.isEmpty()) {
+ safeAssign(ok, false);
+ return QByteArray();
+ }
+
+ QVariantMap ppsData;
+ ppsData[QStringLiteral("msg")] = msg;
+ ppsData[QStringLiteral("id")] = id;
+ ppsData[QStringLiteral("dat")] = dat;
+
+ return QPpsObject::encode(ppsData, ok);
+}
+
+// static
+int QPpsObject::sendMessage(const QString &path, const QString &message)
+{
+ QPpsObject pps(path);
+
+ bool ok = pps.open(QPpsObject::Publish);
+ if (!ok)
+ return pps.error();
+
+ ok = pps.write(message.toLocal8Bit());
+ if (!ok)
+ return pps.error();
+
+ return EOK;
+}
+
+// static
+int QPpsObject::sendMessage(const QString &path, const QVariantMap &message)
+{
+ QPpsObject pps(path);
+
+ bool ok = pps.open(QPpsObject::Publish);
+ if (!ok)
+ return pps.error();
+
+ QByteArray payload = QPpsObject::encode(message, &ok);
+ if (!ok)
+ return -1;
+
+ ok = pps.write(payload);
+ if (!ok)
+ return pps.error();
+
+ return EOK;
+}
+
+// static
+int QPpsObject::sendMessage(const QString &path, const QString &msg, const QVariantMap &dat)
+{
+ // Treat empty msg as an encoding error
+ if (msg.isEmpty())
+ return -1;
+
+ QPpsObject pps(path);
+
+ bool ok = pps.open(QPpsObject::Publish);
+ if (!ok)
+ return pps.error();
+
+ QByteArray payload = QPpsObject::encodeMessage(msg, dat, &ok);
+ if (!ok)
+ return -1;
+
+ ok = pps.write(payload);
+ if (!ok)
+ return pps.error();
+
+ return EOK;
+}
+
+// static
+int QPpsObject::sendMessage(const QString &path, const QByteArray &ppsData)
+{
+ QPpsObject pps(path);
+
+ bool ok = pps.open(QPpsObject::Publish);
+ if (!ok)
+ return pps.error();
+
+ ok = pps.write(ppsData);
+ if (!ok)
+ return pps.error();
+
+ return EOK;
+}
diff --git a/src/corelib/kernel/qppsobject_p.h b/src/corelib/kernel/qppsobject_p.h
new file mode 100644
index 0000000000..1095796a13
--- /dev/null
+++ b/src/corelib/kernel/qppsobject_p.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QPPSOBJECT_P_H
+#define QPPSOBJECT_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 "qppsattribute_p.h"
+
+#include <QMap>
+#include <QObject>
+#include <QVariantMap>
+
+QT_BEGIN_NAMESPACE
+
+class QPpsObjectPrivate;
+
+class Q_CORE_EXPORT QPpsObject : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum OpenMode {
+ Publish = 1,
+ Subscribe = 2,
+ PublishSubscribe = Publish | Subscribe,
+ Create = 4,
+ DeleteContents = 8
+ };
+ Q_DECLARE_FLAGS(OpenModes, OpenMode)
+
+ explicit QPpsObject(const QString &path, QObject *parent = 0);
+ virtual ~QPpsObject();
+
+ int error() const;
+ QString errorString() const;
+
+ bool isReadyReadEnabled() const;
+ bool isBlocking() const;
+ bool setBlocking(bool enable);
+ bool isOpen() const;
+
+ bool open(QPpsObject::OpenModes mode = QPpsObject::PublishSubscribe);
+ bool close();
+ bool remove();
+
+ QByteArray read(bool *ok = 0);
+ bool write(const QByteArray &byteArray);
+
+ int writeMessage(const QString &msg, const QVariantMap &dat);
+ int writeMessage(const QString &msg, const QString &id, const QVariantMap &dat);
+
+ static QVariantMap decode(const QByteArray &rawData, bool *ok = 0);
+ static QPpsAttributeMap decodeWithFlags(const QByteArray &rawData, bool *ok = 0);
+ static QPpsAttributeMap decodeWithFlags(const QByteArray &rawData,
+ QPpsAttribute *objectAttribute, bool *ok = 0);
+
+ static QByteArray encode(const QVariantMap &ppsData, bool *ok = 0);
+ static QByteArray encodeMessage(const QString &msg, const QVariantMap &dat, bool *ok = 0);
+ static QByteArray encodeMessage(const QString &msg, const QString &id, const QVariantMap &dat,
+ bool *ok = 0);
+
+ static int sendMessage(const QString &path, const QString &message);
+ static int sendMessage(const QString &path, const QVariantMap &message);
+ static int sendMessage(const QString &path, const QString &msg, const QVariantMap &dat);
+ static int sendMessage(const QString &path, const QByteArray &ppsData);
+
+public Q_SLOTS:
+ void setReadyReadEnabled(bool enable);
+
+Q_SIGNALS:
+ void readyRead();
+
+private:
+ QScopedPointer<QPpsObjectPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QPpsObject)
+ Q_DISABLE_COPY(QPpsObject)
+};
+
+QT_END_NAMESPACE
+
+#endif // QPPSOBJECT_P_H
diff --git a/src/corelib/kernel/qppsobjectprivate_p.h b/src/corelib/kernel/qppsobjectprivate_p.h
new file mode 100644
index 0000000000..d291d6b559
--- /dev/null
+++ b/src/corelib/kernel/qppsobjectprivate_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+ ** Contact: http://www.qt-project.org/legal
+ **
+ ** This file is part of the QtCore module of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:LGPL$
+ ** Commercial License Usage
+ ** Licensees holding valid commercial Qt licenses may use this file in
+ ** accordance with the commercial license agreement provided with the
+ ** Software or, alternatively, in accordance with the terms contained in
+ ** a written agreement between you and Digia. For licensing terms and
+ ** conditions see http://qt.digia.com/licensing. For further information
+ ** use the contact form at http://qt.digia.com/contact-us.
+ **
+ ** GNU Lesser General Public License Usage
+ ** Alternatively, 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, Digia gives you certain additional
+ ** rights. These rights are described in the Digia 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.
+ **
+ **
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef QPPSOBJECTPRIVATE_P_H_
+#define QPPSOBJECTPRIVATE_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 "qppsattribute_p.h"
+
+#include <QMap>
+#include <QDebug>
+
+#include <sys/pps.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSocketNotifier;
+
+class QPpsObjectPrivate
+{
+public:
+ explicit QPpsObjectPrivate(const QString &path);
+
+ static QPpsAttributeMap decode(const QByteArray &rawData, bool *ok);
+ static QByteArray encode(const QVariantMap &ppsData, bool *ok);
+
+ static QVariantMap variantMapFromPpsAttributeMap(const QPpsAttributeMap &data);
+
+ QSocketNotifier *notifier;
+ QString path;
+ mutable int error;
+ int fd;
+ bool readyReadEnabled;
+
+private:
+ static QPpsAttribute::Flags readFlags(pps_decoder_t *decoder);
+ static QPpsAttribute decodeString(pps_decoder_t *decoder);
+ static QPpsAttribute decodeNumber(pps_decoder_t *decoder);
+ static QPpsAttribute decodeBool(pps_decoder_t *decoder);
+ static QPpsAttribute decodeData(pps_decoder_t *decoder);
+ static QPpsAttributeList decodeArray(pps_decoder_t *decoder, bool *ok);
+ static QPpsAttributeMap decodeObject(pps_decoder_t *decoder, bool *ok);
+ static bool decoderPush(pps_decoder_t *decoder, const char *name = 0);
+ static bool decoderPop(pps_decoder_t *decoder);
+
+ template<typename T>
+ static QPpsAttribute decodeNestedData(T (*decodeFunction)(pps_decoder_t *, bool *),
+ pps_decoder_t *decoder);
+
+ static void encodeData(pps_encoder_t *encoder, const char *name,
+ const QVariant &data, bool *ok);
+ static void encodeArray(pps_encoder_t *encoder, const QVariantList &data, bool *ok);
+ static void encodeObject(pps_encoder_t *encoder, const QVariantMap &data, bool *ok);
+
+ static QVariant variantFromPpsAttribute(const QPpsAttribute &attribute);
+};
+
+inline bool QPpsObjectPrivate::decoderPush(pps_decoder_t *decoder, const char *name)
+{
+ pps_decoder_error_t error = pps_decoder_push(decoder, name);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeData: pps_decoder_push failed";
+ return false;
+ }
+ return true;
+}
+
+inline bool QPpsObjectPrivate::decoderPop(pps_decoder_t *decoder)
+{
+ pps_decoder_error_t error = pps_decoder_pop(decoder);
+ if (error != PPS_DECODER_OK) {
+ qWarning() << "QPpsObjectPrivate::decodeData: pps_decoder_pop failed";
+ return false;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif /* QPPSOBJECTPRIVATE_P_H_ */
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 1f53b94c4d..407a6a4e02 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -62,7 +62,7 @@ QT_BEGIN_NAMESPACE
*/
QString
QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
- const QString &prefix)
+ const QString &prefix)
{
if (key.isEmpty())
return QString();
@@ -350,7 +350,7 @@ bool QSharedMemory::create(int size, AccessMode mode)
if (size <= 0) {
d->error = QSharedMemory::InvalidSize;
d->errorString =
- QSharedMemory::tr("%1: create size is less then 0").arg(function);
+ QSharedMemory::tr("%1: create size is less then 0").arg(function);
return false;
}
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index edf90a31ac..77f7a60814 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -115,7 +115,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
return false;
if (count > 0) {
- if (0 == ReleaseSemaphore(semaphore, count, 0)) {
+ if (0 == ReleaseSemaphore(semaphore, count, 0)) {
setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore"));
#if defined QSYSTEMSEMAPHORE_DEBUG
qDebug() << QLatin1String("QSystemSemaphore::modifySemaphore ReleaseSemaphore failed");
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index a1b7f398e8..dd9a7693ca 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -868,7 +868,7 @@ static void customConstruct(QVariant::Private *d, const void *copy)
// this logic should match with QVariantIntegrator::CanUseInternalSpace
if (size <= sizeof(QVariant::Private::Data)
- && (type.flags() & QMetaType::MovableType)) {
+ && (type.flags() & (QMetaType::MovableType | QMetaType::IsEnumeration))) {
type.construct(&d->data.ptr, copy);
d->is_shared = false;
} else {
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 4ec049e20d..b523d19187 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -67,7 +67,7 @@ template<typename T>
struct QVariantIntegrator
{
static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data)
- && (!QTypeInfo<T>::isStatic);
+ && ((!QTypeInfo<T>::isStatic) || Q_IS_ENUM(T));
};
Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace);
Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace);
diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp
index eab5a37645..c694237dc3 100644
--- a/src/corelib/kernel/qwineventnotifier.cpp
+++ b/src/corelib/kernel/qwineventnotifier.cpp
@@ -41,7 +41,11 @@
#include "qwineventnotifier.h"
+#ifdef Q_OS_WINRT
+#include "qeventdispatcher_winrt_p.h"
+#else
#include "qeventdispatcher_win_p.h"
+#endif
#include "qcoreapplication.h"
#include <private/qthread_p.h>
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 2aed877e6b..e89d6396f6 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -190,7 +190,7 @@ bool QLibraryPrivate::load_sys()
}
#endif
-#if defined(Q_OS_AIX) // Not sure if any other platform actually support this thing.
+#if defined(Q_OS_AIX) // Not sure if any other platform actually support this thing.
if (loadHints & QLibrary::LoadArchiveMemberHint) {
dlFlags |= RTLD_MEMBER;
}
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 928f2c5eb1..b9494a3041 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -107,12 +107,16 @@ bool QLibraryPrivate::load_sys()
attempts.append(QFileInfo(fileName).absoluteFilePath());
#endif
}
+#ifdef Q_OS_WINRT
+ if (fileName.startsWith(QLatin1Char('/')))
+ attempts.prepend(QDir::rootPath() + fileName);
+#endif
Q_FOREACH (const QString &attempt, attempts) {
#ifndef Q_OS_WINRT
pHnd = LoadLibrary((wchar_t*)QDir::toNativeSeparators(attempt).utf16());
#else // Q_OS_WINRT
- QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(fileName));
+ QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(attempt));
pHnd = LoadPackagedLibrary((LPCWSTR)path.utf16(), 0);
if (pHnd)
qualifiedFileName = attempt;
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 4dba12e1b0..d2e2368ca9 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -665,62 +665,62 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root,
QSet<QAbstractState*> &statesToEnter,
QSet<QAbstractState*> &statesForDefaultEntry)
{
- if (QHistoryState *h = toHistoryState(s)) {
- QList<QAbstractState*> hconf = QHistoryStatePrivate::get(h)->configuration;
- if (!hconf.isEmpty()) {
- for (int k = 0; k < hconf.size(); ++k) {
- QAbstractState *s0 = hconf.at(k);
- addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
- }
- #ifdef QSTATEMACHINE_DEBUG
- qDebug() <<q_func() << ": restoring"
- << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow")
- << "history from" << s << ':' << hconf;
- #endif
- } else {
- QList<QAbstractState*> hlst;
- if (QHistoryStatePrivate::get(h)->defaultState)
- hlst.append(QHistoryStatePrivate::get(h)->defaultState);
-
- if (hlst.isEmpty()) {
- setError(QStateMachine::NoDefaultStateInHistoryStateError, h);
- } else {
- for (int k = 0; k < hlst.size(); ++k) {
- QAbstractState *s0 = hlst.at(k);
- addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
- }
- #ifdef QSTATEMACHINE_DEBUG
- qDebug() << q_func() << ": initial history targets for" << s << ':' << hlst;
- #endif
- }
- }
- } else {
- if (s == rootState()) {
- // Error has already been set by exitStates().
- Q_ASSERT(error != QStateMachine::NoError);
+ if (QHistoryState *h = toHistoryState(s)) {
+ QList<QAbstractState*> hconf = QHistoryStatePrivate::get(h)->configuration;
+ if (!hconf.isEmpty()) {
+ for (int k = 0; k < hconf.size(); ++k) {
+ QAbstractState *s0 = hconf.at(k);
+ addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
+ }
+#ifdef QSTATEMACHINE_DEBUG
+ qDebug() << q_func() << ": restoring"
+ << ((QHistoryStatePrivate::get(h)->historyType == QHistoryState::DeepHistory) ? "deep" : "shallow")
+ << "history from" << s << ':' << hconf;
+#endif
+ } else {
+ QList<QAbstractState*> hlst;
+ if (QHistoryStatePrivate::get(h)->defaultState)
+ hlst.append(QHistoryStatePrivate::get(h)->defaultState);
+
+ if (hlst.isEmpty()) {
+ setError(QStateMachine::NoDefaultStateInHistoryStateError, h);
+ } else {
+ for (int k = 0; k < hlst.size(); ++k) {
+ QAbstractState *s0 = hlst.at(k);
+ addStatesToEnter(s0, root, statesToEnter, statesForDefaultEntry);
+ }
+#ifdef QSTATEMACHINE_DEBUG
+ qDebug() << q_func() << ": initial history targets for" << s << ':' << hlst;
+#endif
+ }
+ }
+ } else {
+ if (s == rootState()) {
+ // Error has already been set by exitStates().
+ Q_ASSERT(error != QStateMachine::NoError);
+ return;
+ }
+ statesToEnter.insert(s);
+ if (isParallel(s)) {
+ QState *grp = toStandardState(s);
+ QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates();
+ for (int i = 0; i < lst.size(); ++i) {
+ QAbstractState *child = lst.at(i);
+ addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry);
+ }
+ } else if (isCompound(s)) {
+ statesForDefaultEntry.insert(s);
+ QState *grp = toStandardState(s);
+ QAbstractState *initial = grp->initialState();
+ if (initial != 0) {
+ Q_ASSERT(initial->machine() == q_func());
+ addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry);
+ } else {
+ setError(QStateMachine::NoInitialStateError, grp);
return;
}
- statesToEnter.insert(s);
- if (isParallel(s)) {
- QState *grp = toStandardState(s);
- QList<QAbstractState*> lst = QStatePrivate::get(grp)->childStates();
- for (int i = 0; i < lst.size(); ++i) {
- QAbstractState *child = lst.at(i);
- addStatesToEnter(child, grp, statesToEnter, statesForDefaultEntry);
- }
- } else if (isCompound(s)) {
- statesForDefaultEntry.insert(s);
- QState *grp = toStandardState(s);
- QAbstractState *initial = grp->initialState();
- if (initial != 0) {
- Q_ASSERT(initial->machine() == q_func());
- addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry);
- } else {
- setError(QStateMachine::NoInitialStateError, grp);
- return;
- }
- }
- }
+ }
+ }
}
void QStateMachinePrivate::addAncestorStatesToEnter(QAbstractState *s, QState *root,
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 39d136c006..33e85c1505 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -39,20 +39,48 @@
**
****************************************************************************/
+#include "qatomic.h"
+
/*!
\class QAtomicInt
\inmodule QtCore
- \brief The QAtomicInt class provides platform-independent atomic operations on integers.
+ \brief The QAtomicInt class provides platform-independent atomic operations on int.
\since 4.4
+ This class is a equivalent to \c{QAtomicInteger<int>}. All other
+ functionality is equivalent. Please see that class for more information.
+
+ \sa QAtomicInteger, QAtomicPointer
+*/
+
+/*!
+ \class QAtomicInteger
+ \inmodule QtCore
+ \brief The QAtomicInteger class provides platform-independent atomic operations on integers.
\ingroup thread
For atomic operations on pointers, see the QAtomicPointer class.
An \e atomic operation is a complex operation that completes without interruption.
- The QAtomicInt class provides atomic reference counting, test-and-set, fetch-and-store,
+ The QAtomicInteger class provides atomic reference counting, test-and-set, fetch-and-store,
and fetch-and-add for integers.
+ The template parameter \c T must be a C++ integer type:
+ \list
+ \li 8-bit: char, signed char, unsigned char, qint8, quint8
+ \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11)
+ \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11)
+ \li 64-bit: long long, unsigned long long, qint64, quint64
+ \li platform-specific size: long, unsigned long
+ \li pointer size: qintptr, quintptr, qptrdiff
+ \endlist
+
+ Of the list above, only the 32-bit- and pointer-sized instantiations are guaranteed to
+ work on all platforms. Support for other sizes depends on the compiler and
+ processor architecture the code is being compiled for. To test whether the
+ other types are supported, check the macro \c Q_ATOMIC_INT\e{nn}_IS_SUPPORTED,
+ where \c{\e{nn}} is the number of bits desired.
+
\section1 The Atomic API
\section2 Reference counting
@@ -67,7 +95,7 @@
\section2 Memory ordering
- QAtomicInt provides several implementations of the atomic
+ QAtomicInteger provides several implementations of the atomic
test-and-set, fetch-and-store, and fetch-and-add functions. Each
implementation defines a memory ordering semantic that describes
how memory accesses surrounding the atomic instruction are
@@ -93,8 +121,8 @@
\section2 Test-and-set
- If the current value of the QAtomicInt is an expected value, the
- test-and-set functions assign a new value to the QAtomicInt and
+ If the current value of the QAtomicInteger is an expected value, the
+ test-and-set functions assign a new value to the QAtomicInteger and
return true. If values are \a not the same, these functions do
nothing and return false. This operation equates to the following
code:
@@ -109,7 +137,7 @@
\section2 Fetch-and-store
The atomic fetch-and-store functions read the current value of the
- QAtomicInt and then assign a new value, returning the original
+ QAtomicInteger and then assign a new value, returning the original
value. This operation equates to the following code:
\snippet code/src_corelib_thread_qatomic.cpp 2
@@ -122,7 +150,7 @@
\section2 Fetch-and-add
The atomic fetch-and-add functions read the current value of the
- QAtomicInt and then add the given value to the current value,
+ QAtomicInteger and then add the given value to the current value,
returning the original value. This operation equates to the
following code:
@@ -136,34 +164,35 @@
\section1 Feature Tests for the Atomic API
Providing a platform-independent atomic API that works on all
- processors is challenging. The API provided by QAtomicInt is
+ processors is challenging. The API provided by QAtomicInteger is
guaranteed to work atomically on all processors. However, since
not all processors implement support for every operation provided
- by QAtomicInt, it is necessary to expose information about the
+ by QAtomicInteger, it is necessary to expose information about the
processor.
You can check at compile time which features are supported on your
hardware using various macros. These will tell you if your
hardware always, sometimes, or does not support a particular
operation. The macros have the form
- Q_ATOMIC_INT_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{OPERATION}
+ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_\e{HOW}_NATIVE. \e{nn} is the
+ size of the integer (in bits), \e{OPERATION}
is one of REFERENCE_COUNTING, TEST_AND_SET,
FETCH_AND_STORE, or FETCH_AND_ADD, and \e{HOW} is one of
ALWAYS, SOMETIMES, or NOT. There will always be exactly one
defined macro per operation. For example, if
- Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE is defined,
+ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE is defined,
neither Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE nor
- Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE will be defined.
+ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NOT_NATIVE will be defined.
An operation that completes in constant time is said to be
wait-free. Such operations are not implemented using locks or
loops of any kind. For atomic operations that are always
supported, and that are wait-free, Qt defines the
- Q_ATOMIC_INT_\e{OPERATION}_IS_WAIT_FREE in addition to the
- Q_ATOMIC_INT_\e{OPERATION}_IS_ALWAYS_NATIVE.
+ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_WAIT_FREE in addition to the
+ Q_ATOMIC_INT\e{nn}_\e{OPERATION}_IS_ALWAYS_NATIVE.
In cases where an atomic operation is only supported in newer
- generations of the processor, QAtomicInt also provides a way to
+ generations of the processor, QAtomicInteger also provides a way to
check at runtime what your hardware supports with the
isReferenceCountingNative(), isTestAndSetNative(),
isFetchAndStoreNative(), and isFetchAndAddNative()
@@ -171,32 +200,37 @@
isReferenceCountingWaitFree(), isTestAndSetWaitFree(),
isFetchAndStoreWaitFree(), and isFetchAndAddWaitFree() functions.
- Below is a complete list of all feature macros for QAtomicInt:
+ Below is a complete list of all feature macros for QAtomicInteger:
\list
- \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
+ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_REFERENCE_COUNTING_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
+ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_TEST_AND_SET_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
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_STORE_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
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_NOT_NATIVE
+ \li Q_ATOMIC_INT\e{nn}_FETCH_AND_ADD_IS_WAIT_FREE
\endlist
+ For compatibility with previous versions of Qt, macros with an empty \e{nn}
+ are equivalent to the 32-bit macros. For example,
+ Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE is the same as
+ Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE.
+
\sa QAtomicPointer
*/
@@ -205,21 +239,27 @@
Constructs a QAtomicInt with the given \a value.
*/
-/*! \fn QAtomicInt::QAtomicInt(const QAtomicInt &other)
+/*! \fn QAtomicInteger::QAtomicInteger(T value)
+
+ Constructs a QAtomicInteger with the given \a value.
+*/
+
+/*! \fn QAtomicInteger::QAtomicInteger(const QAtomicInteger &other)
Constructs a copy of \a other.
*/
-/*! \fn QAtomicInt &QAtomicInt::operator=(const QAtomicInt &other)
+/*! \fn QAtomicInteger &QAtomicInteger::operator=(const QAtomicInteger &other)
- Assigns \a other to this QAtomicInt and returns a reference to
- this QAtomicInt.
+ Assigns \a other to this QAtomicInteger and returns a reference to
+ this QAtomicInteger.
*/
+
/*!
- \fn int QAtomicInt::load() const
+ \fn int QAtomicInteger::load() const
- Atomically loads the value of this QAtomicInt using relaxed memory
+ Atomically loads the value of this QAtomicInteger using relaxed memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
@@ -227,9 +267,9 @@
*/
/*!
- \fn int QAtomicInt::loadAcquire() const
+ \fn int QAtomicInteger::loadAcquire() const
- Atomically loads the value of this QAtomicInt using the "Acquire" memory
+ Atomically loads the value of this QAtomicInteger using the "Acquire" memory
ordering. The value is not modified in any way, but note that there's no
guarantee that it remains so.
@@ -237,7 +277,7 @@
*/
/*!
- \fn void QAtomicInt::store(int newValue)
+ \fn void QAtomicInteger::store(int newValue)
Atomically stores the \a newValue value into this atomic type, using
relaxed memory ordering.
@@ -246,7 +286,7 @@
*/
/*!
- \fn void QAtomicInt::storeRelease(int newValue)
+ \fn void QAtomicInteger::storeRelease(int newValue)
Atomically stores the \a newValue value into this atomic type, using
the "Release" memory ordering.
@@ -254,376 +294,824 @@
\sa store(), load()
*/
-/*! \fn bool QAtomicInt::isReferenceCountingNative()
+/*!
+ \fn QAtomicInteger::operator int() const
+ \since 5.3
+
+ Atomically loads the value of this QAtomicInteger using a sequentially
+ consistent memory ordering if possible; or "Acquire" ordering if not. The
+ value is not modified in any way, but note that there's no guarantee that
+ it remains so.
+
+ \sa load(), loadAcquire()
+*/
+
+/*!
+ \fn QAtomicInteger &QAtomicInteger::operator=(int newValue)
+ \since 5.3
+
+ Atomically stores the \a newValue value into this atomic type using a
+ sequentially consistent memory ordering if possible; or "Release" ordering
+ if not. This function returns a reference to this object.
+
+ \sa store(), storeRelease()
+*/
+
+/*! \fn bool QAtomicInteger::isReferenceCountingNative()
Returns \c true if reference counting is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn bool QAtomicInt::isReferenceCountingWaitFree()
+/*! \fn bool QAtomicInteger::isReferenceCountingWaitFree()
Returns \c true if atomic reference counting is wait-free, false
otherwise.
*/
-/*! \fn bool QAtomicInt::ref()
- Atomically increments the value of this QAtomicInt. Returns \c true
+/*! \fn bool QAtomicInteger::ref()
+ Atomically increments the value of this QAtomicInteger. Returns \c true
if the new value is non-zero, false otherwise.
- This function uses \e ordered \l {QAtomicInt#Memory
+ This function uses \e ordered \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before and after the atomic operation (in program order)
may not be re-ordered.
- \sa deref()
+ \sa deref(), operator++()
+*/
+
+/*!
+ \fn int QAtomicInteger::operator++()
+ \since 5.3
+
+ Atomically pre-increments the value of this QAtomicInteger. Returns the new
+ value of this atomic.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa ref(), operator++(int), operator--()
*/
-/*! \fn bool QAtomicInt::deref()
- Atomically decrements the value of this QAtomicInt. Returns \c true
+/*!
+ \fn int QAtomicInteger::operator++(int)
+ \since 5.3
+
+ Atomically post-increments the value of this QAtomicInteger. Returns the old
+ value of this atomic.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa ref(), operator++(), operator--(int)
+*/
+
+/*! \fn bool QAtomicInteger::deref()
+ Atomically decrements the value of this QAtomicInteger. Returns \c true
if the new value is non-zero, false otherwise.
- This function uses \e ordered \l {QAtomicInt#Memory
+ This function uses \e ordered \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before and after the atomic operation (in program order)
may not be re-ordered.
- \sa ref()
+ \sa ref(), operator--()
+*/
+
+/*!
+ \fn int QAtomicInteger::operator--()
+ \since 5.3
+
+ Atomically pre-decrements the value of this QAtomicInteger. Returns the new
+ value of this atomic.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa deref(), operator--(int), operator++()
*/
-/*! \fn bool QAtomicInt::isTestAndSetNative()
+/*!
+ \fn int QAtomicInteger::operator--(int)
+ \since 5.3
+
+ Atomically post-decrements the value of this QAtomicInteger. Returns the old
+ value of this atomic.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa deref(), operator--(), operator++(int)
+*/
+
+/*! \fn bool QAtomicInteger::isTestAndSetNative()
Returns \c true if test-and-set is implemented using atomic processor
instructions, false otherwise.
*/
-/*! \fn bool QAtomicInt::isTestAndSetWaitFree()
+/*! \fn bool QAtomicInteger::isTestAndSetWaitFree()
Returns \c true if atomic test-and-set is wait-free, false otherwise.
*/
-/*! \fn bool QAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+/*! \fn bool QAtomicInteger::testAndSetRelaxed(int expectedValue, int newValue)
Atomic test-and-set.
- If the current value of this QAtomicInt is the \a expectedValue,
+ If the current value of this QAtomicInteger is the \a expectedValue,
the test-and-set functions assign the \a newValue to this
- QAtomicInt and return true. If the values are \e not the same,
+ QAtomicInteger and return true. If the values are \e not the same,
this function does nothing and returns \c false.
- This function uses \e relaxed \l {QAtomicInt#Memory
+ This function uses \e relaxed \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, leaving the compiler and
processor to freely reorder memory accesses.
*/
-/*! \fn bool QAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+/*! \fn bool QAtomicInteger::testAndSetAcquire(int expectedValue, int newValue)
Atomic test-and-set.
- If the current value of this QAtomicInt is the \a expectedValue,
+ If the current value of this QAtomicInteger is the \a expectedValue,
the test-and-set functions assign the \a newValue to this
- QAtomicInt and return true. If the values are \e not the same,
+ QAtomicInteger and return true. If the values are \e not the same,
this function does nothing and returns \c false.
- This function uses \e acquire \l {QAtomicInt#Memory
+ This function uses \e acquire \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access following the atomic operation (in program order) may not
be re-ordered before the atomic operation.
*/
-/*! \fn bool QAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+/*! \fn bool QAtomicInteger::testAndSetRelease(int expectedValue, int newValue)
Atomic test-and-set.
- If the current value of this QAtomicInt is the \a expectedValue,
+ If the current value of this QAtomicInteger is the \a expectedValue,
the test-and-set functions assign the \a newValue to this
- QAtomicInt and return true. If the values are \e not the same,
+ QAtomicInteger and return true. If the values are \e not the same,
this function does nothing and returns \c false.
- This function uses \e release \l {QAtomicInt#Memory
+ This function uses \e release \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before the atomic operation (in program order) may not be
re-ordered after the atomic operation.
*/
-/*! \fn bool QAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+/*! \fn bool QAtomicInteger::testAndSetOrdered(int expectedValue, int newValue)
Atomic test-and-set.
- If the current value of this QAtomicInt is the \a expectedValue,
+ If the current value of this QAtomicInteger is the \a expectedValue,
the test-and-set functions assign the \a newValue to this
- QAtomicInt and return true. If the values are \e not the same,
+ QAtomicInteger and return true. If the values are \e not the same,
this function does nothing and returns \c false.
- This function uses \e ordered \l {QAtomicInt#Memory
+ This function uses \e ordered \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before and after the atomic operation (in program order)
may not be re-ordered.
*/
-/*! \fn bool QAtomicInt::isFetchAndStoreNative()
+/*! \fn bool QAtomicInteger::isFetchAndStoreNative()
Returns \c true if fetch-and-store is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn bool QAtomicInt::isFetchAndStoreWaitFree()
+/*! \fn bool QAtomicInteger::isFetchAndStoreWaitFree()
Returns \c true if atomic fetch-and-store is wait-free, false
otherwise.
*/
-/*! \fn int QAtomicInt::fetchAndStoreRelaxed(int newValue)
+/*! \fn int QAtomicInteger::fetchAndStoreRelaxed(int newValue)
Atomic fetch-and-store.
- Reads the current value of this QAtomicInt and then assigns it the
+ Reads the current value of this QAtomicInteger and then assigns it the
\a newValue, returning the original value.
- This function uses \e relaxed \l {QAtomicInt#Memory
+ This function uses \e relaxed \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, leaving the compiler and
processor to freely reorder memory accesses.
*/
-/*! \fn int QAtomicInt::fetchAndStoreAcquire(int newValue)
+/*! \fn int QAtomicInteger::fetchAndStoreAcquire(int newValue)
Atomic fetch-and-store.
- Reads the current value of this QAtomicInt and then assigns it the
+ Reads the current value of this QAtomicInteger and then assigns it the
\a newValue, returning the original value.
- This function uses \e acquire \l {QAtomicInt#Memory
+ This function uses \e acquire \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access following the atomic operation (in program order) may not
be re-ordered before the atomic operation.
*/
-/*! \fn int QAtomicInt::fetchAndStoreRelease(int newValue)
+/*! \fn int QAtomicInteger::fetchAndStoreRelease(int newValue)
Atomic fetch-and-store.
- Reads the current value of this QAtomicInt and then assigns it the
+ Reads the current value of this QAtomicInteger and then assigns it the
\a newValue, returning the original value.
- This function uses \e release \l {QAtomicInt#Memory
+ This function uses \e release \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before the atomic operation (in program order) may not be
re-ordered after the atomic operation.
*/
-/*! \fn int QAtomicInt::fetchAndStoreOrdered(int newValue)
+/*! \fn int QAtomicInteger::fetchAndStoreOrdered(int newValue)
Atomic fetch-and-store.
- Reads the current value of this QAtomicInt and then assigns it the
+ Reads the current value of this QAtomicInteger and then assigns it the
\a newValue, returning the original value.
- This function uses \e ordered \l {QAtomicInt#Memory
+ This function uses \e ordered \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before and after the atomic operation (in program order)
may not be re-ordered.
*/
-/*! \fn bool QAtomicInt::isFetchAndAddNative()
+/*! \fn bool QAtomicInteger::isFetchAndAddNative()
Returns \c true if fetch-and-add is implemented using atomic
processor instructions, false otherwise.
*/
-/*! \fn bool QAtomicInt::isFetchAndAddWaitFree()
+/*! \fn bool QAtomicInteger::isFetchAndAddWaitFree()
Returns \c true if atomic fetch-and-add is wait-free, false
otherwise.
*/
-/*! \fn int QAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+/*! \fn int QAtomicInteger::fetchAndAddRelaxed(int valueToAdd)
Atomic fetch-and-add.
- Reads the current value of this QAtomicInt and then adds
+ Reads the current value of this QAtomicInteger and then adds
\a valueToAdd to the current value, returning the original value.
- This function uses \e relaxed \l {QAtomicInt#Memory
+ This function uses \e relaxed \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, leaving the compiler and
processor to freely reorder memory accesses.
+
+ \sa operator+=(), fetchAndSubRelaxed()
*/
-/*! \fn int QAtomicInt::fetchAndAddAcquire(int valueToAdd)
+/*! \fn int QAtomicInteger::fetchAndAddAcquire(int valueToAdd)
Atomic fetch-and-add.
- Reads the current value of this QAtomicInt and then adds
+ Reads the current value of this QAtomicInteger and then adds
\a valueToAdd to the current value, returning the original value.
- This function uses \e acquire \l {QAtomicInt#Memory
+ This function uses \e acquire \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access following the atomic operation (in program order) may not
be re-ordered before the atomic operation.
+
+ \sa operator+=(), fetchAndSubAcquire()
*/
-/*! \fn int QAtomicInt::fetchAndAddRelease(int valueToAdd)
+/*! \fn int QAtomicInteger::fetchAndAddRelease(int valueToAdd)
Atomic fetch-and-add.
- Reads the current value of this QAtomicInt and then adds
+ Reads the current value of this QAtomicInteger and then adds
\a valueToAdd to the current value, returning the original value.
- This function uses \e release \l {QAtomicInt#Memory
+ This function uses \e release \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before the atomic operation (in program order) may not be
re-ordered after the atomic operation.
+
+ \sa operator+=(), fetchAndSubRelease()
*/
-/*! \fn int QAtomicInt::fetchAndAddOrdered(int valueToAdd)
+/*! \fn int QAtomicInteger::fetchAndAddOrdered(int valueToAdd)
Atomic fetch-and-add.
- Reads the current value of this QAtomicInt and then adds
+ Reads the current value of this QAtomicInteger and then adds
\a valueToAdd to the current value, returning the original value.
- This function uses \e ordered \l {QAtomicInt#Memory
+ This function uses \e ordered \l {QAtomicInteger#Memory
ordering}{memory ordering} semantics, which ensures that memory
access before and after the atomic operation (in program order)
may not be re-ordered.
+
+ \sa operator+=(), fetchAndSubOrdered()
+*/
+
+/*! \fn int QAtomicInteger::operator+=(int valueToAdd)
+ \since 5.3
+
+ Atomic add-and-fetch.
+
+ Reads the current value of this QAtomicInteger and then adds
+ \a valueToAdd to the current value, returning the new value value.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa fetchAndAddOrdered(), operator-=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndSubRelaxed(int valueToSub)
+ \since 5.3
+
+ Atomic fetch-and-sub.
+
+ Reads the current value of this QAtomicInteger and then subtracts
+ \a valueToSub to the current value, returning the original value.
+
+ This function uses \e relaxed \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, leaving the compiler and
+ processor to freely reorder memory accesses.
+
+ \sa operator-=(), fetchAndAddRelaxed()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndSubAcquire(int valueToSub)
+ \since 5.3
+
+ Atomic fetch-and-sub.
+
+ Reads the current value of this QAtomicInteger and then subtracts
+ \a valueToSub to the current value, returning the original value.
+
+ This function uses \e acquire \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access following the atomic operation (in program order) may not
+ be re-ordered before the atomic operation.
+
+ \sa operator-=(), fetchAndAddAcquire()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndSubRelease(int valueToSub)
+ \since 5.3
+
+ Atomic fetch-and-sub.
+
+ Reads the current value of this QAtomicInteger and then subtracts
+ \a valueToSub to the current value, returning the original value.
+
+ This function uses \e release \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before the atomic operation (in program order) may not be
+ re-ordered after the atomic operation.
+
+ \sa operator-=(), fetchAndAddRelease()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndSubOrdered(int valueToSub)
+ \since 5.3
+
+ Atomic fetch-and-sub.
+
+ Reads the current value of this QAtomicInteger and then subtracts
+ \a valueToSub to the current value, returning the original value.
+
+ This function uses \e ordered \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before and after the atomic operation (in program order)
+ may not be re-ordered.
+
+ \sa operator-=(), fetchAndAddOrdered()
+*/
+
+/*! \fn int QAtomicInteger::operator-=(int valueToSub)
+ \since 5.3
+
+ Atomic sub-and-fetch.
+
+ Reads the current value of this QAtomicInteger and then subtracts
+ \a valueToSub to the current value, returning the new value value.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa fetchAndSubOrdered(), operator+=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndOrRelaxed(int valueToOr)
+ \since 5.3
+
+ Atomic fetch-and-or.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ORs
+ \a valueToOr to the current value, returning the original value.
+
+ This function uses \e relaxed \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, leaving the compiler and
+ processor to freely reorder memory accesses.
+
+ \sa operator|=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndOrAcquire(int valueToOr)
+ \since 5.3
+
+ Atomic fetch-and-or.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ORs
+ \a valueToOr to the current value, returning the original value.
+
+ This function uses \e acquire \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access following the atomic operation (in program order) may not
+ be re-ordered before the atomic operation.
+
+ \sa operator|=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndOrRelease(int valueToOr)
+ \since 5.3
+
+ Atomic fetch-and-or.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ORs
+ \a valueToOr to the current value, returning the original value.
+
+ This function uses \e release \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before the atomic operation (in program order) may not be
+ re-ordered after the atomic operation.
+
+ \sa operator|=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndOrOrdered(int valueToOr)
+ \since 5.3
+
+ Atomic fetch-and-or.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ORs
+ \a valueToOr to the current value, returning the original value.
+
+ This function uses \e ordered \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before and after the atomic operation (in program order)
+ may not be re-ordered.
+
+ \sa operator|=()
+*/
+
+/*! \fn int QAtomicInteger::operator|=(int valueToOr)
+ \since 5.3
+
+ Atomic or-and-fetch.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ORs
+ \a valueToOr to the current value, returning the new value value.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa fetchAndOrOrdered()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndXorRelaxed(int valueToXor)
+ \since 5.3
+
+ Atomic fetch-and-xor.
+
+ Reads the current value of this QAtomicInteger and then bitwise-XORs
+ \a valueToXor to the current value, returning the original value.
+
+ This function uses \e relaxed \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, leaving the compiler and
+ processor to freely reorder memory accesses.
+
+ \sa operator^=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndXorAcquire(int valueToXor)
+ \since 5.3
+
+ Atomic fetch-and-xor.
+
+ Reads the current value of this QAtomicInteger and then bitwise-XORs
+ \a valueToXor to the current value, returning the original value.
+
+ This function uses \e acquire \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access following the atomic operation (in program order) may not
+ be re-ordered before the atomic operation.
+
+ \sa operator^=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndXorRelease(int valueToXor)
+ \since 5.3
+
+ Atomic fetch-and-xor.
+
+ Reads the current value of this QAtomicInteger and then bitwise-XORs
+ \a valueToXor to the current value, returning the original value.
+
+ This function uses \e release \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before the atomic operation (in program order) may not be
+ re-ordered after the atomic operation.
+
+ \sa operator^=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndXorOrdered(int valueToXor)
+ \since 5.3
+
+ Atomic fetch-and-xor.
+
+ Reads the current value of this QAtomicInteger and then bitwise-XORs
+ \a valueToXor to the current value, returning the original value.
+
+ This function uses \e ordered \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before and after the atomic operation (in program order)
+ may not be re-ordered.
+
+ \sa operator^=()
+*/
+
+/*! \fn int QAtomicInteger::operator^=(int valueToXor)
+ \since 5.3
+
+ Atomic xor-and-fetch.
+
+ Reads the current value of this QAtomicInteger and then bitwise-XORs
+ \a valueToXor to the current value, returning the new value value.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa fetchAndXorOrdered()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndAndRelaxed(int valueToAnd)
+ \since 5.3
+
+ Atomic fetch-and-and.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ANDs
+ \a valueToAnd to the current value, returning the original value.
+
+ This function uses \e relaxed \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, leaving the compiler and
+ processor to freely reorder memory accesses.
+
+ \sa operator&=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndAndAcquire(int valueToAnd)
+ \since 5.3
+
+ Atomic fetch-and-and.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ANDs
+ \a valueToAnd to the current value, returning the original value.
+
+ This function uses \e acquire \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access following the atomic operation (in program order) may not
+ be re-ordered before the atomic operation.
+
+ \sa operator&=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndAndRelease(int valueToAnd)
+ \since 5.3
+
+ Atomic fetch-and-and.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ANDs
+ \a valueToAnd to the current value, returning the original value.
+
+ This function uses \e release \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before the atomic operation (in program order) may not be
+ re-ordered after the atomic operation.
+
+ \sa operator&=()
+*/
+
+/*! \fn int QAtomicInteger::fetchAndAndOrdered(int valueToAnd)
+ \since 5.3
+
+ Atomic fetch-and-and.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ANDs
+ \a valueToAnd to the current value, returning the original value.
+
+ This function uses \e ordered \l {QAtomicInteger#Memory
+ ordering}{memory ordering} semantics, which ensures that memory
+ access before and after the atomic operation (in program order)
+ may not be re-ordered.
+
+ \sa operator&=()
+*/
+
+/*! \fn int QAtomicInteger::operator&=(int valueToAnd)
+ \since 5.3
+
+ Atomic add-and-fetch.
+
+ Reads the current value of this QAtomicInteger and then bitwise-ANDs
+ \a valueToAnd to the current value, returning the new value value.
+
+ This function uses a sequentially consistent memory ordering if possible;
+ or "Ordered" ordering if not.
+
+ \sa fetchAndAndOrdered()
*/
/*!
- \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_IS_SUPPORTED
+ \relates QAtomicInteger
+
+ This macro is defined if atomic integers of size \e{nn} (in bits) are
+ supported in this compiler / architecture combination.
+ Q_ATOMIC_INT32_IS_SUPPORTED is always defined.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
+*/
+
+/*!
+ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
+ \relates QAtomicInteger
This macro is defined if and only if all generations of your
processor support atomic reference counting.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
+ \relates QAtomicInteger
This macro is defined when only certain generations of the
processor support atomic reference counting. Use the
- QAtomicInt::isReferenceCountingNative() function to check what
+ QAtomicInteger::isReferenceCountingNative() function to check what
your processor supports.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_NOT_NATIVE
+ \relates QAtomicInteger
This macro is defined when the hardware does not support atomic
reference counting.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_WAIT_FREE
+ \relates QAtomicInteger
This macro is defined together with
- Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE to indicate that
+ Q_ATOMIC_INTnn_REFERENCE_COUNTING_IS_ALWAYS_NATIVE to indicate that
the reference counting is wait-free.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE
+ \relates QAtomicInteger
This macro is defined if and only if your processor supports
atomic test-and-set on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_SOMETIMES_NATIVE
+ \relates QAtomicInteger
This macro is defined when only certain generations of the
processor support atomic test-and-set on integers. Use the
- QAtomicInt::isTestAndSetNative() function to check what your
+ QAtomicInteger::isTestAndSetNative() function to check what your
processor supports.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_NOT_NATIVE
+ \relates QAtomicInteger
This macro is defined when the hardware does not support atomic
test-and-set on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_TEST_AND_SET_IS_WAIT_FREE
+ \relates QAtomicInteger
This macro is defined together with
- Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that the
+ Q_ATOMIC_INTnn_TEST_AND_SET_IS_ALWAYS_NATIVE to indicate that the
atomic test-and-set on integers is wait-free.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE
+ \relates QAtomicInteger
This macro is defined if and only if your processor supports
atomic fetch-and-store on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
+ \relates QAtomicInteger
This macro is defined when only certain generations of the
processor support atomic fetch-and-store on integers. Use the
- QAtomicInt::isFetchAndStoreNative() function to check what your
+ QAtomicInteger::isFetchAndStoreNative() function to check what your
processor supports.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_NOT_NATIVE
+ \relates QAtomicInteger
This macro is defined when the hardware does not support atomic
fetch-and-store on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_WAIT_FREE
+ \relates QAtomicInteger
This macro is defined together with
- Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that the
+ Q_ATOMIC_INTnn_FETCH_AND_STORE_IS_ALWAYS_NATIVE to indicate that the
atomic fetch-and-store on integers is wait-free.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE
+ \relates QAtomicInteger
This macro is defined if and only if your processor supports
atomic fetch-and-add on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
+ \relates QAtomicInteger
This macro is defined when only certain generations of the
processor support atomic fetch-and-add on integers. Use the
- QAtomicInt::isFetchAndAddNative() function to check what your
+ QAtomicInteger::isFetchAndAddNative() function to check what your
processor supports.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_NOT_NATIVE
+ \relates QAtomicInteger
This macro is defined when the hardware does not support atomic
fetch-and-add on integers.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
/*!
- \macro Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE
- \relates QAtomicInt
+ \macro Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_WAIT_FREE
+ \relates QAtomicInteger
This macro is defined together with
- Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that the
+ Q_ATOMIC_INTnn_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that the
atomic fetch-and-add on integers is wait-free.
+
+ \e{nn} is the size of the integer, in bits (8, 16, 32 or 64).
*/
@@ -637,7 +1125,7 @@
\ingroup thread
- For atomic operations on integers, see the QAtomicInt class.
+ For atomic operations on integers, see the QAtomicInteger class.
An \e atomic operation is a complex operation that completes without interruption.
The QAtomicPointer class provides atomic test-and-set, fetch-and-store, and fetch-and-add for pointers.
@@ -769,7 +1257,7 @@
\endlist
- \sa QAtomicInt
+ \sa QAtomicInteger
*/
/*! \fn QAtomicPointer::QAtomicPointer(T *value)
@@ -1126,3 +1614,46 @@
Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE to indicate that
the atomic fetch-and-add on pointers is wait-free.
*/
+
+// static checks
+#ifndef Q_ATOMIC_INT32_IS_SUPPORTED
+# error "Q_ATOMIC_INT32_IS_SUPPORTED must be defined"
+#endif
+#if !defined(Q_ATOMIC_INT64_IS_SUPPORTED) && QT_POINTER_SIZE == 8
+// 64-bit platform
+# error "Q_ATOMIC_INT64_IS_SUPPORTED must be defined on a 64-bit platform"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+// The following specializations must always be defined
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<long>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned long>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<quintptr>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<qptrdiff>));
+#ifdef Q_COMPILER_UNICODE_STRINGS
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<char32_t>));
+#endif
+
+#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<short>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<unsigned short>));
+# if WCHAR_MAX < 0x10000
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>));
+# endif
+# ifdef Q_COMPILER_UNICODE_STRINGS
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<char16_t>));
+# endif
+#endif
+
+#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<qint64>));
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<quint64>));
+#endif
+
+#if WCHAR_MAX == INT_MAX
+Q_STATIC_ASSERT(sizeof(QAtomicInteger<wchar_t>));
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index 1ccaecc135..1faaa22d0f 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -55,27 +55,31 @@ QT_BEGIN_NAMESPACE
#endif
// High-level atomic integer operations
-class QAtomicInt : public QBasicAtomicInt
+template <typename T>
+class QAtomicInteger : public QBasicAtomicInteger<T>
{
public:
// Non-atomic API
-#ifdef Q_BASIC_ATOMIC_HAS_CONSTRUCTORS
- constexpr QAtomicInt(int value = 0) Q_DECL_NOTHROW : QBasicAtomicInt(value) {}
+#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
+ constexpr QAtomicInteger(T value = 0) Q_DECL_NOTHROW : QBasicAtomicInteger<T>(value) {}
#else
- inline QAtomicInt(int value = 0) Q_DECL_NOTHROW
+ inline QAtomicInteger(T value = 0) Q_DECL_NOTHROW
{
- _q_value = value;
+ this->_q_value = value;
}
#endif
- inline QAtomicInt(const QAtomicInt &other) Q_DECL_NOTHROW
+ inline QAtomicInteger(const QAtomicInteger &other) Q_DECL_NOTHROW
+#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
+ : QBasicAtomicInteger<T>()
+#endif
{
- store(other.load());
+ this->storeRelease(other.loadAcquire());
}
- inline QAtomicInt &operator=(const QAtomicInt &other) Q_DECL_NOTHROW
+ inline QAtomicInteger &operator=(const QAtomicInteger &other) Q_DECL_NOTHROW
{
- this->store(other.load());
+ this->storeRelease(other.loadAcquire());
return *this;
}
@@ -85,6 +89,9 @@ public:
void store(int newValue);
void storeRelease(int newValue);
+ operator int() const;
+ QAtomicInteger &operator=(int);
+
static Q_DECL_CONSTEXPR bool isReferenceCountingNative();
static Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree();
@@ -114,7 +121,49 @@ public:
int fetchAndAddAcquire(int valueToAdd);
int fetchAndAddRelease(int valueToAdd);
int fetchAndAddOrdered(int valueToAdd);
+
+ int fetchAndSubRelaxed(int valueToSub);
+ int fetchAndSubAcquire(int valueToSub);
+ int fetchAndSubRelease(int valueToSub);
+ int fetchAndSubOrdered(int valueToSub);
+
+ int fetchAndOrRelaxed(int valueToOr);
+ int fetchAndOrAcquire(int valueToOr);
+ int fetchAndOrRelease(int valueToOr);
+ int fetchAndOrOrdered(int valueToOr);
+
+ int fetchAndAndRelaxed(int valueToAnd);
+ int fetchAndAndAcquire(int valueToAnd);
+ int fetchAndAndRelease(int valueToAnd);
+ int fetchAndAndOrdered(int valueToAnd);
+
+ int fetchAndXorRelaxed(int valueToXor);
+ int fetchAndXorAcquire(int valueToXor);
+ int fetchAndXorRelease(int valueToXor);
+ int fetchAndXorOrdered(int valueToXor);
+
+ int operator++();
+ int operator++(int);
+ int operator--();
+ int operator--(int);
+ int operator+=(int value);
+ int operator-=(int value);
+ int operator|=(int value);
+ int operator&=(int value);
+ int operator^=(int value);
+#endif
+};
+
+class QAtomicInt : public QAtomicInteger<int>
+{
+public:
+ // Non-atomic API
+ // We could use QT_COMPILER_INHERITING_CONSTRUCTORS, but we need only one;
+ // the implicit definition for all the others is fine.
+#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
+ constexpr
#endif
+ QAtomicInt(int value = 0) Q_DECL_NOTHROW : QAtomicInteger<int>(value) {}
};
// High-level atomic pointer operations
@@ -132,12 +181,12 @@ public:
#endif
inline QAtomicPointer(const QAtomicPointer<T> &other) Q_DECL_NOTHROW
{
- this->store(other.load());
+ this->storeRelease(other.loadAcquire());
}
inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) Q_DECL_NOTHROW
{
- this->store(other.load());
+ this->storeRelease(other.loadAcquire());
return *this;
}
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 782ae90698..cf69d34589 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -51,33 +51,17 @@
#elif defined(Q_CC_MSVC)
# include <QtCore/qatomic_msvc.h>
-// Operating system dependent implementation
-#elif defined(Q_OS_INTEGRITY)
-# include "QtCore/qatomic_integrity.h"
-#elif defined(Q_OS_VXWORKS)
-# include "QtCore/qatomic_vxworks.h"
-
// Processor dependent implementation
-#elif defined(Q_PROCESSOR_ALPHA)
-# include "QtCore/qatomic_alpha.h"
#elif defined(Q_PROCESSOR_ARM_V7) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv7.h"
#elif defined(Q_PROCESSOR_ARM_V6) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv6.h"
#elif defined(Q_PROCESSOR_ARM_V5) && defined(Q_PROCESSOR_ARM_32)
# include "QtCore/qatomic_armv5.h"
-#elif defined(Q_PROCESSOR_BFIN)
-# include "QtCore/qatomic_bfin.h"
#elif defined(Q_PROCESSOR_IA64)
# include "QtCore/qatomic_ia64.h"
#elif defined(Q_PROCESSOR_MIPS)
# include "QtCore/qatomic_mips.h"
-#elif defined(Q_PROCESSOR_POWER)
-# include "QtCore/qatomic_power.h"
-#elif defined(Q_PROCESSOR_S390)
-# include "QtCore/qatomic_s390.h"
-#elif defined(Q_PROCESSOR_SH4A)
-# include "QtCore/qatomic_sh4a.h"
#elif defined(Q_PROCESSOR_SPARC)
# include "QtCore/qatomic_sparc.h"
#elif defined(Q_PROCESSOR_X86)
@@ -98,9 +82,6 @@
# error "Qt has not been ported to this platform"
#endif
-// Only include if the implementation has been ported to QAtomicOps
-#ifndef QOLDBASICATOMIC_H
-
QT_BEGIN_NAMESPACE
#if 0
@@ -133,7 +114,8 @@ class QBasicAtomicInteger
public:
typedef QAtomicOps<T> Ops;
// static check that this is a valid integer
- typedef char PermittedIntegerType[QAtomicIntegerTraits<T>::IsInteger ? 1 : -1];
+ Q_STATIC_ASSERT_X(QTypeInfo<T>::isIntegral, "template parameter is not an integral type");
+ Q_STATIC_ASSERT_X(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
typename Ops::Type _q_value;
@@ -144,6 +126,8 @@ public:
T loadAcquire() const Q_DECL_NOTHROW { return Ops::loadAcquire(_q_value); }
void storeRelease(T newValue) Q_DECL_NOTHROW { Ops::storeRelease(_q_value, newValue); }
+ operator T() const Q_DECL_NOTHROW { return loadAcquire(); }
+ T operator=(T newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; }
static Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return Ops::isReferenceCountingNative(); }
static Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return Ops::isReferenceCountingWaitFree(); }
@@ -163,6 +147,15 @@ public:
bool testAndSetOrdered(T expectedValue, T newValue) Q_DECL_NOTHROW
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
+ bool testAndSetRelaxed(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetAcquire(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetRelease(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetOrdered(T expectedValue, T newValue, T &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
+
static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return Ops::isFetchAndStoreNative(); }
static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndStoreWaitFree(); }
@@ -187,6 +180,63 @@ public:
T fetchAndAddOrdered(T valueToAdd) Q_DECL_NOTHROW
{ return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
+ T fetchAndSubRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
+ T fetchAndSubAcquire(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
+ T fetchAndSubRelease(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
+ T fetchAndSubOrdered(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
+
+ T fetchAndAndRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndAndRelaxed(_q_value, valueToAdd); }
+ T fetchAndAndAcquire(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndAndAcquire(_q_value, valueToAdd); }
+ T fetchAndAndRelease(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndAndRelease(_q_value, valueToAdd); }
+ T fetchAndAndOrdered(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndAndOrdered(_q_value, valueToAdd); }
+
+ T fetchAndOrRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndOrRelaxed(_q_value, valueToAdd); }
+ T fetchAndOrAcquire(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndOrAcquire(_q_value, valueToAdd); }
+ T fetchAndOrRelease(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndOrRelease(_q_value, valueToAdd); }
+ T fetchAndOrOrdered(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndOrOrdered(_q_value, valueToAdd); }
+
+ T fetchAndXorRelaxed(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndXorRelaxed(_q_value, valueToAdd); }
+ T fetchAndXorAcquire(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndXorAcquire(_q_value, valueToAdd); }
+ T fetchAndXorRelease(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndXorRelease(_q_value, valueToAdd); }
+ T fetchAndXorOrdered(T valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndXorOrdered(_q_value, valueToAdd); }
+
+ T operator++() Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(1) + 1; }
+ T operator++(int) Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(1); }
+ T operator--() Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(1) - 1; }
+ T operator--(int) Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(1); }
+
+ T operator+=(T v) Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(v) + v; }
+ T operator-=(T v) Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(v) - v; }
+ T operator&=(T v) Q_DECL_NOTHROW
+ { return fetchAndAndOrdered(v) & v; }
+ T operator|=(T v) Q_DECL_NOTHROW
+ { return fetchAndOrOrdered(v) | v; }
+ T operator^=(T v) Q_DECL_NOTHROW
+ { return fetchAndXorOrdered(v) ^ v; }
+
+
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
QBasicAtomicInteger() = default;
constexpr QBasicAtomicInteger(T value) Q_DECL_NOTHROW : _q_value(value) {}
@@ -207,9 +257,10 @@ public:
AtomicType _q_value;
- // Non-atomic API
Type load() const Q_DECL_NOTHROW { return _q_value; }
void store(Type newValue) Q_DECL_NOTHROW { _q_value = newValue; }
+ operator Type() const Q_DECL_NOTHROW { return loadAcquire(); }
+ Type operator=(Type newValue) Q_DECL_NOTHROW { storeRelease(newValue); return newValue; }
// Atomic API, implemented in qatomic_XXX.h
Type loadAcquire() const Q_DECL_NOTHROW { return Ops::loadAcquire(_q_value); }
@@ -227,6 +278,15 @@ public:
bool testAndSetOrdered(Type expectedValue, Type newValue) Q_DECL_NOTHROW
{ return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); }
+ bool testAndSetRelaxed(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetAcquire(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetRelease(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, &currentValue); }
+ bool testAndSetOrdered(Type expectedValue, Type newValue, Type &currentValue) Q_DECL_NOTHROW
+ { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, &currentValue); }
+
static Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return Ops::isFetchAndStoreNative(); }
static Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return Ops::isFetchAndStoreWaitFree(); }
@@ -251,6 +311,28 @@ public:
Type fetchAndAddOrdered(qptrdiff valueToAdd) Q_DECL_NOTHROW
{ return Ops::fetchAndAddOrdered(_q_value, valueToAdd); }
+ Type fetchAndSubRelaxed(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); }
+ Type fetchAndSubAcquire(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); }
+ Type fetchAndSubRelease(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubRelease(_q_value, valueToAdd); }
+ Type fetchAndSubOrdered(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); }
+
+ Type operator++() Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(1) + 1; }
+ Type operator++(int) Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(1); }
+ Type operator--() Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(1) - 1; }
+ Type operator--(int) Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(1); }
+ Type operator+=(qptrdiff valueToAdd) Q_DECL_NOTHROW
+ { return fetchAndAddOrdered(valueToAdd) + valueToAdd; }
+ Type operator-=(qptrdiff valueToSub) Q_DECL_NOTHROW
+ { return fetchAndSubOrdered(valueToSub) - valueToSub; }
+
#ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS
QBasicAtomicPointer() = default;
constexpr QBasicAtomicPointer(Type value) Q_DECL_NOTHROW : _q_value(value) {}
@@ -266,6 +348,4 @@ public:
QT_END_NAMESPACE
-#endif // QOLDBASICATOMIC_H
-
#endif // QBASICATOMIC_H
diff --git a/src/corelib/thread/qgenericatomic.h b/src/corelib/thread/qgenericatomic.h
index 3a213f6a25..0c66d45855 100644
--- a/src/corelib/thread/qgenericatomic.h
+++ b/src/corelib/thread/qgenericatomic.h
@@ -43,6 +43,7 @@
#define QGENERICATOMIC_H
#include <QtCore/qglobal.h>
+#include <QtCore/qtypeinfo.h>
QT_BEGIN_NAMESPACE
@@ -60,7 +61,8 @@ QT_END_NAMESPACE
#define always_inline
#endif
-template<typename T> struct QAtomicIntegerTraits { enum { IsInteger = 0 }; };
+template<int> struct QAtomicOpsSupport { enum { IsSupported = 0 }; };
+template<> struct QAtomicOpsSupport<4> { enum { IsSupported = 1 }; };
template <typename T> struct QAtomicAdditiveType
{
@@ -140,6 +142,8 @@ template <typename BaseClass> struct QGenericAtomicOps
static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW;
template <typename T, typename X> static inline
bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue) Q_DECL_NOTHROW;
+ template <typename T, typename X> static inline
+ bool testAndSetRelaxed(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW;
#endif
template <typename T, typename X> static inline always_inline
@@ -164,6 +168,28 @@ template <typename BaseClass> struct QGenericAtomicOps
return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue);
}
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetAcquire(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ {
+ bool tmp = BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
+ BaseClass::acquireMemoryFence(_q_value);
+ return tmp;
+ }
+
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetRelease(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ {
+ BaseClass::releaseMemoryFence(_q_value);
+ return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
+ }
+
+ template <typename T, typename X> static inline always_inline
+ bool testAndSetOrdered(T &_q_value, X expectedValue, X newValue, X *currentValue) Q_DECL_NOTHROW
+ {
+ BaseClass::orderedMemoryFence(_q_value);
+ return BaseClass::testAndSetRelaxed(_q_value, expectedValue, newValue, currentValue);
+ }
+
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return false; }
static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
@@ -234,6 +260,138 @@ template <typename BaseClass> struct QGenericAtomicOps
BaseClass::orderedMemoryFence(_q_value);
return BaseClass::fetchAndAddRelaxed(_q_value, valueToAdd);
}
+
+ template <typename T> static inline always_inline
+ T fetchAndSubRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ {
+ // implement fetchAndSub on top of testAndSet
+ Q_FOREVER {
+ T tmp = BaseClass::load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp - operand)))
+ return tmp;
+ }
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndSubAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ {
+ T tmp = BaseClass::fetchAndSubRelaxed(_q_value, operand);
+ BaseClass::acquireMemoryFence(_q_value);
+ return tmp;
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndSubRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ {
+ BaseClass::releaseMemoryFence(_q_value);
+ return BaseClass::fetchAndSubRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndSubOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT operand) Q_DECL_NOTHROW
+ {
+ BaseClass::orderedMemoryFence(_q_value);
+ return BaseClass::fetchAndSubRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAndRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ // implement fetchAndAnd on top of testAndSet
+ Q_FOREVER {
+ T tmp = BaseClass::load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp & operand)))
+ return tmp;
+ }
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAndAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ T tmp = BaseClass::fetchAndAndRelaxed(_q_value, operand);
+ BaseClass::acquireMemoryFence(_q_value);
+ return tmp;
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAndRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::releaseMemoryFence(_q_value);
+ return BaseClass::fetchAndAndRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndAndOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::orderedMemoryFence(_q_value);
+ return BaseClass::fetchAndAndRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndOrRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ // implement fetchAndOr on top of testAndSet
+ Q_FOREVER {
+ T tmp = BaseClass::load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp | operand)))
+ return tmp;
+ }
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndOrAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ T tmp = BaseClass::fetchAndOrRelaxed(_q_value, operand);
+ BaseClass::acquireMemoryFence(_q_value);
+ return tmp;
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndOrRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::releaseMemoryFence(_q_value);
+ return BaseClass::fetchAndOrRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndOrOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::orderedMemoryFence(_q_value);
+ return BaseClass::fetchAndOrRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndXorRelaxed(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ // implement fetchAndXor on top of testAndSet
+ Q_FOREVER {
+ T tmp = BaseClass::load(_q_value);
+ if (BaseClass::testAndSetRelaxed(_q_value, tmp, T(tmp ^ operand)))
+ return tmp;
+ }
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndXorAcquire(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ T tmp = BaseClass::fetchAndXorRelaxed(_q_value, operand);
+ BaseClass::acquireMemoryFence(_q_value);
+ return tmp;
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndXorRelease(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::releaseMemoryFence(_q_value);
+ return BaseClass::fetchAndXorRelaxed(_q_value, operand);
+ }
+
+ template <typename T> static inline always_inline
+ T fetchAndXorOrdered(T &_q_value, typename QtPrivate::QEnableIf<QTypeInfo<T>::isIntegral, T>::Type operand) Q_DECL_NOTHROW
+ {
+ BaseClass::orderedMemoryFence(_q_value);
+ return BaseClass::fetchAndXorRelaxed(_q_value, operand);
+ }
};
#undef always_inline
diff --git a/src/corelib/thread/qmutex_win.cpp b/src/corelib/thread/qmutex_win.cpp
index 14b7f34008..a8cdf85fb6 100644
--- a/src/corelib/thread/qmutex_win.cpp
+++ b/src/corelib/thread/qmutex_win.cpp
@@ -48,7 +48,12 @@ QT_BEGIN_NAMESPACE
QMutexPrivate::QMutexPrivate()
{
+#ifndef Q_OS_WINRT
event = CreateEvent(0, FALSE, FALSE, 0);
+#else
+ event = CreateEventEx(0, NULL, 0, EVENT_ALL_ACCESS);
+#endif
+
if (!event)
qWarning("QMutexData::QMutexData: Cannot create event");
}
@@ -58,7 +63,11 @@ QMutexPrivate::~QMutexPrivate()
bool QMutexPrivate::wait(int timeout)
{
+#ifndef Q_OS_WINRT
return (WaitForSingleObject(event, timeout < 0 ? INFINITE : timeout) == WAIT_OBJECT_0);
+#else
+ return (WaitForSingleObjectEx(event, timeout < 0 ? INFINITE : timeout, FALSE) == WAIT_OBJECT_0);
+#endif
}
void QMutexPrivate::wakeUp() Q_DECL_NOTHROW
diff --git a/src/corelib/thread/qoldbasicatomic.h b/src/corelib/thread/qoldbasicatomic.h
deleted file mode 100644
index b755256ff7..0000000000
--- a/src/corelib/thread/qoldbasicatomic.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QOLDBASICATOMIC_H
-#define QOLDBASICATOMIC_H
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-
-#if 0
-// silence syncqt warnings
-QT_END_NAMESPACE
-#pragma qt_sync_skip_header_check
-#pragma qt_no_master_include
-#pragma qt_sync_stop_processing
-#endif
-
-class Q_CORE_EXPORT QBasicAtomicInt
-{
-public:
- volatile int _q_value;
-
- // Atomic API, implemented in qatomic_XXX.h
-
- int load() const { return _q_value; }
- int loadAcquire() { return _q_value; }
- void store(int newValue) { _q_value = newValue; }
- void storeRelease(int newValue) { _q_value = newValue; }
-
- static bool isReferenceCountingNative();
- static bool isReferenceCountingWaitFree();
-
- bool ref();
- bool deref();
-
- static bool isTestAndSetNative();
- static bool isTestAndSetWaitFree();
-
- bool testAndSetRelaxed(int expectedValue, int newValue);
- bool testAndSetAcquire(int expectedValue, int newValue);
- bool testAndSetRelease(int expectedValue, int newValue);
- bool testAndSetOrdered(int expectedValue, int newValue);
-
- static bool isFetchAndStoreNative();
- static bool isFetchAndStoreWaitFree();
-
- int fetchAndStoreRelaxed(int newValue);
- int fetchAndStoreAcquire(int newValue);
- int fetchAndStoreRelease(int newValue);
- int fetchAndStoreOrdered(int newValue);
-
- static bool isFetchAndAddNative();
- static bool isFetchAndAddWaitFree();
-
- int fetchAndAddRelaxed(int valueToAdd);
- int fetchAndAddAcquire(int valueToAdd);
- int fetchAndAddRelease(int valueToAdd);
- int fetchAndAddOrdered(int valueToAdd);
-};
-
-template <typename T>
-class QBasicAtomicPointer
-{
-public:
- T * volatile _q_value;
-
- // Atomic API, implemented in qatomic_XXX.h
-
- T *load() const { return _q_value; }
- T *loadAcquire() { return _q_value; }
- void store(T *newValue) { _q_value = newValue; }
- void storeRelease(T *newValue) { _q_value = newValue; }
-
- static bool isTestAndSetNative();
- static bool isTestAndSetWaitFree();
-
- bool testAndSetRelaxed(T *expectedValue, T *newValue);
- bool testAndSetAcquire(T *expectedValue, T *newValue);
- bool testAndSetRelease(T *expectedValue, T *newValue);
- bool testAndSetOrdered(T *expectedValue, T *newValue);
-
- static bool isFetchAndStoreNative();
- static bool isFetchAndStoreWaitFree();
-
- T *fetchAndStoreRelaxed(T *newValue);
- T *fetchAndStoreAcquire(T *newValue);
- T *fetchAndStoreRelease(T *newValue);
- T *fetchAndStoreOrdered(T *newValue);
-
- static bool isFetchAndAddNative();
- static bool isFetchAndAddWaitFree();
-
- T *fetchAndAddRelaxed(qptrdiff valueToAdd);
- T *fetchAndAddAcquire(qptrdiff valueToAdd);
- T *fetchAndAddRelease(qptrdiff valueToAdd);
- T *fetchAndAddOrdered(qptrdiff valueToAdd);
-};
-
-#define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) }
-
-QT_END_NAMESPACE
-
-#endif // QOLDBASICATOMIC_H
diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp
index 50ccca9eda..adad4b81a1 100644
--- a/src/corelib/thread/qthread.cpp
+++ b/src/corelib/thread/qthread.cpp
@@ -154,7 +154,9 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
thread_id = 0;
#elif defined (Q_OS_WIN)
handle = 0;
+# ifndef Q_OS_WINRT
id = 0;
+# endif
waiters = 0;
#endif
#if defined (Q_OS_WIN)
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index fce84e881b..e2951b125f 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -66,6 +66,10 @@
#include <algorithm>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
+
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
@@ -173,8 +177,13 @@ public:
static unsigned int __stdcall start(void *);
static void finish(void *, bool lockAnyway=true);
+# ifndef Q_OS_WINRT
Qt::HANDLE handle;
unsigned int id;
+# else
+ std::thread *handle;
+ std::thread::id id;
+# endif
int waiters;
bool terminationEnabled, terminatePending;
# endif
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 865b1e6af5..db5c13157c 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
//#define WINVER 0x0500
-#if _WIN32_WINNT < 0x0400
+#if (_WIN32_WINNT < 0x0400) && !defined(Q_OS_WINRT)
#define _WIN32_WINNT 0x0400
#endif
@@ -54,10 +54,17 @@
#include <qpointer.h>
#include <private/qcoreapplication_p.h>
+#ifdef Q_OS_WINRT
+#include <private/qeventdispatcher_winrt_p.h>
+#else
#include <private/qeventdispatcher_win_p.h>
+#endif
#include <qt_windows.h>
+#ifdef Q_OS_WINRT
+#include <thread>
+#endif
#ifndef Q_OS_WINCE
#ifndef _MT
@@ -71,6 +78,7 @@
#ifndef QT_NO_THREAD
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
void qt_watch_adopted_thread(const HANDLE adoptedThreadHandle, QThread *qthread);
DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID);
@@ -92,6 +100,38 @@ static void qt_free_tls()
}
}
Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#else // !Q_OS_WINRT
+
+__declspec(thread) static QThreadData* qt_current_thread_data_tls_index = 0;
+void qt_create_tls()
+{
+}
+
+static void qt_free_tls()
+{
+ if (qt_current_thread_data_tls_index) {
+ qt_current_thread_data_tls_index->deref();
+ qt_current_thread_data_tls_index = 0;
+ }
+}
+
+QThreadData* TlsGetValue(QThreadData*& tls)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ return tls;
+}
+
+void TlsSetValue(QThreadData*& tls, QThreadData* data)
+{
+ Q_ASSERT(tls == qt_current_thread_data_tls_index);
+ if (tls)
+ tls->deref();
+ tls = data;
+ if (tls)
+ tls->ref();
+}
+Q_DESTRUCTOR_FUNCTION(qt_free_tls)
+#endif // Q_OS_WINRT
/*
QThreadData
@@ -124,6 +164,9 @@ QThreadData *QThreadData::current(bool createIfNecessary)
if (!QCoreApplicationPrivate::theMainThread) {
QCoreApplicationPrivate::theMainThread = threadData->thread;
+#ifndef Q_OS_WINRT
+ // TODO: is there a way to reflect the branch's behavior using
+ // WinRT API?
} else {
HANDLE realHandle = INVALID_HANDLE_VALUE;
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
@@ -138,6 +181,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
realHandle = reinterpret_cast<HANDLE>(GetCurrentThreadId());
#endif
qt_watch_adopted_thread(realHandle, threadData->thread);
+#endif // !Q_OS_WINRT
}
}
return threadData;
@@ -145,10 +189,16 @@ QThreadData *QThreadData::current(bool createIfNecessary)
void QAdoptedThread::init()
{
+#ifndef Q_OS_WINRT
d_func()->handle = GetCurrentThread();
d_func()->id = GetCurrentThreadId();
+#else
+ d_func()->handle = nullptr;
+ d_func()->id = std::this_thread::get_id();
+#endif
}
+#ifndef Q_OS_WINRT
static QVector<HANDLE> qt_adopted_thread_handles;
static QVector<QThread *> qt_adopted_qthreads;
static QMutex qt_adopted_thread_watcher_mutex;
@@ -301,6 +351,7 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
}
}
#endif // !QT_NO_DEBUG && Q_CC_MSVC && !Q_OS_WINCE
+#endif // !Q_OS_WINRT
/**************************************************************************
** QThreadPrivate
@@ -310,7 +361,11 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
+#ifdef Q_OS_WINRT
+ QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT;
+#else
QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
+#endif
data->eventDispatcher.storeRelease(theEventDispatcher);
theEventDispatcher->startingUp();
}
@@ -338,7 +393,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
else
createEventDispatcher(data);
-#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
+#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
QByteArray objectName = thr->objectName().toLocal8Bit();
qt_set_thread_name((HANDLE)-1,
@@ -384,11 +439,20 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway)
d->interruptionRequested = false;
if (!d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ d->handle->detach();
+ delete d->handle;
+#endif
d->handle = 0;
}
+#ifndef Q_OS_WINRT
d->id = 0;
+#else
+ d->id = std::thread::id();
+#endif
}
@@ -404,10 +468,15 @@ Qt::HANDLE QThread::currentThreadId() Q_DECL_NOTHROW
int QThread::idealThreadCount() Q_DECL_NOTHROW
{
SYSTEM_INFO sysinfo;
+#ifndef Q_OS_WINRT
GetSystemInfo(&sysinfo);
+#else
+ GetNativeSystemInfo(&sysinfo);
+#endif
return sysinfo.dwNumberOfProcessors;
}
+#ifndef Q_OS_WINRT
void QThread::yieldCurrentThread()
{
#ifndef Q_OS_WINCE
@@ -431,7 +500,28 @@ void QThread::usleep(unsigned long usecs)
{
::Sleep((usecs / 1000) + 1);
}
+#else // !Q_OS_WINRT
+
+void QThread::yieldCurrentThread()
+{
+ std::this_thread::yield();
+}
+void QThread::sleep(unsigned long secs)
+{
+ std::this_thread::sleep_for(std::chrono::seconds(secs));
+}
+
+void QThread::msleep(unsigned long msecs)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(msecs));
+}
+
+void QThread::usleep(unsigned long usecs)
+{
+ std::this_thread::sleep_for(std::chrono::microseconds(usecs));
+}
+#endif // Q_OS_WINRT
void QThread::start(Priority priority)
{
@@ -453,6 +543,7 @@ void QThread::start(Priority priority)
d->returnCode = 0;
d->interruptionRequested = false;
+#ifndef Q_OS_WINRT
/*
NOTE: we create the thread in the suspended state, set the
priority and then resume the thread.
@@ -517,6 +608,23 @@ void QThread::start(Priority priority)
if (ResumeThread(d->handle) == (DWORD) -1) {
qErrnoWarning("QThread::start: Failed to resume new thread");
}
+#else // !Q_OS_WINRT
+ d->handle = new std::thread(QThreadPrivate::start, this);
+
+ if (!d->handle) {
+ qErrnoWarning(errno, "QThread::start: Failed to create thread");
+ d->running = false;
+ d->finished = true;
+ return;
+ }
+
+ d->id = d->handle->get_id();
+
+ if (priority != NormalPriority || priority != InheritPriority) {
+ qWarning("QThread::start: Failed to set thread priority (not implemented)");
+ d->priority = NormalPriority;
+ }
+#endif // Q_OS_WINRT
}
void QThread::terminate()
@@ -529,7 +637,12 @@ void QThread::terminate()
d->terminatePending = true;
return;
}
+
+#ifndef Q_OS_WINRT
TerminateThread(d->handle, 0);
+#else // !Q_OS_WINRT
+ qWarning("QThread::terminate: Terminate is not supported on WinRT");
+#endif // Q_OS_WINRT
QThreadPrivate::finish(this, false);
}
@@ -538,7 +651,11 @@ bool QThread::wait(unsigned long time)
Q_D(QThread);
QMutexLocker locker(&d->mutex);
+#ifndef Q_OS_WINRT
if (d->id == GetCurrentThreadId()) {
+#else
+ if (d->id == std::this_thread::get_id()) {
+#endif
qWarning("QThread::wait: Thread tried to wait on itself");
return false;
}
@@ -549,6 +666,7 @@ bool QThread::wait(unsigned long time)
locker.mutex()->unlock();
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(d->handle, time)) {
case WAIT_OBJECT_0:
ret = true;
@@ -561,6 +679,24 @@ bool QThread::wait(unsigned long time)
default:
break;
}
+#else // !Q_OS_WINRT
+ if (d->handle->joinable()) {
+ HANDLE handle = d->handle->native_handle();
+ switch (WaitForSingleObjectEx(handle, time, FALSE)) {
+ case WAIT_OBJECT_0:
+ ret = true;
+ d->handle->join();
+ break;
+ case WAIT_FAILED:
+ qErrnoWarning("QThread::wait: WaitForSingleObjectEx() failed");
+ break;
+ case WAIT_ABANDONED:
+ case WAIT_TIMEOUT:
+ default:
+ break;
+ }
+ }
+#endif // Q_OS_WINRT
locker.mutex()->lock();
--d->waiters;
@@ -572,7 +708,12 @@ bool QThread::wait(unsigned long time)
}
if (d->finished && !d->waiters) {
+#ifndef Q_OS_WINRT
CloseHandle(d->handle);
+#else
+ d->handle->detach();
+ delete d->handle;
+#endif
d->handle = 0;
}
@@ -590,13 +731,16 @@ void QThread::setTerminationEnabled(bool enabled)
if (enabled && d->terminatePending) {
QThreadPrivate::finish(thr, false);
locker.unlock(); // don't leave the mutex locked!
+#ifndef Q_OS_WINRT
_endthreadex(0);
+#endif
}
}
// Caller must hold the mutex
void QThreadPrivate::setPriority(QThread::Priority threadPriority)
{
+#ifndef Q_OS_WINRT
// copied from start() with a few modifications:
int prio;
@@ -639,6 +783,12 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
if (!SetThreadPriority(handle, prio)) {
qErrnoWarning("QThread::setPriority: Failed to set thread priority");
}
+#else // !Q_OS_WINRT
+ if (priority != threadPriority) {
+ qWarning("QThread::setPriority: Failed to set thread priority (not implemented)");
+ return;
+ }
+#endif // Q_OS_WINRT
}
QT_END_NAMESPACE
diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp
index fb1d1ee7cc..269f561a91 100644
--- a/src/corelib/thread/qthreadpool.cpp
+++ b/src/corelib/thread/qthreadpool.cpp
@@ -61,6 +61,7 @@ public:
void run();
void registerThreadInactive();
+ QWaitCondition runnableReady;
QThreadPoolPrivate *manager;
QRunnable *runnable;
};
@@ -128,14 +129,13 @@ void QThreadPoolThread::run()
// if too many threads are active, expire this thread
bool expired = manager->tooManyThreadsActive();
if (!expired) {
- ++manager->waitingThreads;
+ manager->waitingThreads.enqueue(this);
registerThreadInactive();
// wait for work, exiting after the expiry timeout is reached
- expired = !manager->runnableReady.wait(locker.mutex(), manager->expiryTimeout);
+ runnableReady.wait(locker.mutex(), manager->expiryTimeout);
++manager->activeThreads;
-
- if (expired)
- --manager->waitingThreads;
+ if (manager->waitingThreads.removeOne(this))
+ expired = true;
}
if (expired) {
manager->expiredThreads.enqueue(this);
@@ -160,7 +160,6 @@ QThreadPoolPrivate:: QThreadPoolPrivate()
expiryTimeout(30000),
maxThreadCount(qAbs(QThread::idealThreadCount())),
reservedThreads(0),
- waitingThreads(0),
activeThreads(0)
{ }
@@ -176,11 +175,10 @@ bool QThreadPoolPrivate::tryStart(QRunnable *task)
if (activeThreadCount() >= maxThreadCount)
return false;
- if (waitingThreads > 0) {
+ if (waitingThreads.count() > 0) {
// recycle an available thread
- --waitingThreads;
enqueueTask(task);
- runnableReady.wakeOne();
+ waitingThreads.takeFirst()->runnableReady.wakeOne();
return true;
}
@@ -225,7 +223,7 @@ int QThreadPoolPrivate::activeThreadCount() const
{
return (allThreads.count()
- expiredThreads.count()
- - waitingThreads
+ - waitingThreads.count()
+ reservedThreads);
}
@@ -266,7 +264,6 @@ void QThreadPoolPrivate::reset()
{
QMutexLocker locker(&mutex);
isExiting = true;
- runnableReady.wakeAll();
while (!allThreads.empty()) {
// move the contents of the set out so that we can iterate without the lock
@@ -275,6 +272,7 @@ void QThreadPoolPrivate::reset()
locker.unlock();
foreach (QThreadPoolThread *thread, allThreadsCopy) {
+ thread->runnableReady.wakeAll();
thread->wait();
delete thread;
}
@@ -283,7 +281,7 @@ void QThreadPoolPrivate::reset()
// repeat until all newly arrived threads have also completed
}
- waitingThreads = 0;
+ waitingThreads.clear();
expiredThreads.clear();
isExiting = false;
@@ -459,10 +457,8 @@ void QThreadPool::start(QRunnable *runnable, int priority)
if (!d->tryStart(runnable)) {
d->enqueueTask(runnable, priority);
- if (d->waitingThreads > 0) {
- --d->waitingThreads;
- d->runnableReady.wakeOne();
- }
+ if (!d->waitingThreads.isEmpty())
+ d->waitingThreads.takeFirst()->runnableReady.wakeOne();
}
}
diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h
index ba77f7e57c..bd5f546fdb 100644
--- a/src/corelib/thread/qthreadpool_p.h
+++ b/src/corelib/thread/qthreadpool_p.h
@@ -87,8 +87,8 @@ public:
void stealRunnable(QRunnable *);
mutable QMutex mutex;
- QWaitCondition runnableReady;
QSet<QThreadPoolThread *> allThreads;
+ QQueue<QThreadPoolThread *> waitingThreads;
QQueue<QThreadPoolThread *> expiredThreads;
QList<QPair<QRunnable *, int> > queue;
QWaitCondition noActiveThreads;
@@ -97,7 +97,6 @@ public:
int expiryTimeout;
int maxThreadCount;
int reservedThreads;
- int waitingThreads;
int activeThreads;
};
diff --git a/src/corelib/thread/qwaitcondition.h b/src/corelib/thread/qwaitcondition.h
index 1468951373..ce073c21e9 100644
--- a/src/corelib/thread/qwaitcondition.h
+++ b/src/corelib/thread/qwaitcondition.h
@@ -84,9 +84,9 @@ public:
bool wait(QMutex *mutex, unsigned long time = ULONG_MAX)
{
- Q_UNUSED(mutex);
- Q_UNUSED(time);
- return true;
+ Q_UNUSED(mutex);
+ Q_UNUSED(time);
+ return true;
}
void wakeOne() {}
diff --git a/src/corelib/thread/qwaitcondition_win.cpp b/src/corelib/thread/qwaitcondition_win.cpp
index 1cb1f82b03..f09667a364 100644
--- a/src/corelib/thread/qwaitcondition_win.cpp
+++ b/src/corelib/thread/qwaitcondition_win.cpp
@@ -64,7 +64,11 @@ class QWaitConditionEvent
public:
inline QWaitConditionEvent() : priority(0), wokenUp(false)
{
+#ifndef Q_OS_WINRT
event = CreateEvent(NULL, TRUE, FALSE, NULL);
+#else
+ event = CreateEventEx(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
+#endif
}
inline ~QWaitConditionEvent() { CloseHandle(event); }
int priority;
@@ -91,7 +95,9 @@ QWaitConditionEvent *QWaitConditionPrivate::pre()
mtx.lock();
QWaitConditionEvent *wce =
freeQueue.isEmpty() ? new QWaitConditionEvent : freeQueue.takeFirst();
+#ifndef Q_OS_WINRT
wce->priority = GetThreadPriority(GetCurrentThread());
+#endif
wce->wokenUp = false;
// insert 'wce' into the queue (sorted by priority)
@@ -111,7 +117,12 @@ bool QWaitConditionPrivate::wait(QWaitConditionEvent *wce, unsigned long time)
{
// wait for the event
bool ret = false;
+#ifndef Q_OS_WINRT
switch (WaitForSingleObject(wce->event, time)) {
+#else
+ switch (WaitForSingleObjectEx(wce->event, time, FALSE)) {
+#endif
+
default: break;
case WAIT_OBJECT_0:
diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri
index 13f0502b62..3c1ddd984a 100644
--- a/src/corelib/thread/thread.pri
+++ b/src/corelib/thread/thread.pri
@@ -17,8 +17,7 @@ HEADERS += thread/qmutex.h \
thread/qfuturesynchronizer.h \
thread/qfuturewatcher.h \
thread/qbasicatomic.h \
- thread/qgenericatomic.h \
- thread/qoldbasicatomic.h
+ thread/qgenericatomic.h
# private headers
HEADERS += thread/qmutex_p.h \
diff --git a/src/corelib/tools/qalgorithms.h b/src/corelib/tools/qalgorithms.h
index c6eede05cb..f75f33f25c 100644
--- a/src/corelib/tools/qalgorithms.h
+++ b/src/corelib/tools/qalgorithms.h
@@ -55,28 +55,28 @@ namespace QAlgorithmsPrivate {
#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
+QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
+QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan);
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator, RandomAccessIterator, const T &);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan);
#endif // QT_DEPRECATED_SINCE(5, 2)
}
#if QT_DEPRECATED_SINCE(5, 2)
template <typename InputIterator, typename OutputIterator>
-QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
+QT_DEPRECATED_X("Use std::copy") inline OutputIterator qCopy(InputIterator begin, InputIterator end, OutputIterator dest)
{
while (begin != end)
*dest++ = *begin++;
@@ -84,7 +84,7 @@ QT_DEPRECATED inline OutputIterator qCopy(InputIterator begin, InputIterator end
}
template <typename BiIterator1, typename BiIterator2>
-QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
+QT_DEPRECATED_X("Use std::copy_backward") inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 end, BiIterator2 dest)
{
while (begin != end)
*--dest = *--end;
@@ -92,7 +92,7 @@ QT_DEPRECATED inline BiIterator2 qCopyBackward(BiIterator1 begin, BiIterator1 en
}
template <typename InputIterator1, typename InputIterator2>
-QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
+QT_DEPRECATED_X("Use std::equal") inline bool qEqual(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2)
{
for (; first1 != last1; ++first1, ++first2)
if (!(*first1 == *first2))
@@ -101,20 +101,20 @@ QT_DEPRECATED inline bool qEqual(InputIterator1 first1, InputIterator1 last1, In
}
template <typename ForwardIterator, typename T>
-QT_DEPRECATED inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
+QT_DEPRECATED_X("Use std::fill") inline void qFill(ForwardIterator first, ForwardIterator last, const T &val)
{
for (; first != last; ++first)
*first = val;
}
template <typename Container, typename T>
-QT_DEPRECATED inline void qFill(Container &container, const T &val)
+QT_DEPRECATED_X("Use std::fill") inline void qFill(Container &container, const T &val)
{
qFill(container.begin(), container.end(), val);
}
template <typename InputIterator, typename T>
-QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
+QT_DEPRECATED_X("Use std::find") inline InputIterator qFind(InputIterator first, InputIterator last, const T &val)
{
while (first != last && !(*first == val))
++first;
@@ -122,13 +122,13 @@ QT_DEPRECATED inline InputIterator qFind(InputIterator first, InputIterator last
}
template <typename Container, typename T>
-QT_DEPRECATED inline typename Container::const_iterator qFind(const Container &container, const T &val)
+QT_DEPRECATED_X("Use std::find") inline typename Container::const_iterator qFind(const Container &container, const T &val)
{
return qFind(container.constBegin(), container.constEnd(), val);
}
template <typename InputIterator, typename T, typename Size>
-QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
+QT_DEPRECATED_X("Use std::count") inline void qCount(InputIterator first, InputIterator last, const T &value, Size &n)
{
for (; first != last; ++first)
if (*first == value)
@@ -136,7 +136,7 @@ QT_DEPRECATED inline void qCount(InputIterator first, InputIterator last, const
}
template <typename Container, typename T, typename Size>
-QT_DEPRECATED inline void qCount(const Container &container, const T &value, Size &n)
+QT_DEPRECATED_X("Use std::count") inline void qCount(const Container &container, const T &value, Size &n)
{
qCount(container.constBegin(), container.constEnd(), value, n);
}
@@ -153,7 +153,7 @@ LessThan qGreater()
}
#else
template <typename T>
-class QT_DEPRECATED qLess
+class QT_DEPRECATED_X("Use std::less") qLess
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -163,7 +163,7 @@ public:
};
template <typename T>
-class QT_DEPRECATED qGreater
+class QT_DEPRECATED_X("Use std::greater") qGreater
{
public:
inline bool operator()(const T &t1, const T &t2) const
@@ -174,21 +174,21 @@ public:
#endif
template <typename RandomAccessIterator>
-QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-QT_DEPRECATED inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-QT_DEPRECATED inline void qSort(Container &c)
+QT_DEPRECATED_X("Use std::sort") inline void qSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -199,21 +199,21 @@ QT_DEPRECATED inline void qSort(Container &c)
}
template <typename RandomAccessIterator>
-QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start);
}
template <typename RandomAccessIterator, typename LessThan>
-QT_DEPRECATED inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
{
if (start != end)
QAlgorithmsPrivate::qStableSortHelper(start, end, *start, lessThan);
}
template<typename Container>
-QT_DEPRECATED inline void qStableSort(Container &c)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSort(Container &c)
{
#ifdef Q_CC_BOR
// Work around Borland 5.5 optimizer bug
@@ -224,7 +224,7 @@ QT_DEPRECATED inline void qStableSort(Container &c)
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate to keep existing code
// compiling. We have to allow using *begin and value with different types,
@@ -247,19 +247,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qLowerBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qLowerBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qLowerBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator middle;
@@ -280,19 +280,19 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qUpperBoundHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qUpperBound(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qUpperBoundHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value)
{
// Implementation is duplicated from QAlgorithmsPrivate.
RandomAccessIterator it = qLowerBound(begin, end, value);
@@ -304,13 +304,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccess
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFind(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
return QAlgorithmsPrivate::qBinaryFindHelper(begin, end, value, lessThan);
}
template <typename Container, typename T>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE typename Container::const_iterator qBinaryFind(const Container &container, const T &value)
{
return QAlgorithmsPrivate::qBinaryFindHelper(container.constBegin(), container.constEnd(), value, qLess<T>());
}
@@ -340,7 +340,7 @@ namespace QAlgorithmsPrivate {
#if QT_DEPRECATED_SINCE(5, 2)
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::sort") Q_OUTOFLINE_TEMPLATE void qSortHelper(RandomAccessIterator start, RandomAccessIterator end, const T &t, LessThan lessThan)
{
top:
int span = int(end - start);
@@ -393,13 +393,13 @@ top:
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED_X("Use std::sort") inline void qSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::reverse") Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
{
--end;
while (begin < end)
@@ -407,7 +407,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, Ran
}
template <typename RandomAccessIterator>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
+QT_DEPRECATED_X("Use std::rotate") Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end)
{
qReverse(begin, middle);
qReverse(middle, end);
@@ -415,7 +415,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qRotate(RandomAccessIterator begin, Rand
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::merge") Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, RandomAccessIterator pivot, RandomAccessIterator end, T &t, LessThan lessThan)
{
const int len1 = pivot - begin;
const int len2 = end - pivot;
@@ -450,7 +450,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qMerge(RandomAccessIterator begin, Rando
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
+QT_DEPRECATED_X("Use std::stable_sort") Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &t, LessThan lessThan)
{
const int span = end - begin;
if (span < 2)
@@ -463,13 +463,13 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE void qStableSortHelper(RandomAccessIterator b
}
template <typename RandomAccessIterator, typename T>
-QT_DEPRECATED inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
+QT_DEPRECATED_X("Use std::stable_sort") inline void qStableSortHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &dummy)
{
qStableSortHelper(begin, end, dummy, qLess<T>());
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::lower_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = int(end - begin);
@@ -490,7 +490,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qLowerBoundHelper(Random
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::upper_bound") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator middle;
int n = end - begin;
@@ -510,7 +510,7 @@ QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qUpperBoundHelper(Random
}
template <typename RandomAccessIterator, typename T, typename LessThan>
-QT_DEPRECATED Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
+QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessIterator qBinaryFindHelper(RandomAccessIterator begin, RandomAccessIterator end, const T &value, LessThan lessThan)
{
RandomAccessIterator it = qLowerBoundHelper(begin, end, value, lessThan);
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 27f2606954..7df4694bcd 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -142,7 +142,7 @@ struct QTypedArrayData
inline iterator() : i(0) {}
inline iterator(T *n) : i(n) {}
- inline iterator(const iterator &o): i(o.i){}
+ inline iterator(const iterator &o): i(o.i){} // #### Qt 6: remove, the implicit version is fine
inline T &operator*() const { return *i; }
inline T *operator->() const { return i; }
inline T &operator[](int j) const { return *(i + j); }
@@ -176,7 +176,7 @@ struct QTypedArrayData
inline const_iterator() : i(0) {}
inline const_iterator(const T *n) : i(n) {}
- inline const_iterator(const const_iterator &o): i(o.i) {}
+ inline const_iterator(const const_iterator &o): i(o.i) {} // #### Qt 6: remove, the default version is fine
inline explicit const_iterator(const iterator &o): i(o.i) {}
inline const T &operator*() const { return *i; }
inline const T *operator->() const { return i; }
diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp
index 02cc321262..a6f22abce8 100644
--- a/src/corelib/tools/qbitarray.cpp
+++ b/src/corelib/tools/qbitarray.cpp
@@ -739,8 +739,8 @@ QDataStream &operator>>(QDataStream &in, QBitArray &ba)
quint32 len;
in >> len;
if (len == 0) {
- ba.clear();
- return in;
+ ba.clear();
+ return in;
}
const quint32 Step = 8 * 1024 * 1024;
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 3e3bae9a94..304ce69449 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -132,10 +132,10 @@ char *qstrcpy(char *dst, const char *src)
return 0;
#if defined(_MSC_VER) && _MSC_VER >= 1400
const int len = int(strlen(src));
- // This is actually not secure!!! It will be fixed
- // properly in a later release!
+ // This is actually not secure!!! It will be fixed
+ // properly in a later release!
if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
- return dst;
+ return dst;
return 0;
#else
return strcpy(dst, src);
@@ -166,7 +166,7 @@ char *qstrncpy(char *dst, const char *src, uint len)
if (!src || !dst)
return 0;
#if defined(_MSC_VER) && _MSC_VER >= 1400
- strncpy_s(dst, len, src, len-1);
+ strncpy_s(dst, len, src, len-1);
#else
strncpy(dst, src, len);
#endif
@@ -3266,6 +3266,39 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
bool QByteArray::isNull() const { return d == QArrayData::sharedNull(); }
+static qlonglong toIntegral_helper(const char *data, bool *ok, int base, qlonglong)
+{
+ return QLocaleData::bytearrayToLongLong(data, base, ok);
+}
+
+static qulonglong toIntegral_helper(const char *data, bool *ok, int base, qulonglong)
+{
+ return QLocaleData::bytearrayToUnsLongLong(data, base, ok);
+}
+
+template <typename T> static inline
+T toIntegral_helper(const char *data, bool *ok, int base)
+{
+ // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
+ const bool isUnsigned = T(0) < T(-1);
+ typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
+
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QByteArray::toIntegral: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+
+ // we select the right overload by the last, unused parameter
+ Int64 val = toIntegral_helper(data, ok, base, Int64());
+ if (T(val) != val) {
+ if (ok)
+ *ok = false;
+ val = 0;
+ }
+ return T(val);
+}
/*!
Returns the byte array converted to a \c {long long} using base \a
@@ -3289,14 +3322,7 @@ bool QByteArray::isNull() const { return d == QArrayData::sharedNull(); }
qlonglong QByteArray::toLongLong(bool *ok, int base) const
{
-#if defined(QT_CHECK_RANGE)
- if (base != 0 && (base < 2 || base > 36)) {
- qWarning("QByteArray::toLongLong: Invalid base %d", base);
- base = 10;
- }
-#endif
-
- return QLocalePrivate::bytearrayToLongLong(nulTerminated().constData(), base, ok);
+ return toIntegral_helper<qlonglong>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3322,17 +3348,9 @@ qlonglong QByteArray::toLongLong(bool *ok, int base) const
qulonglong QByteArray::toULongLong(bool *ok, int base) const
{
-#if defined(QT_CHECK_RANGE)
- if (base != 0 && (base < 2 || base > 36)) {
- qWarning("QByteArray::toULongLong: Invalid base %d", base);
- base = 10;
- }
-#endif
-
- return QLocalePrivate::bytearrayToUnsLongLong(nulTerminated().constData(), base, ok);
+ return toIntegral_helper<qulonglong>(nulTerminated().constData(), ok, base);
}
-
/*!
Returns the byte array converted to an \c int using base \a
base, which is 10 by default and must be between 2 and 36, or 0.
@@ -3357,13 +3375,7 @@ qulonglong QByteArray::toULongLong(bool *ok, int base) const
int QByteArray::toInt(bool *ok, int base) const
{
- qlonglong v = toLongLong(ok, base);
- if (v < INT_MIN || v > INT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return int(v);
+ return toIntegral_helper<int>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3388,13 +3400,7 @@ int QByteArray::toInt(bool *ok, int base) const
uint QByteArray::toUInt(bool *ok, int base) const
{
- qulonglong v = toULongLong(ok, base);
- if (v > UINT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return uint(v);
+ return toIntegral_helper<uint>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3422,13 +3428,7 @@ uint QByteArray::toUInt(bool *ok, int base) const
*/
long QByteArray::toLong(bool *ok, int base) const
{
- qlonglong v = toLongLong(ok, base);
- if (v < LONG_MIN || v > LONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return long(v);
+ return toIntegral_helper<long>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3454,13 +3454,7 @@ long QByteArray::toLong(bool *ok, int base) const
*/
ulong QByteArray::toULong(bool *ok, int base) const
{
- qulonglong v = toULongLong(ok, base);
- if (v > ULONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return ulong(v);
+ return toIntegral_helper<ulong>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3485,13 +3479,7 @@ ulong QByteArray::toULong(bool *ok, int base) const
short QByteArray::toShort(bool *ok, int base) const
{
- qlonglong v = toLongLong(ok, base);
- if (v < SHRT_MIN || v > SHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return short(v);
+ return toIntegral_helper<short>(nulTerminated().constData(), ok, base);
}
/*!
@@ -3516,13 +3504,7 @@ short QByteArray::toShort(bool *ok, int base) const
ushort QByteArray::toUShort(bool *ok, int base) const
{
- qulonglong v = toULongLong(ok, base);
- if (v > USHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return ushort(v);
+ return toIntegral_helper<ushort>(nulTerminated().constData(), ok, base);
}
@@ -3544,7 +3526,7 @@ ushort QByteArray::toUShort(bool *ok, int base) const
double QByteArray::toDouble(bool *ok) const
{
- return QLocalePrivate::bytearrayToDouble(nulTerminated().constData(), ok);
+ return QLocaleData::bytearrayToDouble(nulTerminated().constData(), ok);
}
/*!
@@ -3563,7 +3545,7 @@ double QByteArray::toDouble(bool *ok) const
float QByteArray::toFloat(bool *ok) const
{
- return float(toDouble(ok));
+ return QLocaleData::convertDoubleToFloat(toDouble(ok), ok);
}
/*!
@@ -3772,22 +3754,22 @@ QByteArray &QByteArray::setNum(qulonglong n, int base)
QByteArray &QByteArray::setNum(double n, char f, int prec)
{
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
uint flags = 0;
if (qIsUpper(f))
- flags = QLocalePrivate::CapitalEorX;
+ flags = QLocaleData::CapitalEorX;
f = qToLower(f);
switch (f) {
case 'f':
- form = QLocalePrivate::DFDecimal;
+ form = QLocaleData::DFDecimal;
break;
case 'e':
- form = QLocalePrivate::DFExponent;
+ form = QLocaleData::DFExponent;
break;
case 'g':
- form = QLocalePrivate::DFSignificantDigits;
+ form = QLocaleData::DFSignificantDigits;
break;
default:
#if defined(QT_CHECK_RANGE)
@@ -3796,8 +3778,7 @@ QByteArray &QByteArray::setNum(double n, char f, int prec)
break;
}
- QLocale locale(QLocale::C);
- *this = locale.d->doubleToString(n, prec, form, -1, flags).toLatin1();
+ *this = QLocaleData::c()->doubleToString(n, prec, form, -1, flags).toLatin1();
return *this;
}
diff --git a/src/corelib/tools/qbytearraylist.cpp b/src/corelib/tools/qbytearraylist.cpp
new file mode 100644
index 0000000000..817342d682
--- /dev/null
+++ b/src/corelib/tools/qbytearraylist.cpp
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 by Southwest Research Institute (R)
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qbytearraylist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \typedef QByteArrayListIterator
+ \relates QByteArrayList
+
+ The QByteArrayListIterator type definition provides a Java-style const
+ iterator for QByteArrayList.
+
+ QByteArrayList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style const iterator is simply
+ a type definition for QListIterator<QByteArray>.
+
+ \sa QMutableByteArrayListIterator, QByteArrayList::const_iterator
+*/
+
+/*! \typedef QMutableByteArrayListIterator
+ \relates QByteArrayList
+
+ The QByteArrayListIterator type definition provides a Java-style
+ non-const iterator for QByteArrayList.
+
+ QByteArrayList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style non-const iterator is
+ simply a type definition for QMutableListIterator<QByteArray>.
+
+ \sa QByteArrayListIterator, QByteArrayList::iterator
+*/
+
+/*!
+ \class QByteArrayList
+ \inmodule QtCore
+ \since 5.3
+ \brief The QByteArrayList class provides a list of byte arrays.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup string-processing
+
+ \reentrant
+
+ QByteArrayList inherits from QList<QByteArray>. Like QList, QByteArrayList is
+ \l{implicitly shared}. It provides fast index-based access as well as fast
+ insertions and removals. Passing string lists as value parameters is both
+ fast and safe.
+
+ All of QList's functionality also applies to QByteArrayList. For example, you
+ can use isEmpty() to test whether the list is empty, and you can call
+ functions like append(), prepend(), insert(), replace(), removeAll(),
+ removeAt(), removeFirst(), removeLast(), and removeOne() to modify a
+ QByteArrayList. In addition, QByteArrayList provides several join()
+ methods for concatenating the list into a single QByteArray.
+
+ The purpose of QByteArrayList is quite different from that of QStringList.
+ Whereas QStringList has many methods for manipulation of elements within
+ the list, QByteArrayList does not.
+ Normally, QStringList should be used whenever working with a list of printable
+ strings. QByteArrayList should be used to handle and efficiently join large blobs
+ of binary data, as when sequentially receiving serialized data through a
+ QIODevice.
+
+ \sa QByteArray, QStringList
+*/
+
+/*!
+ \fn QByteArrayList::QByteArrayList()
+
+ Constructs an empty byte array list.
+*/
+
+/*!
+ \fn QByteArrayList::QByteArrayList(const QByteArray &ba)
+
+ Constructs a byte array list that contains the given byte array,
+ \a ba. Longer lists are easily created like this:
+
+ \snippet qbytearraylist/main.cpp 0
+
+ \sa append()
+*/
+
+/*!
+ \fn QByteArrayList::QByteArrayList(const QByteArrayList &other)
+
+ Constructs a copy of the \a other byte array list.
+
+ This operation takes \l{constant time} because QByteArrayList is
+ \l{implicitly shared}, making the process of returning a
+ QByteArrayList from a function very fast. If a shared instance is
+ modified, it will be copied (copy-on-write), and that takes
+ \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*!
+ \fn QByteArrayList::QByteArrayList(const QList<QByteArray> &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QByteArrayList is
+ \l{implicitly shared}. This makes returning a QByteArrayList from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), and that takes \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*! \fn QByteArrayList::QByteArrayList(std::initializer_list<QByteArray> args)
+
+ Construct a list from a std::initializer_list given by \a args.
+
+ This constructor is only enabled if the compiler supports C++11 initializer
+ lists.
+*/
+
+/*!
+ \fn QByteArray QByteArrayList::join() const
+
+ Joins all the byte arrays into a single byte array.
+*/
+
+/*!
+ \fn QByteArray QByteArrayList::join(const QByteArray &separator) const
+
+ Joins all the byte arrays into a single byte array with each
+ element separated by the given \a separator.
+*/
+
+int QByteArrayList_joinedSize(const QByteArrayList *that, int seplen)
+{
+ int totalLength = 0;
+ const int size = that->size();
+
+ for (int i = 0; i < size; ++i)
+ totalLength += that->at(i).size();
+
+ if (size > 0)
+ totalLength += seplen * (size - 1);
+
+ return totalLength;
+}
+
+/*!
+ \fn QByteArray QByteArrayList::join(char separator) const
+
+ Joins all the byte arrays into a single byte array with each
+ element separated by the given \a separator.
+*/
+QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char *sep, int seplen)
+{
+ int totalLength = QByteArrayList_joinedSize(that, seplen);
+ QByteArray res;
+ if (totalLength == 0)
+ return res;
+ res.reserve(totalLength);
+ for (int i = 0; i < that->size(); ++i) {
+ if (i)
+ res.append(sep, seplen);
+ res += that->at(i);
+ }
+ return res;
+}
+
+/*!
+ \fn QByteArrayList operator+(const QByteArrayList &list1, const QByteArrayList &list2)
+ \relates QByteArrayList
+
+ Returns a byte array list that is the concatenation of \a list1 and \a list2.
+*/
+
+/*!
+ \fn QByteArrayList& operator+=(QByteArrayList &list1, const QByteArrayList &list2)
+ \relates QByteArrayList
+
+ Appends \a list2 to \a list1 and returns a reference to \a list1.
+*/
+
+/*!
+ \fn QByteArrayList &QByteArrayList::operator<<(const QByteArray &ba)
+
+ Appends the given byte array, \a ba, to this byte array list and returns
+ a reference to the byte array list.
+
+ \sa append()
+*/
+
+/*!
+ \fn QByteArrayList &QByteArrayList::operator<<(const QByteArrayList &other)
+
+ \overload
+
+ Appends the \a other byte array list to the byte array list and returns a reference to
+ the latter byte array list.
+*/
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &in, QByteArrayList &list)
+ \relates QByteArrayList
+
+ Reads a byte array list from the given \a in stream into the specified
+ \a list.
+
+ \sa {Serializing Qt Data Types}
+*/
+
+/*!
+ \fn QDataStream &operator<<(QDataStream &out, const QByteArrayList &list)
+ \relates QByteArrayList
+
+ Writes the given byte array \a list to the specified \a out stream.
+
+ \sa {Serializing Qt Data Types}
+*/
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/tools/qbytearraylist.h
new file mode 100644
index 0000000000..5ce6509c28
--- /dev/null
+++ b/src/corelib/tools/qbytearraylist.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 by Southwest Research Institute (R)
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QBYTEARRAYLIST_H
+#define QBYTEARRAYLIST_H
+
+#include <QtCore/qdatastream.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+
+typedef QListIterator<QByteArray> QByteArrayListIterator;
+typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator;
+
+class QByteArrayList : public QList<QByteArray>
+{
+public:
+ inline QByteArrayList() { }
+ inline explicit QByteArrayList(const QByteArray &i) { append(i); }
+ inline QByteArrayList(const QByteArrayList &l) : QList<QByteArray>(l) { }
+ inline QByteArrayList(const QList<QByteArray> &l) : QList<QByteArray>(l) { }
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ inline QByteArrayList(std::initializer_list<QByteArray> args) : QList<QByteArray>(args) { }
+#endif
+
+ inline QByteArray join() const;
+ inline QByteArray join(const QByteArray &sep) const;
+ inline QByteArray join(char sep) const;
+
+ inline QByteArrayList &operator<<(const QByteArray &str)
+ { append(str); return *this; }
+ inline QByteArrayList &operator<<(const QByteArrayList &l)
+ { *this += l; return *this; }
+};
+
+Q_DECLARE_TYPEINFO(QByteArrayList, Q_MOVABLE_TYPE);
+
+namespace QtPrivate {
+ QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *s, int l);
+}
+
+inline QByteArray QByteArrayList::join() const
+{
+ return QtPrivate::QByteArrayList_join(this, 0, 0);
+}
+
+inline QByteArray QByteArrayList::join(const QByteArray &sep) const
+{
+ return QtPrivate::QByteArrayList_join(this, sep.constData(), sep.size());
+}
+
+inline QByteArray QByteArrayList::join(char sep) const
+{
+ return QtPrivate::QByteArrayList_join(this, &sep, 1);
+}
+
+inline QByteArrayList operator+(const QByteArrayList &lhs, const QByteArrayList &rhs)
+{
+ QByteArrayList res;
+ res.append( lhs );
+ res.append( rhs );
+ return res;
+}
+
+inline QByteArrayList& operator+=(QByteArrayList &lhs, const QByteArrayList &rhs)
+{
+ lhs.append( rhs );
+ return lhs;
+}
+
+#ifndef QT_NO_DATASTREAM
+inline QDataStream &operator>>(QDataStream &in, QByteArrayList &list)
+{
+ return operator>>(in, static_cast<QList<QByteArray> &>(list));
+}
+inline QDataStream &operator<<(QDataStream &out, const QByteArrayList &list)
+{
+ return operator<<(out, static_cast<const QList<QByteArray> &>(list));
+}
+#endif // QT_NO_DATASTREAM
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAYLIST_H
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 4ed0cd5eea..eb59cc719f 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -127,9 +127,9 @@ QT_BEGIN_NAMESPACE
Separator_* or an exceptional code point from Other_Control category).
QChar also provides direction(), which indicates the "natural"
- writing direction of this character. The joining() function
+ writing direction of this character. The joiningType() function
indicates how the character joins with it's neighbors (needed
- mostly for Arabic) and finally hasMirrored(), which indicates
+ mostly for Arabic or Syriac) and finally hasMirrored(), which indicates
whether the character needs to be mirrored when it is printed in
it's "unnatural" writing direction.
@@ -185,8 +185,9 @@ QT_BEGIN_NAMESPACE
\value Unicode_6_0 Version 6.0
\value Unicode_6_1 Version 6.1
\value Unicode_6_2 Version 6.2
+ \value Unicode_6_3 Version 6.3 Since Qt 5.3
\value Unicode_Unassigned The value is not assigned to any character
- in version 6.2 of Unicode.
+ in version 6.3 of Unicode.
\sa unicodeVersion(), currentUnicodeVersion()
*/
@@ -408,14 +409,18 @@ QT_BEGIN_NAMESPACE
\value DirEN
\value DirES
\value DirET
+ \value DirFSI Since Qt 5.3
\value DirL
\value DirLRE
+ \value DirLRI Since Qt 5.3
\value DirLRO
\value DirNSM
\value DirON
\value DirPDF
+ \value DirPDI Since Qt 5.3
\value DirR
\value DirRLE
+ \value DirRLI Since Qt 5.3
\value DirRLO
\value DirS
\value DirWS
@@ -453,7 +458,29 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QChar::JoiningType
+ since 5.3
+
+ This enum type defines the Unicode joining type attributes. See the
+ \l{http://www.unicode.org/}{Unicode Standard} for a description of the values.
+
+ In order to conform to C/C++ naming conventions "Joining_" is prepended
+ to the codes used in the Unicode Standard.
+
+ \value Joining_None
+ \value Joining_Causing
+ \value Joining_Dual
+ \value Joining_Right
+ \value Joining_Left
+ \value Joining_Transparent
+
+ \sa joiningType()
+*/
+
+#if QT_DEPRECATED_SINCE(5, 3)
+/*!
\enum QChar::Joining
+ \deprecated in 5.3, use JoiningType instead.
This enum type defines the Unicode joining attributes. See the
\l{http://www.unicode.org/}{Unicode Standard} for a description
@@ -466,6 +493,7 @@ QT_BEGIN_NAMESPACE
\sa joining()
*/
+#endif
/*!
\enum QChar::CombiningClass
@@ -1048,7 +1076,32 @@ QChar::Direction QChar::direction(uint ucs4)
}
/*!
+ \fn QChar::JoiningType QChar::joiningType() const
+ \since 5.3
+
+ Returns information about the joining type attributes of the character
+ (needed for certain languages such as Arabic or Syriac).
+*/
+
+/*!
+ \overload
+ \since 5.3
+
+ Returns information about the joining type attributes of the UCS-4-encoded
+ character specified by \a ucs4
+ (needed for certain languages such as Arabic or Syriac).
+*/
+QChar::JoiningType QChar::joiningType(uint ucs4)
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::Joining_None;
+ return QChar::JoiningType(qGetProp(ucs4)->joining);
+}
+
+#if QT_DEPRECATED_SINCE(5, 3)
+/*!
\fn QChar::Joining QChar::joining() const
+ \deprecated in 5.3, use joiningType() instead.
Returns information about the joining properties of the character
(needed for certain languages such as Arabic).
@@ -1056,6 +1109,8 @@ QChar::Direction QChar::direction(uint ucs4)
/*!
\overload
+ \deprecated in 5.3, use joiningType() instead.
+
Returns information about the joining properties of the UCS-4-encoded
character specified by \a ucs4 (needed for certain languages such as Arabic).
*/
@@ -1063,8 +1118,15 @@ QChar::Joining QChar::joining(uint ucs4)
{
if (ucs4 > LastValidCodePoint)
return QChar::OtherJoining;
- return (QChar::Joining) qGetProp(ucs4)->joining;
+ switch (qGetProp(ucs4)->joining) {
+ case QChar::Joining_Causing: return QChar::Center;
+ case QChar::Joining_Dual: return QChar::Dual;
+ case QChar::Joining_Right: return QChar::Right;
+ default: break;
+ }
+ return QChar::OtherJoining;
}
+#endif
/*!
\fn bool QChar::hasMirrored() const
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 8afa05bb00..266effb66a 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -262,7 +262,8 @@ public:
enum Direction
{
DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
- DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN,
+ DirLRI, DirRLI, DirFSI, DirPDI
};
enum Decomposition
@@ -287,10 +288,21 @@ public:
Fraction
};
+ enum JoiningType {
+ Joining_None,
+ Joining_Causing,
+ Joining_Dual,
+ Joining_Right,
+ Joining_Left,
+ Joining_Transparent
+ };
+
+#if QT_DEPRECATED_SINCE(5, 3)
enum Joining
{
OtherJoining, Dual, Right, Center
};
+#endif
enum CombiningClass
{
@@ -332,13 +344,24 @@ public:
Unicode_5_2,
Unicode_6_0,
Unicode_6_1,
- Unicode_6_2
+ Unicode_6_2,
+ Unicode_6_3
};
// ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
inline Category category() const { return QChar::category(ucs); }
inline Direction direction() const { return QChar::direction(ucs); }
- inline Joining joining() const { return QChar::joining(ucs); }
+ inline JoiningType joiningType() const { return QChar::joiningType(ucs); }
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED inline Joining joining() const {
+ switch (QChar::joiningType(ucs)) {
+ case QChar::Joining_Causing: return QChar::Center;
+ case QChar::Joining_Dual: return QChar::Dual;
+ case QChar::Joining_Right: return QChar::Right;
+ default: return QChar::OtherJoining;
+ }
+ }
+#endif
inline unsigned char combiningClass() const { return QChar::combiningClass(ucs); }
inline QChar mirroredChar() const { return QChar::mirroredChar(ucs); }
@@ -425,7 +448,10 @@ public:
static Category QT_FASTCALL category(uint ucs4);
static Direction QT_FASTCALL direction(uint ucs4);
- static Joining QT_FASTCALL joining(uint ucs4);
+ static JoiningType QT_FASTCALL joiningType(uint ucs4);
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4);
+#endif
static unsigned char QT_FASTCALL combiningClass(uint ucs4);
static uint QT_FASTCALL mirroredChar(uint ucs4);
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 8e59000946..9a672a0505 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -125,9 +125,15 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
// comparing strings, the value 2 can be subtracted from a nonzero return value. Then, the
// meaning of <0, ==0, and >0 is consistent with the C runtime.
+#ifndef Q_OS_WINRT
return CompareString(LOCALE_USER_DEFAULT, d->collator,
reinterpret_cast<const wchar_t*>(s1), len1,
reinterpret_cast<const wchar_t*>(s2), len2) - 2;
+#else // !Q_OS_WINRT
+ return CompareStringEx(LOCALE_NAME_USER_DEFAULT, d->collator,
+ reinterpret_cast<LPCWSTR>(s1), len1,
+ reinterpret_cast<LPCWSTR>(s2), len2, NULL, NULL, 0) - 2;
+#endif // Q_OS_WINRT
}
int QCollator::compare(const QString &str1, const QString &str2) const
@@ -142,13 +148,31 @@ int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
+#ifndef Q_OS_WINRT
int size = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
0, 0);
+#elif defined(Q_OS_WINPHONE)
+ int size = 0;
+ Q_UNIMPLEMENTED();
+#else // Q_OS_WINPHONE
+ int size = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ 0, 0, NULL, NULL, 0);
+#endif // !Q_OS_WINPHONE
QString ret(size, Qt::Uninitialized);
+#ifndef Q_OS_WINRT
int finalSize = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
reinterpret_cast<wchar_t*>(ret.data()), ret.size());
+#elif defined(Q_OS_WINPHONE)
+ int finalSize = 0;
+#else // Q_OS_WINPHONE
+ int finalSize = LCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ reinterpret_cast<LPWSTR>(ret.data()), ret.size(),
+ NULL, NULL, 0);
+#endif // !Q_OS_WINPHONE
if (finalSize == 0) {
qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError();
}
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 6177012e4b..e38a5f569a 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -61,6 +61,9 @@
# ifdef Q_OS_WINCE
# include "qfunctions_wince.h"
# endif
+# ifdef Q_OS_WINRT
+# include "qfunctions_winrt.h"
+# endif
#endif
#if defined(Q_OS_MAC)
@@ -2201,6 +2204,21 @@ static int qt_timezone()
long offset;
_get_timezone(&offset);
return offset;
+#elif defined(Q_OS_BSD4) && !defined(Q_OS_DARWIN)
+ time_t clock = time(NULL);
+ struct tm t;
+ localtime_r(&clock, &t);
+ // QTBUG-36080 Workaround for systems without the POSIX timezone
+ // variable. This solution is not very efficient but fixing it is up to
+ // the libc implementations.
+ //
+ // tm_gmtoff has some important differences compared to the timezone
+ // variable:
+ // - It returns the number of seconds east of UTC, and we want the
+ // number of seconds west of UTC.
+ // - It also takes DST into account, so we need to adjust it to always
+ // get the Standard Time offset.
+ return -t.tm_gmtoff + (t.tm_isdst ? SECS_PER_HOUR : 0L);
#else
return timezone;
#endif // Q_OS_WIN
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index f14fac00b8..5320ea1fbf 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -60,6 +60,7 @@
#include <qbytearray.h>
#include <qdatetime.h>
#include <qbasicatomic.h>
+#include <private/qsimd_p.h>
#ifndef QT_BOOTSTRAPPED
#include <qcoreapplication.h>
@@ -93,10 +94,69 @@ QT_BEGIN_NAMESPACE
(for instance, gcc 4.4 does that even at -O0).
*/
+#ifdef __SSE4_2__
+static inline bool hasFastCrc32()
+{
+ return true;
+}
+
+template <typename Char>
+static uint crc32(const Char *ptr, size_t len, uint h)
+{
+ // The CRC32 instructions from Nehalem calculate a 32-bit CRC32 checksum
+ const uchar *p = reinterpret_cast<const uchar *>(ptr);
+ const uchar *const e = p + (len * sizeof(Char));
+# ifdef Q_PROCESSOR_X86_64
+ // The 64-bit instruction still calculates only 32-bit, but without this
+ // variable GCC 4.9 still tries to clear the high bits on every loop
+ qulonglong h2 = h;
+
+ p += 8;
+ for ( ; p <= e; p += 8)
+ h2 = _mm_crc32_u64(h2, *reinterpret_cast<const qlonglong *>(p - 8));
+ h = h2;
+ p -= 8;
+
+ len = e - p;
+ if (len & 4) {
+ h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p));
+ p += 4;
+ }
+# else
+ p += 4;
+ for ( ; p <= e; p += 4)
+ h = _mm_crc32_u32(h, *reinterpret_cast<const uint *>(p));
+ p -= 4;
+ len = e - p;
+# endif
+ if (len & 2) {
+ h = _mm_crc32_u16(h, *reinterpret_cast<const ushort *>(p));
+ p += 2;
+ }
+ if (sizeof(Char) == 1 && len & 1)
+ h = _mm_crc32_u8(h, *p);
+ return h;
+}
+#else
+static inline bool hasFastCrc32()
+{
+ return false;
+}
+
+static uint crc32(...)
+{
+ Q_UNREACHABLE();
+ return 0;
+}
+#endif
+
static inline uint hash(const uchar *p, int len, uint seed) Q_DECL_NOTHROW
{
uint h = seed;
+ if (hasFastCrc32())
+ return crc32(p, size_t(len), h);
+
for (int i = 0; i < len; ++i)
h = 31 * h + p[i];
@@ -107,6 +167,9 @@ static inline uint hash(const QChar *p, int len, uint seed) Q_DECL_NOTHROW
{
uint h = seed;
+ if (hasFastCrc32())
+ return crc32(p, size_t(len), h);
+
for (int i = 0; i < len; ++i)
h = 31 * h + p[i].unicode();
@@ -674,6 +737,38 @@ void QHashData::checkSanity()
Returns the hash value for the \a key, using \a seed to seed the calculation.
*/
+/*! \relates QHash
+ \since 5.3
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+*/
+uint qHash(float key, uint seed) Q_DECL_NOTHROW
+{
+ return key != 0.0f ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
+}
+
+/*! \relates QHash
+ \since 5.3
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+*/
+uint qHash(double key, uint seed) Q_DECL_NOTHROW
+{
+ return key != 0.0 ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
+}
+
+#ifndef Q_OS_DARWIN
+/*! \relates QHash
+ \since 5.3
+
+ Returns the hash value for the \a key, using \a seed to seed the calculation.
+*/
+uint qHash(long double key, uint seed) Q_DECL_NOTHROW
+{
+ return key != 0.0L ? hash(reinterpret_cast<const uchar *>(&key), sizeof(key), seed) : seed ;
+}
+#endif
+
/*! \fn uint qHash(QChar key, uint seed = 0)
\relates QHash
\since 5.0
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 9dd0e6144d..d4bf8df442 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -85,6 +85,11 @@ inline uint qHash(quint64 key, uint seed = 0) Q_DECL_NOTHROW
}
}
inline uint qHash(qint64 key, uint seed = 0) Q_DECL_NOTHROW { return qHash(quint64(key), seed); }
+Q_CORE_EXPORT uint qHash(float key, uint seed = 0) Q_DECL_NOTHROW;
+Q_CORE_EXPORT uint qHash(double key, uint seed = 0) Q_DECL_NOTHROW;
+#ifndef Q_OS_DARWIN
+Q_CORE_EXPORT uint qHash(long double key, uint seed = 0) Q_DECL_NOTHROW;
+#endif
inline uint qHash(QChar key, uint seed = 0) Q_DECL_NOTHROW { return qHash(key.unicode(), seed); }
Q_CORE_EXPORT uint qHash(const QByteArray &key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT uint qHash(const QString &key, uint seed = 0) Q_DECL_NOTHROW;
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index 79a62cb87c..bdacdbcd26 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -170,7 +170,7 @@ public:
inline const_iterator(Node *n) : i(n) {}
inline const_iterator(const const_iterator &o) : i(o.i){}
inline const_iterator(iterator ci) : i(ci.i){}
- inline const_iterator &operator=(const const_iterator &o) { i = o.i; return *this; }
+ inline const_iterator &operator=(const const_iterator &o) { i = o.i; return *this; }
inline const T &operator*() const { return i->t; }
inline const T *operator->() const { return &i->t; }
inline bool operator==(const const_iterator &o) const { return i == o.i; }
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 0eb202c5e2..98e38ca587 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -1061,6 +1061,41 @@ QString QLocale::name() const
return result;
}
+static qlonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok,
+ QLocaleData::GroupSeparatorMode mode, qlonglong)
+{
+ return d->stringToLongLong(data, len, 10, ok, mode);
+}
+
+static qulonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok,
+ QLocaleData::GroupSeparatorMode mode, qulonglong)
+{
+ return d->stringToUnsLongLong(data, len, 10, ok, mode);
+}
+
+template <typename T> static inline
+T toIntegral_helper(const QLocalePrivate *d, const QChar *data, int len, bool *ok)
+{
+ // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
+ const bool isUnsigned = T(0) < T(-1);
+ typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
+
+ QLocaleData::GroupSeparatorMode mode
+ = d->m_numberOptions & QLocale::RejectGroupSeparator
+ ? QLocaleData::FailOnGroupSeparators
+ : QLocaleData::ParseGroupSeparators;
+
+ // we select the right overload by the last, unused parameter
+ Int64 val = toIntegral_helper(d->m_data, data, len, ok, mode, Int64());
+ if (T(val) != val) {
+ if (ok)
+ *ok = false;
+ val = 0;
+ }
+ return T(val);
+}
+
+
/*!
\since 4.8
@@ -1135,13 +1170,7 @@ QString QLocale::scriptToString(QLocale::Script script)
short QLocale::toShort(const QString &s, bool *ok) const
{
- qlonglong i = toLongLong(s, ok);
- if (i < SHRT_MIN || i > SHRT_MAX) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
- return short(i);
+ return toIntegral_helper<short>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1159,13 +1188,7 @@ short QLocale::toShort(const QString &s, bool *ok) const
ushort QLocale::toUShort(const QString &s, bool *ok) const
{
- qulonglong i = toULongLong(s, ok);
- if (i > USHRT_MAX) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
- return ushort(i);
+ return toIntegral_helper<ushort>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1183,13 +1206,7 @@ ushort QLocale::toUShort(const QString &s, bool *ok) const
int QLocale::toInt(const QString &s, bool *ok) const
{
- qlonglong i = toLongLong(s, ok);
- if (i < INT_MIN || i > INT_MAX) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
- return int(i);
+ return toIntegral_helper<int>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1207,13 +1224,7 @@ int QLocale::toInt(const QString &s, bool *ok) const
uint QLocale::toUInt(const QString &s, bool *ok) const
{
- qulonglong i = toULongLong(s, ok);
- if (i > UINT_MAX) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
- return uint(i);
+ return toIntegral_helper<uint>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1232,12 +1243,7 @@ uint QLocale::toUInt(const QString &s, bool *ok) const
qlonglong QLocale::toLongLong(const QString &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
-
- return d->stringToLongLong(s, 10, ok, mode);
+ return toIntegral_helper<qlonglong>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1256,12 +1262,7 @@ qlonglong QLocale::toLongLong(const QString &s, bool *ok) const
qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
-
- return d->stringToUnsLongLong(s, 10, ok, mode);
+ return toIntegral_helper<qulonglong>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1276,20 +1277,9 @@ qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
\sa toDouble(), toInt(), toString()
*/
-#define QT_MAX_FLOAT 3.4028234663852886e+38
-
float QLocale::toFloat(const QString &s, bool *ok) const
{
- bool myOk;
- double d = toDouble(s, &myOk);
- if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- if (ok != 0)
- *ok = true;
- return float(d);
+ return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
}
/*!
@@ -1315,12 +1305,12 @@ float QLocale::toFloat(const QString &s, bool *ok) const
double QLocale::toDouble(const QString &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
+ QLocaleData::GroupSeparatorMode mode
= d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
+ ? QLocaleData::FailOnGroupSeparators
+ : QLocaleData::ParseGroupSeparators;
- return d->stringToDouble(s, ok, mode);
+ return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode);
}
/*!
@@ -1340,13 +1330,7 @@ double QLocale::toDouble(const QString &s, bool *ok) const
short QLocale::toShort(const QStringRef &s, bool *ok) const
{
- qlonglong i = toLongLong(s, ok);
- if (i < SHRT_MIN || i > SHRT_MAX) {
- if (ok)
- *ok = false;
- return 0;
- }
- return short(i);
+ return toIntegral_helper<short>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1366,13 +1350,7 @@ short QLocale::toShort(const QStringRef &s, bool *ok) const
ushort QLocale::toUShort(const QStringRef &s, bool *ok) const
{
- qulonglong i = toULongLong(s, ok);
- if (i > USHRT_MAX) {
- if (ok)
- *ok = false;
- return 0;
- }
- return ushort(i);
+ return toIntegral_helper<ushort>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1392,13 +1370,7 @@ ushort QLocale::toUShort(const QStringRef &s, bool *ok) const
int QLocale::toInt(const QStringRef &s, bool *ok) const
{
- qlonglong i = toLongLong(s, ok);
- if (i < INT_MIN || i > INT_MAX) {
- if (ok)
- *ok = false;
- return 0;
- }
- return int(i);
+ return toIntegral_helper<int>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1418,13 +1390,7 @@ int QLocale::toInt(const QStringRef &s, bool *ok) const
uint QLocale::toUInt(const QStringRef &s, bool *ok) const
{
- qulonglong i = toULongLong(s, ok);
- if (i > UINT_MAX) {
- if (ok)
- *ok = false;
- return 0;
- }
- return uint(i);
+ return toIntegral_helper<uint>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1445,12 +1411,7 @@ uint QLocale::toUInt(const QStringRef &s, bool *ok) const
qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
-
- return d->stringToLongLong(s, 10, ok, mode);
+ return toIntegral_helper<qlonglong>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1471,12 +1432,7 @@ qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const
qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
- = d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
-
- return d->stringToUnsLongLong(s, 10, ok, mode);
+ return toIntegral_helper<qulonglong>(d, s.constData(), s.size(), ok);
}
/*!
@@ -1495,16 +1451,7 @@ qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
float QLocale::toFloat(const QStringRef &s, bool *ok) const
{
- bool myOk;
- double d = toDouble(s, &myOk);
- if (!myOk || d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
- if (ok)
- *ok = false;
- return 0.0;
- }
- if (ok)
- *ok = true;
- return float(d);
+ return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
}
/*!
@@ -1532,12 +1479,12 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const
double QLocale::toDouble(const QStringRef &s, bool *ok) const
{
- QLocalePrivate::GroupSeparatorMode mode
+ QLocaleData::GroupSeparatorMode mode
= d->m_numberOptions & RejectGroupSeparator
- ? QLocalePrivate::FailOnGroupSeparators
- : QLocalePrivate::ParseGroupSeparators;
+ ? QLocaleData::FailOnGroupSeparators
+ : QLocaleData::ParseGroupSeparators;
- return d->stringToDouble(s, ok, mode);
+ return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode);
}
@@ -1551,9 +1498,9 @@ QString QLocale::toString(qlonglong i) const
{
int flags = d->m_numberOptions & OmitGroupSeparator
? 0
- : QLocalePrivate::ThousandsGroup;
+ : QLocaleData::ThousandsGroup;
- return d->longLongToString(i, -1, 10, -1, flags);
+ return d->m_data->longLongToString(i, -1, 10, -1, flags);
}
/*!
@@ -1566,9 +1513,9 @@ QString QLocale::toString(qulonglong i) const
{
int flags = d->m_numberOptions & OmitGroupSeparator
? 0
- : QLocalePrivate::ThousandsGroup;
+ : QLocaleData::ThousandsGroup;
- return d->unsLongLongToString(i, -1, 10, -1, flags);
+ return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
}
/*!
@@ -2040,30 +1987,30 @@ static char qToLower(char c)
QString QLocale::toString(double i, char f, int prec) const
{
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
uint flags = 0;
if (qIsUpper(f))
- flags = QLocalePrivate::CapitalEorX;
+ flags = QLocaleData::CapitalEorX;
f = qToLower(f);
switch (f) {
case 'f':
- form = QLocalePrivate::DFDecimal;
+ form = QLocaleData::DFDecimal;
break;
case 'e':
- form = QLocalePrivate::DFExponent;
+ form = QLocaleData::DFExponent;
break;
case 'g':
- form = QLocalePrivate::DFSignificantDigits;
+ form = QLocaleData::DFSignificantDigits;
break;
default:
break;
}
if (!(d->m_numberOptions & OmitGroupSeparator))
- flags |= QLocalePrivate::ThousandsGroup;
- return d->doubleToString(i, prec, form, -1, flags);
+ flags |= QLocaleData::ThousandsGroup;
+ return d->m_data->doubleToString(i, prec, form, -1, flags);
}
/*!
@@ -2577,12 +2524,12 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
case 4: {
const int yr = date.year();
const int len = (yr < 0) ? 5 : 4;
- result.append(longLongToString(yr, -1, 10, len, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(yr, -1, 10, len, QLocaleData::ZeroPadded));
break;
}
case 2:
- result.append(longLongToString(date.year() % 100, -1, 10, 2,
- QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(date.year() % 100, -1, 10, 2,
+ QLocaleData::ZeroPadded));
break;
default:
repeat = 1;
@@ -2596,10 +2543,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date.month()));
+ result.append(m_data->longLongToString(date.month()));
break;
case 2:
- result.append(longLongToString(date.month(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(date.month(), -1, 10, 2, QLocaleData::ZeroPadded));
break;
case 3:
result.append(q->monthName(date.month(), QLocale::ShortFormat));
@@ -2615,10 +2562,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
repeat = qMin(repeat, 4);
switch (repeat) {
case 1:
- result.append(longLongToString(date.day()));
+ result.append(m_data->longLongToString(date.day()));
break;
case 2:
- result.append(longLongToString(date.day(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(date.day(), -1, 10, 2, QLocaleData::ZeroPadded));
break;
case 3:
result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat));
@@ -2648,10 +2595,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
switch (repeat) {
case 1:
- result.append(longLongToString(hour));
+ result.append(m_data->longLongToString(hour));
break;
case 2:
- result.append(longLongToString(hour, -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(hour, -1, 10, 2, QLocaleData::ZeroPadded));
break;
}
break;
@@ -2661,10 +2608,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time.hour()));
+ result.append(m_data->longLongToString(time.hour()));
break;
case 2:
- result.append(longLongToString(time.hour(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(time.hour(), -1, 10, 2, QLocaleData::ZeroPadded));
break;
}
break;
@@ -2674,10 +2621,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time.minute()));
+ result.append(m_data->longLongToString(time.minute()));
break;
case 2:
- result.append(longLongToString(time.minute(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(time.minute(), -1, 10, 2, QLocaleData::ZeroPadded));
break;
}
break;
@@ -2687,10 +2634,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
repeat = qMin(repeat, 2);
switch (repeat) {
case 1:
- result.append(longLongToString(time.second()));
+ result.append(m_data->longLongToString(time.second()));
break;
case 2:
- result.append(longLongToString(time.second(), -1, 10, 2, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(time.second(), -1, 10, 2, QLocaleData::ZeroPadded));
break;
}
break;
@@ -2724,10 +2671,10 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
}
switch (repeat) {
case 1:
- result.append(longLongToString(time.msec()));
+ result.append(m_data->longLongToString(time.msec()));
break;
case 3:
- result.append(longLongToString(time.msec(), -1, 10, 3, QLocalePrivate::ZeroPadded));
+ result.append(m_data->longLongToString(time.msec(), -1, 10, 3, QLocaleData::ZeroPadded));
break;
}
break;
@@ -2756,24 +2703,16 @@ QString QLocalePrivate::dateTimeToString(const QString &format, const QDateTime
return result;
}
-QString QLocalePrivate::doubleToString(double d,
- int precision,
- DoubleForm form,
- int width,
- unsigned flags) const
+QString QLocaleData::doubleToString(double d, int precision, DoubleForm form,
+ int width, unsigned flags) const
{
- return QLocalePrivate::doubleToString(zero(), plus(), minus(), exponential(),
- group(), decimal(),
- d, precision, form, width, flags);
+ return doubleToString(m_zero, m_plus, m_minus, m_exponential, m_group, m_decimal,
+ d, precision, form, width, flags);
}
-QString QLocalePrivate::doubleToString(const QChar _zero, const QChar plus, const QChar minus,
- const QChar exponential, const QChar group, const QChar decimal,
- double d,
- int precision,
- DoubleForm form,
- int width,
- unsigned flags)
+QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const QChar minus,
+ const QChar exponential, const QChar group, const QChar decimal,
+ double d, int precision, DoubleForm form, int width, unsigned flags)
{
if (precision == -1)
precision = 6;
@@ -2893,14 +2832,14 @@ QString QLocalePrivate::doubleToString(const QChar _zero, const QChar plus, cons
// pad with zeros. LeftAdjusted overrides this flag). Also, we don't
// pad special numbers
- if (flags & QLocalePrivate::ZeroPadded
- && !(flags & QLocalePrivate::LeftAdjusted)
+ if (flags & QLocaleData::ZeroPadded
+ && !(flags & QLocaleData::LeftAdjusted)
&& !special_number) {
int num_pad_chars = width - num_str.length();
// leave space for the sign
if (negative
- || flags & QLocalePrivate::AlwaysShowSign
- || flags & QLocalePrivate::BlankBeforePositive)
+ || flags & QLocaleData::AlwaysShowSign
+ || flags & QLocaleData::BlankBeforePositive)
--num_pad_chars;
for (int i = 0; i < num_pad_chars; ++i)
@@ -2910,26 +2849,26 @@ QString QLocalePrivate::doubleToString(const QChar _zero, const QChar plus, cons
// add sign
if (negative)
num_str.prepend(minus);
- else if (flags & QLocalePrivate::AlwaysShowSign)
+ else if (flags & QLocaleData::AlwaysShowSign)
num_str.prepend(plus);
- else if (flags & QLocalePrivate::BlankBeforePositive)
+ else if (flags & QLocaleData::BlankBeforePositive)
num_str.prepend(QLatin1Char(' '));
- if (flags & QLocalePrivate::CapitalEorX)
+ if (flags & QLocaleData::CapitalEorX)
num_str = num_str.toUpper();
return num_str;
}
-QString QLocalePrivate::longLongToString(qlonglong l, int precision,
+QString QLocaleData::longLongToString(qlonglong l, int precision,
int base, int width,
unsigned flags) const
{
- return QLocalePrivate::longLongToString(zero(), group(), plus(), minus(),
+ return longLongToString(m_zero, m_group, m_plus, m_minus,
l, precision, base, width, flags);
}
-QString QLocalePrivate::longLongToString(const QChar zero, const QChar group,
+QString QLocaleData::longLongToString(const QChar zero, const QChar group,
const QChar plus, const QChar minus,
qlonglong l, int precision,
int base, int width,
@@ -3016,15 +2955,15 @@ QString QLocalePrivate::longLongToString(const QChar zero, const QChar group,
return num_str;
}
-QString QLocalePrivate::unsLongLongToString(qulonglong l, int precision,
+QString QLocaleData::unsLongLongToString(qulonglong l, int precision,
int base, int width,
unsigned flags) const
{
- return QLocalePrivate::unsLongLongToString(zero(), group(), plus(),
+ return unsLongLongToString(m_zero, m_group, m_plus,
l, precision, base, width, flags);
}
-QString QLocalePrivate::unsLongLongToString(const QChar zero, const QChar group,
+QString QLocaleData::unsLongLongToString(const QChar zero, const QChar group,
const QChar plus,
qulonglong l, int precision,
int base, int width,
@@ -3099,7 +3038,7 @@ QString QLocalePrivate::unsLongLongToString(const QChar zero, const QChar group,
number. We can't detect junk here, since we don't even know the base
of the number.
*/
-bool QLocalePrivate::numberToCLocale(const QChar *str, int len,
+bool QLocaleData::numberToCLocale(const QChar *str, int len,
GroupSeparatorMode group_sep_mode,
CharBuff *result) const
{
@@ -3113,14 +3052,25 @@ bool QLocalePrivate::numberToCLocale(const QChar *str, int len,
if (idx == l)
return false;
+ // Check trailing whitespace
+ for (; idx < l; --l) {
+ if (!uc[l - 1].isSpace())
+ break;
+ }
+
+ int group_cnt = 0; // counts number of group chars
+ int decpt_idx = -1;
+ int last_separator_idx = -1;
+ int start_of_digits_idx = -1;
+
while (idx < l) {
const QChar in = uc[idx];
char out = digitToCLocale(in);
if (out == 0) {
- if (in == list())
+ if (in == m_list)
out = ';';
- else if (in == percent())
+ else if (in == m_percent)
out = '%';
// for handling base-x numbers
else if (in.unicode() >= 'A' && in.unicode() <= 'Z')
@@ -3130,30 +3080,64 @@ bool QLocalePrivate::numberToCLocale(const QChar *str, int len,
else
break;
}
+ if (group_sep_mode == ParseGroupSeparators) {
+ if (start_of_digits_idx == -1 && out >= '0' && out <= '9') {
+ start_of_digits_idx = idx;
+ } else if (out == ',') {
+ // Don't allow group chars after the decimal point
+ if (decpt_idx != -1)
+ return false;
+
+ // check distance from the last separator or from the beginning of the digits
+ // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
+ return false;
+ if (last_separator_idx == -1 && (start_of_digits_idx == -1 || idx - start_of_digits_idx > 3))
+ return false;
+
+ last_separator_idx = idx;
+ ++group_cnt;
+
+ // don't add the group separator
+ ++idx;
+ continue;
+ } else if (out == '.' || out == 'e' || out == 'E') {
+ // Fail if more than one decimal point
+ if (out == '.' && decpt_idx != -1)
+ return false;
+ if (decpt_idx == -1)
+ decpt_idx = idx;
+
+ // check distance from the last separator
+ // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
+ return false;
+
+ // stop processing separators
+ last_separator_idx = -1;
+ }
+ }
result->append(out);
++idx;
}
- // Check trailing whitespace
- for (; idx < l; ++idx) {
- if (!uc[idx].isSpace())
+ if (group_sep_mode == ParseGroupSeparators) {
+ // group separator post-processing
+ // did we end in a separator?
+ if (last_separator_idx + 1 == idx)
+ return false;
+ // were there enough digits since the last separator?
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
return false;
}
result->append('\0');
-
- // Check separators
- if (group_sep_mode == ParseGroupSeparators
- && !removeGroupSeparators(result))
- return false;
-
-
- return true;
+ return idx == l;
}
-bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
+bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArray *buff,
int decDigits) const
{
buff->clear();
@@ -3246,18 +3230,11 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
return true;
}
-double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
+double QLocaleData::stringToDouble(const QChar *begin, int len, bool *ok,
GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- QString trimmedNumber;
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0.0;
@@ -3265,18 +3242,11 @@ double QLocalePrivate::stringToDouble(const QString &number, bool *ok,
return bytearrayToDouble(buff.constData(), ok);
}
-qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
+qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- QString trimmedNumber;
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
@@ -3285,77 +3255,11 @@ qlonglong QLocalePrivate::stringToLongLong(const QString &number, int base,
return bytearrayToLongLong(buff.constData(), base, ok);
}
-qulonglong QLocalePrivate::stringToUnsLongLong(const QString &number, int base,
+qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int base,
bool *ok, GroupSeparatorMode group_sep_mode) const
{
CharBuff buff;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- QString trimmedNumber;
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
-
- return bytearrayToUnsLongLong(buff.constData(), base, ok);
-}
-
-double QLocalePrivate::stringToDouble(const QStringRef &number, bool *ok,
- GroupSeparatorMode group_sep_mode) const
-{
- CharBuff buff;
- QStringRef trimmedNumber;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- return bytearrayToDouble(buff.constData(), ok);
-}
-
-qlonglong QLocalePrivate::stringToLongLong(const QStringRef &number, int base,
- bool *ok, GroupSeparatorMode group_sep_mode) const
-{
- CharBuff buff;
- QStringRef trimmedNumber;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
- if (ok != 0)
- *ok = false;
- return 0;
- }
-
- return bytearrayToLongLong(buff.constData(), base, ok);
-}
-
-qulonglong QLocalePrivate::stringToUnsLongLong(const QStringRef &number, int base,
- bool *ok, GroupSeparatorMode group_sep_mode) const
-{
- CharBuff buff;
- QStringRef trimmedNumber;
- // Do not use the ternary operator - triggers msvc2012 bug in optimized builds
- if (group().unicode() == 0xa0)
- trimmedNumber = number.trimmed();
- else
- trimmedNumber = number;
- if (!numberToCLocale(trimmedNumber.unicode(), trimmedNumber.size(),
- group_sep_mode, &buff)) {
+ if (!numberToCLocale(begin, len, group_sep_mode, &buff)) {
if (ok != 0)
*ok = false;
return 0;
@@ -3364,7 +3268,7 @@ qulonglong QLocalePrivate::stringToUnsLongLong(const QStringRef &number, int bas
return bytearrayToUnsLongLong(buff.constData(), base, ok);
}
-double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
+double QLocaleData::bytearrayToDouble(const char *num, bool *ok, bool *overflow)
{
if (ok != 0)
*ok = true;
@@ -3416,7 +3320,7 @@ double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok, bool *overfl
return d;
}
-qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow)
+qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow)
{
bool _ok;
const char *endptr;
@@ -3458,7 +3362,7 @@ qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *o
return l;
}
-qulonglong QLocalePrivate::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
+qulonglong QLocaleData::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
{
bool _ok;
const char *endptr;
diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h
index 0fc3f87726..5a4aaf5cfc 100644
--- a/src/corelib/tools/qlocale.h
+++ b/src/corelib/tools/qlocale.h
@@ -390,6 +390,9 @@ public:
TaiDam = 309,
TaiNua = 310,
Ugaritic = 311,
+ Akoose = 312,
+ Lakota = 313,
+ StandardMoroccanTamazight = 314,
Norwegian = NorwegianBokmal,
Moldavian = Romanian,
SerboCroatian = Serbian,
@@ -404,7 +407,7 @@ public:
Chewa = Nyanja,
Frisian = WesternFrisian,
Uigur = Uighur,
- LastLanguage = Ugaritic
+ LastLanguage = StandardMoroccanTamazight
};
enum Script {
diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc
index aceb130857..5a97e60dfa 100644
--- a/src/corelib/tools/qlocale.qdoc
+++ b/src/corelib/tools/qlocale.qdoc
@@ -92,7 +92,7 @@
\note For the current keyboard input locale take a look at
QInputMethod::locale().
- QLocale's data is based on Common Locale Data Repository v23.1.
+ QLocale's data is based on Common Locale Data Repository v24.
The double-to-string and string-to-double conversion functions are
covered by the following licenses:
@@ -130,6 +130,7 @@
\value Afan Obsolete, please use Oromo
\value Afar
\value Afrikaans
+ \value Akoose Since Qt 5.3
\value Albanian
\value Amharic
\value Arabic
@@ -215,6 +216,7 @@
\value Rundi
\value Kurundi Obsolete, please use Rundi
\value Kwanyama
+ \value Lakota Since Qt 5.3
\value Lao
\value Latin
\value Latvian
@@ -272,6 +274,7 @@
\value Slovenian
\value Somali
\value Spanish
+ \value StandardMoroccanTamazight Since Qt 5.3
\value Sundanese
\value Swahili
\value Swedish
diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/tools/qlocale_data_p.h
index 46b3eef658..a47a27689b 100644
--- a/src/corelib/tools/qlocale_data_p.h
+++ b/src/corelib/tools/qlocale_data_p.h
@@ -77,8 +77,8 @@ static const int ImperialMeasurementSystemsCount =
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2013-08-10 from the
- Common Locale Data Repository v23.1
+ This part of the file was generated on 2014-01-11 from the
+ Common Locale Data Repository v24
http://www.unicode.org/cldr/
@@ -102,6 +102,7 @@ static const QLocaleId likely_subtags[] = {
{ 11, 0, 0 }, { 11, 7, 26 }, // ay -> ay_Latn_BO
{ 12, 0, 0 }, { 12, 7, 15 }, // az -> az_Latn_AZ
{ 12, 0, 102 }, { 12, 1, 102 }, // az_IR -> az_Arab_IR
+ { 12, 0, 178 }, { 12, 2, 178 }, // az_RU -> az_Cyrl_RU
{ 12, 1, 0 }, { 12, 1, 102 }, // az_Arab -> az_Arab_IR
{ 13, 0, 0 }, { 13, 2, 178 }, // ba -> ba_Cyrl_RU
{ 266, 0, 0 }, { 266, 7, 101 }, // ban -> ban_Latn_ID
@@ -120,6 +121,7 @@ static const QLocaleId likely_subtags[] = {
{ 19, 0, 0 }, { 19, 7, 74 }, // br -> br_Latn_FR
{ 215, 0, 0 }, { 215, 13, 100 }, // brx -> brx_Deva_IN
{ 142, 0, 0 }, { 142, 7, 27 }, // bs -> bs_Latn_BA
+ { 312, 0, 0 }, { 312, 7, 37 }, // bss -> bss_Latn_CM
{ 269, 0, 0 }, { 269, 7, 101 }, // bug -> bug_Latn_ID
{ 152, 0, 0 }, { 152, 14, 67 }, // byn -> byn_Ethi_ER
{ 24, 0, 0 }, { 24, 7, 197 }, // ca -> ca_Latn_ES
@@ -148,7 +150,6 @@ static const QLocaleId likely_subtags[] = {
{ 161, 0, 0 }, { 161, 7, 83 }, // ee -> ee_Latn_GH
{ 43, 0, 0 }, { 43, 16, 85 }, // el -> el_Grek_GR
{ 31, 0, 0 }, { 31, 7, 225 }, // en -> en_Latn_US
- { 32, 7, 0 }, { 32, 7, 184 }, // eo_Latn -> eo_Latn_SM
{ 111, 0, 0 }, { 111, 7, 197 }, // es -> es_Latn_ES
{ 33, 0, 0 }, { 33, 7, 68 }, // et -> et_Latn_EE
{ 14, 0, 0 }, { 14, 7, 197 }, // eu -> eu_Latn_ES
@@ -171,8 +172,7 @@ static const QLocaleId likely_subtags[] = {
{ 167, 0, 0 }, { 167, 7, 206 }, // gsw -> gsw_Latn_CH
{ 46, 0, 0 }, { 46, 17, 100 }, // gu -> gu_Gujr_IN
{ 175, 0, 0 }, { 175, 7, 111 }, // guz -> guz_Latn_KE
- { 144, 0, 0 }, { 144, 7, 224 }, // gv -> gv_Latn_GB
- { 144, 7, 0 }, { 144, 7, 251 }, // gv_Latn -> gv_Latn_IM
+ { 144, 0, 0 }, { 144, 7, 251 }, // gv -> gv_Latn_IM
{ 47, 0, 0 }, { 47, 7, 157 }, // ha -> ha_Latn_NG
{ 47, 0, 37 }, { 47, 1, 37 }, // ha_CM -> ha_Arab_CM
{ 47, 0, 201 }, { 47, 1, 201 }, // ha_SD -> ha_Arab_SD
@@ -186,7 +186,6 @@ static const QLocaleId likely_subtags[] = {
{ 50, 0, 0 }, { 50, 7, 98 }, // hu -> hu_Latn_HU
{ 9, 0, 0 }, { 9, 10, 11 }, // hy -> hy_Armn_AM
{ 53, 0, 0 }, { 53, 7, 74 }, // ia -> ia_Latn_FR
- { 53, 7, 0 }, { 53, 7, 205 }, // ia_Latn -> ia_Latn_SE
{ 52, 0, 0 }, { 52, 7, 101 }, // id -> id_Latn_ID
{ 149, 0, 0 }, { 149, 7, 157 }, // ig -> ig_Latn_NG
{ 168, 0, 0 }, { 168, 34, 44 }, // ii -> ii_Yiii_CN
@@ -231,13 +230,7 @@ static const QLocaleId likely_subtags[] = {
{ 243, 0, 0 }, { 243, 7, 37 }, // ksf -> ksf_Latn_CM
{ 201, 0, 0 }, { 201, 7, 82 }, // ksh -> ksh_Latn_DE
{ 67, 0, 0 }, { 67, 7, 217 }, // ku -> ku_Latn_TR
- { 67, 0, 11 }, { 67, 1, 11 }, // ku_AM -> ku_Arab_AM
- { 67, 0, 15 }, { 67, 1, 15 }, // ku_AZ -> ku_Arab_AZ
- { 67, 0, 82 }, { 67, 1, 82 }, // ku_DE -> ku_Arab_DE
- { 67, 0, 81 }, { 67, 1, 81 }, // ku_GE -> ku_Arab_GE
- { 67, 0, 103 }, { 67, 1, 103 }, // ku_IQ -> ku_Arab_IQ
{ 67, 0, 119 }, { 67, 1, 119 }, // ku_LB -> ku_Arab_LB
- { 67, 0, 218 }, { 67, 1, 218 }, // ku_TM -> ku_Arab_TM
{ 67, 1, 0 }, { 67, 1, 103 }, // ku_Arab -> ku_Arab_IQ
{ 226, 0, 0 }, { 226, 2, 178 }, // kv -> kv_Cyrl_RU
{ 145, 0, 0 }, { 145, 7, 224 }, // kw -> kw_Latn_GB
@@ -254,6 +247,7 @@ static const QLocaleId likely_subtags[] = {
{ 229, 0, 0 }, { 229, 7, 151 }, // li -> li_Latn_NL
{ 284, 0, 0 }, { 284, 13, 150 }, // lif -> lif_Deva_NP
{ 285, 0, 0 }, { 285, 51, 44 }, // lis -> lis_Lisu_CN
+ { 313, 0, 0 }, { 313, 7, 225 }, // lkt -> lkt_Latn_US
{ 72, 0, 0 }, { 72, 7, 49 }, // ln -> ln_Latn_CD
{ 69, 0, 0 }, { 69, 23, 117 }, // lo -> lo_Laoo_LA
{ 73, 0, 0 }, { 73, 7, 124 }, // lt -> lt_Latn_LT
@@ -261,7 +255,9 @@ static const QLocaleId likely_subtags[] = {
{ 210, 0, 0 }, { 210, 7, 111 }, // luo -> luo_Latn_KE
{ 204, 0, 0 }, { 204, 7, 111 }, // luy -> luy_Latn_KE
{ 71, 0, 0 }, { 71, 7, 118 }, // lv -> lv_Latn_LV
- { 289, 0, 0 }, { 289, 7, 91 }, // man -> man_Latn_GN
+ { 289, 0, 0 }, { 289, 7, 80 }, // man -> man_Latn_GM
+ { 289, 0, 91 }, { 289, 75, 91 }, // man_GN -> man_Nkoo_GN
+ { 289, 75, 0 }, { 289, 75, 91 }, // man_Nkoo -> man_Nkoo_GN
{ 202, 0, 0 }, { 202, 7, 111 }, // mas -> mas_Latn_KE
{ 197, 0, 0 }, { 197, 7, 111 }, // mer -> mer_Latn_KE
{ 191, 0, 0 }, { 191, 7, 137 }, // mfe -> mfe_Latn_MU
@@ -280,7 +276,6 @@ static const QLocaleId likely_subtags[] = {
{ 76, 0, 0 }, { 76, 7, 130 }, // ms -> ms_Latn_MY
{ 76, 0, 46 }, { 76, 1, 46 }, // ms_CC -> ms_Arab_CC
{ 76, 0, 101 }, { 76, 1, 101 }, // ms_ID -> ms_Arab_ID
- { 76, 1, 0 }, { 76, 1, 101 }, // ms_Arab -> ms_Arab_ID
{ 78, 0, 0 }, { 78, 7, 133 }, // mt -> mt_Latn_MT
{ 245, 0, 0 }, { 245, 7, 37 }, // mua -> mua_Latn_CM
{ 21, 0, 0 }, { 21, 25, 147 }, // my -> my_Mymr_MM
@@ -327,14 +322,13 @@ static const QLocaleId likely_subtags[] = {
{ 304, 0, 0 }, { 304, 7, 100 }, // sat -> sat_Latn_IN
{ 305, 0, 0 }, { 305, 90, 100 }, // saz -> saz_Saur_IN
{ 249, 0, 0 }, { 249, 7, 210 }, // sbp -> sbp_Latn_TZ
- { 105, 0, 0 }, { 105, 1, 100 }, // sd -> sd_Arab_IN
+ { 105, 0, 0 }, { 105, 1, 163 }, // sd -> sd_Arab_PK
{ 105, 13, 0 }, { 105, 13, 100 }, // sd_Deva -> sd_Deva_IN
{ 173, 0, 0 }, { 173, 7, 161 }, // se -> se_Latn_NO
{ 180, 0, 0 }, { 180, 7, 146 }, // seh -> seh_Latn_MZ
{ 213, 0, 0 }, { 213, 7, 132 }, // ses -> ses_Latn_ML
{ 98, 0, 0 }, { 98, 7, 41 }, // sg -> sg_Latn_CF
{ 183, 0, 0 }, { 183, 9, 145 }, // shi -> shi_Tfng_MA
- { 183, 0, 145 }, { 183, 7, 145 }, // shi_MA -> shi_Latn_MA
{ 106, 0, 0 }, { 106, 32, 198 }, // si -> si_Sinh_LK
{ 155, 0, 0 }, { 155, 7, 69 }, // sid -> sid_Latn_ET
{ 108, 0, 0 }, { 108, 7, 191 }, // sk -> sk_Latn_SK
@@ -356,7 +350,7 @@ static const QLocaleId likely_subtags[] = {
{ 113, 0, 0 }, { 113, 7, 210 }, // sw -> sw_Latn_TZ
{ 250, 0, 0 }, { 250, 7, 49 }, // swc -> swc_Latn_CD
{ 307, 0, 0 }, { 307, 11, 18 }, // syl -> syl_Beng_BD
- { 151, 0, 0 }, { 151, 33, 207 }, // syr -> syr_Syrc_SY
+ { 151, 0, 0 }, { 151, 33, 103 }, // syr -> syr_Syrc_IQ
{ 117, 0, 0 }, { 117, 27, 100 }, // ta -> ta_Taml_IN
{ 308, 0, 0 }, { 308, 7, 170 }, // tbw -> tbw_Latn_PH
{ 310, 0, 0 }, { 310, 99, 44 }, // tdd -> tdd_Tale_CN
@@ -384,10 +378,9 @@ static const QLocaleId likely_subtags[] = {
{ 128, 2, 0 }, { 128, 2, 110 }, // ug_Cyrl -> ug_Cyrl_KZ
{ 129, 0, 0 }, { 129, 2, 222 }, // uk -> uk_Cyrl_UA
{ 130, 0, 0 }, { 130, 1, 163 }, // ur -> ur_Arab_PK
- { 131, 0, 0 }, { 131, 2, 228 }, // uz -> uz_Cyrl_UZ
+ { 131, 0, 0 }, { 131, 7, 228 }, // uz -> uz_Latn_UZ
{ 131, 0, 1 }, { 131, 1, 1 }, // uz_AF -> uz_Arab_AF
- { 131, 0, 218 }, { 131, 7, 218 }, // uz_TM -> uz_Latn_TM
- { 131, 0, 217 }, { 131, 7, 217 }, // uz_TR -> uz_Latn_TR
+ { 131, 0, 44 }, { 131, 2, 44 }, // uz_CN -> uz_Cyrl_CN
{ 131, 1, 0 }, { 131, 1, 1 }, // uz_Arab -> uz_Arab_AF
{ 252, 0, 0 }, { 252, 35, 121 }, // vai -> vai_Vaii_LR
{ 160, 0, 0 }, { 160, 7, 195 }, // ve -> ve_Latn_ZA
@@ -400,10 +393,10 @@ static const QLocaleId likely_subtags[] = {
{ 136, 0, 0 }, { 136, 7, 195 }, // xh -> xh_Latn_ZA
{ 203, 0, 0 }, { 203, 7, 221 }, // xog -> xog_Latn_UG
{ 254, 0, 0 }, { 254, 7, 37 }, // yav -> yav_Latn_CM
- { 137, 0, 0 }, { 137, 18, 105 }, // yi -> yi_Hebr_IL
- { 137, 18, 0 }, { 137, 18, 222 }, // yi_Hebr -> yi_Hebr_UA
+ { 137, 0, 0 }, { 137, 18, 222 }, // yi -> yi_Hebr_UA
{ 138, 0, 0 }, { 138, 7, 157 }, // yo -> yo_Latn_NG
{ 139, 0, 0 }, { 139, 7, 44 }, // za -> za_Latn_CN
+ { 314, 0, 0 }, { 314, 9, 145 }, // zgh -> zgh_Tfng_MA
{ 25, 0, 0 }, { 25, 5, 44 }, // zh -> zh_Hans_CN
{ 25, 0, 13 }, { 25, 6, 13 }, // zh_AU -> zh_Hant_AU
{ 25, 0, 32 }, { 25, 6, 32 }, // zh_BN -> zh_Hant_BN
@@ -421,7 +414,6 @@ static const QLocaleId likely_subtags[] = {
{ 25, 0, 208 }, { 25, 6, 208 }, // zh_TW -> zh_Hant_TW
{ 25, 0, 225 }, { 25, 6, 225 }, // zh_US -> zh_Hant_US
{ 25, 0, 232 }, { 25, 6, 232 }, // zh_VN -> zh_Hant_VN
- { 25, 54, 0 }, { 25, 5, 44 }, // zh_Hani -> zh_Hans_CN
{ 25, 6, 0 }, { 25, 6, 208 }, // zh_Hant -> zh_Hant_TW
{ 140, 0, 0 }, { 140, 7, 195 }, // zu -> zu_Latn_ZA
{ 0, 0, 5 }, { 24, 7, 5 }, // und_AD -> ca_Latn_AD
@@ -461,7 +453,7 @@ static const QLocaleId likely_subtags[] = {
{ 0, 0, 37 }, { 37, 7, 37 }, // und_CM -> fr_Latn_CM
{ 0, 0, 44 }, { 25, 5, 44 }, // und_CN -> zh_Hans_CN
{ 0, 0, 47 }, { 111, 7, 47 }, // und_CO -> es_Latn_CO
- { 0, 0, 241 }, { 37, 7, 241 }, // und_CP -> fr_Latn_CP
+ { 0, 0, 241 }, { 0, 7, 241 }, // und_CP -> und_Latn_CP
{ 0, 0, 52 }, { 111, 7, 52 }, // und_CR -> es_Latn_CR
{ 0, 0, 55 }, { 111, 7, 55 }, // und_CU -> es_Latn_CU
{ 0, 0, 39 }, { 91, 7, 39 }, // und_CV -> pt_Latn_CV
@@ -546,7 +538,7 @@ static const QLocaleId likely_subtags[] = {
{ 0, 0, 139 }, { 111, 7, 139 }, // und_MX -> es_Latn_MX
{ 0, 0, 130 }, { 76, 7, 130 }, // und_MY -> ms_Latn_MY
{ 0, 0, 146 }, { 91, 7, 146 }, // und_MZ -> pt_Latn_MZ
- { 0, 0, 148 }, { 228, 7, 148 }, // und_NA -> kj_Latn_NA
+ { 0, 0, 148 }, { 5, 7, 148 }, // und_NA -> af_Latn_NA
{ 0, 0, 153 }, { 37, 7, 153 }, // und_NC -> fr_Latn_NC
{ 0, 0, 156 }, { 47, 7, 156 }, // und_NE -> ha_Latn_NE
{ 0, 0, 155 }, { 111, 7, 155 }, // und_NI -> es_Latn_NI
@@ -600,23 +592,20 @@ static const QLocaleId likely_subtags[] = {
{ 0, 0, 222 }, { 129, 2, 222 }, // und_UA -> uk_Cyrl_UA
{ 0, 0, 221 }, { 113, 7, 221 }, // und_UG -> sw_Latn_UG
{ 0, 0, 227 }, { 111, 7, 227 }, // und_UY -> es_Latn_UY
- { 0, 0, 228 }, { 131, 2, 228 }, // und_UZ -> uz_Cyrl_UZ
+ { 0, 0, 228 }, { 131, 7, 228 }, // und_UZ -> uz_Latn_UZ
{ 0, 0, 230 }, { 70, 7, 230 }, // und_VA -> la_Latn_VA
{ 0, 0, 231 }, { 111, 7, 231 }, // und_VE -> es_Latn_VE
{ 0, 0, 232 }, { 132, 7, 232 }, // und_VN -> vi_Latn_VN
{ 0, 0, 229 }, { 18, 7, 229 }, // und_VU -> bi_Latn_VU
{ 0, 0, 235 }, { 37, 7, 235 }, // und_WF -> fr_Latn_WF
{ 0, 0, 183 }, { 97, 7, 183 }, // und_WS -> sm_Latn_WS
+ { 0, 0, 257 }, { 6, 7, 257 }, // und_XK -> sq_Latn_XK
{ 0, 0, 237 }, { 8, 1, 237 }, // und_YE -> ar_Arab_YE
{ 0, 0, 138 }, { 37, 7, 138 }, // und_YT -> fr_Latn_YT
{ 0, 1, 0 }, { 8, 1, 64 }, // und_Arab -> ar_Arab_EG
- { 0, 1, 11 }, { 67, 1, 11 }, // und_Arab_AM -> ku_Arab_AM
- { 0, 1, 15 }, { 67, 1, 15 }, // und_Arab_AZ -> ku_Arab_AZ
{ 0, 1, 46 }, { 76, 1, 46 }, // und_Arab_CC -> ms_Arab_CC
{ 0, 1, 44 }, { 128, 1, 44 }, // und_Arab_CN -> ug_Arab_CN
- { 0, 1, 82 }, { 67, 1, 82 }, // und_Arab_DE -> ku_Arab_DE
{ 0, 1, 224 }, { 62, 1, 224 }, // und_Arab_GB -> ks_Arab_GB
- { 0, 1, 81 }, { 67, 1, 81 }, // und_Arab_GE -> ku_Arab_GE
{ 0, 1, 101 }, { 76, 1, 101 }, // und_Arab_ID -> ms_Arab_ID
{ 0, 1, 100 }, { 130, 1, 100 }, // und_Arab_IN -> ur_Arab_IN
{ 0, 1, 143 }, { 63, 1, 143 }, // und_Arab_MN -> kk_Arab_MN
@@ -624,8 +613,6 @@ static const QLocaleId likely_subtags[] = {
{ 0, 1, 157 }, { 47, 1, 157 }, // und_Arab_NG -> ha_Arab_NG
{ 0, 1, 163 }, { 130, 1, 163 }, // und_Arab_PK -> ur_Arab_PK
{ 0, 1, 209 }, { 89, 1, 209 }, // und_Arab_TJ -> fa_Arab_TJ
- { 0, 1, 218 }, { 67, 1, 218 }, // und_Arab_TM -> ku_Arab_TM
- { 0, 1, 217 }, { 67, 1, 217 }, // und_Arab_TR -> ku_Arab_TR
{ 0, 57, 0 }, { 265, 57, 102 }, // und_Armi -> arc_Armi_IR
{ 0, 10, 0 }, { 9, 10, 11 }, // und_Armn -> hy_Armn_AM
{ 0, 36, 0 }, { 255, 36, 102 }, // und_Avst -> ae_Avst_IR
@@ -650,10 +637,11 @@ static const QLocaleId likely_subtags[] = {
{ 0, 2, 27 }, { 100, 2, 27 }, // und_Cyrl_BA -> sr_Cyrl_BA
{ 0, 2, 81 }, { 2, 2, 81 }, // und_Cyrl_GE -> ab_Cyrl_GE
{ 0, 2, 85 }, { 74, 2, 85 }, // und_Cyrl_GR -> mk_Cyrl_GR
- { 0, 2, 141 }, { 20, 2, 141 }, // und_Cyrl_MD -> bg_Cyrl_MD
+ { 0, 2, 141 }, { 129, 2, 141 }, // und_Cyrl_MD -> uk_Cyrl_MD
{ 0, 2, 172 }, { 22, 2, 172 }, // und_Cyrl_PL -> be_Cyrl_PL
{ 0, 2, 177 }, { 20, 2, 177 }, // und_Cyrl_RO -> bg_Cyrl_RO
{ 0, 2, 191 }, { 129, 2, 191 }, // und_Cyrl_SK -> uk_Cyrl_SK
+ { 0, 2, 257 }, { 100, 2, 257 }, // und_Cyrl_XK -> sr_Cyrl_XK
{ 0, 13, 0 }, { 49, 13, 100 }, // und_Deva -> hi_Deva_IN
{ 0, 13, 25 }, { 84, 13, 25 }, // und_Deva_BT -> ne_Deva_BT
{ 0, 50, 0 }, { 263, 50, 64 }, // und_Egyp -> egy_Egyp_EG
@@ -665,12 +653,16 @@ static const QLocaleId likely_subtags[] = {
{ 0, 17, 0 }, { 46, 17, 100 }, // und_Gujr -> gu_Gujr_IN
{ 0, 4, 0 }, { 92, 4, 100 }, // und_Guru -> pa_Guru_IN
{ 0, 55, 0 }, { 66, 55, 114 }, // und_Hang -> ko_Hang_KR
- { 0, 54, 0 }, { 25, 5, 44 }, // und_Hani -> zh_Hans_CN
+ { 0, 54, 0 }, { 25, 54, 44 }, // und_Hani -> zh_Hani_CN
{ 0, 56, 0 }, { 280, 56, 170 }, // und_Hano -> hnn_Hano_PH
{ 0, 5, 0 }, { 25, 5, 44 }, // und_Hans -> zh_Hans_CN
{ 0, 6, 0 }, { 25, 6, 208 }, // und_Hant -> zh_Hant_TW
{ 0, 18, 0 }, { 48, 18, 105 }, // und_Hebr -> he_Hebr_IL
+ { 0, 18, 38 }, { 137, 18, 38 }, // und_Hebr_CA -> yi_Hebr_CA
+ { 0, 18, 224 }, { 137, 18, 224 }, // und_Hebr_GB -> yi_Hebr_GB
+ { 0, 18, 205 }, { 137, 18, 205 }, // und_Hebr_SE -> yi_Hebr_SE
{ 0, 18, 222 }, { 137, 18, 222 }, // und_Hebr_UA -> yi_Hebr_UA
+ { 0, 18, 225 }, { 137, 18, 225 }, // und_Hebr_US -> yi_Hebr_US
{ 0, 104, 0 }, { 59, 104, 108 }, // und_Hira -> ja_Hira_JP
{ 0, 79, 0 }, { 278, 79, 106 }, // und_Ital -> ett_Ital_IT
{ 0, 60, 0 }, { 60, 60, 101 }, // und_Java -> jv_Java_ID
@@ -690,7 +682,6 @@ static const QLocaleId likely_subtags[] = {
{ 0, 7, 44 }, { 139, 7, 44 }, // und_Latn_CN -> za_Latn_CN
{ 0, 7, 56 }, { 125, 7, 56 }, // und_Latn_CY -> tr_Latn_CY
{ 0, 7, 3 }, { 37, 7, 3 }, // und_Latn_DZ -> fr_Latn_DZ
- { 0, 7, 67 }, { 4, 7, 67 }, // und_Latn_ER -> aa_Latn_ER
{ 0, 7, 69 }, { 31, 7, 69 }, // und_Latn_ET -> en_Latn_ET
{ 0, 7, 81 }, { 67, 7, 81 }, // und_Latn_GE -> ku_Latn_GE
{ 0, 7, 85 }, { 125, 7, 85 }, // und_Latn_GR -> tr_Latn_GR
@@ -703,8 +694,6 @@ static const QLocaleId likely_subtags[] = {
{ 0, 7, 127 }, { 6, 7, 127 }, // und_Latn_MK -> sq_Latn_MK
{ 0, 7, 126 }, { 91, 7, 126 }, // und_Latn_MO -> pt_Latn_MO
{ 0, 7, 136 }, { 37, 7, 136 }, // und_Latn_MR -> fr_Latn_MR
- { 0, 7, 178 }, { 36, 7, 178 }, // und_Latn_RU -> fi_Latn_RU
- { 0, 7, 194 }, { 110, 7, 194 }, // und_Latn_SO -> so_Latn_SO
{ 0, 7, 207 }, { 37, 7, 207 }, // und_Latn_SY -> fr_Latn_SY
{ 0, 7, 216 }, { 37, 7, 216 }, // und_Latn_TN -> fr_Latn_TN
{ 0, 7, 208 }, { 174, 7, 208 }, // und_Latn_TW -> trv_Latn_TW
@@ -743,7 +732,7 @@ static const QLocaleId likely_subtags[] = {
{ 0, 93, 0 }, { 306, 93, 100 }, // und_Sora -> srb_Sora_IN
{ 0, 95, 0 }, { 112, 95, 101 }, // und_Sund -> su_Sund_ID
{ 0, 96, 0 }, { 307, 96, 18 }, // und_Sylo -> syl_Sylo_BD
- { 0, 33, 0 }, { 151, 33, 207 }, // und_Syrc -> syr_Syrc_SY
+ { 0, 33, 0 }, { 151, 33, 103 }, // und_Syrc -> syr_Syrc_IQ
{ 0, 98, 0 }, { 308, 98, 170 }, // und_Tagb -> tbw_Tagb_PH
{ 0, 101, 0 }, { 275, 101, 100 }, // und_Takr -> doi_Takr_IN
{ 0, 99, 0 }, { 310, 99, 44 }, // und_Tale -> tdd_Tale_CN
@@ -751,7 +740,7 @@ static const QLocaleId likely_subtags[] = {
{ 0, 27, 0 }, { 117, 27, 100 }, // und_Taml -> ta_Taml_IN
{ 0, 100, 0 }, { 309, 100, 232 }, // und_Tavt -> blt_Tavt_VN
{ 0, 28, 0 }, { 119, 28, 100 }, // und_Telu -> te_Telu_IN
- { 0, 9, 0 }, { 183, 9, 216 }, // und_Tfng -> shi_Tfng_TN
+ { 0, 9, 0 }, { 314, 9, 145 }, // und_Tfng -> zgh_Tfng_MA
{ 0, 97, 0 }, { 166, 97, 170 }, // und_Tglg -> fil_Tglg_PH
{ 0, 29, 0 }, { 143, 29, 131 }, // und_Thaa -> dv_Thaa_MV
{ 0, 30, 0 }, { 120, 30, 211 }, // und_Thai -> th_Thai_TH
@@ -773,213 +762,213 @@ static const quint16 locale_index[] = {
8, // Albanian
11, // Amharic
12, // Arabic
- 38, // Armenian
- 39, // Assamese
+ 39, // Armenian
+ 40, // Assamese
0, // Aymara
- 40, // Azerbaijani
+ 41, // Azerbaijani
0, // Bashkir
- 42, // Basque
- 43, // Bengali
- 45, // Dzongkha
+ 43, // Basque
+ 44, // Bengali
+ 46, // Dzongkha
0, // Bihari
0, // Bislama
- 46, // Breton
- 47, // Bulgarian
- 48, // Burmese
- 49, // Belarusian
- 50, // Khmer
- 51, // Catalan
- 53, // Chinese
+ 47, // Breton
+ 48, // Bulgarian
+ 49, // Burmese
+ 50, // Belarusian
+ 51, // Khmer
+ 52, // Catalan
+ 56, // Chinese
0, // Corsican
- 60, // Croatian
- 62, // Czech
- 63, // Danish
- 64, // Dutch
- 70, // English
+ 63, // Croatian
+ 65, // Czech
+ 66, // Danish
+ 68, // Dutch
+ 75, // English
0, // Esperanto
- 141, // Estonian
- 142, // Faroese
+ 166, // Estonian
+ 167, // Faroese
0, // Fijian
- 143, // Finnish
- 144, // French
+ 168, // Finnish
+ 169, // French
0, // Western Frisian
- 188, // Gaelic
- 189, // Galician
- 190, // Georgian
- 191, // German
- 197, // Greek
- 199, // Greenlandic
+ 215, // Gaelic
+ 216, // Galician
+ 217, // Georgian
+ 218, // German
+ 224, // Greek
+ 226, // Greenlandic
0, // Guarani
- 200, // Gujarati
- 201, // Hausa
- 204, // Hebrew
- 205, // Hindi
- 206, // Hungarian
- 207, // Icelandic
- 208, // Indonesian
- 209, // Interlingua
+ 227, // Gujarati
+ 228, // Hausa
+ 231, // Hebrew
+ 232, // Hindi
+ 233, // Hungarian
+ 234, // Icelandic
+ 235, // Indonesian
+ 236, // Interlingua
0, // Interlingue
0, // Inuktitut
0, // Inupiak
- 210, // Irish
- 211, // Italian
- 214, // Japanese
+ 237, // Irish
+ 238, // Italian
+ 241, // Japanese
0, // Javanese
- 215, // Kannada
- 216, // Kashmiri
- 217, // Kazakh
- 218, // Kinyarwanda
- 219, // Kirghiz
- 220, // Korean
+ 242, // Kannada
+ 243, // Kashmiri
+ 244, // Kazakh
+ 245, // Kinyarwanda
+ 246, // Kirghiz
+ 247, // Korean
0, // Kurdish
- 222, // Rundi
- 223, // Lao
+ 249, // Rundi
+ 250, // Lao
0, // Latin
- 224, // Latvian
- 225, // Lingala
- 229, // Lithuanian
- 230, // Macedonian
- 231, // Malagasy
- 232, // Malay
- 235, // Malayalam
- 236, // Maltese
+ 251, // Latvian
+ 252, // Lingala
+ 256, // Lithuanian
+ 257, // Macedonian
+ 258, // Malagasy
+ 259, // Malay
+ 262, // Malayalam
+ 263, // Maltese
0, // Maori
- 237, // Marathi
+ 264, // Marathi
0, // Marshallese
- 238, // Mongolian
+ 265, // Mongolian
0, // Nauru
- 239, // Nepali
- 241, // NorwegianBokmal
+ 266, // Nepali
+ 268, // NorwegianBokmal
0, // Occitan
- 242, // Oriya
- 243, // Pashto
- 244, // Persian
- 246, // Polish
- 247, // Portuguese
- 256, // Punjabi
+ 270, // Oriya
+ 271, // Pashto
+ 272, // Persian
+ 274, // Polish
+ 275, // Portuguese
+ 284, // Punjabi
0, // Quechua
- 258, // Romansh
- 259, // Romanian
- 261, // Russian
+ 286, // Romansh
+ 287, // Romanian
+ 289, // Russian
0, // Samoan
- 267, // Sango
+ 295, // Sango
0, // Sanskrit
- 268, // Serbian
- 276, // Ossetic
- 278, // Southern Sotho
- 280, // Tswana
- 282, // Shona
+ 296, // Serbian
+ 304, // Ossetic
+ 306, // Southern Sotho
+ 308, // Tswana
+ 310, // Shona
0, // Sindhi
- 283, // Sinhala
- 284, // Swati
- 286, // Slovak
- 287, // Slovenian
- 288, // Somali
- 292, // Spanish
+ 311, // Sinhala
+ 312, // Swati
+ 314, // Slovak
+ 315, // Slovenian
+ 316, // Somali
+ 320, // Spanish
0, // Sundanese
- 318, // Swahili
- 321, // Swedish
+ 346, // Swahili
+ 349, // Swedish
0, // Sardinian
- 324, // Tajik
- 325, // Tamil
+ 352, // Tajik
+ 353, // Tamil
0, // Tatar
- 329, // Telugu
- 330, // Thai
- 331, // Tibetan
- 333, // Tigrinya
- 335, // Tongan
- 336, // Tsonga
- 337, // Turkish
+ 357, // Telugu
+ 358, // Thai
+ 359, // Tibetan
+ 361, // Tigrinya
+ 363, // Tongan
+ 364, // Tsonga
+ 365, // Turkish
0, // Turkmen
0, // Tahitian
0, // Uighur
- 339, // Ukrainian
- 340, // Urdu
- 342, // Uzbek
- 345, // Vietnamese
+ 367, // Ukrainian
+ 368, // Urdu
+ 370, // Uzbek
+ 373, // Vietnamese
0, // Volapuk
- 346, // Welsh
+ 374, // Welsh
0, // Wolof
- 347, // Xhosa
+ 375, // Xhosa
0, // Yiddish
- 348, // Yoruba
+ 376, // Yoruba
0, // Zhuang
- 349, // Zulu
- 350, // NorwegianNynorsk
- 351, // Bosnian
+ 378, // Zulu
+ 379, // NorwegianNynorsk
+ 380, // Bosnian
0, // Divehi
- 353, // Manx
- 354, // Cornish
- 355, // Akan
- 356, // Konkani
+ 382, // Manx
+ 383, // Cornish
+ 384, // Akan
+ 385, // Konkani
0, // Ga
- 357, // Igbo
- 358, // Kamba
+ 386, // Igbo
+ 387, // Kamba
0, // Syriac
- 359, // Blin
+ 388, // Blin
0, // Geez
0, // Koro
0, // Sidamo
0, // Atsam
- 360, // Tigre
+ 389, // Tigre
0, // Jju
- 361, // Friulian
- 362, // Venda
- 363, // Ewe
- 365, // Walamo
- 366, // Hawaiian
+ 390, // Friulian
+ 391, // Venda
+ 392, // Ewe
+ 394, // Walamo
+ 395, // Hawaiian
0, // Tyap
0, // Nyanja
- 367, // Filipino
- 368, // Swiss German
- 369, // Sichuan Yi
+ 396, // Filipino
+ 397, // Swiss German
+ 399, // Sichuan Yi
0, // Kpelle
0, // Low German
- 370, // South Ndebele
- 371, // Northern Sotho
- 372, // Northern Sami
+ 400, // South Ndebele
+ 401, // Northern Sotho
+ 402, // Northern Sami
0, // Taroko
- 374, // Gusii
- 375, // Taita
- 376, // Fulah
- 377, // Kikuyu
- 378, // Samburu
- 379, // Sena
- 380, // North Ndebele
- 381, // Rombo
- 382, // Tachelhit
- 384, // Kabyle
- 385, // Nyankole
- 386, // Bena
- 387, // Vunjo
- 388, // Bambara
- 389, // Embu
- 390, // Cherokee
- 391, // Morisyen
- 392, // Makonde
- 393, // Langi
- 394, // Ganda
- 395, // Bemba
- 396, // Kabuverdianu
- 397, // Meru
- 398, // Kalenjin
- 399, // Nama
- 400, // Machame
- 401, // Colognian
- 402, // Masai
- 404, // Soga
- 405, // Luyia
- 406, // Asu
- 407, // Teso
- 409, // Saho
- 410, // Koyra Chiini
- 411, // Rwa
- 412, // Luo
- 413, // Chiga
- 414, // Central Morocco Tamazight
- 415, // Koyraboro Senni
- 416, // Shambala
- 417, // Bodo
+ 404, // Gusii
+ 405, // Taita
+ 406, // Fulah
+ 407, // Kikuyu
+ 408, // Samburu
+ 409, // Sena
+ 410, // North Ndebele
+ 411, // Rombo
+ 412, // Tachelhit
+ 414, // Kabyle
+ 415, // Nyankole
+ 416, // Bena
+ 417, // Vunjo
+ 418, // Bambara
+ 419, // Embu
+ 420, // Cherokee
+ 421, // Morisyen
+ 422, // Makonde
+ 423, // Langi
+ 424, // Ganda
+ 425, // Bemba
+ 426, // Kabuverdianu
+ 427, // Meru
+ 428, // Kalenjin
+ 429, // Nama
+ 430, // Machame
+ 431, // Colognian
+ 432, // Masai
+ 434, // Soga
+ 435, // Luyia
+ 436, // Asu
+ 437, // Teso
+ 439, // Saho
+ 440, // Koyra Chiini
+ 441, // Rwa
+ 442, // Luo
+ 443, // Chiga
+ 444, // Central Morocco Tamazight
+ 445, // Koyraboro Senni
+ 446, // Shambala
+ 447, // Bodo
0, // Avaric
0, // Chamorro
0, // Chechen
@@ -994,37 +983,37 @@ static const quint16 locale_index[] = {
0, // Kongo
0, // Kwanyama
0, // Limburgish
- 418, // LubaKatanga
+ 448, // LubaKatanga
0, // Luxembourgish
0, // Navaho
0, // Ndonga
0, // Ojibwa
0, // Pali
0, // Walloon
- 419, // Aghem
- 420, // Basaa
- 421, // Zarma
- 422, // Duala
- 423, // JolaFonyi
- 424, // Ewondo
- 425, // Bafia
- 426, // MakhuwaMeetto
- 427, // Mundang
- 428, // Kwasio
- 429, // Nuer
- 430, // Sakha
- 431, // Sangu
- 432, // Congo Swahili
- 433, // Tasawaq
- 434, // Vai
- 436, // Walser
- 437, // Yangben
+ 449, // Aghem
+ 450, // Basaa
+ 451, // Zarma
+ 452, // Duala
+ 453, // JolaFonyi
+ 454, // Ewondo
+ 455, // Bafia
+ 456, // MakhuwaMeetto
+ 457, // Mundang
+ 458, // Kwasio
+ 459, // Nuer
+ 460, // Sakha
+ 461, // Sangu
+ 462, // Congo Swahili
+ 463, // Tasawaq
+ 464, // Vai
+ 466, // Walser
+ 467, // Yangben
0, // Avestan
- 438, // Asturian
- 439, // Ngomba
- 440, // Kako
- 441, // Meta
- 442, // Ngiemboon
+ 468, // Asturian
+ 469, // Ngomba
+ 470, // Kako
+ 471, // Meta
+ 472, // Ngiemboon
0, // Aragonese
0, // Akkadian
0, // AncientEgyptian
@@ -1076,6 +1065,9 @@ static const quint16 locale_index[] = {
0, // TaiDam
0, // TaiNua
0, // Ugaritic
+ 0, // Akoose
+ 473, // Lakota
+ 474, // Standard Moroccan Tamazight
0 // trailing 0
};
@@ -1087,481 +1079,517 @@ static const QLocaleData locale_data[] = {
{ 4, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 196,28 , 224,52 , 276,14 , 196,28 , 224,52 , 276,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 0,7 , 4,4 , 4,0 , 24,5 , 29,7 , 2, 1, 7, 6, 7 }, // Afar/Latin/Ethiopia
{ 4, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 534,119 , 510,24 , 344,48 , 534,119 , 510,24 , 196,28 , 224,52 , 276,14 , 196,28 , 224,52 , 276,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 0,7 , 4,4 , 4,0 , 24,5 , 36,7 , 0, 0, 6, 6, 7 }, // Afar/Latin/Djibouti
{ 4, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 196,28 , 224,52 , 276,14 , 196,28 , 224,52 , 276,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 24,5 , 43,7 , 2, 1, 1, 6, 7 }, // Afar/Latin/Eritrea
- { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 82,17 , 18,7 , 25,12 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {90,65,82}, 11,1 , 31,27 , 4,4 , 8,6 , 50,9 , 59,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/SouthAfrica
- { 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 99,16 , 37,5 , 8,10 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {78,65,68}, 12,1 , 58,23 , 14,5 , 4,0 , 50,9 , 70,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia
- { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {65,76,76}, 13,3 , 0,7 , 4,4 , 4,0 , 77,5 , 82,9 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
- { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {77,75,68}, 16,3 , 0,7 , 4,4 , 4,0 , 77,5 , 91,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
- { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 115,8 , 123,18 , 42,7 , 49,12 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,2 , 7,2 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 77,5 , 99,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
- { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 14,6 , 14,6 , 20,9 , 29,8 , 141,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 9,3 , 9,4 , {69,84,66}, 20,2 , 92,34 , 4,4 , 8,6 , 105,4 , 109,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
- { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,71,80}, 22,5 , 126,70 , 14,5 , 19,6 , 114,7 , 121,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
- { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,90,68}, 27,5 , 196,91 , 14,5 , 19,6 , 114,7 , 124,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
- { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {66,72,68}, 32,5 , 287,91 , 14,5 , 19,6 , 114,7 , 131,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
- { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {88,65,70}, 37,4 , 378,84 , 14,5 , 19,6 , 114,7 , 138,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
- { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,77,70}, 41,7 , 462,105 , 14,5 , 19,6 , 114,7 , 142,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
- { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {68,74,70}, 5,3 , 567,84 , 14,5 , 19,6 , 114,7 , 151,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
- { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {69,82,78}, 8,3 , 651,91 , 14,5 , 19,6 , 114,7 , 157,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
- { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,81,68}, 48,5 , 742,84 , 14,5 , 19,6 , 114,7 , 164,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
- { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 170,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
- { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {74,79,68}, 54,5 , 959,84 , 14,5 , 19,6 , 114,7 , 177,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
- { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {75,87,68}, 59,5 , 1043,84 , 14,5 , 19,6 , 114,7 , 183,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
- { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,66,80}, 64,5 , 1127,84 , 14,5 , 19,6 , 114,7 , 189,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
- { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {76,89,68}, 69,5 , 1211,77 , 14,5 , 19,6 , 114,7 , 194,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
- { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,82,79}, 74,5 , 1288,112 , 14,5 , 19,6 , 114,7 , 199,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
- { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1584,71 , 1655,71 , 1726,24 , 1655,71 , 1750,71 , 1821,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 208,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
- { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {79,77,82}, 84,5 , 1477,77 , 14,5 , 19,6 , 114,7 , 214,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
- { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {73,76,83}, 53,1 , 826,133 , 14,5 , 19,6 , 114,7 , 219,6 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
- { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {81,65,82}, 89,5 , 1554,70 , 4,4 , 4,0 , 114,7 , 225,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
- { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,65,82}, 94,5 , 1624,77 , 4,4 , 4,0 , 114,7 , 228,24 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/SaudiArabia
- { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,79,83}, 99,1 , 1701,77 , 14,5 , 19,6 , 114,7 , 252,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
- { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,68,71}, 0,0 , 1778,84 , 14,5 , 19,6 , 114,7 , 259,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
- { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1376,92 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {83,89,80}, 100,5 , 1862,77 , 4,4 , 4,0 , 114,7 , 266,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
- { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 179,8 , 161,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {84,78,68}, 105,5 , 1939,77 , 4,4 , 4,0 , 114,7 , 271,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
- { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {65,69,68}, 110,5 , 2016,91 , 14,5 , 19,6 , 114,7 , 275,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
- { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {77,65,68}, 79,5 , 1400,77 , 14,5 , 19,6 , 114,7 , 299,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
- { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 43,8 , 51,7 , 151,10 , 161,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 12,1 , 13,1 , {89,69,82}, 115,5 , 2107,70 , 4,4 , 4,0 , 114,7 , 314,5 , 0, 0, 6, 4, 5 }, // Arabic/Arabic/Yemen
- { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 58,7 , 58,7 , 187,8 , 195,21 , 61,4 , 65,10 , 1845,48 , 1893,106 , 1999,24 , 1845,48 , 1893,106 , 1999,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 13,12 , 14,12 , {65,77,68}, 120,3 , 2177,46 , 25,5 , 4,0 , 319,7 , 326,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
- { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 216,8 , 224,18 , 75,8 , 83,12 , 2023,62 , 2085,88 , 158,27 , 2023,62 , 2085,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 25,9 , 26,7 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 334,7 , 341,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
- { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2173,48 , 2221,77 , 158,27 , 2173,48 , 2221,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 124,4 , 2223,41 , 14,5 , 4,0 , 345,12 , 357,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
- { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 250,19 , 37,5 , 8,10 , 2298,77 , 2298,77 , 158,27 , 2298,77 , 2298,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 128,4 , 2264,12 , 14,5 , 4,0 , 367,10 , 367,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
- { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 65,9 , 65,9 , 72,10 , 269,18 , 37,5 , 8,10 , 2375,48 , 2423,93 , 2516,24 , 2375,48 , 2423,93 , 2516,24 , 978,21 , 999,68 , 1067,14 , 978,21 , 999,68 , 1081,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2276,12 , 25,5 , 30,7 , 377,7 , 384,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
- { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {66,68,84}, 132,1 , 2288,21 , 0,4 , 37,6 , 392,5 , 397,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
- { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 74,10 , 84,9 , 287,6 , 224,18 , 18,7 , 25,12 , 2540,90 , 2540,90 , 2630,33 , 2540,90 , 2540,90 , 2630,33 , 1095,37 , 1132,58 , 1190,18 , 1095,37 , 1132,58 , 1190,18 , 34,9 , 33,7 , {73,78,82}, 123,1 , 2309,19 , 0,4 , 37,6 , 392,5 , 405,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
- { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 93,9 , 93,9 , 93,9 , 93,9 , 72,10 , 293,30 , 95,22 , 117,27 , 2663,63 , 2726,191 , 2917,27 , 2944,27 , 2971,132 , 3103,27 , 1208,34 , 1242,79 , 1321,27 , 1208,34 , 1242,79 , 1321,27 , 43,5 , 40,6 , {66,84,78}, 133,3 , 2328,15 , 4,4 , 4,0 , 409,6 , 415,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
- { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 3130,55 , 3185,78 , 158,27 , 3130,55 , 3185,78 , 158,27 , 1348,33 , 1381,43 , 1424,21 , 1348,33 , 1381,43 , 1424,21 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2343,11 , 14,5 , 4,0 , 420,9 , 429,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
- { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 340,18 , 37,5 , 8,10 , 3263,59 , 3322,82 , 3404,24 , 3263,59 , 3322,82 , 3404,24 , 1445,21 , 1466,55 , 1521,14 , 1445,21 , 1466,55 , 1521,14 , 48,7 , 46,7 , {66,71,78}, 136,3 , 2354,47 , 25,5 , 4,0 , 434,9 , 443,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
- { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 3428,43 , 3471,88 , 3559,24 , 3428,43 , 3471,88 , 3559,24 , 1535,25 , 1560,54 , 1614,14 , 1535,25 , 1560,54 , 1614,14 , 55,5 , 53,3 , {77,77,75}, 139,1 , 2401,18 , 14,5 , 4,0 , 451,3 , 454,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
- { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 358,6 , 10,17 , 144,5 , 149,10 , 3583,48 , 3631,99 , 3730,24 , 3754,48 , 3802,95 , 3897,24 , 1628,21 , 1649,56 , 1705,14 , 1628,21 , 1649,56 , 1705,14 , 60,10 , 56,13 , {66,89,82}, 140,2 , 2419,23 , 4,4 , 4,0 , 460,10 , 470,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
- { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 109,9 , 364,8 , 10,17 , 18,7 , 25,12 , 3921,71 , 3921,71 , 158,27 , 3921,71 , 3921,71 , 158,27 , 1719,46 , 1719,46 , 1765,14 , 1719,46 , 1719,46 , 1765,14 , 70,5 , 69,5 , {75,72,82}, 142,1 , 2442,18 , 4,4 , 8,6 , 478,5 , 483,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
- { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 496,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
- { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 27,8 , 372,21 , 159,4 , 163,9 , 3992,60 , 4052,82 , 4134,24 , 4158,93 , 4251,115 , 4366,24 , 1779,21 , 1800,60 , 1779,21 , 1860,28 , 1888,60 , 1779,21 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 4,4 , 8,6 , 490,6 , 503,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
- { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 393,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {67,78,89}, 143,1 , 2480,10 , 4,4 , 8,6 , 510,4 , 514,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
- { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 4,0 , 510,4 , 516,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
- { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2499,10 , 4,4 , 4,0 , 510,4 , 525,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
- { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 125,5 , 125,5 , 130,5 , 130,5 , 27,8 , 399,13 , 188,7 , 178,10 , 4390,39 , 4429,38 , 158,27 , 4390,39 , 4429,38 , 158,27 , 1948,21 , 1969,28 , 1997,14 , 1948,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {83,71,68}, 12,1 , 2509,11 , 4,4 , 4,0 , 510,4 , 534,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
- { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 287,6 , 399,13 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {72,75,68}, 12,1 , 2490,9 , 4,4 , 8,6 , 537,4 , 541,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
- { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 412,7 , 419,15 , 172,6 , 195,13 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {77,79,80}, 144,4 , 2520,10 , 4,4 , 4,0 , 537,4 , 555,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
- { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 130,5 , 130,5 , 179,8 , 399,13 , 172,6 , 208,11 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 2011,21 , 1969,28 , 1997,14 , 2011,21 , 1969,28 , 1997,14 , 79,2 , 78,2 , {84,87,68}, 148,3 , 2530,10 , 4,4 , 4,0 , 537,4 , 569,2 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
- { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {72,82,75}, 151,2 , 2540,74 , 25,5 , 4,0 , 571,8 , 579,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
- { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 434,9 , 443,19 , 37,5 , 8,10 , 4467,49 , 4516,94 , 4610,39 , 4467,49 , 4649,98 , 4610,39 , 2032,28 , 2060,58 , 2118,14 , 2032,28 , 2060,58 , 2132,14 , 0,2 , 0,2 , {66,65,77}, 153,2 , 2614,106 , 25,5 , 4,0 , 571,8 , 587,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
- { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 187,8 , 462,18 , 61,4 , 219,9 , 4747,48 , 4795,82 , 4877,24 , 4747,48 , 4901,84 , 158,27 , 2146,21 , 2167,49 , 2216,14 , 2146,21 , 2167,49 , 2216,14 , 81,4 , 80,4 , {67,90,75}, 155,2 , 2720,56 , 25,5 , 4,0 , 606,7 , 613,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
- { 29, 7, 58, 44, 46, 44, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 27,8 , 480,23 , 144,5 , 149,10 , 4985,48 , 5033,84 , 134,24 , 5117,59 , 5033,84 , 134,24 , 2230,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 2776,42 , 25,5 , 4,0 , 628,5 , 633,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
- { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 19,6 , 640,10 , 650,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
- { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,87,71}, 159,4 , 2837,55 , 14,5 , 19,6 , 640,10 , 659,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
- { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 511,7 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 664,6 , 670,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
- { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 676,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
- { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 2989,24 , 14,5 , 19,6 , 640,10 , 683,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
- { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 503,8 , 99,16 , 37,5 , 8,10 , 5176,48 , 5224,88 , 134,24 , 5312,59 , 5224,88 , 134,24 , 2358,21 , 2379,59 , 2438,14 , 2358,21 , 2379,59 , 2438,14 , 0,2 , 0,2 , {65,78,71}, 163,4 , 2892,97 , 14,5 , 19,6 , 640,10 , 691,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
- { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 703,12 , 715,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
- { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 5371,80 , 5451,154 , 5605,36 , 5371,80 , 5451,154 , 5605,36 , 2452,49 , 2501,85 , 2586,21 , 2452,49 , 2501,85 , 2586,21 , 85,4 , 84,4 , {85,83,68}, 12,1 , 0,7 , 14,5 , 4,0 , 728,10 , 738,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
- { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 770,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
- { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 784,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
- { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 4,0 , 803,18 , 821,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
- { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3178,53 , 4,4 , 8,6 , 763,7 , 830,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
- { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3231,56 , 4,4 , 8,6 , 763,7 , 837,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
- { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 37,5 , 228,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 25,5 , 4,0 , 763,7 , 845,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
- { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 524,12 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3287,47 , 4,4 , 4,0 , 763,7 , 852,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
- { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3334,53 , 4,4 , 8,6 , 763,7 , 858,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
- { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 3387,50 , 4,4 , 4,0 , 763,7 , 865,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
- { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 3437,50 , 4,4 , 8,6 , 763,7 , 873,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
- { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3487,53 , 4,4 , 8,6 , 881,16 , 897,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
- { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3540,71 , 4,4 , 8,6 , 763,7 , 903,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
- { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 917,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
- { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 3611,47 , 4,4 , 8,6 , 763,7 , 925,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
- { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 929,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
- { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 172,1 , 3705,50 , 4,4 , 8,6 , 763,7 , 937,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
- { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 3755,47 , 4,4 , 8,6 , 763,7 , 943,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
- { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,73,80}, 171,1 , 3802,53 , 4,4 , 4,0 , 763,7 , 948,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
- { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 957,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
- { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 964,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
- { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 3855,56 , 4,4 , 8,6 , 763,7 , 968,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
- { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {72,75,68}, 12,1 , 3911,56 , 4,4 , 8,6 , 763,7 , 974,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
- { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {73,78,82}, 123,1 , 3967,44 , 14,5 , 4,0 , 763,7 , 993,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
- { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 998,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
- { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 287,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4011,53 , 4,4 , 4,0 , 763,7 , 1005,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
- { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4064,53 , 4,4 , 8,6 , 763,7 , 1012,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
- { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3119,59 , 4,4 , 8,6 , 763,7 , 1017,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
- { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1025,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
- { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4178,53 , 4,4 , 8,6 , 763,7 , 1032,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
- { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 4231,54 , 4,4 , 8,6 , 763,7 , 1039,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
- { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 178,2 , 4285,53 , 4,4 , 8,6 , 763,7 , 1049,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
- { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {69,85,82}, 19,1 , 2818,19 , 4,4 , 4,0 , 763,7 , 1055,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
- { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1060,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
- { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 4338,53 , 4,4 , 8,6 , 763,7 , 1076,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
- { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1085,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
- { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 4391,53 , 4,4 , 4,0 , 763,7 , 1095,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
- { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 511,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {78,90,68}, 12,1 , 4444,62 , 4,4 , 4,0 , 763,7 , 1102,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
- { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 4506,50 , 4,4 , 8,6 , 763,7 , 1113,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
- { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1120,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
- { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {80,75,82}, 180,2 , 4556,53 , 14,5 , 4,0 , 763,7 , 1144,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
- { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1152,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
- { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 139,1 , 4609,73 , 4,4 , 8,6 , 763,7 , 1157,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
- { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 4682,42 , 4,4 , 8,6 , 763,7 , 1173,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
- { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1184,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
- { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1195,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
- { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1216,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
- { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 167,3 , 3048,71 , 4,4 , 8,6 , 763,7 , 1227,32 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
- { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 184,3 , 4724,40 , 4,4 , 8,6 , 763,7 , 1259,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
- { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 4764,59 , 4,4 , 8,6 , 763,7 , 1264,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
- { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 189,2 , 4823,68 , 4,4 , 8,6 , 763,7 , 1274,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
- { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 287,6 , 224,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {83,71,68}, 12,1 , 4891,56 , 4,4 , 8,6 , 763,7 , 1286,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
- { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 4947,74 , 4,4 , 8,6 , 763,7 , 1295,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
- { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 536,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4117,61 , 4,4 , 8,6 , 763,7 , 1310,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
- { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 5021,53 , 4,4 , 8,6 , 763,7 , 1322,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
- { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 192,3 , 5074,62 , 4,4 , 8,6 , 763,7 , 1331,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
- { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 5136,49 , 4,4 , 8,6 , 763,7 , 1339,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
- { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5185,86 , 4,4 , 4,0 , 763,7 , 1344,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
- { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1363,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
- { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 5271,56 , 4,4 , 8,6 , 763,7 , 1387,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
- { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 1393,15 , 1408,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
- { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1422,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
- { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 5327,44 , 4,4 , 8,6 , 763,7 , 1443,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
- { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1450,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
- { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3013,35 , 4,4 , 8,6 , 763,7 , 1472,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
- { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 202,2 , 5371,50 , 4,4 , 8,6 , 763,7 , 1491,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
- { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 364,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 3013,35 , 4,4 , 4,0 , 763,7 , 1497,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
- { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1505,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
- { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 160,9 , 160,9 , 141,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 89,2 , 88,2 , {71,66,80}, 171,1 , 3658,47 , 4,4 , 4,0 , 763,7 , 1516,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
- { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 150,10 , 160,9 , 518,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 171,1 , 5421,68 , 4,4 , 8,6 , 763,7 , 1522,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
- { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 169,8 , 169,8 , 187,8 , 462,18 , 61,4 , 252,9 , 5641,59 , 5700,91 , 5791,24 , 5641,59 , 5700,91 , 5791,24 , 2607,14 , 2621,63 , 2607,14 , 2607,14 , 2621,63 , 2607,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 5489,20 , 25,5 , 30,7 , 1533,5 , 1538,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
- { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 503,8 , 82,17 , 37,5 , 8,10 , 5815,48 , 5863,83 , 134,24 , 5815,48 , 5863,83 , 134,24 , 2684,28 , 2712,74 , 2786,14 , 2684,28 , 2712,74 , 2786,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 5509,42 , 4,4 , 43,5 , 1543,8 , 1551,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
- { 36, 7, 73, 44, 160, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 546,8 , 554,17 , 159,4 , 163,9 , 5946,69 , 6015,105 , 6120,24 , 6144,129 , 6144,129 , 6120,24 , 2800,21 , 2821,67 , 2888,14 , 2800,21 , 2902,81 , 2888,14 , 91,3 , 90,3 , {69,85,82}, 19,1 , 5551,20 , 25,5 , 4,0 , 1558,5 , 1563,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
- { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1576,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
- { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,90,68}, 207,2 , 5571,51 , 25,5 , 30,7 , 1568,8 , 1582,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
- { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 511,7 , 99,16 , 37,5 , 261,23 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1589,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
- { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1597,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
- { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1602,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
- { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {66,73,70}, 212,3 , 5681,53 , 25,5 , 30,7 , 1568,8 , 1614,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
- { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1621,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
- { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 115,8 , 99,16 , 37,5 , 228,24 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 5790,54 , 25,5 , 30,7 , 1629,17 , 897,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
- { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1646,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
- { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1671,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
- { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {75,77,70}, 215,2 , 5844,51 , 25,5 , 30,7 , 1568,8 , 1676,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
- { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,68,70}, 217,2 , 5895,53 , 25,5 , 30,7 , 1568,8 , 1683,32 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
- { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1715,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
- { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1732,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
- { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 5948,57 , 25,5 , 30,7 , 1568,8 , 1745,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
- { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1753,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
- { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1771,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
- { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1787,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
- { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,65,70}, 37,4 , 5734,56 , 25,5 , 30,7 , 1568,8 , 1806,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
- { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1811,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
- { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {71,78,70}, 223,2 , 6040,48 , 25,5 , 30,7 , 1568,8 , 1821,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
- { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {72,84,71}, 225,1 , 6088,57 , 25,5 , 30,7 , 1568,8 , 1827,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
- { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1832,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
- { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 6145,54 , 25,5 , 30,7 , 1568,8 , 1039,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
- { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1842,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
- { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1846,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
- { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,82,79}, 226,2 , 6199,66 , 25,5 , 30,7 , 1568,8 , 1856,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
- { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 6265,63 , 25,5 , 30,7 , 1568,8 , 1866,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
- { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1873,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
- { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1880,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
- { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 6328,54 , 25,5 , 30,7 , 1568,8 , 1886,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
- { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,80,70}, 219,4 , 6005,35 , 25,5 , 30,7 , 1568,8 , 1891,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
- { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1909,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
- { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1914,7 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
- { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 6382,50 , 25,5 , 30,7 , 1568,8 , 1921,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
- { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1927,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
- { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,67,82}, 187,2 , 6432,71 , 25,5 , 30,7 , 1568,8 , 1264,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
- { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 177,8 , 177,8 , 187,8 , 10,17 , 37,5 , 284,14 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 6503,45 , 14,5 , 48,5 , 1934,15 , 1949,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
- { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {83,89,80}, 233,2 , 6548,51 , 25,5 , 30,7 , 1568,8 , 1955,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
- { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 5622,59 , 25,5 , 30,7 , 1568,8 , 1960,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
- { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {84,78,68}, 235,2 , 6599,51 , 25,5 , 30,7 , 1568,8 , 1964,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
- { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {86,85,86}, 200,2 , 6650,51 , 25,5 , 30,7 , 1568,8 , 1443,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
- { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1971,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
- { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 177,8 , 177,8 , 141,10 , 99,16 , 37,5 , 8,10 , 6273,63 , 6336,85 , 134,24 , 6273,63 , 6336,85 , 134,24 , 2983,35 , 3018,52 , 3070,14 , 2983,35 , 3018,52 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 30,7 , 1568,8 , 1987,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
- { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,11 , 196,10 , 141,10 , 10,17 , 37,5 , 8,10 , 6421,61 , 6482,142 , 6624,36 , 6421,61 , 6482,142 , 6624,36 , 3084,28 , 3112,69 , 3181,14 , 3084,28 , 3112,69 , 3181,14 , 0,2 , 0,2 , {71,66,80}, 171,1 , 6701,22 , 4,4 , 8,6 , 2018,8 , 2026,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
- { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6660,48 , 6708,87 , 6795,24 , 6660,48 , 6708,87 , 6795,24 , 3195,28 , 3223,49 , 3272,14 , 3195,28 , 3223,49 , 3272,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 6723,20 , 4,4 , 8,6 , 2048,6 , 2054,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
- { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 213,8 , 213,8 , 187,8 , 571,19 , 37,5 , 8,10 , 6819,48 , 6867,99 , 6966,24 , 6819,48 , 6867,99 , 6966,24 , 3286,28 , 3314,62 , 3376,14 , 3286,28 , 3314,62 , 3376,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 6743,19 , 25,5 , 4,0 , 2060,7 , 2067,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
- { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2084,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
- { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 590,19 , 37,5 , 8,10 , 7180,48 , 7038,83 , 134,24 , 7228,58 , 7286,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 14,5 , 4,0 , 2095,24 , 2119,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
- { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2129,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
- { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 0,0 , 6781,58 , 14,5 , 4,0 , 2077,7 , 2136,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
- { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {69,85,82}, 19,1 , 6762,19 , 25,5 , 4,0 , 2077,7 , 2149,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
- { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 7038,83 , 134,24 , 7121,59 , 7038,83 , 134,24 , 3390,21 , 3411,60 , 3471,14 , 3485,28 , 3411,60 , 3471,14 , 94,5 , 93,6 , {67,72,70}, 230,3 , 6781,58 , 14,5 , 48,5 , 2158,21 , 2179,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
- { 43, 16, 85, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 25,5 , 4,0 , 2186,8 , 2194,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
- { 43, 16, 56, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 230,9 , 230,9 , 287,6 , 10,17 , 18,7 , 25,12 , 7369,50 , 7419,115 , 7534,24 , 7558,50 , 7608,115 , 7534,24 , 3513,28 , 3541,55 , 3596,14 , 3513,28 , 3541,55 , 3596,14 , 99,4 , 99,4 , {69,85,82}, 19,1 , 6839,19 , 4,4 , 4,0 , 2186,8 , 2200,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
- { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 239,11 , 239,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4985,48 , 7723,96 , 134,24 , 4985,48 , 7723,96 , 134,24 , 3610,28 , 3638,98 , 3736,14 , 3610,28 , 3638,98 , 3736,14 , 0,2 , 0,2 , {68,75,75}, 157,2 , 6858,59 , 4,4 , 43,5 , 2206,11 , 2217,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
- { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 250,9 , 250,9 , 609,7 , 224,18 , 298,8 , 306,13 , 7819,64 , 7883,87 , 7970,31 , 8001,67 , 8068,87 , 7970,31 , 3750,32 , 3782,53 , 3835,19 , 3750,32 , 3782,53 , 3835,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 6917,20 , 4,4 , 8,6 , 2233,7 , 2240,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
- { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {78,71,78}, 182,1 , 6937,12 , 14,5 , 4,0 , 2244,5 , 2249,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
- { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {71,72,83}, 173,3 , 0,7 , 14,5 , 4,0 , 2244,5 , 2257,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
- { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 224,18 , 37,5 , 8,10 , 8155,48 , 8203,85 , 8288,24 , 8155,48 , 8203,85 , 8288,24 , 3854,21 , 3875,52 , 3927,14 , 3854,21 , 3875,52 , 3927,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 6949,36 , 14,5 , 4,0 , 2244,5 , 2261,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
- { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 259,6 , 259,6 , 27,8 , 616,18 , 37,5 , 8,10 , 8312,58 , 8370,72 , 158,27 , 8442,48 , 8370,72 , 158,27 , 3941,46 , 3987,65 , 4052,19 , 3941,46 , 3987,65 , 4071,21 , 103,6 , 103,5 , {73,76,83}, 53,1 , 6985,54 , 25,5 , 4,0 , 2266,5 , 2271,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
- { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 265,9 , 274,8 , 634,6 , 10,17 , 18,7 , 25,12 , 8490,75 , 8490,75 , 8565,30 , 8490,75 , 8490,75 , 8565,30 , 4092,38 , 4130,57 , 4187,19 , 4092,38 , 4130,57 , 4187,19 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7039,19 , 14,5 , 4,0 , 2276,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
- { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 282,8 , 282,8 , 640,11 , 651,19 , 61,4 , 219,9 , 8595,64 , 8659,98 , 8757,25 , 8595,64 , 8659,98 , 8782,25 , 4206,19 , 4225,52 , 4277,17 , 4206,19 , 4225,52 , 4277,17 , 118,3 , 115,3 , {72,85,70}, 237,2 , 7058,20 , 25,5 , 4,0 , 2286,6 , 2292,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
- { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 142,8 , 142,8 , 546,8 , 462,18 , 37,5 , 8,10 , 8807,48 , 8855,82 , 8937,24 , 8807,48 , 8855,82 , 8961,24 , 4294,28 , 4322,81 , 4403,14 , 4294,28 , 4322,81 , 4417,14 , 121,4 , 118,4 , {73,83,75}, 157,2 , 7078,49 , 4,4 , 8,6 , 2304,8 , 2312,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
- { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 27,8 , 123,18 , 144,5 , 149,10 , 8985,48 , 9033,87 , 134,24 , 8985,48 , 9033,87 , 134,24 , 4431,28 , 4459,43 , 4502,14 , 4431,28 , 4459,43 , 4502,14 , 0,2 , 0,2 , {73,68,82}, 239,2 , 7127,23 , 4,4 , 4,0 , 2318,16 , 2334,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
- { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 9120,48 , 9168,93 , 158,27 , 9120,48 , 9168,93 , 158,27 , 4516,28 , 4544,57 , 85,14 , 4516,28 , 4544,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 7150,12 , 14,5 , 4,0 , 2343,11 , 2354,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
- { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 9261,62 , 9323,107 , 9430,24 , 9261,62 , 9323,107 , 9430,24 , 4601,37 , 4638,75 , 4713,14 , 4601,37 , 4638,75 , 4713,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 81,11 , 4,4 , 4,0 , 2361,7 , 2368,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
- { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2380,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
- { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 309,8 , 206,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2818,19 , 14,5 , 4,0 , 2372,8 , 2386,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
- { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 309,8 , 206,7 , 187,8 , 10,17 , 37,5 , 284,14 , 9454,48 , 9502,94 , 9596,24 , 9454,48 , 9620,94 , 9596,24 , 4727,28 , 4755,57 , 4812,14 , 4727,28 , 4826,57 , 4812,14 , 0,2 , 0,2 , {67,72,70}, 230,3 , 7162,53 , 14,5 , 48,5 , 2372,8 , 2396,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
- { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 125,5 , 125,5 , 125,5 , 125,5 , 536,10 , 399,13 , 61,4 , 319,10 , 4390,39 , 4390,39 , 158,27 , 4390,39 , 4390,39 , 158,27 , 4883,14 , 4897,28 , 4883,14 , 4883,14 , 4897,28 , 4883,14 , 125,2 , 122,2 , {74,80,89}, 143,1 , 7215,10 , 4,4 , 4,0 , 2404,3 , 2407,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
- { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 317,12 , 329,11 , 634,6 , 99,16 , 298,8 , 306,13 , 9714,91 , 9805,86 , 9891,31 , 9714,91 , 9805,86 , 9922,31 , 4925,28 , 4953,53 , 5006,19 , 4925,28 , 4953,53 , 5006,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7225,20 , 4,4 , 8,6 , 2409,5 , 2414,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
- { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 9953,72 , 9953,72 , 10025,24 , 9953,72 , 9953,72 , 10025,24 , 5025,54 , 5079,56 , 5135,14 , 5025,54 , 5079,56 , 5135,14 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7245,23 , 14,5 , 4,0 , 2418,5 , 2423,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
- { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10049,61 , 10110,83 , 158,27 , 10049,61 , 10110,83 , 158,27 , 5149,28 , 5177,54 , 85,14 , 5149,28 , 5177,54 , 85,14 , 0,2 , 0,2 , {75,90,84}, 241,1 , 7268,24 , 25,5 , 4,0 , 2433,10 , 2443,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
- { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 10193,60 , 10253,101 , 158,27 , 10193,60 , 10253,101 , 158,27 , 5231,35 , 5266,84 , 85,14 , 5231,35 , 5266,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 228,2 , 0,7 , 14,5 , 4,0 , 2452,11 , 1921,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
- { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 187,8 , 670,22 , 37,5 , 8,10 , 10354,60 , 10414,80 , 158,27 , 10494,59 , 10553,80 , 158,27 , 5350,28 , 5378,57 , 85,14 , 5435,28 , 5463,57 , 85,14 , 0,2 , 0,2 , {75,71,83}, 242,3 , 0,7 , 14,5 , 4,0 , 2463,6 , 2469,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
- { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,82,87}, 245,1 , 7292,13 , 4,4 , 8,6 , 2479,3 , 2482,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
- { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 340,7 , 340,7 , 692,9 , 701,16 , 329,7 , 336,13 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 10633,39 , 5520,14 , 5534,28 , 5520,14 , 5520,14 , 5534,28 , 5520,14 , 127,2 , 124,2 , {75,80,87}, 0,0 , 7305,23 , 4,4 , 8,6 , 2479,3 , 2486,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
- { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 10672,60 , 10732,106 , 158,27 , 10672,60 , 10732,106 , 158,27 , 5562,34 , 5596,89 , 85,14 , 5562,34 , 5596,89 , 85,14 , 129,5 , 126,5 , {66,73,70}, 212,3 , 7328,27 , 0,4 , 4,0 , 2500,8 , 2508,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
- { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 717,18 , 61,4 , 349,24 , 10838,62 , 10900,75 , 158,27 , 10975,61 , 10900,75 , 158,27 , 5685,23 , 5708,57 , 5765,18 , 5783,24 , 5708,57 , 1765,14 , 134,8 , 131,8 , {76,65,75}, 246,1 , 7355,14 , 4,4 , 48,5 , 2516,3 , 2519,9 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
- { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 347,8 , 347,8 , 187,8 , 735,26 , 37,5 , 8,10 , 11036,65 , 11101,101 , 134,24 , 11202,65 , 11267,101 , 134,24 , 5807,21 , 5828,72 , 5900,14 , 5807,21 , 5914,72 , 5900,14 , 142,14 , 139,11 , {76,86,76}, 247,2 , 7369,59 , 4,4 , 8,6 , 2528,8 , 2536,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
- { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {67,68,70}, 217,2 , 7428,23 , 25,5 , 4,0 , 2543,7 , 2550,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
- { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {65,79,65}, 249,2 , 7451,23 , 25,5 , 4,0 , 2543,7 , 2579,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
- { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2585,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
- { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 355,9 , 355,9 , 364,8 , 99,16 , 37,5 , 8,10 , 11368,48 , 11416,203 , 11619,24 , 11368,48 , 11416,203 , 11619,24 , 5986,28 , 6014,100 , 6114,14 , 5986,28 , 6014,100 , 6114,14 , 156,8 , 150,6 , {88,65,70}, 37,4 , 7474,23 , 25,5 , 4,0 , 2543,7 , 2611,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
- { 73, 7, 124, 44, 160, 59, 37, 48, 8211, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 364,8 , 364,8 , 72,10 , 761,27 , 37,5 , 8,10 , 11643,70 , 11713,96 , 11809,24 , 11643,70 , 11713,96 , 11809,24 , 6128,21 , 6149,89 , 6238,14 , 6128,21 , 6149,89 , 6238,14 , 164,9 , 156,6 , {76,84,76}, 251,2 , 7497,62 , 25,5 , 4,0 , 2616,8 , 2624,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
- { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 788,7 , 123,18 , 37,5 , 8,10 , 11833,63 , 11896,85 , 11981,24 , 11833,63 , 11896,85 , 11981,24 , 6252,34 , 6286,54 , 1521,14 , 6252,34 , 6286,54 , 1521,14 , 173,10 , 162,8 , {77,75,68}, 253,3 , 7559,23 , 14,5 , 4,0 , 2631,10 , 2641,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
- { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 12005,48 , 12053,92 , 134,24 , 12005,48 , 12053,92 , 134,24 , 6340,34 , 6374,60 , 6434,14 , 6340,34 , 6374,60 , 6434,14 , 0,2 , 0,2 , {77,71,65}, 176,2 , 7582,13 , 4,4 , 4,0 , 2651,8 , 2659,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
- { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {77,89,82}, 256,2 , 7595,23 , 4,4 , 8,6 , 2671,13 , 2684,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
- { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 524,12 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {66,78,68}, 12,1 , 7618,19 , 14,5 , 4,0 , 2671,13 , 2692,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
- { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 290,10 , 300,9 , 511,7 , 10,17 , 18,7 , 25,12 , 12145,49 , 12194,82 , 12276,24 , 12145,49 , 12194,82 , 12276,24 , 6448,28 , 6476,43 , 6519,14 , 6448,28 , 6476,43 , 6519,14 , 183,2 , 170,3 , {83,71,68}, 12,1 , 7637,22 , 4,4 , 8,6 , 2671,13 , 2698,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
- { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 372,13 , 385,12 , 27,8 , 795,18 , 18,7 , 25,12 , 12300,62 , 12362,87 , 12449,31 , 12300,62 , 12362,87 , 12449,31 , 6533,41 , 6574,70 , 6644,22 , 6533,41 , 6574,70 , 6644,22 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7659,40 , 0,4 , 4,0 , 2707,6 , 2713,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
- { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 397,8 , 405,7 , 141,10 , 813,23 , 37,5 , 8,10 , 12480,48 , 12528,86 , 12614,24 , 12480,48 , 12528,86 , 12614,24 , 6666,28 , 6694,63 , 6757,14 , 6666,28 , 6694,63 , 6757,14 , 185,2 , 173,2 , {69,85,82}, 19,1 , 7699,11 , 4,4 , 4,0 , 2719,5 , 1055,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
- { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 412,9 , 412,9 , 634,6 , 99,16 , 373,7 , 380,12 , 12638,66 , 12704,86 , 12790,32 , 12638,66 , 12704,86 , 12790,32 , 6771,32 , 6803,53 , 4187,19 , 6771,32 , 6803,53 , 4187,19 , 0,2 , 0,2 , {73,78,82}, 123,1 , 7710,19 , 4,4 , 8,6 , 2724,5 , 2282,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
- { 82, 2, 143, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 836,31 , 37,5 , 8,10 , 12822,48 , 12870,66 , 158,27 , 12822,48 , 12870,66 , 158,27 , 6856,21 , 6877,43 , 1765,14 , 6856,21 , 6877,43 , 1765,14 , 187,2 , 175,2 , {77,78,84}, 258,1 , 7729,25 , 14,5 , 4,0 , 2729,6 , 2735,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
- { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 12992,85 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 6953,54 , 7007,14 , 189,14 , 177,14 , {78,80,82}, 259,4 , 7754,52 , 14,5 , 4,0 , 2741,6 , 2747,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
- { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 12936,56 , 12992,85 , 13077,27 , 12936,56 , 13104,80 , 13077,27 , 6920,33 , 6953,54 , 7007,14 , 6920,33 , 7021,54 , 7007,14 , 109,9 , 108,7 , {73,78,82}, 123,1 , 7806,49 , 14,5 , 4,0 , 2741,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
- { 85, 7, 161, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 7075,28 , 2258,51 , 2309,14 , 2323,35 , 2258,51 , 2309,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 7855,44 , 14,5 , 4,0 , 2752,12 , 2764,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
- { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 10,17 , 18,7 , 25,12 , 13326,89 , 13326,89 , 13415,32 , 13326,89 , 13326,89 , 13415,32 , 7103,33 , 7136,54 , 7190,18 , 7103,33 , 7136,54 , 7190,18 , 89,2 , 88,2 , {73,78,82}, 123,1 , 7899,11 , 14,5 , 4,0 , 2769,5 , 2774,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
- { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 867,20 , 61,4 , 408,11 , 13447,68 , 13447,68 , 158,27 , 13447,68 , 13447,68 , 158,27 , 7208,49 , 7208,49 , 85,14 , 7208,49 , 7208,49 , 85,14 , 203,4 , 191,4 , {65,70,78}, 263,1 , 7910,13 , 25,5 , 4,0 , 2778,4 , 2782,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
- { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13585,24 , 13609,74 , 13609,74 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {73,82,82}, 264,1 , 7923,17 , 53,5 , 58,7 , 2791,5 , 2796,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
- { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 8722, 43, 101, 171, 187, 8249, 8250, 421,7 , 421,7 , 43,8 , 51,7 , 179,8 , 99,16 , 61,4 , 408,11 , 13515,70 , 13515,70 , 13683,24 , 13707,64 , 13771,68 , 13585,24 , 7208,49 , 7208,49 , 7257,14 , 7208,49 , 7208,49 , 7257,14 , 207,9 , 195,8 , {65,70,78}, 263,1 , 7940,23 , 53,5 , 58,7 , 2801,3 , 2782,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
- { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 118,7 , 118,7 , 887,10 , 10,17 , 37,5 , 8,10 , 13839,48 , 13887,97 , 13984,24 , 13839,48 , 14008,99 , 13984,24 , 7271,34 , 7305,59 , 7364,14 , 7271,34 , 7305,59 , 7364,14 , 0,2 , 0,2 , {80,76,78}, 265,2 , 7963,77 , 25,5 , 30,7 , 2804,6 , 2810,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
- { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14107,48 , 14155,89 , 134,24 , 14107,48 , 14155,89 , 134,24 , 7378,28 , 7406,79 , 7485,14 , 7378,28 , 7406,79 , 7485,14 , 0,2 , 0,2 , {66,82,76}, 267,2 , 8040,54 , 4,4 , 8,6 , 2816,19 , 2835,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
- { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {65,79,65}, 249,2 , 8094,54 , 25,5 , 4,0 , 2841,9 , 2850,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
- { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {67,86,69}, 0,0 , 8148,69 , 25,5 , 4,0 , 2841,9 , 2856,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
- { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 8217,81 , 25,5 , 4,0 , 2841,9 , 2866,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
- { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 8298,62 , 25,5 , 4,0 , 2841,9 , 2877,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
- { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,79,80}, 144,4 , 8360,53 , 25,5 , 4,0 , 2841,9 , 2889,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
- { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 8413,72 , 25,5 , 4,0 , 2841,9 , 2908,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
- { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 8485,20 , 25,5 , 4,0 , 2918,17 , 2935,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
- { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 897,27 , 37,5 , 8,10 , 14244,48 , 14292,89 , 134,24 , 14244,48 , 14292,89 , 134,24 , 7378,28 , 7499,79 , 7485,14 , 7378,28 , 7499,79 , 7485,14 , 0,2 , 0,2 , {83,84,68}, 272,2 , 8505,92 , 25,5 , 4,0 , 2841,9 , 2943,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
- { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14381,68 , 14381,68 , 14449,27 , 14381,68 , 14381,68 , 14449,27 , 7578,38 , 7616,55 , 7671,23 , 7578,38 , 7616,55 , 7671,23 , 216,11 , 203,11 , {73,78,82}, 123,1 , 8597,12 , 14,5 , 4,0 , 2962,6 , 2968,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
- { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 123,18 , 18,7 , 25,12 , 14476,67 , 14476,67 , 158,27 , 14476,67 , 14476,67 , 158,27 , 7694,37 , 7694,37 , 85,14 , 7694,37 , 7694,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 274,1 , 8609,13 , 14,5 , 4,0 , 2972,5 , 2977,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
- { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 503,8 , 924,28 , 37,5 , 8,10 , 14543,67 , 14610,92 , 14702,24 , 14543,67 , 14610,92 , 14702,24 , 7731,23 , 7754,56 , 7810,14 , 7731,23 , 7754,56 , 7810,14 , 89,2 , 214,2 , {67,72,70}, 230,3 , 8622,20 , 25,5 , 4,0 , 2983,9 , 2992,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
- { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {82,79,78}, 0,0 , 8642,57 , 25,5 , 4,0 , 2998,6 , 3004,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
- { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 428,8 , 428,8 , 887,10 , 10,17 , 37,5 , 8,10 , 14726,60 , 14786,98 , 14884,24 , 14726,60 , 14786,98 , 14884,24 , 7824,21 , 7845,48 , 3070,14 , 7824,21 , 7845,48 , 3070,14 , 0,2 , 0,2 , {77,68,76}, 0,0 , 8699,69 , 25,5 , 4,0 , 2998,6 , 3011,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
- { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {82,85,66}, 275,4 , 8768,89 , 25,5 , 4,0 , 3028,7 , 3035,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
- { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {66,89,82}, 140,2 , 8857,94 , 25,5 , 4,0 , 3028,7 , 470,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
- { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,90,84}, 241,1 , 8951,83 , 25,5 , 4,0 , 3028,7 , 3041,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
- { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {75,71,83}, 242,3 , 9034,81 , 25,5 , 4,0 , 3028,7 , 3050,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
- { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 61,4 , 219,9 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {77,68,76}, 0,0 , 9115,79 , 25,5 , 4,0 , 3028,7 , 3058,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
- { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 102,7 , 102,7 , 187,8 , 952,22 , 37,5 , 8,10 , 14908,62 , 10414,80 , 14970,24 , 14994,63 , 15057,82 , 14970,24 , 7893,21 , 7914,62 , 7976,14 , 7990,21 , 8011,62 , 7990,21 , 227,10 , 216,13 , {85,65,72}, 279,1 , 9194,92 , 25,5 , 4,0 , 3028,7 , 3065,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
- { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 15139,48 , 15187,91 , 15278,24 , 15139,48 , 15187,91 , 15278,24 , 8073,28 , 8101,66 , 8167,14 , 8073,28 , 8101,66 , 8167,14 , 237,2 , 229,2 , {88,65,70}, 37,4 , 9286,25 , 4,4 , 48,5 , 3072,5 , 3077,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
- { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {82,83,68}, 280,4 , 9311,72 , 25,5 , 4,0 , 3099,6 , 3105,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
- { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 9383,196 , 25,5 , 4,0 , 3111,6 , 587,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
- { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3117,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
- { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {82,83,68}, 284,4 , 9606,72 , 25,5 , 4,0 , 3111,6 , 3126,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
- { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 115,8 , 981,20 , 37,5 , 419,40 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 9678,196 , 25,5 , 4,0 , 3132,6 , 3138,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
- { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3157,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
- { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15302,48 , 15350,81 , 11981,24 , 15302,48 , 15350,81 , 11981,24 , 8181,28 , 8209,52 , 8261,14 , 8181,28 , 8209,52 , 8261,14 , 239,9 , 231,7 , {69,85,82}, 19,1 , 9874,27 , 25,5 , 4,0 , 3099,6 , 3166,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
- { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 118,7 , 118,7 , 974,7 , 981,20 , 144,5 , 149,10 , 15431,48 , 15479,81 , 15560,24 , 15431,48 , 15479,81 , 15560,24 , 8275,28 , 8303,54 , 2118,14 , 8275,28 , 8303,54 , 2118,14 , 248,9 , 238,7 , {69,85,82}, 19,1 , 9579,27 , 25,5 , 4,0 , 3111,6 , 3172,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
- { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 9901,17 , 14,5 , 4,0 , 3178,4 , 3182,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
- { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 436,9 , 436,9 , 187,8 , 1001,23 , 37,5 , 8,10 , 14908,62 , 15667,82 , 14970,24 , 15749,59 , 15808,86 , 14970,24 , 8439,28 , 8467,61 , 8528,14 , 8542,28 , 8570,61 , 8528,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 9918,17 , 14,5 , 4,0 , 3178,4 , 3193,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
- { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
- { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 15894,48 , 15942,105 , 158,27 , 15894,48 , 15942,105 , 158,27 , 8631,27 , 8658,61 , 85,14 , 8631,27 , 8658,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3199,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
- { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
- { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16047,48 , 16095,117 , 158,27 , 16047,48 , 16095,117 , 158,27 , 8719,27 , 8746,64 , 85,14 , 8719,27 , 8746,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 170,1 , 0,7 , 4,4 , 4,0 , 3206,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
- { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 16212,47 , 16259,100 , 16359,24 , 16212,47 , 16259,100 , 16359,24 , 8810,32 , 8842,55 , 8897,14 , 8810,32 , 8842,55 , 8897,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 9935,22 , 4,4 , 8,6 , 3214,8 , 1497,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
- { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 536,10 , 323,17 , 459,7 , 466,13 , 16383,59 , 16442,96 , 16538,32 , 16570,61 , 16442,96 , 16538,32 , 8911,30 , 8941,62 , 9003,19 , 8911,30 , 8941,62 , 9003,19 , 257,5 , 245,4 , {76,75,82}, 290,3 , 9957,19 , 14,5 , 4,0 , 3222,5 , 3227,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
- { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
- { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 16631,48 , 16679,114 , 158,27 , 16631,48 , 16679,114 , 158,27 , 9022,27 , 9049,68 , 85,14 , 9022,27 , 9049,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 191,1 , 0,7 , 4,4 , 4,0 , 3238,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
- { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 135,7 , 135,7 , 546,8 , 462,18 , 61,4 , 219,9 , 16793,48 , 16841,82 , 15560,24 , 16793,48 , 16923,89 , 15560,24 , 9117,21 , 9138,52 , 9190,14 , 9117,21 , 9138,52 , 9190,14 , 262,10 , 249,9 , {69,85,82}, 19,1 , 9976,28 , 25,5 , 4,0 , 3245,10 , 3255,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
- { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 445,8 , 445,8 , 1024,9 , 590,19 , 37,5 , 8,10 , 15431,48 , 17012,86 , 15560,24 , 17098,59 , 17012,86 , 15560,24 , 9204,28 , 9232,52 , 9284,14 , 9298,35 , 9232,52 , 9284,14 , 81,4 , 258,4 , {69,85,82}, 19,1 , 10004,28 , 4,4 , 8,6 , 3264,11 , 3275,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
- { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {83,79,83}, 99,1 , 10032,22 , 4,4 , 4,0 , 3284,8 , 3292,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
- { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {68,74,70}, 5,3 , 10054,21 , 4,4 , 4,0 , 3284,8 , 3302,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
- { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {69,84,66}, 0,2 , 10075,22 , 4,4 , 4,0 , 3284,8 , 3309,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
- { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17157,48 , 17205,189 , 17394,24 , 17157,48 , 17205,189 , 17394,24 , 9333,28 , 9361,47 , 9408,14 , 9333,28 , 9361,47 , 9408,14 , 272,3 , 262,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3284,8 , 3317,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
- { 111, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3324,17 , 2054,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
- { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 479,14 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {65,82,83}, 12,1 , 10097,51 , 4,4 , 4,0 , 3341,7 , 3348,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
- { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {66,79,66}, 293,2 , 10148,35 , 4,4 , 4,0 , 3341,7 , 3357,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
- { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 503,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,76,80}, 12,1 , 10183,45 , 4,4 , 48,5 , 3341,7 , 3364,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
- { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,79,80}, 12,1 , 10228,54 , 4,4 , 4,0 , 3341,7 , 3369,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
- { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,82,67}, 295,1 , 10282,67 , 4,4 , 4,0 , 3341,7 , 3377,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
- { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {67,85,80}, 12,1 , 10349,42 , 4,4 , 4,0 , 3341,7 , 3387,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
- { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {68,79,80}, 12,1 , 10391,54 , 4,4 , 4,0 , 3341,7 , 3391,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
- { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 61,4 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 48,5 , 3341,7 , 3411,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
- { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 204,3 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3418,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
- { 111, 7, 66, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {88,65,70}, 37,4 , 10515,53 , 4,4 , 4,0 , 3341,7 , 3429,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
- { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {71,84,81}, 296,1 , 10568,70 , 4,4 , 4,0 , 3341,7 , 3446,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
- { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 1033,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {72,78,76}, 297,1 , 10638,60 , 4,4 , 4,0 , 3341,7 , 3455,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
- { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {77,88,78}, 12,1 , 10698,48 , 4,4 , 4,0 , 3341,7 , 3463,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
- { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {78,73,79}, 298,2 , 10746,69 , 4,4 , 4,0 , 3341,7 , 3469,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
- { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,65,66}, 300,3 , 10815,54 , 4,4 , 4,0 , 3341,7 , 3478,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
- { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,89,71}, 303,1 , 10869,61 , 14,5 , 65,6 , 3341,7 , 3484,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
- { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 511,7 , 897,27 , 37,5 , 493,15 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {80,69,78}, 304,3 , 10930,62 , 4,4 , 4,0 , 3341,7 , 3492,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
- { 111, 7, 170, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {80,72,80}, 183,1 , 10992,48 , 25,5 , 4,0 , 3341,7 , 3496,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
- { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 1060,8 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 1184,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
- { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 518,6 , 897,27 , 18,7 , 25,12 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 10445,70 , 4,4 , 4,0 , 3341,7 , 3505,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
- { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {85,89,85}, 12,1 , 11040,48 , 14,5 , 71,7 , 3341,7 , 3519,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
- { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {86,69,70}, 307,3 , 11088,64 , 4,4 , 48,5 , 3341,7 , 3526,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
- { 111, 7, 238, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3535,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
- { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 3070,14 , 9422,28 , 9450,53 , 3070,14 , 75,4 , 74,4 , {0,0,0}, 0,0 , 11152,0 , 4,4 , 4,0 , 3549,23 , 3572,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
- { 111, 7, 250, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 453,7 , 453,7 , 27,8 , 897,27 , 37,5 , 8,10 , 17418,49 , 17467,89 , 17556,24 , 17580,48 , 17467,89 , 17556,24 , 9422,28 , 9450,53 , 9503,14 , 9422,28 , 9450,53 , 9503,14 , 75,4 , 74,4 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 3341,7 , 3585,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
- { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {84,90,83}, 192,3 , 11152,27 , 4,4 , 8,6 , 3600,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
- { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {75,69,83}, 2,3 , 11179,24 , 4,4 , 4,0 , 3600,9 , 1012,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
- { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 460,9 , 469,8 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 17676,84 , 134,24 , 17628,48 , 17676,84 , 134,24 , 9517,22 , 9539,60 , 9599,14 , 9517,22 , 9539,60 , 9599,14 , 275,7 , 265,7 , {85,71,88}, 197,3 , 11203,25 , 4,4 , 8,6 , 3600,9 , 1387,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
- { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {83,69,75}, 157,2 , 11228,45 , 25,5 , 4,0 , 3609,7 , 3616,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
- { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3623,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
- { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 477,9 , 477,9 , 72,10 , 1068,30 , 37,5 , 392,16 , 17760,48 , 17808,86 , 134,24 , 4985,48 , 17894,86 , 134,24 , 9613,28 , 9641,50 , 2309,14 , 9691,29 , 9720,50 , 2309,14 , 282,2 , 272,2 , {69,85,82}, 19,1 , 11273,19 , 25,5 , 4,0 , 3609,7 , 3630,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
- { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 158,27 , 17980,48 , 18028,71 , 158,27 , 9770,28 , 9798,55 , 85,14 , 9770,28 , 9798,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 242,3 , 11292,13 , 14,5 , 4,0 , 3635,6 , 3641,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
- { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11305,13 , 14,5 , 4,0 , 3651,5 , 3656,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
- { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {77,89,82}, 256,2 , 11318,22 , 14,5 , 4,0 , 3651,5 , 3663,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
- { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {83,71,68}, 12,1 , 11340,24 , 14,5 , 4,0 , 3651,5 , 3670,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
- { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 486,13 , 486,13 , 634,6 , 224,18 , 18,7 , 25,12 , 18099,58 , 18157,86 , 18243,31 , 18099,58 , 18274,86 , 18243,31 , 9853,20 , 9873,49 , 9853,20 , 9853,20 , 9873,49 , 9853,20 , 0,2 , 0,2 , {76,75,82}, 310,3 , 11364,20 , 14,5 , 4,0 , 3651,5 , 3681,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
- { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 499,11 , 499,11 , 503,8 , 99,16 , 18,7 , 25,12 , 18360,66 , 18426,86 , 18512,31 , 18543,78 , 18426,86 , 18621,31 , 9922,32 , 9954,60 , 10014,18 , 9922,32 , 9954,60 , 10014,18 , 0,2 , 0,2 , {73,78,82}, 123,1 , 11384,26 , 4,4 , 8,6 , 3687,6 , 3693,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
- { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 510,5 , 510,5 , 515,8 , 523,7 , 287,6 , 1098,19 , 37,5 , 508,28 , 18652,63 , 18715,98 , 18652,63 , 18652,63 , 18715,98 , 18813,62 , 10032,23 , 10055,68 , 10032,23 , 10032,23 , 10055,68 , 10032,23 , 284,10 , 274,10 , {84,72,66}, 313,1 , 11410,13 , 4,4 , 8,6 , 3702,3 , 3702,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
- { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {67,78,89}, 314,1 , 11423,13 , 14,5 , 4,0 , 3705,8 , 3713,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
- { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 2663,63 , 18875,158 , 158,27 , 2663,63 , 18875,158 , 158,27 , 10123,49 , 10172,77 , 10249,21 , 10123,49 , 10172,77 , 10270,22 , 294,7 , 284,8 , {73,78,82}, 123,1 , 11436,22 , 14,5 , 4,0 , 3705,8 , 3719,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
- { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1117,23 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 10292,29 , 10292,29 , 10321,14 , 10292,29 , 10292,29 , 10321,14 , 301,7 , 292,7 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 3726,4 , 109,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
- { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1140,23 , 18,7 , 25,12 , 19141,46 , 19187,54 , 1050,24 , 19141,46 , 19187,54 , 1050,24 , 10335,29 , 10335,29 , 10321,14 , 10335,29 , 10335,29 , 10321,14 , 301,7 , 292,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 3726,4 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
- { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 530,8 , 530,8 , 530,8 , 530,8 , 287,6 , 99,16 , 37,5 , 8,10 , 19241,51 , 19292,87 , 19379,24 , 19241,51 , 19292,87 , 19379,24 , 10364,29 , 10393,60 , 10453,14 , 10364,29 , 10393,60 , 10453,14 , 0,2 , 0,2 , {84,79,80}, 195,2 , 0,7 , 14,5 , 4,0 , 3734,13 , 1339,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
- { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 19403,48 , 19451,122 , 158,27 , 19403,48 , 19451,122 , 158,27 , 10467,27 , 10494,72 , 85,14 , 10467,27 , 10494,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3747,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
- { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {84,82,89}, 315,1 , 11474,18 , 25,5 , 30,7 , 3755,6 , 3761,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
- { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 538,8 , 538,8 , 1163,9 , 1172,16 , 37,5 , 8,10 , 19573,48 , 19621,75 , 19696,24 , 19573,48 , 19621,75 , 19696,24 , 10566,28 , 10594,54 , 10648,14 , 10566,28 , 10594,54 , 10648,14 , 308,2 , 299,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 30,7 , 3755,6 , 3768,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
- { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 546,8 , 546,8 , 187,8 , 1188,22 , 37,5 , 8,10 , 19720,48 , 19768,95 , 19863,24 , 19887,67 , 19954,87 , 19863,24 , 10662,21 , 10683,56 , 10739,14 , 10662,21 , 10683,56 , 10739,14 , 310,2 , 301,2 , {85,65,72}, 279,1 , 11492,49 , 25,5 , 4,0 , 3791,10 , 3801,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
- { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {80,75,82}, 180,2 , 11541,21 , 4,4 , 4,0 , 3808,4 , 3812,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
- { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 37,6 , 37,6 , 554,10 , 564,9 , 287,6 , 161,18 , 18,7 , 25,12 , 20041,66 , 20041,66 , 134,24 , 20041,66 , 20041,66 , 134,24 , 10753,36 , 10753,36 , 85,14 , 10753,36 , 10753,36 , 85,14 , 312,9 , 303,9 , {73,78,82}, 123,1 , 11562,18 , 14,5 , 4,0 , 3808,4 , 3819,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
- { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 17980,48 , 18028,71 , 14970,24 , 17980,48 , 18028,71 , 14970,24 , 10789,28 , 10817,53 , 10870,14 , 10789,28 , 10817,53 , 10870,14 , 0,2 , 0,2 , {85,90,83}, 316,3 , 11580,21 , 14,5 , 4,0 , 3824,5 , 3829,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
- { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 1210,33 , 61,4 , 408,11 , 20107,48 , 13771,68 , 158,27 , 20107,48 , 13771,68 , 158,27 , 10884,21 , 7208,49 , 85,14 , 10884,21 , 7208,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 263,1 , 11601,13 , 25,5 , 4,0 , 3839,6 , 2782,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
- { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 20155,52 , 20207,77 , 20284,24 , 20155,52 , 20207,77 , 20284,24 , 10905,34 , 10939,61 , 11000,14 , 10905,34 , 10939,61 , 11000,14 , 0,2 , 0,2 , {85,90,83}, 319,4 , 11614,23 , 14,5 , 4,0 , 3845,9 , 3854,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
- { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 573,8 , 573,8 , 141,10 , 1243,31 , 37,5 , 8,10 , 20308,75 , 20383,130 , 158,27 , 20308,75 , 20383,130 , 158,27 , 11014,33 , 11047,55 , 11102,21 , 11014,33 , 11047,55 , 11102,21 , 321,2 , 312,2 , {86,78,68}, 323,1 , 11637,20 , 25,5 , 4,0 , 3865,10 , 3875,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
- { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 135,7 , 135,7 , 141,10 , 10,17 , 37,5 , 8,10 , 20513,52 , 20565,87 , 20652,26 , 20678,62 , 20565,87 , 20652,26 , 11123,29 , 11152,77 , 11229,15 , 11244,30 , 11152,77 , 11229,15 , 0,2 , 0,2 , {71,66,80}, 171,1 , 11657,154 , 4,4 , 4,0 , 3883,7 , 3890,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
- { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 20740,48 , 20788,91 , 158,27 , 20740,48 , 20788,91 , 158,27 , 11274,28 , 11302,61 , 85,14 , 11274,28 , 11302,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3906,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
- { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 20879,73 , 20952,121 , 158,27 , 20879,73 , 20952,121 , 158,27 , 11363,44 , 11407,69 , 85,14 , 11363,44 , 11407,69 , 85,14 , 323,5 , 314,5 , {78,71,78}, 182,1 , 11811,34 , 4,4 , 8,6 , 3914,10 , 3924,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
- { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 581,9 , 590,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21073,48 , 21121,104 , 134,24 , 21073,48 , 21225,90 , 134,24 , 11476,28 , 11504,68 , 11572,14 , 11476,28 , 11504,68 , 11572,14 , 328,7 , 319,8 , {90,65,82}, 11,1 , 11845,27 , 4,4 , 8,6 , 3942,7 , 3949,17 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
- { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 142,8 , 142,8 , 187,8 , 554,17 , 37,5 , 392,16 , 5815,48 , 13184,83 , 134,24 , 13267,59 , 13184,83 , 134,24 , 11586,28 , 11614,51 , 2309,14 , 11665,28 , 11614,51 , 2309,14 , 335,9 , 327,11 , {78,79,75}, 157,2 , 11872,42 , 25,5 , 4,0 , 3966,7 , 3973,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
- { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 118,7 , 118,7 , 1274,9 , 981,20 , 37,5 , 8,10 , 15431,48 , 21315,83 , 15560,24 , 15431,48 , 21315,83 , 15560,24 , 2032,28 , 2060,58 , 85,14 , 2032,28 , 2060,58 , 85,14 , 248,9 , 238,7 , {66,65,77}, 153,2 , 11914,218 , 14,5 , 4,0 , 3978,8 , 587,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
- { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 102,7 , 102,7 , 974,7 , 981,20 , 37,5 , 8,10 , 15302,48 , 15584,83 , 11981,24 , 15302,48 , 15584,83 , 11981,24 , 8357,28 , 8385,54 , 8261,14 , 8357,28 , 8385,54 , 8261,14 , 239,9 , 231,7 , {66,65,77}, 288,2 , 12132,195 , 25,5 , 4,0 , 3986,8 , 3138,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
- { 144, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21398,102 , 21500,140 , 158,27 , 21398,102 , 21500,140 , 158,27 , 11693,30 , 11723,57 , 85,14 , 11693,30 , 11723,57 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 3994,5 , 3999,14 , 2, 1, 1, 6, 7 }, // Manx/Latin/UnitedKingdom
- { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 99,16 , 37,5 , 8,10 , 21640,46 , 21686,124 , 158,27 , 21640,46 , 21686,124 , 158,27 , 11780,28 , 11808,60 , 85,14 , 11780,28 , 11808,60 , 85,14 , 75,4 , 74,4 , {71,66,80}, 171,1 , 0,7 , 4,4 , 4,0 , 4013,8 , 3999,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
- { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 242,8 , 269,18 , 37,5 , 8,10 , 21810,48 , 21858,192 , 158,27 , 21810,48 , 21858,192 , 158,27 , 11868,28 , 11896,49 , 11945,14 , 11868,28 , 11896,49 , 11945,14 , 344,2 , 338,2 , {71,72,83}, 173,3 , 12327,17 , 4,4 , 4,0 , 4021,4 , 4025,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
- { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 634,6 , 99,16 , 18,7 , 25,12 , 22050,87 , 22050,87 , 158,27 , 22050,87 , 22050,87 , 158,27 , 6771,32 , 11959,55 , 85,14 , 6771,32 , 11959,55 , 85,14 , 346,5 , 340,5 , {73,78,82}, 123,1 , 0,7 , 14,5 , 4,0 , 4030,6 , 2282,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
- { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22137,48 , 22185,86 , 158,27 , 22137,48 , 22185,86 , 158,27 , 12014,29 , 12043,57 , 85,14 , 12014,29 , 12043,57 , 85,14 , 351,4 , 345,4 , {78,71,78}, 182,1 , 12344,12 , 4,4 , 8,6 , 4036,4 , 1113,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
- { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 22271,48 , 22319,189 , 22508,24 , 22271,48 , 22319,189 , 22508,24 , 12100,28 , 12128,74 , 12202,14 , 12100,28 , 12128,74 , 12202,14 , 355,9 , 349,7 , {75,69,83}, 2,3 , 12356,23 , 4,4 , 8,6 , 4040,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
- { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1283,22 , 18,7 , 25,12 , 22532,47 , 22579,77 , 22656,24 , 22532,47 , 22579,77 , 22656,24 , 12216,26 , 12242,43 , 12285,14 , 12216,26 , 12242,43 , 12285,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4047,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
- { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1305,21 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12299,27 , 12326,41 , 12367,14 , 12299,27 , 12326,41 , 12367,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4050,3 , 3730,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
- { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 206,7 , 206,7 , 27,8 , 1326,27 , 37,5 , 8,10 , 22680,48 , 22728,77 , 22805,24 , 22680,48 , 22728,77 , 22805,24 , 12381,28 , 12409,50 , 3070,14 , 12381,28 , 12409,50 , 3070,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 14,5 , 4,0 , 4053,6 , 4059,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
- { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 22829,48 , 22877,111 , 158,27 , 22829,48 , 22877,111 , 158,27 , 12459,27 , 12486,70 , 85,14 , 12459,27 , 12486,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4065,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
- { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {71,72,83}, 173,3 , 12379,37 , 4,4 , 8,6 , 4074,6 , 4080,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
- { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 600,11 , 611,10 , 518,6 , 1353,23 , 536,12 , 548,12 , 22988,48 , 23036,87 , 23123,24 , 22988,48 , 23036,87 , 23123,24 , 12556,28 , 12584,44 , 12628,14 , 12556,28 , 12584,44 , 12628,14 , 364,3 , 356,5 , {88,79,70}, 209,3 , 12416,106 , 4,4 , 8,6 , 4074,6 , 4092,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
- { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1376,22 , 18,7 , 25,12 , 19033,46 , 19079,62 , 1050,24 , 19033,46 , 19079,62 , 1050,24 , 12642,27 , 12642,27 , 12669,14 , 12642,27 , 12642,27 , 12669,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 11458,16 , 4,4 , 4,0 , 4103,5 , 109,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
- { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 287,6 , 10,17 , 18,7 , 25,12 , 23147,59 , 23206,95 , 158,27 , 23147,59 , 23206,95 , 158,27 , 12683,21 , 12704,57 , 85,14 , 12683,21 , 12704,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 8,6 , 4108,14 , 4122,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
- { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 621,8 , 621,8 , 518,6 , 1398,18 , 37,5 , 8,10 , 23301,48 , 23349,88 , 23437,24 , 23301,48 , 23349,88 , 23437,24 , 12761,28 , 12789,55 , 12844,14 , 12858,28 , 12789,55 , 12844,14 , 0,2 , 0,2 , {80,72,80}, 183,1 , 12522,22 , 4,4 , 8,6 , 4141,8 , 4149,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
- { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 187,8 , 462,18 , 37,5 , 8,10 , 6990,48 , 23461,86 , 134,24 , 6990,48 , 23461,86 , 134,24 , 12886,28 , 12914,63 , 3471,14 , 12886,28 , 12914,63 , 3471,14 , 94,5 , 361,4 , {67,72,70}, 230,3 , 12544,55 , 25,5 , 4,0 , 4158,16 , 4174,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
- { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 158,27 , 23547,38 , 158,27 , 158,27 , 23547,38 , 158,27 , 12977,21 , 12998,28 , 13026,14 , 12977,21 , 12998,28 , 13026,14 , 367,2 , 365,2 , {67,78,89}, 314,1 , 0,7 , 14,5 , 4,0 , 4181,3 , 4184,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
- { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23585,48 , 23633,100 , 158,27 , 23585,48 , 23633,100 , 158,27 , 13040,27 , 13067,66 , 85,14 , 13040,27 , 13067,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4186,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
- { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 323,17 , 37,5 , 8,10 , 23733,48 , 23781,94 , 158,27 , 23733,48 , 23781,94 , 158,27 , 13133,27 , 13160,63 , 85,14 , 13133,27 , 13160,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4196,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
- { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 23875,59 , 23934,145 , 24079,24 , 23875,59 , 23934,145 , 24079,24 , 13223,33 , 13256,75 , 13331,14 , 13223,33 , 13256,75 , 13331,14 , 0,2 , 0,2 , {78,79,75}, 157,2 , 12599,63 , 25,5 , 4,0 , 4212,15 , 4227,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
- { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 169,8 , 169,8 , 72,10 , 323,17 , 37,5 , 8,10 , 24103,85 , 23934,145 , 24079,24 , 24103,85 , 23934,145 , 24079,24 , 13223,33 , 13345,65 , 13410,14 , 13223,33 , 13345,65 , 13410,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 12662,23 , 25,5 , 4,0 , 4212,15 , 4232,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
- { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24188,48 , 24236,88 , 24324,24 , 24188,48 , 24236,88 , 24324,24 , 13424,28 , 13452,62 , 13514,14 , 13424,28 , 13452,62 , 13514,14 , 369,5 , 367,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4238,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
- { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24348,48 , 24396,221 , 24617,24 , 24348,48 , 24396,221 , 24617,24 , 13528,28 , 13556,105 , 13661,14 , 13528,28 , 13556,105 , 13661,14 , 374,10 , 377,10 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4246,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
- { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 24641,48 , 24689,77 , 24766,24 , 24641,48 , 24689,77 , 24766,24 , 13675,28 , 13703,59 , 13762,14 , 13675,28 , 13703,59 , 13762,14 , 384,6 , 387,7 , {88,79,70}, 209,3 , 12709,26 , 25,5 , 4,0 , 4253,6 , 4259,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
- { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 24790,48 , 24838,185 , 25023,24 , 24790,48 , 24838,185 , 25023,24 , 13776,28 , 13804,63 , 13867,14 , 13776,28 , 13804,63 , 13867,14 , 390,6 , 394,8 , {75,69,83}, 2,3 , 12735,23 , 4,4 , 8,6 , 4267,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
- { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25047,48 , 25095,173 , 25268,24 , 25047,48 , 25095,173 , 25268,24 , 13881,28 , 13909,105 , 14014,14 , 13881,28 , 13909,105 , 14014,14 , 396,7 , 402,5 , {75,69,83}, 2,3 , 12758,25 , 4,4 , 8,6 , 4273,8 , 1012,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
- { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 897,27 , 37,5 , 8,10 , 25292,48 , 25340,88 , 134,24 , 25292,48 , 25340,88 , 134,24 , 14028,28 , 14056,55 , 14111,14 , 14028,28 , 14056,55 , 14111,14 , 0,2 , 0,2 , {77,90,78}, 269,3 , 12783,28 , 0,4 , 4,0 , 4281,4 , 2908,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
- { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25428,52 , 25480,112 , 25592,24 , 25428,52 , 25480,112 , 25592,24 , 14125,28 , 14153,50 , 14203,14 , 14125,28 , 14153,50 , 14203,14 , 0,2 , 0,2 , {85,83,68}, 204,3 , 12811,24 , 4,4 , 8,6 , 4186,10 , 1497,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
- { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 25616,39 , 25655,194 , 25849,24 , 25616,39 , 25655,194 , 25849,24 , 14217,29 , 14246,65 , 14311,14 , 14217,29 , 14246,65 , 14311,14 , 403,8 , 407,7 , {84,90,83}, 192,3 , 12835,25 , 4,4 , 4,0 , 4285,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
- { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 25873,48 , 25921,81 , 26002,24 , 25873,48 , 25921,81 , 26002,24 , 14325,30 , 14355,47 , 85,14 , 14325,30 , 14355,47 , 85,14 , 411,6 , 414,8 , {77,65,68}, 0,0 , 12860,21 , 0,4 , 4,0 , 4294,8 , 4302,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
- { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26026,48 , 26074,81 , 26155,24 , 26026,48 , 26074,81 , 26155,24 , 14402,30 , 14432,48 , 85,14 , 14402,30 , 14432,48 , 85,14 , 417,6 , 422,8 , {77,65,68}, 0,0 , 12881,21 , 0,4 , 4,0 , 4308,9 , 4317,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
- { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26179,48 , 26227,84 , 26311,24 , 26179,48 , 26227,84 , 26311,24 , 14480,30 , 14510,51 , 14561,14 , 14480,30 , 14510,51 , 14561,14 , 423,7 , 430,9 , {68,90,68}, 207,2 , 12902,21 , 0,4 , 4,0 , 4323,9 , 4332,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
- { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4340,10 , 1387,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
- { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26535,48 , 26583,254 , 26837,24 , 26535,48 , 26583,254 , 26837,24 , 14691,28 , 14719,82 , 14801,14 , 14691,28 , 14719,82 , 14801,14 , 430,7 , 439,7 , {84,90,83}, 192,3 , 12949,29 , 0,4 , 4,0 , 4350,6 , 4356,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
- { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4366,8 , 1331,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
- { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 26948,47 , 26995,92 , 27087,24 , 26948,47 , 26995,92 , 27087,24 , 14919,28 , 14947,44 , 14991,14 , 14919,28 , 14947,44 , 14991,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13005,24 , 4,4 , 8,6 , 4374,9 , 1842,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
- { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,207 , 27366,24 , 27111,48 , 27159,207 , 27366,24 , 15005,28 , 15033,64 , 15097,14 , 15005,28 , 15033,64 , 15097,14 , 442,2 , 455,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4383,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
- { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 27390,36 , 27426,58 , 27484,24 , 27390,36 , 27426,58 , 27484,24 , 15111,28 , 15139,49 , 15188,14 , 15111,28 , 15139,49 , 15188,14 , 444,3 , 457,6 , {85,83,68}, 12,1 , 13029,19 , 4,4 , 8,6 , 4389,3 , 4392,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
- { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 27508,47 , 27555,68 , 27623,24 , 27508,47 , 27555,68 , 27623,24 , 15202,27 , 15229,48 , 15277,14 , 15202,27 , 15229,48 , 15277,14 , 0,2 , 0,2 , {77,85,82}, 180,2 , 13048,21 , 14,5 , 4,0 , 4396,14 , 4410,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
- { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 27647,264 , 134,24 , 17628,48 , 27647,264 , 134,24 , 15291,28 , 15319,133 , 14311,14 , 15291,28 , 15319,133 , 14311,14 , 447,4 , 463,5 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 8,6 , 4415,10 , 1331,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
- { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 27911,83 , 27994,111 , 28105,24 , 27911,83 , 27994,111 , 28105,24 , 15452,36 , 15488,63 , 15551,14 , 15452,36 , 15488,63 , 15551,14 , 451,3 , 468,3 , {84,90,83}, 192,3 , 13069,29 , 14,5 , 4,0 , 4425,8 , 4433,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
- { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 15565,28 , 15593,66 , 15659,14 , 15565,28 , 15593,66 , 15659,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 13098,26 , 0,4 , 4,0 , 4442,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
- { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28274,48 , 28322,83 , 28405,24 , 28274,48 , 28322,83 , 28405,24 , 15673,80 , 15673,80 , 85,14 , 15673,80 , 15673,80 , 85,14 , 454,8 , 471,7 , {90,77,87}, 202,2 , 0,7 , 4,4 , 8,6 , 4456,9 , 1491,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
- { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 453,7 , 453,7 , 364,8 , 1416,27 , 37,5 , 8,10 , 28429,48 , 28477,86 , 134,24 , 28429,48 , 28477,86 , 134,24 , 15753,28 , 15781,73 , 15854,14 , 15753,28 , 15781,73 , 15854,14 , 89,2 , 88,2 , {67,86,69}, 0,0 , 13124,25 , 0,4 , 4,0 , 4465,12 , 4477,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
- { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28563,48 , 28611,86 , 28697,24 , 28563,48 , 28611,86 , 28697,24 , 15868,28 , 15896,51 , 15947,14 , 15868,28 , 15896,51 , 15947,14 , 462,2 , 478,2 , {75,69,83}, 2,3 , 12685,24 , 4,4 , 8,6 , 4487,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
- { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28721,48 , 28769,111 , 28880,24 , 28721,48 , 28769,111 , 28880,24 , 15961,28 , 15989,93 , 16082,14 , 15961,28 , 15989,93 , 16082,14 , 464,4 , 480,4 , {75,69,83}, 2,3 , 13149,26 , 4,4 , 8,6 , 4493,8 , 4501,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
- { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 0,48 , 28904,136 , 134,24 , 0,48 , 28904,136 , 134,24 , 16096,23 , 16119,92 , 16211,14 , 16096,23 , 16119,92 , 16211,14 , 468,7 , 484,5 , {78,65,68}, 12,1 , 13175,22 , 4,4 , 4,0 , 4513,13 , 4526,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
- { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 4,4 , 4,0 , 4534,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
- { 201, 7, 82, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 347,8 , 347,8 , 1443,10 , 1453,23 , 37,5 , 8,10 , 29040,59 , 29099,87 , 134,24 , 29186,48 , 29099,87 , 134,24 , 16225,28 , 16253,72 , 3471,14 , 16225,28 , 16253,72 , 3471,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 81,11 , 25,5 , 4,0 , 4543,6 , 4549,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
- { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {75,69,83}, 2,3 , 13197,25 , 4,4 , 8,6 , 4560,3 , 1012,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
- { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29234,51 , 29285,132 , 158,27 , 29234,51 , 29285,132 , 158,27 , 14815,28 , 16325,58 , 14311,14 , 14815,28 , 16325,58 , 14311,14 , 475,9 , 489,6 , {84,90,83}, 192,3 , 13222,28 , 4,4 , 8,6 , 4560,3 , 4563,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
- { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 28129,48 , 28177,97 , 134,24 , 28129,48 , 28177,97 , 134,24 , 16383,35 , 16418,65 , 16483,14 , 16383,35 , 16418,65 , 16483,14 , 484,6 , 495,6 , {85,71,88}, 197,3 , 13098,26 , 25,5 , 4,0 , 4571,7 , 4449,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
- { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29417,48 , 17676,84 , 134,24 , 29417,48 , 17676,84 , 134,24 , 16497,21 , 16518,75 , 85,14 , 16497,21 , 16518,75 , 85,14 , 75,4 , 74,4 , {75,69,83}, 2,3 , 13250,23 , 4,4 , 83,6 , 4578,7 , 1012,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
- { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29465,48 , 17676,84 , 134,24 , 29465,48 , 17676,84 , 134,24 , 16593,28 , 9539,60 , 14905,14 , 16593,28 , 9539,60 , 14905,14 , 490,9 , 501,8 , {84,90,83}, 192,3 , 13273,28 , 25,5 , 4,0 , 4585,6 , 4591,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
- { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {85,71,88}, 197,3 , 13301,28 , 4,4 , 8,6 , 4599,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
- { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29513,48 , 29561,94 , 29655,24 , 29513,48 , 29561,94 , 29655,24 , 16621,28 , 16649,69 , 16718,14 , 16621,28 , 16649,69 , 16718,14 , 499,9 , 509,6 , {75,69,83}, 2,3 , 13329,27 , 4,4 , 8,6 , 4599,6 , 4605,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
- { 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 16732,28 , 16760,56 , 16816,14 , 16732,28 , 16760,56 , 16816,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 0,0 , 43,7 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea
- { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 16830,28 , 16858,53 , 16911,14 , 16830,28 , 16858,53 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4610,11 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
- { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 26861,87 , 134,24 , 17628,48 , 26861,87 , 134,24 , 14815,28 , 14843,62 , 14905,14 , 14815,28 , 14843,62 , 14905,14 , 437,5 , 446,9 , {84,90,83}, 192,3 , 12978,27 , 0,4 , 4,0 , 4626,6 , 1331,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
- { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 29837,48 , 29885,186 , 30071,24 , 29837,48 , 29885,186 , 30071,24 , 16925,28 , 16953,69 , 17022,14 , 16925,28 , 16953,69 , 17022,14 , 514,2 , 521,2 , {75,69,83}, 2,3 , 13379,23 , 0,4 , 4,0 , 4632,6 , 1012,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
- { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 26335,48 , 26383,152 , 134,24 , 26335,48 , 26383,152 , 134,24 , 14575,28 , 14603,74 , 14677,14 , 14575,28 , 14603,74 , 14677,14 , 0,2 , 0,2 , {85,71,88}, 197,3 , 12923,26 , 4,4 , 78,5 , 4638,6 , 1387,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
- { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 30095,48 , 30143,86 , 30229,24 , 30095,48 , 30143,86 , 30229,24 , 17036,28 , 17064,48 , 17112,14 , 17036,28 , 17064,48 , 17112,14 , 516,9 , 523,10 , {77,65,68}, 0,0 , 13402,22 , 25,5 , 4,0 , 4644,8 , 4652,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
- { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 508,6 , 515,6 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4658,15 , 4621,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
- { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 17628,48 , 30253,84 , 134,24 , 17628,48 , 30253,84 , 134,24 , 17208,28 , 17236,63 , 9599,14 , 17208,28 , 17236,63 , 9599,14 , 525,5 , 533,8 , {84,90,83}, 192,3 , 11152,27 , 0,4 , 4,0 , 4673,9 , 1331,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
- { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 518,6 , 35,18 , 18,7 , 25,12 , 30337,88 , 30337,88 , 30425,31 , 30337,88 , 30337,88 , 30425,31 , 17299,33 , 17332,54 , 17386,19 , 17299,33 , 17332,54 , 17386,19 , 530,3 , 541,6 , {73,78,82}, 123,1 , 13424,10 , 14,5 , 4,0 , 4682,4 , 2282,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
- { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30456,49 , 30505,99 , 30604,24 , 30456,49 , 30505,99 , 30604,24 , 17405,28 , 17433,50 , 17483,14 , 17405,28 , 17433,50 , 17483,14 , 533,5 , 547,6 , {67,68,70}, 217,2 , 13434,24 , 0,4 , 4,0 , 4686,8 , 4694,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
- { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30628,48 , 30676,195 , 30871,24 , 30628,48 , 30676,195 , 30871,24 , 17497,28 , 17525,72 , 17597,14 , 17497,28 , 17525,72 , 17597,14 , 538,3 , 553,3 , {88,65,70}, 37,4 , 13458,21 , 0,4 , 4,0 , 4710,5 , 4715,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
- { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 30895,48 , 30943,90 , 31033,24 , 30895,48 , 30943,90 , 31033,24 , 17611,28 , 17639,70 , 17709,14 , 17611,28 , 17639,70 , 17709,14 , 541,10 , 556,9 , {88,65,70}, 37,4 , 13479,22 , 25,5 , 4,0 , 4722,5 , 4727,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
- { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17723,53 , 17776,14 , 17126,28 , 17723,53 , 17776,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4735,10 , 4745,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
- { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31057,49 , 31106,99 , 31205,24 , 31057,49 , 31106,99 , 31205,24 , 17790,28 , 17818,45 , 17863,14 , 17790,28 , 17818,45 , 17863,14 , 559,5 , 575,6 , {88,65,70}, 37,4 , 0,7 , 25,5 , 4,0 , 4750,5 , 1621,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
- { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31229,36 , 31265,82 , 31347,24 , 31229,36 , 31265,82 , 31347,24 , 17877,28 , 17905,50 , 17955,14 , 17877,28 , 17905,50 , 17955,14 , 0,2 , 0,2 , {88,79,70}, 209,3 , 13501,23 , 25,5 , 4,0 , 4755,5 , 4760,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
- { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31371,50 , 31421,141 , 31562,24 , 31371,50 , 31421,141 , 31562,24 , 17969,30 , 17999,85 , 18084,14 , 17969,30 , 17999,85 , 18084,14 , 564,7 , 581,9 , {88,65,70}, 37,4 , 13524,23 , 25,5 , 4,0 , 4767,6 , 4773,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
- { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 31586,39 , 31625,191 , 158,27 , 31586,39 , 31625,191 , 158,27 , 18098,29 , 18127,45 , 18172,14 , 18098,29 , 18127,45 , 18172,14 , 571,6 , 590,7 , {88,65,70}, 37,4 , 13547,11 , 25,5 , 4,0 , 4780,5 , 4785,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
- { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 31816,48 , 31864,213 , 32077,24 , 31816,48 , 31864,213 , 32077,24 , 18186,28 , 18214,59 , 18273,14 , 18186,28 , 18214,59 , 18273,14 , 577,8 , 597,10 , {77,90,78}, 269,3 , 0,7 , 14,5 , 4,0 , 4792,5 , 4797,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
- { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32101,48 , 32149,139 , 32288,24 , 32101,48 , 32149,139 , 32288,24 , 18287,28 , 18315,74 , 18389,14 , 18287,28 , 18315,74 , 18389,14 , 585,5 , 607,5 , {88,65,70}, 37,4 , 13558,17 , 4,4 , 8,6 , 4807,6 , 4813,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
- { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 32312,51 , 32363,143 , 158,27 , 32312,51 , 32363,143 , 158,27 , 18403,30 , 18433,89 , 18522,14 , 18403,30 , 18433,89 , 18522,14 , 590,4 , 612,4 , {88,65,70}, 37,4 , 13575,20 , 25,5 , 4,0 , 4820,6 , 4826,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
- { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1476,9 , 99,16 , 18,7 , 560,12 , 32506,54 , 32560,96 , 32656,24 , 32506,54 , 32560,96 , 32656,24 , 18536,38 , 18574,79 , 18653,14 , 18536,38 , 18574,79 , 18653,14 , 594,2 , 616,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 8,6 , 4833,9 , 4842,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
- { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 1485,6 , 1491,30 , 37,5 , 8,10 , 32680,75 , 32755,121 , 32876,24 , 32680,75 , 32755,121 , 32876,24 , 18667,21 , 18688,73 , 18761,14 , 18667,21 , 18688,73 , 18761,14 , 0,2 , 0,2 , {82,85,66}, 275,4 , 0,7 , 14,5 , 4,0 , 4847,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
- { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 32900,48 , 32948,117 , 158,27 , 32900,48 , 32948,117 , 158,27 , 18775,28 , 18803,60 , 18863,14 , 18775,28 , 18803,60 , 18863,14 , 596,9 , 618,9 , {84,90,83}, 192,3 , 13595,25 , 0,4 , 4,0 , 4856,9 , 4865,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
- { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33065,48 , 33113,188 , 33301,24 , 33065,48 , 33113,188 , 33301,24 , 18877,28 , 18905,93 , 18998,14 , 18877,28 , 18905,93 , 18998,14 , 605,10 , 627,10 , {67,68,70}, 217,2 , 13620,23 , 4,4 , 4,0 , 4874,18 , 4892,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
- { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 29679,46 , 29725,88 , 29813,24 , 29679,46 , 29725,88 , 29813,24 , 17126,28 , 17154,54 , 16911,14 , 17126,28 , 17154,54 , 16911,14 , 551,8 , 565,10 , {88,79,70}, 209,3 , 13356,23 , 0,4 , 4,0 , 4924,13 , 4745,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
- { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33325,50 , 33325,50 , 158,27 , 33325,50 , 33325,50 , 158,27 , 19012,30 , 19012,30 , 85,14 , 19012,30 , 19012,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13643,15 , 4,4 , 8,6 , 4937,2 , 4939,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
- { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 141,10 , 10,17 , 18,7 , 25,12 , 33375,81 , 33375,81 , 158,27 , 33375,81 , 33375,81 , 158,27 , 19042,48 , 19042,48 , 85,14 , 19042,48 , 19042,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 13658,20 , 4,4 , 8,6 , 4943,3 , 4946,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
- { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 221,9 , 221,9 , 72,10 , 462,18 , 37,5 , 8,10 , 33456,48 , 33504,99 , 33603,24 , 33456,48 , 33504,99 , 33603,24 , 19090,28 , 19118,53 , 19171,14 , 19090,28 , 19118,53 , 19171,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 14,5 , 4,0 , 4954,6 , 4960,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
- { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 364,8 , 99,16 , 37,5 , 8,10 , 33627,51 , 33678,191 , 158,27 , 33627,51 , 33678,191 , 158,27 , 19185,21 , 19206,71 , 19277,14 , 19185,21 , 19206,71 , 19277,14 , 615,8 , 637,8 , {88,65,70}, 37,4 , 0,7 , 25,5 , 30,7 , 4966,6 , 4972,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
- { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 453,7 , 453,7 , 287,6 , 1521,23 , 37,5 , 8,10 , 33869,48 , 33917,85 , 34002,24 , 34026,48 , 34074,117 , 34002,24 , 19291,28 , 19319,54 , 3272,14 , 19291,28 , 19319,54 , 3272,14 , 0,2 , 0,2 , {69,85,82}, 19,1 , 2460,20 , 25,5 , 4,0 , 4979,9 , 2054,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
- { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 629,11 , 629,11 , 640,16 , 656,9 , 72,10 , 269,18 , 37,5 , 8,10 , 34191,174 , 34191,174 , 158,27 , 34191,174 , 34191,174 , 158,27 , 19373,60 , 19373,60 , 19433,25 , 19373,60 , 19373,60 , 19433,25 , 623,8 , 645,13 , {88,65,70}, 37,4 , 13678,12 , 14,5 , 4,0 , 4988,5 , 4993,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
- { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1544,10 , 82,17 , 37,5 , 8,10 , 34365,102 , 34365,102 , 158,27 , 34365,102 , 34365,102 , 158,27 , 19458,54 , 19458,54 , 19512,21 , 19458,54 , 19458,54 , 19512,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13690,16 , 14,5 , 4,0 , 5000,4 , 5004,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
- { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 269,18 , 37,5 , 8,10 , 34467,137 , 34604,142 , 34746,36 , 34467,137 , 34604,142 , 34746,36 , 19533,49 , 19533,49 , 19582,21 , 19533,49 , 19533,49 , 19582,21 , 0,2 , 0,2 , {88,65,70}, 37,4 , 13706,12 , 14,5 , 4,0 , 5011,5 , 5016,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
- { 260, 7, 37, 44, 46, 44, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1554,32 , 37,5 , 8,10 , 34782,164 , 34782,164 , 158,27 , 34782,164 , 34782,164 , 158,27 , 19603,111 , 19603,111 , 85,14 , 19603,111 , 19603,111 , 85,14 , 631,9 , 658,8 , {88,65,70}, 37,4 , 13718,16 , 14,5 , 4,0 , 5023,16 , 5039,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
+ { 5, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 82,17 , 18,7 , 25,12 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {90,65,82}, 11,1 , 31,27 , 4,4 , 4,0 , 50,9 , 59,11 , 2, 1, 7, 6, 7 }, // Afrikaans/Latin/SouthAfrica
+ { 5, 7, 148, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 72,10 , 99,16 , 37,5 , 8,10 , 653,48 , 701,92 , 134,24 , 653,48 , 701,92 , 134,24 , 290,21 , 311,58 , 369,14 , 290,21 , 311,58 , 369,14 , 4,3 , 4,3 , {78,65,68}, 12,1 , 58,23 , 8,5 , 4,0 , 50,9 , 70,7 , 2, 1, 1, 6, 7 }, // Afrikaans/Latin/Namibia
+ { 6, 7, 2, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 27,8 , 115,18 , 37,5 , 8,10 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,8 , 7,7 , {65,76,76}, 13,4 , 81,45 , 13,5 , 4,0 , 77,5 , 82,8 , 0, 0, 1, 6, 7 }, // Albanian/Latin/Albania
+ { 6, 7, 127, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 27,8 , 115,18 , 37,5 , 8,10 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,8 , 7,7 , {77,75,68}, 17,3 , 126,53 , 13,5 , 4,0 , 77,5 , 90,8 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Macedonia
+ { 6, 7, 257, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 14,9 , 14,9 , 27,8 , 115,18 , 37,5 , 8,10 , 793,48 , 841,78 , 919,24 , 793,48 , 841,78 , 919,24 , 383,28 , 411,58 , 469,14 , 383,28 , 411,58 , 469,14 , 7,8 , 7,7 , {69,85,82}, 20,1 , 179,19 , 13,5 , 4,0 , 77,5 , 98,6 , 2, 1, 1, 6, 7 }, // Albanian/Latin/Kosovo
+ { 7, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 23,6 , 23,6 , 29,9 , 38,8 , 133,10 , 10,17 , 18,7 , 25,12 , 943,46 , 989,61 , 1050,24 , 1074,46 , 1120,62 , 1050,24 , 483,27 , 510,28 , 538,14 , 483,27 , 510,28 , 538,14 , 15,3 , 14,4 , {69,84,66}, 21,2 , 198,34 , 4,4 , 4,0 , 104,4 , 108,5 , 2, 1, 7, 6, 7 }, // Amharic/Ethiopic/Ethiopia
+ { 8, 1, 64, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 60,6 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {69,71,80}, 23,5 , 232,70 , 8,5 , 4,0 , 113,7 , 120,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Egypt
+ { 8, 1, 3, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 171,8 , 153,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {68,90,68}, 28,5 , 302,91 , 8,5 , 4,0 , 113,7 , 123,7 , 2, 1, 6, 4, 5 }, // Arabic/Arabic/Algeria
+ { 8, 1, 17, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {66,72,68}, 33,5 , 393,91 , 8,5 , 4,0 , 113,7 , 130,7 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Bahrain
+ { 8, 1, 42, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {88,65,70}, 38,4 , 484,84 , 8,5 , 4,0 , 113,7 , 137,4 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Chad
+ { 8, 1, 48, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {75,77,70}, 42,7 , 568,105 , 8,5 , 4,0 , 113,7 , 141,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Comoros
+ { 8, 1, 59, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {68,74,70}, 5,3 , 673,84 , 8,5 , 4,0 , 113,7 , 150,6 , 0, 0, 6, 6, 7 }, // Arabic/Arabic/Djibouti
+ { 8, 1, 67, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {69,82,78}, 8,3 , 757,91 , 8,5 , 4,0 , 113,7 , 156,7 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/Eritrea
+ { 8, 1, 103, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1492,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {73,81,68}, 49,5 , 848,84 , 8,5 , 4,0 , 113,7 , 163,6 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Iraq
+ { 8, 1, 105, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {73,76,83}, 54,1 , 932,133 , 8,5 , 4,0 , 113,7 , 169,7 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/Israel
+ { 8, 1, 109, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1376,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {74,79,68}, 55,5 , 1065,84 , 8,5 , 4,0 , 113,7 , 176,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Jordan
+ { 8, 1, 115, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {75,87,68}, 60,5 , 1149,84 , 8,5 , 4,0 , 113,7 , 182,6 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Kuwait
+ { 8, 1, 119, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1376,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {76,66,80}, 65,5 , 1233,84 , 8,5 , 4,0 , 113,7 , 188,5 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Lebanon
+ { 8, 1, 122, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {76,89,68}, 70,5 , 1317,77 , 8,5 , 4,0 , 113,7 , 193,5 , 3, 0, 6, 5, 6 }, // Arabic/Arabic/Libya
+ { 8, 1, 136, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1584,72 , 1584,72 , 1656,24 , 1584,72 , 1584,72 , 1656,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {77,82,79}, 75,5 , 1394,112 , 8,5 , 4,0 , 113,7 , 198,9 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Mauritania
+ { 8, 1, 145, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 171,8 , 153,18 , 18,7 , 25,12 , 1680,70 , 1680,70 , 1750,24 , 1680,70 , 1680,70 , 1750,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {77,65,68}, 80,5 , 1506,77 , 8,5 , 4,0 , 113,7 , 207,6 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Morocco
+ { 8, 1, 162, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {79,77,82}, 85,5 , 1583,77 , 8,5 , 4,0 , 113,7 , 213,5 , 3, 0, 6, 4, 5 }, // Arabic/Arabic/Oman
+ { 8, 1, 165, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1376,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {73,76,83}, 54,1 , 932,133 , 8,5 , 4,0 , 113,7 , 218,18 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/PalestinianTerritories
+ { 8, 1, 175, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {81,65,82}, 90,5 , 1660,70 , 4,4 , 4,0 , 113,7 , 236,3 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Qatar
+ { 8, 1, 186, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {83,65,82}, 95,5 , 1730,77 , 4,4 , 4,0 , 113,7 , 239,24 , 2, 1, 7, 5, 6 }, // Arabic/Arabic/SaudiArabia
+ { 8, 1, 194, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {83,79,83}, 100,1 , 1807,77 , 8,5 , 4,0 , 113,7 , 263,7 , 0, 0, 1, 6, 7 }, // Arabic/Arabic/Somalia
+ { 8, 1, 201, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {83,68,71}, 101,4 , 1884,84 , 8,5 , 4,0 , 113,7 , 270,7 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/Sudan
+ { 8, 1, 207, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1376,92 , 1376,92 , 1468,24 , 1376,92 , 1376,92 , 1468,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {83,89,80}, 105,5 , 1968,77 , 4,4 , 4,0 , 113,7 , 277,5 , 0, 0, 6, 5, 6 }, // Arabic/Arabic/Syria
+ { 8, 1, 216, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 171,8 , 153,18 , 18,7 , 25,12 , 1281,71 , 1281,71 , 1352,24 , 1281,71 , 1281,71 , 1352,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {84,78,68}, 110,5 , 2045,77 , 4,4 , 4,0 , 113,7 , 282,4 , 3, 0, 7, 5, 6 }, // Arabic/Arabic/Tunisia
+ { 8, 1, 223, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {65,69,68}, 115,5 , 2122,91 , 8,5 , 4,0 , 113,7 , 286,24 , 2, 1, 6, 5, 6 }, // Arabic/Arabic/UnitedArabEmirates
+ { 8, 1, 236, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {77,65,68}, 80,5 , 1506,77 , 8,5 , 4,0 , 113,7 , 310,15 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/WesternSahara
+ { 8, 1, 237, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {89,69,82}, 120,5 , 2213,70 , 4,4 , 4,0 , 113,7 , 325,5 , 0, 0, 7, 5, 6 }, // Arabic/Arabic/Yemen
+ { 8, 1, 254, 1643, 1644, 1563, 1642, 1632, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 52,8 , 66,7 , 143,10 , 153,18 , 18,7 , 25,12 , 1182,75 , 1182,75 , 1257,24 , 1182,75 , 1182,75 , 1257,24 , 552,52 , 552,52 , 604,14 , 552,52 , 552,52 , 604,14 , 18,1 , 18,1 , {83,83,80}, 125,1 , 2283,126 , 8,5 , 4,0 , 113,7 , 330,12 , 2, 1, 1, 6, 7 }, // Arabic/Arabic/SouthSudan
+ { 9, 10, 11, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 73,7 , 73,7 , 179,8 , 187,19 , 42,4 , 46,10 , 1774,48 , 1822,94 , 1916,24 , 1774,48 , 1940,106 , 1916,24 , 618,28 , 646,62 , 708,15 , 618,28 , 646,62 , 708,15 , 19,12 , 19,12 , {65,77,68}, 126,3 , 2409,46 , 13,5 , 4,0 , 342,7 , 349,8 , 0, 0, 1, 6, 7 }, // Armenian/Armenian/Armenia
+ { 10, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 206,8 , 214,18 , 56,8 , 64,12 , 2046,62 , 2108,88 , 158,27 , 2046,62 , 2108,88 , 158,27 , 723,37 , 760,58 , 85,14 , 723,37 , 760,58 , 85,14 , 31,9 , 31,7 , {73,78,82}, 129,1 , 0,7 , 8,5 , 4,0 , 357,7 , 364,4 , 2, 1, 7, 7, 7 }, // Assamese/Bengali/India
+ { 12, 7, 15, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 80,8 , 80,8 , 179,8 , 232,17 , 37,5 , 8,10 , 2196,48 , 2244,77 , 158,27 , 2196,48 , 2321,77 , 158,27 , 818,26 , 844,67 , 99,14 , 818,26 , 844,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 130,4 , 2455,58 , 8,5 , 4,0 , 368,10 , 378,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Latin/Azerbaijan
+ { 12, 2, 15, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 179,8 , 249,19 , 37,5 , 8,10 , 2398,77 , 2398,77 , 158,27 , 2398,77 , 2398,77 , 158,27 , 911,67 , 911,67 , 99,14 , 911,67 , 911,67 , 99,14 , 0,2 , 0,2 , {65,90,78}, 134,4 , 2513,12 , 8,5 , 4,0 , 388,10 , 388,10 , 2, 1, 1, 6, 7 }, // Azerbaijani/Cyrillic/Azerbaijan
+ { 14, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 88,9 , 88,9 , 72,10 , 268,26 , 37,5 , 8,10 , 2475,60 , 2535,93 , 2628,24 , 2475,60 , 2652,105 , 2628,24 , 978,28 , 1006,68 , 1074,14 , 978,28 , 1006,68 , 1074,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2525,20 , 13,5 , 4,0 , 398,7 , 405,8 , 2, 1, 1, 6, 7 }, // Basque/Latin/Spain
+ { 15, 11, 18, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 97,10 , 107,9 , 294,6 , 214,18 , 18,7 , 25,12 , 2757,90 , 2757,90 , 2847,33 , 2757,90 , 2757,90 , 2847,33 , 1088,37 , 1125,58 , 1183,18 , 1088,37 , 1125,58 , 1183,18 , 40,9 , 38,7 , {66,68,84}, 138,1 , 2545,49 , 0,4 , 18,6 , 413,5 , 418,8 , 2, 1, 5, 6, 7 }, // Bengali/Bengali/Bangladesh
+ { 15, 11, 100, 46, 44, 59, 37, 2534, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 97,10 , 107,9 , 294,6 , 214,18 , 18,7 , 25,12 , 2757,90 , 2757,90 , 2847,33 , 2757,90 , 2757,90 , 2847,33 , 1088,37 , 1125,58 , 1183,18 , 1088,37 , 1125,58 , 1183,18 , 40,9 , 38,7 , {73,78,82}, 129,1 , 2594,43 , 0,4 , 18,6 , 413,5 , 426,4 , 2, 1, 7, 7, 7 }, // Bengali/Bengali/India
+ { 16, 31, 25, 46, 44, 59, 37, 3872, 45, 43, 101, 8220, 8221, 8216, 8217, 116,9 , 116,9 , 116,9 , 116,9 , 72,10 , 300,30 , 76,22 , 98,27 , 2880,63 , 2943,191 , 3134,27 , 3161,27 , 3188,132 , 3320,27 , 1201,34 , 1235,79 , 1314,27 , 1201,34 , 1235,79 , 1314,27 , 49,5 , 45,6 , {66,84,78}, 139,3 , 2637,15 , 4,4 , 4,0 , 430,6 , 436,5 , 2, 1, 7, 6, 7 }, // Dzongkha/Tibetan/Bhutan
+ { 19, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 3347,55 , 3402,78 , 158,27 , 3347,55 , 3402,78 , 158,27 , 1341,33 , 1374,43 , 1417,21 , 1341,33 , 1374,43 , 1417,21 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2652,11 , 8,5 , 4,0 , 441,9 , 450,5 , 2, 1, 1, 6, 7 }, // Breton/Latin/France
+ { 20, 2, 33, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 347,7 , 354,22 , 42,4 , 125,9 , 3480,59 , 3539,82 , 3621,24 , 3480,59 , 3539,82 , 3621,24 , 1438,21 , 1459,55 , 1514,14 , 1438,21 , 1459,55 , 1514,14 , 54,6 , 51,6 , {66,71,78}, 142,3 , 2663,47 , 13,5 , 4,0 , 455,9 , 464,8 , 2, 1, 1, 6, 7 }, // Bulgarian/Cyrillic/Bulgaria
+ { 21, 25, 147, 46, 44, 4170, 37, 4160, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 132,11 , 143,9 , 376,8 , 384,18 , 37,5 , 8,10 , 3645,88 , 3645,88 , 3733,24 , 3645,88 , 3645,88 , 3733,24 , 1528,54 , 1528,54 , 1582,14 , 1528,54 , 1528,54 , 1582,14 , 60,5 , 57,3 , {77,77,75}, 145,1 , 2710,27 , 8,5 , 4,0 , 472,3 , 475,6 , 0, 0, 7, 6, 7 }, // Burmese/Myanmar/Myanmar
+ { 22, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 402,6 , 10,17 , 134,5 , 139,10 , 3757,48 , 3805,95 , 3900,24 , 3924,48 , 3972,98 , 3900,24 , 1596,21 , 1617,56 , 1673,14 , 1596,21 , 1617,56 , 1673,14 , 65,10 , 60,13 , {66,89,82}, 146,2 , 2737,23 , 4,4 , 4,0 , 481,10 , 491,8 , 0, 0, 7, 6, 7 }, // Belarusian/Cyrillic/Belarus
+ { 23, 20, 36, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 152,9 , 408,8 , 99,16 , 18,7 , 25,12 , 4070,71 , 4070,71 , 158,27 , 4070,71 , 4070,71 , 158,27 , 1687,46 , 1687,46 , 1733,14 , 1687,46 , 1687,46 , 1733,14 , 75,5 , 73,5 , {75,72,82}, 148,1 , 2760,18 , 4,4 , 4,0 , 499,5 , 504,7 , 2, 1, 7, 6, 7 }, // Khmer/Khmer/Cambodia
+ { 24, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 161,7 , 161,7 , 294,6 , 416,22 , 149,4 , 153,9 , 4141,59 , 4200,82 , 4282,36 , 4141,59 , 4200,82 , 4282,36 , 1747,28 , 1775,60 , 1835,21 , 1747,28 , 1775,60 , 1835,21 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 511,6 , 517,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Spain
+ { 24, 7, 5, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 161,7 , 161,7 , 294,6 , 416,22 , 149,4 , 153,9 , 4141,59 , 4200,82 , 4282,36 , 4141,59 , 4200,82 , 4282,36 , 1747,28 , 1775,60 , 1835,21 , 1747,28 , 1775,60 , 1835,21 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 511,6 , 524,7 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Andorra
+ { 24, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 161,7 , 161,7 , 294,6 , 416,22 , 149,4 , 153,9 , 4141,59 , 4200,82 , 4282,36 , 4141,59 , 4200,82 , 4282,36 , 1747,28 , 1775,60 , 1835,21 , 1747,28 , 1775,60 , 1835,21 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 511,6 , 531,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/France
+ { 24, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 171, 187, 0,6 , 0,6 , 161,7 , 161,7 , 294,6 , 416,22 , 149,4 , 153,9 , 4141,59 , 4200,82 , 4282,36 , 4141,59 , 4200,82 , 4282,36 , 1747,28 , 1775,60 , 1835,21 , 1747,28 , 1775,60 , 1835,21 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 511,6 , 537,6 , 2, 1, 1, 6, 7 }, // Catalan/Latin/Italy
+ { 25, 5, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 168,5 , 168,5 , 173,5 , 173,5 , 438,6 , 444,13 , 162,6 , 168,10 , 4318,39 , 4357,38 , 158,27 , 4318,39 , 4357,38 , 158,27 , 1856,21 , 1877,28 , 1905,14 , 1856,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {67,78,89}, 149,1 , 2798,13 , 8,5 , 4,0 , 543,4 , 547,2 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/China
+ { 25, 5, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 168,5 , 168,5 , 173,5 , 173,5 , 294,6 , 444,13 , 162,6 , 168,10 , 4318,39 , 4357,38 , 158,27 , 4318,39 , 4357,38 , 158,27 , 1856,21 , 1877,28 , 1905,14 , 1856,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {72,75,68}, 12,1 , 2811,11 , 4,4 , 4,0 , 543,4 , 549,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/HongKong
+ { 25, 5, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 168,5 , 168,5 , 173,5 , 173,5 , 294,6 , 444,13 , 162,6 , 168,10 , 4318,39 , 4357,38 , 158,27 , 4318,39 , 4357,38 , 158,27 , 1856,21 , 1877,28 , 1905,14 , 1856,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {77,79,80}, 150,4 , 2822,13 , 4,4 , 4,0 , 543,4 , 558,9 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Macau
+ { 25, 5, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 168,5 , 168,5 , 173,5 , 173,5 , 27,8 , 444,13 , 178,7 , 168,10 , 4318,39 , 4357,38 , 158,27 , 4318,39 , 4357,38 , 158,27 , 1856,21 , 1877,28 , 1905,14 , 1856,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {83,71,68}, 12,1 , 2835,15 , 4,4 , 4,0 , 543,4 , 567,3 , 2, 1, 7, 6, 7 }, // Chinese/Simplified Han/Singapore
+ { 25, 6, 97, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 168,5 , 168,5 , 173,5 , 173,5 , 294,6 , 444,13 , 162,6 , 185,13 , 4318,39 , 4318,39 , 158,27 , 4318,39 , 4318,39 , 158,27 , 1919,21 , 1877,28 , 1905,14 , 1919,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {72,75,68}, 12,1 , 2850,11 , 4,4 , 4,0 , 570,4 , 574,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/HongKong
+ { 25, 6, 126, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 168,5 , 168,5 , 173,5 , 173,5 , 457,7 , 464,15 , 162,6 , 185,13 , 4318,39 , 4318,39 , 158,27 , 4318,39 , 4318,39 , 158,27 , 1919,21 , 1877,28 , 1905,14 , 1919,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {77,79,80}, 150,4 , 2861,13 , 4,4 , 4,0 , 570,4 , 588,14 , 2, 1, 7, 6, 7 }, // Chinese/Traditional Han/Macau
+ { 25, 6, 208, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 168,5 , 168,5 , 173,5 , 173,5 , 171,8 , 444,13 , 162,6 , 198,11 , 4318,39 , 4318,39 , 158,27 , 4318,39 , 4318,39 , 158,27 , 1919,21 , 1877,28 , 1905,14 , 1919,21 , 1877,28 , 1905,14 , 85,2 , 83,2 , {84,87,68}, 154,3 , 2874,13 , 4,4 , 4,0 , 570,4 , 602,2 , 2, 0, 7, 6, 7 }, // Chinese/Traditional Han/Taiwan
+ { 27, 7, 54, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 486,19 , 37,5 , 8,10 , 4395,49 , 4444,94 , 4538,39 , 4395,49 , 4577,98 , 4538,39 , 1940,28 , 1968,58 , 2026,14 , 1940,28 , 1968,58 , 2040,14 , 0,2 , 0,2 , {72,82,75}, 157,2 , 2887,60 , 13,5 , 4,0 , 604,8 , 612,8 , 2, 1, 1, 6, 7 }, // Croatian/Latin/Croatia
+ { 27, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 486,19 , 37,5 , 8,10 , 4395,49 , 4444,94 , 4538,39 , 4395,49 , 4577,98 , 4538,39 , 1940,28 , 1968,58 , 2026,14 , 1940,28 , 1968,58 , 2040,14 , 0,2 , 0,2 , {66,65,77}, 159,2 , 2947,85 , 13,5 , 4,0 , 604,8 , 620,19 , 2, 1, 1, 6, 7 }, // Croatian/Latin/BosniaAndHerzegowina
+ { 28, 7, 57, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 178,7 , 178,7 , 179,8 , 505,17 , 42,4 , 125,9 , 4675,48 , 4723,82 , 4805,24 , 4675,48 , 4829,84 , 158,27 , 2054,21 , 2075,49 , 2124,14 , 2054,21 , 2075,49 , 2124,14 , 0,2 , 0,2 , {67,90,75}, 161,2 , 3032,68 , 13,5 , 4,0 , 639,7 , 646,15 , 2, 1, 1, 6, 7 }, // Czech/Latin/CzechRepublic
+ { 29, 7, 58, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 27,8 , 522,23 , 134,5 , 139,10 , 4913,48 , 4961,84 , 134,24 , 5045,59 , 4961,84 , 134,24 , 2138,28 , 2166,51 , 2217,14 , 2231,35 , 2166,51 , 2217,14 , 0,2 , 0,2 , {68,75,75}, 163,2 , 3100,42 , 13,5 , 4,0 , 661,5 , 666,7 , 2, 1, 1, 6, 7 }, // Danish/Latin/Denmark
+ { 29, 7, 86, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 27,8 , 522,23 , 134,5 , 139,10 , 4913,48 , 4961,84 , 134,24 , 5045,59 , 4961,84 , 134,24 , 2138,28 , 2166,51 , 2217,14 , 2231,35 , 2166,51 , 2217,14 , 0,2 , 0,2 , {68,75,75}, 163,2 , 3100,42 , 13,5 , 4,0 , 661,5 , 673,8 , 2, 1, 1, 6, 7 }, // Danish/Latin/Greenland
+ { 30, 7, 151, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 179,19 , 8,5 , 24,6 , 681,10 , 691,9 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Netherlands
+ { 30, 7, 12, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {65,87,71}, 165,4 , 3142,55 , 8,5 , 24,6 , 681,10 , 700,5 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Aruba
+ { 30, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 553,7 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 179,19 , 13,5 , 4,0 , 705,6 , 711,6 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Belgium
+ { 30, 7, 152, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {65,78,71}, 169,4 , 3197,97 , 8,5 , 24,6 , 681,10 , 717,7 , 2, 1, 1, 6, 7 }, // Dutch/Latin/CuraSao
+ { 30, 7, 202, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {83,82,68}, 12,1 , 3294,58 , 8,5 , 24,6 , 681,10 , 724,8 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Suriname
+ { 30, 7, 255, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3352,61 , 8,5 , 24,6 , 681,10 , 732,19 , 2, 1, 1, 6, 7 }, // Dutch/Latin/Bonaire
+ { 30, 7, 256, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 6,8 , 6,8 , 545,8 , 99,16 , 37,5 , 8,10 , 5104,48 , 5152,88 , 134,24 , 5240,59 , 5152,88 , 134,24 , 2266,21 , 2287,59 , 2346,14 , 2266,21 , 2287,59 , 2346,14 , 0,2 , 0,2 , {65,78,71}, 169,4 , 3197,97 , 8,5 , 24,6 , 681,10 , 751,12 , 2, 1, 1, 6, 7 }, // Dutch/Latin/SintMaarten
+ { 31, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 763,16 , 779,13 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStates
+ { 31, 3, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 5299,80 , 5379,154 , 5533,36 , 5299,80 , 5379,154 , 5533,36 , 2360,49 , 2409,85 , 2494,21 , 2360,49 , 2409,85 , 2494,21 , 87,4 , 85,4 , {85,83,68}, 12,1 , 0,7 , 8,5 , 4,0 , 792,10 , 802,25 , 2, 1, 7, 6, 7 }, // English/Deseret/UnitedStates
+ { 31, 7, 4, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 834,14 , 2, 1, 7, 6, 7 }, // English/Latin/AmericanSamoa
+ { 31, 7, 7, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 848,8 , 2, 1, 1, 6, 7 }, // English/Latin/Anguilla
+ { 31, 7, 9, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 856,19 , 2, 1, 7, 6, 7 }, // English/Latin/AntiguaAndBarbuda
+ { 31, 7, 13, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 566,9 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 875,18 , 893,9 , 2, 1, 7, 6, 7 }, // English/Latin/Australia
+ { 31, 7, 16, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,83,68}, 12,1 , 3578,53 , 4,4 , 4,0 , 827,7 , 902,7 , 2, 1, 7, 6, 7 }, // English/Latin/Bahamas
+ { 31, 7, 19, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,66,68}, 12,1 , 3631,56 , 4,4 , 4,0 , 827,7 , 909,8 , 2, 1, 1, 6, 7 }, // English/Latin/Barbados
+ { 31, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 27,8 , 99,16 , 37,5 , 209,24 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {69,85,82}, 20,1 , 3687,20 , 13,5 , 4,0 , 827,7 , 917,7 , 2, 1, 1, 6, 7 }, // English/Latin/Belgium
+ { 31, 7, 22, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 27,8 , 82,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,90,68}, 12,1 , 3707,47 , 4,4 , 4,0 , 827,7 , 924,6 , 2, 1, 7, 6, 7 }, // English/Latin/Belize
+ { 31, 7, 24, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,77,68}, 12,1 , 3754,53 , 4,4 , 4,0 , 827,7 , 930,7 , 2, 1, 1, 6, 7 }, // English/Latin/Bermuda
+ { 31, 7, 28, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 27,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {66,87,80}, 176,1 , 3807,50 , 4,4 , 4,0 , 827,7 , 937,8 , 2, 1, 7, 6, 7 }, // English/Latin/Botswana
+ { 31, 7, 31, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 945,30 , 2, 1, 1, 6, 7 }, // English/Latin/BritishIndianOceanTerritory
+ { 31, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 3857,50 , 4,4 , 4,0 , 827,7 , 975,8 , 0, 0, 1, 6, 7 }, // English/Latin/Cameroon
+ { 31, 7, 38, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 3907,53 , 4,4 , 4,0 , 983,16 , 999,6 , 2, 0, 7, 6, 7 }, // English/Latin/Canada
+ { 31, 7, 40, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,89,68}, 12,1 , 3960,71 , 4,4 , 4,0 , 827,7 , 1005,14 , 2, 1, 1, 6, 7 }, // English/Latin/CaymanIslands
+ { 31, 7, 45, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1019,16 , 2, 1, 1, 6, 7 }, // English/Latin/ChristmasIsland
+ { 31, 7, 46, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1035,23 , 2, 1, 1, 6, 7 }, // English/Latin/CocosIslands
+ { 31, 7, 51, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,90,68}, 12,1 , 4031,62 , 4,4 , 4,0 , 827,7 , 1058,12 , 2, 1, 1, 6, 7 }, // English/Latin/CookIslands
+ { 31, 7, 60, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1070,8 , 2, 1, 7, 6, 7 }, // English/Latin/Dominica
+ { 31, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 4093,50 , 4,4 , 4,0 , 827,7 , 1078,7 , 2, 1, 1, 6, 7 }, // English/Latin/Eritrea
+ { 31, 7, 70, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {70,75,80}, 125,1 , 4143,74 , 4,4 , 4,0 , 827,7 , 1085,16 , 2, 1, 1, 6, 7 }, // English/Latin/FalklandIslands
+ { 31, 7, 72, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {70,74,68}, 12,1 , 4217,47 , 4,4 , 4,0 , 827,7 , 1101,4 , 2, 1, 1, 6, 7 }, // English/Latin/Fiji
+ { 31, 7, 75, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {71,66,80}, 125,1 , 4264,47 , 4,4 , 4,0 , 827,7 , 1105,8 , 2, 1, 1, 6, 7 }, // English/Latin/Guernsey
+ { 31, 7, 80, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,77,68}, 177,1 , 4311,50 , 4,4 , 4,0 , 827,7 , 1113,6 , 2, 1, 1, 6, 7 }, // English/Latin/Gambia
+ { 31, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,72,83}, 178,3 , 4361,47 , 4,4 , 4,0 , 827,7 , 1119,5 , 2, 1, 1, 6, 7 }, // English/Latin/Ghana
+ { 31, 7, 84, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {71,73,80}, 125,1 , 4408,53 , 4,4 , 4,0 , 827,7 , 1124,9 , 2, 1, 1, 6, 7 }, // English/Latin/Gibraltar
+ { 31, 7, 87, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1133,7 , 2, 1, 1, 6, 7 }, // English/Latin/Grenada
+ { 31, 7, 89, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1140,4 , 2, 1, 7, 6, 7 }, // English/Latin/Guam
+ { 31, 7, 93, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {71,89,68}, 12,1 , 4461,56 , 4,4 , 4,0 , 827,7 , 1144,6 , 0, 0, 1, 6, 7 }, // English/Latin/Guyana
+ { 31, 7, 97, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 294,6 , 214,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {72,75,68}, 12,1 , 4517,56 , 4,4 , 4,0 , 827,7 , 1150,19 , 2, 1, 7, 6, 7 }, // English/Latin/HongKong
+ { 31, 7, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 27,8 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {73,78,82}, 129,1 , 4573,44 , 8,5 , 4,0 , 827,7 , 1169,5 , 2, 1, 7, 7, 7 }, // English/Latin/India
+ { 31, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 99,16 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 93,4 , 91,4 , {69,85,82}, 20,1 , 3687,20 , 4,4 , 4,0 , 827,7 , 1174,7 , 2, 1, 7, 6, 7 }, // English/Latin/Ireland
+ { 31, 7, 107, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 294,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {74,77,68}, 12,1 , 4617,53 , 4,4 , 4,0 , 827,7 , 1181,7 , 2, 1, 7, 6, 7 }, // English/Latin/Jamaica
+ { 31, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 4670,53 , 4,4 , 4,0 , 827,7 , 1188,5 , 2, 1, 7, 6, 7 }, // English/Latin/Kenya
+ { 31, 7, 112, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1193,8 , 2, 1, 1, 6, 7 }, // English/Latin/Kiribati
+ { 31, 7, 120, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4723,61 , 4,4 , 4,0 , 827,7 , 1201,7 , 2, 1, 1, 6, 7 }, // English/Latin/Lesotho
+ { 31, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 4784,53 , 4,4 , 4,0 , 827,7 , 1208,7 , 2, 1, 1, 6, 7 }, // English/Latin/Liberia
+ { 31, 7, 126, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {77,79,80}, 150,4 , 4837,53 , 4,4 , 4,0 , 827,7 , 1215,15 , 2, 1, 7, 6, 7 }, // English/Latin/Macau
+ { 31, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,71,65}, 181,2 , 4890,54 , 4,4 , 4,0 , 827,7 , 1230,10 , 0, 0, 1, 6, 7 }, // English/Latin/Madagascar
+ { 31, 7, 129, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,87,75}, 183,2 , 4944,53 , 4,4 , 4,0 , 827,7 , 1240,6 , 2, 1, 1, 6, 7 }, // English/Latin/Malawi
+ { 31, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {69,85,82}, 20,1 , 3687,20 , 4,4 , 4,0 , 827,7 , 1246,5 , 2, 1, 7, 6, 7 }, // English/Latin/Malta
+ { 31, 7, 134, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1251,16 , 2, 1, 7, 6, 7 }, // English/Latin/MarshallIslands
+ { 31, 7, 137, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {77,85,82}, 185,2 , 4997,53 , 4,4 , 4,0 , 827,7 , 1267,9 , 0, 0, 1, 6, 7 }, // English/Latin/Mauritius
+ { 31, 7, 140, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 3413,35 , 4,4 , 4,0 , 827,7 , 1276,10 , 2, 1, 1, 6, 7 }, // English/Latin/Micronesia
+ { 31, 7, 144, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1286,10 , 2, 1, 1, 6, 7 }, // English/Latin/Montserrat
+ { 31, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,65,68}, 12,1 , 5050,53 , 4,4 , 4,0 , 827,7 , 1296,7 , 2, 1, 1, 6, 7 }, // English/Latin/Namibia
+ { 31, 7, 149, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1303,5 , 2, 1, 1, 6, 7 }, // English/Latin/Nauru
+ { 31, 7, 154, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 553,7 , 10,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {78,90,68}, 12,1 , 4031,62 , 4,4 , 4,0 , 827,7 , 1308,11 , 2, 1, 7, 6, 7 }, // English/Latin/NewZealand
+ { 31, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,71,78}, 190,1 , 5103,50 , 4,4 , 4,0 , 827,7 , 1319,7 , 2, 1, 1, 6, 7 }, // English/Latin/Nigeria
+ { 31, 7, 158, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,90,68}, 12,1 , 4031,62 , 4,4 , 4,0 , 827,7 , 1326,4 , 2, 1, 1, 6, 7 }, // English/Latin/Niue
+ { 31, 7, 159, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1330,14 , 2, 1, 1, 6, 7 }, // English/Latin/NorfolkIsland
+ { 31, 7, 160, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1344,24 , 2, 1, 1, 6, 7 }, // English/Latin/NorthernMarianaIslands
+ { 31, 7, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 99,16 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {80,75,82}, 185,2 , 5153,53 , 8,5 , 4,0 , 827,7 , 1368,8 , 0, 0, 7, 6, 7 }, // English/Latin/Pakistan
+ { 31, 7, 164, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 3413,35 , 4,4 , 4,0 , 827,7 , 1376,5 , 2, 1, 1, 6, 7 }, // English/Latin/Palau
+ { 31, 7, 167, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,71,75}, 145,1 , 5206,73 , 4,4 , 4,0 , 827,7 , 1381,16 , 2, 1, 1, 6, 7 }, // English/Latin/PapuaNewGuinea
+ { 31, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {80,72,80}, 191,1 , 5279,53 , 4,4 , 4,0 , 827,7 , 1397,11 , 2, 1, 7, 6, 7 }, // English/Latin/Philippines
+ { 31, 7, 171, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,90,68}, 12,1 , 4031,62 , 4,4 , 4,0 , 827,7 , 1408,16 , 2, 1, 1, 6, 7 }, // English/Latin/Pitcairn
+ { 31, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1424,11 , 2, 1, 7, 6, 7 }, // English/Latin/PuertoRico
+ { 31, 7, 179, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {82,87,70}, 192,2 , 5332,47 , 4,4 , 4,0 , 827,7 , 1435,6 , 0, 0, 1, 6, 7 }, // English/Latin/Rwanda
+ { 31, 7, 180, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1441,21 , 2, 1, 1, 6, 7 }, // English/Latin/SaintKittsAndNevis
+ { 31, 7, 181, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1462,11 , 2, 1, 1, 6, 7 }, // English/Latin/SaintLucia
+ { 31, 7, 182, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {88,67,68}, 173,3 , 3448,71 , 4,4 , 4,0 , 827,7 , 1473,24 , 2, 1, 1, 6, 7 }, // English/Latin/SaintVincentAndTheGrenadines
+ { 31, 7, 183, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {87,83,84}, 194,3 , 5379,40 , 4,4 , 4,0 , 827,7 , 1497,5 , 2, 1, 7, 6, 7 }, // English/Latin/Samoa
+ { 31, 7, 188, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,67,82}, 197,2 , 5419,59 , 4,4 , 4,0 , 827,7 , 1502,10 , 2, 1, 1, 6, 7 }, // English/Latin/Seychelles
+ { 31, 7, 189, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,76,76}, 199,2 , 5478,68 , 4,4 , 4,0 , 827,7 , 1512,12 , 0, 0, 1, 6, 7 }, // English/Latin/SierraLeone
+ { 31, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 294,6 , 214,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {83,71,68}, 12,1 , 5546,56 , 4,4 , 4,0 , 827,7 , 1524,9 , 2, 1, 7, 6, 7 }, // English/Latin/Singapore
+ { 31, 7, 193, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,66,68}, 12,1 , 5602,74 , 4,4 , 4,0 , 827,7 , 1533,15 , 2, 1, 1, 6, 7 }, // English/Latin/SolomonIslands
+ { 31, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 575,10 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 4723,61 , 4,4 , 4,0 , 827,7 , 1548,12 , 2, 1, 7, 6, 7 }, // English/Latin/SouthAfrica
+ { 31, 7, 199, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {83,72,80}, 125,1 , 5676,62 , 4,4 , 4,0 , 827,7 , 1560,12 , 2, 1, 1, 6, 7 }, // English/Latin/SaintHelena
+ { 31, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,68,71}, 0,0 , 5738,50 , 4,4 , 4,0 , 827,7 , 1572,5 , 2, 1, 6, 5, 6 }, // English/Latin/Sudan
+ { 31, 7, 204, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,90,76}, 201,1 , 5788,53 , 4,4 , 4,0 , 827,7 , 1577,9 , 2, 1, 1, 6, 7 }, // English/Latin/Swaziland
+ { 31, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,90,83}, 202,3 , 5841,62 , 4,4 , 4,0 , 827,7 , 1586,8 , 0, 0, 1, 6, 7 }, // English/Latin/Tanzania
+ { 31, 7, 213, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {78,90,68}, 12,1 , 4031,62 , 4,4 , 4,0 , 827,7 , 1594,7 , 2, 1, 1, 6, 7 }, // English/Latin/Tokelau
+ { 31, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,79,80}, 205,2 , 5903,49 , 4,4 , 4,0 , 827,7 , 1601,5 , 2, 1, 1, 6, 7 }, // English/Latin/Tonga
+ { 31, 7, 215, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {84,84,68}, 12,1 , 5952,86 , 4,4 , 4,0 , 827,7 , 1606,19 , 2, 1, 7, 6, 7 }, // English/Latin/TrinidadAndTobago
+ { 31, 7, 219, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 3413,35 , 4,4 , 4,0 , 827,7 , 1625,24 , 2, 1, 1, 6, 7 }, // English/Latin/TurksAndCaicosIslands
+ { 31, 7, 220, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,85,68}, 12,1 , 3519,59 , 4,4 , 4,0 , 827,7 , 1649,6 , 2, 1, 1, 6, 7 }, // English/Latin/Tuvalu
+ { 31, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,71,88}, 207,3 , 6038,56 , 4,4 , 4,0 , 827,7 , 1655,6 , 0, 0, 1, 6, 7 }, // English/Latin/Uganda
+ { 31, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {71,66,80}, 125,1 , 4264,47 , 4,4 , 4,0 , 1661,10 , 1671,14 , 2, 1, 1, 6, 7 }, // English/Latin/UnitedKingdom
+ { 31, 7, 226, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1685,21 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesMinorOutlyingIslands
+ { 31, 7, 229, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {86,85,86}, 210,2 , 6094,44 , 4,4 , 4,0 , 827,7 , 1706,7 , 0, 0, 1, 6, 7 }, // English/Latin/Vanuatu
+ { 31, 7, 233, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1713,22 , 2, 1, 1, 6, 7 }, // English/Latin/BritishVirginIslands
+ { 31, 7, 234, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1735,19 , 2, 1, 7, 6, 7 }, // English/Latin/UnitedStatesVirginIslands
+ { 31, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {90,77,87}, 145,1 , 6138,50 , 4,4 , 4,0 , 827,7 , 1754,6 , 2, 1, 1, 6, 7 }, // English/Latin/Zambia
+ { 31, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 408,8 , 82,17 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 3413,35 , 4,4 , 4,0 , 827,7 , 1760,8 , 2, 1, 7, 6, 7 }, // English/Latin/Zimbabwe
+ { 31, 7, 249, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {85,83,68}, 12,1 , 3413,35 , 4,4 , 4,0 , 827,7 , 1768,12 , 2, 1, 1, 6, 7 }, // English/Latin/DiegoGarcia
+ { 31, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {71,66,80}, 125,1 , 4264,47 , 4,4 , 4,0 , 827,7 , 1780,11 , 2, 1, 1, 6, 7 }, // English/Latin/IsleOfMan
+ { 31, 7, 252, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 203,9 , 203,9 , 133,10 , 10,17 , 37,5 , 8,10 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 91,2 , 89,2 , {71,66,80}, 125,1 , 4264,47 , 4,4 , 4,0 , 827,7 , 1791,6 , 2, 1, 1, 6, 7 }, // English/Latin/Jersey
+ { 31, 7, 254, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {83,83,80}, 125,1 , 6188,68 , 4,4 , 4,0 , 827,7 , 1797,11 , 2, 1, 1, 6, 7 }, // English/Latin/SouthSudan
+ { 31, 7, 256, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 203,9 , 560,6 , 35,18 , 18,7 , 25,12 , 0,48 , 48,86 , 134,24 , 0,48 , 48,86 , 134,24 , 0,28 , 28,57 , 85,14 , 0,28 , 28,57 , 85,14 , 0,2 , 0,2 , {65,78,71}, 169,4 , 6256,95 , 4,4 , 4,0 , 827,7 , 1808,12 , 2, 1, 1, 6, 7 }, // English/Latin/SintMaarten
+ { 33, 7, 68, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 212,8 , 212,8 , 179,8 , 585,18 , 42,4 , 233,9 , 5569,59 , 5628,91 , 5719,24 , 5569,59 , 5628,91 , 5719,24 , 2515,14 , 2529,63 , 2515,14 , 2515,14 , 2529,63 , 2515,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 6351,20 , 13,5 , 4,0 , 1820,5 , 1825,5 , 2, 1, 1, 6, 7 }, // Estonian/Latin/Estonia
+ { 34, 7, 71, 44, 46, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 545,8 , 82,17 , 37,5 , 8,10 , 5743,48 , 5791,83 , 134,24 , 5743,48 , 5791,83 , 134,24 , 2592,28 , 2620,74 , 2694,14 , 2592,28 , 2620,74 , 2694,14 , 0,2 , 0,2 , {68,75,75}, 163,2 , 6371,42 , 4,4 , 30,5 , 1830,8 , 1838,7 , 2, 1, 1, 6, 7 }, // Faroese/Latin/FaroeIslands
+ { 36, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 212,8 , 212,8 , 603,8 , 505,17 , 149,4 , 153,9 , 5874,69 , 5943,105 , 6048,24 , 6072,129 , 6072,129 , 6048,24 , 2708,21 , 2729,67 , 2796,14 , 2708,21 , 2810,81 , 2796,14 , 97,3 , 95,3 , {69,85,82}, 20,1 , 6413,20 , 13,5 , 4,0 , 1845,5 , 1850,5 , 2, 1, 1, 6, 7 }, // Finnish/Latin/Finland
+ { 37, 7, 74, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 1863,6 , 2, 1, 1, 6, 7 }, // French/Latin/France
+ { 37, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {68,90,68}, 212,2 , 6433,51 , 13,5 , 4,0 , 1855,8 , 1869,7 , 2, 1, 6, 4, 5 }, // French/Latin/Algeria
+ { 37, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 553,7 , 99,16 , 37,5 , 242,23 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 1876,8 , 2, 1, 1, 6, 7 }, // French/Latin/Belgium
+ { 37, 7, 23, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 1884,5 , 0, 0, 1, 6, 7 }, // French/Latin/Benin
+ { 37, 7, 34, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 1889,12 , 0, 0, 1, 6, 7 }, // French/Latin/BurkinaFaso
+ { 37, 7, 35, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {66,73,70}, 217,3 , 6543,53 , 13,5 , 4,0 , 1855,8 , 1901,7 , 0, 0, 1, 6, 7 }, // French/Latin/Burundi
+ { 37, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 1908,8 , 0, 0, 1, 6, 7 }, // French/Latin/Cameroon
+ { 37, 7, 38, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 220,8 , 220,8 , 611,8 , 99,16 , 37,5 , 209,24 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {67,65,68}, 12,1 , 6652,54 , 13,5 , 4,0 , 1916,17 , 999,6 , 2, 0, 7, 6, 7 }, // French/Latin/Canada
+ { 37, 7, 41, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 1933,25 , 0, 0, 1, 6, 7 }, // French/Latin/CentralAfricanRepublic
+ { 37, 7, 42, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 1958,5 , 0, 0, 1, 6, 7 }, // French/Latin/Chad
+ { 37, 7, 48, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {75,77,70}, 220,2 , 6706,51 , 13,5 , 4,0 , 1855,8 , 1963,7 , 0, 0, 1, 6, 7 }, // French/Latin/Comoros
+ { 37, 7, 49, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {67,68,70}, 222,2 , 6757,53 , 13,5 , 4,0 , 1855,8 , 1970,14 , 2, 1, 1, 6, 7 }, // French/Latin/CongoKinshasa
+ { 37, 7, 50, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 1984,17 , 0, 0, 1, 6, 7 }, // French/Latin/CongoBrazzaville
+ { 37, 7, 53, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 2001,13 , 0, 0, 1, 6, 7 }, // French/Latin/IvoryCoast
+ { 37, 7, 59, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {68,74,70}, 5,3 , 6810,57 , 13,5 , 4,0 , 1855,8 , 2014,8 , 0, 0, 6, 6, 7 }, // French/Latin/Djibouti
+ { 37, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 2022,18 , 0, 0, 1, 6, 7 }, // French/Latin/EquatorialGuinea
+ { 37, 7, 76, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2040,16 , 2, 1, 1, 6, 7 }, // French/Latin/FrenchGuiana
+ { 37, 7, 77, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,80,70}, 224,4 , 6867,35 , 13,5 , 4,0 , 1855,8 , 2056,19 , 0, 0, 1, 6, 7 }, // French/Latin/FrenchPolynesia
+ { 37, 7, 79, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,65,70}, 38,4 , 6596,56 , 13,5 , 4,0 , 1855,8 , 2075,5 , 0, 0, 1, 6, 7 }, // French/Latin/Gabon
+ { 37, 7, 88, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2080,10 , 2, 1, 1, 6, 7 }, // French/Latin/Guadeloupe
+ { 37, 7, 91, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {71,78,70}, 228,2 , 6902,48 , 13,5 , 4,0 , 1855,8 , 2090,6 , 0, 0, 1, 6, 7 }, // French/Latin/Guinea
+ { 37, 7, 94, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {72,84,71}, 230,1 , 6950,57 , 13,5 , 4,0 , 1855,8 , 2096,5 , 2, 1, 1, 6, 7 }, // French/Latin/Haiti
+ { 37, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2101,10 , 2, 1, 1, 6, 7 }, // French/Latin/Luxembourg
+ { 37, 7, 128, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {77,71,65}, 181,2 , 7007,54 , 13,5 , 4,0 , 1855,8 , 1230,10 , 0, 0, 1, 6, 7 }, // French/Latin/Madagascar
+ { 37, 7, 132, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 2111,4 , 0, 0, 1, 6, 7 }, // French/Latin/Mali
+ { 37, 7, 135, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2115,10 , 2, 1, 1, 6, 7 }, // French/Latin/Martinique
+ { 37, 7, 136, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {77,82,79}, 231,2 , 7061,66 , 13,5 , 4,0 , 1855,8 , 2125,10 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritania
+ { 37, 7, 137, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {77,85,82}, 185,2 , 7127,63 , 13,5 , 4,0 , 1855,8 , 2135,7 , 0, 0, 1, 6, 7 }, // French/Latin/Mauritius
+ { 37, 7, 138, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2142,7 , 2, 1, 1, 6, 7 }, // French/Latin/Mayotte
+ { 37, 7, 142, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2149,6 , 2, 1, 1, 6, 7 }, // French/Latin/Monaco
+ { 37, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {77,65,68}, 0,0 , 7190,54 , 13,5 , 4,0 , 1855,8 , 2155,5 , 2, 1, 6, 5, 6 }, // French/Latin/Morocco
+ { 37, 7, 153, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,80,70}, 224,4 , 6867,35 , 13,5 , 4,0 , 1855,8 , 2160,18 , 0, 0, 1, 6, 7 }, // French/Latin/NewCaledonia
+ { 37, 7, 156, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 2178,5 , 0, 0, 1, 6, 7 }, // French/Latin/Niger
+ { 37, 7, 176, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2183,10 , 2, 1, 1, 6, 7 }, // French/Latin/Reunion
+ { 37, 7, 179, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {82,87,70}, 192,2 , 7244,50 , 13,5 , 4,0 , 1855,8 , 1435,6 , 0, 0, 1, 6, 7 }, // French/Latin/Rwanda
+ { 37, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 2193,7 , 0, 0, 1, 6, 7 }, // French/Latin/Senegal
+ { 37, 7, 188, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {83,67,82}, 197,2 , 7294,71 , 13,5 , 4,0 , 1855,8 , 1502,10 , 2, 1, 1, 6, 7 }, // French/Latin/Seychelles
+ { 37, 7, 200, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2200,24 , 2, 1, 1, 6, 7 }, // French/Latin/SaintPierreAndMiquelon
+ { 37, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 220,8 , 220,8 , 179,8 , 10,17 , 37,5 , 265,14 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {67,72,70}, 233,3 , 7365,45 , 8,5 , 35,5 , 2224,15 , 2239,6 , 2, 0, 1, 6, 7 }, // French/Latin/Switzerland
+ { 37, 7, 207, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {83,89,80}, 236,2 , 7410,51 , 13,5 , 4,0 , 1855,8 , 2245,5 , 0, 0, 6, 5, 6 }, // French/Latin/Syria
+ { 37, 7, 212, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 6484,59 , 13,5 , 4,0 , 1855,8 , 2250,4 , 0, 0, 1, 6, 7 }, // French/Latin/Togo
+ { 37, 7, 216, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {84,78,68}, 238,2 , 7461,51 , 13,5 , 4,0 , 1855,8 , 2254,7 , 3, 0, 7, 5, 6 }, // French/Latin/Tunisia
+ { 37, 7, 229, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {86,85,86}, 210,2 , 7512,51 , 13,5 , 4,0 , 1855,8 , 1706,7 , 0, 0, 1, 6, 7 }, // French/Latin/Vanuatu
+ { 37, 7, 235, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {88,80,70}, 224,4 , 6867,35 , 13,5 , 4,0 , 1855,8 , 2261,16 , 0, 0, 1, 6, 7 }, // French/Latin/WallisAndFutunaIslands
+ { 37, 7, 244, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2277,16 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Barthelemy
+ { 37, 7, 245, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 220,8 , 220,8 , 133,10 , 99,16 , 37,5 , 8,10 , 6201,63 , 6264,85 , 134,24 , 6201,63 , 6264,85 , 134,24 , 2891,35 , 2926,52 , 2978,14 , 2891,35 , 2926,52 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 1855,8 , 2293,31 , 2, 1, 1, 6, 7 }, // French/Latin/Saint Martin
+ { 39, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 228,11 , 239,10 , 133,10 , 10,17 , 37,5 , 8,10 , 6349,61 , 6410,142 , 6552,36 , 6349,61 , 6410,142 , 6552,36 , 2992,28 , 3020,69 , 3089,14 , 2992,28 , 3020,69 , 3089,14 , 0,2 , 0,2 , {71,66,80}, 125,1 , 7563,22 , 4,4 , 4,0 , 2324,8 , 2332,22 , 2, 1, 1, 6, 7 }, // Gaelic/Latin/UnitedKingdom
+ { 40, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 82,17 , 37,5 , 8,10 , 6588,48 , 6636,87 , 6723,24 , 6747,48 , 6795,87 , 6723,24 , 3103,28 , 3131,49 , 3180,14 , 3194,28 , 3222,49 , 3180,14 , 93,4 , 91,4 , {69,85,82}, 20,1 , 3687,20 , 4,4 , 4,0 , 2354,6 , 2360,6 , 2, 1, 1, 6, 7 }, // Galician/Latin/Spain
+ { 41, 15, 81, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 171, 187, 0,6 , 0,6 , 256,8 , 256,8 , 179,8 , 619,19 , 37,5 , 8,10 , 6882,48 , 6930,99 , 7029,24 , 6882,48 , 6930,99 , 7029,24 , 3271,28 , 3299,62 , 3361,14 , 3271,28 , 3299,62 , 3361,14 , 100,5 , 98,7 , {71,69,76}, 0,0 , 7585,43 , 13,5 , 4,0 , 2366,7 , 2373,10 , 2, 1, 1, 6, 7 }, // Georgian/Georgian/Georgia
+ { 42, 7, 82, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 7101,83 , 134,24 , 7184,59 , 7101,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {69,85,82}, 20,1 , 7628,19 , 13,5 , 4,0 , 2383,7 , 2390,11 , 2, 1, 1, 6, 7 }, // German/Latin/Germany
+ { 42, 7, 14, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 638,19 , 37,5 , 8,10 , 7243,48 , 7291,83 , 134,24 , 7374,59 , 7291,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {69,85,82}, 20,1 , 7628,19 , 8,5 , 4,0 , 2401,24 , 2425,10 , 2, 1, 1, 6, 7 }, // German/Latin/Austria
+ { 42, 7, 21, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 7101,83 , 134,24 , 7184,59 , 7101,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {69,85,82}, 20,1 , 7628,19 , 13,5 , 4,0 , 2383,7 , 2435,7 , 2, 1, 1, 6, 7 }, // German/Latin/Belgium
+ { 42, 7, 123, 46, 39, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 7101,83 , 134,24 , 7184,59 , 7101,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {67,72,70}, 0,0 , 7647,58 , 8,5 , 4,0 , 2383,7 , 2442,13 , 2, 0, 1, 6, 7 }, // German/Latin/Liechtenstein
+ { 42, 7, 125, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 7101,83 , 134,24 , 7184,59 , 7101,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {69,85,82}, 20,1 , 7628,19 , 13,5 , 4,0 , 2383,7 , 2455,9 , 2, 1, 1, 6, 7 }, // German/Latin/Luxembourg
+ { 42, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 7101,83 , 134,24 , 7184,59 , 7101,83 , 134,24 , 3375,21 , 3396,60 , 3456,14 , 3470,28 , 3396,60 , 3456,14 , 105,5 , 105,6 , {67,72,70}, 233,3 , 7647,58 , 8,5 , 35,5 , 2464,21 , 2485,7 , 2, 0, 1, 6, 7 }, // German/Latin/Switzerland
+ { 43, 16, 85, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 34, 34, 0,6 , 0,6 , 273,9 , 273,9 , 294,6 , 10,17 , 18,7 , 25,12 , 7433,50 , 7483,115 , 7598,24 , 7622,50 , 7672,115 , 7598,24 , 3498,28 , 3526,55 , 3581,14 , 3498,28 , 3526,55 , 3581,14 , 110,4 , 111,4 , {69,85,82}, 20,1 , 7705,19 , 13,5 , 4,0 , 2492,8 , 2500,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Greece
+ { 43, 16, 56, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 34, 34, 0,6 , 0,6 , 273,9 , 273,9 , 294,6 , 10,17 , 18,7 , 25,12 , 7433,50 , 7483,115 , 7598,24 , 7622,50 , 7672,115 , 7598,24 , 3498,28 , 3526,55 , 3581,14 , 3498,28 , 3526,55 , 3581,14 , 110,4 , 111,4 , {69,85,82}, 20,1 , 7705,19 , 4,4 , 4,0 , 2492,8 , 2506,6 , 2, 1, 1, 6, 7 }, // Greek/Greek/Cyprus
+ { 44, 7, 86, 44, 46, 59, 37, 48, 8722, 43, 101, 187, 171, 8250, 8249, 0,6 , 0,6 , 282,11 , 282,11 , 72,10 , 82,17 , 18,7 , 25,12 , 4913,48 , 7787,96 , 134,24 , 4913,48 , 7787,96 , 134,24 , 3595,28 , 3623,98 , 3721,14 , 3595,28 , 3623,98 , 3721,14 , 0,2 , 0,2 , {68,75,75}, 163,2 , 7724,62 , 4,4 , 30,5 , 2512,11 , 2523,16 , 2, 1, 1, 6, 7 }, // Greenlandic/Latin/Greenland
+ { 46, 17, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 293,9 , 293,9 , 657,7 , 214,18 , 279,8 , 287,13 , 7883,64 , 7947,87 , 8034,31 , 8065,67 , 7947,87 , 8034,31 , 3735,32 , 3767,53 , 3820,19 , 3735,32 , 3767,53 , 3820,19 , 0,2 , 0,2 , {73,78,82}, 129,1 , 7786,46 , 4,4 , 4,0 , 2539,7 , 2546,4 , 2, 1, 7, 7, 7 }, // Gujarati/Gujarati/India
+ { 47, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 294,6 , 214,18 , 37,5 , 8,10 , 8132,48 , 8180,85 , 8265,24 , 8132,48 , 8180,85 , 8265,24 , 3839,21 , 3860,52 , 3912,14 , 3839,21 , 3860,52 , 3912,14 , 0,2 , 0,2 , {78,71,78}, 190,1 , 7832,12 , 8,5 , 4,0 , 2550,5 , 2555,8 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Nigeria
+ { 47, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 294,6 , 214,18 , 37,5 , 8,10 , 8132,48 , 8180,85 , 8265,24 , 8132,48 , 8180,85 , 8265,24 , 3839,21 , 3860,52 , 3912,14 , 3839,21 , 3860,52 , 3912,14 , 0,2 , 0,2 , {71,72,83}, 178,3 , 0,7 , 8,5 , 4,0 , 2550,5 , 2563,4 , 2, 1, 1, 6, 7 }, // Hausa/Latin/Ghana
+ { 47, 7, 156, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 294,6 , 214,18 , 37,5 , 8,10 , 8132,48 , 8180,85 , 8265,24 , 8132,48 , 8180,85 , 8265,24 , 3839,21 , 3860,52 , 3912,14 , 3839,21 , 3860,52 , 3912,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 7844,36 , 8,5 , 4,0 , 2550,5 , 2567,5 , 0, 0, 1, 6, 7 }, // Hausa/Latin/Niger
+ { 48, 18, 105, 46, 44, 59, 37, 48, 45, 43, 101, 1524, 1524, 1523, 1523, 0,6 , 0,6 , 302,6 , 302,6 , 27,8 , 664,18 , 37,5 , 8,10 , 8289,58 , 8347,72 , 158,27 , 8419,48 , 8347,72 , 158,27 , 3926,46 , 3972,65 , 4037,21 , 3926,46 , 3972,65 , 4037,21 , 114,6 , 115,5 , {73,76,83}, 54,1 , 7880,54 , 13,5 , 4,0 , 2572,5 , 2577,5 , 2, 1, 7, 5, 6 }, // Hebrew/Hebrew/Israel
+ { 49, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 308,9 , 317,8 , 682,6 , 10,17 , 18,7 , 25,12 , 8467,54 , 8521,73 , 8594,30 , 8467,54 , 8521,73 , 8594,30 , 4058,32 , 4090,53 , 4143,19 , 4058,32 , 4090,53 , 4143,19 , 120,9 , 120,7 , {73,78,82}, 129,1 , 7934,42 , 4,4 , 4,0 , 2582,5 , 2587,4 , 2, 1, 7, 7, 7 }, // Hindi/Devanagari/India
+ { 50, 7, 98, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 187, 171, 0,6 , 0,6 , 325,8 , 325,8 , 688,13 , 701,19 , 42,4 , 125,9 , 8624,64 , 8688,98 , 8786,25 , 8624,64 , 8688,98 , 8786,25 , 4162,19 , 4181,52 , 4233,17 , 4162,19 , 4181,52 , 4233,17 , 129,3 , 127,3 , {72,85,70}, 240,2 , 7976,46 , 13,5 , 4,0 , 2591,6 , 2597,12 , 0, 0, 1, 6, 7 }, // Hungarian/Latin/Hungary
+ { 51, 7, 99, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 185,8 , 185,8 , 603,8 , 585,18 , 37,5 , 8,10 , 8811,59 , 8870,82 , 8952,24 , 8811,59 , 8870,82 , 8952,24 , 4250,35 , 4285,81 , 4366,14 , 4250,35 , 4285,81 , 4366,14 , 132,4 , 130,4 , {73,83,75}, 163,2 , 8022,49 , 13,5 , 4,0 , 2609,8 , 2617,6 , 0, 0, 1, 6, 7 }, // Icelandic/Latin/Iceland
+ { 52, 7, 101, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 333,10 , 343,9 , 27,8 , 115,18 , 134,5 , 139,10 , 8976,48 , 9024,87 , 134,24 , 8976,48 , 9024,87 , 134,24 , 4380,28 , 4408,43 , 4451,14 , 4380,28 , 4408,43 , 4451,14 , 0,2 , 0,2 , {73,68,82}, 242,2 , 8071,39 , 4,4 , 4,0 , 2623,16 , 2639,9 , 0, 0, 7, 6, 7 }, // Indonesian/Latin/Indonesia
+ { 53, 7, 74, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 376,8 , 384,18 , 37,5 , 8,10 , 9111,48 , 9159,93 , 158,27 , 9111,48 , 9159,93 , 158,27 , 4465,28 , 4493,57 , 85,14 , 4465,28 , 4493,57 , 85,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 8110,12 , 8,5 , 4,0 , 2648,11 , 2659,7 , 2, 1, 1, 6, 7 }, // Interlingua/Latin/France
+ { 57, 7, 104, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 99,16 , 37,5 , 8,10 , 9252,62 , 9314,107 , 9421,24 , 9252,62 , 9314,107 , 9421,24 , 4550,37 , 4587,75 , 4662,14 , 4550,37 , 4587,75 , 4662,14 , 93,4 , 91,4 , {69,85,82}, 20,1 , 8122,11 , 4,4 , 4,0 , 2666,7 , 2673,4 , 2, 1, 7, 6, 7 }, // Irish/Latin/Ireland
+ { 58, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 352,8 , 249,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9445,48 , 9493,94 , 9587,24 , 9445,48 , 9611,94 , 9587,24 , 4676,28 , 4704,57 , 4761,14 , 4676,28 , 4775,57 , 4761,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 179,19 , 13,5 , 4,0 , 2677,8 , 2685,6 , 2, 1, 1, 6, 7 }, // Italian/Latin/Italy
+ { 58, 7, 184, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 352,8 , 249,7 , 27,8 , 99,16 , 37,5 , 8,10 , 9445,48 , 9493,94 , 9587,24 , 9445,48 , 9611,94 , 9587,24 , 4676,28 , 4704,57 , 4761,14 , 4676,28 , 4775,57 , 4761,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 179,19 , 13,5 , 4,0 , 2677,8 , 2691,10 , 2, 1, 1, 6, 7 }, // Italian/Latin/SanMarino
+ { 58, 7, 206, 46, 39, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 352,8 , 249,7 , 179,8 , 10,17 , 37,5 , 265,14 , 9445,48 , 9493,94 , 9587,24 , 9445,48 , 9611,94 , 9587,24 , 4676,28 , 4704,57 , 4761,14 , 4676,28 , 4775,57 , 4761,14 , 0,2 , 0,2 , {67,72,70}, 233,3 , 8133,53 , 8,5 , 35,5 , 2677,8 , 2701,8 , 2, 0, 1, 6, 7 }, // Italian/Latin/Switzerland
+ { 59, 19, 108, 46, 44, 59, 37, 48, 45, 43, 101, 12300, 12301, 12302, 12303, 168,5 , 168,5 , 168,5 , 168,5 , 575,10 , 444,13 , 42,4 , 300,10 , 4318,39 , 4318,39 , 158,27 , 4318,39 , 4318,39 , 158,27 , 4832,14 , 4846,28 , 4832,14 , 4832,14 , 4846,28 , 4832,14 , 136,2 , 134,2 , {74,80,89}, 149,1 , 8186,11 , 4,4 , 4,0 , 2709,3 , 2712,2 , 0, 0, 7, 6, 7 }, // Japanese/Japanese/Japan
+ { 61, 21, 100, 46, 44, 59, 37, 48, 45, 43, 3208, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 360,12 , 0,6 , 682,6 , 232,17 , 279,8 , 287,13 , 9705,65 , 9770,86 , 9856,31 , 9705,65 , 9770,86 , 9856,31 , 4874,32 , 4906,53 , 4959,19 , 4978,28 , 4906,53 , 4959,19 , 0,2 , 0,2 , {73,78,82}, 129,1 , 8197,20 , 4,4 , 4,0 , 2714,5 , 2719,4 , 2, 1, 7, 7, 7 }, // Kannada/Kannada/India
+ { 62, 1, 100, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 560,6 , 35,18 , 18,7 , 25,12 , 9887,72 , 9887,72 , 9959,24 , 9887,72 , 9887,72 , 9959,24 , 5006,54 , 5060,56 , 5116,14 , 5006,54 , 5060,56 , 5116,14 , 0,2 , 0,2 , {73,78,82}, 129,1 , 8217,23 , 8,5 , 4,0 , 2723,5 , 2728,10 , 2, 1, 7, 7, 7 }, // Kashmiri/Arabic/India
+ { 63, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 720,22 , 37,5 , 8,10 , 9983,61 , 10044,83 , 158,27 , 9983,61 , 10044,83 , 158,27 , 5130,28 , 5158,55 , 5213,14 , 5130,28 , 5158,55 , 5213,14 , 138,11 , 136,12 , {75,90,84}, 244,1 , 8240,24 , 13,5 , 4,0 , 2738,10 , 2748,9 , 2, 1, 1, 6, 7 }, // Kazakh/Cyrillic/Kazakhstan
+ { 64, 7, 179, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 376,8 , 384,18 , 37,5 , 8,10 , 10127,60 , 10187,101 , 158,27 , 10127,60 , 10187,101 , 158,27 , 5227,35 , 5262,84 , 85,14 , 5227,35 , 5262,84 , 85,14 , 0,2 , 0,2 , {82,87,70}, 192,2 , 0,7 , 8,5 , 4,0 , 2757,11 , 1435,6 , 0, 0, 1, 6, 7 }, // Kinyarwanda/Latin/Rwanda
+ { 65, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 372,10 , 372,10 , 179,8 , 742,23 , 37,5 , 8,10 , 10288,59 , 10347,80 , 10427,24 , 10288,59 , 10347,80 , 10427,24 , 5346,28 , 5374,57 , 5431,14 , 5445,21 , 5346,28 , 5431,14 , 149,13 , 148,14 , {75,71,83}, 245,3 , 8264,52 , 13,5 , 4,0 , 2768,8 , 2776,10 , 2, 1, 1, 6, 7 }, // Kirghiz/Cyrillic/Kyrgyzstan
+ { 66, 22, 114, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 382,7 , 382,7 , 765,9 , 774,16 , 310,7 , 317,13 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 5466,14 , 5480,28 , 5466,14 , 5466,14 , 5480,28 , 5466,14 , 162,2 , 162,2 , {75,82,87}, 248,1 , 8316,13 , 4,4 , 40,6 , 2786,3 , 2789,4 , 0, 0, 7, 6, 7 }, // Korean/Korean/SouthKorea
+ { 66, 22, 113, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 382,7 , 382,7 , 765,9 , 774,16 , 310,7 , 317,13 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 10451,39 , 5466,14 , 5480,28 , 5466,14 , 5466,14 , 5480,28 , 5466,14 , 162,2 , 162,2 , {75,80,87}, 0,0 , 8329,23 , 4,4 , 40,6 , 2786,3 , 2793,14 , 0, 0, 1, 6, 7 }, // Korean/Korean/NorthKorea
+ { 68, 7, 35, 44, 46, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 10490,60 , 10550,106 , 158,27 , 10490,60 , 10550,106 , 158,27 , 5508,34 , 5542,89 , 85,14 , 5508,34 , 5542,89 , 85,14 , 164,5 , 164,5 , {66,73,70}, 217,3 , 8352,27 , 0,4 , 4,0 , 2807,8 , 2815,8 , 0, 0, 1, 6, 7 }, // Rundi/Latin/Burundi
+ { 69, 23, 117, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 389,9 , 408,8 , 790,19 , 42,4 , 330,24 , 10656,61 , 10717,75 , 158,27 , 10656,61 , 10717,75 , 158,27 , 5631,57 , 5631,57 , 5688,18 , 5631,57 , 5631,57 , 1733,14 , 169,8 , 169,8 , {76,65,75}, 249,1 , 8379,14 , 4,4 , 35,5 , 2823,3 , 2823,3 , 0, 0, 7, 6, 7 }, // Lao/Lao/Laos
+ { 71, 7, 118, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 398,8 , 398,8 , 179,8 , 809,26 , 37,5 , 8,10 , 10792,65 , 10857,101 , 134,24 , 10958,65 , 11023,101 , 134,24 , 5706,21 , 5727,72 , 5799,14 , 5706,21 , 5813,72 , 5799,14 , 177,14 , 177,11 , {69,85,82}, 20,1 , 8393,23 , 4,4 , 40,6 , 2826,8 , 2834,7 , 2, 1, 1, 6, 7 }, // Latvian/Latin/Latvia
+ { 72, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 406,9 , 406,9 , 408,8 , 99,16 , 37,5 , 8,10 , 11124,48 , 11172,203 , 11375,24 , 11124,48 , 11172,203 , 11375,24 , 5885,28 , 5913,100 , 6013,14 , 5885,28 , 5913,100 , 6013,14 , 191,8 , 188,6 , {67,68,70}, 222,2 , 8416,23 , 13,5 , 4,0 , 2841,7 , 2848,29 , 2, 1, 1, 6, 7 }, // Lingala/Latin/CongoKinshasa
+ { 72, 7, 6, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 406,9 , 406,9 , 408,8 , 99,16 , 37,5 , 8,10 , 11124,48 , 11172,203 , 11375,24 , 11124,48 , 11172,203 , 11375,24 , 5885,28 , 5913,100 , 6013,14 , 5885,28 , 5913,100 , 6013,14 , 191,8 , 188,6 , {65,79,65}, 250,2 , 8439,23 , 13,5 , 4,0 , 2841,7 , 2877,6 , 2, 1, 1, 6, 7 }, // Lingala/Latin/Angola
+ { 72, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 406,9 , 406,9 , 408,8 , 99,16 , 37,5 , 8,10 , 11124,48 , 11172,203 , 11375,24 , 11124,48 , 11172,203 , 11375,24 , 5885,28 , 5913,100 , 6013,14 , 5885,28 , 5913,100 , 6013,14 , 191,8 , 188,6 , {88,65,70}, 38,4 , 8462,23 , 13,5 , 4,0 , 2841,7 , 2883,26 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CentralAfricanRepublic
+ { 72, 7, 50, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 406,9 , 406,9 , 408,8 , 99,16 , 37,5 , 8,10 , 11124,48 , 11172,203 , 11375,24 , 11124,48 , 11172,203 , 11375,24 , 5885,28 , 5913,100 , 6013,14 , 5885,28 , 5913,100 , 6013,14 , 191,8 , 188,6 , {88,65,70}, 38,4 , 8462,23 , 13,5 , 4,0 , 2841,7 , 2909,5 , 0, 0, 1, 6, 7 }, // Lingala/Latin/CongoBrazzaville
+ { 73, 7, 124, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8222, 8220, 0,6 , 0,6 , 415,8 , 415,8 , 72,10 , 835,27 , 37,5 , 8,10 , 11399,70 , 11469,96 , 11565,24 , 11399,70 , 11469,96 , 11565,24 , 6027,21 , 6048,89 , 6137,14 , 6027,21 , 6048,89 , 6137,14 , 199,9 , 194,6 , {76,84,76}, 252,2 , 8485,75 , 13,5 , 4,0 , 2914,8 , 2922,7 , 2, 1, 1, 6, 7 }, // Lithuanian/Latin/Lithuania
+ { 74, 2, 127, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 862,7 , 869,23 , 37,5 , 8,10 , 11589,61 , 11650,85 , 11735,24 , 11589,61 , 11650,85 , 11735,24 , 6151,34 , 6185,54 , 1514,14 , 6151,34 , 6185,54 , 1514,14 , 208,10 , 200,8 , {77,75,68}, 254,3 , 8560,55 , 8,5 , 4,0 , 2929,10 , 2939,10 , 2, 1, 1, 6, 7 }, // Macedonian/Cyrillic/Macedonia
+ { 75, 7, 128, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 11759,48 , 11807,92 , 134,24 , 11759,48 , 11807,92 , 134,24 , 6239,34 , 6273,60 , 6333,14 , 6239,34 , 6273,60 , 6333,14 , 0,2 , 0,2 , {77,71,65}, 181,2 , 8615,13 , 4,4 , 4,0 , 2949,8 , 2957,12 , 0, 0, 1, 6, 7 }, // Malagasy/Latin/Madagascar
+ { 76, 7, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 333,10 , 343,9 , 553,7 , 10,17 , 18,7 , 25,12 , 11899,48 , 11947,82 , 12029,24 , 11899,48 , 11947,82 , 12029,24 , 6347,28 , 6375,43 , 6418,14 , 6347,28 , 6375,43 , 6418,14 , 218,2 , 208,3 , {77,89,82}, 257,2 , 8628,39 , 4,4 , 4,0 , 2969,13 , 2982,8 , 2, 1, 1, 6, 7 }, // Malay/Latin/Malaysia
+ { 76, 7, 32, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 333,10 , 343,9 , 553,7 , 892,12 , 18,7 , 25,12 , 11899,48 , 11947,82 , 12029,24 , 11899,48 , 11947,82 , 12029,24 , 6347,28 , 6375,43 , 6418,14 , 6347,28 , 6375,43 , 6418,14 , 218,2 , 208,3 , {66,78,68}, 12,1 , 8667,31 , 8,5 , 4,0 , 2969,13 , 2990,6 , 2, 1, 1, 6, 7 }, // Malay/Latin/Brunei
+ { 76, 7, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 333,10 , 343,9 , 553,7 , 10,17 , 18,7 , 25,12 , 11899,48 , 11947,82 , 12029,24 , 11899,48 , 11947,82 , 12029,24 , 6347,28 , 6375,43 , 6418,14 , 6347,28 , 6375,43 , 6418,14 , 218,2 , 208,3 , {83,71,68}, 12,1 , 8698,37 , 4,4 , 4,0 , 2969,13 , 2996,9 , 2, 1, 7, 6, 7 }, // Malay/Latin/Singapore
+ { 77, 24, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 423,13 , 436,12 , 27,8 , 904,18 , 18,7 , 25,12 , 12053,62 , 12115,88 , 12203,31 , 12053,62 , 12115,88 , 12203,31 , 6432,41 , 6473,77 , 6550,22 , 6432,41 , 6572,76 , 6550,22 , 0,2 , 0,2 , {73,78,82}, 129,1 , 8735,40 , 0,4 , 4,0 , 3005,6 , 3011,6 , 2, 1, 7, 7, 7 }, // Malayalam/Malayalam/India
+ { 78, 7, 133, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 448,8 , 456,7 , 133,10 , 922,23 , 37,5 , 8,10 , 12234,48 , 12282,86 , 12368,24 , 12234,48 , 12282,86 , 12368,24 , 6648,28 , 6676,63 , 6739,14 , 6648,28 , 6676,63 , 6739,14 , 220,2 , 211,2 , {69,85,82}, 20,1 , 8775,11 , 4,4 , 4,0 , 3017,5 , 1246,5 , 2, 1, 7, 6, 7 }, // Maltese/Latin/Malta
+ { 80, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 463,9 , 463,9 , 294,6 , 214,18 , 18,7 , 25,12 , 12392,66 , 12458,86 , 12544,32 , 12392,66 , 12458,86 , 12544,32 , 6753,32 , 6785,53 , 4143,19 , 6753,32 , 6785,53 , 4143,19 , 222,4 , 213,4 , {73,78,82}, 129,1 , 8786,43 , 4,4 , 4,0 , 3022,5 , 2587,4 , 2, 1, 7, 7, 7 }, // Marathi/Devanagari/India
+ { 82, 2, 143, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 945,32 , 37,5 , 8,10 , 12576,99 , 12675,189 , 158,27 , 12576,99 , 12675,189 , 158,27 , 6838,21 , 6859,43 , 1733,14 , 6838,21 , 6859,43 , 1733,14 , 226,2 , 217,2 , {77,78,84}, 259,1 , 8829,25 , 8,5 , 4,0 , 3027,6 , 3033,6 , 0, 0, 1, 6, 7 }, // Mongolian/Cyrillic/Mongolia
+ { 84, 13, 150, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 472,7 , 0,6 , 472,7 , 472,7 , 72,10 , 330,17 , 37,5 , 8,10 , 12864,85 , 12864,85 , 12949,27 , 12864,85 , 12864,85 , 12949,27 , 6902,33 , 6935,54 , 6989,18 , 6902,33 , 6935,54 , 6989,18 , 228,14 , 219,14 , {78,80,82}, 260,4 , 8854,52 , 4,4 , 4,0 , 3039,6 , 3045,5 , 2, 1, 7, 6, 7 }, // Nepali/Devanagari/Nepal
+ { 84, 13, 100, 46, 44, 59, 37, 2406, 45, 43, 101, 8220, 8221, 8216, 8217, 472,7 , 0,6 , 472,7 , 472,7 , 72,10 , 330,17 , 37,5 , 8,10 , 12864,85 , 12864,85 , 12949,27 , 12864,85 , 12976,80 , 12949,27 , 6902,33 , 6935,54 , 6989,18 , 6902,33 , 7007,54 , 6989,18 , 120,9 , 120,7 , {73,78,82}, 129,1 , 8906,49 , 4,4 , 4,0 , 3039,6 , 2587,4 , 2, 1, 7, 7, 7 }, // Nepali/Devanagari/India
+ { 85, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 179,8 , 505,17 , 134,5 , 139,10 , 5743,48 , 13056,83 , 134,24 , 13139,59 , 13056,83 , 134,24 , 7061,28 , 2166,51 , 2217,14 , 2231,35 , 2166,51 , 2217,14 , 93,4 , 91,4 , {78,79,75}, 163,2 , 8955,44 , 8,5 , 4,0 , 3050,12 , 3062,5 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/Norway
+ { 85, 7, 203, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 179,8 , 505,17 , 134,5 , 139,10 , 5743,48 , 13056,83 , 134,24 , 13139,59 , 13056,83 , 134,24 , 7061,28 , 2166,51 , 2217,14 , 2231,35 , 2166,51 , 2217,14 , 93,4 , 91,4 , {78,79,75}, 163,2 , 8955,44 , 8,5 , 4,0 , 3050,12 , 3067,21 , 2, 1, 1, 6, 7 }, // NorwegianBokmal/Latin/SvalbardAndJanMayenIslands
+ { 87, 26, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 682,6 , 10,17 , 18,7 , 25,12 , 13198,89 , 13198,89 , 13287,32 , 13198,89 , 13198,89 , 13287,32 , 7089,33 , 7122,54 , 7176,18 , 7089,33 , 7122,54 , 7176,18 , 91,2 , 89,2 , {73,78,82}, 129,1 , 8999,11 , 8,5 , 4,0 , 3088,5 , 3093,4 , 2, 1, 7, 7, 7 }, // Oriya/Oriya/India
+ { 88, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 171,8 , 977,20 , 42,4 , 354,11 , 13319,68 , 13319,68 , 158,27 , 13319,68 , 13319,68 , 158,27 , 7194,49 , 7194,49 , 85,14 , 7194,49 , 7194,49 , 85,14 , 242,4 , 233,4 , {65,70,78}, 264,1 , 9010,13 , 13,5 , 4,0 , 3097,4 , 3101,9 , 0, 0, 6, 4, 5 }, // Pashto/Arabic/Afghanistan
+ { 89, 1, 102, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 479,7 , 479,7 , 52,8 , 66,7 , 171,8 , 99,16 , 42,4 , 354,11 , 13387,70 , 13387,70 , 13457,24 , 13481,74 , 13481,74 , 13457,24 , 7194,49 , 7194,49 , 7243,14 , 7194,49 , 7194,49 , 7243,14 , 246,9 , 237,8 , {73,82,82}, 265,4 , 9023,37 , 46,5 , 4,0 , 3110,5 , 3115,5 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Iran
+ { 89, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 171, 187, 8249, 8250, 479,7 , 479,7 , 52,8 , 66,7 , 171,8 , 99,16 , 42,4 , 354,11 , 13387,70 , 13387,70 , 13555,24 , 13579,64 , 13643,68 , 13457,24 , 7194,49 , 7194,49 , 7243,14 , 7194,49 , 7194,49 , 7243,14 , 246,9 , 237,8 , {65,70,78}, 264,1 , 9060,55 , 46,5 , 4,0 , 3120,3 , 3101,9 , 0, 0, 6, 4, 5 }, // Persian/Arabic/Afghanistan
+ { 90, 7, 172, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 161,7 , 161,7 , 997,10 , 10,17 , 37,5 , 8,10 , 13711,48 , 13759,97 , 13856,24 , 13711,48 , 13880,99 , 13856,24 , 7257,34 , 7291,59 , 7350,14 , 7257,34 , 7291,59 , 7350,14 , 0,2 , 0,2 , {80,76,78}, 269,2 , 9115,77 , 13,5 , 4,0 , 3123,6 , 3129,6 , 2, 1, 1, 6, 7 }, // Polish/Latin/Poland
+ { 91, 7, 30, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 13979,48 , 14027,89 , 134,24 , 13979,48 , 14027,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 0,2 , 0,2 , {66,82,76}, 271,2 , 9192,54 , 4,4 , 4,0 , 3135,19 , 3154,6 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Brazil
+ { 91, 7, 6, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {65,79,65}, 250,2 , 9246,54 , 13,5 , 4,0 , 3160,9 , 3169,6 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Angola
+ { 91, 7, 39, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {67,86,69}, 0,0 , 9300,69 , 13,5 , 4,0 , 3160,9 , 3175,10 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/CapeVerde
+ { 91, 7, 62, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {85,83,68}, 187,3 , 9369,81 , 13,5 , 4,0 , 3160,9 , 3185,11 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/EastTimor
+ { 91, 7, 92, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {88,79,70}, 214,3 , 9450,65 , 13,5 , 4,0 , 3160,9 , 3196,12 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/GuineaBissau
+ { 91, 7, 126, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {77,79,80}, 150,4 , 9515,53 , 13,5 , 4,0 , 3160,9 , 3208,19 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Macau
+ { 91, 7, 146, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {77,90,78}, 273,3 , 9568,72 , 13,5 , 4,0 , 3160,9 , 3227,10 , 2, 1, 7, 6, 7 }, // Portuguese/Latin/Mozambique
+ { 91, 7, 173, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {69,85,82}, 20,1 , 9640,20 , 13,5 , 4,0 , 3237,17 , 3254,8 , 2, 1, 1, 6, 7 }, // Portuguese/Latin/Portugal
+ { 91, 7, 185, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 14116,48 , 14164,89 , 134,24 , 14116,48 , 14164,89 , 134,24 , 7364,28 , 7392,79 , 7471,14 , 7364,28 , 7392,79 , 7471,14 , 255,8 , 245,8 , {83,84,68}, 276,2 , 9660,92 , 13,5 , 4,0 , 3160,9 , 3262,19 , 0, 0, 1, 6, 7 }, // Portuguese/Latin/SaoTomeAndPrincipe
+ { 92, 4, 100, 46, 44, 59, 37, 48, 45, 43, 101, 39, 39, 34, 34, 0,6 , 0,6 , 486,9 , 486,9 , 294,6 , 10,17 , 18,7 , 25,12 , 14253,68 , 14253,68 , 14321,28 , 14253,68 , 14253,68 , 14321,28 , 7485,39 , 7524,53 , 7577,23 , 7485,39 , 7524,53 , 7577,23 , 0,2 , 0,2 , {73,78,82}, 129,1 , 9752,37 , 4,4 , 4,0 , 3281,6 , 3287,4 , 2, 1, 7, 7, 7 }, // Punjabi/Gurmukhi/India
+ { 92, 1, 163, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 115,18 , 18,7 , 25,12 , 14349,67 , 14349,67 , 158,27 , 14349,67 , 14349,67 , 158,27 , 7600,37 , 7600,37 , 85,14 , 7600,37 , 7600,37 , 85,14 , 0,2 , 0,2 , {80,75,82}, 278,1 , 9789,13 , 8,5 , 4,0 , 3291,5 , 3296,6 , 0, 0, 7, 6, 7 }, // Punjabi/Arabic/Pakistan
+ { 94, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 545,8 , 1034,28 , 37,5 , 8,10 , 14416,67 , 14483,92 , 14575,24 , 14416,67 , 14483,92 , 14575,24 , 7637,23 , 7660,56 , 7716,14 , 7637,23 , 7660,56 , 7716,14 , 91,2 , 253,2 , {67,72,70}, 233,3 , 9802,20 , 13,5 , 4,0 , 3302,9 , 3311,6 , 2, 0, 1, 6, 7 }, // Romansh/Latin/Switzerland
+ { 95, 7, 177, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 495,8 , 495,8 , 997,10 , 10,17 , 37,5 , 8,10 , 14599,60 , 14659,98 , 14757,24 , 14599,60 , 14659,98 , 14757,24 , 7730,28 , 7758,48 , 2978,14 , 7730,28 , 7758,48 , 2978,14 , 93,4 , 91,4 , {82,79,78}, 0,0 , 9822,57 , 13,5 , 4,0 , 3317,6 , 3323,7 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Romania
+ { 95, 7, 141, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 495,8 , 495,8 , 997,10 , 10,17 , 37,5 , 8,10 , 14599,60 , 14659,98 , 14757,24 , 14599,60 , 14659,98 , 14757,24 , 7730,28 , 7758,48 , 2978,14 , 7730,28 , 7758,48 , 2978,14 , 93,4 , 91,4 , {77,68,76}, 279,1 , 9879,69 , 13,5 , 4,0 , 3317,6 , 3330,17 , 2, 1, 1, 6, 7 }, // Romanian/Latin/Moldova
+ { 96, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 42,4 , 125,9 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {82,85,66}, 280,4 , 9948,73 , 13,5 , 4,0 , 3347,7 , 3354,6 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Russia
+ { 96, 2, 20, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 42,4 , 125,9 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {66,89,82}, 146,2 , 10021,77 , 13,5 , 4,0 , 3347,7 , 491,8 , 0, 0, 7, 6, 7 }, // Russian/Cyrillic/Belarus
+ { 96, 2, 110, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 42,4 , 125,9 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {75,90,84}, 244,1 , 10098,68 , 13,5 , 4,0 , 3347,7 , 3360,9 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kazakhstan
+ { 96, 2, 116, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 42,4 , 125,9 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {75,71,83}, 245,3 , 10166,66 , 13,5 , 4,0 , 3347,7 , 3369,8 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Kyrgyzstan
+ { 96, 2, 141, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 42,4 , 125,9 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {77,68,76}, 279,1 , 10232,65 , 13,5 , 4,0 , 3347,7 , 3377,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Moldova
+ { 96, 2, 222, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 125,7 , 125,7 , 179,8 , 354,22 , 37,5 , 8,10 , 14781,62 , 14843,80 , 10427,24 , 14923,63 , 14986,82 , 10427,24 , 7806,21 , 7827,62 , 7889,14 , 7903,21 , 7924,62 , 7903,21 , 263,10 , 255,13 , {85,65,72}, 284,1 , 10297,75 , 13,5 , 4,0 , 3347,7 , 3384,7 , 2, 1, 1, 6, 7 }, // Russian/Cyrillic/Ukraine
+ { 98, 7, 41, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 15068,48 , 15116,91 , 15207,24 , 15068,48 , 15116,91 , 15207,24 , 7986,28 , 8014,66 , 8080,14 , 7986,28 , 8014,66 , 8080,14 , 273,2 , 268,2 , {88,65,70}, 38,4 , 10372,25 , 4,4 , 35,5 , 3391,5 , 3396,22 , 0, 0, 1, 6, 7 }, // Sango/Latin/CentralAfricanRepublic
+ { 100, 2, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 125,7 , 125,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15231,48 , 15279,81 , 11735,24 , 15231,48 , 15279,81 , 11735,24 , 8094,28 , 8122,52 , 8174,14 , 8094,28 , 8122,52 , 8174,14 , 275,9 , 270,7 , {82,83,68}, 285,4 , 10397,58 , 13,5 , 4,0 , 3418,6 , 3424,6 , 0, 0, 1, 6, 7 }, // Serbian/Cyrillic/Serbia
+ { 100, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15360,48 , 15408,81 , 15489,24 , 15360,48 , 15408,81 , 15489,24 , 8188,28 , 8216,54 , 2026,14 , 8188,28 , 8216,54 , 2026,14 , 284,9 , 277,7 , {66,65,77}, 159,2 , 10455,152 , 13,5 , 4,0 , 3430,6 , 620,19 , 2, 1, 1, 6, 7 }, // Serbian/Latin/BosniaAndHerzegowina
+ { 100, 7, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15360,48 , 15408,81 , 15489,24 , 15360,48 , 15408,81 , 15489,24 , 8188,28 , 8216,54 , 2026,14 , 8188,28 , 8216,54 , 2026,14 , 284,9 , 277,7 , {69,85,82}, 20,1 , 10607,23 , 13,5 , 4,0 , 3430,6 , 3436,9 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Montenegro
+ { 100, 7, 243, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15360,48 , 15408,81 , 15489,24 , 15360,48 , 15408,81 , 15489,24 , 8188,28 , 8216,54 , 2026,14 , 8188,28 , 8216,54 , 2026,14 , 284,9 , 277,7 , {82,83,68}, 289,4 , 10630,58 , 13,5 , 4,0 , 3430,6 , 3445,6 , 0, 0, 1, 6, 7 }, // Serbian/Latin/Serbia
+ { 100, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 125,7 , 125,7 , 611,8 , 1062,20 , 37,5 , 365,40 , 15231,48 , 15279,81 , 11735,24 , 15231,48 , 15513,83 , 11735,24 , 8094,28 , 8122,52 , 8174,14 , 8270,28 , 8298,54 , 8174,14 , 275,9 , 270,7 , {66,65,77}, 293,2 , 10688,152 , 13,5 , 4,0 , 3451,6 , 3457,19 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/BosniaAndHerzegowina
+ { 100, 2, 242, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 125,7 , 125,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15231,48 , 15279,81 , 11735,24 , 15231,48 , 15279,81 , 11735,24 , 8094,28 , 8122,52 , 8174,14 , 8094,28 , 8122,52 , 8174,14 , 275,9 , 270,7 , {69,85,82}, 20,1 , 10840,23 , 13,5 , 4,0 , 3418,6 , 3476,9 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Montenegro
+ { 100, 2, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 125,7 , 125,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15231,48 , 15279,81 , 11735,24 , 15231,48 , 15279,81 , 11735,24 , 8094,28 , 8122,52 , 8174,14 , 8094,28 , 8122,52 , 8174,14 , 275,9 , 270,7 , {69,85,82}, 20,1 , 10840,23 , 13,5 , 4,0 , 3418,6 , 3485,6 , 2, 1, 1, 6, 7 }, // Serbian/Cyrillic/Kosovo
+ { 100, 7, 257, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 161,7 , 161,7 , 479,7 , 1062,20 , 134,5 , 139,10 , 15360,48 , 15408,81 , 15489,24 , 15360,48 , 15408,81 , 15489,24 , 8188,28 , 8216,54 , 2026,14 , 8188,28 , 8216,54 , 2026,14 , 284,9 , 277,7 , {69,85,82}, 20,1 , 10607,23 , 13,5 , 4,0 , 3430,6 , 3491,6 , 2, 1, 1, 6, 7 }, // Serbian/Latin/Kosovo
+ { 101, 2, 81, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 503,9 , 503,9 , 179,8 , 1082,23 , 37,5 , 8,10 , 14781,62 , 15596,82 , 10427,24 , 15678,59 , 15737,86 , 10427,24 , 8352,28 , 8380,61 , 8441,14 , 8455,28 , 8483,61 , 8441,14 , 0,2 , 0,2 , {71,69,76}, 0,0 , 10863,17 , 8,5 , 4,0 , 3497,4 , 3501,11 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Georgia
+ { 101, 2, 178, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 503,9 , 503,9 , 179,8 , 1082,23 , 37,5 , 8,10 , 14781,62 , 15596,82 , 10427,24 , 15678,59 , 15737,86 , 10427,24 , 8352,28 , 8380,61 , 8441,14 , 8455,28 , 8483,61 , 8441,14 , 0,2 , 0,2 , {82,85,66}, 280,4 , 10880,17 , 8,5 , 4,0 , 3497,4 , 3512,6 , 2, 1, 1, 6, 7 }, // Ossetic/Cyrillic/Russia
+ { 102, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 15823,48 , 15871,105 , 158,27 , 15823,48 , 15871,105 , 158,27 , 8544,27 , 8571,61 , 85,14 , 8544,27 , 8571,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3518,7 , 0,0 , 2, 1, 7, 6, 7 }, // Southern Sotho/Latin/SouthAfrica
+ { 102, 7, 120, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 15823,48 , 15871,105 , 158,27 , 15823,48 , 15871,105 , 158,27 , 8544,27 , 8571,61 , 85,14 , 8544,27 , 8571,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3518,7 , 0,0 , 2, 1, 1, 6, 7 }, // Southern Sotho/Latin/Lesotho
+ { 103, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 15976,48 , 16024,117 , 158,27 , 15976,48 , 16024,117 , 158,27 , 8632,27 , 8659,64 , 85,14 , 8632,27 , 8659,64 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3525,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/SouthAfrica
+ { 103, 7, 28, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 15976,48 , 16024,117 , 158,27 , 15976,48 , 16024,117 , 158,27 , 8632,27 , 8659,64 , 85,14 , 8632,27 , 8659,64 , 85,14 , 0,2 , 0,2 , {66,87,80}, 176,1 , 0,7 , 4,4 , 4,0 , 3525,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tswana/Latin/Botswana
+ { 104, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 16141,47 , 16188,100 , 16288,24 , 16141,47 , 16188,100 , 16288,24 , 8723,32 , 8755,55 , 8810,14 , 8723,32 , 8755,55 , 8810,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 10897,22 , 4,4 , 4,0 , 3533,8 , 1760,8 , 2, 1, 7, 6, 7 }, // Shona/Latin/Zimbabwe
+ { 106, 32, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 512,9 , 521,8 , 72,10 , 330,17 , 405,7 , 412,12 , 16312,59 , 16371,96 , 16467,32 , 16499,61 , 16371,96 , 16467,32 , 8824,39 , 8863,62 , 8925,19 , 8824,39 , 8863,62 , 8925,19 , 293,5 , 284,4 , {76,75,82}, 295,3 , 10919,24 , 4,4 , 4,0 , 3541,5 , 3546,11 , 2, 1, 1, 6, 7 }, // Sinhala/Sinhala/SriLanka
+ { 107, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 16560,48 , 16608,114 , 158,27 , 16560,48 , 16608,114 , 158,27 , 8944,27 , 8971,68 , 85,14 , 8944,27 , 8971,68 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 3557,7 , 0,0 , 2, 1, 7, 6, 7 }, // Swati/Latin/SouthAfrica
+ { 107, 7, 204, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 16560,48 , 16608,114 , 158,27 , 16560,48 , 16608,114 , 158,27 , 8944,27 , 8971,68 , 85,14 , 8944,27 , 8971,68 , 85,14 , 0,2 , 0,2 , {83,90,76}, 201,1 , 0,7 , 4,4 , 4,0 , 3557,7 , 0,0 , 2, 1, 1, 6, 7 }, // Swati/Latin/Swaziland
+ { 108, 7, 191, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 178,7 , 178,7 , 603,8 , 585,18 , 42,4 , 125,9 , 16722,48 , 16770,82 , 15489,24 , 16722,48 , 16852,89 , 15489,24 , 9039,21 , 9060,52 , 9112,14 , 9039,21 , 9060,52 , 9112,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 10943,26 , 13,5 , 4,0 , 3564,10 , 3574,9 , 2, 1, 1, 6, 7 }, // Slovak/Latin/Slovakia
+ { 109, 7, 192, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 529,8 , 529,8 , 1105,9 , 638,19 , 37,5 , 8,10 , 15360,48 , 16941,86 , 15489,24 , 17027,59 , 16941,86 , 15489,24 , 9126,28 , 9154,52 , 9206,14 , 9220,35 , 9154,52 , 9206,14 , 298,4 , 288,4 , {69,85,82}, 20,1 , 10969,28 , 4,4 , 40,6 , 3583,11 , 3594,9 , 2, 1, 1, 6, 7 }, // Slovenian/Latin/Slovenia
+ { 110, 7, 194, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17086,48 , 17134,189 , 17323,24 , 17086,48 , 17134,189 , 17323,24 , 9255,28 , 9283,47 , 9330,14 , 9255,28 , 9283,47 , 9330,14 , 302,3 , 292,3 , {83,79,83}, 100,1 , 10997,22 , 4,4 , 4,0 , 3603,8 , 3611,10 , 0, 0, 1, 6, 7 }, // Somali/Latin/Somalia
+ { 110, 7, 59, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17086,48 , 17134,189 , 17323,24 , 17086,48 , 17134,189 , 17323,24 , 9255,28 , 9283,47 , 9330,14 , 9255,28 , 9283,47 , 9330,14 , 302,3 , 292,3 , {68,74,70}, 5,3 , 11019,21 , 4,4 , 4,0 , 3603,8 , 3621,7 , 0, 0, 6, 6, 7 }, // Somali/Latin/Djibouti
+ { 110, 7, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17086,48 , 17134,189 , 17323,24 , 17086,48 , 17134,189 , 17323,24 , 9255,28 , 9283,47 , 9330,14 , 9255,28 , 9283,47 , 9330,14 , 302,3 , 292,3 , {69,84,66}, 0,2 , 11040,22 , 4,4 , 4,0 , 3603,8 , 3628,8 , 2, 1, 7, 6, 7 }, // Somali/Latin/Ethiopia
+ { 110, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 17086,48 , 17134,189 , 17323,24 , 17086,48 , 17134,189 , 17323,24 , 9255,28 , 9283,47 , 9330,14 , 9255,28 , 9283,47 , 9330,14 , 302,3 , 292,3 , {75,69,83}, 2,3 , 0,7 , 4,4 , 4,0 , 3603,8 , 3636,7 , 2, 1, 7, 6, 7 }, // Somali/Latin/Kenya
+ { 111, 7, 197, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 3643,17 , 2360,6 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Spain
+ { 111, 7, 10, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 424,14 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {65,82,83}, 12,1 , 11062,51 , 4,4 , 4,0 , 3660,7 , 3667,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Argentina
+ { 111, 7, 26, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {66,79,66}, 298,2 , 11113,35 , 4,4 , 4,0 , 3660,7 , 3676,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Bolivia
+ { 111, 7, 43, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 545,8 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {67,76,80}, 12,1 , 11148,45 , 4,4 , 35,5 , 3660,7 , 3683,5 , 0, 0, 1, 6, 7 }, // Spanish/Latin/Chile
+ { 111, 7, 47, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 553,7 , 1007,27 , 18,7 , 438,14 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {67,79,80}, 12,1 , 11193,54 , 4,4 , 4,0 , 3660,7 , 3688,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Colombia
+ { 111, 7, 52, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {67,82,67}, 300,1 , 11247,67 , 4,4 , 4,0 , 3660,7 , 3696,10 , 0, 0, 1, 6, 7 }, // Spanish/Latin/CostaRica
+ { 111, 7, 55, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {67,85,80}, 12,1 , 11314,42 , 4,4 , 4,0 , 3660,7 , 3706,4 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Cuba
+ { 111, 7, 61, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {68,79,80}, 12,1 , 11356,54 , 4,4 , 4,0 , 3660,7 , 3710,20 , 2, 1, 7, 6, 7 }, // Spanish/Latin/DominicanRepublic
+ { 111, 7, 63, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {85,83,68}, 12,1 , 11410,70 , 4,4 , 35,5 , 3660,7 , 3730,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Ecuador
+ { 111, 7, 65, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {85,83,68}, 12,1 , 11410,70 , 4,4 , 4,0 , 3660,7 , 3737,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/ElSalvador
+ { 111, 7, 66, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {88,65,70}, 38,4 , 11480,53 , 4,4 , 4,0 , 3660,7 , 3748,17 , 0, 0, 1, 6, 7 }, // Spanish/Latin/EquatorialGuinea
+ { 111, 7, 90, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 553,7 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {71,84,81}, 301,1 , 11533,70 , 4,4 , 4,0 , 3660,7 , 3765,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Guatemala
+ { 111, 7, 96, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1114,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {72,78,76}, 279,1 , 11603,60 , 4,4 , 4,0 , 3660,7 , 3774,8 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Honduras
+ { 111, 7, 139, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 27,8 , 1007,27 , 37,5 , 8,10 , 17671,56 , 17582,89 , 17727,29 , 17756,59 , 17582,89 , 17727,29 , 9534,33 , 9467,53 , 9520,14 , 9567,36 , 9467,53 , 9520,14 , 93,4 , 91,4 , {77,88,78}, 12,1 , 11663,48 , 4,4 , 4,0 , 3782,17 , 3799,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Mexico
+ { 111, 7, 155, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {78,73,79}, 302,2 , 11711,69 , 4,4 , 4,0 , 3660,7 , 3805,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Nicaragua
+ { 111, 7, 166, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 1141,8 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {80,65,66}, 304,3 , 11780,54 , 4,4 , 4,0 , 3660,7 , 3814,6 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Panama
+ { 111, 7, 168, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {80,89,71}, 307,1 , 11834,61 , 8,5 , 51,6 , 3660,7 , 3820,8 , 0, 0, 7, 6, 7 }, // Spanish/Latin/Paraguay
+ { 111, 7, 169, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 553,7 , 1007,27 , 42,4 , 452,15 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {80,69,78}, 308,3 , 11895,62 , 4,4 , 4,0 , 3660,7 , 3828,4 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Peru
+ { 111, 7, 170, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {80,72,80}, 191,1 , 11957,48 , 13,5 , 4,0 , 3660,7 , 3832,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Philippines
+ { 111, 7, 174, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 1141,8 , 1007,27 , 18,7 , 25,12 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {85,83,68}, 12,1 , 11410,70 , 4,4 , 4,0 , 3660,7 , 1424,11 , 2, 1, 7, 6, 7 }, // Spanish/Latin/PuertoRico
+ { 111, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 560,6 , 1007,27 , 18,7 , 25,12 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 11410,70 , 4,4 , 4,0 , 3660,7 , 3841,14 , 2, 1, 7, 6, 7 }, // Spanish/Latin/UnitedStates
+ { 111, 7, 227, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {85,89,85}, 12,1 , 12005,48 , 8,5 , 4,0 , 3660,7 , 3855,7 , 2, 1, 1, 6, 7 }, // Spanish/Latin/Uruguay
+ { 111, 7, 231, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {86,69,70}, 311,3 , 12053,64 , 4,4 , 35,5 , 3660,7 , 3862,9 , 2, 1, 7, 6, 7 }, // Spanish/Latin/Venezuela
+ { 111, 7, 238, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 3660,7 , 3871,14 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CanaryIslands
+ { 111, 7, 246, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {0,0,0}, 0,0 , 12117,0 , 4,4 , 4,0 , 3885,18 , 3903,13 , 2, 1, 1, 6, 7 }, // Spanish/Latin/LatinAmericaAndTheCaribbean
+ { 111, 7, 250, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1007,27 , 42,4 , 354,11 , 17347,61 , 17408,89 , 17497,24 , 17521,61 , 17582,89 , 17497,24 , 9344,35 , 9379,53 , 2978,14 , 9432,35 , 9467,53 , 9520,14 , 80,5 , 78,5 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 3660,7 , 3916,15 , 2, 1, 1, 6, 7 }, // Spanish/Latin/CeutaAndMelilla
+ { 113, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 544,9 , 553,8 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 17863,84 , 134,24 , 17815,48 , 17863,84 , 134,24 , 9603,22 , 9625,60 , 9685,14 , 9603,22 , 9625,60 , 9685,14 , 0,2 , 0,2 , {84,90,83}, 202,3 , 12117,27 , 4,4 , 4,0 , 3931,9 , 1586,8 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Tanzania
+ { 113, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 544,9 , 553,8 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 17863,84 , 134,24 , 17815,48 , 17863,84 , 134,24 , 9603,22 , 9625,60 , 9685,14 , 9603,22 , 9625,60 , 9685,14 , 0,2 , 0,2 , {75,69,83}, 2,3 , 12144,24 , 4,4 , 4,0 , 3931,9 , 1188,5 , 2, 1, 7, 6, 7 }, // Swahili/Latin/Kenya
+ { 113, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 544,9 , 553,8 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 17863,84 , 134,24 , 17815,48 , 17863,84 , 134,24 , 9603,22 , 9625,60 , 9685,14 , 9603,22 , 9625,60 , 9685,14 , 0,2 , 0,2 , {85,71,88}, 207,3 , 12168,25 , 4,4 , 4,0 , 3931,9 , 1655,6 , 0, 0, 1, 6, 7 }, // Swahili/Latin/Uganda
+ { 114, 7, 205, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 561,9 , 561,9 , 72,10 , 1149,30 , 37,5 , 467,16 , 17947,48 , 17995,86 , 134,24 , 4913,48 , 18081,86 , 134,24 , 9699,28 , 9727,50 , 2217,14 , 9777,29 , 9806,50 , 2217,14 , 305,2 , 295,2 , {83,69,75}, 163,2 , 12193,45 , 13,5 , 4,0 , 3940,7 , 3947,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Sweden
+ { 114, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 561,9 , 561,9 , 1179,10 , 1149,30 , 37,5 , 467,16 , 17947,48 , 17995,86 , 134,24 , 4913,48 , 18081,86 , 134,24 , 9699,28 , 9727,50 , 2217,14 , 9777,29 , 9806,50 , 2217,14 , 305,2 , 295,2 , {69,85,82}, 20,1 , 12238,19 , 13,5 , 4,0 , 3940,7 , 3954,7 , 2, 1, 1, 6, 7 }, // Swedish/Latin/Finland
+ { 114, 7, 248, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 561,9 , 561,9 , 72,10 , 1149,30 , 37,5 , 467,16 , 17947,48 , 17995,86 , 134,24 , 4913,48 , 18081,86 , 134,24 , 9699,28 , 9727,50 , 2217,14 , 9777,29 , 9806,50 , 2217,14 , 305,2 , 295,2 , {69,85,82}, 20,1 , 12238,19 , 13,5 , 4,0 , 3940,7 , 3961,5 , 2, 1, 1, 6, 7 }, // Swedish/Latin/AlandIslands
+ { 116, 2, 209, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 171, 8222, 0,6 , 0,6 , 0,6 , 0,6 , 376,8 , 384,18 , 37,5 , 8,10 , 18167,48 , 18215,71 , 158,27 , 18167,48 , 18215,71 , 158,27 , 9856,28 , 9884,55 , 85,14 , 9856,28 , 9884,55 , 85,14 , 0,2 , 0,2 , {84,74,83}, 245,3 , 12257,13 , 8,5 , 4,0 , 3966,6 , 3972,10 , 2, 1, 1, 6, 7 }, // Tajik/Cyrillic/Tajikistan
+ { 117, 27, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 570,13 , 570,13 , 682,6 , 214,18 , 18,7 , 25,12 , 18286,58 , 18344,86 , 18430,31 , 18286,58 , 18461,86 , 18430,31 , 9939,20 , 9959,49 , 9939,20 , 9939,20 , 9959,49 , 9939,20 , 307,8 , 297,8 , {73,78,82}, 129,1 , 12270,13 , 8,5 , 4,0 , 3982,5 , 3987,7 , 2, 1, 7, 7, 7 }, // Tamil/Tamil/India
+ { 117, 27, 130, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 570,13 , 570,13 , 682,6 , 214,18 , 18,7 , 25,12 , 18286,58 , 18344,86 , 18430,31 , 18286,58 , 18461,86 , 18430,31 , 9939,20 , 9959,49 , 9939,20 , 9939,20 , 9959,49 , 9939,20 , 307,8 , 297,8 , {77,89,82}, 257,2 , 12283,22 , 8,5 , 4,0 , 3982,5 , 3994,7 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/Malaysia
+ { 117, 27, 190, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 570,13 , 570,13 , 682,6 , 214,18 , 18,7 , 25,12 , 18286,58 , 18344,86 , 18430,31 , 18286,58 , 18461,86 , 18430,31 , 9939,20 , 9959,49 , 9939,20 , 9939,20 , 9959,49 , 9939,20 , 307,8 , 297,8 , {83,71,68}, 12,1 , 12305,24 , 8,5 , 4,0 , 3982,5 , 4001,11 , 2, 1, 7, 6, 7 }, // Tamil/Tamil/Singapore
+ { 117, 27, 198, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 570,13 , 570,13 , 682,6 , 214,18 , 18,7 , 25,12 , 18286,58 , 18344,86 , 18430,31 , 18286,58 , 18461,86 , 18430,31 , 9939,20 , 9959,49 , 9939,20 , 9939,20 , 9959,49 , 9939,20 , 307,8 , 297,8 , {76,75,82}, 314,3 , 12329,20 , 8,5 , 4,0 , 3982,5 , 4012,6 , 2, 1, 1, 6, 7 }, // Tamil/Tamil/SriLanka
+ { 119, 28, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 583,11 , 583,11 , 545,8 , 1189,16 , 18,7 , 25,12 , 18547,66 , 18613,86 , 18699,31 , 18730,62 , 18792,86 , 18699,31 , 10008,32 , 10040,60 , 10100,18 , 10008,32 , 10040,60 , 10100,18 , 0,2 , 0,2 , {73,78,82}, 129,1 , 12349,26 , 4,4 , 4,0 , 4018,6 , 4024,9 , 2, 1, 7, 7, 7 }, // Telugu/Telugu/India
+ { 120, 30, 211, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 594,5 , 594,5 , 599,8 , 607,7 , 294,6 , 1205,19 , 37,5 , 483,28 , 18878,63 , 18941,98 , 18878,63 , 18878,63 , 18941,98 , 18878,63 , 10118,23 , 10141,68 , 10209,16 , 10118,23 , 10141,68 , 10209,16 , 315,10 , 305,10 , {84,72,66}, 317,1 , 12375,19 , 4,4 , 4,0 , 4033,3 , 4033,3 , 2, 1, 7, 6, 7 }, // Thai/Thai/Thailand
+ { 121, 31, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 2880,63 , 19039,158 , 158,27 , 2880,63 , 19039,158 , 158,27 , 10225,49 , 10274,77 , 10351,21 , 10225,49 , 10274,77 , 10372,22 , 325,7 , 315,8 , {67,78,89}, 318,1 , 12394,13 , 8,5 , 4,0 , 4036,8 , 4044,6 , 2, 1, 7, 6, 7 }, // Tibetan/Tibetan/China
+ { 121, 31, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 2880,63 , 19039,158 , 158,27 , 2880,63 , 19039,158 , 158,27 , 10225,49 , 10274,77 , 10351,21 , 10225,49 , 10274,77 , 10372,22 , 325,7 , 315,8 , {73,78,82}, 129,1 , 12407,22 , 8,5 , 4,0 , 4036,8 , 4050,7 , 2, 1, 7, 7, 7 }, // Tibetan/Tibetan/India
+ { 122, 14, 69, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1224,23 , 18,7 , 25,12 , 19197,46 , 19243,62 , 1050,24 , 19197,46 , 19243,62 , 1050,24 , 10394,29 , 10394,29 , 10423,14 , 10394,29 , 10394,29 , 10423,14 , 332,7 , 323,7 , {69,84,66}, 0,2 , 12429,16 , 4,4 , 4,0 , 4057,4 , 108,5 , 2, 1, 7, 6, 7 }, // Tigrinya/Ethiopic/Ethiopia
+ { 122, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1247,23 , 18,7 , 25,12 , 19305,46 , 19351,54 , 1050,24 , 19305,46 , 19351,54 , 1050,24 , 10437,29 , 10437,29 , 10423,14 , 10437,29 , 10437,29 , 10423,14 , 332,7 , 323,7 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4057,4 , 4061,4 , 2, 1, 1, 6, 7 }, // Tigrinya/Ethiopic/Eritrea
+ { 123, 7, 214, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 614,8 , 614,8 , 294,6 , 99,16 , 18,7 , 25,12 , 19405,51 , 19456,87 , 19543,24 , 19405,51 , 19456,87 , 19543,24 , 10466,29 , 10495,60 , 10555,14 , 10466,29 , 10495,60 , 10555,14 , 0,2 , 0,2 , {84,79,80}, 205,2 , 12445,21 , 8,5 , 4,0 , 4065,13 , 1601,5 , 2, 1, 1, 6, 7 }, // Tongan/Latin/Tonga
+ { 124, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 19567,48 , 19615,122 , 158,27 , 19567,48 , 19615,122 , 158,27 , 10569,27 , 10596,72 , 85,14 , 10569,27 , 10596,72 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4078,8 , 0,0 , 2, 1, 7, 6, 7 }, // Tsonga/Latin/SouthAfrica
+ { 125, 7, 217, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 622,8 , 622,8 , 1270,9 , 1189,16 , 37,5 , 8,10 , 19737,48 , 19785,75 , 19860,24 , 19737,48 , 19785,75 , 19860,24 , 10668,28 , 10696,54 , 10750,14 , 10668,28 , 10696,54 , 10750,14 , 339,2 , 330,2 , {84,82,89}, 319,1 , 12466,40 , 13,5 , 4,0 , 4086,6 , 4092,7 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Turkey
+ { 125, 7, 56, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 622,8 , 622,8 , 1270,9 , 1189,16 , 37,5 , 8,10 , 19737,48 , 19785,75 , 19860,24 , 19737,48 , 19785,75 , 19860,24 , 10668,28 , 10696,54 , 10750,14 , 10668,28 , 10696,54 , 10750,14 , 339,2 , 330,2 , {69,85,82}, 20,1 , 7628,19 , 13,5 , 4,0 , 4086,6 , 4099,23 , 2, 1, 1, 6, 7 }, // Turkish/Latin/Cyprus
+ { 129, 2, 222, 44, 160, 59, 37, 48, 45, 43, 1077, 171, 187, 8222, 8220, 0,6 , 0,6 , 630,8 , 630,8 , 179,8 , 1279,22 , 37,5 , 8,10 , 19884,48 , 19932,95 , 20027,24 , 20051,67 , 20118,87 , 20027,24 , 10764,21 , 10785,56 , 10841,14 , 10764,21 , 10855,56 , 10841,14 , 341,2 , 332,2 , {85,65,72}, 284,1 , 12506,49 , 13,5 , 4,0 , 4122,10 , 4132,7 , 2, 1, 1, 6, 7 }, // Ukrainian/Cyrillic/Ukraine
+ { 130, 1, 163, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 638,10 , 648,9 , 294,6 , 153,18 , 18,7 , 25,12 , 20205,68 , 20205,68 , 134,24 , 20205,68 , 20205,68 , 134,24 , 10911,39 , 10911,39 , 85,14 , 10911,39 , 10911,39 , 85,14 , 343,9 , 334,9 , {80,75,82}, 185,2 , 12555,21 , 57,5 , 4,0 , 4139,4 , 4143,7 , 0, 0, 7, 6, 7 }, // Urdu/Arabic/Pakistan
+ { 130, 1, 100, 46, 44, 59, 37, 1776, 45, 43, 1602, 8221, 8220, 8217, 8216, 46,6 , 46,6 , 638,10 , 648,9 , 294,6 , 153,18 , 18,7 , 25,12 , 20205,68 , 20205,68 , 134,24 , 20205,68 , 20205,68 , 134,24 , 10950,36 , 10950,36 , 85,14 , 10950,36 , 10950,36 , 85,14 , 343,9 , 334,9 , {73,78,82}, 129,1 , 12576,18 , 8,5 , 4,0 , 4139,4 , 4150,5 , 2, 1, 7, 7, 7 }, // Urdu/Arabic/India
+ { 131, 7, 228, 44, 160, 59, 37, 48, 45, 43, 101, 34, 34, 39, 39, 0,6 , 0,6 , 657,8 , 657,8 , 376,8 , 384,18 , 37,5 , 8,10 , 20273,52 , 20325,77 , 20402,24 , 20273,52 , 20325,77 , 20402,24 , 10986,34 , 11020,61 , 11081,14 , 10986,34 , 11020,61 , 11081,14 , 0,2 , 0,2 , {85,90,83}, 320,4 , 12594,55 , 8,5 , 4,0 , 4155,9 , 4164,11 , 0, 0, 1, 6, 7 }, // Uzbek/Latin/Uzbekistan
+ { 131, 1, 1, 1643, 1644, 1563, 1642, 1776, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 171,8 , 1301,33 , 42,4 , 354,11 , 20426,48 , 13643,68 , 158,27 , 20426,48 , 13643,68 , 158,27 , 11095,21 , 7194,49 , 85,14 , 11095,21 , 7194,49 , 85,14 , 0,2 , 0,2 , {65,70,78}, 264,1 , 12649,13 , 13,5 , 4,0 , 4175,6 , 3101,9 , 0, 0, 6, 4, 5 }, // Uzbek/Arabic/Afghanistan
+ { 131, 2, 228, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 376,8 , 384,18 , 37,5 , 8,10 , 18167,48 , 18215,71 , 10427,24 , 18167,48 , 18215,71 , 10427,24 , 11116,28 , 11144,53 , 11197,14 , 11116,28 , 11144,53 , 11197,14 , 0,2 , 0,2 , {85,90,83}, 324,3 , 12662,49 , 8,5 , 4,0 , 4181,5 , 4186,10 , 0, 0, 1, 6, 7 }, // Uzbek/Cyrillic/Uzbekistan
+ { 132, 7, 232, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 665,8 , 665,8 , 133,10 , 1334,31 , 37,5 , 8,10 , 20474,75 , 20549,99 , 158,27 , 20648,75 , 20723,99 , 158,27 , 11211,33 , 11244,55 , 11299,21 , 11211,33 , 11244,55 , 11299,21 , 352,2 , 343,2 , {86,78,68}, 327,1 , 12711,33 , 13,5 , 4,0 , 4196,10 , 4206,8 , 0, 0, 1, 6, 7 }, // Vietnamese/Latin/Vietnam
+ { 134, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 37,5 , 8,10 , 20822,52 , 20874,87 , 20961,26 , 20987,62 , 20874,87 , 20961,26 , 11320,29 , 11349,77 , 11426,15 , 11441,30 , 11349,77 , 11426,15 , 0,2 , 0,2 , {71,66,80}, 125,1 , 12744,154 , 4,4 , 4,0 , 4214,7 , 4221,16 , 2, 1, 1, 6, 7 }, // Welsh/Latin/UnitedKingdom
+ { 136, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 21049,48 , 21097,91 , 158,27 , 21049,48 , 21097,91 , 158,27 , 11471,28 , 11499,61 , 85,14 , 11471,28 , 11499,61 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4237,8 , 0,0 , 2, 1, 7, 6, 7 }, // Xhosa/Latin/SouthAfrica
+ { 138, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 21188,73 , 21261,121 , 158,27 , 21188,73 , 21261,121 , 158,27 , 11560,44 , 11604,69 , 85,14 , 11560,44 , 11604,69 , 85,14 , 354,5 , 345,5 , {78,71,78}, 190,1 , 12898,34 , 4,4 , 4,0 , 4245,10 , 4255,18 , 2, 1, 1, 6, 7 }, // Yoruba/Latin/Nigeria
+ { 138, 7, 23, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 21382,74 , 21456,134 , 158,27 , 21382,74 , 21456,134 , 158,27 , 11673,44 , 11717,69 , 85,14 , 11673,44 , 11717,69 , 85,14 , 359,5 , 350,5 , {88,79,70}, 214,3 , 12932,34 , 4,4 , 4,0 , 4245,10 , 4273,16 , 0, 0, 1, 6, 7 }, // Yoruba/Latin/Benin
+ { 140, 7, 195, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 673,9 , 682,10 , 72,10 , 82,17 , 18,7 , 25,12 , 21590,48 , 21638,104 , 134,24 , 21590,48 , 21742,90 , 134,24 , 11786,28 , 11814,67 , 11881,14 , 11786,28 , 11814,67 , 11895,14 , 364,7 , 355,8 , {90,65,82}, 11,1 , 12966,27 , 4,4 , 4,0 , 4289,7 , 4296,14 , 2, 1, 7, 6, 7 }, // Zulu/Latin/SouthAfrica
+ { 141, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 185,8 , 185,8 , 179,8 , 505,17 , 37,5 , 467,16 , 5743,48 , 13056,83 , 134,24 , 21832,59 , 13056,83 , 134,24 , 11909,28 , 11937,51 , 2217,14 , 11988,28 , 11937,51 , 2217,14 , 371,9 , 363,11 , {78,79,75}, 163,2 , 12993,42 , 13,5 , 4,0 , 4310,7 , 4317,5 , 2, 1, 1, 6, 7 }, // NorwegianNynorsk/Latin/Norway
+ { 142, 7, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 161,7 , 161,7 , 1365,9 , 1062,20 , 37,5 , 8,10 , 15360,48 , 21891,83 , 15489,24 , 15360,48 , 21891,83 , 15489,24 , 1940,28 , 1968,58 , 85,14 , 1940,28 , 1968,58 , 85,14 , 284,9 , 277,7 , {66,65,77}, 159,2 , 13035,218 , 8,5 , 4,0 , 4322,8 , 620,19 , 2, 1, 1, 6, 7 }, // Bosnian/Latin/BosniaAndHerzegowina
+ { 142, 2, 27, 44, 46, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 125,7 , 125,7 , 479,7 , 1062,20 , 37,5 , 8,10 , 15231,48 , 15513,83 , 11735,24 , 15231,48 , 15513,83 , 11735,24 , 8270,28 , 8298,54 , 8174,14 , 8270,28 , 8298,54 , 8174,14 , 275,9 , 270,7 , {66,65,77}, 293,2 , 13253,195 , 13,5 , 4,0 , 4330,8 , 3457,19 , 2, 1, 1, 6, 7 }, // Bosnian/Cyrillic/BosniaAndHerzegowina
+ { 144, 7, 251, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 82,17 , 37,5 , 8,10 , 21974,102 , 22076,140 , 158,27 , 21974,102 , 22076,140 , 158,27 , 12016,30 , 12046,57 , 85,14 , 12016,30 , 12046,57 , 85,14 , 93,4 , 91,4 , {71,66,80}, 125,1 , 0,7 , 4,4 , 4,0 , 4338,5 , 4343,12 , 2, 1, 1, 6, 7 }, // Manx/Latin/IsleOfMan
+ { 145, 7, 224, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 99,16 , 37,5 , 8,10 , 22216,46 , 22262,124 , 158,27 , 22216,46 , 22262,124 , 158,27 , 12103,28 , 12131,60 , 85,14 , 12103,28 , 12131,60 , 85,14 , 93,4 , 91,4 , {71,66,80}, 125,1 , 0,7 , 4,4 , 4,0 , 4355,8 , 4363,14 , 2, 1, 1, 6, 7 }, // Cornish/Latin/UnitedKingdom
+ { 146, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 376,8 , 384,18 , 37,5 , 8,10 , 22386,48 , 22434,192 , 158,27 , 22386,48 , 22434,192 , 158,27 , 12191,28 , 12219,49 , 12268,14 , 12191,28 , 12219,49 , 12268,14 , 380,2 , 374,2 , {71,72,83}, 178,3 , 13448,17 , 4,4 , 4,0 , 4377,4 , 4381,5 , 2, 1, 1, 6, 7 }, // Akan/Latin/Ghana
+ { 147, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 682,6 , 99,16 , 18,7 , 25,12 , 22626,87 , 22626,87 , 158,27 , 22626,87 , 22626,87 , 158,27 , 6753,32 , 12282,55 , 85,14 , 6753,32 , 12282,55 , 85,14 , 382,5 , 376,5 , {73,78,82}, 129,1 , 0,7 , 8,5 , 4,0 , 4386,6 , 2587,4 , 2, 1, 7, 7, 7 }, // Konkani/Devanagari/India
+ { 149, 7, 157, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 22713,48 , 22761,86 , 158,27 , 22713,48 , 22761,86 , 158,27 , 12337,29 , 12366,57 , 85,14 , 12337,29 , 12366,57 , 85,14 , 387,4 , 381,4 , {78,71,78}, 190,1 , 13465,12 , 4,4 , 4,0 , 4392,4 , 1319,7 , 2, 1, 1, 6, 7 }, // Igbo/Latin/Nigeria
+ { 150, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 22847,48 , 22895,189 , 23084,24 , 22847,48 , 22895,189 , 23084,24 , 12423,28 , 12451,74 , 12525,14 , 12423,28 , 12451,74 , 12525,14 , 391,9 , 385,7 , {75,69,83}, 2,3 , 13477,23 , 4,4 , 4,0 , 4396,7 , 1188,5 , 2, 1, 7, 6, 7 }, // Kamba/Latin/Kenya
+ { 152, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1374,22 , 18,7 , 25,12 , 23108,47 , 23155,77 , 23232,24 , 23108,47 , 23155,77 , 23232,24 , 12539,26 , 12565,43 , 12608,14 , 12539,26 , 12565,43 , 12608,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4403,3 , 4061,4 , 2, 1, 1, 6, 7 }, // Blin/Ethiopic/Eritrea
+ { 157, 14, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1396,21 , 18,7 , 25,12 , 19197,46 , 19243,62 , 1050,24 , 19197,46 , 19243,62 , 1050,24 , 12622,27 , 12649,41 , 12690,14 , 12622,27 , 12649,41 , 12690,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 4406,3 , 4061,4 , 2, 1, 1, 6, 7 }, // Tigre/Ethiopic/Eritrea
+ { 159, 7, 106, 44, 46, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 249,7 , 249,7 , 27,8 , 1417,27 , 37,5 , 8,10 , 23256,48 , 23304,77 , 23381,24 , 23256,48 , 23304,77 , 23381,24 , 12704,28 , 12732,50 , 2978,14 , 12704,28 , 12732,50 , 2978,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 8,5 , 4,0 , 4409,6 , 4415,6 , 2, 1, 1, 6, 7 }, // Friulian/Latin/Italy
+ { 160, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 23405,48 , 23453,111 , 158,27 , 23405,48 , 23453,111 , 158,27 , 12782,27 , 12809,70 , 85,14 , 12782,27 , 12809,70 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4421,9 , 0,0 , 2, 1, 7, 6, 7 }, // Venda/Latin/SouthAfrica
+ { 161, 7, 83, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 692,11 , 703,10 , 560,6 , 1444,23 , 511,12 , 523,12 , 23564,48 , 23612,87 , 23699,24 , 23564,48 , 23612,87 , 23699,24 , 12879,28 , 12907,44 , 12951,14 , 12879,28 , 12907,44 , 12951,14 , 400,3 , 392,5 , {71,72,83}, 178,3 , 13500,37 , 4,4 , 4,0 , 4430,6 , 4436,12 , 2, 1, 1, 6, 7 }, // Ewe/Latin/Ghana
+ { 161, 7, 212, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 692,11 , 703,10 , 560,6 , 1444,23 , 511,12 , 523,12 , 23564,48 , 23612,87 , 23699,24 , 23564,48 , 23612,87 , 23699,24 , 12879,28 , 12907,44 , 12951,14 , 12879,28 , 12907,44 , 12951,14 , 400,3 , 392,5 , {88,79,70}, 214,3 , 13537,106 , 4,4 , 4,0 , 4430,6 , 4448,11 , 0, 0, 1, 6, 7 }, // Ewe/Latin/Togo
+ { 162, 14, 69, 46, 8217, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1467,22 , 18,7 , 25,12 , 19197,46 , 19243,62 , 1050,24 , 19197,46 , 19243,62 , 1050,24 , 12965,27 , 12965,27 , 12992,14 , 12965,27 , 12965,27 , 12992,14 , 0,2 , 0,2 , {69,84,66}, 0,2 , 12429,16 , 4,4 , 4,0 , 4459,5 , 108,5 , 2, 1, 7, 6, 7 }, // Walamo/Ethiopic/Ethiopia
+ { 163, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 294,6 , 10,17 , 18,7 , 25,12 , 23723,59 , 23782,95 , 158,27 , 23723,59 , 23782,95 , 158,27 , 13006,21 , 13027,57 , 85,14 , 13006,21 , 13027,57 , 85,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 4,4 , 4,0 , 4464,14 , 4478,19 , 2, 1, 7, 6, 7 }, // Hawaiian/Latin/UnitedStates
+ { 166, 7, 170, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 193,10 , 713,8 , 560,6 , 35,18 , 18,7 , 25,12 , 23877,48 , 23925,88 , 24013,24 , 23877,48 , 23925,88 , 24013,24 , 13084,28 , 13112,55 , 13167,14 , 13084,28 , 13112,55 , 13167,14 , 0,2 , 0,2 , {80,72,80}, 191,1 , 5279,53 , 4,4 , 4,0 , 4497,8 , 4505,9 , 2, 1, 7, 6, 7 }, // Filipino/Latin/Philippines
+ { 167, 7, 206, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 24037,86 , 134,24 , 7053,48 , 24037,86 , 134,24 , 13181,28 , 13209,63 , 3456,14 , 13181,28 , 13209,63 , 3456,14 , 105,5 , 397,4 , {67,72,70}, 233,3 , 13643,55 , 13,5 , 4,0 , 4514,16 , 4530,7 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Switzerland
+ { 167, 7, 123, 46, 8217, 59, 37, 48, 8722, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 264,9 , 264,9 , 179,8 , 585,18 , 37,5 , 8,10 , 7053,48 , 24037,86 , 134,24 , 7053,48 , 24037,86 , 134,24 , 13181,28 , 13209,63 , 3456,14 , 13181,28 , 13209,63 , 3456,14 , 105,5 , 397,4 , {67,72,70}, 233,3 , 13643,55 , 13,5 , 4,0 , 4514,16 , 4537,13 , 2, 0, 1, 6, 7 }, // Swiss German/Latin/Liechtenstein
+ { 168, 34, 44, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 158,27 , 24123,38 , 158,27 , 158,27 , 24123,38 , 158,27 , 13272,21 , 13293,28 , 13321,14 , 13272,21 , 13293,28 , 13321,14 , 403,2 , 401,2 , {67,78,89}, 318,1 , 0,7 , 8,5 , 4,0 , 4550,3 , 4553,2 , 2, 1, 7, 6, 7 }, // Sichuan Yi/Yi/China
+ { 171, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 24161,48 , 24209,100 , 158,27 , 24161,48 , 24209,100 , 158,27 , 13335,27 , 13362,66 , 85,14 , 13335,27 , 13362,66 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4555,10 , 0,0 , 2, 1, 7, 6, 7 }, // South Ndebele/Latin/SouthAfrica
+ { 172, 7, 195, 44, 160, 59, 37, 48, 45, 43, 101, 8216, 8217, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 330,17 , 37,5 , 8,10 , 24309,48 , 24357,94 , 158,27 , 24309,48 , 24357,94 , 158,27 , 13428,27 , 13455,63 , 85,14 , 13428,27 , 13455,63 , 85,14 , 0,2 , 0,2 , {90,65,82}, 11,1 , 0,7 , 4,4 , 4,0 , 4565,16 , 0,0 , 2, 1, 7, 6, 7 }, // Northern Sotho/Latin/SouthAfrica
+ { 173, 7, 161, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 212,8 , 212,8 , 72,10 , 330,17 , 37,5 , 8,10 , 24451,59 , 24510,145 , 24655,24 , 24451,59 , 24510,145 , 24655,24 , 13518,33 , 13551,75 , 13626,14 , 13518,33 , 13551,75 , 13626,14 , 0,2 , 0,2 , {78,79,75}, 163,2 , 13698,63 , 13,5 , 4,0 , 4581,15 , 4596,5 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Norway
+ { 173, 7, 73, 44, 160, 59, 37, 48, 8722, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 212,8 , 212,8 , 72,10 , 330,17 , 37,5 , 8,10 , 24679,85 , 24510,145 , 24655,24 , 24679,85 , 24510,145 , 24655,24 , 13518,33 , 13640,65 , 13705,14 , 13518,33 , 13640,65 , 13705,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 13761,23 , 13,5 , 4,0 , 4581,15 , 4601,6 , 2, 1, 1, 6, 7 }, // Northern Sami/Latin/Finland
+ { 175, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 24764,48 , 24812,88 , 24900,24 , 24764,48 , 24812,88 , 24900,24 , 13719,28 , 13747,62 , 13809,14 , 13719,28 , 13747,62 , 13809,14 , 405,5 , 403,10 , {75,69,83}, 2,3 , 13784,24 , 4,4 , 4,0 , 4607,8 , 1188,5 , 2, 1, 7, 6, 7 }, // Gusii/Latin/Kenya
+ { 176, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 24924,48 , 24972,221 , 25193,24 , 24924,48 , 24972,221 , 25193,24 , 13823,28 , 13851,105 , 13956,14 , 13823,28 , 13851,105 , 13956,14 , 410,10 , 413,10 , {75,69,83}, 2,3 , 13784,24 , 4,4 , 4,0 , 4615,7 , 1188,5 , 2, 1, 7, 6, 7 }, // Taita/Latin/Kenya
+ { 177, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 25217,48 , 25265,77 , 25342,24 , 25217,48 , 25265,77 , 25342,24 , 13970,28 , 13998,59 , 14057,14 , 13970,28 , 13998,59 , 14057,14 , 420,6 , 423,7 , {88,79,70}, 214,3 , 13808,26 , 13,5 , 4,0 , 4622,6 , 4628,8 , 0, 0, 1, 6, 7 }, // Fulah/Latin/Senegal
+ { 178, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 25366,48 , 25414,185 , 25599,24 , 25366,48 , 25414,185 , 25599,24 , 14071,28 , 14099,63 , 14162,14 , 14071,28 , 14099,63 , 14162,14 , 426,6 , 430,8 , {75,69,83}, 2,3 , 13834,23 , 4,4 , 4,0 , 4636,6 , 1188,5 , 2, 1, 7, 6, 7 }, // Kikuyu/Latin/Kenya
+ { 179, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 25623,48 , 25671,173 , 25844,24 , 25623,48 , 25671,173 , 25844,24 , 14176,28 , 14204,105 , 14309,14 , 14176,28 , 14204,105 , 14309,14 , 432,7 , 438,5 , {75,69,83}, 2,3 , 13857,25 , 4,4 , 4,0 , 4642,8 , 1188,5 , 2, 1, 7, 6, 7 }, // Samburu/Latin/Kenya
+ { 180, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 1007,27 , 37,5 , 8,10 , 25868,48 , 25916,88 , 134,24 , 25868,48 , 25916,88 , 134,24 , 14323,28 , 14351,55 , 14406,14 , 14323,28 , 14351,55 , 14406,14 , 0,2 , 0,2 , {77,90,78}, 273,3 , 13882,28 , 0,4 , 4,0 , 4650,4 , 3227,10 , 2, 1, 7, 6, 7 }, // Sena/Latin/Mozambique
+ { 181, 7, 240, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 26004,52 , 26056,112 , 26168,24 , 26004,52 , 26056,112 , 26168,24 , 14420,28 , 14448,50 , 14498,14 , 14420,28 , 14448,50 , 14498,14 , 0,2 , 0,2 , {85,83,68}, 187,3 , 13910,24 , 4,4 , 4,0 , 4555,10 , 1760,8 , 2, 1, 7, 6, 7 }, // North Ndebele/Latin/Zimbabwe
+ { 182, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 26192,39 , 26231,194 , 26425,24 , 26192,39 , 26231,194 , 26425,24 , 14512,29 , 14541,65 , 14606,14 , 14512,29 , 14541,65 , 14606,14 , 439,8 , 443,7 , {84,90,83}, 202,3 , 13934,25 , 4,4 , 4,0 , 4654,9 , 1586,8 , 0, 0, 1, 6, 7 }, // Rombo/Latin/Tanzania
+ { 183, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 26449,48 , 26497,81 , 26578,24 , 26449,48 , 26497,81 , 26578,24 , 14620,30 , 14650,47 , 85,14 , 14620,30 , 14650,47 , 85,14 , 447,6 , 450,8 , {77,65,68}, 0,0 , 13959,21 , 0,4 , 4,0 , 4663,8 , 4671,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Tifinagh/Morocco
+ { 183, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 26602,48 , 26650,81 , 26731,24 , 26602,48 , 26650,81 , 26731,24 , 14697,30 , 14727,48 , 85,14 , 14697,30 , 14727,48 , 85,14 , 453,6 , 458,8 , {77,65,68}, 0,0 , 13980,21 , 0,4 , 4,0 , 4677,9 , 4686,6 , 2, 1, 6, 5, 6 }, // Tachelhit/Latin/Morocco
+ { 184, 7, 3, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 26755,48 , 26803,84 , 26887,24 , 26755,48 , 26803,84 , 26887,24 , 14775,30 , 14805,51 , 14856,14 , 14775,30 , 14805,51 , 14856,14 , 459,7 , 466,9 , {68,90,68}, 212,2 , 14001,21 , 0,4 , 4,0 , 4692,9 , 4701,8 , 2, 1, 6, 4, 5 }, // Kabyle/Latin/Algeria
+ { 185, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 26911,48 , 26959,152 , 134,24 , 26911,48 , 26959,152 , 134,24 , 14870,28 , 14898,74 , 14972,14 , 14870,28 , 14898,74 , 14972,14 , 0,2 , 0,2 , {85,71,88}, 207,3 , 14022,26 , 4,4 , 4,0 , 4709,10 , 1655,6 , 0, 0, 1, 6, 7 }, // Nyankole/Latin/Uganda
+ { 186, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 27111,48 , 27159,254 , 27413,24 , 27111,48 , 27159,254 , 27413,24 , 14986,28 , 15014,82 , 15096,14 , 14986,28 , 15014,82 , 15096,14 , 466,7 , 475,7 , {84,90,83}, 202,3 , 14048,29 , 0,4 , 4,0 , 4719,6 , 4725,10 , 0, 0, 1, 6, 7 }, // Bena/Latin/Tanzania
+ { 187, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 27437,87 , 134,24 , 17815,48 , 27437,87 , 134,24 , 15110,28 , 15138,62 , 15200,14 , 15110,28 , 15138,62 , 15200,14 , 473,5 , 482,9 , {84,90,83}, 202,3 , 14077,27 , 4,4 , 4,0 , 4735,8 , 1586,8 , 0, 0, 1, 6, 7 }, // Vunjo/Latin/Tanzania
+ { 188, 7, 132, 46, 44, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 27524,47 , 27571,92 , 27663,24 , 27524,47 , 27571,92 , 27663,24 , 15214,28 , 15242,44 , 15286,14 , 15214,28 , 15242,44 , 15286,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 14104,24 , 4,4 , 4,0 , 4743,9 , 2111,4 , 0, 0, 1, 6, 7 }, // Bambara/Latin/Mali
+ { 189, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 27687,48 , 27735,207 , 27942,24 , 27687,48 , 27735,207 , 27942,24 , 15300,28 , 15328,64 , 15392,14 , 15300,28 , 15328,64 , 15392,14 , 478,2 , 491,2 , {75,69,83}, 2,3 , 13784,24 , 4,4 , 4,0 , 4752,6 , 1188,5 , 2, 1, 7, 6, 7 }, // Embu/Latin/Kenya
+ { 190, 12, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 560,6 , 35,18 , 18,7 , 25,12 , 27966,36 , 28002,58 , 28060,24 , 27966,36 , 28002,58 , 28060,24 , 15406,28 , 15434,49 , 15483,14 , 15406,28 , 15434,49 , 15483,14 , 480,3 , 493,6 , {85,83,68}, 12,1 , 14128,19 , 4,4 , 4,0 , 4758,3 , 4761,4 , 2, 1, 7, 6, 7 }, // Cherokee/Cherokee/UnitedStates
+ { 191, 7, 137, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 28084,47 , 28131,68 , 28199,24 , 28084,47 , 28131,68 , 28199,24 , 15497,27 , 15524,48 , 15572,14 , 15497,27 , 15524,48 , 15572,14 , 0,2 , 0,2 , {77,85,82}, 185,2 , 14147,21 , 8,5 , 4,0 , 4765,14 , 4779,5 , 0, 0, 1, 6, 7 }, // Morisyen/Latin/Mauritius
+ { 192, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 28223,264 , 134,24 , 17815,48 , 28223,264 , 134,24 , 15586,28 , 15614,133 , 14606,14 , 15586,28 , 15614,133 , 14606,14 , 483,4 , 499,5 , {84,90,83}, 202,3 , 14077,27 , 4,4 , 4,0 , 4784,10 , 1586,8 , 0, 0, 1, 6, 7 }, // Makonde/Latin/Tanzania
+ { 193, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8221, 8221, 8217, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 28487,83 , 28570,111 , 28681,24 , 28487,83 , 28570,111 , 28681,24 , 15747,36 , 15783,63 , 15846,14 , 15747,36 , 15783,63 , 15846,14 , 487,3 , 504,3 , {84,90,83}, 202,3 , 14168,29 , 8,5 , 4,0 , 4794,8 , 4802,9 , 0, 0, 1, 6, 7 }, // Langi/Latin/Tanzania
+ { 194, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 28705,48 , 28753,97 , 134,24 , 28705,48 , 28753,97 , 134,24 , 15860,28 , 15888,66 , 15954,14 , 15860,28 , 15888,66 , 15954,14 , 0,2 , 0,2 , {85,71,88}, 207,3 , 14197,26 , 0,4 , 4,0 , 4811,7 , 4818,7 , 0, 0, 1, 6, 7 }, // Ganda/Latin/Uganda
+ { 195, 7, 239, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 28850,48 , 28898,83 , 28981,24 , 28850,48 , 28898,83 , 28981,24 , 15968,80 , 15968,80 , 85,14 , 15968,80 , 15968,80 , 85,14 , 490,8 , 507,7 , {90,77,87}, 145,1 , 0,7 , 4,4 , 4,0 , 4825,9 , 1754,6 , 2, 1, 1, 6, 7 }, // Bemba/Latin/Zambia
+ { 196, 7, 39, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 537,7 , 537,7 , 408,8 , 1489,27 , 37,5 , 8,10 , 29005,48 , 29053,86 , 134,24 , 29005,48 , 29053,86 , 134,24 , 16048,28 , 16076,73 , 16149,14 , 16048,28 , 16076,73 , 16149,14 , 91,2 , 89,2 , {67,86,69}, 0,0 , 14223,25 , 0,4 , 4,0 , 4834,12 , 4846,10 , 2, 1, 1, 6, 7 }, // Kabuverdianu/Latin/CapeVerde
+ { 197, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 29139,48 , 29187,86 , 29273,24 , 29139,48 , 29187,86 , 29273,24 , 16163,28 , 16191,51 , 16242,14 , 16163,28 , 16191,51 , 16242,14 , 498,2 , 514,2 , {75,69,83}, 2,3 , 13784,24 , 4,4 , 4,0 , 4856,6 , 1188,5 , 2, 1, 7, 6, 7 }, // Meru/Latin/Kenya
+ { 198, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 29297,48 , 29345,111 , 29456,24 , 29297,48 , 29345,111 , 29456,24 , 16256,28 , 16284,93 , 16377,14 , 16256,28 , 16284,93 , 16377,14 , 500,4 , 516,4 , {75,69,83}, 2,3 , 14248,26 , 4,4 , 4,0 , 4862,8 , 4870,12 , 2, 1, 7, 6, 7 }, // Kalenjin/Latin/Kenya
+ { 199, 7, 148, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 0,48 , 29480,136 , 134,24 , 0,48 , 29480,136 , 134,24 , 16391,23 , 16414,92 , 16506,14 , 16391,23 , 16414,92 , 16506,14 , 504,7 , 520,5 , {78,65,68}, 12,1 , 14274,22 , 4,4 , 4,0 , 4882,13 , 4895,8 , 2, 1, 1, 6, 7 }, // Nama/Latin/Namibia
+ { 200, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 27437,87 , 134,24 , 17815,48 , 27437,87 , 134,24 , 15110,28 , 15138,62 , 15200,14 , 15110,28 , 15138,62 , 15200,14 , 473,5 , 482,9 , {84,90,83}, 202,3 , 14077,27 , 4,4 , 4,0 , 4903,9 , 1586,8 , 0, 0, 1, 6, 7 }, // Machame/Latin/Tanzania
+ { 201, 7, 82, 44, 160, 59, 37, 48, 8722, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 398,8 , 398,8 , 1516,10 , 1526,23 , 37,5 , 8,10 , 29616,59 , 29675,87 , 134,24 , 29762,48 , 29675,87 , 134,24 , 16520,28 , 16548,72 , 3456,14 , 16520,28 , 16548,72 , 3456,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 8122,11 , 13,5 , 4,0 , 4912,6 , 4918,11 , 2, 1, 1, 6, 7 }, // Colognian/Latin/Germany
+ { 202, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 29810,51 , 29861,132 , 158,27 , 29810,51 , 29861,132 , 158,27 , 15110,28 , 16620,58 , 14606,14 , 15110,28 , 16620,58 , 14606,14 , 511,9 , 525,6 , {75,69,83}, 2,3 , 14296,25 , 4,4 , 4,0 , 4929,3 , 1188,5 , 2, 1, 7, 6, 7 }, // Masai/Latin/Kenya
+ { 202, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 29810,51 , 29861,132 , 158,27 , 29810,51 , 29861,132 , 158,27 , 15110,28 , 16620,58 , 14606,14 , 15110,28 , 16620,58 , 14606,14 , 511,9 , 525,6 , {84,90,83}, 202,3 , 14321,28 , 4,4 , 4,0 , 4929,3 , 4932,8 , 0, 0, 1, 6, 7 }, // Masai/Latin/Tanzania
+ { 203, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 28705,48 , 28753,97 , 134,24 , 28705,48 , 28753,97 , 134,24 , 16678,35 , 16713,65 , 16778,14 , 16678,35 , 16713,65 , 16778,14 , 520,6 , 531,6 , {85,71,88}, 207,3 , 14197,26 , 13,5 , 4,0 , 4940,7 , 4818,7 , 0, 0, 1, 6, 7 }, // Soga/Latin/Uganda
+ { 204, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8222, 8220, 8218, 8216, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 29993,48 , 17863,84 , 134,24 , 29993,48 , 17863,84 , 134,24 , 16792,21 , 16813,75 , 85,14 , 16792,21 , 16813,75 , 85,14 , 93,4 , 91,4 , {75,69,83}, 2,3 , 14349,23 , 4,4 , 62,6 , 4947,7 , 1188,5 , 2, 1, 7, 6, 7 }, // Luyia/Latin/Kenya
+ { 205, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 30041,48 , 17863,84 , 134,24 , 30041,48 , 17863,84 , 134,24 , 16888,28 , 9625,60 , 15200,14 , 16888,28 , 9625,60 , 15200,14 , 526,9 , 537,8 , {84,90,83}, 202,3 , 14372,28 , 13,5 , 4,0 , 4954,6 , 4960,8 , 0, 0, 1, 6, 7 }, // Asu/Latin/Tanzania
+ { 206, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 30089,48 , 30137,94 , 30231,24 , 30089,48 , 30137,94 , 30231,24 , 16916,28 , 16944,69 , 17013,14 , 16916,28 , 16944,69 , 17013,14 , 535,9 , 545,6 , {85,71,88}, 207,3 , 14400,28 , 4,4 , 4,0 , 4968,6 , 1655,6 , 0, 0, 1, 6, 7 }, // Teso/Latin/Uganda
+ { 206, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 30089,48 , 30137,94 , 30231,24 , 30089,48 , 30137,94 , 30231,24 , 16916,28 , 16944,69 , 17013,14 , 16916,28 , 16944,69 , 17013,14 , 535,9 , 545,6 , {75,69,83}, 2,3 , 14428,27 , 4,4 , 4,0 , 4968,6 , 4974,5 , 2, 1, 7, 6, 7 }, // Teso/Latin/Kenya
+ { 207, 7, 67, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 53,19 , 18,7 , 25,12 , 344,48 , 392,118 , 510,24 , 344,48 , 392,118 , 510,24 , 17027,28 , 17055,56 , 17111,14 , 17027,28 , 17055,56 , 17111,14 , 0,2 , 0,2 , {69,82,78}, 8,3 , 0,7 , 4,4 , 4,0 , 0,0 , 43,7 , 2, 1, 1, 6, 7 }, // Saho/Latin/Eritrea
+ { 208, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 30255,46 , 30301,88 , 30389,24 , 30255,46 , 30301,88 , 30389,24 , 17125,28 , 17153,53 , 17206,14 , 17125,28 , 17153,53 , 17206,14 , 544,6 , 551,6 , {88,79,70}, 214,3 , 14455,23 , 0,4 , 4,0 , 4979,11 , 4990,5 , 0, 0, 1, 6, 7 }, // Koyra Chiini/Latin/Mali
+ { 209, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 27437,87 , 134,24 , 17815,48 , 27437,87 , 134,24 , 15110,28 , 15138,62 , 15200,14 , 15110,28 , 15138,62 , 15200,14 , 473,5 , 482,9 , {84,90,83}, 202,3 , 14077,27 , 0,4 , 4,0 , 4995,6 , 1586,8 , 0, 0, 1, 6, 7 }, // Rwa/Latin/Tanzania
+ { 210, 7, 111, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 30413,48 , 30461,186 , 30647,24 , 30413,48 , 30461,186 , 30647,24 , 17220,28 , 17248,69 , 17317,14 , 17220,28 , 17248,69 , 17317,14 , 550,2 , 557,2 , {75,69,83}, 2,3 , 14478,23 , 0,4 , 4,0 , 5001,6 , 1188,5 , 2, 1, 7, 6, 7 }, // Luo/Latin/Kenya
+ { 211, 7, 221, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 26911,48 , 26959,152 , 134,24 , 26911,48 , 26959,152 , 134,24 , 14870,28 , 14898,74 , 14972,14 , 14870,28 , 14898,74 , 14972,14 , 0,2 , 0,2 , {85,71,88}, 207,3 , 14022,26 , 4,4 , 4,0 , 5007,6 , 1655,6 , 0, 0, 1, 6, 7 }, // Chiga/Latin/Uganda
+ { 212, 7, 145, 44, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 30671,48 , 30719,86 , 30805,24 , 30671,48 , 30719,86 , 30805,24 , 17331,28 , 17359,48 , 17407,14 , 17331,28 , 17359,48 , 17407,14 , 552,9 , 559,10 , {77,65,68}, 0,0 , 14501,22 , 13,5 , 4,0 , 5013,8 , 5021,6 , 2, 1, 6, 5, 6 }, // Central Morocco Tamazight/Latin/Morocco
+ { 213, 7, 132, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 30255,46 , 30301,88 , 30389,24 , 30255,46 , 30301,88 , 30389,24 , 17421,28 , 17449,54 , 17206,14 , 17421,28 , 17449,54 , 17206,14 , 544,6 , 551,6 , {88,79,70}, 214,3 , 14455,23 , 0,4 , 4,0 , 5027,15 , 4990,5 , 0, 0, 1, 6, 7 }, // Koyraboro Senni/Latin/Mali
+ { 214, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 17815,48 , 30829,84 , 134,24 , 17815,48 , 30829,84 , 134,24 , 17503,28 , 17531,63 , 9685,14 , 17503,28 , 17531,63 , 9685,14 , 561,5 , 569,8 , {84,90,83}, 202,3 , 12117,27 , 0,4 , 4,0 , 5042,9 , 1586,8 , 0, 0, 1, 6, 7 }, // Shambala/Latin/Tanzania
+ { 215, 13, 100, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 560,6 , 35,18 , 18,7 , 25,12 , 30913,88 , 30913,88 , 31001,31 , 30913,88 , 30913,88 , 31001,31 , 17594,33 , 17627,54 , 17681,19 , 17594,33 , 17627,54 , 17681,19 , 566,3 , 577,6 , {73,78,82}, 129,1 , 14523,10 , 8,5 , 4,0 , 5051,4 , 2587,4 , 2, 1, 7, 7, 7 }, // Bodo/Devanagari/India
+ { 230, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31032,49 , 31081,99 , 31180,24 , 31032,49 , 31081,99 , 31180,24 , 17700,28 , 17728,50 , 17778,14 , 17700,28 , 17728,50 , 17778,14 , 569,5 , 583,6 , {67,68,70}, 222,2 , 14533,24 , 0,4 , 4,0 , 5055,8 , 5063,16 , 2, 1, 1, 6, 7 }, // LubaKatanga/Latin/CongoKinshasa
+ { 237, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 8218, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31204,48 , 31252,195 , 31447,24 , 31204,48 , 31252,195 , 31447,24 , 17792,28 , 17820,72 , 17892,14 , 17792,28 , 17820,72 , 17892,14 , 574,3 , 589,3 , {88,65,70}, 38,4 , 14557,21 , 0,4 , 4,0 , 5079,5 , 5084,7 , 0, 0, 1, 6, 7 }, // Aghem/Latin/Cameroon
+ { 238, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8220, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31471,48 , 31519,90 , 31609,24 , 31471,48 , 31519,90 , 31609,24 , 17906,28 , 17934,70 , 18004,14 , 17906,28 , 17934,70 , 18004,14 , 577,10 , 592,9 , {88,65,70}, 38,4 , 14578,22 , 13,5 , 4,0 , 5091,5 , 5096,8 , 0, 0, 1, 6, 7 }, // Basaa/Latin/Cameroon
+ { 239, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 30255,46 , 30301,88 , 30389,24 , 30255,46 , 30301,88 , 30389,24 , 17421,28 , 18018,53 , 18071,14 , 17421,28 , 18018,53 , 18071,14 , 587,8 , 601,10 , {88,79,70}, 214,3 , 14455,23 , 0,4 , 4,0 , 5104,10 , 5114,5 , 0, 0, 1, 6, 7 }, // Zarma/Latin/Niger
+ { 240, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31633,49 , 31682,99 , 31781,24 , 31633,49 , 31682,99 , 31781,24 , 18085,28 , 18113,45 , 18158,14 , 18085,28 , 18113,45 , 18158,14 , 595,5 , 611,6 , {88,65,70}, 38,4 , 0,7 , 13,5 , 4,0 , 5119,5 , 1908,8 , 0, 0, 1, 6, 7 }, // Duala/Latin/Cameroon
+ { 241, 7, 187, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31805,36 , 31841,82 , 31923,24 , 31805,36 , 31841,82 , 31923,24 , 18172,28 , 18200,50 , 18250,14 , 18172,28 , 18200,50 , 18250,14 , 0,2 , 0,2 , {88,79,70}, 214,3 , 14600,23 , 13,5 , 4,0 , 5124,5 , 5129,7 , 0, 0, 1, 6, 7 }, // JolaFonyi/Latin/Senegal
+ { 242, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 31947,50 , 31997,141 , 32138,24 , 31947,50 , 31997,141 , 32138,24 , 18264,30 , 18294,85 , 18379,14 , 18264,30 , 18294,85 , 18379,14 , 600,7 , 617,9 , {88,65,70}, 38,4 , 14623,23 , 13,5 , 4,0 , 5136,6 , 5142,7 , 0, 0, 1, 6, 7 }, // Ewondo/Latin/Cameroon
+ { 243, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 32162,39 , 32201,191 , 158,27 , 32162,39 , 32201,191 , 158,27 , 18393,29 , 18422,45 , 18467,14 , 18393,29 , 18422,45 , 18467,14 , 607,6 , 626,7 , {88,65,70}, 38,4 , 14646,11 , 13,5 , 4,0 , 5149,5 , 5154,7 , 0, 0, 1, 6, 7 }, // Bafia/Latin/Cameroon
+ { 244, 7, 146, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 32392,48 , 32440,213 , 32653,24 , 32392,48 , 32440,213 , 32653,24 , 18481,28 , 18509,59 , 18568,14 , 18481,28 , 18509,59 , 18568,14 , 613,8 , 633,10 , {77,90,78}, 273,3 , 0,7 , 8,5 , 4,0 , 5161,5 , 5166,10 , 2, 1, 7, 6, 7 }, // MakhuwaMeetto/Latin/Mozambique
+ { 245, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 32677,48 , 32725,139 , 32864,24 , 32677,48 , 32725,139 , 32864,24 , 18582,28 , 18610,74 , 18684,14 , 18582,28 , 18610,74 , 18684,14 , 621,5 , 643,5 , {88,65,70}, 38,4 , 14657,17 , 4,4 , 4,0 , 5176,6 , 5182,7 , 0, 0, 1, 6, 7 }, // Mundang/Latin/Cameroon
+ { 246, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 8222, 8221, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 32888,51 , 32939,143 , 158,27 , 32888,51 , 32939,143 , 158,27 , 18698,30 , 18728,89 , 18817,14 , 18698,30 , 18728,89 , 18817,14 , 626,4 , 648,4 , {88,65,70}, 38,4 , 14674,20 , 13,5 , 4,0 , 5189,6 , 5195,7 , 0, 0, 1, 6, 7 }, // Kwasio/Latin/Cameroon
+ { 247, 7, 201, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 566,9 , 99,16 , 18,7 , 535,12 , 33082,54 , 33136,96 , 33232,24 , 33082,54 , 33136,96 , 33232,24 , 18831,38 , 18869,79 , 18948,14 , 18831,38 , 18869,79 , 18948,14 , 630,2 , 652,2 , {83,68,71}, 0,0 , 0,7 , 4,4 , 4,0 , 5202,9 , 1572,5 , 2, 1, 6, 5, 6 }, // Nuer/Latin/Sudan
+ { 248, 2, 178, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 438,6 , 1549,30 , 37,5 , 8,10 , 33256,75 , 33331,121 , 33452,24 , 33256,75 , 33331,121 , 33452,24 , 18962,21 , 18983,73 , 19056,14 , 18962,21 , 18983,73 , 19056,14 , 0,2 , 0,2 , {82,85,66}, 280,4 , 0,7 , 8,5 , 4,0 , 5211,9 , 0,0 , 2, 1, 1, 6, 7 }, // Sakha/Cyrillic/Russia
+ { 249, 7, 210, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 33476,48 , 33524,117 , 158,27 , 33476,48 , 33524,117 , 158,27 , 19070,28 , 19098,60 , 19158,14 , 19070,28 , 19098,60 , 19158,14 , 632,9 , 654,9 , {84,90,83}, 202,3 , 14694,25 , 0,4 , 4,0 , 5220,9 , 5229,9 , 0, 0, 1, 6, 7 }, // Sangu/Latin/Tanzania
+ { 250, 7, 49, 44, 46, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 33641,48 , 33689,188 , 33877,24 , 33641,48 , 33689,188 , 33877,24 , 19172,28 , 19200,93 , 19293,14 , 19172,28 , 19200,93 , 19293,14 , 641,10 , 663,10 , {67,68,70}, 222,2 , 14719,23 , 4,4 , 4,0 , 5238,18 , 5256,32 , 2, 1, 1, 6, 7 }, // Congo Swahili/Latin/CongoKinshasa
+ { 251, 7, 156, 46, 160, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 30255,46 , 30301,88 , 30389,24 , 30255,46 , 30301,88 , 30389,24 , 17421,28 , 17449,54 , 17206,14 , 17421,28 , 17449,54 , 17206,14 , 587,8 , 601,10 , {88,79,70}, 214,3 , 14455,23 , 0,4 , 4,0 , 5288,13 , 5114,5 , 0, 0, 1, 6, 7 }, // Tasawaq/Latin/Niger
+ { 252, 35, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 33901,50 , 33901,50 , 158,27 , 33901,50 , 33901,50 , 158,27 , 19307,30 , 19307,30 , 85,14 , 19307,30 , 19307,30 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 14742,15 , 4,4 , 4,0 , 5301,2 , 5303,4 , 2, 1, 1, 6, 7 }, // Vai/Vai/Liberia
+ { 252, 7, 121, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 133,10 , 10,17 , 18,7 , 25,12 , 33951,81 , 33951,81 , 158,27 , 33951,81 , 33951,81 , 158,27 , 19337,48 , 19337,48 , 85,14 , 19337,48 , 19337,48 , 85,14 , 0,2 , 0,2 , {76,82,68}, 12,1 , 14757,20 , 4,4 , 4,0 , 5307,3 , 5310,8 , 2, 1, 1, 6, 7 }, // Vai/Latin/Liberia
+ { 253, 7, 206, 44, 8217, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 264,9 , 264,9 , 72,10 , 585,18 , 37,5 , 8,10 , 34032,48 , 34080,99 , 34179,24 , 34032,48 , 34080,99 , 34179,24 , 19385,28 , 19413,53 , 19466,14 , 19385,28 , 19413,53 , 19466,14 , 0,2 , 0,2 , {67,72,70}, 0,0 , 0,7 , 8,5 , 4,0 , 5318,6 , 5324,6 , 2, 0, 1, 6, 7 }, // Walser/Latin/Switzerland
+ { 254, 7, 37, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 171, 187, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 34203,51 , 34254,191 , 158,27 , 34203,51 , 34254,191 , 158,27 , 19480,21 , 19501,71 , 19572,14 , 19480,21 , 19501,71 , 19572,14 , 651,8 , 673,8 , {88,65,70}, 38,4 , 0,7 , 13,5 , 4,0 , 5330,6 , 5336,7 , 0, 0, 1, 6, 7 }, // Yangben/Latin/Cameroon
+ { 256, 7, 197, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 537,7 , 537,7 , 294,6 , 1579,23 , 37,5 , 8,10 , 34445,48 , 34493,85 , 34578,24 , 34602,48 , 34650,117 , 34578,24 , 19586,28 , 19614,54 , 3180,14 , 19586,28 , 19614,54 , 3180,14 , 0,2 , 0,2 , {69,85,82}, 20,1 , 2778,20 , 13,5 , 4,0 , 5343,9 , 2360,6 , 2, 1, 1, 6, 7 }, // Asturian/Latin/Spain
+ { 257, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 721,11 , 721,11 , 732,16 , 748,9 , 72,10 , 384,18 , 37,5 , 8,10 , 34767,174 , 34767,174 , 158,27 , 34767,174 , 34767,174 , 158,27 , 19668,60 , 19668,60 , 19728,25 , 19668,60 , 19668,60 , 19728,25 , 659,8 , 681,13 , {88,65,70}, 38,4 , 14777,12 , 8,5 , 4,0 , 5352,5 , 5357,7 , 0, 0, 1, 6, 7 }, // Ngomba/Latin/Cameroon
+ { 258, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8249, 8250, 0,6 , 0,6 , 0,6 , 0,6 , 1602,10 , 82,17 , 37,5 , 8,10 , 34941,102 , 34941,102 , 158,27 , 34941,102 , 34941,102 , 158,27 , 19753,54 , 19753,54 , 19807,21 , 19753,54 , 19753,54 , 19807,21 , 0,2 , 0,2 , {88,65,70}, 38,4 , 14789,16 , 8,5 , 4,0 , 5364,4 , 5368,7 , 0, 0, 1, 6, 7 }, // Kako/Latin/Cameroon
+ { 259, 7, 37, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 72,10 , 384,18 , 37,5 , 8,10 , 35043,137 , 35180,142 , 35322,36 , 35043,137 , 35180,142 , 35322,36 , 19828,49 , 19828,49 , 19877,21 , 19828,49 , 19828,49 , 19877,21 , 0,2 , 0,2 , {88,65,70}, 38,4 , 14805,12 , 8,5 , 4,0 , 5375,5 , 5380,7 , 0, 0, 1, 6, 7 }, // Meta/Latin/Cameroon
+ { 260, 7, 37, 44, 46, 59, 37, 48, 45, 43, 101, 171, 187, 8220, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 27,8 , 1612,32 , 37,5 , 8,10 , 35358,164 , 35358,164 , 158,27 , 35358,164 , 35358,164 , 158,27 , 19898,111 , 19898,111 , 85,14 , 19898,111 , 19898,111 , 85,14 , 667,9 , 694,8 , {88,65,70}, 38,4 , 14817,16 , 8,5 , 4,0 , 5387,16 , 5403,7 , 0, 0, 1, 6, 7 }, // Ngiemboon/Latin/Cameroon
+ { 313, 7, 225, 46, 44, 59, 37, 48, 45, 43, 101, 8220, 8221, 8216, 8217, 0,6 , 0,6 , 0,6 , 0,6 , 560,6 , 35,18 , 18,7 , 25,12 , 35522,180 , 35522,180 , 158,27 , 35522,180 , 35522,180 , 158,27 , 20009,87 , 20009,87 , 85,14 , 20009,87 , 20009,87 , 20096,14 , 0,2 , 0,2 , {85,83,68}, 12,1 , 0,7 , 8,5 , 4,0 , 5410,12 , 5422,22 , 2, 1, 7, 6, 7 }, // Lakota/Latin/UnitedStates
+ { 314, 9, 145, 44, 160, 59, 37, 48, 45, 43, 101, 171, 187, 8222, 8221, 0,6 , 0,6 , 0,6 , 0,6 , 408,8 , 99,16 , 37,5 , 8,10 , 26449,48 , 26497,81 , 26578,24 , 26449,48 , 26497,81 , 26578,24 , 14620,30 , 20110,48 , 85,14 , 14620,30 , 20110,48 , 85,14 , 447,6 , 450,8 , {77,65,68}, 0,0 , 13959,21 , 0,4 , 4,0 , 4663,8 , 4671,6 , 2, 1, 6, 5, 6 }, // Standard Moroccan Tamazight/Tifinagh/Morocco
{ 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, 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, 0,0, 0,0, 0, 0, 0, 0, 0, 0,0, 0,0 } // trailing 0s
};
static const ushort list_pattern_part_data[] = {
-0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x1363, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c,
-0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x587, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x74, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x98f, 0x9ac,
-0x982, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x98f, 0x9ac, 0x982, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xf51, 0xf44, 0xf0b, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0x438, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793, 0x17b7, 0x1784, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x3001, 0x25, 0x32, 0x25, 0x31, 0x548c, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x67, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6a, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
-0x65, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61,
-0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x10d3, 0x10d0, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x3ba, 0x3b1, 0x3b9, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x20, 0x61, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa85, 0xaa8, 0xac7, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x20, 0x5d5, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x914, 0x930, 0x20,
-0x25, 0x32, 0x25, 0x31, 0x20, 0xe9, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c,
-0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x70,
-0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x20, 0xd0e,
-0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15, 0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c,
-0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x906, 0x923, 0x93f, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x60c, 0x200f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x15f, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5,
-0x43c, 0x4d5, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x79, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
-0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd, 0x20, 0x25, 0x32, 0x25,
-0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe41, 0xe25,
-0xe30, 0x25, 0x32, 0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x6f, 0x20, 0x25, 0x32, 0x25, 0x31,
-0x20, 0x76, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x442, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x627, 0x648,
-0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x6f, 0x2d, 0x25, 0x32, 0x49, 0x2d, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25,
-0x32, 0x25, 0x31, 0x20, 0x61, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b, 0x301, 0x261, 0x25b, 0x20, 0x25, 0x32,
-0x25, 0x31, 0x2c, 0x20, 0x1e3f, 0x62, 0x25b, 0x6e, 0x20, 0x14b, 0x301, 0x261, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x70,
-0x254, 0x70, 0x20, 0x25, 0x32
+0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x68, 0x65,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x1363, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x12a5, 0x1293, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x25, 0x32, 0x25, 0x31, 0x60c, 0x20, 0x648, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x648, 0x25, 0x32, 0x25, 0x31, 0x20, 0x648, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x587, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x76, 0x259, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x74, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c,
+0x20, 0x98f, 0x9ac, 0x982, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x98f, 0x9ac, 0x982, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xf51,
+0xf44, 0xf0b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x438, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x1014, 0x103e, 0x1004, 0x1037,
+0x103a, 0x25, 0x32, 0x25, 0x31, 0x1014, 0x103e, 0x1004, 0x1037, 0x103a, 0x25, 0x32, 0x25, 0x31, 0x20, 0x1793, 0x17b7, 0x1784, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x69, 0x20, 0x25, 0x32, 0x25, 0x31, 0x3001, 0x25, 0x32, 0x25, 0x31, 0x548c, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6f, 0x67, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x6e, 0x64,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6a, 0x61, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x20, 0x65, 0x74, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x20, 0x61, 0x67, 0x75, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x10d3,
+0x10d0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75, 0x6e, 0x64, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x3ba, 0x3b1, 0x3b9, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x61, 0x6d, 0x6d, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa85, 0xaa8, 0xac7, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0x5d5, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x914, 0x930, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xe9, 0x73, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x64, 0x61, 0x6e,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x64, 0x61, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x65, 0x20, 0x25, 0x32,
+0x25, 0x31, 0x2c, 0x20, 0xcae, 0xca4, 0xccd, 0xca4, 0xcc1, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x436, 0x430, 0x43d, 0x430, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0xbc0f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xec1, 0xea5, 0xeb0, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x20, 0x75, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x70, 0xe9, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x72,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x25, 0x32, 0x20, 0xd0e, 0xd28, 0xd4d, 0xd28, 0xd3f, 0xd35, 0x25, 0x31, 0x20, 0xd15,
+0xd42, 0xd1f, 0xd3e, 0xd24, 0xd46, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x75, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x75,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x906, 0x923, 0x93f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x930, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x60c, 0x200f, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xa05, 0xa24, 0xa47, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x219, 0x69,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x4d5, 0x43c, 0x4d5, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0xdc3, 0xdc4, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0xdc3, 0xdc4, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x69, 0x6e, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x79, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6e, 0x61, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x20, 0x6f, 0x63, 0x68, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xbae, 0xbb1, 0xbcd, 0xbb1, 0xbc1, 0xbae, 0xbcd,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0xc2e, 0xc30, 0xc3f, 0xc2f, 0xc41, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x25, 0x32, 0x25,
+0x31, 0x20, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0xe41, 0xe25, 0xe30, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6d, 0x6f, 0x20,
+0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x442, 0x430, 0x20, 0x25, 0x32, 0x25, 0x31,
+0x60c, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x627, 0x648, 0x631, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20,
+0x76, 0x61, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x76, 0xe0, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6e, 0x6f, 0x2d,
+0x25, 0x32, 0x49, 0x2d, 0x25, 0x31, 0x20, 0x6e, 0x65, 0x2d, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x6b, 0x70, 0x6c, 0x65,
+0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x6b, 0x70, 0x6c, 0x65, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x61, 0x74, 0x20, 0x25,
+0x32, 0x25, 0x31, 0x2c, 0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x2c, 0x20, 0x1e3f, 0x62, 0x25b, 0x6e,
+0x20, 0x14b, 0x301, 0x67, 0x25b, 0x20, 0x25, 0x32, 0x25, 0x31, 0x20, 0x70, 0x254, 0x70, 0x20, 0x25, 0x32
};
static const ushort date_format_data[] = {
@@ -1570,113 +1598,115 @@ static const ushort date_format_data[] = {
0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d,
0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d,
0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64,
-0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d,
-0x2d, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
-0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f, 0x79, 0x79, 0x79,
-0x79, 0x64, 0x64, 0x64, 0x64, 0x60c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79,
-0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d,
-0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x569, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d,
-0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79,
-0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x4d,
-0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0xf66,
-0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66,
-0xf0b, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64,
-0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e,
-0x4d, 0x2e, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x4d,
-0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x2d, 0x64, 0x79,
-0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x79,
-0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x4d, 0x6708, 0x64, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79,
-0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
-0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x4d, 0x2f,
-0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-0x2f, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64,
-0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
-0x2c, 0x20, 0x64, 0x20, 0x5d1, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79,
-0x79, 0x79, 0x79, 0x79, 0x2e, 0x4d, 0x4d, 0x2e, 0x64, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x4d,
-0x4d, 0x20, 0x64, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d,
-0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436, 0x27, 0x2e, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64,
-0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20, 0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
-0x64, 0xe97, 0xeb5, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c,
-0x20, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d,
-0x4d, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x64,
-0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2c,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64,
-0x20, 0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
-0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x43e, 0x43d, 0x44b, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x441, 0x430,
-0x440, 0x44b, 0x43d, 0x27, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x62f,
-0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64,
-0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20,
-0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x69, 0x6c, 0x73, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64,
-0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20,
-0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79,
-0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20,
-0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x64,
-0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x27, 0x65, 0x6e, 0x27, 0x20, 0x27, 0x64, 0x65,
-0x6e, 0x27, 0x20, 0x64, 0x3a, 0x27, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
-0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64,
-0x64, 0x1363, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79,
-0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
-0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x6cc,
-0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x20, 0x6a9,
-0x648, 0x646, 0x6cc, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x6e, 0x67, 0xe0, 0x79, 0x27, 0x20, 0x64, 0x64, 0x20, 0x4d,
-0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x6e, 0x103, 0x6d, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e,
-0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x130d, 0x122d, 0x130b,
-0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x12ee,
-0x121d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d,
-0x4d, 0x4d, 0x20, 0x27, 0x64, 0x61, 0x6c, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d,
-0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x6c, 0x69, 0x61, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
-0x1365, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x130b, 0x120b, 0x1233, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
-0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
-0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79,
-0x79, 0x79, 0x79, 0x64, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27,
-0x64, 0xe4, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d,
-0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x441, 0x44b, 0x43b,
-0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x43a, 0x4af, 0x43d, 0x44d, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64,
-0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20,
-0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x2c,
-0x20, 0x27, 0x6c, 0x79, 0x25b, 0x27, 0x30c, 0x2bc, 0x20, 0x64, 0x20, 0x27, 0x6e, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
-0x2c, 0x20, 0x79, 0x79, 0x79, 0x79
+0x64, 0x64, 0x64, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c,
+0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79,
+0x79, 0x79, 0x79, 0x64, 0x200f, 0x2f, 0x4d, 0x200f, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x60c, 0x20, 0x64,
+0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x60c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f, 0x4d, 0x2f, 0x64, 0x64,
+0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x569, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64,
+0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x28, 0x27, 0x65, 0x27, 0x29, 0x27, 0x6b, 0x6f,
+0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79,
+0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf63, 0xf7c, 0xf0b, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d,
+0x4d, 0x4d, 0x4d, 0x20, 0xf5a, 0xf7a, 0xf66, 0xf0b, 0x64, 0x64, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x64, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x79, 0x79, 0x2f, 0x4d,
+0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
+0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+0x2f, 0x4d, 0x2f, 0x64, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x6708, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x79, 0x79, 0x5e74,
+0x4d, 0x6708, 0x64, 0x65e5, 0x79, 0x79, 0x79, 0x79, 0x5e74, 0x4d, 0x4d, 0x6708, 0x64, 0x64, 0x65e5, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x27, 0x64, 0x65, 0x6e, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79,
+0x4d, 0x2f, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x2f, 0x4d, 0x4d, 0x2f, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2f,
+0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79,
+0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2d, 0x4d, 0x4d, 0x2d, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64,
+0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2d, 0x4d,
+0x4d, 0x2d, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x5d1, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x2d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x64, 0x64,
+0x2e, 0x79, 0x79, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2e, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x436,
+0x27, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x2d, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79,
+0x2d, 0x27, 0x436, 0x27, 0x2e, 0x79, 0x79, 0x2e, 0x20, 0x4d, 0x2e, 0x20, 0x64, 0x2e, 0x79, 0x79, 0x79, 0x79, 0xb144, 0x20,
+0x4d, 0xc6d4, 0x20, 0x64, 0xc77c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x20, 0xe97, 0xeb5, 0x20, 0x64, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x2e,
+0x20, 0x27, 0x67, 0x61, 0x64, 0x61, 0x27, 0x20, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x79, 0x79, 0x79, 0x79, 0x20,
+0x27, 0x6d, 0x27, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x64, 0x27, 0x2e, 0x2c, 0x20, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x64, 0x2e, 0x4d, 0x2e, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d,
+0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x433, 0x27, 0x2e, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x2c, 0x20, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x74, 0x61, 0x27, 0x2019, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x43e, 0x43d, 0x44b,
+0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x441, 0x430, 0x440, 0x44b, 0x43d, 0x27, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x20, 0x62f, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x62f, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x2e,
+0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x27, 0x69, 0x6c, 0x73, 0x27, 0x20, 0x64, 0x20, 0x27, 0x64, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79,
+0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20, 0x79, 0x79, 0x79, 0x79,
+0x20, 0x27, 0x430, 0x437, 0x27, 0x64, 0x2e, 0x20, 0x4d, 0x4d, 0x2e, 0x20, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x64,
+0x64, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79, 0x79,
+0x79, 0x4d, 0x4d, 0x2f, 0x64, 0x64, 0x2f, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x27, 0x65, 0x6e, 0x27, 0x20, 0x27, 0x64,
+0x65, 0x6e, 0x27, 0x20, 0x64, 0x3a, 0x27, 0x65, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x64, 0x2d, 0x4d, 0x4d, 0x2d, 0x79, 0x79, 0x79, 0x79, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79,
+0x20, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0xe17, 0xe35, 0xe48, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1363, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x1218, 0x12d3,
+0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x1218, 0x12d3, 0x120d, 0x1272, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x79, 0x79, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x440, 0x27,
+0x2e, 0x79, 0x79, 0x79, 0x79, 0x20, 0x646, 0x686, 0x6cc, 0x20, 0x6cc, 0x6cc, 0x644, 0x20, 0x64, 0x20, 0x646, 0x686, 0x6cc, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x64, 0x64, 0x64, 0x20, 0x6a9, 0x648, 0x646, 0x6cc, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20,
+0x27, 0x6e, 0x67, 0xe0, 0x79, 0x27, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x6e, 0x103, 0x6d, 0x27,
+0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x2e, 0x4d, 0x4d, 0x2e, 0x79, 0x79, 0x2e, 0x64, 0x64, 0x64, 0x64, 0x1361, 0x20,
+0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x130d, 0x122d, 0x130b, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64,
+0x1361, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x12ee, 0x121d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64,
+0x64, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x61, 0x6c, 0x27, 0x20,
+0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x6c, 0x69,
+0x61, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x1365, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d,
+0x20, 0x130b, 0x120b, 0x1233, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x20, 0x27, 0x64, 0x69,
+0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x69, 0x27, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x2e, 0x20, 0x4d,
+0x2e, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x2c, 0x20, 0x27, 0x64, 0xe4, 0x27, 0x20, 0x64, 0x2e, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x20, 0x27, 0x441, 0x44b, 0x43b, 0x27, 0x20,
+0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x64, 0x20, 0x27, 0x43a, 0x4af, 0x43d, 0x44d, 0x27, 0x2c, 0x20, 0x64, 0x64, 0x64, 0x64, 0x64,
+0x64, 0x64, 0x64, 0x2c, 0x20, 0x64, 0x64, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x20, 0x27, 0x64, 0x65, 0x27, 0x20, 0x79, 0x79,
+0x79, 0x79, 0x64, 0x64, 0x2f, 0x4d, 0x4d, 0x20, 0x79, 0x79, 0x79, 0x79, 0x64, 0x64, 0x64, 0x64, 0x20, 0x2c, 0x20, 0x27,
+0x6c, 0x79, 0x25b, 0x27, 0x30c, 0x2bc, 0x20, 0x64, 0x20, 0x27, 0x6e, 0x61, 0x27, 0x20, 0x4d, 0x4d, 0x4d, 0x4d, 0x2c, 0x20,
+0x79, 0x79, 0x79, 0x79
};
static const ushort time_format_data[] = {
0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x68, 0x3a,
0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x48, 0x3a,
-0x6d, 0x6d, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x41, 0x50, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x2e, 0x41, 0x50, 0x20,
-0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x2e, 0x6d, 0x6d, 0x2e,
-0x20, 0x41, 0x50, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0xf46, 0xf74, 0xf0b, 0xf5a, 0xf7c,
-0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0xf46, 0xf74, 0xf0b,
-0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20,
-0x41, 0x50, 0x20, 0x74, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x48,
-0x2e, 0x6d, 0x6d, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x74, 0x41,
-0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x41, 0x50, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x68, 0x3a, 0x6d,
-0x6d, 0x3a, 0x73, 0x73, 0x20, 0x5b, 0x74, 0x5d, 0x74, 0x41, 0x50, 0x68, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x48,
-0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d,
-0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27, 0x73, 0x27, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20,
-0x74, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27,
-0x73, 0x27, 0x20, 0x74, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x68, 0x27, 0x20, 0x74, 0x68, 0x68,
-0x3a, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x48,
-0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68,
-0xc2dc, 0x20, 0x6d, 0xbd84, 0x20, 0x73, 0xcd08, 0x20, 0x74, 0x48, 0x20, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0x20, 0xe99, 0xeb2, 0xe97,
-0xeb5, 0x20, 0x73, 0x73, 0x20, 0xea7, 0xeb4, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x68, 0x2d, 0x6d, 0x6d, 0x20, 0x41, 0x50,
-0x68, 0x2d, 0x6d, 0x6d, 0x2d, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0x27, 0x6b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x48,
-0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x28, 0x74, 0x29, 0x48,
-0x48, 0x20, 0x27, 0x447, 0x430, 0x441, 0x43e, 0x432, 0x430, 0x27, 0x2c, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x43c, 0x438, 0x43d, 0x443,
-0x442, 0x430, 0x27, 0x2c, 0x20, 0x73, 0x73, 0x20, 0x27, 0x441, 0x435, 0x43a, 0x443, 0x43d, 0x434, 0x438, 0x27, 0x20, 0x74, 0x41,
-0x50, 0x20, 0x68, 0x2e, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48,
-0x48, 0x27, 0x68, 0x27, 0x27, 0x27, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x48, 0x27, 0x48, 0x27, 0x6d, 0x6d,
-0x27, 0x27, 0x73, 0x73, 0x27, 0x27, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, 0x20,
-0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, 0x27,
-0x67, 0x61, 0x27, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74,
-0x74, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50
+0x6d, 0x6d, 0x48, 0x3a, 0x6d, 0x6d, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x2e, 0x6d, 0x6d,
+0x2e, 0x20, 0x41, 0x50, 0x68, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74, 0xf46, 0xf74, 0xf0b, 0xf5a,
+0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0xf46, 0xf74,
+0xf0b, 0xf5a, 0xf7c, 0xf51, 0xf0b, 0x20, 0x68, 0x20, 0xf66, 0xf90, 0xf62, 0xf0b, 0xf58, 0xf0b, 0x20, 0x6d, 0x6d, 0x3a, 0x73, 0x73,
+0x20, 0x41, 0x50, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x48,
+0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73, 0x20, 0x74, 0x48, 0x2e, 0x6d, 0x6d, 0x48, 0x2e, 0x6d, 0x6d, 0x2e, 0x73, 0x73,
+0x20, 0x74, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x74, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x41, 0x50,
+0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x5b, 0x74, 0x5d, 0x74, 0x41,
+0x50, 0x68, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x48, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27,
+0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20, 0x27, 0x73, 0x27, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x2e, 0x73, 0x73,
+0x20, 0x74, 0x48, 0x20, 0x27, 0x68, 0x27, 0x20, 0x6d, 0x6d, 0x20, 0x27, 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x73, 0x73, 0x20,
+0x27, 0x73, 0x27, 0x20, 0x74, 0x48, 0x48, 0x2e, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x27, 0x68, 0x27, 0x20, 0x74, 0x68,
+0x68, 0x3a, 0x6d, 0x6d, 0x20, 0x41, 0x50, 0x68, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x74,
+0x48, 0x6642, 0x6d, 0x6d, 0x5206, 0x73, 0x73, 0x79d2, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20,
+0x68, 0xc2dc, 0x20, 0x6d, 0xbd84, 0x20, 0x73, 0xcd08, 0x20, 0x74, 0x48, 0x20, 0xec2, 0xea1, 0xe87, 0x20, 0x6d, 0x20, 0xe99, 0xeb2,
+0xe97, 0xeb5, 0x20, 0x73, 0x73, 0x20, 0xea7, 0xeb4, 0xe99, 0xeb2, 0xe97, 0xeb5, 0x20, 0x74, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73,
+0x73, 0x20, 0x28, 0x74, 0x29, 0x48, 0x48, 0x20, 0x27, 0x447, 0x430, 0x441, 0x43e, 0x432, 0x430, 0x27, 0x2c, 0x20, 0x6d, 0x6d,
+0x20, 0x27, 0x43c, 0x438, 0x43d, 0x443, 0x442, 0x430, 0x27, 0x2c, 0x20, 0x73, 0x73, 0x20, 0x27, 0x441, 0x435, 0x43a, 0x443, 0x43d,
+0x434, 0x438, 0x27, 0x20, 0x74, 0x41, 0x50, 0x20, 0x68, 0x2e, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x2e, 0x6d, 0x6d, 0x2e,
+0x73, 0x73, 0x20, 0x74, 0x48, 0x48, 0x27, 0x68, 0x27, 0x27, 0x27, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x68, 0x3a,
+0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50, 0x20, 0x28, 0x74, 0x29, 0x48, 0x48, 0x27, 0x48, 0x27, 0x6d, 0x6d, 0x27,
+0x27, 0x73, 0x73, 0x27, 0x27, 0x20, 0x74, 0x27, 0x6b, 0x6c, 0x27, 0x2e, 0x20, 0x48, 0x48, 0x3a, 0x6d, 0x6d, 0x3a, 0x73,
+0x73, 0x20, 0x74, 0x48, 0x20, 0xe19, 0xe32, 0xe2c, 0xe34, 0xe01, 0xe32, 0x20, 0x6d, 0x6d, 0x20, 0xe19, 0xe32, 0xe17, 0xe35, 0x20,
+0x73, 0x73, 0x20, 0xe27, 0xe34, 0xe19, 0xe32, 0xe17, 0xe35, 0x20, 0x74, 0x41, 0x50, 0x20, 0x27, 0x67, 0x61, 0x27, 0x20, 0x68,
+0x3a, 0x6d, 0x6d, 0x41, 0x50, 0x20, 0x68, 0x3a, 0x6d, 0x6d, 0x3a, 0x73, 0x73, 0x20, 0x74, 0x74, 0x20, 0x68, 0x3a, 0x6d,
+0x6d, 0x3a, 0x73, 0x73, 0x20, 0x41, 0x50
};
static const ushort months_data[] = {
@@ -1760,1674 +1790,1712 @@ static const ushort months_data[] = {
0x3b, 0x623, 0x64a, 0x644, 0x648, 0x644, 0x3b, 0x62a, 0x634, 0x631, 0x6cc, 0x646, 0x20, 0x627, 0x644, 0x623, 0x648, 0x644, 0x3b, 0x62a,
0x634, 0x631, 0x64a, 0x646, 0x20, 0x627, 0x644, 0x62b, 0x627, 0x646, 0x64a, 0x3b, 0x643, 0x627, 0x646, 0x648, 0x646, 0x20, 0x627, 0x644,
0x623, 0x648, 0x644, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631,
-0x633, 0x3b, 0x623, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648,
-0x644, 0x64a, 0x648, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628,
-0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631,
-0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0xfe84, 0x628, 0xfeae, 0x64a, 0xfedf, 0x3b, 0x645,
-0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x633,
-0x628, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f,
-0x64a, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x625, 0x3b, 0x645, 0x3b, 0xfee5, 0x3b, 0xfedd, 0x3b,
-0x63a, 0x3b, 0x634, 0x3b, 0xfed9, 0x3b, 0xfe8f, 0x3b, 0xfea9, 0x3b, 0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627,
-0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x625, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648,
-0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x633, 0x628, 0x62a, 0x645, 0x628, 0x631,
-0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x646, 0x628, 0x631, 0x3b, 0x62f, 0x64a, 0x633, 0x645, 0x628, 0x631,
-0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0xfe83, 0x3b, 0x645, 0x3b, 0xfee5, 0x3b, 0xfedd, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0xfed9,
-0x3b, 0xfe8f, 0x3b, 0xfea9, 0x3b, 0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f, 0x57e, 0x3b, 0x574, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580,
-0x3b, 0x574, 0x575, 0x57d, 0x3b, 0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c, 0x57d, 0x3b, 0x585, 0x563, 0x57d, 0x3b, 0x57d, 0x565, 0x57a,
-0x3b, 0x570, 0x578, 0x56f, 0x3b, 0x576, 0x578, 0x575, 0x3b, 0x564, 0x565, 0x56f, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580,
-0x56b, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561, 0x580, 0x57f, 0x56b, 0x3b, 0x561, 0x57a, 0x580,
-0x56b, 0x56c, 0x56b, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b, 0x57d, 0x56b, 0x3b, 0x570,
-0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x56b, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x56b, 0x3b, 0x57d, 0x565, 0x57a, 0x57f,
-0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x576, 0x578,
-0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x540,
-0x3b, 0x553, 0x3b, 0x544, 0x3b, 0x531, 0x3b, 0x544, 0x3b, 0x540, 0x3b, 0x540, 0x3b, 0x555, 0x3b, 0x54d, 0x3b, 0x540, 0x3b, 0x546,
-0x3b, 0x534, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a,
-0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987,
-0x3b, 0x986, 0x997, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x3b,
-0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1,
-0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7,
-0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b, 0x99b, 0x9c7, 0x9aa,
-0x9cd, 0x9a4, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8, 0x9f1, 0x9c7, 0x9ae,
-0x9cd, 0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76,
-0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b, 0x69, 0x79, 0x6c,
-0x3b, 0x61, 0x76, 0x71, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b, 0x64, 0x65, 0x6b,
-0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b,
-0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79, 0x75, 0x6c, 0x3b,
-0x41, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x79,
-0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430,
+0x633, 0x3b, 0x625, 0x628, 0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a,
+0x648, 0x644, 0x64a, 0x648, 0x3b, 0x623, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648,
+0x628, 0x631, 0x3b, 0x646, 0x648, 0x641, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x645, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b,
+0x645, 0x3b, 0x625, 0x3b, 0x648, 0x3b, 0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b,
+0x64a, 0x646, 0x627, 0x64a, 0x631, 0x3b, 0x641, 0x628, 0x631, 0x627, 0x64a, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x623, 0x628,
+0x631, 0x64a, 0x644, 0x3b, 0x645, 0x627, 0x64a, 0x3b, 0x64a, 0x648, 0x646, 0x64a, 0x648, 0x3b, 0x64a, 0x648, 0x644, 0x64a, 0x648, 0x632,
+0x3b, 0x63a, 0x634, 0x62a, 0x3b, 0x634, 0x62a, 0x646, 0x628, 0x631, 0x3b, 0x623, 0x643, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648,
+0x646, 0x628, 0x631, 0x3b, 0x62f, 0x62c, 0x646, 0x628, 0x631, 0x3b, 0x64a, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x623, 0x3b, 0x645, 0x3b,
+0x646, 0x3b, 0x644, 0x3b, 0x63a, 0x3b, 0x634, 0x3b, 0x643, 0x3b, 0x628, 0x3b, 0x62f, 0x3b, 0x570, 0x576, 0x57e, 0x3b, 0x583, 0x57f,
+0x57e, 0x3b, 0x574, 0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x3b, 0x574, 0x575, 0x57d, 0x3b, 0x570, 0x576, 0x57d, 0x3b, 0x570, 0x56c,
+0x57d, 0x3b, 0x585, 0x563, 0x57d, 0x3b, 0x57d, 0x57a, 0x57f, 0x3b, 0x570, 0x56f, 0x57f, 0x3b, 0x576, 0x575, 0x574, 0x3b, 0x564, 0x56f,
+0x57f, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x3b, 0x574, 0x561,
+0x580, 0x57f, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x3b, 0x570, 0x578, 0x582, 0x576, 0x56b,
+0x57d, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578, 0x57d, 0x3b, 0x57d, 0x565, 0x57a,
+0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x576, 0x578, 0x575,
+0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x3b, 0x540, 0x3b, 0x553, 0x3b,
+0x544, 0x3b, 0x531, 0x3b, 0x544, 0x3b, 0x540, 0x3b, 0x540, 0x3b, 0x555, 0x3b, 0x54d, 0x3b, 0x540, 0x3b, 0x546, 0x3b, 0x534, 0x3b,
+0x570, 0x578, 0x582, 0x576, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x583, 0x565, 0x57f, 0x580, 0x57e, 0x561, 0x580, 0x56b, 0x3b, 0x574, 0x561,
+0x580, 0x57f, 0x56b, 0x3b, 0x561, 0x57a, 0x580, 0x56b, 0x56c, 0x56b, 0x3b, 0x574, 0x561, 0x575, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578,
+0x582, 0x576, 0x56b, 0x57d, 0x56b, 0x3b, 0x570, 0x578, 0x582, 0x56c, 0x56b, 0x57d, 0x56b, 0x3b, 0x585, 0x563, 0x578, 0x57d, 0x57f, 0x578,
+0x57d, 0x56b, 0x3b, 0x57d, 0x565, 0x57a, 0x57f, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x570, 0x578, 0x56f, 0x57f, 0x565, 0x574,
+0x562, 0x565, 0x580, 0x56b, 0x3b, 0x576, 0x578, 0x575, 0x565, 0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x564, 0x565, 0x56f, 0x57f, 0x565,
+0x574, 0x562, 0x565, 0x580, 0x56b, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9f0, 0x9c1, 0x3b, 0x9ae, 0x9be,
+0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1,
+0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x3b, 0x9a8,
+0x9ad, 0x9c7, 0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x3b, 0x99c, 0x9be, 0x9a8, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac,
+0x9cd, 0x9f0, 0x9c1, 0x9f1, 0x9be, 0x9f0, 0x9c0, 0x3b, 0x9ae, 0x9be, 0x9f0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9f0, 0x9bf, 0x9b2,
+0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b7, 0x9cd, 0x99f, 0x3b,
+0x99b, 0x9c7, 0x9aa, 0x9cd, 0x9a4, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9f0, 0x3b, 0x9a8,
+0x9f1, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x9a1, 0x9bf, 0x99a, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9f0, 0x3b, 0x79, 0x61, 0x6e, 0x3b,
+0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x6e, 0x3b,
+0x69, 0x79, 0x6c, 0x3b, 0x61, 0x76, 0x71, 0x3b, 0x73, 0x65, 0x6e, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x79, 0x3b,
+0x64, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d, 0x61,
+0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x130, 0x79, 0x75, 0x6e, 0x3b, 0x130, 0x79,
+0x75, 0x6c, 0x3b, 0x41, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4f,
+0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62, 0x72,
+0x3b, 0x79, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b,
+0x61, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x69, 0x79, 0x75, 0x6e, 0x3b, 0x69, 0x79, 0x75, 0x6c, 0x3b,
+0x61, 0x76, 0x71, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x79,
+0x61, 0x62, 0x72, 0x3b, 0x6e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x64, 0x65, 0x6b, 0x61, 0x62, 0x72, 0x3b, 0x458, 0x430,
0x43d, 0x432, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440,
0x435, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x458, 0x443, 0x43d, 0x3b, 0x438, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433,
0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x458, 0x430, 0x431, 0x440,
-0x3b, 0x43d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, 0x74, 0x3b, 0x6f,
-0x74, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x69, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x65, 0x6b, 0x61, 0x3b, 0x75,
-0x7a, 0x74, 0x3b, 0x61, 0x62, 0x75, 0x3b, 0x69, 0x72, 0x61, 0x3b, 0x75, 0x72, 0x72, 0x3b, 0x61, 0x7a, 0x61, 0x3b, 0x61,
-0x62, 0x65, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61,
-0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x3b, 0x61, 0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69,
-0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x75, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b,
-0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61,
-0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b,
-0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b,
-0x99c, 0x9be, 0x9a8, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0,
-0x9c0, 0x3b, 0x9ae, 0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1,
-0x9a8, 0x3b, 0x99c, 0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7,
-0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0,
-0x3b, 0x9a1, 0x9bf, 0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae, 0x9be, 0x3b, 0x98f,
-0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b,
-0x9a1, 0x9bf, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23, 0x3b, 0xf5f, 0xfb3,
-0xf0b, 0xf24, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27, 0x3b, 0xf5f, 0xfb3,
-0xf0b, 0xf28, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf21, 0x3b,
-0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf66,
-0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b,
-0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
-0xf5e, 0xf72, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66,
-0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
-0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62,
-0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54,
-0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1,
-0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1,
-0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22,
-0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21,
-0x3b, 0xf21, 0xf22, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b,
-0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf5f,
-0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b,
-0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b,
-0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b,
-0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0x39,
-0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x3b,
-0x4d, 0x65, 0x75, 0x72, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x3b, 0x47, 0x6f,
-0x75, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75,
-0x3b, 0x4b, 0x65, 0x72, 0x3b, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65,
-0x72, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d,
-0x65, 0x7a, 0x68, 0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b,
-0x47, 0x77, 0x65, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72,
-0x7a, 0x75, 0x3b, 0x44f, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f,
-0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b,
-0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a,
-0x2e, 0x3b, 0x44f, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430,
-0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438,
-0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a,
-0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c,
-0x432, 0x440, 0x438, 0x3b, 0x44f, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b,
-0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x3b, 0x1016, 0x1031, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027,
-0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x3b, 0x1029, 0x3b, 0x1005, 0x1000, 0x103a, 0x3b, 0x1021, 0x1031,
-0x102c, 0x1000, 0x103a, 0x3b, 0x1014, 0x102d, 0x102f, 0x3b, 0x1012, 0x102e, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b,
-0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b,
-0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014, 0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010,
-0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018,
-0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007,
-0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027, 0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014,
-0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x442,
-0x440, 0x430, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a,
-0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b,
-0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456,
-0x43a, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456,
-0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d,
-0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430,
-0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, 0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b,
-0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e,
-0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456,
-0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d,
-0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441, 0x430, 0x43a, 0x430,
-0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440,
-0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435, 0x43d, 0x44c, 0x3b,
-0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x3b,
-0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b, 0x441, 0x3b, 0x43b,
-0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x442, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b, 0x43b, 0x3b, 0x441,
-0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797, 0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1,
-0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790, 0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a,
-0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789, 0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7,
-0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc, 0x3b, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62,
-0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75,
-0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74,
-0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65,
-0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67,
-0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73,
-0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x67, 0x3b, 0x66, 0x3b, 0x6d, 0x3b,
-0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x64, 0x65,
-0x20, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61,
-0x72, 0xe7, 0x3b, 0x64, 0x2019, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65,
-0x20, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x2e, 0x3b,
-0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f,
-0x76, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x64, 0x65, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b,
-0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x64, 0x2019,
-0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6e,
-0x79, 0x3b, 0x64, 0x65, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c, 0x3b, 0x64, 0x2019, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b,
-0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x2019, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72,
-0x65, 0x3b, 0x64, 0x65, 0x20, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x64, 0x65, 0x73,
-0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b,
-0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x31, 0x6708, 0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, 0x34,
-0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38, 0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, 0x6708,
-0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x4e00, 0x6708, 0x3b, 0x4e8c, 0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, 0x6708,
-0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708, 0x3b, 0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, 0x5341,
-0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75, 0x3b,
-0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, 0x3b,
-0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x74, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, 0x65,
-0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, 0x3b,
-0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, 0x61,
-0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, 0x75,
-0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x69,
-0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x31, 0x2e, 0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b, 0x34,
-0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38, 0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30, 0x2e,
-0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, 0x65,
-0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, 0x61,
-0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x6e,
-0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b, 0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69,
-0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, 0x72,
-0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x3b, 0xfa, 0x6e, 0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b, 0x64,
-0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, 0x10d, 0x76, 0x6e, 0x3b, 0x10d, 0x76, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x7a,
-0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x70, 0x72, 0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65, 0x6e,
-0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e, 0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, 0x6b,
-0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65,
-0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, 0x6c,
-0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x3b, 0xfa,
-0x3b, 0x62, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, 0x10d, 0x3b, 0x10d, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x159, 0x3b, 0x6c, 0x3b, 0x70,
-0x3b, 0x6c, 0x65, 0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x6e, 0x61, 0x3b,
-0x64, 0x75, 0x62, 0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x6e, 0x61, 0x3b,
-0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x61, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b,
-0x159, 0xed, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x73,
-0x69, 0x6e, 0x63, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72,
-0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70,
-0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b,
-0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
-0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74,
-0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e,
-0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a,
-0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e,
-0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x3b,
-0x66, 0x65, 0x62, 0x3b, 0x6d, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b,
-0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b,
-0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69,
-0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e,
-0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74,
-0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62,
-0x2e, 0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e,
-0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e,
-0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc30, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc19,
-0xd801, 0xdc2f, 0xd801, 0xdc3a, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc2a, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc01, 0xd801, 0xdc39, 0xd801, 0xdc49, 0x3b, 0xd801,
-0xdc23, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4a, 0x3b, 0xd801, 0xdc02,
-0xd801, 0xdc40, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc2f, 0xd801, 0xdc39, 0x3b, 0xd801, 0xdc09, 0xd801, 0xdc3f, 0xd801, 0xdc3b, 0x3b, 0xd801, 0xdc24, 0xd801,
-0xdc2c, 0xd801, 0xdc42, 0x3b, 0xd801, 0xdc14, 0xd801, 0xdc28, 0xd801, 0xdc45, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc30, 0xd801, 0xdc4c, 0xd801, 0xdc37, 0xd801,
-0xdc2d, 0xd801, 0xdc2f, 0xd801, 0xdc49, 0xd801, 0xdc28, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc2f, 0xd801, 0xdc3a, 0xd801, 0xdc49, 0xd801, 0xdc2d, 0xd801, 0xdc2f,
-0xd801, 0xdc49, 0xd801, 0xdc28, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc2a, 0xd801, 0xdc49, 0xd801, 0xdc3d, 0x3b, 0xd801, 0xdc01, 0xd801, 0xdc39, 0xd801, 0xdc49,
-0xd801, 0xdc2e, 0xd801, 0xdc4a, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc16, 0xd801,
-0xdc2d, 0xd801, 0xdc4a, 0xd801, 0xdc34, 0x3b, 0xd801, 0xdc02, 0xd801, 0xdc40, 0xd801, 0xdc32, 0xd801, 0xdc45, 0xd801, 0xdc3b, 0x3b, 0xd801, 0xdc1d, 0xd801,
-0xdc2f, 0xd801, 0xdc39, 0xd801, 0xdc3b, 0xd801, 0xdc2f, 0xd801, 0xdc4b, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc09, 0xd801, 0xdc3f,
-0xd801, 0xdc3b, 0xd801, 0xdc2c, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc24, 0xd801, 0xdc2c, 0xd801, 0xdc42, 0xd801, 0xdc2f, 0xd801,
-0xdc4b, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc14, 0xd801, 0xdc28, 0xd801, 0xdc45, 0xd801, 0xdc2f, 0xd801, 0xdc4b, 0xd801, 0xdc3a,
-0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc16, 0x3b, 0xd801, 0xdc19, 0x3b, 0xd801, 0xdc23, 0x3b, 0xd801, 0xdc01, 0x3b, 0xd801, 0xdc23, 0x3b,
-0xd801, 0xdc16, 0x3b, 0xd801, 0xdc16, 0x3b, 0xd801, 0xdc02, 0x3b, 0xd801, 0xdc1d, 0x3b, 0xd801, 0xdc09, 0x3b, 0xd801, 0xdc24, 0x3b, 0xd801, 0xdc14,
-0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70,
-0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75,
-0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b,
-0x6a, 0x61, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72,
-0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b,
-0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x64, 0x65, 0x74, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d,
-0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66,
-0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a,
-0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64,
-0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61,
-0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75,
-0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73,
-0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61,
-0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73,
-0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b,
-0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69,
-0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b,
-0x75, 0x75, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75,
-0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c,
-0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75,
-0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b,
-0x54, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b,
-0x4d, 0x3b, 0x4a, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69,
-0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x75,
-0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b,
-0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61,
-0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b,
-0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x74,
-0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66,
-0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a,
-0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e,
-0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76,
-0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72,
-0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74, 0x3b,
-0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62,
-0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65,
-0x3b, 0x46, 0x61, 0x6f, 0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72, 0x3b, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, 0x62,
-0x6c, 0x3b, 0x43, 0xe8, 0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68, 0x3b, 0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, 0x6e,
-0x61, 0x3b, 0x53, 0x75, 0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, 0x62,
-0x68, 0x3b, 0x41, 0x6d, 0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, 0x47,
-0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x69,
-0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8, 0x69, 0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20,
-0x74, 0x2d, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, 0x61,
-0x72, 0x3b, 0x41, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61, 0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53,
-0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xe0, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, 0x6e,
-0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61,
-0x63, 0x68, 0x64, 0x3b, 0x46, 0x41, 0x3b, 0x47, 0x45, 0x3b, 0x4d, 0xc0, 0x3b, 0x47, 0x49, 0x3b, 0x43, 0xc8, 0x3b, 0xd2,
-0x47, 0x3b, 0x49, 0x55, 0x3b, 0x4c, 0xd9, 0x3b, 0x53, 0x55, 0x3b, 0x44, 0xc0, 0x3b, 0x53, 0x41, 0x3b, 0x44, 0xd9, 0x3b,
-0x58, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b,
-0x58, 0x75, 0xf1, 0x3b, 0x58, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x75, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x58, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72,
-0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69,
-0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b,
-0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76,
-0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d,
-0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x10d8,
-0x10d0, 0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0, 0x10d8, 0x3b, 0x10d8,
-0x10d5, 0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5, 0x10e2, 0x3b, 0x10dc,
-0x10dd, 0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x10d4, 0x10e0,
-0x10d5, 0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0,
-0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d0, 0x10d2,
-0x10d5, 0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dd, 0x10e5, 0x10e2,
-0x10dd, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x10d4,
-0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8, 0x3b, 0x10d8, 0x3b,
-0x10d0, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4,
-0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75,
-0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61,
-0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70,
-0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75,
-0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62,
-0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e,
-0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b,
-0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b,
-0x4a, 0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b,
-0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72,
-0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
-0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e,
-0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72,
-0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69,
-0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3ac, 0x3c1,
-0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b, 0x391,
-0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399,
-0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf,
-0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c,
-0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bb, 0x3b9, 0x3bf, 0x3c2,
-0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9,
-0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9,
-0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b, 0x3a6, 0x3b, 0x39c, 0x3b,
-0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b, 0x394, 0x3b, 0x399, 0x3b1,
-0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1, 0x3ca, 0x3b, 0x399, 0x3bf,
-0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b,
-0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x3a6,
-0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391,
-0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3af, 0x3bf,
-0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3, 0x3c4, 0x3bf, 0x3c5, 0x3b,
-0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9, 0x3b2, 0x3c1, 0x3af, 0x3bf,
-0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af,
-0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b,
-0x6d, 0x61, 0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x69, 0x3b, 0x6a,
-0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x69, 0x3b, 0x73,
-0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0xa9c,
-0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f,
-0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91,
-0xa97, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1, 0xabf,
-0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0xa86,
-0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c,
-0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7,
-0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0,
-0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b, 0xaae, 0xabe, 0x3b, 0xa8f,
-0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1, 0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b, 0xaa8, 0x3b, 0xaa1, 0xabf,
-0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a,
-0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88,
-0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8,
-0xab5, 0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7,
-0xaac, 0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2,
-0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b,
-0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5,
-0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46,
-0x61, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59,
-0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44,
-0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x75, 0x72, 0x61, 0x69, 0x72, 0x75,
-0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b,
-0x59, 0x75, 0x6e, 0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74,
-0x75, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b,
-0x44, 0x69, 0x73, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b,
-0x59, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3, 0x3b, 0x5e4, 0x5d1, 0x5e8,
-0x5f3, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5f3, 0x3b,
-0x5d9, 0x5d5, 0x5dc, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5f3, 0x3b,
-0x5e0, 0x5d5, 0x5d1, 0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5d5,
-0x5d0, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0,
-0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1, 0x5e8,
-0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5d1,
-0x5e8, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x3b, 0x5de, 0x5d0,
-0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x3b, 0x5d0, 0x5d5,
-0x5e7, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x930, 0x935, 0x930,
-0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942,
-0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x92e, 0x94d, 0x92c,
-0x930, 0x3b, 0x905, 0x915, 0x94d, 0x924, 0x942, 0x92c, 0x930, 0x3b, 0x928, 0x935, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938,
-0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x93c, 0x3b, 0x92e, 0x93e, 0x3b, 0x905, 0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b,
-0x91c, 0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b,
-0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e, 0x3b, 0xe1, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a,
-0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65,
-0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a,
-0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75,
-0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0xe1, 0x6a, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69,
-0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b,
-0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46,
-0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b,
-0x44, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x7a,
-0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
-0x70, 0x72, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0xe1, 0x67, 0xfa, 0x3b, 0x73,
-0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0xf3, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61,
-0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0xfa, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c,
-0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74,
-0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e,
-0xf3, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46,
-0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
-0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x4c, 0x3b, 0x4f,
-0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70,
-0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69,
-0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69,
-0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73,
-0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
-0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b,
-0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b,
-0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62,
-0x72, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b,
-0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x75, 0x67,
-0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62,
-0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65,
-0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62,
-0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e,
-0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x4e, 0x6f,
-0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72, 0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x72, 0x61, 0x3b, 0x4d, 0xe1,
-0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65, 0xe1, 0x6e, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x6e,
-0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61, 0x6d, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e,
-0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x44, 0x65, 0x69,
-0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69,
-0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b,
-0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65,
-0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x67, 0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75,
-0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x74, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69,
-0x63, 0x3b, 0x47, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x4d,
-0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x4d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x47,
-0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x4c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b,
-0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f,
-0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b,
-0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b,
-0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72,
-0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65, 0x3b, 0x6d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75,
-0x67, 0x6e, 0x6f, 0x3b, 0x6c, 0x75, 0x67, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65,
-0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b,
-0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcc1, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd,
-0xcb0, 0xcbf, 0xcb2, 0xccd, 0x200c, 0x200c, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b,
-0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x200c, 0x3b, 0xc85,
-0xc95, 0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6,
-0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcc0, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcb5, 0xcb0, 0xcc0, 0x3b,
-0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8e, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b, 0xcae, 0xcc6, 0x3b, 0xc9c, 0xcc2,
-0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b, 0xcb8, 0xcaa, 0xccd, 0xc9f, 0xcc6,
-0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8, 0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0,
-0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab, 0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8e,
-0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, 0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1,
-0xcbf, 0x3b, 0xc9c, 0x3b, 0xcab, 0xcc6, 0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1,
-0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, 0x3b, 0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0x62c, 0x646, 0x624, 0x631, 0x6cc, 0x3b, 0x641,
-0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x655, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x654,
-0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b, 0x62c, 0x648, 0x657, 0x644, 0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633,
-0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x657, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f,
-0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627,
-0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x49b, 0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d,
-0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9, 0x443, 0x2e, 0x3b, 0x43c, 0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448,
-0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430, 0x43c, 0x2e, 0x3b, 0x49b, 0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b,
-0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435, 0x43b, 0x442, 0x2e, 0x3b, 0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f,
-0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443, 0x440, 0x44b, 0x437, 0x3b, 0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b,
-0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441, 0x44b, 0x43c, 0x3b, 0x448, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437,
-0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af, 0x439, 0x435, 0x43a, 0x3b, 0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430,
-0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b, 0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61,
-0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61,
-0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b,
-0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75, 0x2e, 0x3b, 0x75, 0x6b, 0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d,
-0x61, 0x3b, 0x47, 0x61, 0x73, 0x68, 0x79, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77,
-0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61, 0x3b, 0x47, 0x69, 0x63, 0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d,
-0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b,
-0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b, 0x55, 0x6b, 0x77, 0x61, 0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68,
-0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x55, 0x6b, 0x75, 0x62, 0x6f, 0x7a, 0x61, 0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424,
-0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x2e, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418,
-0x44e, 0x43d, 0x2e, 0x3b, 0x418, 0x44e, 0x43b, 0x2e, 0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, 0x435, 0x43d, 0x2e, 0x3b, 0x41e,
-0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c,
-0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c,
-0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441,
-0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d,
-0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444,
-0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e,
-0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a,
-0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b,
-0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b,
-0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442,
-0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e,
-0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33,
-0xc6d4, 0x3b, 0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b,
-0x31, 0x30, 0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47, 0x61, 0x73,
-0x2e, 0x3b, 0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, 0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b, 0x61, 0x6d,
-0x2e, 0x3b, 0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55, 0x6b, 0x77,
-0x2e, 0x3b, 0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x52, 0x75,
-0x68, 0x75, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e, 0x64, 0x61,
-0x6d, 0x75, 0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, 0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65, 0x73, 0x68,
-0x69, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x61, 0x72,
-0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74, 0x75, 0x3b,
-0x4d, 0x75, 0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, 0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0xea1, 0x2e,
-0xe81, 0x2e, 0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb5, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, 0xe9e,
-0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b,
-0xe81, 0x2e, 0xe8d, 0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b,
-0xea1, 0xeb1, 0xe87, 0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, 0xea1,
-0xeaa, 0xeb2, 0x3b, 0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, 0xecd,
-0xea5, 0xeb0, 0xe81, 0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, 0xeb8,
-0xea5, 0xeb2, 0x3b, 0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, 0xea7, 0xeb2, 0x3b, 0xea1, 0x2e, 0xe81, 0x2e, 0x3b,
-0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe9e, 0x2e, 0x3b,
-0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b, 0xe81, 0x2e, 0xe8d, 0x2e,
-0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x76,
-0x2e, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d,
-0x61, 0x69, 0x6a, 0x73, 0x3b, 0x4a, 0x16b, 0x6e, 0x2e, 0x3b, 0x4a, 0x16b, 0x6c, 0x2e, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b,
-0x53, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e,
-0x3b, 0x4a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b,
-0x4d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x69, 0x6a, 0x73, 0x3b,
-0x4a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x4a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74,
-0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69,
-0x73, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69,
-0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b,
-0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, 0x2e,
-0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76,
-0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, 0x72,
-0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b,
-0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b,
-0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6f,
-0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, 0x65,
-0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, 0x3b,
-0x61, 0x70, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, 0x3b,
-0x73, 0x74, 0x62, 0x3b, 0x254, 0x74, 0x62, 0x3b, 0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, 0x7a,
-0xe1, 0x20, 0x79, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20,
-0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1,
-0x74, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1,
-0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20,
-0x79, 0x61, 0x20, 0x6d, 0x6f, 0x74, 0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e,
-0x73, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62,
-0x65, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e,
-0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20,
-0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1,
-0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x79,
-0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, 0x6e,
-0x3b, 0x64, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x2e, 0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, 0x62,
-0x61, 0x6c, 0x2e, 0x3b, 0x67, 0x65, 0x67, 0x2e, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x2e,
-0x3b, 0x72, 0x75, 0x67, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, 0x6c,
-0x61, 0x70, 0x6b, 0x72, 0x2e, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b,
-0x76, 0x61, 0x73, 0x61, 0x72, 0x69, 0x73, 0x3b, 0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64,
-0x69, 0x73, 0x3b, 0x67, 0x65, 0x67, 0x75, 0x17e, 0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x6c,
-0x69, 0x65, 0x70, 0x61, 0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117,
-0x6a, 0x69, 0x73, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73,
-0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42,
-0x3b, 0x4c, 0x3b, 0x52, 0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435,
-0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d,
-0x2e, 0x3b, 0x458, 0x443, 0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a,
-0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443,
-0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f,
-0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432,
+0x3b, 0x43d, 0x43e, 0x458, 0x430, 0x431, 0x440, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0x75, 0x72, 0x74, 0x2e, 0x3b,
+0x6f, 0x74, 0x73, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x69, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x2e, 0x3b,
+0x65, 0x6b, 0x61, 0x2e, 0x3b, 0x75, 0x7a, 0x74, 0x2e, 0x3b, 0x61, 0x62, 0x75, 0x2e, 0x3b, 0x69, 0x72, 0x61, 0x2e, 0x3b,
+0x75, 0x72, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x61, 0x2e, 0x3b, 0x61, 0x62, 0x65, 0x2e, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72,
+0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61,
+0x3b, 0x61, 0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x3b, 0x65, 0x6b, 0x61,
+0x69, 0x6e, 0x61, 0x3b, 0x75, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x61, 0x62, 0x75, 0x7a, 0x74, 0x75, 0x61, 0x3b,
+0x69, 0x72, 0x61, 0x69, 0x6c, 0x61, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x3b, 0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x3b,
+0x61, 0x62, 0x65, 0x6e, 0x64, 0x75, 0x61, 0x3b, 0x55, 0x3b, 0x4f, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x45, 0x3b,
+0x55, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x55, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x75, 0x72, 0x74, 0x61, 0x72, 0x72, 0x69, 0x6c,
+0x61, 0x6b, 0x3b, 0x6f, 0x74, 0x73, 0x61, 0x69, 0x6c, 0x61, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x78, 0x6f, 0x61, 0x6b,
+0x3b, 0x61, 0x70, 0x69, 0x72, 0x69, 0x6c, 0x61, 0x6b, 0x3b, 0x6d, 0x61, 0x69, 0x61, 0x74, 0x7a, 0x61, 0x6b, 0x3b, 0x65,
+0x6b, 0x61, 0x69, 0x6e, 0x61, 0x6b, 0x3b, 0x75, 0x7a, 0x74, 0x61, 0x69, 0x6c, 0x61, 0x6b, 0x3b, 0x61, 0x62, 0x75, 0x7a,
+0x74, 0x75, 0x61, 0x6b, 0x3b, 0x69, 0x72, 0x61, 0x69, 0x6c, 0x61, 0x6b, 0x3b, 0x75, 0x72, 0x72, 0x69, 0x61, 0x6b, 0x3b,
+0x61, 0x7a, 0x61, 0x72, 0x6f, 0x61, 0x6b, 0x3b, 0x61, 0x62, 0x65, 0x6e, 0x64, 0x75, 0x61, 0x6b, 0x3b, 0x99c, 0x9be, 0x9a8,
+0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ab, 0x9c7, 0x9ac, 0x9cd, 0x9b0, 0x9c1, 0x9af, 0x9bc, 0x9be, 0x9b0, 0x9c0, 0x3b, 0x9ae,
+0x9be, 0x9b0, 0x9cd, 0x99a, 0x3b, 0x98f, 0x9aa, 0x9cd, 0x9b0, 0x9bf, 0x9b2, 0x3b, 0x9ae, 0x9c7, 0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c,
+0x9c1, 0x9b2, 0x9be, 0x987, 0x3b, 0x986, 0x997, 0x9b8, 0x9cd, 0x99f, 0x3b, 0x9b8, 0x9c7, 0x9aa, 0x9cd, 0x99f, 0x9c7, 0x9ae, 0x9cd, 0x9ac,
+0x9b0, 0x3b, 0x985, 0x995, 0x9cd, 0x99f, 0x9cb, 0x9ac, 0x9b0, 0x3b, 0x9a8, 0x9ad, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x9a1, 0x9bf,
+0x9b8, 0x9c7, 0x9ae, 0x9cd, 0x9ac, 0x9b0, 0x3b, 0x99c, 0x9be, 0x3b, 0x9ab, 0x9c7, 0x3b, 0x9ae, 0x9be, 0x3b, 0x98f, 0x3b, 0x9ae, 0x9c7,
+0x3b, 0x99c, 0x9c1, 0x9a8, 0x3b, 0x99c, 0x9c1, 0x3b, 0x986, 0x3b, 0x9b8, 0x9c7, 0x3b, 0x985, 0x3b, 0x9a8, 0x3b, 0x9a1, 0x9bf, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf22, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf23, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf24, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf25, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf26, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf27, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf28, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf29, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf20, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf21, 0xf21, 0x3b, 0xf5f, 0xfb3, 0xf0b,
+0xf21, 0xf22, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72,
+0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b,
+0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b,
+0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72,
+0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
+0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51,
+0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66,
+0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xfb1, 0xf72, 0xf0b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b,
+0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21, 0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22,
+0x3b, 0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0xf24, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0xf29, 0x3b, 0xf21,
+0xf20, 0x3b, 0xf21, 0xf21, 0x3b, 0x31, 0x32, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf44, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42,
+0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf42, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3,
+0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b,
+0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3,
+0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72,
+0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b,
+0xf21, 0x3b, 0xf22, 0x3b, 0xf23, 0x3b, 0x34, 0x3b, 0xf25, 0x3b, 0xf26, 0x3b, 0xf27, 0x3b, 0xf28, 0x3b, 0x39, 0x3b, 0xf21, 0xf20,
+0x3b, 0xf21, 0xf21, 0x3b, 0xf21, 0xf22, 0x3b, 0x47, 0x65, 0x6e, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x3b, 0x4d, 0x65, 0x75,
+0x72, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x3b,
+0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65,
+0x72, 0x3b, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x43, 0x2bc, 0x68, 0x77, 0x65, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x4d,
+0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x65, 0x3b, 0x4d, 0x65, 0x7a, 0x68,
+0x65, 0x76, 0x65, 0x6e, 0x3b, 0x47, 0x6f, 0x75, 0x65, 0x72, 0x65, 0x3b, 0x45, 0x6f, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x65,
+0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x48, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65, 0x72, 0x7a, 0x75, 0x3b,
+0x44f, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b,
+0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f,
+0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f,
+0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b,
+0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x44e, 0x43d, 0x438, 0x3b, 0x44e, 0x43b, 0x438, 0x3b, 0x430, 0x432,
0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c,
0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438,
-0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e,
-0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70,
-0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79,
-0x3b, 0x46, 0x65, 0x62, 0x72, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72,
-0x69, 0x6c, 0x79, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x61, 0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41,
-0x6f, 0x67, 0x6f, 0x73, 0x69, 0x74, 0x72, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f,
-0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61,
-0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65,
-0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72,
-0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c,
-0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b,
-0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f,
-0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b,
-0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b,
-0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f,
-0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46,
-0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38,
-0xd02, 0x3b, 0xd1c, 0xd28, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e,
-0xd3e, 0xd7c, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0xd7d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c,
-0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd06, 0xd17, 0xd38, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a,
-0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c,
-0xd7c, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd1c, 0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e,
-0xd47, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd13, 0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72, 0x61, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b,
-0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75, 0x6c, 0x3b, 0x41, 0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x10b, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b,
-0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75,
-0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75, 0x6c, 0x6a, 0x75, 0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65,
-0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x10b, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b,
-0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x91c, 0x93e,
-0x928, 0x947, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930,
-0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x3b, 0x938, 0x947, 0x92a,
-0x94d, 0x91f, 0x947, 0x902, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f,
-0x938, 0x947, 0x902, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935,
-0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b,
-0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947,
-0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c,
-0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x93e, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f,
-0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x911, 0x3b, 0x938, 0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921,
-0x93f, 0x3b, 0x445, 0x443, 0x43b, 0x3b, 0x4af, 0x445, 0x44d, 0x3b, 0x431, 0x430, 0x440, 0x3b, 0x442, 0x443, 0x443, 0x3b, 0x43b, 0x443,
-0x443, 0x3b, 0x43c, 0x43e, 0x433, 0x3b, 0x43c, 0x43e, 0x440, 0x3b, 0x445, 0x43e, 0x43d, 0x3b, 0x431, 0x438, 0x447, 0x3b, 0x442, 0x430,
-0x445, 0x3b, 0x43d, 0x43e, 0x445, 0x3b, 0x433, 0x430, 0x445, 0x3b, 0x425, 0x443, 0x43b, 0x433, 0x430, 0x43d, 0x430, 0x3b, 0x4ae, 0x445,
-0x44d, 0x440, 0x3b, 0x411, 0x430, 0x440, 0x3b, 0x422, 0x443, 0x443, 0x43b, 0x430, 0x439, 0x3b, 0x41b, 0x443, 0x443, 0x3b, 0x41c, 0x43e,
-0x433, 0x43e, 0x439, 0x3b, 0x41c, 0x43e, 0x440, 0x44c, 0x3b, 0x425, 0x43e, 0x43d, 0x44c, 0x3b, 0x411, 0x438, 0x447, 0x3b, 0x422, 0x430,
-0x445, 0x438, 0x430, 0x3b, 0x41d, 0x43e, 0x445, 0x43e, 0x439, 0x3b, 0x413, 0x430, 0x445, 0x430, 0x439, 0x3b, 0x91c, 0x928, 0x3b, 0x92b,
-0x947, 0x92c, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941,
-0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x3b, 0x905, 0x917, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x3b, 0x905, 0x915, 0x94d, 0x91f,
-0x94b, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x947,
-0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x932,
-0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x91f, 0x3b,
-0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928,
-0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x967, 0x3b, 0x968,
-0x3b, 0x969, 0x3b, 0x96a, 0x3b, 0x96b, 0x3b, 0x96c, 0x3b, 0x96d, 0x3b, 0x96e, 0x3b, 0x96f, 0x3b, 0x967, 0x966, 0x3b, 0x967, 0x967,
-0x3b, 0x967, 0x968, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d,
-0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x947, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e,
-0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905,
-0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x92e,
-0x94d, 0x92c, 0x930, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d,
-0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a,
-0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
-0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65,
-0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
-0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69,
-0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e,
-0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0xb1c, 0xb3e, 0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, 0xb4d, 0xb30, 0xb41,
-0xb5f, 0xb3e, 0xb30, 0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30, 0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b,
-0xb2e, 0xb47, 0x3b, 0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c, 0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38,
-0xb47, 0xb2a, 0xb4d, 0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d,
-0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f, 0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47,
-0x3b, 0xb2e, 0xb3e, 0x3b, 0xb05, 0x3b, 0xb2e, 0xb47, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b,
-0xb05, 0x3b, 0xb28, 0x3b, 0xb21, 0xb3f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b,
-0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648,
-0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6ab, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648,
-0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc,
-0x647, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645,
-0x647, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a,
-0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633,
-0x627, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, 0x3b, 0x627,
-0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, 0x648, 0x631,
-0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, 0x3b, 0x698,
-0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc, 0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645,
-0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645,
-0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633,
-0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627,
-0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x62c, 0x648,
-0x644, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b,
-0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631,
-0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648,
-0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b,
-0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x73,
-0x74, 0x79, 0x3b, 0x6c, 0x75, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63,
-0x7a, 0x65, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73, 0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c,
-0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b,
-0x6d, 0x61, 0x72, 0x7a, 0x65, 0x63, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b,
-0x63, 0x7a, 0x65, 0x72, 0x77, 0x69, 0x65, 0x63, 0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72,
-0x70, 0x69, 0x65, 0x144, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69,
-0x65, 0x72, 0x6e, 0x69, 0x6b, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a,
-0x69, 0x65, 0x144, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b,
-0x77, 0x3b, 0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b, 0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74,
-0x65, 0x67, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d,
-0x61, 0x6a, 0x61, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69,
-0x65, 0x72, 0x70, 0x6e, 0x69, 0x61, 0x3b, 0x77, 0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64,
-0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67,
-0x72, 0x75, 0x64, 0x6e, 0x69, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
-0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73,
-0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69,
-0x72, 0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61,
-0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68,
-0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75,
-0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d,
-0x62, 0x72, 0x6f, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b,
-0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b,
-0x4f, 0x75, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b,
-0x46, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69,
-0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41,
-0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62,
-0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f,
-0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2b, 0xa3c, 0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05,
-0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, 0xa08, 0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05,
-0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70,
-0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa1c, 0x3b, 0xa2b, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b,
-0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, 0xa05, 0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631,
-0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645,
-0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a,
-0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645,
-0x628, 0x631, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73,
-0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61,
-0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b,
-0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61,
-0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74,
-0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x66, 0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b,
-0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f,
-0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65,
-0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b,
-0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e,
-0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b,
-0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e,
-0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75,
-0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x69, 0x65, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b,
-0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x69, 0x65, 0x3b, 0x69, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75,
-0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62,
-0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
-0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b,
-0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c,
-0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e,
-0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x2e, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d,
-0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x414, 0x435, 0x43a, 0x2e, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, 0x41c, 0x3b,
-0x418, 0x3b, 0x418, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444,
-0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x44f, 0x3b,
-0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e,
-0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432,
-0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b, 0x430, 0x43f,
-0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, 0x3b, 0x430,
-0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43e, 0x43a, 0x442, 0x44f,
-0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44f, 0x3b, 0x4e,
-0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x42, 0xea, 0x6c, 0x3b, 0x46,
-0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x4e, 0x67, 0x62, 0x3b, 0x4e,
-0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x75, 0x6e, 0x64,
-0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b, 0x4e, 0x67, 0x75, 0x62, 0xf9, 0x65, 0x3b, 0x42, 0xea,
-0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x65, 0x6e, 0x67, 0x75, 0x61, 0x3b, 0x4b, 0xfc,
-0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x67, 0x62, 0x65, 0x72, 0x65, 0x72, 0x65, 0x3b,
-0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b, 0x61, 0x6b, 0x61, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x3b,
-0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b,
-0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c, 0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430,
-0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a,
-0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431,
-0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b,
-0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435,
-0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430,
-0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
-0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
-0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a,
-0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61,
-0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67,
-0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61,
-0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
-0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b,
-0x6e, 0x3b, 0x64, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c,
-0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458,
-0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440,
-0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435,
-0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
-0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b,
-0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d,
-0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c,
-0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c,
-0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e,
-0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e,
-0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430,
-0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b, 0x3b, 0x43c,
-0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442,
-0x44b, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43d,
-0x43e, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44b, 0x3b, 0x50, 0x68, 0x65, 0x3b, 0x4b, 0x6f,
-0x6c, 0x3b, 0x55, 0x62, 0x65, 0x3b, 0x4d, 0x6d, 0x65, 0x3b, 0x4d, 0x6f, 0x74, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x55, 0x70,
-0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x65, 0x6f, 0x3b, 0x4d, 0x70, 0x68, 0x3b, 0x50, 0x75, 0x6e, 0x3b, 0x54, 0x73,
-0x68, 0x3b, 0x50, 0x68, 0x65, 0x73, 0x65, 0x6b, 0x67, 0x6f, 0x6e, 0x67, 0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x6f, 0x6c, 0x61,
-0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x3b, 0x4d, 0x6d, 0x65, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x74,
-0x73, 0x68, 0x65, 0x61, 0x6e, 0x6f, 0x6e, 0x67, 0x3b, 0x50, 0x68, 0x75, 0x70, 0x6a, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x68,
-0x75, 0x70, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x65, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x70,
-0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x75, 0x6e, 0x64, 0x75, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x54,
-0x73, 0x68, 0x69, 0x74, 0x77, 0x65, 0x3b, 0x46, 0x65, 0x72, 0x3b, 0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x6f, 0x70, 0x3b, 0x4d,
-0x6f, 0x72, 0x3b, 0x4d, 0x6f, 0x74, 0x3b, 0x53, 0x65, 0x65, 0x3b, 0x50, 0x68, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c,
-0x77, 0x65, 0x3b, 0x44, 0x69, 0x70, 0x3b, 0x4e, 0x67, 0x77, 0x3b, 0x53, 0x65, 0x64, 0x3b, 0x46, 0x65, 0x72, 0x69, 0x6b,
-0x67, 0x6f, 0x6e, 0x67, 0x3b, 0x54, 0x6c, 0x68, 0x61, 0x6b, 0x6f, 0x6c, 0x65, 0x3b, 0x4d, 0x6f, 0x70, 0x69, 0x74, 0x6c,
-0x6f, 0x3b, 0x4d, 0x6f, 0x72, 0x61, 0x6e, 0x61, 0x6e, 0x67, 0x3b, 0x4d, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x67, 0x61, 0x6e,
-0x61, 0x6e, 0x67, 0x3b, 0x53, 0x65, 0x65, 0x74, 0x65, 0x62, 0x6f, 0x73, 0x69, 0x67, 0x6f, 0x3b, 0x50, 0x68, 0x75, 0x6b,
-0x77, 0x69, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x77, 0x65, 0x3b, 0x4c, 0x77, 0x65, 0x74, 0x73, 0x65, 0x3b, 0x44, 0x69, 0x70,
-0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x4e, 0x67, 0x77, 0x61, 0x6e, 0x61, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x53,
-0x65, 0x64, 0x69, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6f, 0x6c, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x3b, 0x4b, 0x75, 0x6b, 0x3b,
-0x4b, 0x75, 0x72, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76, 0x3b, 0x43, 0x68, 0x6b, 0x3b, 0x43, 0x68, 0x67, 0x3b,
-0x4e, 0x79, 0x61, 0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d, 0x3b, 0x4d, 0x62, 0x3b, 0x5a, 0x76, 0x69, 0x3b, 0x4e,
-0x64, 0x69, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x75, 0x6d, 0x65, 0x3b,
-0x4b, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x76, 0x61, 0x62, 0x76, 0x75, 0x3b, 0x43, 0x68,
-0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6e, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4e, 0x79, 0x61,
-0x6d, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x61, 0x3b, 0x47, 0x75, 0x6d,
-0x69, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a, 0x69, 0x3b, 0x5a, 0x76, 0x69, 0x74, 0x61, 0x3b, 0x4e,
-0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4e, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d,
-0x3b, 0x5a, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb,
-0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85,
-0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3,
-0xdd0, 0x3b, 0xda2, 0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb8, 0xdcf,
-0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2,
-0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4,
-0xdca, 0xdad, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc,
-0xdc0, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xda2, 0x3b,
-0xdb4, 0xdd9, 0x3b, 0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b, 0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3,
-0xdd0, 0x3b, 0xd94, 0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb,
-0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6,
-0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca,
-0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0x42, 0x68, 0x69, 0x3b, 0x56, 0x61, 0x6e, 0x3b, 0x56,
-0x6f, 0x6c, 0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x68, 0x3b, 0x4e, 0x68, 0x6c, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4e,
-0x67, 0x63, 0x3b, 0x4e, 0x79, 0x6f, 0x3b, 0x4d, 0x70, 0x68, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4e, 0x67, 0x6f, 0x3b, 0x42,
-0x68, 0x69, 0x6d, 0x62, 0x69, 0x64, 0x76, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x69, 0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x61, 0x6e,
-0x61, 0x3b, 0x69, 0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x75, 0x2d, 0x6c, 0x65, 0x6e, 0x6b, 0x68, 0x75, 0x6c, 0x75, 0x3b, 0x4d,
-0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, 0x69, 0x4e, 0x6b, 0x68, 0x77, 0x65, 0x6b, 0x68, 0x77, 0x65, 0x74, 0x69, 0x3b, 0x69,
-0x4e, 0x68, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x4b, 0x68, 0x6f, 0x6c, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x69, 0x4e, 0x67, 0x63,
-0x69, 0x3b, 0x69, 0x4e, 0x79, 0x6f, 0x6e, 0x69, 0x3b, 0x69, 0x4d, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x77, 0x65,
-0x74, 0x69, 0x3b, 0x69, 0x4e, 0x67, 0x6f, 0x6e, 0x67, 0x6f, 0x6e, 0x69, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62,
-0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c,
+0x3b, 0x44f, 0x3b, 0x444, 0x3b, 0x43c, 0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x44e, 0x3b, 0x44e, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e,
+0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x1007, 0x1014, 0x103a, 0x1014, 0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1016, 0x1031, 0x1016, 0x1031, 0x102c, 0x103a,
+0x101d, 0x102b, 0x101b, 0x102e, 0x3b, 0x1019, 0x1010, 0x103a, 0x3b, 0x1027, 0x1015, 0x103c, 0x102e, 0x3b, 0x1019, 0x1031, 0x3b, 0x1007, 0x103d, 0x1014,
+0x103a, 0x3b, 0x1007, 0x1030, 0x101c, 0x102d, 0x102f, 0x1004, 0x103a, 0x3b, 0x1029, 0x1002, 0x102f, 0x1010, 0x103a, 0x3b, 0x1005, 0x1000, 0x103a, 0x1010,
+0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1021, 0x1031, 0x102c, 0x1000, 0x103a, 0x1010, 0x102d, 0x102f, 0x1018, 0x102c, 0x3b, 0x1014, 0x102d, 0x102f, 0x101d,
+0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1012, 0x102e, 0x1007, 0x1004, 0x103a, 0x1018, 0x102c, 0x3b, 0x1007, 0x3b, 0x1016, 0x3b, 0x1019, 0x3b, 0x1027,
+0x3b, 0x1019, 0x3b, 0x1007, 0x3b, 0x1007, 0x3b, 0x1029, 0x3b, 0x1005, 0x3b, 0x1021, 0x3b, 0x1014, 0x3b, 0x1012, 0x3b, 0x441, 0x442, 0x443,
+0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x447, 0x44d, 0x440,
+0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b, 0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441,
+0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x44e, 0x442, 0x44b, 0x3b, 0x441,
+0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x441, 0x430, 0x432, 0x456, 0x43a, 0x3b, 0x43c, 0x430, 0x439, 0x3b,
+0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x43b, 0x456, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x436, 0x43d, 0x456, 0x432, 0x435,
+0x43d, 0x44c, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d,
+0x456, 0x43a, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430, 0x434, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x430, 0x43d, 0x44c, 0x3b,
+0x441, 0x3b, 0x43b, 0x3b, 0x441, 0x3b, 0x43a, 0x3b, 0x43c, 0x3b, 0x447, 0x3b, 0x43b, 0x3b, 0x436, 0x3b, 0x432, 0x3b, 0x43a, 0x3b,
+0x43b, 0x3b, 0x441, 0x3b, 0x441, 0x442, 0x443, 0x3b, 0x43b, 0x44e, 0x442, 0x3b, 0x441, 0x430, 0x43a, 0x3b, 0x43a, 0x440, 0x430, 0x3b,
+0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x3b, 0x43b, 0x456, 0x43f, 0x3b, 0x436, 0x43d, 0x456, 0x3b, 0x432, 0x435, 0x440, 0x3b,
+0x43a, 0x430, 0x441, 0x3b, 0x43b, 0x456, 0x441, 0x3b, 0x441, 0x43d, 0x435, 0x3b, 0x441, 0x442, 0x443, 0x434, 0x437, 0x435, 0x43d, 0x44f,
+0x3b, 0x43b, 0x44e, 0x442, 0x430, 0x433, 0x430, 0x3b, 0x441, 0x430, 0x43a, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43a, 0x440, 0x430,
+0x441, 0x430, 0x432, 0x456, 0x43a, 0x430, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x447, 0x44d, 0x440, 0x432, 0x435, 0x43d, 0x44f, 0x3b, 0x43b,
+0x456, 0x43f, 0x435, 0x43d, 0x44f, 0x3b, 0x436, 0x43d, 0x456, 0x45e, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x430, 0x441, 0x43d, 0x44f,
+0x3b, 0x43a, 0x430, 0x441, 0x442, 0x440, 0x44b, 0x447, 0x43d, 0x456, 0x43a, 0x430, 0x3b, 0x43b, 0x456, 0x441, 0x442, 0x430, 0x43f, 0x430,
+0x434, 0x430, 0x3b, 0x441, 0x43d, 0x435, 0x436, 0x43d, 0x44f, 0x3b, 0x1798, 0x1780, 0x179a, 0x17b6, 0x3b, 0x1780, 0x17bb, 0x1798, 0x17d2, 0x1797,
+0x17c8, 0x3b, 0x1798, 0x17b8, 0x1793, 0x17b6, 0x3b, 0x1798, 0x17c1, 0x179f, 0x17b6, 0x3b, 0x17a7, 0x179f, 0x1797, 0x17b6, 0x3b, 0x1798, 0x17b7, 0x1790,
+0x17bb, 0x1793, 0x17b6, 0x3b, 0x1780, 0x1780, 0x17d2, 0x1780, 0x178a, 0x17b6, 0x3b, 0x179f, 0x17b8, 0x17a0, 0x17b6, 0x3b, 0x1780, 0x1789, 0x17d2, 0x1789,
+0x17b6, 0x3b, 0x178f, 0x17bb, 0x179b, 0x17b6, 0x3b, 0x179c, 0x17b7, 0x1785, 0x17d2, 0x1786, 0x17b7, 0x1780, 0x17b6, 0x3b, 0x1792, 0x17d2, 0x1793, 0x17bc,
+0x3b, 0x67, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62, 0x72, 0x2e,
+0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b,
+0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b,
+0x67, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x3b, 0x61, 0x62,
+0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x67, 0x3b, 0x6a, 0x75, 0x6e, 0x79, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x6c,
+0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75,
+0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x72,
+0x65, 0x3b, 0x47, 0x4e, 0x3b, 0x46, 0x42, 0x3b, 0x4d, 0xc7, 0x3b, 0x41, 0x42, 0x3b, 0x4d, 0x47, 0x3b, 0x4a, 0x4e, 0x3b,
+0x4a, 0x4c, 0x3b, 0x41, 0x47, 0x3b, 0x53, 0x54, 0x3b, 0x4f, 0x43, 0x3b, 0x4e, 0x56, 0x3b, 0x44, 0x53, 0x3b, 0x31, 0x6708,
+0x3b, 0x32, 0x6708, 0x3b, 0x33, 0x6708, 0x3b, 0x34, 0x6708, 0x3b, 0x35, 0x6708, 0x3b, 0x36, 0x6708, 0x3b, 0x37, 0x6708, 0x3b, 0x38,
+0x6708, 0x3b, 0x39, 0x6708, 0x3b, 0x31, 0x30, 0x6708, 0x3b, 0x31, 0x31, 0x6708, 0x3b, 0x31, 0x32, 0x6708, 0x3b, 0x4e00, 0x6708, 0x3b,
+0x4e8c, 0x6708, 0x3b, 0x4e09, 0x6708, 0x3b, 0x56db, 0x6708, 0x3b, 0x4e94, 0x6708, 0x3b, 0x516d, 0x6708, 0x3b, 0x4e03, 0x6708, 0x3b, 0x516b, 0x6708,
+0x3b, 0x4e5d, 0x6708, 0x3b, 0x5341, 0x6708, 0x3b, 0x5341, 0x4e00, 0x6708, 0x3b, 0x5341, 0x4e8c, 0x6708, 0x3b, 0x73, 0x69, 0x6a, 0x3b, 0x76,
+0x65, 0x6c, 0x6a, 0x3b, 0x6f, 0x17e, 0x75, 0x3b, 0x74, 0x72, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x3b, 0x6c, 0x69, 0x70, 0x3b,
+0x73, 0x72, 0x70, 0x3b, 0x6b, 0x6f, 0x6c, 0x3b, 0x72, 0x75, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x73, 0x74, 0x75, 0x3b,
+0x70, 0x72, 0x6f, 0x3b, 0x73, 0x69, 0x6a, 0x65, 0x10d, 0x61, 0x6e, 0x6a, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x61,
+0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x61, 0x6b, 0x3b, 0x74, 0x72, 0x61, 0x76, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x76, 0x69, 0x62,
+0x61, 0x6e, 0x6a, 0x3b, 0x6c, 0x69, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x73, 0x72, 0x70, 0x61, 0x6e, 0x6a, 0x3b, 0x6b, 0x6f,
+0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x3b, 0x72, 0x75, 0x6a, 0x61, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64,
+0x3b, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x69, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x61, 0x63, 0x3b, 0x31, 0x2e,
+0x3b, 0x32, 0x2e, 0x3b, 0x33, 0x2e, 0x3b, 0x34, 0x2e, 0x3b, 0x35, 0x2e, 0x3b, 0x36, 0x2e, 0x3b, 0x37, 0x2e, 0x3b, 0x38,
+0x2e, 0x3b, 0x39, 0x2e, 0x3b, 0x31, 0x30, 0x2e, 0x3b, 0x31, 0x31, 0x2e, 0x3b, 0x31, 0x32, 0x2e, 0x3b, 0x73, 0x69, 0x6a,
+0x65, 0x10d, 0x6e, 0x6a, 0x61, 0x3b, 0x76, 0x65, 0x6c, 0x6a, 0x61, 0x10d, 0x65, 0x3b, 0x6f, 0x17e, 0x75, 0x6a, 0x6b, 0x61,
+0x3b, 0x74, 0x72, 0x61, 0x76, 0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x76, 0x69, 0x62, 0x6e, 0x6a, 0x61, 0x3b, 0x6c, 0x69, 0x70,
+0x6e, 0x6a, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x6f, 0x6c, 0x6f, 0x76, 0x6f, 0x7a, 0x61, 0x3b,
+0x72, 0x75, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x73, 0x74, 0x75, 0x64,
+0x65, 0x6e, 0x6f, 0x67, 0x61, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x61, 0x3b, 0x6c, 0x65, 0x64, 0x3b, 0xfa,
+0x6e, 0x6f, 0x3b, 0x62, 0x159, 0x65, 0x3b, 0x64, 0x75, 0x62, 0x3b, 0x6b, 0x76, 0x11b, 0x3b, 0x10d, 0x76, 0x6e, 0x3b, 0x10d,
+0x76, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x3b, 0x7a, 0xe1, 0x159, 0x3b, 0x159, 0xed, 0x6a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x70,
+0x72, 0x6f, 0x3b, 0x6c, 0x65, 0x64, 0x65, 0x6e, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x3b, 0x62, 0x159, 0x65, 0x7a, 0x65, 0x6e,
+0x3b, 0x64, 0x75, 0x62, 0x65, 0x6e, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x65, 0x6e, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e,
+0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x65, 0x63, 0x3b, 0x73, 0x72, 0x70, 0x65, 0x6e, 0x3b, 0x7a, 0xe1, 0x159, 0xed,
+0x3b, 0x159, 0xed, 0x6a, 0x65, 0x6e, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x70, 0x72, 0x6f, 0x73,
+0x69, 0x6e, 0x65, 0x63, 0x3b, 0x6c, 0x3b, 0xfa, 0x3b, 0x62, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, 0x10d, 0x3b, 0x10d, 0x3b, 0x73,
+0x3b, 0x7a, 0x3b, 0x159, 0x3b, 0x6c, 0x3b, 0x70, 0x3b, 0x6c, 0x65, 0x64, 0x6e, 0x61, 0x3b, 0xfa, 0x6e, 0x6f, 0x72, 0x61,
+0x3b, 0x62, 0x159, 0x65, 0x7a, 0x6e, 0x61, 0x3b, 0x64, 0x75, 0x62, 0x6e, 0x61, 0x3b, 0x6b, 0x76, 0x11b, 0x74, 0x6e, 0x61,
+0x3b, 0x10d, 0x65, 0x72, 0x76, 0x6e, 0x61, 0x3b, 0x10d, 0x65, 0x72, 0x76, 0x65, 0x6e, 0x63, 0x65, 0x3b, 0x73, 0x72, 0x70,
+0x6e, 0x61, 0x3b, 0x7a, 0xe1, 0x159, 0xed, 0x3b, 0x159, 0xed, 0x6a, 0x6e, 0x61, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70,
+0x61, 0x64, 0x75, 0x3b, 0x70, 0x72, 0x6f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62,
+0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c,
0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63,
-0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65,
-0x63, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b,
-0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74,
-0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
-0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x61, 0x3b,
-0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x61, 0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b, 0x6a, 0xfa,
-0x6e, 0x61, 0x3b, 0x6a, 0xfa, 0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74,
-0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
-0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66,
-0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d,
-0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73,
-0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b,
-0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61,
-0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61,
-0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70,
-0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x4b, 0x6f, 0x62,
-0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x41, 0x66, 0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c, 0x69, 0x78,
-0x3b, 0x54, 0x6f, 0x64, 0x3b, 0x53, 0x69, 0x64, 0x3b, 0x53, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b, 0x49, 0x54,
-0x3b, 0x4c, 0x49, 0x54, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42,
-0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61,
-0x64, 0x64, 0x65, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64,
-0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x68, 0x61, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61,
-0x20, 0x4c, 0x69, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61,
-0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x69, 0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42,
-0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x67, 0x61, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61,
-0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69,
-0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62,
-0x61, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b,
-0x41, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x65, 0x6e,
-0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a,
-0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e,
-0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f,
-0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75,
-0x6e, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70,
-0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69,
-0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46, 0x3b,
-0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b,
-0x65, 0x6e, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b,
-0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b,
-0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b,
-0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b,
-0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75,
-0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41,
-0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69,
-0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74,
-0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x6a, 0x3b,
-0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72,
-0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x6a, 0x3b,
-0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65,
-0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
-0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72,
-0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69,
-0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75,
-0x73, 0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
+0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74,
+0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c,
+0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f,
+0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b,
+0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61,
+0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64,
+0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x3b,
+0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b,
+0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b,
+0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c,
+0x3b, 0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73,
+0x74, 0x75, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410, 0x43f, 0x440, 0x3b, 0x41c, 0x430, 0x439, 0x3b,
-0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421, 0x435, 0x43d, 0x3b, 0x41e, 0x43a, 0x442, 0x3b,
-0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b,
-0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b,
-0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e,
-0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c,
-0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b,
-0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa,
-0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b, 0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5,
-0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f,
-0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86,
-0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbc1, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd,
-0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa,
-0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, 0x3b, 0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c,
-0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xb85, 0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b,
-0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0,
-0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd,
-0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa,
-0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b,
-0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30,
-0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc42, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f,
-0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b,
-0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f,
-0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0e, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32, 0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c,
-0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc42, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d,
-0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c,
-0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c, 0x3b, 0xc2b, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b,
-0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b, 0xc38, 0xc46, 0x3b, 0xc05, 0x3b, 0xc28, 0x3b,
-0xc21, 0xc3f, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f,
-0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc42, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17,
-0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f,
-0xc4b, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d,
-0x3b, 0xc1c, 0x3b, 0xc2b, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0x3b, 0xc1c, 0xc41, 0x3b,
-0xc06, 0x3b, 0xc38, 0xc46, 0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e,
-0x2e, 0x3b, 0xe21, 0xe35, 0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21,
-0xe34, 0x2e, 0xe22, 0x2e, 0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b,
-0xe15, 0x2e, 0xe04, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04,
-0xe21, 0x3b, 0xe01, 0xe38, 0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21, 0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b,
-0xe40, 0xe21, 0xe29, 0xe32, 0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19,
-0xe32, 0xe22, 0xe19, 0x3b, 0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34, 0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b,
-0xe01, 0xe31, 0xe19, 0xe22, 0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21, 0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34,
-0xe01, 0xe32, 0xe22, 0xe19, 0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0xe21, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e,
-0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, 0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe04, 0x2e, 0x3b,
-0xe21, 0xe34, 0x2e, 0xe22, 0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b,
-0xe15, 0x2e, 0xe04, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b,
-0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b,
-0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf5e, 0xf72,
-0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b,
-0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74, 0xf53, 0xf0b, 0xf54, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b,
-0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f,
-0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
-0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0x1303, 0x1295, 0x12e9, 0x3b, 0x134c, 0x1265, 0x1229,
-0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x1228, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6,
-0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x3b, 0x1303,
-0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x1228, 0x120d, 0x3b,
-0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234, 0x1355, 0x1274, 0x121d, 0x1260,
-0x122d, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x12cd, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2, 0x1234, 0x121d, 0x1260, 0x122d,
-0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x3b, 0x1218, 0x130b, 0x1262, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x3b, 0x130d, 0x1295, 0x1266, 0x3b,
-0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x3b, 0x1325, 0x1245, 0x121d, 0x3b, 0x1215,
-0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, 0x1218, 0x130b, 0x1262, 0x1275, 0x3b,
-0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230,
-0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x1235,
-0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x3b, 0x4d,
-0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x2bb,
-0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, 0x3b, 0x53, 0x101, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b,
-0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x73, 0x69, 0x3b, 0x2bb, 0x45, 0x70, 0x65, 0x6c,
-0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb,
-0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61,
-0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b, 0x54, 0x12b, 0x73, 0x65, 0x6d, 0x61, 0x3b, 0x53,
-0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e,
-0x3b, 0x54, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x4b, 0x75, 0x6c, 0x3b, 0x44, 0x7a, 0x69, 0x3b, 0x4d,
-0x75, 0x64, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x68, 0x61, 0x3b, 0x4e, 0x64, 0x7a, 0x3b, 0x4e,
-0x68, 0x6c, 0x3b, 0x48, 0x75, 0x6b, 0x3b, 0x4e, 0x27, 0x77, 0x3b, 0x53, 0x75, 0x6e, 0x67, 0x75, 0x74, 0x69, 0x3b, 0x4e,
-0x79, 0x65, 0x6e, 0x79, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x69, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x75,
-0x6c, 0x75, 0x3b, 0x44, 0x7a, 0x69, 0x76, 0x61, 0x6d, 0x69, 0x73, 0x6f, 0x6b, 0x6f, 0x3b, 0x4d, 0x75, 0x64, 0x79, 0x61,
-0x78, 0x69, 0x68, 0x69, 0x3b, 0x4b, 0x68, 0x6f, 0x74, 0x61, 0x76, 0x75, 0x78, 0x69, 0x6b, 0x61, 0x3b, 0x4d, 0x61, 0x77,
-0x75, 0x77, 0x61, 0x6e, 0x69, 0x3b, 0x4d, 0x68, 0x61, 0x77, 0x75, 0x72, 0x69, 0x3b, 0x4e, 0x64, 0x7a, 0x68, 0x61, 0x74,
-0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x48, 0x75, 0x6b, 0x75, 0x72, 0x69, 0x3b, 0x4e,
-0x27, 0x77, 0x65, 0x6e, 0x64, 0x7a, 0x61, 0x6d, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4f, 0x63, 0x61, 0x3b, 0x15e, 0x75, 0x62,
-0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a, 0x3b, 0x54, 0x65, 0x6d,
-0x3b, 0x41, 0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x41, 0x72, 0x61,
-0x3b, 0x4f, 0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x4e, 0x69, 0x73,
-0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e, 0x3b, 0x54, 0x65, 0x6d,
-0x6d, 0x75, 0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc, 0x6c, 0x3b, 0x45, 0x6b,
-0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b, 0x4f, 0x3b, 0x15e, 0x3b,
-0x4d, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x41, 0x3b,
-0x421, 0x456, 0x447, 0x3b, 0x41b, 0x44e, 0x442, 0x3b, 0x411, 0x435, 0x440, 0x3b, 0x41a, 0x432, 0x456, 0x3b, 0x422, 0x440, 0x430, 0x3b,
-0x427, 0x435, 0x440, 0x3b, 0x41b, 0x438, 0x43f, 0x3b, 0x421, 0x435, 0x440, 0x3b, 0x412, 0x435, 0x440, 0x3b, 0x416, 0x43e, 0x432, 0x3b,
-0x41b, 0x438, 0x441, 0x3b, 0x413, 0x440, 0x443, 0x3b, 0x421, 0x456, 0x447, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x44e, 0x442, 0x438, 0x439,
-0x3b, 0x411, 0x435, 0x440, 0x435, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x41a, 0x432, 0x456, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x422, 0x440,
-0x430, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x427, 0x435, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x438, 0x43f, 0x435, 0x43d, 0x44c,
-0x3b, 0x421, 0x435, 0x440, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x412, 0x435, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x3b, 0x416, 0x43e,
-0x432, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x3b, 0x413, 0x440, 0x443, 0x434, 0x435,
-0x43d, 0x44c, 0x3b, 0x421, 0x3b, 0x41b, 0x3b, 0x411, 0x3b, 0x41a, 0x3b, 0x422, 0x3b, 0x427, 0x3b, 0x41b, 0x3b, 0x421, 0x3b, 0x412,
-0x3b, 0x416, 0x3b, 0x41b, 0x3b, 0x413, 0x3b, 0x441, 0x456, 0x447, 0x2e, 0x3b, 0x43b, 0x44e, 0x442, 0x2e, 0x3b, 0x431, 0x435, 0x440,
-0x2e, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x2e, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x2e, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x2e, 0x3b,
-0x43b, 0x438, 0x43f, 0x2e, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x2e, 0x3b, 0x432, 0x435, 0x440, 0x2e, 0x3b, 0x436, 0x43e, 0x432, 0x442,
-0x2e, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x2e, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x2e, 0x3b, 0x441, 0x456, 0x447, 0x43d, 0x44f, 0x3b,
-0x43b, 0x44e, 0x442, 0x43e, 0x433, 0x43e, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x43d, 0x44f, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x43d,
-0x44f, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x43d, 0x44f, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x43f, 0x43d,
-0x44f, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x43d, 0x44f, 0x3b, 0x436, 0x43e, 0x432,
-0x442, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x43d, 0x44f,
-0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e,
-0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x626, 0x3b, 0x627, 0x6af, 0x633,
-0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631,
-0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x3b, 0x627,
-0x67e, 0x631, 0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x3b, 0x633,
-0x67e, 0x62a, 0x3b, 0x627, 0x6a9, 0x62a, 0x3b, 0x646, 0x648, 0x645, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x3b,
-0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e,
-0x3b, 0x49, 0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f,
-0x79, 0x61, 0x3b, 0x44, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c,
-0x3b, 0x4d, 0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e,
-0x3b, 0x49, 0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62,
-0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b,
-0x61, 0x62, 0x72, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b,
-0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x32, 0x3b,
+0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x72, 0x74, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b,
+0x6d, 0x65, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73,
+0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0xd801,
+0xdc16, 0xd801, 0xdc30, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc2f, 0xd801, 0xdc3a, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc2a, 0xd801, 0xdc49, 0x3b,
+0xd801, 0xdc01, 0xd801, 0xdc39, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0x3b, 0xd801,
+0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4a, 0x3b, 0xd801, 0xdc02, 0xd801, 0xdc40, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc2f, 0xd801, 0xdc39, 0x3b, 0xd801, 0xdc09,
+0xd801, 0xdc3f, 0xd801, 0xdc3b, 0x3b, 0xd801, 0xdc24, 0xd801, 0xdc2c, 0xd801, 0xdc42, 0x3b, 0xd801, 0xdc14, 0xd801, 0xdc28, 0xd801, 0xdc45, 0x3b, 0xd801,
+0xdc16, 0xd801, 0xdc30, 0xd801, 0xdc4c, 0xd801, 0xdc37, 0xd801, 0xdc2d, 0xd801, 0xdc2f, 0xd801, 0xdc49, 0xd801, 0xdc28, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc2f,
+0xd801, 0xdc3a, 0xd801, 0xdc49, 0xd801, 0xdc2d, 0xd801, 0xdc2f, 0xd801, 0xdc49, 0xd801, 0xdc28, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc2a, 0xd801, 0xdc49, 0xd801,
+0xdc3d, 0x3b, 0xd801, 0xdc01, 0xd801, 0xdc39, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc4a, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc16,
+0xd801, 0xdc2d, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc16, 0xd801, 0xdc2d, 0xd801, 0xdc4a, 0xd801, 0xdc34, 0x3b, 0xd801, 0xdc02, 0xd801, 0xdc40, 0xd801, 0xdc32,
+0xd801, 0xdc45, 0xd801, 0xdc3b, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc2f, 0xd801, 0xdc39, 0xd801, 0xdc3b, 0xd801, 0xdc2f, 0xd801, 0xdc4b, 0xd801, 0xdc3a, 0xd801,
+0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc09, 0xd801, 0xdc3f, 0xd801, 0xdc3b, 0xd801, 0xdc2c, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801,
+0xdc24, 0xd801, 0xdc2c, 0xd801, 0xdc42, 0xd801, 0xdc2f, 0xd801, 0xdc4b, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc14, 0xd801, 0xdc28,
+0xd801, 0xdc45, 0xd801, 0xdc2f, 0xd801, 0xdc4b, 0xd801, 0xdc3a, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc16, 0x3b, 0xd801, 0xdc19, 0x3b, 0xd801,
+0xdc23, 0x3b, 0xd801, 0xdc01, 0x3b, 0xd801, 0xdc23, 0x3b, 0xd801, 0xdc16, 0x3b, 0xd801, 0xdc16, 0x3b, 0xd801, 0xdc02, 0x3b, 0xd801, 0xdc1d, 0x3b,
+0xd801, 0xdc09, 0x3b, 0xd801, 0xdc24, 0x3b, 0xd801, 0xdc14, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x3b, 0x76, 0x65, 0x65, 0x62, 0x72, 0x3b,
+0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b,
+0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e,
+0x6f, 0x76, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x3b, 0x6a, 0x61, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x76, 0x65, 0x65, 0x62,
+0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0xe4, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x6d, 0x61,
+0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74,
+0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b,
+0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x74, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a,
+0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e,
+0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d,
+0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f,
+0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65,
+0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0x69,
+0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x3b,
+0x68, 0x65, 0x6c, 0x6d, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x3b, 0x74,
+0x6f, 0x75, 0x6b, 0x6f, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x3b, 0x68, 0x65, 0x69, 0x6e, 0xe4, 0x3b, 0x65, 0x6c, 0x6f, 0x3b,
+0x73, 0x79, 0x79, 0x73, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x3b, 0x6a, 0x6f, 0x75,
+0x6c, 0x75, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75,
+0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x3b,
+0x74, 0x6f, 0x75, 0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x68, 0x65, 0x69,
+0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x3b, 0x73, 0x79, 0x79, 0x73, 0x6b, 0x75, 0x75,
+0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x3b, 0x6a,
+0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x4b, 0x3b,
+0x48, 0x3b, 0x45, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x74, 0x61, 0x6d, 0x6d, 0x69, 0x6b, 0x75, 0x75,
+0x74, 0x61, 0x3b, 0x68, 0x65, 0x6c, 0x6d, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x73,
+0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x75, 0x68, 0x74, 0x69, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x74, 0x6f, 0x75,
+0x6b, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x68, 0x65,
+0x69, 0x6e, 0xe4, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x65, 0x6c, 0x6f, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x73, 0x79,
+0x79, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6c, 0x6f, 0x6b, 0x61, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6d, 0x61,
+0x72, 0x72, 0x61, 0x73, 0x6b, 0x75, 0x75, 0x74, 0x61, 0x3b, 0x6a, 0x6f, 0x75, 0x6c, 0x75, 0x6b, 0x75, 0x75, 0x74, 0x61,
+0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76,
+0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b, 0x6a, 0x75, 0x69, 0x6c, 0x2e, 0x3b, 0x61, 0x6f,
+0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64,
+0xe9, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x72, 0x3b, 0x66, 0xe9, 0x76, 0x72, 0x69, 0x65, 0x72, 0x3b,
+0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x69, 0x6e, 0x3b,
+0x6a, 0x75, 0x69, 0x6c, 0x6c, 0x65, 0x74, 0x3b, 0x61, 0x6f, 0xfb, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
+0x64, 0xe9, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x46, 0x61, 0x6f, 0x69, 0x3b, 0x47, 0x65, 0x61, 0x72, 0x72, 0x3b,
+0x4d, 0xe0, 0x72, 0x74, 0x3b, 0x47, 0x69, 0x62, 0x6c, 0x3b, 0x43, 0xe8, 0x69, 0x74, 0x3b, 0xd2, 0x67, 0x6d, 0x68, 0x3b,
+0x49, 0x75, 0x63, 0x68, 0x3b, 0x4c, 0xf9, 0x6e, 0x61, 0x3b, 0x53, 0x75, 0x6c, 0x74, 0x3b, 0x44, 0xe0, 0x6d, 0x68, 0x3b,
+0x53, 0x61, 0x6d, 0x68, 0x3b, 0x44, 0xf9, 0x62, 0x68, 0x3b, 0x41, 0x6d, 0x20, 0x46, 0x61, 0x6f, 0x69, 0x6c, 0x6c, 0x65,
+0x61, 0x63, 0x68, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x65, 0x61, 0x72, 0x72, 0x61, 0x6e, 0x3b, 0x41, 0x6d, 0x20, 0x4d, 0xe0,
+0x72, 0x74, 0x3b, 0x41, 0x6e, 0x20, 0x47, 0x69, 0x62, 0x6c, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x43, 0xe8, 0x69,
+0x74, 0x65, 0x61, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0xd2, 0x67, 0x6d, 0x68, 0x69, 0x6f, 0x73, 0x3b, 0x41, 0x6e,
+0x20, 0x74, 0x2d, 0x49, 0x75, 0x63, 0x68, 0x61, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x4c, 0xf9, 0x6e, 0x61, 0x73, 0x74, 0x61,
+0x6c, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x75, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x41, 0x6e, 0x20, 0x44, 0xe0,
+0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x41, 0x6e, 0x20, 0x74, 0x2d, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x41,
+0x6e, 0x20, 0x44, 0xf9, 0x62, 0x68, 0x6c, 0x61, 0x63, 0x68, 0x64, 0x3b, 0x46, 0x41, 0x3b, 0x47, 0x45, 0x3b, 0x4d, 0xc0,
+0x3b, 0x47, 0x49, 0x3b, 0x43, 0xc8, 0x3b, 0xd2, 0x47, 0x3b, 0x49, 0x55, 0x3b, 0x4c, 0xd9, 0x3b, 0x53, 0x55, 0x3b, 0x44,
+0xc0, 0x3b, 0x53, 0x41, 0x3b, 0x44, 0xd9, 0x3b, 0x58, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b,
+0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x58, 0x75, 0xf1, 0x3b, 0x58, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b,
+0x53, 0x65, 0x74, 0x3b, 0x4f, 0x75, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x58, 0x61, 0x6e, 0x65,
+0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41,
+0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x58, 0x75, 0xf1, 0x6f, 0x3b, 0x58, 0x75, 0x6c, 0x6c, 0x6f,
+0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74,
+0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62,
+0x72, 0x6f, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53,
+0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x78, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61,
+0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x78, 0x75, 0xf1, 0x3b, 0x78, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73,
+0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x78, 0x61, 0x6e, 0x65, 0x69,
+0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x62,
+0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x78, 0x75, 0xf1, 0x6f, 0x3b, 0x78, 0x75, 0x6c, 0x6c, 0x6f, 0x3b,
+0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75,
+0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72,
+0x6f, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x3b, 0x10d7, 0x10d4, 0x10d1, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x3b, 0x10db, 0x10d0,
+0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x3b, 0x10d0, 0x10d2, 0x10d5, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x3b, 0x10dd, 0x10e5,
+0x10e2, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x3b, 0x10d3, 0x10d4, 0x10d9, 0x3b, 0x10d8, 0x10d0, 0x10dc, 0x10d5, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x10d7, 0x10d4,
+0x10d1, 0x10d4, 0x10e0, 0x10d5, 0x10d0, 0x10da, 0x10d8, 0x3b, 0x10db, 0x10d0, 0x10e0, 0x10e2, 0x10d8, 0x3b, 0x10d0, 0x10de, 0x10e0, 0x10d8, 0x10da, 0x10d8,
+0x3b, 0x10db, 0x10d0, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10dc, 0x10d8, 0x10e1, 0x10d8, 0x3b, 0x10d8, 0x10d5, 0x10da, 0x10d8, 0x10e1, 0x10d8,
+0x3b, 0x10d0, 0x10d2, 0x10d5, 0x10d8, 0x10e1, 0x10e2, 0x10dd, 0x3b, 0x10e1, 0x10d4, 0x10e5, 0x10e2, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b,
+0x10dd, 0x10e5, 0x10e2, 0x10dd, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10dc, 0x10dd, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d3,
+0x10d4, 0x10d9, 0x10d4, 0x10db, 0x10d1, 0x10d4, 0x10e0, 0x10d8, 0x3b, 0x10d8, 0x3b, 0x10d7, 0x3b, 0x10db, 0x3b, 0x10d0, 0x3b, 0x10db, 0x3b, 0x10d8,
+0x3b, 0x10d8, 0x3b, 0x10d0, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10dc, 0x3b, 0x10d3, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
+0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
+0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a,
+0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a,
+0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
+0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b,
+0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d,
+0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41,
+0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75,
+0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65,
+0x7a, 0x2e, 0x3b, 0x4a, 0xe4, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d,
+0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f,
+0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x4a, 0xe4, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x46, 0x65,
+0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69,
+0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0xe4, 0x6e, 0x2e, 0x3b, 0x46,
+0x65, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75,
+0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x2e, 0x3b, 0x4f, 0x6b,
+0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2,
+0x3b, 0x39c, 0x3ac, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b, 0x399, 0x3bf,
+0x3cd, 0x3bb, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3ad, 0x3b, 0x394,
+0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5,
+0x3ac, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3c1, 0x3c4, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3af, 0x3bb, 0x3b9,
+0x3bf, 0x3c2, 0x3b, 0x39c, 0x3ac, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd, 0x3bd, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3bf, 0x3cd,
+0x3bb, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x391, 0x3cd, 0x3b3, 0x3bf, 0x3c5, 0x3c3, 0x3c4, 0x3bf, 0x3c2, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3ad,
+0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3ce, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x39d, 0x3bf, 0x3ad,
+0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3ad, 0x3bc, 0x3b2, 0x3c1, 0x3b9, 0x3bf, 0x3c2, 0x3b, 0x399, 0x3b,
+0x3a6, 0x3b, 0x39c, 0x3b, 0x391, 0x3b, 0x39c, 0x3b, 0x399, 0x3b, 0x399, 0x3b, 0x391, 0x3b, 0x3a3, 0x3b, 0x39f, 0x3b, 0x39d, 0x3b,
+0x394, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b, 0x39c, 0x3b1,
+0x390, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bd, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3b,
+0x39f, 0x3ba, 0x3c4, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b, 0x399, 0x3b1, 0x3bd, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af,
+0x3bf, 0x3c5, 0x3b, 0x3a6, 0x3b5, 0x3b2, 0x3c1, 0x3bf, 0x3c5, 0x3b1, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x3c1, 0x3c4, 0x3af,
+0x3bf, 0x3c5, 0x3b, 0x391, 0x3c0, 0x3c1, 0x3b9, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39c, 0x3b1, 0x390, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf,
+0x3c5, 0x3bd, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x399, 0x3bf, 0x3c5, 0x3bb, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x391, 0x3c5, 0x3b3, 0x3bf, 0x3cd, 0x3c3,
+0x3c4, 0x3bf, 0x3c5, 0x3b, 0x3a3, 0x3b5, 0x3c0, 0x3c4, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39f, 0x3ba, 0x3c4, 0x3c9,
+0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x39d, 0x3bf, 0x3b5, 0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x394, 0x3b5, 0x3ba, 0x3b5,
+0x3bc, 0x3b2, 0x3c1, 0x3af, 0x3bf, 0x3c5, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75,
+0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x61,
+0x6a, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x75,
+0x73, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65,
+0x72, 0x69, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65,
+0x72, 0x69, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae, 0xabe, 0xab0,
+0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2,
+0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5,
+0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaab, 0xac7, 0xaac,
+0xacd, 0xab0, 0xac1, 0xa86, 0xab0, 0xac0, 0x3b, 0xaae, 0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b,
+0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c, 0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8,
+0xaaa, 0xacd, 0xa9f, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa91, 0xa95, 0xacd, 0xa9f, 0xacb, 0xaac, 0xab0, 0x3b, 0xaa8, 0xab5, 0xac7,
+0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0xaae, 0xacd, 0xaac, 0xab0, 0x3b, 0xa9c, 0xabe, 0x3b, 0xaab, 0xac7, 0x3b,
+0xaae, 0xabe, 0x3b, 0xa8f, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0x3b, 0xa9c, 0xac1, 0x3b, 0xa91, 0x3b, 0xab8, 0x3b, 0xa91, 0x3b,
+0xaa8, 0x3b, 0xaa1, 0xabf, 0x3b, 0xa9c, 0xabe, 0xaa8, 0xacd, 0xaaf, 0xac1, 0x3b, 0xaab, 0xac7, 0xaac, 0xacd, 0xab0, 0xac1, 0x3b, 0xaae,
+0xabe, 0xab0, 0xacd, 0xa9a, 0x3b, 0xa8f, 0xaaa, 0xacd, 0xab0, 0xabf, 0xab2, 0x3b, 0xaae, 0xac7, 0x3b, 0xa9c, 0xac2, 0xaa8, 0x3b, 0xa9c,
+0xac1, 0xab2, 0xabe, 0xa88, 0x3b, 0xa91, 0xa97, 0xab8, 0xacd, 0xa9f, 0x3b, 0xab8, 0xaaa, 0xacd, 0xa9f, 0xac7, 0x3b, 0xa91, 0xa95, 0xacd,
+0xa9f, 0xacb, 0x3b, 0xaa8, 0xab5, 0xac7, 0x3b, 0xaa1, 0xabf, 0xab8, 0xac7, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x61, 0x62, 0x3b,
+0x4d, 0x61, 0x72, 0x3b, 0x41, 0x66, 0x69, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b,
+0x41, 0x67, 0x75, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x75, 0x77, 0x3b, 0x44, 0x69, 0x73, 0x3b,
+0x4a, 0x61, 0x6e, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x46, 0x61, 0x62, 0x75, 0x72, 0x61, 0x69, 0x72, 0x75, 0x3b, 0x4d, 0x61,
+0x72, 0x69, 0x73, 0x3b, 0x41, 0x66, 0x69, 0x72, 0x69, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e,
+0x69, 0x3b, 0x59, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x61, 0x3b, 0x53, 0x61, 0x74, 0x75, 0x6d, 0x62,
+0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x75, 0x77, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73,
+0x61, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x41,
+0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5f3, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5f3, 0x3b, 0x5de,
+0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5f3, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dc,
+0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5f3, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5f3, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x5f3, 0x3b, 0x5e0, 0x5d5, 0x5d1,
+0x5f3, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5f3, 0x3b, 0x5d9, 0x5e0, 0x5d5, 0x5d0, 0x5e8, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x5d5, 0x5d0, 0x5e8, 0x3b,
+0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x5d9, 0x5dc, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5e0, 0x5d9, 0x3b, 0x5d9,
+0x5d5, 0x5dc, 0x5d9, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x5d5, 0x5e1, 0x5d8, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d0, 0x5d5,
+0x5e7, 0x5d8, 0x5d5, 0x5d1, 0x5e8, 0x3b, 0x5e0, 0x5d5, 0x5d1, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x5d1, 0x5e8, 0x3b, 0x5d9,
+0x5e0, 0x5d5, 0x3b, 0x5e4, 0x5d1, 0x5e8, 0x3b, 0x5de, 0x5e8, 0x5e5, 0x3b, 0x5d0, 0x5e4, 0x5e8, 0x3b, 0x5de, 0x5d0, 0x5d9, 0x3b, 0x5d9,
+0x5d5, 0x5e0, 0x3b, 0x5d9, 0x5d5, 0x5dc, 0x3b, 0x5d0, 0x5d5, 0x5d2, 0x3b, 0x5e1, 0x5e4, 0x5d8, 0x3b, 0x5d0, 0x5d5, 0x5e7, 0x3b, 0x5e0,
+0x5d5, 0x5d1, 0x3b, 0x5d3, 0x5e6, 0x5de, 0x3b, 0x91c, 0x928, 0x3b, 0x92b, 0x93c, 0x930, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b,
+0x905, 0x92a, 0x94d, 0x930, 0x948, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x3b, 0x905, 0x917,
+0x3b, 0x938, 0x93f, 0x924, 0x902, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x942, 0x3b, 0x928, 0x935, 0x902, 0x3b, 0x926, 0x93f, 0x938, 0x902,
+0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x93c, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b,
+0x905, 0x92a, 0x94d, 0x930, 0x948, 0x932, 0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b,
+0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b, 0x938, 0x93f, 0x924, 0x902, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x942, 0x92c, 0x930,
+0x3b, 0x928, 0x935, 0x902, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x93c, 0x3b, 0x92e,
+0x93e, 0x3b, 0x905, 0x3b, 0x92e, 0x3b, 0x91c, 0x942, 0x3b, 0x91c, 0x941, 0x3b, 0x905, 0x3b, 0x938, 0x93f, 0x3b, 0x905, 0x3b, 0x928,
+0x3b, 0x926, 0x93f, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x2e,
+0x3b, 0xe1, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0xe1, 0x6a, 0x2e, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b, 0x6a, 0xfa, 0x6c, 0x2e,
+0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f,
+0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75,
+0xe1, 0x72, 0x3b, 0x6d, 0xe1, 0x72, 0x63, 0x69, 0x75, 0x73, 0x3b, 0xe1, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x73, 0x3b, 0x6d,
+0xe1, 0x6a, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6e, 0x69, 0x75, 0x73, 0x3b, 0x6a, 0xfa, 0x6c, 0x69, 0x75, 0x73, 0x3b, 0x61,
+0x75, 0x67, 0x75, 0x73, 0x7a, 0x74, 0x75, 0x73, 0x3b, 0x73, 0x7a, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0xc1, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b,
+0x41, 0x3b, 0x53, 0x7a, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e,
+0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0xed, 0x3b, 0x6a, 0xfa, 0x6e, 0x2e, 0x3b,
+0x6a, 0xfa, 0x6c, 0x2e, 0x3b, 0xe1, 0x67, 0xfa, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b,
+0x6e, 0xf3, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0xfa, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62,
+0x72, 0xfa, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0x61, 0xed, 0x3b,
+0x6a, 0xfa, 0x6e, 0xed, 0x3b, 0x6a, 0xfa, 0x6c, 0xed, 0x3b, 0xe1, 0x67, 0xfa, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0xf3, 0x76, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b,
+0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0xc1, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b,
+0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b,
+0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b,
+0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69,
+0x3b, 0x4d, 0x61, 0x72, 0x65, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
+0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x75, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65,
+0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65,
+0x72, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61,
+0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x63, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x6f, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x69, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69,
+0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x61, 0x62,
+0x68, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x3b, 0x4d, 0x65, 0x69,
+0x74, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x3b, 0x4d, 0x46, 0xf3, 0x6d, 0x68, 0x3b, 0x44, 0x46,
+0xf3, 0x6d, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x3b, 0x45, 0x61, 0x6e, 0xe1, 0x69, 0x72,
+0x3b, 0x46, 0x65, 0x61, 0x62, 0x68, 0x72, 0x61, 0x3b, 0x4d, 0xe1, 0x72, 0x74, 0x61, 0x3b, 0x41, 0x69, 0x62, 0x72, 0x65,
+0xe1, 0x6e, 0x3b, 0x42, 0x65, 0x61, 0x6c, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x74, 0x68, 0x65, 0x61,
+0x6d, 0x68, 0x3b, 0x49, 0xfa, 0x69, 0x6c, 0x3b, 0x4c, 0xfa, 0x6e, 0x61, 0x73, 0x61, 0x3b, 0x4d, 0x65, 0xe1, 0x6e, 0x20,
+0x46, 0xf3, 0x6d, 0x68, 0x61, 0x69, 0x72, 0x3b, 0x44, 0x65, 0x69, 0x72, 0x65, 0x61, 0x64, 0x68, 0x20, 0x46, 0xf3, 0x6d,
+0x68, 0x61, 0x69, 0x72, 0x3b, 0x53, 0x61, 0x6d, 0x68, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x6f, 0x6c, 0x6c, 0x61, 0x69, 0x67,
+0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x42, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x44,
+0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x67, 0x65, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72,
+0x3b, 0x6d, 0x61, 0x67, 0x3b, 0x67, 0x69, 0x75, 0x3b, 0x6c, 0x75, 0x67, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74,
+0x3b, 0x6f, 0x74, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x69, 0x63, 0x3b, 0x47, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f,
+0x3b, 0x46, 0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x70, 0x72, 0x69,
+0x6c, 0x65, 0x3b, 0x4d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x47, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x4c, 0x75, 0x67,
+0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65,
+0x3b, 0x4f, 0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69,
+0x63, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x47, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x4c,
+0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x67, 0x65, 0x6e, 0x6e, 0x61, 0x69, 0x6f, 0x3b, 0x66,
+0x65, 0x62, 0x62, 0x72, 0x61, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x65,
+0x3b, 0x6d, 0x61, 0x67, 0x67, 0x69, 0x6f, 0x3b, 0x67, 0x69, 0x75, 0x67, 0x6e, 0x6f, 0x3b, 0x6c, 0x75, 0x67, 0x6c, 0x69,
+0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f,
+0x74, 0x74, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x69, 0x63, 0x65,
+0x6d, 0x62, 0x72, 0x65, 0x3b, 0xc9c, 0xca8, 0x2e, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd, 0xcb0, 0xcc1, 0x2e, 0x3b, 0xcae, 0xcbe, 0x3b,
+0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0x2e, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1, 0x2e, 0x3b, 0xc86, 0xc97, 0x2e,
+0x3b, 0xcb8, 0xcc6, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0x2e, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0x2e, 0x3b, 0xca8, 0xcb5, 0xcc6,
+0xc82, 0x2e, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0x2e, 0x3b, 0xc9c, 0xca8, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcab, 0xcc6, 0xcac, 0xccd,
+0xcb0, 0xcb5, 0xcb0, 0xcbf, 0x3b, 0xcae, 0xcbe, 0xcb0, 0xccd, 0xc9a, 0xccd, 0x3b, 0xc8f, 0xcaa, 0xccd, 0xcb0, 0xcbf, 0xcb2, 0xccd, 0x3b,
+0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0xca8, 0xccd, 0x3b, 0xc9c, 0xcc1, 0xcb2, 0xcc8, 0x3b, 0xc86, 0xc97, 0xcb8, 0xccd, 0xc9f, 0xccd, 0x3b,
+0xcb8, 0xcaa, 0xccd, 0xc9f, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc85, 0xc95, 0xccd, 0xc9f, 0xccb, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca8,
+0xcb5, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xca1, 0xcbf, 0xcb8, 0xcc6, 0xc82, 0xcac, 0xcb0, 0xccd, 0x3b, 0xc9c, 0x3b, 0xcab, 0xcc6,
+0x3b, 0xcae, 0xcbe, 0x3b, 0xc8f, 0x3b, 0xcae, 0xcc7, 0x3b, 0xc9c, 0xcc2, 0x3b, 0xc9c, 0xcc1, 0x3b, 0xc86, 0x3b, 0xcb8, 0xcc6, 0x3b,
+0xc85, 0x3b, 0xca8, 0x3b, 0xca1, 0xcbf, 0x3b, 0x62c, 0x646, 0x624, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x624, 0x631, 0x6cc, 0x3b, 0x645,
+0x627, 0x631, 0x655, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x654, 0x3b, 0x62c, 0x648, 0x657, 0x646, 0x3b,
+0x62c, 0x648, 0x657, 0x644, 0x627, 0x6cc, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627,
+0x6a9, 0x62a, 0x648, 0x657, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x62c,
+0x3b, 0x641, 0x3b, 0x645, 0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x633, 0x3b, 0x627,
+0x3b, 0x646, 0x3b, 0x49b, 0x430, 0x4a3, 0x2e, 0x3b, 0x430, 0x49b, 0x43f, 0x2e, 0x3b, 0x43d, 0x430, 0x443, 0x2e, 0x3b, 0x441, 0x4d9,
+0x443, 0x2e, 0x3b, 0x43c, 0x430, 0x43c, 0x2e, 0x3b, 0x43c, 0x430, 0x443, 0x2e, 0x3b, 0x448, 0x456, 0x43b, 0x2e, 0x3b, 0x442, 0x430,
+0x43c, 0x2e, 0x3b, 0x49b, 0x44b, 0x440, 0x2e, 0x3b, 0x49b, 0x430, 0x437, 0x2e, 0x3b, 0x49b, 0x430, 0x440, 0x2e, 0x3b, 0x436, 0x435,
+0x43b, 0x442, 0x2e, 0x3b, 0x49b, 0x430, 0x4a3, 0x442, 0x430, 0x440, 0x3b, 0x430, 0x49b, 0x43f, 0x430, 0x43d, 0x3b, 0x43d, 0x430, 0x443,
+0x440, 0x44b, 0x437, 0x3b, 0x441, 0x4d9, 0x443, 0x456, 0x440, 0x3b, 0x43c, 0x430, 0x43c, 0x44b, 0x440, 0x3b, 0x43c, 0x430, 0x443, 0x441,
+0x44b, 0x43c, 0x3b, 0x448, 0x456, 0x43b, 0x434, 0x435, 0x3b, 0x442, 0x430, 0x43c, 0x44b, 0x437, 0x3b, 0x49b, 0x44b, 0x440, 0x43a, 0x4af,
+0x439, 0x435, 0x43a, 0x3b, 0x49b, 0x430, 0x437, 0x430, 0x43d, 0x3b, 0x49b, 0x430, 0x440, 0x430, 0x448, 0x430, 0x3b, 0x436, 0x435, 0x43b,
+0x442, 0x43e, 0x49b, 0x441, 0x430, 0x43d, 0x3b, 0x6d, 0x75, 0x74, 0x2e, 0x3b, 0x67, 0x61, 0x73, 0x2e, 0x3b, 0x77, 0x65, 0x72,
+0x2e, 0x3b, 0x6d, 0x61, 0x74, 0x2e, 0x3b, 0x67, 0x69, 0x63, 0x2e, 0x3b, 0x6b, 0x61, 0x6d, 0x2e, 0x3b, 0x6e, 0x79, 0x61,
+0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x6e, 0x7a, 0x65, 0x2e, 0x3b, 0x75, 0x6b, 0x77, 0x2e, 0x3b, 0x75, 0x67, 0x75,
+0x2e, 0x3b, 0x75, 0x6b, 0x75, 0x2e, 0x3b, 0x4d, 0x75, 0x74, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0x47, 0x61, 0x73, 0x68,
+0x79, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x3b, 0x57, 0x65, 0x72, 0x75, 0x72, 0x77, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x61,
+0x3b, 0x47, 0x69, 0x63, 0x75, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x3b, 0x4b, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x3b, 0x4e, 0x79,
+0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x3b, 0x4e, 0x7a, 0x65, 0x6c, 0x69, 0x3b,
+0x55, 0x6b, 0x77, 0x61, 0x6b, 0x69, 0x72, 0x61, 0x3b, 0x55, 0x67, 0x75, 0x73, 0x68, 0x79, 0x69, 0x6e, 0x67, 0x6f, 0x3b,
+0x55, 0x6b, 0x75, 0x62, 0x6f, 0x7a, 0x61, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430,
+0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e, 0x43d, 0x2e, 0x3b, 0x438, 0x44e, 0x43b,
+0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f,
+0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b,
+0x44c, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x43c, 0x430, 0x439, 0x3b, 0x438, 0x44e,
+0x43d, 0x44c, 0x3b, 0x438, 0x44e, 0x43b, 0x44c, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f,
+0x431, 0x440, 0x44c, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x434,
+0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x42f, 0x3b, 0x424, 0x3b, 0x41c, 0x3b, 0x410, 0x3b, 0x41c, 0x3b, 0x418, 0x3b, 0x418,
+0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x41e, 0x3b, 0x41d, 0x3b, 0x414, 0x3b, 0x31, 0xc6d4, 0x3b, 0x32, 0xc6d4, 0x3b, 0x33, 0xc6d4, 0x3b,
+0x34, 0xc6d4, 0x3b, 0x35, 0xc6d4, 0x3b, 0x36, 0xc6d4, 0x3b, 0x37, 0xc6d4, 0x3b, 0x38, 0xc6d4, 0x3b, 0x39, 0xc6d4, 0x3b, 0x31, 0x30,
+0xc6d4, 0x3b, 0x31, 0x31, 0xc6d4, 0x3b, 0x31, 0x32, 0xc6d4, 0x3b, 0x4d, 0x75, 0x74, 0x2e, 0x3b, 0x47, 0x61, 0x73, 0x2e, 0x3b,
+0x57, 0x65, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x74, 0x2e, 0x3b, 0x47, 0x69, 0x63, 0x2e, 0x3b, 0x4b, 0x61, 0x6d, 0x2e, 0x3b,
+0x4e, 0x79, 0x61, 0x2e, 0x3b, 0x4b, 0x61, 0x6e, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x2e, 0x3b, 0x55, 0x6b, 0x77, 0x2e, 0x3b,
+0x55, 0x67, 0x75, 0x2e, 0x3b, 0x55, 0x6b, 0x75, 0x2e, 0x3b, 0x4e, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x52, 0x75, 0x68, 0x75,
+0x68, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x74, 0x77, 0x61, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x3b, 0x4e, 0x64, 0x61, 0x6d, 0x75,
+0x6b, 0x69, 0x7a, 0x61, 0x3b, 0x52, 0x75, 0x73, 0x61, 0x6d, 0x61, 0x3b, 0x52, 0x75, 0x68, 0x65, 0x73, 0x68, 0x69, 0x3b,
+0x4d, 0x75, 0x6b, 0x61, 0x6b, 0x61, 0x72, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x61, 0x72, 0x6f, 0x3b,
+0x4e, 0x79, 0x61, 0x6b, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x47, 0x69, 0x74, 0x75, 0x67, 0x75, 0x74, 0x75, 0x3b, 0x4d, 0x75,
+0x6e, 0x79, 0x6f, 0x6e, 0x79, 0x6f, 0x3b, 0x4b, 0x69, 0x67, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x3b, 0xea1, 0x2e, 0xe81, 0x2e,
+0x3b, 0xe81, 0x2e, 0xe9e, 0x2e, 0x3b, 0xea1, 0x2e, 0xe99, 0x2e, 0x3b, 0xea1, 0x2e, 0xeaa, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe9e, 0x2e,
+0x3b, 0xea1, 0xeb4, 0x2e, 0xe96, 0x2e, 0x3b, 0xe81, 0x2e, 0xea5, 0x2e, 0x3b, 0xeaa, 0x2e, 0xeab, 0x2e, 0x3b, 0xe81, 0x2e, 0xe8d,
+0x2e, 0x3b, 0xe95, 0x2e, 0xea5, 0x2e, 0x3b, 0xe9e, 0x2e, 0xe88, 0x2e, 0x3b, 0xe97, 0x2e, 0xea7, 0x2e, 0x3b, 0xea1, 0xeb1, 0xe87,
+0xe81, 0xead, 0xe99, 0x3b, 0xe81, 0xeb8, 0xea1, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb5, 0xe99, 0xeb2, 0x3b, 0xec0, 0xea1, 0xeaa, 0xeb2, 0x3b,
+0xe9e, 0xeb6, 0xe94, 0xeaa, 0xeb0, 0xe9e, 0xeb2, 0x3b, 0xea1, 0xeb4, 0xe96, 0xeb8, 0xe99, 0xeb2, 0x3b, 0xe81, 0xecd, 0xea5, 0xeb0, 0xe81,
+0xebb, 0xe94, 0x3b, 0xeaa, 0xeb4, 0xe87, 0xeab, 0xeb2, 0x3b, 0xe81, 0xeb1, 0xe99, 0xe8d, 0xeb2, 0x3b, 0xe95, 0xeb8, 0xea5, 0xeb2, 0x3b,
+0xe9e, 0xeb0, 0xe88, 0xeb4, 0xe81, 0x3b, 0xe97, 0xeb1, 0xe99, 0xea7, 0xeb2, 0x3b, 0x4a, 0x61, 0x6e, 0x76, 0x2e, 0x3b, 0x46, 0x65,
+0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x69, 0x6a, 0x73,
+0x3b, 0x4a, 0x16b, 0x6e, 0x2e, 0x3b, 0x4a, 0x16b, 0x6c, 0x2e, 0x3b, 0x41, 0x75, 0x67, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x74,
+0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x63, 0x2e, 0x3b, 0x4a, 0x61, 0x6e,
+0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74,
+0x73, 0x3b, 0x41, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x4a, 0x16b, 0x6e, 0x69,
+0x6a, 0x73, 0x3b, 0x4a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x73, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x4e, 0x6f,
+0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6a, 0x61,
+0x6e, 0x76, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e,
+0x3b, 0x6d, 0x61, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x2e, 0x3b, 0x6a, 0x16b, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67,
+0x2e, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65,
+0x63, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x76, 0x101, 0x72, 0x69, 0x73, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x101, 0x72, 0x69,
+0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x12b, 0x6c, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x69, 0x6a,
+0x73, 0x3b, 0x6a, 0x16b, 0x6e, 0x69, 0x6a, 0x73, 0x3b, 0x6a, 0x16b, 0x6c, 0x69, 0x6a, 0x73, 0x3b, 0x61, 0x75, 0x67, 0x75,
+0x73, 0x74, 0x73, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62,
+0x72, 0x69, 0x73, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x73, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62,
+0x72, 0x69, 0x73, 0x3b, 0x79, 0x61, 0x6e, 0x3b, 0x66, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x69, 0x3b, 0x61, 0x70, 0x6c, 0x3b,
+0x6d, 0x61, 0x69, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x74, 0x3b, 0x73, 0x74, 0x62, 0x3b,
+0x254, 0x74, 0x62, 0x3b, 0x6e, 0x76, 0x62, 0x3b, 0x64, 0x73, 0x62, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61,
+0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61,
+0x6c, 0xe9, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x73,
+0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0x65, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20,
+0x79, 0x61, 0x20, 0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d,
+0x6f, 0x74, 0xf3, 0x62, 0xe1, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6e, 0x73, 0x61, 0x6d, 0x62,
+0x6f, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x77, 0x61, 0x6d, 0x62, 0x65, 0x3b, 0x73, 0xe1,
+0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x6c, 0x69, 0x62, 0x77, 0x61, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79,
+0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20, 0x7a, 0xf3, 0x6d, 0x69,
+0x20, 0x6e, 0x61, 0x20, 0x6d, 0x254, 0x30c, 0x6b, 0x254, 0x301, 0x3b, 0x73, 0xe1, 0x6e, 0x7a, 0xe1, 0x20, 0x79, 0x61, 0x20,
+0x7a, 0xf3, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x79, 0x3b, 0x66, 0x3b, 0x6d,
+0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x254, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x73,
+0x61, 0x75, 0x73, 0x2e, 0x3b, 0x76, 0x61, 0x73, 0x2e, 0x3b, 0x6b, 0x6f, 0x76, 0x2e, 0x3b, 0x62, 0x61, 0x6c, 0x2e, 0x3b,
+0x67, 0x65, 0x67, 0x2e, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x2e, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67,
+0x70, 0x2e, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x2e, 0x3b, 0x73, 0x70, 0x61, 0x6c, 0x2e, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72,
+0x2e, 0x3b, 0x67, 0x72, 0x75, 0x6f, 0x64, 0x2e, 0x3b, 0x73, 0x61, 0x75, 0x73, 0x69, 0x73, 0x3b, 0x76, 0x61, 0x73, 0x61,
+0x72, 0x69, 0x73, 0x3b, 0x6b, 0x6f, 0x76, 0x61, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x69, 0x73, 0x3b, 0x67,
+0x65, 0x67, 0x75, 0x17e, 0x117, 0x3b, 0x62, 0x69, 0x72, 0x17e, 0x65, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x69, 0x65, 0x70, 0x61,
+0x3b, 0x72, 0x75, 0x67, 0x70, 0x6a, 0x16b, 0x74, 0x69, 0x73, 0x3b, 0x72, 0x75, 0x67, 0x73, 0x117, 0x6a, 0x69, 0x73, 0x3b,
+0x73, 0x70, 0x61, 0x6c, 0x69, 0x73, 0x3b, 0x6c, 0x61, 0x70, 0x6b, 0x72, 0x69, 0x74, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75,
+0x6f, 0x64, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x47, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x52,
+0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x47, 0x3b, 0x458, 0x430, 0x43d, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c,
+0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x2e, 0x3b, 0x458, 0x443,
+0x43b, 0x2e, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d,
+0x43e, 0x435, 0x43c, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x444, 0x435,
+0x432, 0x440, 0x443, 0x430, 0x440, 0x438, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430,
+0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x441,
+0x435, 0x43f, 0x442, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x43d, 0x43e,
+0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x434, 0x435, 0x43a, 0x435, 0x43c, 0x432, 0x440, 0x438, 0x3b, 0x458, 0x3b, 0x444, 0x3b, 0x43c,
+0x3b, 0x430, 0x3b, 0x43c, 0x3b, 0x458, 0x3b, 0x458, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x43e, 0x3b, 0x43d, 0x3b, 0x434, 0x3b, 0x4a,
+0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a,
+0x6f, 0x6e, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x41, 0x6f, 0x67, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
+0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x6f, 0x61, 0x72, 0x79, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x6f,
+0x61, 0x72, 0x79, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x73, 0x61, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x3b, 0x4d, 0x65,
+0x79, 0x3b, 0x4a, 0x6f, 0x6e, 0x61, 0x3b, 0x4a, 0x6f, 0x6c, 0x61, 0x79, 0x3b, 0x41, 0x6f, 0x67, 0x6f, 0x73, 0x69, 0x74,
+0x72, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x72, 0x61,
+0x3b, 0x4e, 0x6f, 0x76, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x61, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x4a,
+0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a,
+0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e,
+0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75,
+0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75,
+0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x6f, 0x73, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b,
+0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a,
+0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0xd1c, 0xd28, 0xd41, 0x3b, 0xd2b, 0xd46, 0xd2c,
+0xd4d, 0xd30, 0xd41, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0x3b, 0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c,
+0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48, 0x3b, 0xd13, 0xd17, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0x3b,
+0xd12, 0xd15, 0xd4d, 0xd1f, 0xd4b, 0x3b, 0xd28, 0xd35, 0xd02, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02, 0x3b, 0xd1c, 0xd28, 0xd41, 0xd35, 0xd30,
+0xd3f, 0x3b, 0xd2b, 0xd46, 0xd2c, 0xd4d, 0xd30, 0xd41, 0xd35, 0xd30, 0xd3f, 0x3b, 0xd2e, 0xd3e, 0xd7c, 0xd1a, 0xd4d, 0xd1a, 0xd4d, 0x3b,
+0xd0f, 0xd2a, 0xd4d, 0xd30, 0xd3f, 0xd7d, 0x3b, 0xd2e, 0xd47, 0xd2f, 0xd4d, 0x3b, 0xd1c, 0xd42, 0xd7a, 0x3b, 0xd1c, 0xd42, 0xd32, 0xd48,
+0x3b, 0xd06, 0xd17, 0xd38, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd4d, 0x3b, 0xd38, 0xd46, 0xd2a, 0xd4d, 0xd31, 0xd4d, 0xd31, 0xd02, 0xd2c, 0xd7c,
+0x3b, 0xd12, 0xd15, 0xd4d, 0x200c, 0xd1f, 0xd4b, 0xd2c, 0xd7c, 0x3b, 0xd28, 0xd35, 0xd02, 0xd2c, 0xd7c, 0x3b, 0xd21, 0xd3f, 0xd38, 0xd02,
+0xd2c, 0xd7c, 0x3b, 0xd1c, 0x3b, 0xd2b, 0xd46, 0x3b, 0xd2e, 0xd3e, 0x3b, 0xd0f, 0x3b, 0xd2e, 0xd47, 0x3b, 0xd1c, 0xd42, 0x3b, 0xd1c,
+0xd42, 0x3b, 0xd13, 0x3b, 0xd38, 0xd46, 0x3b, 0xd12, 0x3b, 0xd28, 0x3b, 0xd21, 0xd3f, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x72,
+0x61, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x6a, 0x3b, 0x120, 0x75, 0x6e, 0x3b, 0x4c, 0x75,
+0x6c, 0x3b, 0x41, 0x77, 0x77, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69,
+0x10b, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x61, 0x72, 0x3b, 0x46, 0x72, 0x61, 0x72, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x75, 0x3b,
+0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x6a, 0x6a, 0x75, 0x3b, 0x120, 0x75, 0x6e, 0x6a, 0x75, 0x3b, 0x4c, 0x75,
+0x6c, 0x6a, 0x75, 0x3b, 0x41, 0x77, 0x77, 0x69, 0x73, 0x73, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x72,
+0x75, 0x3b, 0x4f, 0x74, 0x74, 0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x44,
+0x69, 0x10b, 0x65, 0x6d, 0x62, 0x72, 0x75, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x120, 0x3b,
+0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x3b, 0x92b, 0x947, 0x92c,
+0x94d, 0x930, 0x941, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c,
+0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x911, 0x917, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x3b, 0x911, 0x915,
+0x94d, 0x91f, 0x94b, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x3b, 0x91c, 0x93e,
+0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e,
+0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941,
+0x932, 0x948, 0x3b, 0x911, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x911, 0x915,
+0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947,
+0x902, 0x92c, 0x930, 0x3b, 0x91c, 0x93e, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942,
+0x3b, 0x91c, 0x941, 0x3b, 0x911, 0x3b, 0x938, 0x3b, 0x911, 0x3b, 0x928, 0x94b, 0x3b, 0x921, 0x93f, 0x3b, 0x31, 0x2d, 0x440, 0x20,
+0x441, 0x430, 0x440, 0x3b, 0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x33, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b,
+0x34, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x35, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x36, 0x2d, 0x440, 0x20,
+0x441, 0x430, 0x440, 0x3b, 0x37, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x38, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b,
+0x39, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x30, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x31, 0x2d,
+0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x31, 0x32, 0x2d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x41d, 0x44d, 0x433, 0x434, 0x4af,
+0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x425, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20,
+0x441, 0x430, 0x440, 0x3b, 0x413, 0x443, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b,
+0x414, 0x4e9, 0x440, 0x4e9, 0x432, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x422, 0x430, 0x432, 0x434,
+0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x417, 0x443, 0x440, 0x433, 0x430, 0x434, 0x443, 0x433, 0x430, 0x430,
+0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x414, 0x43e, 0x43b, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b,
+0x41d, 0x430, 0x439, 0x43c, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x415, 0x441, 0x434, 0x4af, 0x433,
+0x44d, 0x44d, 0x440, 0x20, 0x441, 0x430, 0x440, 0x3b, 0x410, 0x440, 0x430, 0x432, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20, 0x441,
+0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x43d, 0x44d, 0x433, 0x434, 0x4af, 0x433, 0x44d, 0x44d, 0x440, 0x20, 0x441,
+0x430, 0x440, 0x3b, 0x410, 0x440, 0x432, 0x430, 0x43d, 0x20, 0x445, 0x43e, 0x451, 0x440, 0x434, 0x443, 0x433, 0x430, 0x430, 0x440, 0x20,
+0x441, 0x430, 0x440, 0x3b, 0x91c, 0x928, 0x935, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x905, 0x930, 0x940, 0x3b,
+0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b,
+0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d,
+0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b,
+0x921, 0x93f, 0x938, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x967, 0x3b, 0x968, 0x3b, 0x969, 0x3b, 0x96a, 0x3b, 0x96b, 0x3b, 0x96c,
+0x3b, 0x96d, 0x3b, 0x96e, 0x3b, 0x96f, 0x3b, 0x967, 0x966, 0x3b, 0x967, 0x967, 0x3b, 0x967, 0x968, 0x3b, 0x91c, 0x928, 0x935, 0x930,
+0x940, 0x3b, 0x92b, 0x930, 0x935, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x905, 0x92a, 0x94d, 0x930, 0x947, 0x932,
+0x3b, 0x92e, 0x908, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x908, 0x3b, 0x905, 0x917, 0x938, 0x94d, 0x924, 0x3b,
+0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x905, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928,
+0x94b, 0x92d, 0x947, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x92e, 0x94d, 0x92c, 0x930, 0x3b, 0x6a, 0x61, 0x6e, 0x75,
+0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69,
+0x6c, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75,
+0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72,
+0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a,
+0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d,
+0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65,
+0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0xb1c, 0xb3e,
+0xb28, 0xb41, 0xb06, 0xb30, 0xb40, 0x3b, 0xb2b, 0xb47, 0xb2c, 0xb4d, 0xb30, 0xb41, 0xb5f, 0xb3e, 0xb30, 0xb40, 0x3b, 0xb2e, 0xb3e, 0xb30,
+0xb4d, 0xb1a, 0xb4d, 0xb1a, 0x3b, 0xb05, 0xb2a, 0xb4d, 0xb30, 0xb47, 0xb32, 0x3b, 0xb2e, 0xb47, 0x3b, 0xb1c, 0xb41, 0xb28, 0x3b, 0xb1c,
+0xb41, 0xb32, 0xb3e, 0xb07, 0x3b, 0xb05, 0xb17, 0xb37, 0xb4d, 0xb1f, 0x3b, 0xb38, 0xb47, 0xb2a, 0xb4d, 0xb1f, 0xb47, 0xb2e, 0xb4d, 0xb2c,
+0xb30, 0x3b, 0xb05, 0xb15, 0xb4d, 0xb1f, 0xb4b, 0xb2c, 0xb30, 0x3b, 0xb28, 0xb2d, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb21, 0xb3f,
+0xb38, 0xb47, 0xb2e, 0xb4d, 0xb2c, 0xb30, 0x3b, 0xb1c, 0xb3e, 0x3b, 0xb2b, 0xb47, 0x3b, 0xb2e, 0xb3e, 0x3b, 0xb05, 0x3b, 0xb2e, 0xb47,
+0x3b, 0xb1c, 0xb41, 0x3b, 0xb1c, 0xb41, 0x3b, 0xb05, 0x3b, 0xb38, 0xb47, 0x3b, 0xb05, 0x3b, 0xb28, 0x3b, 0xb21, 0xb3f, 0x3b, 0x62c,
+0x646, 0x648, 0x631, 0x64a, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x64a, 0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631,
+0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b, 0x627, 0x6ab, 0x633, 0x62a,
+0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631,
+0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x3b,
+0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698,
+0x648, 0x626, 0x6cc, 0x647, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a,
+0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x698, 0x3b, 0x641,
+0x3b, 0x645, 0x3b, 0x622, 0x3b, 0x645, 0x3b, 0x698, 0x3b, 0x698, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f,
+0x3b, 0x698, 0x627, 0x646, 0x648, 0x6cc, 0x647, 0x654, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633,
+0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x647, 0x654, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x698, 0x648, 0x626, 0x6cc,
+0x647, 0x654, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631,
+0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62c, 0x3b, 0x641, 0x3b, 0x645,
+0x3b, 0x627, 0x3b, 0x645, 0x3b, 0x62c, 0x3b, 0x62c, 0x3b, 0x627, 0x3b, 0x633, 0x3b, 0x627, 0x3b, 0x646, 0x3b, 0x62f, 0x3b, 0x62c,
+0x646, 0x648, 0x3b, 0x641, 0x648, 0x631, 0x6cc, 0x647, 0x654, 0x3b, 0x645, 0x627, 0x631, 0x633, 0x3b, 0x622, 0x648, 0x631, 0x6cc, 0x644,
+0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x698, 0x648, 0x626, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x648, 0x62a, 0x3b, 0x633, 0x67e,
+0x62a, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x627, 0x645, 0x628, 0x631, 0x3b, 0x62f,
+0x633, 0x645, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x628, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631, 0x686,
+0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627, 0x6cc, 0x3b,
+0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x67e, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631, 0x3b, 0x646,
+0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x73, 0x74, 0x79, 0x3b, 0x6c, 0x75, 0x74, 0x3b, 0x6d,
+0x61, 0x72, 0x3b, 0x6b, 0x77, 0x69, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x3b, 0x6c, 0x69, 0x70, 0x3b, 0x73,
+0x69, 0x65, 0x3b, 0x77, 0x72, 0x7a, 0x3b, 0x70, 0x61, 0x17a, 0x3b, 0x6c, 0x69, 0x73, 0x3b, 0x67, 0x72, 0x75, 0x3b, 0x73,
+0x74, 0x79, 0x63, 0x7a, 0x65, 0x144, 0x3b, 0x6c, 0x75, 0x74, 0x79, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x65, 0x63, 0x3b, 0x6b,
+0x77, 0x69, 0x65, 0x63, 0x69, 0x65, 0x144, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x63, 0x7a, 0x65, 0x72, 0x77, 0x69, 0x65, 0x63,
+0x3b, 0x6c, 0x69, 0x70, 0x69, 0x65, 0x63, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x69, 0x65, 0x144, 0x3b, 0x77, 0x72, 0x7a,
+0x65, 0x73, 0x69, 0x65, 0x144, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x3b, 0x6c, 0x69,
+0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x7a, 0x69, 0x65, 0x144, 0x3b, 0x73, 0x3b, 0x6c, 0x3b,
+0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x63, 0x3b, 0x6c, 0x3b, 0x73, 0x3b, 0x77, 0x3b, 0x70, 0x3b, 0x6c, 0x3b, 0x67, 0x3b,
+0x73, 0x74, 0x79, 0x63, 0x7a, 0x6e, 0x69, 0x61, 0x3b, 0x6c, 0x75, 0x74, 0x65, 0x67, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x63,
+0x61, 0x3b, 0x6b, 0x77, 0x69, 0x65, 0x74, 0x6e, 0x69, 0x61, 0x3b, 0x6d, 0x61, 0x6a, 0x61, 0x3b, 0x63, 0x7a, 0x65, 0x72,
+0x77, 0x63, 0x61, 0x3b, 0x6c, 0x69, 0x70, 0x63, 0x61, 0x3b, 0x73, 0x69, 0x65, 0x72, 0x70, 0x6e, 0x69, 0x61, 0x3b, 0x77,
+0x72, 0x7a, 0x65, 0x15b, 0x6e, 0x69, 0x61, 0x3b, 0x70, 0x61, 0x17a, 0x64, 0x7a, 0x69, 0x65, 0x72, 0x6e, 0x69, 0x6b, 0x61,
+0x3b, 0x6c, 0x69, 0x73, 0x74, 0x6f, 0x70, 0x61, 0x64, 0x61, 0x3b, 0x67, 0x72, 0x75, 0x64, 0x6e, 0x69, 0x61, 0x3b, 0x6a,
+0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a,
+0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x6e,
+0x6f, 0x76, 0x3b, 0x64, 0x65, 0x7a, 0x3b, 0x6a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x76, 0x65, 0x72,
+0x65, 0x69, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x69,
+0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x6a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f,
+0x3b, 0x73, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x6f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x6e, 0x6f,
+0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x64, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4a, 0x61, 0x6e, 0x3b,
+0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b,
+0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x75, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b,
+0x44, 0x65, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x65, 0x72, 0x65, 0x69, 0x72,
+0x6f, 0x3b, 0x4d, 0x61, 0x72, 0xe7, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a,
+0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65,
+0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f, 0x75, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d,
+0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x7a, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0xa1c, 0xa28, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2b,
+0xa3c, 0xa30, 0xa35, 0xa30, 0xa40, 0x3b, 0xa2e, 0xa3e, 0xa30, 0xa1a, 0x3b, 0xa05, 0xa2a, 0xa4d, 0xa30, 0xa48, 0xa32, 0x3b, 0xa2e, 0xa08,
+0x3b, 0xa1c, 0xa42, 0xa28, 0x3b, 0xa1c, 0xa41, 0xa32, 0xa3e, 0xa08, 0x3b, 0xa05, 0xa17, 0xa38, 0xa24, 0x3b, 0xa38, 0xa24, 0xa70, 0xa2c,
+0xa30, 0x3b, 0xa05, 0xa15, 0xa24, 0xa42, 0xa2c, 0xa30, 0x3b, 0xa28, 0xa35, 0xa70, 0xa2c, 0xa30, 0x3b, 0xa26, 0xa38, 0xa70, 0xa2c, 0xa30,
+0x3b, 0xa1c, 0x3b, 0xa2b, 0xa3c, 0x3b, 0xa2e, 0xa3e, 0x3b, 0xa05, 0x3b, 0xa2e, 0x3b, 0xa1c, 0xa42, 0x3b, 0xa1c, 0xa41, 0x3b, 0xa05,
+0x3b, 0xa38, 0x3b, 0xa05, 0x3b, 0xa28, 0x3b, 0xa26, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc,
+0x3b, 0x645, 0x627, 0x631, 0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c,
+0x648, 0x644, 0x627, 0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a,
+0x648, 0x628, 0x631, 0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x73, 0x63, 0x68, 0x61,
+0x6e, 0x2e, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x2e, 0x3b, 0x6d,
+0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c, 0x2e, 0x3b, 0x66, 0x61, 0x6e, 0x2e, 0x3b, 0x61, 0x76, 0x75, 0x73,
+0x74, 0x3b, 0x73, 0x65, 0x74, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65,
+0x63, 0x2e, 0x3b, 0x73, 0x63, 0x68, 0x61, 0x6e, 0x65, 0x72, 0x3b, 0x66, 0x61, 0x76, 0x72, 0x65, 0x72, 0x3b, 0x6d, 0x61,
+0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x67, 0x6c, 0x3b, 0x6d, 0x61, 0x74, 0x67, 0x3b, 0x7a, 0x65, 0x72, 0x63, 0x6c,
+0x61, 0x64, 0x75, 0x72, 0x3b, 0x66, 0x61, 0x6e, 0x61, 0x64, 0x75, 0x72, 0x3b, 0x61, 0x76, 0x75, 0x73, 0x74, 0x3b, 0x73,
+0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d,
+0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x69,
+0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d,
+0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e, 0x2e, 0x3b, 0x69, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65,
+0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x69,
+0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x65, 0x3b, 0x6d, 0x61,
+0x72, 0x74, 0x69, 0x65, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x65, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x69, 0x75, 0x6e,
+0x69, 0x65, 0x3b, 0x69, 0x75, 0x6c, 0x69, 0x65, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x6f, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x6e, 0x6f, 0x69,
+0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x69, 0x65, 0x3b, 0x49, 0x3b, 0x46,
+0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
+0x3b, 0x42f, 0x43d, 0x432, 0x2e, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440,
+0x2e, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x2e,
+0x3b, 0x421, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x41e, 0x43a, 0x442, 0x2e, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x2e, 0x3b, 0x414, 0x435,
+0x43a, 0x2e, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430,
+0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418,
+0x44e, 0x43b, 0x44c, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b,
+0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431,
+0x440, 0x44c, 0x3b, 0x44f, 0x43d, 0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b,
+0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, 0x3b, 0x430,
+0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x2e,
+0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432, 0x430, 0x440, 0x44f, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44f,
+0x3b, 0x43c, 0x430, 0x440, 0x442, 0x430, 0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44f, 0x3b, 0x43c, 0x430, 0x44f, 0x3b, 0x438, 0x44e,
+0x43d, 0x44f, 0x3b, 0x438, 0x44e, 0x43b, 0x44f, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x442,
+0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44f, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44f, 0x3b,
+0x434, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44f, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x3b, 0x4d, 0x62, 0xe4, 0x3b,
+0x4e, 0x67, 0x75, 0x3b, 0x42, 0xea, 0x6c, 0x3b, 0x46, 0xf6, 0x6e, 0x3b, 0x4c, 0x65, 0x6e, 0x3b, 0x4b, 0xfc, 0x6b, 0x3b,
+0x4d, 0x76, 0x75, 0x3b, 0x4e, 0x67, 0x62, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6b, 0x3b, 0x4e, 0x79, 0x65, 0x6e,
+0x79, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x75, 0x6e, 0x64, 0xef, 0x67, 0x69, 0x3b, 0x4d, 0x62, 0xe4, 0x6e, 0x67, 0xfc, 0x3b,
+0x4e, 0x67, 0x75, 0x62, 0xf9, 0x65, 0x3b, 0x42, 0xea, 0x6c, 0xe4, 0x77, 0xfc, 0x3b, 0x46, 0xf6, 0x6e, 0x64, 0x6f, 0x3b,
+0x4c, 0x65, 0x6e, 0x67, 0x75, 0x61, 0x3b, 0x4b, 0xfc, 0x6b, 0xfc, 0x72, 0xfc, 0x3b, 0x4d, 0x76, 0x75, 0x6b, 0x61, 0x3b,
+0x4e, 0x67, 0x62, 0x65, 0x72, 0x65, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x62, 0xe4, 0x6e, 0x64, 0xfc, 0x72, 0x75, 0x3b, 0x4b,
+0x61, 0x6b, 0x61, 0x75, 0x6b, 0x61, 0x3b, 0x4e, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x46, 0x3b, 0x4c,
+0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x458, 0x430, 0x43d, 0x3b, 0x444, 0x435, 0x431, 0x3b, 0x43c,
+0x430, 0x440, 0x3b, 0x430, 0x43f, 0x440, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430,
+0x432, 0x433, 0x3b, 0x441, 0x435, 0x43f, 0x3b, 0x43e, 0x43a, 0x442, 0x3b, 0x43d, 0x43e, 0x432, 0x3b, 0x434, 0x435, 0x446, 0x3b, 0x458,
+0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b, 0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430,
+0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c, 0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x3b, 0x458, 0x443, 0x43b, 0x3b, 0x430, 0x432, 0x433,
+0x443, 0x441, 0x442, 0x3b, 0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430,
+0x440, 0x3b, 0x43d, 0x43e, 0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b,
+0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0x61, 0x6a, 0x3b,
+0x6a, 0x75, 0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b,
+0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75,
+0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75,
+0x6e, 0x3b, 0x6a, 0x75, 0x6c, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
+0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6a,
+0x3b, 0x6a, 0x3b, 0x61, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x458, 0x430, 0x43d, 0x443, 0x430, 0x440, 0x3b,
+0x444, 0x435, 0x431, 0x440, 0x443, 0x430, 0x440, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x3b, 0x430, 0x43f, 0x440, 0x438, 0x43b, 0x3b, 0x43c,
+0x430, 0x458, 0x3b, 0x458, 0x443, 0x43d, 0x438, 0x3b, 0x458, 0x443, 0x43b, 0x438, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b,
+0x441, 0x435, 0x43f, 0x442, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x43e, 0x43a, 0x442, 0x43e, 0x431, 0x430, 0x440, 0x3b, 0x43d, 0x43e,
+0x432, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x434, 0x435, 0x446, 0x435, 0x43c, 0x431, 0x430, 0x440, 0x3b, 0x42f, 0x43d, 0x432, 0x430,
+0x440, 0x44c, 0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x3b, 0x410, 0x43f,
+0x440, 0x435, 0x43b, 0x44c, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x44c, 0x3b, 0x418, 0x44e, 0x43b, 0x44c, 0x3b, 0x410,
+0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431,
+0x440, 0x44c, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x44c, 0x3b, 0x414, 0x435, 0x43a, 0x430, 0x431, 0x440, 0x44c, 0x3b, 0x44f, 0x43d,
+0x432, 0x2e, 0x3b, 0x444, 0x435, 0x432, 0x2e, 0x3b, 0x43c, 0x430, 0x440, 0x2e, 0x3b, 0x430, 0x43f, 0x440, 0x2e, 0x3b, 0x43c, 0x430,
+0x44f, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e, 0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x2e, 0x3b, 0x441, 0x435, 0x43d,
+0x2e, 0x3b, 0x43e, 0x43a, 0x442, 0x2e, 0x3b, 0x43d, 0x43e, 0x44f, 0x2e, 0x3b, 0x434, 0x435, 0x43a, 0x2e, 0x3b, 0x44f, 0x43d, 0x432,
+0x430, 0x440, 0x44b, 0x3b, 0x444, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x440, 0x442, 0x44a, 0x438, 0x439, 0x44b,
+0x3b, 0x430, 0x43f, 0x440, 0x435, 0x43b, 0x44b, 0x3b, 0x43c, 0x430, 0x439, 0x44b, 0x3b, 0x438, 0x44e, 0x43d, 0x44b, 0x3b, 0x438, 0x44e,
+0x43b, 0x44b, 0x3b, 0x430, 0x432, 0x433, 0x443, 0x441, 0x442, 0x44b, 0x3b, 0x441, 0x435, 0x43d, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b,
+0x43e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x43d, 0x43e, 0x44f, 0x431, 0x440, 0x44b, 0x3b, 0x434, 0x435, 0x43a, 0x430, 0x431,
+0x440, 0x44b, 0x3b, 0x50, 0x68, 0x65, 0x3b, 0x4b, 0x6f, 0x6c, 0x3b, 0x55, 0x62, 0x65, 0x3b, 0x4d, 0x6d, 0x65, 0x3b, 0x4d,
+0x6f, 0x74, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x55, 0x70, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x65, 0x6f, 0x3b, 0x4d,
+0x70, 0x68, 0x3b, 0x50, 0x75, 0x6e, 0x3b, 0x54, 0x73, 0x68, 0x3b, 0x50, 0x68, 0x65, 0x73, 0x65, 0x6b, 0x67, 0x6f, 0x6e,
+0x67, 0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x6f, 0x6c, 0x61, 0x3b, 0x48, 0x6c, 0x61, 0x6b, 0x75, 0x62, 0x65, 0x6c, 0x65, 0x3b,
+0x4d, 0x6d, 0x65, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x61, 0x6e, 0x6f, 0x6e, 0x67, 0x3b, 0x50, 0x68,
+0x75, 0x70, 0x6a, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x68, 0x75, 0x70, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x61, 0x3b, 0x4c,
+0x65, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x50, 0x75, 0x6e, 0x64,
+0x75, 0x6e, 0x67, 0x77, 0x61, 0x6e, 0x65, 0x3b, 0x54, 0x73, 0x68, 0x69, 0x74, 0x77, 0x65, 0x3b, 0x46, 0x65, 0x72, 0x3b,
+0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x6f, 0x70, 0x3b, 0x4d, 0x6f, 0x72, 0x3b, 0x4d, 0x6f, 0x74, 0x3b, 0x53, 0x65, 0x65, 0x3b,
+0x50, 0x68, 0x75, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x44, 0x69, 0x70, 0x3b, 0x4e, 0x67, 0x77, 0x3b,
+0x53, 0x65, 0x64, 0x3b, 0x46, 0x65, 0x72, 0x69, 0x6b, 0x67, 0x6f, 0x6e, 0x67, 0x3b, 0x54, 0x6c, 0x68, 0x61, 0x6b, 0x6f,
+0x6c, 0x65, 0x3b, 0x4d, 0x6f, 0x70, 0x69, 0x74, 0x6c, 0x6f, 0x3b, 0x4d, 0x6f, 0x72, 0x61, 0x6e, 0x61, 0x6e, 0x67, 0x3b,
+0x4d, 0x6f, 0x74, 0x73, 0x68, 0x65, 0x67, 0x61, 0x6e, 0x61, 0x6e, 0x67, 0x3b, 0x53, 0x65, 0x65, 0x74, 0x65, 0x62, 0x6f,
+0x73, 0x69, 0x67, 0x6f, 0x3b, 0x50, 0x68, 0x75, 0x6b, 0x77, 0x69, 0x3b, 0x50, 0x68, 0x61, 0x74, 0x77, 0x65, 0x3b, 0x4c,
+0x77, 0x65, 0x74, 0x73, 0x65, 0x3b, 0x44, 0x69, 0x70, 0x68, 0x61, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x4e, 0x67, 0x77, 0x61,
+0x6e, 0x61, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x53, 0x65, 0x64, 0x69, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6f, 0x6c, 0x65,
+0x3b, 0x4e, 0x64, 0x69, 0x3b, 0x4b, 0x75, 0x6b, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x4b, 0x75, 0x62, 0x3b, 0x43, 0x68, 0x76,
+0x3b, 0x43, 0x68, 0x6b, 0x3b, 0x43, 0x68, 0x67, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x47, 0x75, 0x6e, 0x3b, 0x47, 0x75, 0x6d,
+0x3b, 0x4d, 0x62, 0x3b, 0x5a, 0x76, 0x69, 0x3b, 0x4e, 0x64, 0x69, 0x72, 0x61, 0x3b, 0x4b, 0x75, 0x6b, 0x61, 0x64, 0x7a,
+0x69, 0x3b, 0x4b, 0x75, 0x72, 0x75, 0x6d, 0x65, 0x3b, 0x4b, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x62, 0x69, 0x3b, 0x43, 0x68,
+0x69, 0x76, 0x61, 0x62, 0x76, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x6b, 0x75,
+0x6e, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4e, 0x79, 0x61, 0x6d, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x75, 0x3b, 0x47, 0x75,
+0x6e, 0x79, 0x61, 0x6e, 0x61, 0x3b, 0x47, 0x75, 0x6d, 0x69, 0x67, 0x75, 0x72, 0x75, 0x3b, 0x4d, 0x62, 0x75, 0x64, 0x7a,
+0x69, 0x3b, 0x5a, 0x76, 0x69, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x43, 0x3b,
+0x43, 0x3b, 0x4e, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0xda2, 0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8,
+0xdcf, 0xdbb, 0xdca, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6,
+0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca,
+0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b, 0xda2, 0xdb1, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb4, 0xdd9,
+0xdb6, 0xdbb, 0xdc0, 0xdcf, 0xdbb, 0xdd2, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda,
+0xdbd, 0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c,
+0xddd, 0xdc3, 0xdca, 0xdad, 0xdd4, 0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0xdad, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xd94, 0xd9a,
+0xdca, 0xdad, 0xddd, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xdaf, 0xdd9, 0xdc3,
+0xdd0, 0xdb8, 0xdca, 0xdb6, 0xdbb, 0xdca, 0x3b, 0xda2, 0x3b, 0xdb4, 0xdd9, 0x3b, 0xdb8, 0xdcf, 0x3b, 0xd85, 0x3b, 0xdb8, 0xdd0, 0x3b,
+0xda2, 0xdd6, 0x3b, 0xda2, 0xdd6, 0x3b, 0xd85, 0x3b, 0xdc3, 0xdd0, 0x3b, 0xd94, 0x3b, 0xdb1, 0xdd9, 0x3b, 0xdaf, 0xdd9, 0x3b, 0xda2,
+0xdb1, 0x3b, 0xdb4, 0xdd9, 0xdb6, 0x3b, 0xdb8, 0xdcf, 0xdbb, 0xdca, 0xdad, 0xdd4, 0x3b, 0xd85, 0xdb4, 0xdca, 0x200d, 0xdbb, 0xdda, 0xdbd,
+0xdca, 0x3b, 0xdb8, 0xdd0, 0xdba, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdb1, 0xdd2, 0x3b, 0xda2, 0xdd6, 0xdbd, 0xdd2, 0x3b, 0xd85, 0xd9c, 0xddd,
+0x3b, 0xdc3, 0xdd0, 0xdb4, 0xdca, 0x3b, 0xd94, 0xd9a, 0xdca, 0x3b, 0xdb1, 0xddc, 0xdc0, 0xdd0, 0x3b, 0xdaf, 0xdd9, 0xdc3, 0xdd0, 0x3b,
+0x42, 0x68, 0x69, 0x3b, 0x56, 0x61, 0x6e, 0x3b, 0x56, 0x6f, 0x6c, 0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x68, 0x3b,
+0x4e, 0x68, 0x6c, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4e, 0x67, 0x63, 0x3b, 0x4e, 0x79, 0x6f, 0x3b, 0x4d, 0x70, 0x68, 0x3b,
+0x4c, 0x77, 0x65, 0x3b, 0x4e, 0x67, 0x6f, 0x3b, 0x42, 0x68, 0x69, 0x6d, 0x62, 0x69, 0x64, 0x76, 0x77, 0x61, 0x6e, 0x65,
+0x3b, 0x69, 0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x61, 0x6e, 0x61, 0x3b, 0x69, 0x4e, 0x64, 0x6c, 0x6f, 0x76, 0x75, 0x2d, 0x6c,
+0x65, 0x6e, 0x6b, 0x68, 0x75, 0x6c, 0x75, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, 0x69, 0x4e, 0x6b, 0x68, 0x77,
+0x65, 0x6b, 0x68, 0x77, 0x65, 0x74, 0x69, 0x3b, 0x69, 0x4e, 0x68, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x4b, 0x68, 0x6f, 0x6c,
+0x77, 0x61, 0x6e, 0x65, 0x3b, 0x69, 0x4e, 0x67, 0x63, 0x69, 0x3b, 0x69, 0x4e, 0x79, 0x6f, 0x6e, 0x69, 0x3b, 0x69, 0x4d,
+0x70, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4c, 0x77, 0x65, 0x74, 0x69, 0x3b, 0x69, 0x4e, 0x67, 0x6f, 0x6e, 0x67, 0x6f, 0x6e,
+0x69, 0x3b, 0x6a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x70, 0x72, 0x3b, 0x6d, 0xe1,
+0x6a, 0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f, 0x6b,
+0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x63, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x3b, 0x66, 0x65, 0x62,
+0x72, 0x75, 0xe1, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65, 0x63, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c, 0x3b, 0x6d, 0xe1, 0x6a,
+0x3b, 0x6a, 0xfa, 0x6e, 0x3b, 0x6a, 0xfa, 0x6c, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74,
+0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0xe1, 0x72, 0x61, 0x3b,
+0x66, 0x65, 0x62, 0x72, 0x75, 0xe1, 0x72, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x3b, 0x61, 0x70, 0x72, 0xed, 0x6c,
+0x61, 0x3b, 0x6d, 0xe1, 0x6a, 0x61, 0x3b, 0x6a, 0xfa, 0x6e, 0x61, 0x3b, 0x6a, 0xfa, 0x6c, 0x61, 0x3b, 0x61, 0x75, 0x67,
+0x75, 0x73, 0x74, 0x61, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x6f, 0x6b, 0x74, 0xf3, 0x62,
+0x72, 0x61, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x61, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x61,
+0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x65,
+0x63, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6a, 0x3b, 0x6a, 0x75,
+0x6c, 0x69, 0x6a, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65,
+0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
+0x2e, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e,
+0x3b, 0x61, 0x76, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e,
+0x3b, 0x64, 0x65, 0x63, 0x2e, 0x3b, 0x4b, 0x6f, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x41, 0x66,
+0x72, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x4c, 0x69, 0x78, 0x3b, 0x54, 0x6f, 0x64, 0x3b, 0x53, 0x69, 0x64, 0x3b, 0x53, 0x61,
+0x67, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x4b, 0x49, 0x54, 0x3b, 0x4c, 0x49, 0x54, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20,
+0x4b, 0x6f, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x61, 0x64,
+0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x64, 0x64, 0x65, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
+0x68, 0x61, 0x20, 0x41, 0x66, 0x72, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x68, 0x61, 0x6e,
+0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x69, 0x78, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73,
+0x68, 0x61, 0x20, 0x54, 0x6f, 0x64, 0x6f, 0x62, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x69,
+0x64, 0x65, 0x65, 0x64, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x53, 0x61, 0x67, 0x61, 0x61, 0x6c,
+0x61, 0x61, 0x64, 0x3b, 0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b, 0x42, 0x69,
+0x73, 0x68, 0x61, 0x20, 0x4b, 0x6f, 0x77, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61, 0x61, 0x64, 0x3b,
+0x42, 0x69, 0x73, 0x68, 0x61, 0x20, 0x4c, 0x61, 0x62, 0x61, 0x20, 0x69, 0x79, 0x6f, 0x20, 0x54, 0x6f, 0x62, 0x6e, 0x61,
+0x61, 0x64, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53,
+0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x45, 0x6e, 0x65, 0x2e, 0x3b, 0x46, 0x65, 0x62, 0x2e, 0x3b, 0x4d, 0x61, 0x72,
+0x2e, 0x3b, 0x41, 0x62, 0x72, 0x2e, 0x3b, 0x4d, 0x61, 0x79, 0x2e, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c,
+0x2e, 0x3b, 0x41, 0x67, 0x6f, 0x2e, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x4f, 0x63, 0x74, 0x2e, 0x3b, 0x4e, 0x6f,
+0x76, 0x2e, 0x3b, 0x44, 0x69, 0x63, 0x2e, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x65, 0x72,
+0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x7a, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x4a,
+0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x76,
+0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x46,
+0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
+0x3b, 0x65, 0x6e, 0x65, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e,
+0x3b, 0x6d, 0x61, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x6f, 0x2e,
+0x3b, 0x73, 0x65, 0x70, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63,
+0x2e, 0x3b, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x7a,
+0x6f, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x6f, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x3b, 0x6a,
+0x75, 0x6c, 0x69, 0x6f, 0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x69, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x6f, 0x63, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x6e, 0x6f, 0x76, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65,
+0x3b, 0x64, 0x69, 0x63, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x65, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e,
+0x3b, 0x6d, 0x7a, 0x6f, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x79, 0x2e, 0x3b, 0x6a, 0x75, 0x6e, 0x3b, 0x6a,
+0x75, 0x6c, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b, 0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76,
+0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x45, 0x3b, 0x46, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x3b, 0x4d, 0x79, 0x3b, 0x4a,
+0x6e, 0x3b, 0x4a, 0x6c, 0x3b, 0x41, 0x67, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x65, 0x6e, 0x65, 0x2e,
+0x3b, 0x66, 0x65, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x7a, 0x6f, 0x2e, 0x3b, 0x61, 0x62, 0x72, 0x2e, 0x3b, 0x6d, 0x79, 0x2e,
+0x3b, 0x6a, 0x75, 0x6e, 0x2e, 0x3b, 0x6a, 0x75, 0x6c, 0x2e, 0x3b, 0x61, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x74, 0x2e, 0x3b,
+0x6f, 0x63, 0x74, 0x2e, 0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x69, 0x63, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46,
+0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a,
+0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44,
+0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b,
+0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
+0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44,
+0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41,
+0x70, 0x72, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b, 0x53,
+0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61,
+0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x70, 0x72,
+0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x6a, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67,
+0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62,
+0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x6d, 0x61,
+0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75,
+0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72,
+0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x64, 0x65,
+0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x42f, 0x43d, 0x432, 0x3b, 0x424, 0x435, 0x432, 0x3b, 0x41c, 0x430, 0x440, 0x3b, 0x410,
+0x43f, 0x440, 0x3b, 0x41c, 0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x3b, 0x421,
+0x435, 0x43d, 0x3b, 0x41e, 0x43a, 0x442, 0x3b, 0x41d, 0x43e, 0x44f, 0x3b, 0x414, 0x435, 0x43a, 0x3b, 0x42f, 0x43d, 0x432, 0x430, 0x440,
+0x3b, 0x424, 0x435, 0x432, 0x440, 0x430, 0x43b, 0x3b, 0x41c, 0x430, 0x440, 0x442, 0x3b, 0x410, 0x43f, 0x440, 0x435, 0x43b, 0x3b, 0x41c,
+0x430, 0x439, 0x3b, 0x418, 0x44e, 0x43d, 0x3b, 0x418, 0x44e, 0x43b, 0x3b, 0x410, 0x432, 0x433, 0x443, 0x441, 0x442, 0x3b, 0x421, 0x435,
+0x43d, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41e, 0x43a, 0x442, 0x44f, 0x431, 0x440, 0x3b, 0x41d, 0x43e, 0x44f, 0x431, 0x440, 0x3b, 0x414,
+0x435, 0x43a, 0x430, 0x431, 0x440, 0x3b, 0xb9c, 0xba9, 0x2e, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd,
+0x2e, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b,
+0xb86, 0xb95, 0x2e, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0x2e, 0x3b, 0xb85, 0xb95, 0xbcd, 0x2e, 0x3b, 0xba8, 0xbb5, 0x2e, 0x3b, 0xb9f,
+0xbbf, 0xb9a, 0x2e, 0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae,
+0xbbe, 0xbb0, 0xbcd, 0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd,
+0x3b, 0xb9c, 0xbc2, 0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbc1, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd,
+0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd,
+0x3b, 0xb9f, 0xbbf, 0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9c, 0x3b, 0xbaa, 0xbbf, 0x3b, 0xbae, 0xbbe, 0x3b, 0xb8f, 0x3b,
+0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb9c, 0xbc2, 0x3b, 0xb86, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xb85, 0x3b, 0xba8, 0x3b, 0xb9f, 0xbbf,
+0x3b, 0xb9c, 0xba9, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbaa, 0xbbf, 0xbaa, 0xbcd, 0xbb0, 0xbb5, 0xbb0, 0xbbf, 0x3b, 0xbae, 0xbbe, 0xbb0, 0xbcd,
+0xb9a, 0xbcd, 0x3b, 0xb8f, 0xbaa, 0xbcd, 0xbb0, 0xbb2, 0xbcd, 0x3b, 0xbae, 0xbc7, 0x3b, 0xb9c, 0xbc2, 0xba9, 0xbcd, 0x3b, 0xb9c, 0xbc2,
+0xbb2, 0xbc8, 0x3b, 0xb86, 0xb95, 0xbb8, 0xbcd, 0xb9f, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbaa, 0xbcd, 0xb9f, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd,
+0x3b, 0xb85, 0xb95, 0xbcd, 0xb9f, 0xbcb, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xba8, 0xbb5, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xb9f, 0xbbf,
+0xb9a, 0xbae, 0xbcd, 0xbaa, 0xbb0, 0xbcd, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d,
+0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32,
+0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d,
+0xc1f, 0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b,
+0xc3f, 0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0e, 0xc2a, 0xc4d, 0xc30, 0xc3f,
+0xc32, 0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc42, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d,
+0xc1f, 0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c,
+0xc30, 0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc1c,
+0x3b, 0xc2b, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0x3b, 0xc0f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0x3b, 0xc1c, 0xc41, 0x3b, 0xc06, 0x3b,
+0xc38, 0xc46, 0x3b, 0xc05, 0x3b, 0xc28, 0x3b, 0xc21, 0xc3f, 0x3b, 0xc1c, 0xc28, 0x3b, 0xc2b, 0xc3f, 0xc2c, 0xc4d, 0xc30, 0x3b, 0xc2e,
+0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0f, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b,
+0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f,
+0xc4b, 0x3b, 0xc28, 0xc35, 0xc02, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0x3b, 0xc1c, 0xc28, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2b, 0xc3f,
+0xc2c, 0xc4d, 0xc30, 0xc35, 0xc30, 0xc3f, 0x3b, 0xc2e, 0xc3e, 0xc30, 0xc4d, 0xc1a, 0xc3f, 0x3b, 0xc0e, 0xc2a, 0xc4d, 0xc30, 0xc3f, 0xc32,
+0xc4d, 0x3b, 0xc2e, 0xc47, 0x3b, 0xc1c, 0xc42, 0xc28, 0xc4d, 0x3b, 0xc1c, 0xc41, 0xc32, 0xc48, 0x3b, 0xc06, 0xc17, 0xc38, 0xc4d, 0xc1f,
+0xc41, 0x3b, 0xc38, 0xc46, 0xc2a, 0xc4d, 0xc1f, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc05, 0xc15, 0xc4d, 0xc1f, 0xc4b, 0xc2c, 0xc30,
+0xc4d, 0x3b, 0xc28, 0xc35, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xc21, 0xc3f, 0xc38, 0xc46, 0xc02, 0xc2c, 0xc30, 0xc4d, 0x3b, 0xe21, 0x2e,
+0xe04, 0x2e, 0x3b, 0xe01, 0x2e, 0xe1e, 0x2e, 0x3b, 0xe21, 0xe35, 0x2e, 0xe04, 0x2e, 0x3b, 0xe40, 0xe21, 0x2e, 0xe22, 0x2e, 0x3b,
+0xe1e, 0x2e, 0xe04, 0x2e, 0x3b, 0xe21, 0xe34, 0x2e, 0xe22, 0x2e, 0x3b, 0xe01, 0x2e, 0xe04, 0x2e, 0x3b, 0xe2a, 0x2e, 0xe04, 0x2e,
+0x3b, 0xe01, 0x2e, 0xe22, 0x2e, 0x3b, 0xe15, 0x2e, 0xe04, 0x2e, 0x3b, 0xe1e, 0x2e, 0xe22, 0x2e, 0x3b, 0xe18, 0x2e, 0xe04, 0x2e,
+0x3b, 0xe21, 0xe01, 0xe23, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe38, 0xe21, 0xe20, 0xe32, 0xe1e, 0xe31, 0xe19, 0xe18, 0xe4c, 0x3b, 0xe21,
+0xe35, 0xe19, 0xe32, 0xe04, 0xe21, 0x3b, 0xe40, 0xe21, 0xe29, 0xe32, 0xe22, 0xe19, 0x3b, 0xe1e, 0xe24, 0xe29, 0xe20, 0xe32, 0xe04, 0xe21,
+0x3b, 0xe21, 0xe34, 0xe16, 0xe38, 0xe19, 0xe32, 0xe22, 0xe19, 0x3b, 0xe01, 0xe23, 0xe01, 0xe0e, 0xe32, 0xe04, 0xe21, 0x3b, 0xe2a, 0xe34,
+0xe07, 0xe2b, 0xe32, 0xe04, 0xe21, 0x3b, 0xe01, 0xe31, 0xe19, 0xe22, 0xe32, 0xe22, 0xe19, 0x3b, 0xe15, 0xe38, 0xe25, 0xe32, 0xe04, 0xe21,
+0x3b, 0xe1e, 0xe24, 0xe28, 0xe08, 0xe34, 0xe01, 0xe32, 0xe22, 0xe19, 0x3b, 0xe18, 0xe31, 0xe19, 0xe27, 0xe32, 0xe04, 0xe21, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf44, 0xf0b, 0xf54, 0xf7c, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66,
+0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf66, 0xf74, 0xf58, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56,
+0xf0b, 0xf56, 0xf5e, 0xf72, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf63, 0xf94, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xfb2, 0xf74, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf51, 0xf74,
+0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf62, 0xf92, 0xfb1, 0xf51, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf51, 0xf42, 0xf74, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b,
+0xf54, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf45, 0xf72, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b,
+0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0xf56, 0xf45, 0xf74, 0xf0b, 0xf42, 0xf49, 0xf72, 0xf66, 0xf0b, 0xf54, 0xf0b, 0x3b, 0x1303, 0x1295, 0x12e9,
+0x3b, 0x134c, 0x1265, 0x1229, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4, 0x1355, 0x1228, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301,
+0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x3b, 0x1234, 0x1355, 0x1274, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x3b, 0x1296, 0x126c, 0x121d, 0x3b, 0x12f2,
+0x1234, 0x121d, 0x3b, 0x1303, 0x1295, 0x12e9, 0x12c8, 0x122a, 0x3b, 0x134c, 0x1265, 0x1229, 0x12c8, 0x122a, 0x3b, 0x121b, 0x122d, 0x127d, 0x3b, 0x12a4,
+0x1355, 0x1228, 0x120d, 0x3b, 0x121c, 0x12ed, 0x3b, 0x1301, 0x1295, 0x3b, 0x1301, 0x120b, 0x12ed, 0x3b, 0x12a6, 0x1308, 0x1235, 0x1275, 0x3b, 0x1234,
+0x1355, 0x1274, 0x121d, 0x1260, 0x122d, 0x3b, 0x12a6, 0x12ad, 0x1270, 0x12cd, 0x1260, 0x122d, 0x3b, 0x1296, 0x126c, 0x121d, 0x1260, 0x122d, 0x3b, 0x12f2,
+0x1234, 0x121d, 0x1260, 0x122d, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x3b, 0x1218, 0x130b, 0x1262, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x3b,
+0x130d, 0x1295, 0x1266, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208, 0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x3b, 0x1325,
+0x1245, 0x121d, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b, 0x1273, 0x1215, 0x1233, 0x3b, 0x1325, 0x122a, 0x3b, 0x1208, 0x12ab, 0x1272, 0x1275, 0x3b, 0x1218,
+0x130b, 0x1262, 0x1275, 0x3b, 0x121a, 0x12eb, 0x12dd, 0x12eb, 0x3b, 0x130d, 0x1295, 0x1266, 0x1275, 0x3b, 0x1230, 0x1290, 0x3b, 0x1213, 0x121d, 0x1208,
+0x3b, 0x1290, 0x1213, 0x1230, 0x3b, 0x1218, 0x1235, 0x12a8, 0x1228, 0x121d, 0x3b, 0x1325, 0x1245, 0x121d, 0x1272, 0x3b, 0x1215, 0x12f3, 0x122d, 0x3b,
+0x1273, 0x1215, 0x1233, 0x1235, 0x3b, 0x53, 0x101, 0x6e, 0x3b, 0x46, 0x113, 0x70, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x3b, 0x2bb, 0x45,
+0x70, 0x65, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x53, 0x69, 0x75, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x3b, 0x53,
+0x65, 0x70, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x3b, 0x54, 0x12b, 0x73, 0x3b, 0x53, 0x101, 0x6e, 0x75,
+0x61, 0x6c, 0x69, 0x3b, 0x46, 0x113, 0x70, 0x75, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x2bb, 0x61, 0x73, 0x69, 0x3b, 0x2bb,
+0x45, 0x70, 0x65, 0x6c, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x113, 0x3b, 0x53, 0x75, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x75, 0x6c,
+0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x6f, 0x6b, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x69, 0x74, 0x65, 0x6d, 0x61, 0x3b,
+0x2bb, 0x4f, 0x6b, 0x61, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x4e, 0x14d, 0x76, 0x65, 0x6d, 0x61, 0x3b, 0x54, 0x12b, 0x73, 0x65,
+0x6d, 0x61, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x53,
+0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x4b, 0x75, 0x6c, 0x3b, 0x44,
+0x7a, 0x69, 0x3b, 0x4d, 0x75, 0x64, 0x3b, 0x4b, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x68, 0x61, 0x3b, 0x4e,
+0x64, 0x7a, 0x3b, 0x4e, 0x68, 0x6c, 0x3b, 0x48, 0x75, 0x6b, 0x3b, 0x4e, 0x27, 0x77, 0x3b, 0x53, 0x75, 0x6e, 0x67, 0x75,
+0x74, 0x69, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x69, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x79,
+0x61, 0x6e, 0x6b, 0x75, 0x6c, 0x75, 0x3b, 0x44, 0x7a, 0x69, 0x76, 0x61, 0x6d, 0x69, 0x73, 0x6f, 0x6b, 0x6f, 0x3b, 0x4d,
+0x75, 0x64, 0x79, 0x61, 0x78, 0x69, 0x68, 0x69, 0x3b, 0x4b, 0x68, 0x6f, 0x74, 0x61, 0x76, 0x75, 0x78, 0x69, 0x6b, 0x61,
+0x3b, 0x4d, 0x61, 0x77, 0x75, 0x77, 0x61, 0x6e, 0x69, 0x3b, 0x4d, 0x68, 0x61, 0x77, 0x75, 0x72, 0x69, 0x3b, 0x4e, 0x64,
+0x7a, 0x68, 0x61, 0x74, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x48, 0x75, 0x6b, 0x75,
+0x72, 0x69, 0x3b, 0x4e, 0x27, 0x77, 0x65, 0x6e, 0x64, 0x7a, 0x61, 0x6d, 0x68, 0x61, 0x6c, 0x61, 0x3b, 0x4f, 0x63, 0x61,
+0x3b, 0x15e, 0x75, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4e, 0x69, 0x73, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x61, 0x7a,
+0x3b, 0x54, 0x65, 0x6d, 0x3b, 0x41, 0x11f, 0x75, 0x3b, 0x45, 0x79, 0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x3b, 0x4b, 0x61, 0x73,
+0x3b, 0x41, 0x72, 0x61, 0x3b, 0x4f, 0x63, 0x61, 0x6b, 0x3b, 0x15e, 0x75, 0x62, 0x61, 0x74, 0x3b, 0x4d, 0x61, 0x72, 0x74,
+0x3b, 0x4e, 0x69, 0x73, 0x61, 0x6e, 0x3b, 0x4d, 0x61, 0x79, 0x131, 0x73, 0x3b, 0x48, 0x61, 0x7a, 0x69, 0x72, 0x61, 0x6e,
+0x3b, 0x54, 0x65, 0x6d, 0x6d, 0x75, 0x7a, 0x3b, 0x41, 0x11f, 0x75, 0x73, 0x74, 0x6f, 0x73, 0x3b, 0x45, 0x79, 0x6c, 0xfc,
+0x6c, 0x3b, 0x45, 0x6b, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x73, 0x131, 0x6d, 0x3b, 0x41, 0x72, 0x61, 0x6c, 0x131, 0x6b, 0x3b,
+0x4f, 0x3b, 0x15e, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x45, 0x3b, 0x45, 0x3b,
+0x4b, 0x3b, 0x41, 0x3b, 0x421, 0x456, 0x447, 0x3b, 0x41b, 0x44e, 0x442, 0x3b, 0x411, 0x435, 0x440, 0x3b, 0x41a, 0x432, 0x456, 0x3b,
+0x422, 0x440, 0x430, 0x3b, 0x427, 0x435, 0x440, 0x3b, 0x41b, 0x438, 0x43f, 0x3b, 0x421, 0x435, 0x440, 0x3b, 0x412, 0x435, 0x440, 0x3b,
+0x416, 0x43e, 0x432, 0x3b, 0x41b, 0x438, 0x441, 0x3b, 0x413, 0x440, 0x443, 0x3b, 0x421, 0x456, 0x447, 0x435, 0x43d, 0x44c, 0x3b, 0x41b,
+0x44e, 0x442, 0x438, 0x439, 0x3b, 0x411, 0x435, 0x440, 0x435, 0x437, 0x435, 0x43d, 0x44c, 0x3b, 0x41a, 0x432, 0x456, 0x442, 0x435, 0x43d,
+0x44c, 0x3b, 0x422, 0x440, 0x430, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x427, 0x435, 0x440, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x438,
+0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x421, 0x435, 0x440, 0x43f, 0x435, 0x43d, 0x44c, 0x3b, 0x412, 0x435, 0x440, 0x435, 0x441, 0x435, 0x43d,
+0x44c, 0x3b, 0x416, 0x43e, 0x432, 0x442, 0x435, 0x43d, 0x44c, 0x3b, 0x41b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x3b, 0x413,
+0x440, 0x443, 0x434, 0x435, 0x43d, 0x44c, 0x3b, 0x421, 0x3b, 0x41b, 0x3b, 0x411, 0x3b, 0x41a, 0x3b, 0x422, 0x3b, 0x427, 0x3b, 0x41b,
+0x3b, 0x421, 0x3b, 0x412, 0x3b, 0x416, 0x3b, 0x41b, 0x3b, 0x413, 0x3b, 0x441, 0x456, 0x447, 0x2e, 0x3b, 0x43b, 0x44e, 0x442, 0x2e,
+0x3b, 0x431, 0x435, 0x440, 0x2e, 0x3b, 0x43a, 0x432, 0x456, 0x442, 0x2e, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x2e, 0x3b, 0x447, 0x435,
+0x440, 0x432, 0x2e, 0x3b, 0x43b, 0x438, 0x43f, 0x2e, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x2e, 0x3b, 0x432, 0x435, 0x440, 0x2e, 0x3b,
+0x436, 0x43e, 0x432, 0x442, 0x2e, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x2e, 0x3b, 0x433, 0x440, 0x443, 0x434, 0x2e, 0x3b, 0x441, 0x456,
+0x447, 0x43d, 0x44f, 0x3b, 0x43b, 0x44e, 0x442, 0x43e, 0x433, 0x43e, 0x3b, 0x431, 0x435, 0x440, 0x435, 0x437, 0x43d, 0x44f, 0x3b, 0x43a,
+0x432, 0x456, 0x442, 0x43d, 0x44f, 0x3b, 0x442, 0x440, 0x430, 0x432, 0x43d, 0x44f, 0x3b, 0x447, 0x435, 0x440, 0x432, 0x43d, 0x44f, 0x3b,
+0x43b, 0x438, 0x43f, 0x43d, 0x44f, 0x3b, 0x441, 0x435, 0x440, 0x43f, 0x43d, 0x44f, 0x3b, 0x432, 0x435, 0x440, 0x435, 0x441, 0x43d, 0x44f,
+0x3b, 0x436, 0x43e, 0x432, 0x442, 0x43d, 0x44f, 0x3b, 0x43b, 0x438, 0x441, 0x442, 0x43e, 0x43f, 0x430, 0x434, 0x430, 0x3b, 0x433, 0x440,
+0x443, 0x434, 0x43d, 0x44f, 0x3b, 0x62c, 0x646, 0x648, 0x631, 0x6cc, 0x3b, 0x641, 0x631, 0x648, 0x631, 0x6cc, 0x3b, 0x645, 0x627, 0x631,
+0x686, 0x3b, 0x627, 0x67e, 0x631, 0x6cc, 0x644, 0x3b, 0x645, 0x626, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x627,
+0x626, 0x6cc, 0x3b, 0x627, 0x6af, 0x633, 0x62a, 0x3b, 0x633, 0x62a, 0x645, 0x628, 0x631, 0x3b, 0x627, 0x6a9, 0x62a, 0x648, 0x628, 0x631,
+0x3b, 0x646, 0x648, 0x645, 0x628, 0x631, 0x3b, 0x62f, 0x633, 0x645, 0x628, 0x631, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x3b, 0x46, 0x65,
+0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e, 0x3b, 0x49,
+0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x79, 0x61,
+0x3b, 0x44, 0x65, 0x6b, 0x3b, 0x59, 0x61, 0x6e, 0x76, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x61, 0x6c, 0x3b, 0x4d,
+0x61, 0x72, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x49, 0x79, 0x75, 0x6e, 0x3b, 0x49,
+0x79, 0x75, 0x6c, 0x3b, 0x41, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x6e, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b,
+0x4f, 0x6b, 0x74, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x4e, 0x6f, 0x79, 0x61, 0x62, 0x72, 0x3b, 0x44, 0x65, 0x6b, 0x61, 0x62,
+0x72, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x53, 0x3b,
+0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x62c, 0x646, 0x648, 0x3b, 0x641, 0x628, 0x631, 0x3b, 0x645, 0x627, 0x631, 0x3b, 0x627, 0x67e,
+0x631, 0x3b, 0x645, 0x640, 0x6cc, 0x3b, 0x62c, 0x648, 0x646, 0x3b, 0x62c, 0x648, 0x644, 0x3b, 0x627, 0x6af, 0x633, 0x3b, 0x633, 0x67e,
+0x62a, 0x3b, 0x627, 0x6a9, 0x62a, 0x3b, 0x646, 0x648, 0x645, 0x3b, 0x62f, 0x633, 0x645, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x3b,
+0x54, 0x68, 0x67, 0x20, 0x32, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x54, 0x68,
+0x67, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x36, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x54, 0x68, 0x67, 0x20,
+0x38, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x39, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31,
+0x31, 0x3b, 0x54, 0x68, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x3b, 0x54, 0x68, 0xe1,
+0x6e, 0x67, 0x20, 0x32, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x33, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x34,
+0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x35, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x36, 0x3b, 0x54, 0x68, 0xe1,
+0x6e, 0x67, 0x20, 0x37, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x38, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x39,
+0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x54, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x54,
+0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x32, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x32, 0x3b,
0x74, 0x68, 0x67, 0x20, 0x33, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x34, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x35, 0x3b, 0x74, 0x68,
0x67, 0x20, 0x36, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x37, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x38, 0x3b, 0x74, 0x68, 0x67, 0x20,
0x39, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x30, 0x3b, 0x74, 0x68, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0x67, 0x20,
-0x31, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1ed9, 0x74, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x68,
-0x61, 0x69, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x62, 0x61, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x74, 0x1b0,
-0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6e, 0x103, 0x6d, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x73, 0xe1, 0x75,
-0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x62, 0x1ea3, 0x79, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x74, 0xe1, 0x6d,
-0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x63, 0x68, 0xed, 0x6e, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0,
-0x1edd, 0x69, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0, 0x1edd, 0x69, 0x20, 0x6d, 0x1ed9, 0x74, 0x3b, 0x74, 0x68,
-0xe1, 0x6e, 0x67, 0x20, 0x6d, 0x1b0, 0x1edd, 0x69, 0x20, 0x68, 0x61, 0x69, 0x3b, 0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77,
-0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72,
-0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b,
-0x52, 0x68, 0x61, 0x67, 0x3b, 0x49, 0x6f, 0x6e, 0x61, 0x77, 0x72, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x72, 0x6f, 0x72,
-0x3b, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d,
-0x65, 0x68, 0x65, 0x66, 0x69, 0x6e, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x65, 0x6e, 0x6e, 0x61, 0x66, 0x3b, 0x41, 0x77,
-0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x72, 0x65, 0x66, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x77,
-0x65, 0x64, 0x64, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x66, 0x79, 0x72, 0x3b, 0x49, 0x3b, 0x43, 0x68, 0x3b, 0x4d, 0x3b, 0x45,
-0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x52, 0x68, 0x3b, 0x49, 0x6f,
-0x6e, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x3b, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x69, 0x6c,
-0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72, 0x66, 0x66, 0x3b, 0x41, 0x77, 0x73, 0x74,
-0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x3b,
-0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b,
-0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x79, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65,
-0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x74, 0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c,
-0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41,
-0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f,
-0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1e62,
-0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc,
-0x67, 0x62, 0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9,
-0x6d, 0x1ecd, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0,
-0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72,
-0x1eb9, 0x301, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9,
-0x300, 0x6e, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62,
-0x69, 0x62, 0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67,
-0x1eb9, 0x6d, 0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65,
-0x77, 0x65, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9,
-0x6c, 0xfa, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
-0x3b, 0x4d, 0x61, 0x73, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
-0x3b, 0x41, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73,
-0x3b, 0x75, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72,
-0x69, 0x3b, 0x75, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x75, 0x2d, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x75, 0x4d,
-0x65, 0x79, 0x69, 0x3b, 0x75, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x75, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x75, 0x41,
-0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x75, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x2d, 0x4f,
-0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x75, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x44, 0x69, 0x73,
-0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77,
-0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79,
-0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69,
-0x3b, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e,
-0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61,
-0x72, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c,
-0x3b, 0x6d, 0x61, 0x6a, 0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73,
-0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b,
-0x6e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4a, 0x2d,
-0x67, 0x75, 0x65, 0x72, 0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b,
-0x41, 0x76, 0x72, 0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75,
-0x72, 0x65, 0x65, 0x3b, 0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74,
-0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72,
-0x3b, 0x4d, 0x2e, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2e, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b,
-0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61,
-0x67, 0x68, 0x74, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65,
-0x72, 0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75,
-0x72, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75,
-0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b,
-0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f,
-0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b,
-0x47, 0x65, 0x6e, 0x3b, 0x57, 0x68, 0x65, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x45,
-0x66, 0x6e, 0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44,
-0x75, 0x3b, 0x4b, 0x65, 0x76, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x4d, 0x79, 0x73,
-0x20, 0x57, 0x68, 0x65, 0x76, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b, 0x4d,
-0x79, 0x73, 0x20, 0x45, 0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x4d, 0x79, 0x73, 0x20,
-0x45, 0x66, 0x61, 0x6e, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x6e, 0x3b, 0x4d,
-0x79, 0x65, 0x20, 0x45, 0x73, 0x74, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x67, 0x61, 0x6c, 0x61, 0x3b,
-0x4d, 0x79, 0x73, 0x20, 0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x44, 0x75, 0x3b, 0x4d, 0x79, 0x73,
-0x20, 0x4b, 0x65, 0x76, 0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d, 0x186, 0x3b, 0x45, 0x2d,
-0x186, 0x3b, 0x45, 0x2d, 0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d, 0x4b, 0x3b, 0x44, 0x2d,
-0x186, 0x3b, 0x46, 0x2d, 0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d, 0x186, 0x3b, 0x53, 0x61,
-0x6e, 0x64, 0x61, 0x2d, 0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77, 0x61, 0x72, 0x2d, 0x186,
-0x67, 0x79, 0x65, 0x66, 0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e, 0x65, 0x6d, 0x3b, 0x45,
-0x62, 0x254, 0x62, 0x69, 0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b, 0x45, 0x73, 0x75, 0x73,
-0x6f, 0x77, 0x20, 0x41, 0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74, 0x254, 0x6e, 0x69, 0x6d,
-0x62, 0x61, 0x3b, 0x4f, 0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x6d, 0x75,
-0x6d, 0x75, 0x3b, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77, 0x6f, 0x6e, 0x73, 0x61,
-0x3b, 0x44, 0x69, 0x66, 0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46, 0x61, 0x6e, 0x6b, 0x77,
-0x61, 0x2d, 0x190, 0x62, 0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e, 0x69, 0x6d, 0x65, 0x3b,
-0x186, 0x62, 0x65, 0x72, 0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b, 0x4d, 0x75, 0x6d, 0x75,
-0x2d, 0x186, 0x70, 0x25b, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b,
-0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930,
-0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x913, 0x917, 0x938, 0x94d, 0x91f,
-0x3b, 0x938, 0x947, 0x92a, 0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x913, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928,
-0x94b, 0x935, 0x94d, 0x939, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x4a, 0x65, 0x6e,
-0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75,
-0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76,
-0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x1ee5, 0x77,
-0x61, 0x72, 0x1ecb, 0x3b, 0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x65, 0x65,
-0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x1ecd, 0x73, 0x74, 0x3b, 0x53,
-0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d,
-0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x65, 0x6c, 0x3b, 0x4b,
-0x74, 0x169, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x6f, 0x3b, 0x4e,
-0x79, 0x61, 0x3b, 0x4b, 0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128, 0x6b, 0x6d, 0x3b, 0x128, 0x6b, 0x6c, 0x3b, 0x4d,
-0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20,
-0x6b, 0x65, 0x6c, 0x129, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b,
-0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61,
-0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e,
-0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x75, 0x6f, 0x6e, 0x7a, 0x61,
-0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x77, 0x61,
-0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129,
-0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e,
-0x61, 0x20, 0x129, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69,
-0x20, 0x6e, 0x61, 0x20, 0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b,
-0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x120d, 0x12f0, 0x1275, 0x3b, 0x12ab, 0x1265, 0x12bd, 0x3b,
-0x12ad, 0x1265, 0x120b, 0x3b, 0x134b, 0x1305, 0x12ba, 0x3b, 0x12ad, 0x1262, 0x1245, 0x3b, 0x121d, 0x2f, 0x1275, 0x3b, 0x12b0, 0x122d, 0x3b, 0x121b,
-0x122d, 0x12eb, 0x3b, 0x12eb, 0x12b8, 0x1292, 0x3b, 0x1218, 0x1270, 0x1209, 0x3b, 0x121d, 0x2f, 0x121d, 0x3b, 0x1270, 0x1215, 0x1233, 0x3b, 0x120d,
-0x12f0, 0x1275, 0x122a, 0x3b, 0x12ab, 0x1265, 0x12bd, 0x1265, 0x1272, 0x3b, 0x12ad, 0x1265, 0x120b, 0x3b, 0x134b, 0x1305, 0x12ba, 0x122a, 0x3b, 0x12ad,
-0x1262, 0x1245, 0x122a, 0x3b, 0x121d, 0x12aa, 0x12a4, 0x120d, 0x20, 0x1275, 0x131f, 0x1292, 0x122a, 0x3b, 0x12b0, 0x122d, 0x12a9, 0x3b, 0x121b, 0x122d,
-0x12eb, 0x121d, 0x20, 0x1275, 0x122a, 0x3b, 0x12eb, 0x12b8, 0x1292, 0x20, 0x1218, 0x1233, 0x1245, 0x1208, 0x122a, 0x3b, 0x1218, 0x1270, 0x1209, 0x3b,
-0x121d, 0x12aa, 0x12a4, 0x120d, 0x20, 0x1218, 0x123d, 0x12c8, 0x122a, 0x3b, 0x1270, 0x1215, 0x1233, 0x1235, 0x122a, 0x3b, 0x120d, 0x3b, 0x12ab, 0x3b,
-0x12ad, 0x3b, 0x134b, 0x3b, 0x12ad, 0x3b, 0x121d, 0x3b, 0x12b0, 0x3b, 0x121b, 0x3b, 0x12eb, 0x3b, 0x1218, 0x3b, 0x121d, 0x3b, 0x1270, 0x3b,
-0x5a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b,
-0x4a, 0x75, 0x67, 0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b,
-0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72,
-0x3b, 0x4d, 0x61, 0x72, 0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e,
-0x3b, 0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b,
-0x4f, 0x74, 0x75, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65,
-0x6d, 0x62, 0x61, 0x72, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41,
-0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x75, 0x68, 0x3b, 0x1e70, 0x68, 0x66,
-0x3b, 0x4c, 0x61, 0x6d, 0x3b, 0x53, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x3b, 0x1e70, 0x68, 0x61,
-0x3b, 0x4b, 0x68, 0x75, 0x3b, 0x54, 0x73, 0x68, 0x3b, 0x1e3c, 0x61, 0x72, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x50, 0x68, 0x61,
-0x6e, 0x64, 0x6f, 0x3b, 0x4c, 0x75, 0x68, 0x75, 0x68, 0x69, 0x3b, 0x1e70, 0x68, 0x61, 0x66, 0x61, 0x6d, 0x75, 0x68, 0x77,
-0x65, 0x3b, 0x4c, 0x61, 0x6d, 0x62, 0x61, 0x6d, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x75, 0x6e, 0x64, 0x75, 0x6e, 0x74, 0x68,
-0x75, 0x6c, 0x65, 0x3b, 0x46, 0x75, 0x6c, 0x77, 0x69, 0x3b, 0x46, 0x75, 0x6c, 0x77, 0x61, 0x6e, 0x61, 0x3b, 0x1e70, 0x68,
-0x61, 0x6e, 0x67, 0x75, 0x6c, 0x65, 0x3b, 0x4b, 0x68, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x65, 0x64, 0x7a, 0x69, 0x3b, 0x54,
-0x73, 0x68, 0x69, 0x6d, 0x65, 0x64, 0x7a, 0x69, 0x3b, 0x1e3c, 0x61, 0x72, 0x61, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x64, 0x61,
-0x76, 0x68, 0x75, 0x73, 0x69, 0x6b, 0x75, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64, 0x3b,
-0x61, 0x66, 0x254, 0x3b, 0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61, 0x3b,
-0x61, 0x6e, 0x79, 0x3b, 0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f, 0x76,
-0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254, 0x66,
-0x129, 0x65, 0x3b, 0x64, 0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d,
-0x3b, 0x64, 0x65, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b,
-0x6b, 0x65, 0x6c, 0x65, 0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a, 0x6f,
-0x6d, 0x65, 0x3b, 0x64, 0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x61,
-0x3b, 0x6b, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c,
-0x2e, 0x3b, 0x2bb, 0x41, 0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e,
-0x3b, 0x2bb, 0x41, 0x75, 0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e,
-0x3b, 0x4b, 0x65, 0x6b, 0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75,
-0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b,
-0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61,
-0x6b, 0x65, 0x3b, 0x4b, 0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f,
-0x70, 0x61, 0x3b, 0x4e, 0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61,
-0x3b, 0x45, 0x6e, 0x65, 0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79,
-0x3b, 0x48, 0x75, 0x6e, 0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74,
-0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72, 0x65,
-0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b,
-0x48, 0x75, 0x6e, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53,
-0x65, 0x74, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x62,
-0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x50,
-0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
-0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a,
-0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69,
-0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x63, 0x68, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b,
-0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65,
-0x7a, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0xa2cd, 0xa1aa, 0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c,
-0xa1aa, 0x3b, 0xa0d8, 0xa1aa, 0x3b, 0xa3c3, 0xa1aa, 0x3b, 0xa246, 0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa,
-0x3b, 0xa2b0, 0xa44b, 0xa1aa, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x41, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x72, 0x68, 0x3b, 0x53, 0x65, 0x70,
-0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x55, 0x73, 0x69, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x62, 0x61, 0x72,
-0x69, 0x3b, 0x75, 0x46, 0x65, 0x62, 0x65, 0x72, 0x62, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x4d, 0x61, 0x74, 0x6a, 0x68, 0x69,
-0x3b, 0x75, 0x2d, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b,
-0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x72, 0x68, 0x6f, 0x73, 0x74, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70,
-0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x55, 0x73, 0x69, 0x6e, 0x79, 0x69, 0x6b,
-0x68, 0x61, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
-0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x41, 0x70, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
-0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x66, 0x3b, 0x44, 0x69, 0x73,
-0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x46, 0x65, 0x62, 0x65, 0x72, 0x77, 0x61, 0x72, 0x65, 0x3b,
-0x4d, 0x61, 0x74, 0x161, 0x68, 0x65, 0x3b, 0x41, 0x70, 0x6f, 0x72, 0x65, 0x6c, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a,
-0x75, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x65, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x73, 0x65, 0x3b, 0x53,
-0x65, 0x74, 0x65, 0x6d, 0x65, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x6f, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x66,
-0x65, 0x6d, 0x65, 0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x72, 0x65, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b,
-0x67, 0x75, 0x6f, 0x76, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67,
-0x65, 0x61, 0x73, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67,
-0x6f, 0x6c, 0x67, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61,
-0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b,
-0x6e, 0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x6f, 0x6d, 0xe1, 0x6e,
-0x6e, 0x75, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73,
-0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b,
-0x62, 0x6f, 0x72, 0x67, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e,
-0x75, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d,
-0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x4f,
-0x3b, 0x47, 0x3b, 0x4e, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x10c, 0x3b, 0x47, 0x3b, 0x53,
-0x3b, 0x4a, 0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, 0x61, 0x3b, 0x6e,
-0x6a, 0x75, 0x6b, 0x10d, 0x61, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x6f, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x3b, 0x67,
-0x65, 0x61, 0x73, 0x73, 0x65, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x3b,
-0x10d, 0x61, 0x6b, 0x10d, 0x61, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61,
-0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b,
-0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b,
-0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x43, 0x68, 0x61, 0x6e,
-0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b,
-0x41, 0x70, 0x69, 0x72, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x43, 0x68, 0x75,
-0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b,
-0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65,
-0x6d, 0x62, 0x61, 0x3b, 0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x43, 0x3b, 0x41, 0x3b,
-0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, 0x64, 0x3b,
-0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x57, 0x75, 0x6e, 0x3b,
-0x49, 0x6b, 0x65, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69,
-0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68,
-0x77, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61,
-0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b,
-0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x6f, 0x72,
-0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72,
-0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65, 0x3b, 0x4d, 0x6f, 0x72, 0x69,
-0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20,
-0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77,
-0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b,
-0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67,
-0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77, 0x69, 0x3b, 0x49, 0x3b, 0x4b,
-0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49,
-0x3b, 0x73, 0x69, 0x69, 0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x64, 0x75, 0x75,
-0x3b, 0x6b, 0x6f, 0x72, 0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c, 0x74, 0x3b, 0x79, 0x61, 0x72,
-0x3b, 0x6a, 0x6f, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, 0x74, 0x65,
-0x3b, 0x6d, 0x62, 0x6f, 0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64, 0x75, 0x75, 0x6a, 0x61, 0x6c,
-0x3b, 0x6b, 0x6f, 0x72, 0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75, 0x6b, 0x6f, 0x3b, 0x73, 0x69,
-0x69, 0x6c, 0x74, 0x6f, 0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a, 0x6f, 0x6c, 0x61, 0x6c, 0x3b,
-0x62, 0x6f, 0x77, 0x74, 0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b,
-0x6a, 0x3b, 0x73, 0x3b, 0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57, 0x4b, 0x52, 0x3b, 0x57, 0x47,
-0x54, 0x3b, 0x57, 0x4b, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57, 0x4d, 0x4a, 0x3b, 0x57, 0x4e,
-0x4e, 0x3b, 0x57, 0x4b, 0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44, 0x49, 0x54, 0x3b, 0x4e, 0x6a,
-0x65, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x72, 0x129,
-0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65,
-0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20,
-0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61,
-0x6e, 0x64, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, 0x77, 0x61,
-0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65,
-0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69,
-0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x74, 0x68, 0x65, 0x6d,
-0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b,
-0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b, 0x4f, 0x6b, 0x75, 0x3b, 0x4f,
-0x6e, 0x67, 0x3b, 0x49, 0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b, 0x49, 0x73, 0x69, 0x3b, 0x53,
-0x61, 0x61, 0x3b, 0x54, 0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20,
-0x6c, 0x65, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65,
-0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20,
-0x6c, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69,
-0x6d, 0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61,
-0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x69,
-0x65, 0x74, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x70, 0x61,
-0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f,
-0x6d, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f,
-0x6e, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, 0x49, 0x3b,
-0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b,
-0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b,
-0x41, 0x75, 0x67, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b,
-0x4a, 0x61, 0x6e, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72,
-0x63, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x6f, 0x3b,
-0x4a, 0x75, 0x6c, 0x68, 0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62,
-0x72, 0x6f, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44,
-0x65, 0x63, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x3b, 0x4d, 0x62, 0x69,
-0x3b, 0x4d, 0x61, 0x62, 0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x3b, 0x4e, 0x63,
-0x77, 0x3b, 0x4d, 0x70, 0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x3b,
-0x5a, 0x69, 0x62, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x6c, 0x61, 0x6e, 0x6a, 0x61,
-0x3b, 0x4d, 0x62, 0x69, 0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x6b,
-0x77, 0x65, 0x6e, 0x6b, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x4e,
-0x74, 0x75, 0x6c, 0x69, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b,
-0x4d, 0x70, 0x61, 0x6e, 0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x7a,
-0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b,
-0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x31, 0x3b, 0x4d,
-0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d, 0x37, 0x3b, 0x4d, 0x38, 0x3b,
-0x4d, 0x39, 0x3b, 0x4d, 0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
-0x20, 0x77, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
-0x6b, 0x61, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74,
-0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65,
-0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
-0x73, 0x69, 0x74, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d,
-0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d,
-0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
-0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20,
-0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x53,
-0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x3b, 0x2d31, 0x2d55, 0x2d30,
-0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x3b, 0x2d62, 0x2d53, 0x2d4d,
-0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x3b, 0x2d37, 0x2d53, 0x2d4a,
-0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x2d5a, 0x3b, 0x2d49,
-0x2d31, 0x2d54, 0x2d49, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4d,
-0x2d62, 0x2d53, 0x2d63, 0x3b, 0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d3d, 0x2d5c,
-0x2d53, 0x2d31, 0x2d54, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x2d30, 0x2d4f, 0x2d31, 0x2d49,
-0x2d54, 0x3b, 0x2d49, 0x3b, 0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62, 0x3b, 0x2d56, 0x3b, 0x2d5b, 0x3b,
-0x2d3d, 0x3b, 0x2d4f, 0x3b, 0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d, 0x61, 0x1e5b, 0x3b, 0x69, 0x62,
-0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263, 0x75, 0x63, 0x3b, 0x63, 0x75,
-0x74, 0x3b, 0x6b, 0x74, 0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69, 0x6e, 0x6e, 0x61, 0x79, 0x72,
-0x3b, 0x62, 0x1e5b, 0x61, 0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x6d, 0x61,
-0x79, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x263, 0x75, 0x63,
-0x74, 0x3b, 0x63, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x3b, 0x6e, 0x75, 0x77,
-0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x69, 0x3b, 0x62, 0x3b, 0x6d,
-0x3b, 0x69, 0x3b, 0x6d, 0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x59,
-0x65, 0x6e, 0x3b, 0x46, 0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59,
-0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x4e,
-0x75, 0x6e, 0x3b, 0x44, 0x75, 0x1e7, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61,
-0x72, 0x3b, 0x4d, 0x65, 0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79,
-0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43,
-0x74, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75, 0x6e, 0x65, 0x6d, 0x62, 0x65,
-0x1e5b, 0x3b, 0x44, 0x75, 0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x4d,
-0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4b, 0x42, 0x5a, 0x3b, 0x4b,
-0x42, 0x52, 0x3b, 0x4b, 0x53, 0x54, 0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b, 0x4b, 0x4d, 0x4b, 0x3b, 0x4b,
-0x4d, 0x53, 0x3b, 0x4b, 0x4d, 0x4e, 0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b, 0x4b, 0x4e, 0x4b, 0x3b, 0x4b,
-0x4e, 0x42, 0x3b, 0x4f, 0x6b, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b,
-0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6b,
-0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f,
-0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x73, 0x68, 0x61,
-0x6e, 0x6a, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61,
-0x6d, 0x77, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4f, 0x6b, 0x77,
-0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65, 0x3b, 0x4f, 0x6b, 0x77, 0x61,
-0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x75, 0x74, 0x3b, 0x56,
-0x69, 0x6c, 0x3b, 0x44, 0x61, 0x74, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53,
-0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4b, 0x6d, 0x6a, 0x3b, 0x4b,
-0x6d, 0x62, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x68, 0x75, 0x74,
-0x61, 0x6c, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75,
-0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77,
-0x75, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20,
-0x77, 0x75, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20,
-0x77, 0x75, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61,
-0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20,
-0x73, 0x61, 0x62, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6e,
-0x61, 0x6e, 0x65, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x74, 0x69,
-0x73, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d,
-0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69,
-0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67,
-0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x48, 0x3b, 0x56,
-0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b,
-0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61,
-0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x79,
-0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x79, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74,
-0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b,
-0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b,
-0x61, 0x77, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73,
-0x25b, 0x74, 0x3b, 0x254, 0x6b, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x77, 0x75,
-0x79, 0x65, 0x3b, 0x66, 0x65, 0x62, 0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x61,
-0x77, 0x69, 0x72, 0x69, 0x6c, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e, 0x3b, 0x7a, 0x75, 0x6c, 0x75,
-0x79, 0x65, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x254, 0x6b, 0x75,
-0x74, 0x254, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x73,
-0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x5a,
-0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x186, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x61, 0x69, 0x3b, 0x4b,
-0x61, 0x74, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x4b,
-0x6e, 0x6e, 0x3b, 0x4b, 0x65, 0x6e, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x67, 0x69, 0x3b, 0x4d,
-0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x6b, 0x61, 0x129, 0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
-0x74, 0x68, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72,
-0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
-0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65,
-0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d,
-0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77,
-0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
-0x4b, 0x61, 0x129, 0x72, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b,
-0x4b, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6, 0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7,
-0x13ec, 0x3b, 0x13a0, 0x13c2, 0x3b, 0x13d5, 0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da, 0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b,
-0x13c5, 0x13d3, 0x3b, 0x13a4, 0x13cd, 0x3b, 0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5, 0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b,
-0x13a7, 0x13ec, 0x13c2, 0x3b, 0x13a0, 0x13c2, 0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b, 0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b,
-0x13a6, 0x13b6, 0x13c2, 0x3b, 0x13da, 0x13b5, 0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5, 0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a4,
-0x13cd, 0x13a9, 0x13f1, 0x3b, 0x13a4, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5, 0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b,
-0x13da, 0x3b, 0x13da, 0x3b, 0x13c5, 0x3b, 0x13a4, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b,
-0x61, 0x76, 0x72, 0x3b, 0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73,
-0x65, 0x70, 0x3b, 0x6f, 0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x76, 0x69,
-0x65, 0x3b, 0x66, 0x65, 0x76, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c,
-0x3b, 0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65,
-0x70, 0x74, 0x61, 0x6d, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61, 0x6d, 0x3b, 0x64, 0x65, 0x73,
-0x61, 0x6d, 0x3b, 0x7a, 0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x7a, 0x3b, 0x6f, 0x3b, 0x73,
-0x3b, 0x6f, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b,
-0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20,
-0x77, 0x61, 0x20, 0x54, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x63, 0x68,
-0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f,
-0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20,
-0x55, 0x6d, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20,
-0x6e, 0x61, 0x20, 0x4d, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e,
-0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64,
-0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63,
-0x68, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e,
-0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e,
-0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x3b,
-0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e,
-0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4e,
-0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa, 0x6d, 0x69, 0x3b, 0x49, 0x6e,
-0x79, 0x61, 0x6d, 0x62, 0x61, 0x6c, 0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4d, 0x289, 0x289, 0x6e,
-0x63, 0x68, 0x268, 0x3b, 0x56, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x49, 0x6e, 0x79, 0x69,
-0x3b, 0x53, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x289, 0x66, 0xfa, 0x6e, 0x67,
-0x61, 0x74, 0x268, 0x3b, 0x4b, 0x289, 0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b, 0x65, 0x65, 0x6e, 0x64, 0x61,
-0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0xe1,
-0x6c, 0x61, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b, 0x289, 0x6d, 0x289, 0x289, 0x6e,
-0x63, 0x68, 0x268, 0x3b, 0x4b, 0x289, 0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x74, 0x289, 0x3b,
-0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4b, 0x289, 0x73, 0x61,
-0x73, 0x61, 0x74, 0x289, 0x3b, 0x46, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x56,
-0x3b, 0x53, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72,
-0x3b, 0x41, 0x70, 0x75, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75,
-0x3b, 0x53, 0x65, 0x62, 0x3b, 0x4f, 0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e,
-0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x72,
-0x69, 0x73, 0x69, 0x3b, 0x41, 0x70, 0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e,
-0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69, 0x74, 0x6f, 0x3b, 0x53, 0x65,
-0x62, 0x75, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x62, 0x61, 0x3b, 0x4e, 0x6f,
-0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65,
-0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75,
-0x6c, 0x3b, 0x4f, 0x67, 0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69,
-0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d,
-0x61, 0x63, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b,
-0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
-0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73,
-0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f,
-0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72,
-0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f,
-0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69, 0x7a, 0x3b, 0x4a, 0x61, 0x6e,
-0x65, 0x72, 0x75, 0x3b, 0x46, 0x65, 0x76, 0x65, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x75, 0x3b, 0x41,
-0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x68,
-0x75, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74,
-0x75, 0x62, 0x72, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x7a, 0x65, 0x6e, 0x62,
-0x72, 0x75, 0x3b, 0x4a, 0x41, 0x4e, 0x3b, 0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128, 0x50, 0x55, 0x3b, 0x4d,
-0x128, 0x128, 0x3b, 0x4e, 0x4a, 0x55, 0x3b, 0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53, 0x50, 0x54, 0x3b, 0x4f,
-0x4b, 0x54, 0x3b, 0x4e, 0x4f, 0x56, 0x3b, 0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x46,
-0x65, 0x62, 0x75, 0x72, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128, 0x70, 0x75, 0x72, 0x169,
-0x3b, 0x4d, 0x129, 0x129, 0x3b, 0x4e, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61, 0x129, 0x3b, 0x41, 0x67,
-0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x169, 0x62, 0x61,
-0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46,
-0x3b, 0x4d, 0x3b, 0x128, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44,
-0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x61, 0x3b, 0x4b, 0x69, 0x70, 0x3b, 0x49, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0x65,
-0x3b, 0x57, 0x61, 0x6b, 0x3b, 0x52, 0x6f, 0x70, 0x3b, 0x4b, 0x6f, 0x67, 0x3b, 0x42, 0x75, 0x72, 0x3b, 0x45, 0x70, 0x65,
-0x3b, 0x54, 0x61, 0x69, 0x3b, 0x41, 0x65, 0x6e, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x27, 0x61,
-0x74, 0x79, 0x61, 0x74, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x6d, 0x6f, 0x3b, 0x49, 0x77, 0x61, 0x74, 0x20, 0x6b,
-0x75, 0x74, 0x3b, 0x4e, 0x67, 0x27, 0x65, 0x69, 0x79, 0x65, 0x74, 0x3b, 0x57, 0x61, 0x6b, 0x69, 0x3b, 0x52, 0x6f, 0x70,
-0x74, 0x75, 0x69, 0x3b, 0x4b, 0x69, 0x70, 0x6b, 0x6f, 0x67, 0x61, 0x67, 0x61, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x74, 0x3b,
-0x45, 0x70, 0x65, 0x73, 0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x74, 0x61, 0x69,
-0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20, 0x61, 0x65, 0x6e, 0x67, 0x3b,
-0x4d, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x4e, 0x3b, 0x57, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x45, 0x3b,
-0x4b, 0x3b, 0x4b, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x1c0, 0x67, 0xf4,
-0x61, 0x62, 0x3b, 0x1c0, 0x4b, 0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c3, 0x48, 0xf4, 0x61, 0x1c2, 0x6b,
-0x68, 0x61, 0x69, 0x62, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62, 0x3b, 0x47, 0x61, 0x6d, 0x61, 0x1c0,
-0x61, 0x65, 0x62, 0x3b, 0x1c2, 0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b, 0x41, 0x6f, 0x1c1, 0x6b, 0x68, 0x75,
-0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb,
-0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73, 0x65, 0x62, 0x3b, 0x1c0, 0x48, 0x6f,
-0x6f, 0x1c2, 0x67, 0x61, 0x65, 0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b,
-0x4a, 0x61, 0x6e, 0x2e, 0x3b, 0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b,
-0x4d, 0xe4, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x4f, 0x75, 0x6a, 0x2e, 0x3b, 0x53,
-0xe4, 0x70, 0x2e, 0x3b, 0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a,
-0x61, 0x6e, 0x6e, 0x65, 0x77, 0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61, 0x3b, 0x4d, 0xe4, 0xe4, 0x7a, 0x3b,
-0x41, 0x70, 0x72, 0x65, 0x6c, 0x6c, 0x3b, 0x4d, 0xe4, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x75,
-0x6c, 0x69, 0x3b, 0x4f, 0x75, 0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f,
-0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a,
-0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b, 0x4d, 0xe4, 0x7a, 0x3b, 0x41, 0x70,
-0x72, 0x3b, 0x4d, 0xe4, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x75, 0x6a, 0x3b, 0x53, 0xe4,
-0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x44, 0x61, 0x6c, 0x3b, 0x41, 0x72,
-0xe1, 0x3b, 0x186, 0x25b, 0x6e, 0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b, 0x52, 0x6f, 0x6b, 0x3b, 0x53, 0xe1,
-0x73, 0x3b, 0x42, 0x254, 0x301, 0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73, 0x3b, 0x53, 0x68, 0x289, 0x301, 0x3b,
-0x4e, 0x74, 0x289, 0x301, 0x3b, 0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b, 0x41, 0x72, 0xe1, 0x74, 0x3b, 0x186,
-0x25b, 0x6e, 0x268, 0x301, 0x254, 0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64, 0x6f, 0x79, 0xed, 0xf3, 0x72, 0xed,
-0xea, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69, 0x6c, 0xe9, 0x70, 0x16b, 0x6e, 0x79,
-0x12b, 0x113, 0x20, 0x69, 0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a, 0xfa, 0x254, 0x72, 0x254, 0x6b, 0x3b,
-0x4d, 0xf3, 0x72, 0x75, 0x73, 0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301, 0x268, 0x301, 0x62, 0x254, 0x301, 0x72,
-0xe1, 0x72, 0x25b, 0x3b, 0x4b, 0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67, 0xed, 0x73, 0x61, 0x6e, 0x3b, 0x50,
-0x289, 0x73, 0x68, 0x289, 0x301, 0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289, 0x301, 0x73, 0x3b, 0x4a, 0x61, 0x6e,
-0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e,
-0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76,
-0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72,
-0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70,
-0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4d, 0x75, 0x6b,
-0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x6f, 0x64, 0x3b, 0x4a, 0x6f, 0x6c,
-0x3b, 0x50, 0x65, 0x64, 0x3b, 0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x50, 0x6f, 0x6f,
-0x3b, 0x4f, 0x72, 0x61, 0x72, 0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x67, 0x27, 0x3b,
-0x4f, 0x64, 0x75, 0x6e, 0x67, 0x27, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75, 0x6b, 0x3b, 0x4f, 0x6d, 0x6f, 0x64,
-0x6f, 0x6b, 0x27, 0x6b, 0x69, 0x6e, 0x67, 0x27, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f, 0x6c, 0x61, 0x3b, 0x4f, 0x70, 0x65,
-0x64, 0x65, 0x6c, 0x3b, 0x4f, 0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d, 0x61, 0x3b, 0x4f, 0x74, 0x69, 0x62,
-0x61, 0x72, 0x3b, 0x4f, 0x6c, 0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f, 0x3b, 0x52, 0x3b, 0x4d, 0x3b, 0x4b,
-0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x50, 0x3b, 0x17d,
-0x61, 0x6e, 0x3b, 0x46, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75,
-0x77, 0x3b, 0x17d, 0x75, 0x79, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x6f,
-0x3b, 0x44, 0x65, 0x65, 0x3b, 0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46, 0x65, 0x65, 0x77, 0x69, 0x72, 0x69,
-0x79, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x3b, 0x17d,
-0x75, 0x77, 0x65, 0x14b, 0x3b, 0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x74, 0x61, 0x6e,
-0x62, 0x75, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e, 0x6f, 0x6f, 0x77, 0x61, 0x6e, 0x62,
-0x75, 0x72, 0x3b, 0x44, 0x65, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41,
-0x3b, 0x4d, 0x3b, 0x17d, 0x3b, 0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44, 0x41, 0x43,
-0x3b, 0x44, 0x41, 0x52, 0x3b, 0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44, 0x41, 0x48, 0x3b, 0x44, 0x41, 0x55,
-0x3b, 0x44, 0x41, 0x4f, 0x3b, 0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44, 0x41, 0x50, 0x3b, 0x44, 0x47, 0x49,
-0x3b, 0x44, 0x41, 0x47, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b,
-0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61,
-0x72, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x6e, 0x67, 0x27, 0x77,
-0x65, 0x6e, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x44, 0x77, 0x65,
-0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72,
-0x20, 0x41, 0x62, 0x69, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x6f,
-0x72, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68, 0x69, 0x6b, 0x6f, 0x3b, 0x44, 0x77,
-0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x67,
-0x69, 0x20, 0x61, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61,
-0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x4e, 0x3b, 0x42,
-0x3b, 0x55, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x59,
-0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59,
-0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75, 0x3b, 0x4e, 0x77, 0x61, 0x3b, 0x44,
-0x75, 0x6a, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x61, 0x79, 0x65, 0x72,
-0x3b, 0x4d, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75,
-0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x75, 0x74, 0x61,
-0x6e, 0x62, 0x69, 0x72, 0x3b, 0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b,
-0x44, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x59,
-0x3b, 0x59, 0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69,
-0x3b, 0x46, 0x65, 0x62, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x6c, 0x69,
-0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67,
-0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61,
-0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928,
-0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930,
-0x94d, 0x938, 0x3b, 0x90f, 0x92b, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932,
-0x93e, 0x907, 0x3b, 0x906, 0x917, 0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b,
-0x905, 0x916, 0x925, 0x92c, 0x930, 0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x947, 0x91c,
-0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941,
-0x3b, 0x91c, 0x941, 0x3b, 0x906, 0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x43, 0x69, 0x6f, 0x3b,
-0x4c, 0x75, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x66, 0x3b,
-0x4b, 0x61, 0x62, 0x3b, 0x4c, 0x75, 0x73, 0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4b, 0x61, 0x73,
-0x3b, 0x43, 0x69, 0x73, 0x3b, 0x43, 0x69, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73, 0x68, 0x69, 0x3b, 0x4c,
-0x75, 0x73, 0xf2, 0x6c, 0x6f, 0x3b, 0x4d, 0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9, 0x6e, 0x67, 0xf9, 0x6c,
-0xf9, 0x3b, 0x4c, 0x75, 0x66, 0x75, 0x69, 0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0, 0x73, 0x68, 0xec, 0x70,
-0xf9, 0x3b, 0x4c, 0xf9, 0x73, 0x68, 0xec, 0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b,
-0x4c, 0x75, 0x6e, 0x67, 0xf9, 0x64, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73, 0xe8, 0x3b, 0x43, 0x69,
-0x73, 0x77, 0xe0, 0x3b, 0x43, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b,
-0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x43, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b, 0x268, 0x7a, 0x3b, 0x74, 0x268, 0x64, 0x3b,
-0x74, 0x61, 0x61, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x66, 0x254, 0x65, 0x3b,
-0x64, 0x7a, 0x75, 0x3b, 0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254,
-0x300, 0x14b, 0x254, 0x300, 0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x197, 0x300, 0x7a,
-0xf9, 0x294, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x64, 0x289, 0x300, 0x67, 0x68, 0xe0,
-0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66, 0x289, 0x304, 0x67, 0x68, 0x101, 0x3b, 0x6e,
-0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0x7a,
-0xf9, 0x67, 0x68, 0xf2, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x64, 0xf9, 0x6d, 0x6c, 0x6f, 0x3b, 0x6e,
-0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
-0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64, 0x7a, 0x75, 0x67, 0x68, 0xf9, 0x3b, 0x6e,
-0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65, 0x6c, 0x254, 0x300, 0x6d, 0x3b, 0x6e, 0x64,
-0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b, 0x61, 0x61, 0x20, 0x77, 0x6f, 0x3b, 0x6e,
-0x64, 0x7a, 0x254, 0x300, 0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x74, 0x3b, 0x74, 0x3b, 0x73,
-0x3b, 0x7a, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b, 0x66, 0x3b, 0x6b, 0x254, 0x6e, 0x3b, 0x6d,
-0x61, 0x63, 0x3b, 0x6d, 0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70, 0x75, 0x3b, 0x68, 0x69, 0x6c, 0x3b, 0x6e,
-0x6a, 0x65, 0x3b, 0x68, 0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6c,
-0x69, 0x253, 0x3b, 0x4b, 0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63, 0x25b, 0x302, 0x6c, 0x3b, 0x4d, 0xe0, 0x74,
-0xf9, 0x6d, 0x62, 0x3b, 0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70, 0x75, 0x79, 0x25b, 0x3b, 0x48, 0xec, 0x6c,
-0xf2, 0x6e, 0x64, 0x25b, 0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48, 0xec, 0x6b, 0x61, 0x14b, 0x3b, 0x44, 0xec,
-0x70, 0x254, 0x300, 0x73, 0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0, 0x79, 0x25b, 0x73, 0xe8, 0x70, 0x3b, 0x4c,
-0xec, 0x62, 0x75, 0x79, 0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d,
-0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, 0x6c, 0x3b, 0x64, 0x69, 0x3b,
-0x14b, 0x67, 0x254, 0x6e, 0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b, 0x65, 0x6d, 0x69, 0x3b, 0x65, 0x73, 0x254,
-0x3b, 0x6d, 0x61, 0x64, 0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x74, 0x69,
-0x6e, 0x3b, 0x65, 0x6c, 0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x64, 0x25b,
-0x3b, 0x73, 0x254, 0x14b, 0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b, 0x65, 0x6d, 0x69, 0x61, 0x73, 0x65, 0x6c,
-0x65, 0x3b, 0x65, 0x73, 0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d, 0x61, 0x64, 0x69, 0x253, 0x25b, 0x301, 0x64,
-0xed, 0x253, 0x25b, 0x301, 0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x25b, 0x6b,
-0x69, 0x3b, 0x6d, 0x61, 0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e, 0xed, 0x6e, 0xed, 0x3b, 0x65, 0x6c, 0xe1,
-0x14b, 0x67, 0x25b, 0x301, 0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x65, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x64,
-0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46, 0x65, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x62,
-0x3b, 0x4d, 0x65, 0x3b, 0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x3b, 0x4f, 0x6b, 0x3b, 0x4e,
-0x6f, 0x3b, 0x44, 0x65, 0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46, 0xe9, 0x62, 0x69, 0x72, 0x69, 0x65, 0x3b,
-0x4d, 0x61, 0x72, 0x73, 0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x65, 0x14b,
-0x3b, 0x53, 0xfa, 0x75, 0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72,
-0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69,
-0x73, 0x61, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53,
-0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67, 0x6f, 0x3b, 0x6e, 0x67, 0x62, 0x3b, 0x6e,
-0x67, 0x6c, 0x3b, 0x6e, 0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67, 0x73, 0x3b, 0x6e, 0x67, 0x7a, 0x3b, 0x6e,
-0x67, 0x6d, 0x3b, 0x6e, 0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67, 0x61, 0x64, 0x3b, 0x6e, 0x67, 0x61, 0x62,
-0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6e,
-0x67, 0x254, 0x6e, 0x20, 0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6e, 0x79, 0x69, 0x6e, 0x61, 0x3b,
-0x6e, 0x67, 0x254, 0x6e, 0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x73, 0x61, 0x6d, 0x259, 0x6e,
-0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e,
-0x20, 0x6d, 0x77, 0x6f, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62, 0x75, 0x6c, 0xfa, 0x3b, 0x6e, 0x67, 0x254,
-0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20,
-0x64, 0x7a, 0x69, 0xe1, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x62, 0x25b,
-0x30c, 0x3b, 0x6f, 0x3b, 0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6d, 0x3b, 0x65, 0x3b,
-0x61, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b, 0x33, 0x3b, 0x14b, 0x34, 0x3b, 0x14b, 0x35,
-0x3b, 0x14b, 0x36, 0x3b, 0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b, 0x14b, 0x31, 0x30, 0x3b, 0x14b, 0x31, 0x31,
-0x3b, 0x14b, 0x31, 0x32, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x74, 0x254, 0x3b,
-0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
-0x6b, 0x1dd, 0x20, 0x72, 0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x69, 0x6e, 0x3b,
-0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
-0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74,
-0xe1, 0x61, 0x62, 0x25b, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x72, 0x61,
-0x61, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77,
-0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd,
-0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
-0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x4b, 0x77, 0x61, 0x3b,
-0x55, 0x6e, 0x61, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x63, 0x3b,
-0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4d, 0x6f, 0x6a, 0x3b,
-0x59, 0x65, 0x6c, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b,
-0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65,
-0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20,
-0x77, 0x6f, 0x20, 0x75, 0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x6f, 0x20, 0x75, 0x6e, 0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20,
-0x74, 0x68, 0x61, 0x6e, 0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
-0x20, 0x77, 0x6f, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6e, 0x61,
-0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65,
-0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20,
-0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
-0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c, 0x27, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x55,
-0x3b, 0x52, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x59,
-0x3b, 0x46, 0x4c, 0x4f, 0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b, 0x46, 0x4d, 0x46, 0x3b, 0x4d, 0x41, 0x44,
-0x3b, 0x4d, 0x42, 0x49, 0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b, 0x46, 0x44, 0x45, 0x3b, 0x46, 0x4d, 0x55,
-0x3b, 0x46, 0x47, 0x57, 0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4c, 0x6f, 0x6f, 0x3b, 0x43, 0x6f, 0x6b,
-0x63, 0x77, 0x61, 0x6b, 0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x69, 0x69,
-0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x1dd, 0x75, 0x75, 0x74,
-0x1dd, 0x62, 0x69, 0x6a, 0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x66, 0x61, 0x68, 0x62,
-0x69, 0x69, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x64, 0x1dd,
-0x6d, 0x62, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20,
-0x4d, 0x75, 0x6e, 0x64, 0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77, 0x61, 0x68, 0x6c, 0x6c, 0x65, 0x3b, 0x46,
-0x129, 0x69, 0x20, 0x59, 0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x44, 0x3b, 0x42, 0x3b,
-0x4c, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e, 0x67, 0x31, 0x3b, 0x6e, 0x67, 0x32, 0x3b,
-0x6e, 0x67, 0x33, 0x3b, 0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e, 0x67, 0x36, 0x3b, 0x6e, 0x67, 0x37, 0x3b,
-0x6e, 0x67, 0x38, 0x3b, 0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b, 0x6e, 0x67, 0x31, 0x31, 0x3b, 0x6b, 0x72,
-0x69, 0x73, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1, 0x68, 0x72, 0x61, 0x3b, 0x6e, 0x67, 0x77,
-0x25b, 0x6e, 0x20, 0x144, 0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6c, 0x61, 0x6c, 0x3b, 0x6e,
-0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x61, 0x6e, 0x3b,
-0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x68, 0x25b, 0x6d,
-0x62, 0x75, 0x25b, 0x72, 0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c, 0x254, 0x6d, 0x62, 0x69, 0x3b, 0x6e, 0x67,
-0x77, 0x25b, 0x6e, 0x20, 0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d,
-0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61, 0x76, 0x16d, 0x72, 0x3b, 0x6b, 0x72, 0xed,
-0x73, 0x69, 0x6d, 0x69, 0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254,
-0x331, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x54,
-0x68, 0x6f, 0x6f, 0x3b, 0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x64, 0x3b,
-0x54, 0x69, 0x6f, 0x70, 0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75,
-0x254, 0x331, 0x254, 0x331, 0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x74, 0x3b, 0x4b, 0x6f, 0x72, 0x6e,
-0x79, 0x6f, 0x6f, 0x74, 0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331, 0x74, 0x6e, 0x69, 0x3b, 0x54, 0x68, 0x6f,
-0x331, 0x6f, 0x331, 0x72, 0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61, 0x74, 0x68, 0x3b, 0x4b, 0x75, 0x72, 0x3b,
-0x54, 0x69, 0x6f, 0x331, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69, 0x331, 0x74, 0x3b, 0x54, 0x3b, 0x50, 0x3b,
-0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x54, 0x3b,
-0x422, 0x43e, 0x445, 0x441, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d, 0x5f, 0x442, 0x442, 0x440, 0x3b, 0x41c, 0x443,
-0x441, 0x5f, 0x443, 0x441, 0x442, 0x3b, 0x42b, 0x430, 0x43c, 0x5f, 0x439, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x5f, 0x439, 0x43d, 0x3b,
-0x41e, 0x442, 0x5f, 0x439, 0x43d, 0x3b, 0x410, 0x442, 0x440, 0x434, 0x44c, 0x5f, 0x439, 0x43d, 0x3b, 0x411, 0x43b, 0x495, 0x43d, 0x5f,
-0x439, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x3b, 0x421, 0x44d, 0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x443,
-0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442,
-0x443, 0x442, 0x430, 0x440, 0x3b, 0x41c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430, 0x43c, 0x20,
-0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b, 0x439, 0x44b,
-0x43d, 0x3b, 0x410, 0x442, 0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430, 0x43b, 0x430,
-0x495, 0x430, 0x43d, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x421, 0x44d,
-0x442, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x3b, 0x410, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b,
-0x41a, 0x3b, 0x41c, 0x3b, 0x42b, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b,
-0x4d, 0x75, 0x70, 0x3b, 0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b,
-0x4d, 0x75, 0x6a, 0x3b, 0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b,
-0x4d, 0x75, 0x73, 0x3b, 0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61,
-0x3b, 0x4d, 0x77, 0x69, 0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75,
-0x6e, 0x79, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b,
-0x4d, 0x75, 0x6a, 0x69, 0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69, 0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75,
-0x70, 0x75, 0x67, 0x75, 0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68,
-0x75, 0x3b, 0x4d, 0x75, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d, 0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68,
-0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x6d, 0x6b, 0x77, 0x3b, 0x6d, 0x70, 0x69, 0x3b, 0x6d, 0x74, 0x75, 0x3b, 0x6d, 0x69, 0x6e,
-0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x73, 0x74, 0x3b, 0x6d, 0x73, 0x62, 0x3b, 0x6d, 0x75, 0x6e, 0x3b, 0x6d, 0x74, 0x73,
-0x3b, 0x6d, 0x6b, 0x75, 0x3b, 0x6d, 0x6b, 0x6d, 0x3b, 0x6d, 0x6b, 0x62, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79,
-0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x70, 0x69,
-0x6c, 0x69, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x6d, 0x77, 0x65,
-0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x69, 0x6e, 0x65, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74,
-0x61, 0x6e, 0x75, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x6d, 0x77,
-0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61,
-0x20, 0x6d, 0x75, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74, 0x69, 0x73,
-0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x6d, 0x77, 0x65, 0x7a,
-0x69, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x79, 0x61, 0x3b, 0x6d, 0x77,
-0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69,
-0x3b, 0x6b, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x69, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x6b,
-0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0xa5a8, 0xa56a, 0xa583, 0x20, 0xa51e, 0xa56e, 0x3b, 0xa552, 0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b,
-0xa5a2, 0xa595, 0x3b, 0xa591, 0xa571, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e,
-0xa60b, 0xa554, 0xa57f, 0x20, 0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa56a, 0xa571, 0x20, 0xa5cf, 0xa56e, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61,
-0x6f, 0x20, 0x6b, 0x65, 0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253, 0x75, 0x3b, 0x76, 0x254, 0x254, 0x3b, 0x66,
-0x75, 0x6c, 0x75, 0x3b, 0x67, 0x6f, 0x6f, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x6b, 0x254, 0x6e, 0x64, 0x65, 0x3b, 0x73, 0x61,
-0x61, 0x68, 0x3b, 0x67, 0x61, 0x6c, 0x6f, 0x3b, 0x6b, 0x65, 0x6e, 0x70, 0x6b, 0x61, 0x74, 0x6f, 0x20, 0x253, 0x6f, 0x6c,
-0x6f, 0x6c, 0x254, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6c, 0x254, 0x6d, 0x61, 0x3b, 0x4a, 0x65, 0x6e, 0x3b,
-0x48, 0x6f, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x42, 0x72, 0xe1, 0x3b,
-0x48, 0x65, 0x69, 0x3b, 0xd6, 0x69, 0x67, 0x3b, 0x48, 0x65, 0x72, 0x3b, 0x57, 0xed, 0x6d, 0x3b, 0x57, 0x69, 0x6e, 0x3b,
-0x43, 0x68, 0x72, 0x3b, 0x4a, 0x65, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x48, 0x6f, 0x72, 0x6e, 0x69, 0x67, 0x3b, 0x4d, 0xe4,
-0x72, 0x7a, 0x65, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x6a, 0x65, 0x3b, 0x42, 0x72,
-0xe1, 0x10d, 0x65, 0x74, 0x3b, 0x48, 0x65, 0x69, 0x77, 0x65, 0x74, 0x3b, 0xd6, 0x69, 0x67, 0x161, 0x74, 0x65, 0x3b, 0x48,
-0x65, 0x72, 0x62, 0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0xed, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57,
-0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x43, 0x68, 0x72, 0x69, 0x161, 0x74, 0x6d, 0xe1, 0x6e,
-0x65, 0x74, 0x3b, 0x4a, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x48, 0x3b, 0xd6, 0x3b, 0x48,
-0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x43, 0x3b, 0x6f, 0x2e, 0x31, 0x3b, 0x6f, 0x2e, 0x32, 0x3b, 0x6f, 0x2e, 0x33, 0x3b, 0x6f,
-0x2e, 0x34, 0x3b, 0x6f, 0x2e, 0x35, 0x3b, 0x6f, 0x2e, 0x36, 0x3b, 0x6f, 0x2e, 0x37, 0x3b, 0x6f, 0x2e, 0x38, 0x3b, 0x6f,
-0x2e, 0x39, 0x3b, 0x6f, 0x2e, 0x31, 0x30, 0x3b, 0x6f, 0x2e, 0x31, 0x31, 0x3b, 0x6f, 0x2e, 0x31, 0x32, 0x3b, 0x70, 0x69,
-0x6b, 0xed, 0x74, 0xed, 0x6b, 0xed, 0x74, 0x69, 0x65, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0xed, 0x20, 0xfa, 0x20, 0x6b, 0x75,
-0x74, 0xfa, 0x61, 0x6e, 0x3b, 0x73, 0x69, 0x25b, 0x79, 0x25b, 0x301, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20,
-0x6b, 0xe1, 0x6e, 0x64, 0xed, 0x25b, 0x3b, 0x254, 0x6e, 0x73, 0xfa, 0x6d, 0x62, 0x254, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c,
-0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x74, 0xfa, 0x25b, 0x3b, 0x6d, 0x65, 0x73, 0x69, 0x14b, 0x2c, 0x20, 0x6f,
-0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe9, 0x6e, 0x69, 0x65, 0x3b, 0x65, 0x6e, 0x73, 0x69, 0x6c, 0x2c, 0x20, 0x6f,
-0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x6e, 0x75, 0x25b, 0x3b, 0x254, 0x73, 0x254, 0x6e, 0x3b, 0x65,
-0x66, 0x75, 0x74, 0x65, 0x3b, 0x70, 0x69, 0x73, 0x75, 0x79, 0xfa, 0x3b, 0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70,
-0x75, 0x254, 0x73, 0x3b, 0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x74, 0xfa, 0x6b, 0x2c, 0x6f, 0xf3, 0x6c,
-0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xed, 0x25b, 0x3b, 0x6d, 0x61, 0x6b, 0x61, 0x6e, 0x64, 0x69, 0x6b, 0x25b, 0x3b,
-0x70, 0x69, 0x6c, 0x254, 0x6e, 0x64, 0x254, 0x301, 0x3b, 0x58, 0x69, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72,
-0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x58, 0x75, 0x6e, 0x3b, 0x58, 0x6e, 0x74, 0x3b, 0x41, 0x67, 0x6f,
-0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x63, 0x68, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x41, 0x76, 0x69, 0x3b, 0x78, 0x69, 0x6e,
-0x65, 0x72, 0x75, 0x3b, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x61, 0x62,
-0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x79, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x65, 0x74, 0x75,
-0x3b, 0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63,
-0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74,
-0x75, 0x3b, 0x58, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b,
-0x4f, 0x3b, 0x50, 0x3b, 0x41, 0x3b, 0x78, 0x69, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62,
-0x72, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x78, 0x75, 0x6e, 0x3b, 0x78, 0x6e, 0x74, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65,
-0x74, 0x3b, 0x6f, 0x63, 0x68, 0x3b, 0x70, 0x61, 0x79, 0x3b, 0x61, 0x76, 0x69, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x69, 0x6e,
-0x65, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61,
-0x72, 0x7a, 0x75, 0x3b, 0x64, 0x27, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x79, 0x75, 0x3b,
-0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x65, 0x74, 0x75, 0x3b, 0x64, 0x27,
-0x61, 0x67, 0x6f, 0x73, 0x74, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b,
-0x64, 0x27, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73,
-0x3b, 0x64, 0x27, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x4e, 0x64, 0x75, 0x14b, 0x6d, 0x62, 0x69, 0x20, 0x53,
-0x61, 0x14b, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x70, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b,
-0x20, 0x50, 0x25b, 0x301, 0x74, 0xe1, 0x74, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301,
-0x6b, 0x77, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x61, 0x74, 0x61, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61,
-0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6e, 0x74, 0xfa, 0x6b, 0xfa, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20,
-0x53, 0x61, 0x61, 0x6d, 0x62, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x66,
-0x254, 0x6d, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x70, 0x66, 0xfa, 0xa78b, 0xfa,
-0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x25b, 0x67, 0x25b, 0x301, 0x6d, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20,
-0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x6d, 0x254, 0x301, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254,
-0x30c, 0x70, 0x70, 0xe1, 0x3b, 0x70, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6d, 0x62, 0x69,
-0x79, 0x254, 0x20, 0x6d, 0x25b, 0x6e, 0x64, 0x6f, 0x14b, 0x67, 0x254, 0x3b, 0x4e, 0x79, 0x254, 0x6c, 0x254, 0x6d, 0x62, 0x254,
-0x14b, 0x67, 0x254, 0x3b, 0x4d, 0x254, 0x6e, 0x254, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4e, 0x79, 0x61,
-0x14b, 0x67, 0x77, 0x25b, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x75, 0x14b, 0x67, 0x77, 0x25b, 0x3b,
-0x66, 0x25b, 0x3b, 0x6e, 0x6a, 0x61, 0x70, 0x69, 0x3b, 0x6e, 0x79, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x31, 0x31, 0x3b, 0x253,
-0x75, 0x6c, 0x253, 0x75, 0x73, 0x25b, 0x3b, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20,
-0xe0, 0x62, 0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75, 0x62, 0x69,
-0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x66, 0x6f,
-0x67, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67,
-0x20, 0xe0, 0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x6b,
-0x61, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8, 0x73, 0x69,
-0x2bc, 0x65, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a,
-0x6d, 0x65, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65,
-0x67, 0x20, 0xe0, 0x62, 0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75,
-0x62, 0x69, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20,
-0x66, 0x6f, 0x67, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d,
-0x259, 0x67, 0x20, 0xe0, 0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68,
-0x69, 0x6b, 0x61, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8,
-0x73, 0x69, 0x2bc, 0x65, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x72,
-0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b, 0x4d, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4e, 0x34, 0x3b, 0x46, 0x35,
-0x3b, 0x49, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x49, 0x38, 0x3b, 0x4b, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31,
-0x32, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b, 0x73,
-0x61, 0x14b, 0x20, 0x6b, 0xe0, 0x67, 0x20, 0x6e, 0x67, 0x77, 0xf3, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6c, 0x65, 0x70,
-0x79, 0xe8, 0x20, 0x73, 0x68, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20,
-0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, 0x6a, 0xff, 0x6f, 0x6c, 0xe1,
-0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x6d, 0x62,
-0x289, 0x300, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, 0x67, 0x77,
-0x254, 0x300, 0x2bc, 0x20, 0x6d, 0x62, 0xff, 0x25b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0xe0, 0x14b, 0x61, 0x20, 0x74, 0x73,
-0x65, 0x74, 0x73, 0xe1, 0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x65, 0x6a, 0x77, 0x6f, 0x14b, 0xf3, 0x3b, 0x73, 0x61,
-0x14b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b
+0x31, 0x32, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x32, 0x3b, 0x74,
+0x68, 0xe1, 0x6e, 0x67, 0x20, 0x33, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x34, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67,
+0x20, 0x35, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x36, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x37, 0x3b, 0x74,
+0x68, 0xe1, 0x6e, 0x67, 0x20, 0x38, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x39, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67,
+0x20, 0x31, 0x30, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31, 0x31, 0x3b, 0x74, 0x68, 0xe1, 0x6e, 0x67, 0x20, 0x31,
+0x32, 0x3b, 0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x61,
+0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47, 0x6f, 0x72, 0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b,
+0x48, 0x79, 0x64, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x3b, 0x49, 0x6f, 0x6e, 0x61, 0x77, 0x72,
+0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x72, 0x6f, 0x72, 0x3b, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72,
+0x69, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x65, 0x66, 0x69, 0x6e, 0x3b, 0x47, 0x6f, 0x72, 0x66,
+0x66, 0x65, 0x6e, 0x6e, 0x61, 0x66, 0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64,
+0x72, 0x65, 0x66, 0x3b, 0x54, 0x61, 0x63, 0x68, 0x77, 0x65, 0x64, 0x64, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x66, 0x79, 0x72,
+0x3b, 0x49, 0x3b, 0x43, 0x68, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x41, 0x3b, 0x4d, 0x3b,
+0x48, 0x3b, 0x54, 0x3b, 0x52, 0x68, 0x3b, 0x49, 0x6f, 0x6e, 0x3b, 0x43, 0x68, 0x77, 0x65, 0x66, 0x3b, 0x4d, 0x61, 0x77,
+0x72, 0x74, 0x68, 0x3b, 0x45, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4d, 0x65, 0x68, 0x3b, 0x47,
+0x6f, 0x72, 0x66, 0x66, 0x3b, 0x41, 0x77, 0x73, 0x74, 0x3b, 0x4d, 0x65, 0x64, 0x69, 0x3b, 0x48, 0x79, 0x64, 0x3b, 0x54,
+0x61, 0x63, 0x68, 0x3b, 0x52, 0x68, 0x61, 0x67, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74,
+0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x61,
+0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e,
+0x79, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x74,
+0x73, 0x68, 0x69, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69,
+0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b,
+0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8,
+0x3b, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b,
+0xd2, 0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65,
+0x77, 0x65, 0x3b, 0x1ecc, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x1ecc, 0x300, 0x70, 0x1eb9, 0x300,
+0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1e62, 0x1eb9, 0x301, 0x72, 0x1eb9, 0x301, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c,
+0xe8, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x72, 0x1eb9, 0x300, 0x6e, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xcc, 0x67, 0x62,
+0xe9, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1eb8, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x6b, 0xfa,
+0x64, 0x75, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x41, 0x67, 0x1eb9, 0x6d, 0x1ecd, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0xd2, 0x67, 0xfa,
+0x6e, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x77, 0xe0,
+0x72, 0xe0, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f, 0x1e63, 0xf9, 0x20, 0x1ecc, 0x300, 0x70, 0x1eb9,
+0x300, 0x3b, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b, 0x190, 0x72, 0x25b, 0x300,
+0x6e, 0xe0, 0x3b, 0xcc, 0x67, 0x62, 0xe9, 0x3b, 0x190, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0xd2, 0x6b, 0xfa, 0x64, 0x75,
+0x3b, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x186, 0x300,
+0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4f, 0x73, 0x68, 0xf9,
+0x20, 0x53, 0x68, 0x25b, 0x301, 0x72, 0x25b, 0x301, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xc8, 0x72, 0xe8, 0x6c, 0xe8, 0x3b,
+0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x72, 0x25b, 0x300, 0x6e, 0xe0, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xcc, 0x67, 0x62,
+0xe9, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x190, 0x300, 0x62, 0x69, 0x62, 0x69, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0xd2,
+0x6b, 0xfa, 0x64, 0x75, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x41, 0x67, 0x25b, 0x6d, 0x254, 0x3b, 0x4f, 0x73, 0x68, 0xf9,
+0x20, 0xd2, 0x67, 0xfa, 0x6e, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x4f, 0x77, 0x65, 0x77, 0x65, 0x3b, 0x4f, 0x73, 0x68,
+0xf9, 0x20, 0x186, 0x300, 0x77, 0xe0, 0x72, 0xe0, 0x3b, 0x4f, 0x73, 0x68, 0xf9, 0x20, 0x42, 0xe9, 0x6c, 0xfa, 0x3b, 0x4f,
+0x73, 0x68, 0xf9, 0x20, 0x186, 0x300, 0x70, 0x25b, 0x300, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61,
+0x73, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67,
+0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x75, 0x4a,
+0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x75,
+0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x75, 0x2d, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x75, 0x4d, 0x65, 0x79, 0x69,
+0x3b, 0x75, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x75, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x75, 0x41, 0x67, 0x61, 0x73,
+0x74, 0x69, 0x3b, 0x75, 0x53, 0x65, 0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x2d, 0x4f, 0x6b, 0x74, 0x68,
+0x6f, 0x62, 0x61, 0x3b, 0x75, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x75, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62,
+0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x77, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x77, 0x61, 0x72, 0x69,
+0x3b, 0x4d, 0x61, 0x73, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a,
+0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65,
+0x70, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x68, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x6a, 0x61, 0x6e, 0x2e, 0x3b, 0x66, 0x65, 0x62,
+0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x70, 0x72, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x3b, 0x6a, 0x75, 0x6e, 0x69,
+0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x75, 0x67, 0x2e, 0x3b, 0x73, 0x65, 0x70, 0x2e, 0x3b, 0x6f, 0x6b, 0x74, 0x2e,
+0x3b, 0x6e, 0x6f, 0x76, 0x2e, 0x3b, 0x64, 0x65, 0x73, 0x2e, 0x3b, 0x6a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x3b, 0x66, 0x65,
+0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x3b, 0x61, 0x70, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x61, 0x6a,
+0x3b, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x6a, 0x75, 0x6c, 0x69, 0x3b, 0x61, 0x76, 0x67, 0x75, 0x73, 0x74, 0x3b, 0x73, 0x65,
+0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x72, 0x3b, 0x6e, 0x6f, 0x76, 0x65,
+0x6d, 0x62, 0x61, 0x72, 0x3b, 0x64, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4a, 0x2d, 0x67, 0x75, 0x65, 0x72,
+0x3b, 0x54, 0x2d, 0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x72, 0x72,
+0x69, 0x6c, 0x3b, 0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b,
+0x4a, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73, 0x74, 0x79, 0x6e, 0x3b, 0x4d,
+0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x2e, 0x48,
+0x6f, 0x75, 0x6e, 0x65, 0x79, 0x3b, 0x4d, 0x2e, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x4a, 0x65, 0x72, 0x72,
+0x65, 0x79, 0x2d, 0x67, 0x65, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x54, 0x6f, 0x73, 0x68, 0x69, 0x61, 0x67, 0x68, 0x74, 0x2d,
+0x61, 0x72, 0x72, 0x65, 0x65, 0x3b, 0x4d, 0x61, 0x79, 0x72, 0x6e, 0x74, 0x3b, 0x41, 0x76, 0x65, 0x72, 0x69, 0x6c, 0x3b,
+0x42, 0x6f, 0x61, 0x6c, 0x64, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b,
+0x4a, 0x65, 0x72, 0x72, 0x65, 0x79, 0x2d, 0x73, 0x6f, 0x75, 0x72, 0x65, 0x65, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x69, 0x73,
+0x74, 0x79, 0x6e, 0x3b, 0x4d, 0x65, 0x61, 0x6e, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4a, 0x65, 0x72, 0x72,
+0x65, 0x79, 0x2d, 0x66, 0x6f, 0x75, 0x79, 0x69, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x20, 0x48, 0x6f, 0x75, 0x6e, 0x65, 0x79,
+0x3b, 0x4d, 0x65, 0x65, 0x20, 0x6e, 0x79, 0x20, 0x4e, 0x6f, 0x6c, 0x6c, 0x69, 0x63, 0x6b, 0x3b, 0x47, 0x65, 0x6e, 0x3b,
+0x57, 0x68, 0x65, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x45, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x3b, 0x45, 0x66, 0x6e, 0x3b, 0x47,
+0x6f, 0x72, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x47, 0x77, 0x6e, 0x3b, 0x48, 0x65, 0x64, 0x3b, 0x44, 0x75, 0x3b, 0x4b, 0x65,
+0x76, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x57, 0x68, 0x65,
+0x76, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x45,
+0x62, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4d, 0x65, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x45, 0x66, 0x61, 0x6e,
+0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x65, 0x6e, 0x3b, 0x4d, 0x79, 0x65, 0x20, 0x45,
+0x73, 0x74, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x47, 0x77, 0x79, 0x6e, 0x67, 0x61, 0x6c, 0x61, 0x3b, 0x4d, 0x79, 0x73, 0x20,
+0x48, 0x65, 0x64, 0x72, 0x61, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x44, 0x75, 0x3b, 0x4d, 0x79, 0x73, 0x20, 0x4b, 0x65, 0x76,
+0x61, 0x72, 0x64, 0x68, 0x75, 0x3b, 0x53, 0x2d, 0x186, 0x3b, 0x4b, 0x2d, 0x186, 0x3b, 0x45, 0x2d, 0x186, 0x3b, 0x45, 0x2d,
+0x4f, 0x3b, 0x45, 0x2d, 0x4b, 0x3b, 0x4f, 0x2d, 0x41, 0x3b, 0x41, 0x2d, 0x4b, 0x3b, 0x44, 0x2d, 0x186, 0x3b, 0x46, 0x2d,
+0x190, 0x3b, 0x186, 0x2d, 0x41, 0x3b, 0x186, 0x2d, 0x4f, 0x3b, 0x4d, 0x2d, 0x186, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x61, 0x2d,
+0x186, 0x70, 0x25b, 0x70, 0x254, 0x6e, 0x3b, 0x4b, 0x77, 0x61, 0x6b, 0x77, 0x61, 0x72, 0x2d, 0x186, 0x67, 0x79, 0x65, 0x66,
+0x75, 0x6f, 0x3b, 0x45, 0x62, 0x254, 0x77, 0x2d, 0x186, 0x62, 0x65, 0x6e, 0x65, 0x6d, 0x3b, 0x45, 0x62, 0x254, 0x62, 0x69,
+0x72, 0x61, 0x2d, 0x4f, 0x66, 0x6f, 0x72, 0x69, 0x73, 0x75, 0x6f, 0x3b, 0x45, 0x73, 0x75, 0x73, 0x6f, 0x77, 0x20, 0x41,
+0x6b, 0x65, 0x74, 0x73, 0x65, 0x61, 0x62, 0x61, 0x2d, 0x4b, 0x254, 0x74, 0x254, 0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x4f,
+0x62, 0x69, 0x72, 0x61, 0x64, 0x65, 0x2d, 0x41, 0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x6d, 0x75, 0x6d, 0x75, 0x3b, 0x41,
+0x79, 0x25b, 0x77, 0x6f, 0x68, 0x6f, 0x2d, 0x4b, 0x69, 0x74, 0x61, 0x77, 0x6f, 0x6e, 0x73, 0x61, 0x3b, 0x44, 0x69, 0x66,
+0x75, 0x75, 0x2d, 0x186, 0x73, 0x61, 0x6e, 0x64, 0x61, 0x61, 0x3b, 0x46, 0x61, 0x6e, 0x6b, 0x77, 0x61, 0x2d, 0x190, 0x62,
+0x254, 0x3b, 0x186, 0x62, 0x25b, 0x73, 0x25b, 0x2d, 0x41, 0x68, 0x69, 0x6e, 0x69, 0x6d, 0x65, 0x3b, 0x186, 0x62, 0x65, 0x72,
+0x25b, 0x66, 0x25b, 0x77, 0x2d, 0x4f, 0x62, 0x75, 0x62, 0x75, 0x6f, 0x3b, 0x4d, 0x75, 0x6d, 0x75, 0x2d, 0x186, 0x70, 0x25b,
+0x6e, 0x69, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x947, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930,
+0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x91a, 0x3b, 0x90f, 0x92a, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e,
+0x947, 0x3b, 0x91c, 0x942, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x948, 0x3b, 0x913, 0x917, 0x938, 0x94d, 0x91f, 0x3b, 0x938, 0x947, 0x92a,
+0x94d, 0x91f, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x913, 0x915, 0x94d, 0x91f, 0x94b, 0x92c, 0x930, 0x3b, 0x928, 0x94b, 0x935, 0x94d, 0x939,
+0x947, 0x902, 0x92c, 0x930, 0x3b, 0x921, 0x93f, 0x938, 0x947, 0x902, 0x92c, 0x930, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x46, 0x65, 0x62,
+0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c,
+0x3b, 0x1ecc, 0x67, 0x1ecd, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x1ecc, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73,
+0x3b, 0x4a, 0x65, 0x6e, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x1ee5, 0x77, 0x61, 0x72, 0x1ecb, 0x3b,
+0x4d, 0x61, 0x61, 0x63, 0x68, 0x1ecb, 0x3b, 0x45, 0x70, 0x72, 0x65, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x4a, 0x75, 0x75,
+0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x1ecb, 0x3b, 0x1ecc, 0x67, 0x1ecd, 0x1ecd, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x1ecc, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44,
+0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x65, 0x6c, 0x3b, 0x4b, 0x74, 0x169, 0x3b, 0x4b,
+0x61, 0x6e, 0x3b, 0x4b, 0x74, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x6f, 0x3b, 0x4e, 0x79, 0x61, 0x3b, 0x4b,
+0x6e, 0x64, 0x3b, 0x128, 0x6b, 0x75, 0x3b, 0x128, 0x6b, 0x6d, 0x3b, 0x128, 0x6b, 0x6c, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20,
+0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129,
+0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74,
+0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74,
+0x169, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x75, 0x6f, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x61,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x6e, 0x79, 0x61, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69,
+0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x129, 0x6d,
+0x77, 0x65, 0x3b, 0x4d, 0x77, 0x61, 0x69, 0x20, 0x77, 0x61, 0x20, 0x129, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
+0x69, 0x6c, 0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b,
+0x4b, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x128, 0x3b, 0x120d, 0x12f0, 0x1275, 0x3b, 0x12ab, 0x1265, 0x12bd, 0x3b, 0x12ad, 0x1265, 0x120b, 0x3b,
+0x134b, 0x1305, 0x12ba, 0x3b, 0x12ad, 0x1262, 0x1245, 0x3b, 0x121d, 0x2f, 0x1275, 0x3b, 0x12b0, 0x122d, 0x3b, 0x121b, 0x122d, 0x12eb, 0x3b, 0x12eb,
+0x12b8, 0x1292, 0x3b, 0x1218, 0x1270, 0x1209, 0x3b, 0x121d, 0x2f, 0x121d, 0x3b, 0x1270, 0x1215, 0x1233, 0x3b, 0x120d, 0x12f0, 0x1275, 0x122a, 0x3b,
+0x12ab, 0x1265, 0x12bd, 0x1265, 0x1272, 0x3b, 0x12ad, 0x1265, 0x120b, 0x3b, 0x134b, 0x1305, 0x12ba, 0x122a, 0x3b, 0x12ad, 0x1262, 0x1245, 0x122a, 0x3b,
+0x121d, 0x12aa, 0x12a4, 0x120d, 0x20, 0x1275, 0x131f, 0x1292, 0x122a, 0x3b, 0x12b0, 0x122d, 0x12a9, 0x3b, 0x121b, 0x122d, 0x12eb, 0x121d, 0x20, 0x1275,
+0x122a, 0x3b, 0x12eb, 0x12b8, 0x1292, 0x20, 0x1218, 0x1233, 0x1245, 0x1208, 0x122a, 0x3b, 0x1218, 0x1270, 0x1209, 0x3b, 0x121d, 0x12aa, 0x12a4, 0x120d,
+0x20, 0x1218, 0x123d, 0x12c8, 0x122a, 0x3b, 0x1270, 0x1215, 0x1233, 0x1235, 0x122a, 0x3b, 0x120d, 0x3b, 0x12ab, 0x3b, 0x12ad, 0x3b, 0x134b, 0x3b,
+0x12ad, 0x3b, 0x121d, 0x3b, 0x12b0, 0x3b, 0x121b, 0x3b, 0x12eb, 0x3b, 0x1218, 0x3b, 0x121d, 0x3b, 0x1270, 0x3b, 0x5a, 0x65, 0x6e, 0x3b,
+0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x76, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x3b,
+0x4c, 0x75, 0x69, 0x3b, 0x41, 0x76, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b,
+0x44, 0x69, 0x63, 0x3b, 0x5a, 0x65, 0x6e, 0xe2, 0x72, 0x3b, 0x46, 0x65, 0x76, 0x72, 0xe2, 0x72, 0x3b, 0x4d, 0x61, 0x72,
+0xe7, 0x3b, 0x41, 0x76, 0x72, 0xee, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x67, 0x6e, 0x3b, 0x4c, 0x75, 0x69,
+0x3b, 0x41, 0x76, 0x6f, 0x73, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x74, 0x75, 0x62,
+0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x72,
+0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x50, 0x68, 0x61, 0x3b, 0x4c, 0x75, 0x68, 0x3b, 0x1e70, 0x68, 0x66, 0x3b, 0x4c, 0x61, 0x6d,
+0x3b, 0x53, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x3b, 0x1e70, 0x68, 0x61, 0x3b, 0x4b, 0x68, 0x75,
+0x3b, 0x54, 0x73, 0x68, 0x3b, 0x1e3c, 0x61, 0x72, 0x3b, 0x4e, 0x79, 0x65, 0x3b, 0x50, 0x68, 0x61, 0x6e, 0x64, 0x6f, 0x3b,
+0x4c, 0x75, 0x68, 0x75, 0x68, 0x69, 0x3b, 0x1e70, 0x68, 0x61, 0x66, 0x61, 0x6d, 0x75, 0x68, 0x77, 0x65, 0x3b, 0x4c, 0x61,
+0x6d, 0x62, 0x61, 0x6d, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x75, 0x6e, 0x64, 0x75, 0x6e, 0x74, 0x68, 0x75, 0x6c, 0x65, 0x3b,
+0x46, 0x75, 0x6c, 0x77, 0x69, 0x3b, 0x46, 0x75, 0x6c, 0x77, 0x61, 0x6e, 0x61, 0x3b, 0x1e70, 0x68, 0x61, 0x6e, 0x67, 0x75,
+0x6c, 0x65, 0x3b, 0x4b, 0x68, 0x75, 0x62, 0x76, 0x75, 0x6d, 0x65, 0x64, 0x7a, 0x69, 0x3b, 0x54, 0x73, 0x68, 0x69, 0x6d,
+0x65, 0x64, 0x7a, 0x69, 0x3b, 0x1e3c, 0x61, 0x72, 0x61, 0x3b, 0x4e, 0x79, 0x65, 0x6e, 0x64, 0x61, 0x76, 0x68, 0x75, 0x73,
+0x69, 0x6b, 0x75, 0x3b, 0x64, 0x7a, 0x76, 0x3b, 0x64, 0x7a, 0x64, 0x3b, 0x74, 0x65, 0x64, 0x3b, 0x61, 0x66, 0x254, 0x3b,
+0x64, 0x61, 0x6d, 0x3b, 0x6d, 0x61, 0x73, 0x3b, 0x73, 0x69, 0x61, 0x3b, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x6e, 0x79, 0x3b,
+0x6b, 0x65, 0x6c, 0x3b, 0x61, 0x64, 0x65, 0x3b, 0x64, 0x7a, 0x6d, 0x3b, 0x64, 0x7a, 0x6f, 0x76, 0x65, 0x3b, 0x64, 0x7a,
+0x6f, 0x64, 0x7a, 0x65, 0x3b, 0x74, 0x65, 0x64, 0x6f, 0x78, 0x65, 0x3b, 0x61, 0x66, 0x254, 0x66, 0x129, 0x65, 0x3b, 0x64,
+0x61, 0x6d, 0x61, 0x3b, 0x6d, 0x61, 0x73, 0x61, 0x3b, 0x73, 0x69, 0x61, 0x6d, 0x6c, 0x254, 0x6d, 0x3b, 0x64, 0x65, 0x61,
+0x73, 0x69, 0x61, 0x6d, 0x69, 0x6d, 0x65, 0x3b, 0x61, 0x6e, 0x79, 0x254, 0x6e, 0x79, 0x254, 0x3b, 0x6b, 0x65, 0x6c, 0x65,
+0x3b, 0x61, 0x64, 0x65, 0x25b, 0x6d, 0x65, 0x6b, 0x70, 0x254, 0x78, 0x65, 0x3b, 0x64, 0x7a, 0x6f, 0x6d, 0x65, 0x3b, 0x64,
+0x3b, 0x64, 0x3b, 0x74, 0x3b, 0x61, 0x3b, 0x64, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6b, 0x3b, 0x61,
+0x3b, 0x64, 0x3b, 0x49, 0x61, 0x6e, 0x2e, 0x3b, 0x50, 0x65, 0x70, 0x2e, 0x3b, 0x4d, 0x61, 0x6c, 0x2e, 0x3b, 0x2bb, 0x41,
+0x70, 0x2e, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x49, 0x75, 0x6e, 0x2e, 0x3b, 0x49, 0x75, 0x6c, 0x2e, 0x3b, 0x2bb, 0x41, 0x75,
+0x2e, 0x3b, 0x4b, 0x65, 0x70, 0x2e, 0x3b, 0x2bb, 0x4f, 0x6b, 0x2e, 0x3b, 0x4e, 0x6f, 0x77, 0x2e, 0x3b, 0x4b, 0x65, 0x6b,
+0x2e, 0x3b, 0x49, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x50, 0x65, 0x70, 0x65, 0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b,
+0x4d, 0x61, 0x6c, 0x61, 0x6b, 0x69, 0x3b, 0x2bb, 0x41, 0x70, 0x65, 0x6c, 0x69, 0x6c, 0x61, 0x3b, 0x4d, 0x65, 0x69, 0x3b,
+0x49, 0x75, 0x6e, 0x65, 0x3b, 0x49, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x2bb, 0x41, 0x75, 0x6b, 0x61, 0x6b, 0x65, 0x3b, 0x4b,
+0x65, 0x70, 0x61, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x2bb, 0x4f, 0x6b, 0x61, 0x6b, 0x6f, 0x70, 0x61, 0x3b, 0x4e,
+0x6f, 0x77, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x4b, 0x65, 0x6b, 0x65, 0x6d, 0x61, 0x70, 0x61, 0x3b, 0x45, 0x6e, 0x65,
+0x3b, 0x50, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x48, 0x75, 0x6e,
+0x3b, 0x48, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62,
+0x3b, 0x44, 0x69, 0x73, 0x3b, 0x45, 0x6e, 0x65, 0x72, 0x6f, 0x3b, 0x50, 0x65, 0x62, 0x72, 0x65, 0x72, 0x6f, 0x3b, 0x4d,
+0x61, 0x72, 0x73, 0x6f, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x79, 0x6f, 0x3b, 0x48, 0x75, 0x6e, 0x79,
+0x6f, 0x3b, 0x48, 0x75, 0x6c, 0x79, 0x6f, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x79, 0x65,
+0x6d, 0x62, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x62, 0x79, 0x65, 0x6d, 0x62,
+0x72, 0x65, 0x3b, 0x44, 0x69, 0x73, 0x79, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x45, 0x3b, 0x50, 0x3b, 0x4d, 0x3b, 0x41,
+0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x3b, 0x41, 0x70, 0x72,
+0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x69, 0x3b, 0x41, 0x75, 0x67,
+0x75, 0x73, 0x63, 0x68, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f,
+0x6f, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62,
+0x65, 0x72, 0x3b, 0xa2cd, 0xa1aa, 0x3b, 0xa44d, 0xa1aa, 0x3b, 0xa315, 0xa1aa, 0x3b, 0xa1d6, 0xa1aa, 0x3b, 0xa26c, 0xa1aa, 0x3b, 0xa0d8, 0xa1aa,
+0x3b, 0xa3c3, 0xa1aa, 0x3b, 0xa246, 0xa1aa, 0x3b, 0xa22c, 0xa1aa, 0x3b, 0xa2b0, 0xa1aa, 0x3b, 0xa2b0, 0xa2aa, 0xa1aa, 0x3b, 0xa2b0, 0xa44b, 0xa1aa,
+0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x79,
+0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x72, 0x68, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74,
+0x3b, 0x55, 0x73, 0x69, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x61, 0x62, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x46,
+0x65, 0x62, 0x65, 0x72, 0x62, 0x61, 0x72, 0x69, 0x3b, 0x75, 0x4d, 0x61, 0x74, 0x6a, 0x68, 0x69, 0x3b, 0x75, 0x2d, 0x41,
+0x70, 0x72, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x65, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61,
+0x79, 0x69, 0x3b, 0x41, 0x72, 0x68, 0x6f, 0x73, 0x74, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62,
+0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x55, 0x73, 0x69, 0x6e, 0x79, 0x69, 0x6b, 0x68, 0x61, 0x62, 0x61,
+0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x74,
+0x3b, 0x41, 0x70, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f,
+0x3b, 0x53, 0x65, 0x74, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x66, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61, 0x6e,
+0x61, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x46, 0x65, 0x62, 0x65, 0x72, 0x77, 0x61, 0x72, 0x65, 0x3b, 0x4d, 0x61, 0x74, 0x161,
+0x68, 0x65, 0x3b, 0x41, 0x70, 0x6f, 0x72, 0x65, 0x6c, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x65, 0x3b,
+0x4a, 0x75, 0x6c, 0x61, 0x65, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x6f, 0x73, 0x65, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d,
+0x65, 0x72, 0x65, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x6f, 0x72, 0x65, 0x3b, 0x4e, 0x6f, 0x66, 0x65, 0x6d, 0x65, 0x72,
+0x65, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x65, 0x72, 0x65, 0x3b, 0x6f, 0x111, 0x111, 0x6a, 0x3b, 0x67, 0x75, 0x6f, 0x76,
+0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x3b, 0x63, 0x75, 0x6f, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x3b,
+0x73, 0x75, 0x6f, 0x69, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x3b,
+0x73, 0x6b, 0xe1, 0x62, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x3b, 0x6f, 0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x6d, 0xe1,
+0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6e, 0x6a, 0x75, 0x6b,
+0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x6f, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x6d,
+0x69, 0x65, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73, 0x65, 0x6d, 0xe1, 0x6e,
+0x6e, 0x75, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, 0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x62, 0x6f, 0x72, 0x67,
+0x65, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x10d, 0x61, 0x6b, 0x10d, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x67, 0x6f,
+0x6c, 0x67, 0x67, 0x6f, 0x74, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x6d, 0xe1, 0x6e,
+0x6e, 0x75, 0x3b, 0x6a, 0x75, 0x6f, 0x76, 0x6c, 0x61, 0x6d, 0xe1, 0x6e, 0x6e, 0x75, 0x3b, 0x4f, 0x3b, 0x47, 0x3b, 0x4e,
+0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x10c, 0x3b, 0x47, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x6f,
+0x111, 0x111, 0x61, 0x6a, 0x61, 0x67, 0x65, 0x3b, 0x67, 0x75, 0x6f, 0x76, 0x76, 0x61, 0x3b, 0x6e, 0x6a, 0x75, 0x6b, 0x10d,
+0x61, 0x3b, 0x63, 0x75, 0x6f, 0x14b, 0x6f, 0x3b, 0x6d, 0x69, 0x65, 0x73, 0x73, 0x65, 0x3b, 0x67, 0x65, 0x61, 0x73, 0x73,
+0x65, 0x3b, 0x73, 0x75, 0x6f, 0x69, 0x64, 0x6e, 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x67, 0x65, 0x3b, 0x10d, 0x61, 0x6b, 0x10d,
+0x61, 0x3b, 0x67, 0x6f, 0x6c, 0x67, 0x67, 0x6f, 0x74, 0x3b, 0x73, 0x6b, 0xe1, 0x62, 0x6d, 0x61, 0x3b, 0x6a, 0x75, 0x6f,
+0x76, 0x6c, 0x61, 0x3b, 0x43, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b,
+0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x43, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x74, 0x3b, 0x53, 0x65, 0x70, 0x3b,
+0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x62, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x43, 0x68, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x69,
+0x3b, 0x46, 0x65, 0x62, 0x75, 0x72, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x69, 0x72,
+0x69, 0x72, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x43, 0x68, 0x75, 0x6c, 0x61, 0x69, 0x3b,
+0x41, 0x67, 0x6f, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74,
+0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b,
+0x43, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b,
+0x4e, 0x3b, 0x44, 0x3b, 0x49, 0x6d, 0x62, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, 0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b,
+0x4b, 0x61, 0x73, 0x3b, 0x4b, 0x61, 0x72, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x57, 0x75, 0x6e, 0x3b, 0x49, 0x6b, 0x65, 0x3b,
+0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77,
+0x61, 0x20, 0x69, 0x6d, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b,
+0x61, 0x77, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75,
+0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69,
+0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68,
+0x77, 0x61, 0x20, 0x6b, 0x61, 0x72, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68,
+0x77, 0x61, 0x20, 0x6d, 0x66, 0x75, 0x6e, 0x67, 0x61, 0x64, 0x65, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77,
+0x61, 0x20, 0x77, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x79, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61,
+0x20, 0x69, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b,
+0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20,
+0x6e, 0x61, 0x20, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4d, 0x6f, 0x72, 0x69, 0x20, 0x67, 0x68, 0x77, 0x61, 0x20,
+0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x77, 0x69, 0x3b, 0x49, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b,
+0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x73, 0x69, 0x69,
+0x3b, 0x63, 0x6f, 0x6c, 0x3b, 0x6d, 0x62, 0x6f, 0x3b, 0x73, 0x65, 0x65, 0x3b, 0x64, 0x75, 0x75, 0x3b, 0x6b, 0x6f, 0x72,
+0x3b, 0x6d, 0x6f, 0x72, 0x3b, 0x6a, 0x75, 0x6b, 0x3b, 0x73, 0x6c, 0x74, 0x3b, 0x79, 0x61, 0x72, 0x3b, 0x6a, 0x6f, 0x6c,
+0x3b, 0x62, 0x6f, 0x77, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x6f, 0x3b, 0x63, 0x6f, 0x6c, 0x74, 0x65, 0x3b, 0x6d, 0x62, 0x6f,
+0x6f, 0x79, 0x3b, 0x73, 0x65, 0x65, 0x257, 0x74, 0x6f, 0x3b, 0x64, 0x75, 0x75, 0x6a, 0x61, 0x6c, 0x3b, 0x6b, 0x6f, 0x72,
+0x73, 0x65, 0x3b, 0x6d, 0x6f, 0x72, 0x73, 0x6f, 0x3b, 0x6a, 0x75, 0x6b, 0x6f, 0x3b, 0x73, 0x69, 0x69, 0x6c, 0x74, 0x6f,
+0x3b, 0x79, 0x61, 0x72, 0x6b, 0x6f, 0x6d, 0x61, 0x61, 0x3b, 0x6a, 0x6f, 0x6c, 0x61, 0x6c, 0x3b, 0x62, 0x6f, 0x77, 0x74,
+0x65, 0x3b, 0x73, 0x3b, 0x63, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x73, 0x3b,
+0x79, 0x3b, 0x6a, 0x3b, 0x62, 0x3b, 0x4a, 0x45, 0x4e, 0x3b, 0x57, 0x4b, 0x52, 0x3b, 0x57, 0x47, 0x54, 0x3b, 0x57, 0x4b,
+0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x57, 0x54, 0x44, 0x3b, 0x57, 0x4d, 0x4a, 0x3b, 0x57, 0x4e, 0x4e, 0x3b, 0x57, 0x4b,
+0x44, 0x3b, 0x57, 0x49, 0x4b, 0x3b, 0x57, 0x4d, 0x57, 0x3b, 0x44, 0x49, 0x54, 0x3b, 0x4e, 0x6a, 0x65, 0x6e, 0x75, 0x61,
+0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x72, 0x129, 0x3b, 0x4d, 0x77, 0x65,
+0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77,
+0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61,
+0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74,
+0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
+0x65, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20,
+0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x65, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69,
+0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4e, 0x64, 0x69, 0x74, 0x68, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a,
+0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49,
+0x3b, 0x44, 0x3b, 0x4f, 0x62, 0x6f, 0x3b, 0x57, 0x61, 0x61, 0x3b, 0x4f, 0x6b, 0x75, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49,
+0x6d, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b, 0x49, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x61, 0x3b, 0x54,
+0x6f, 0x6d, 0x3b, 0x54, 0x6f, 0x62, 0x3b, 0x54, 0x6f, 0x77, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f,
+0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4c, 0x61, 0x70,
+0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x6f,
+0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6d, 0x65, 0x74, 0x3b,
+0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20,
+0x73, 0x61, 0x70, 0x61, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x69, 0x65, 0x74, 0x3b, 0x4c,
+0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x73, 0x61, 0x61, 0x6c, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20,
+0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20,
+0x6f, 0x62, 0x6f, 0x3b, 0x4c, 0x61, 0x70, 0x61, 0x20, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x77, 0x61,
+0x61, 0x72, 0x65, 0x3b, 0x4f, 0x3b, 0x57, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x49, 0x3b,
+0x53, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b,
+0x41, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x75, 0x67, 0x3b,
+0x53, 0x65, 0x74, 0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x4a, 0x61, 0x6e, 0x65,
+0x69, 0x72, 0x6f, 0x3b, 0x46, 0x65, 0x76, 0x72, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x63, 0x6f, 0x3b, 0x41,
+0x62, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x61, 0x69, 0x6f, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x6f, 0x3b, 0x4a, 0x75, 0x6c, 0x68,
+0x6f, 0x3b, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x4f,
+0x74, 0x75, 0x62, 0x72, 0x6f, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x72, 0x6f, 0x3b, 0x44, 0x65, 0x63, 0x65, 0x6d,
+0x62, 0x72, 0x6f, 0x3b, 0x5a, 0x69, 0x62, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x3b, 0x4d, 0x62, 0x69, 0x3b, 0x4d, 0x61, 0x62,
+0x3b, 0x4e, 0x6b, 0x77, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x3b, 0x4e, 0x63, 0x77, 0x3b, 0x4d, 0x70,
+0x61, 0x6e, 0x3b, 0x4d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x3b, 0x4d, 0x70, 0x61, 0x6c, 0x3b, 0x5a, 0x69, 0x62, 0x61,
+0x6e, 0x64, 0x6c, 0x65, 0x6c, 0x61, 0x3b, 0x4e, 0x68, 0x6c, 0x6f, 0x6c, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x62, 0x69,
+0x6d, 0x62, 0x69, 0x74, 0x68, 0x6f, 0x3b, 0x4d, 0x61, 0x62, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x6b, 0x77, 0x65, 0x6e, 0x6b,
+0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4e, 0x68, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x3b, 0x4e, 0x74, 0x75, 0x6c, 0x69,
+0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4e, 0x63, 0x77, 0x61, 0x62, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x4d, 0x70, 0x61, 0x6e,
+0x64, 0x75, 0x6c, 0x61, 0x3b, 0x4d, 0x66, 0x75, 0x6d, 0x66, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x7a, 0x69, 0x3b, 0x4d, 0x70,
+0x61, 0x6c, 0x61, 0x6b, 0x61, 0x7a, 0x69, 0x3b, 0x5a, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b,
+0x4e, 0x3b, 0x4e, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x31, 0x3b, 0x4d, 0x32, 0x3b, 0x4d, 0x33,
+0x3b, 0x4d, 0x34, 0x3b, 0x4d, 0x35, 0x3b, 0x4d, 0x36, 0x3b, 0x4d, 0x37, 0x3b, 0x4d, 0x38, 0x3b, 0x4d, 0x39, 0x3b, 0x4d,
+0x31, 0x30, 0x3b, 0x4d, 0x31, 0x31, 0x3b, 0x4d, 0x31, 0x32, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
+0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x69, 0x6c,
+0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
+0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61,
+0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x74, 0x69,
+0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61,
+0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d,
+0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e,
+0x3b, 0x54, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x2d49, 0x2d4f, 0x2d4f, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x3b, 0x2d4e, 0x2d30, 0x2d55,
+0x3b, 0x2d49, 0x2d31, 0x2d54, 0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x3b, 0x2d62, 0x2d53, 0x2d4d, 0x3b, 0x2d56, 0x2d53, 0x2d5b,
+0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x3b, 0x2d4f, 0x2d53, 0x2d61, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x3b, 0x2d49, 0x2d4f, 0x2d4f,
+0x2d30, 0x2d62, 0x2d54, 0x3b, 0x2d31, 0x2d55, 0x2d30, 0x2d62, 0x2d55, 0x3b, 0x2d4e, 0x2d30, 0x2d55, 0x2d5a, 0x3b, 0x2d49, 0x2d31, 0x2d54, 0x2d49, 0x2d54,
+0x3b, 0x2d4e, 0x2d30, 0x2d62, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4f, 0x2d62, 0x2d53, 0x3b, 0x2d62, 0x2d53, 0x2d4d, 0x2d62, 0x2d53, 0x2d63, 0x3b,
+0x2d56, 0x2d53, 0x2d5b, 0x2d5c, 0x3b, 0x2d5b, 0x2d53, 0x2d5c, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d3d, 0x2d5c, 0x2d53, 0x2d31, 0x2d54, 0x3b,
+0x2d4f, 0x2d53, 0x2d61, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d37, 0x2d53, 0x2d4a, 0x2d30, 0x2d4f, 0x2d31, 0x2d49, 0x2d54, 0x3b, 0x2d49, 0x3b,
+0x2d31, 0x3b, 0x2d4e, 0x3b, 0x2d49, 0x3b, 0x2d4e, 0x3b, 0x2d62, 0x3b, 0x2d62, 0x3b, 0x2d56, 0x3b, 0x2d5b, 0x3b, 0x2d3d, 0x3b, 0x2d4f, 0x3b,
+0x2d37, 0x3b, 0x69, 0x6e, 0x6e, 0x3b, 0x62, 0x1e5b, 0x61, 0x3b, 0x6d, 0x61, 0x1e5b, 0x3b, 0x69, 0x62, 0x72, 0x3b, 0x6d, 0x61,
+0x79, 0x3b, 0x79, 0x75, 0x6e, 0x3b, 0x79, 0x75, 0x6c, 0x3b, 0x263, 0x75, 0x63, 0x3b, 0x63, 0x75, 0x74, 0x3b, 0x6b, 0x74,
+0x75, 0x3b, 0x6e, 0x75, 0x77, 0x3b, 0x64, 0x75, 0x6a, 0x3b, 0x69, 0x6e, 0x6e, 0x61, 0x79, 0x72, 0x3b, 0x62, 0x1e5b, 0x61,
+0x79, 0x1e5b, 0x3b, 0x6d, 0x61, 0x1e5b, 0x1e63, 0x3b, 0x69, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x6d, 0x61, 0x79, 0x79, 0x75, 0x3b,
+0x79, 0x75, 0x6e, 0x79, 0x75, 0x3b, 0x79, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x263, 0x75, 0x63, 0x74, 0x3b, 0x63, 0x75,
+0x74, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x6b, 0x74, 0x75, 0x62, 0x72, 0x3b, 0x6e, 0x75, 0x77, 0x61, 0x6e, 0x62, 0x69,
+0x72, 0x3b, 0x64, 0x75, 0x6a, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x69, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, 0x69, 0x3b, 0x6d,
+0x3b, 0x79, 0x3b, 0x79, 0x3b, 0x263, 0x3b, 0x63, 0x3b, 0x6b, 0x3b, 0x6e, 0x3b, 0x64, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x46,
+0x75, 0x72, 0x3b, 0x4d, 0x65, 0x263, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59,
+0x75, 0x6c, 0x3b, 0x194, 0x75, 0x63, 0x3b, 0x43, 0x74, 0x65, 0x3b, 0x54, 0x75, 0x62, 0x3b, 0x4e, 0x75, 0x6e, 0x3b, 0x44,
+0x75, 0x1e7, 0x3b, 0x59, 0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x46, 0x75, 0x1e5b, 0x61, 0x72, 0x3b, 0x4d, 0x65,
+0x263, 0x72, 0x65, 0x73, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75,
+0x6e, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6c, 0x79, 0x75, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x74, 0x65, 0x6d, 0x62,
+0x65, 0x1e5b, 0x3b, 0x54, 0x75, 0x62, 0x65, 0x1e5b, 0x3b, 0x4e, 0x75, 0x6e, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x44, 0x75,
+0x1e7, 0x65, 0x6d, 0x62, 0x65, 0x1e5b, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59,
+0x3b, 0x194, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4b, 0x42, 0x5a, 0x3b, 0x4b, 0x42, 0x52, 0x3b, 0x4b,
+0x53, 0x54, 0x3b, 0x4b, 0x4b, 0x4e, 0x3b, 0x4b, 0x54, 0x4e, 0x3b, 0x4b, 0x4d, 0x4b, 0x3b, 0x4b, 0x4d, 0x53, 0x3b, 0x4b,
+0x4d, 0x4e, 0x3b, 0x4b, 0x4d, 0x57, 0x3b, 0x4b, 0x4b, 0x4d, 0x3b, 0x4b, 0x4e, 0x4b, 0x3b, 0x4b, 0x4e, 0x42, 0x3b, 0x4f,
+0x6b, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72,
+0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61,
+0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d,
+0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x6a, 0x75, 0x3b,
+0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x75, 0x6e, 0x61, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x77, 0x65, 0x6e,
+0x64, 0x61, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75,
+0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x77, 0x65, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x69, 0x6b, 0x75, 0x6d,
+0x69, 0x20, 0x6e, 0x61, 0x20, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x48, 0x75, 0x74, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x44,
+0x61, 0x74, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x48, 0x61, 0x6e, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e,
+0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4b, 0x6d, 0x6a, 0x3b, 0x4b, 0x6d, 0x62, 0x3b, 0x70,
+0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x68, 0x75, 0x74, 0x61, 0x6c, 0x61, 0x3b,
+0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x76, 0x69, 0x6c, 0x69,
+0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x64, 0x61, 0x74,
+0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x74, 0x61,
+0x69, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x77, 0x75, 0x68, 0x61,
+0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x69, 0x74,
+0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61,
+0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b,
+0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x70,
+0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x70, 0x61,
+0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20,
+0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x77, 0x65, 0x64, 0x7a, 0x69, 0x20, 0x67, 0x77, 0x61, 0x20, 0x6b,
+0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x48, 0x3b, 0x56, 0x3b, 0x44, 0x3b, 0x54,
+0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4a, 0x61, 0x6e,
+0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b,
+0x41, 0x70, 0x72, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x79, 0x69, 0x3b, 0x4a, 0x75,
+0x6c, 0x79, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61,
+0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65,
+0x6d, 0x62, 0x61, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x77, 0x69, 0x3b,
+0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x3b, 0x7a, 0x75, 0x6c, 0x3b, 0x75, 0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x3b, 0x254,
+0x6b, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x77, 0x75, 0x79, 0x65, 0x3b, 0x66,
+0x65, 0x62, 0x75, 0x72, 0x75, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b, 0x61, 0x77, 0x69, 0x72, 0x69,
+0x6c, 0x69, 0x3b, 0x6d, 0x25b, 0x3b, 0x7a, 0x75, 0x77, 0x25b, 0x6e, 0x3b, 0x7a, 0x75, 0x6c, 0x75, 0x79, 0x65, 0x3b, 0x75,
+0x74, 0x69, 0x3b, 0x73, 0x25b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x254, 0x6b, 0x75, 0x74, 0x254, 0x62, 0x75,
+0x72, 0x75, 0x3b, 0x6e, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75,
+0x72, 0x75, 0x3b, 0x5a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x5a, 0x3b, 0x55, 0x3b, 0x53,
+0x3b, 0x186, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x62, 0x65, 0x3b, 0x4b, 0x61, 0x69, 0x3b, 0x4b, 0x61, 0x74, 0x3b, 0x4b,
+0x61, 0x6e, 0x3b, 0x47, 0x61, 0x74, 0x3b, 0x47, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x4b, 0x6e, 0x6e, 0x3b, 0x4b,
+0x65, 0x6e, 0x3b, 0x49, 0x6b, 0x75, 0x3b, 0x49, 0x6d, 0x77, 0x3b, 0x49, 0x67, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b,
+0x61, 0x129, 0x72, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x68, 0x61, 0x74,
+0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20,
+0x6d, 0x169, 0x67, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61,
+0x6e, 0x61, 0x6e, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x65, 0x6e, 0x64, 0x61, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69,
+0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x169, 0x6d, 0x77, 0x65, 0x3b, 0x4d, 0x77,
+0x65, 0x72, 0x69, 0x20, 0x77, 0x61, 0x20, 0x69, 0x6b, 0x169, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x4b, 0x61, 0x129, 0x72,
+0x129, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x47, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b,
+0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x13a4, 0x13c3, 0x3b, 0x13a7, 0x13a6, 0x3b, 0x13a0, 0x13c5, 0x3b, 0x13a7, 0x13ec, 0x3b, 0x13a0, 0x13c2,
+0x3b, 0x13d5, 0x13ad, 0x3b, 0x13ab, 0x13f0, 0x3b, 0x13a6, 0x13b6, 0x3b, 0x13da, 0x13b5, 0x3b, 0x13da, 0x13c2, 0x3b, 0x13c5, 0x13d3, 0x3b, 0x13a4,
+0x13cd, 0x3b, 0x13a4, 0x13c3, 0x13b8, 0x13d4, 0x13c5, 0x3b, 0x13a7, 0x13a6, 0x13b5, 0x3b, 0x13a0, 0x13c5, 0x13f1, 0x3b, 0x13a7, 0x13ec, 0x13c2, 0x3b,
+0x13a0, 0x13c2, 0x13cd, 0x13ac, 0x13d8, 0x3b, 0x13d5, 0x13ad, 0x13b7, 0x13f1, 0x3b, 0x13ab, 0x13f0, 0x13c9, 0x13c2, 0x3b, 0x13a6, 0x13b6, 0x13c2, 0x3b,
+0x13da, 0x13b5, 0x13cd, 0x13d7, 0x3b, 0x13da, 0x13c2, 0x13c5, 0x13d7, 0x3b, 0x13c5, 0x13d3, 0x13d5, 0x13c6, 0x3b, 0x13a4, 0x13cd, 0x13a9, 0x13f1, 0x3b,
+0x13a4, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13a7, 0x3b, 0x13a0, 0x3b, 0x13d5, 0x3b, 0x13ab, 0x3b, 0x13a6, 0x3b, 0x13da, 0x3b, 0x13da, 0x3b,
+0x13c5, 0x3b, 0x13a4, 0x3b, 0x7a, 0x61, 0x6e, 0x3b, 0x66, 0x65, 0x76, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x76, 0x72, 0x3b,
+0x6d, 0x65, 0x3b, 0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x3b, 0x6f,
+0x6b, 0x74, 0x3b, 0x6e, 0x6f, 0x76, 0x3b, 0x64, 0x65, 0x73, 0x3b, 0x7a, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x66, 0x65,
+0x76, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x73, 0x3b, 0x61, 0x76, 0x72, 0x69, 0x6c, 0x3b, 0x6d, 0x65, 0x3b,
+0x7a, 0x69, 0x6e, 0x3b, 0x7a, 0x69, 0x6c, 0x79, 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x3b, 0x73, 0x65, 0x70, 0x74, 0x61, 0x6d,
+0x3b, 0x6f, 0x6b, 0x74, 0x6f, 0x62, 0x3b, 0x6e, 0x6f, 0x76, 0x61, 0x6d, 0x3b, 0x64, 0x65, 0x73, 0x61, 0x6d, 0x3b, 0x7a,
+0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x7a, 0x3b, 0x6f, 0x3b, 0x73, 0x3b, 0x6f, 0x3b, 0x6e,
+0x3b, 0x64, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x4e, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x50, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x54,
+0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69,
+0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65,
+0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x6d, 0x6f, 0x3b,
+0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d,
+0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61,
+0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4d,
+0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e,
+0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x77, 0x65, 0x64, 0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f,
+0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x55, 0x3b, 0x4d, 0x77, 0x65, 0x64,
+0x69, 0x20, 0x77, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x4d, 0x3b, 0x46, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b, 0x4e, 0x61, 0x61, 0x6e, 0x268,
+0x3b, 0x4b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x49, 0x6b, 0xfa, 0x6d, 0x69, 0x3b, 0x49, 0x6e, 0x79, 0x61, 0x6d, 0x62,
+0x61, 0x6c, 0x61, 0x3b, 0x49, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b,
+0x56, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x53, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x49, 0x6e, 0x79, 0x69, 0x3b, 0x53, 0x61, 0x61,
+0x6e, 0x6f, 0x3b, 0x53, 0x61, 0x73, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x289, 0x66, 0xfa, 0x6e, 0x67, 0x61, 0x74, 0x268, 0x3b,
+0x4b, 0x289, 0x6e, 0x61, 0x61, 0x6e, 0x268, 0x3b, 0x4b, 0x289, 0x6b, 0x65, 0x65, 0x6e, 0x64, 0x61, 0x3b, 0x4b, 0x77, 0x69,
+0x69, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4b, 0x77, 0x69, 0x69, 0x6e, 0x79, 0x61, 0x6d, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x4b,
+0x77, 0x69, 0x69, 0x64, 0x77, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x4b, 0x289, 0x6d, 0x289, 0x289, 0x6e, 0x63, 0x68, 0x268, 0x3b,
+0x4b, 0x289, 0x76, 0x268, 0x268, 0x72, 0x268, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x74, 0x289, 0x3b, 0x4b, 0x77, 0x69, 0x69,
+0x6e, 0x79, 0x69, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4b, 0x289, 0x73, 0x61, 0x73, 0x61, 0x74, 0x289,
+0x3b, 0x46, 0x3b, 0x4e, 0x3b, 0x4b, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x49,
+0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x75,
+0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x62,
+0x3b, 0x4f, 0x6b, 0x69, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x77, 0x61, 0x6c, 0x69,
+0x79, 0x6f, 0x3b, 0x46, 0x65, 0x62, 0x77, 0x61, 0x6c, 0x69, 0x79, 0x6f, 0x3b, 0x4d, 0x61, 0x72, 0x69, 0x73, 0x69, 0x3b,
+0x41, 0x70, 0x75, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75,
+0x6c, 0x61, 0x61, 0x79, 0x69, 0x3b, 0x41, 0x67, 0x75, 0x73, 0x69, 0x74, 0x6f, 0x3b, 0x53, 0x65, 0x62, 0x75, 0x74, 0x74,
+0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x69, 0x74, 0x6f, 0x62, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62,
+0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61,
+0x63, 0x3b, 0x45, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x67,
+0x61, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x69, 0x73, 0x3b, 0x4a, 0x61,
+0x6e, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69,
+0x3b, 0x45, 0x70, 0x72, 0x65, 0x6f, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61,
+0x69, 0x3b, 0x4f, 0x67, 0x61, 0x73, 0x74, 0x69, 0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b,
+0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x73, 0x65, 0x6d, 0x62, 0x61,
+0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4f, 0x3b, 0x53, 0x3b, 0x4f,
+0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x76, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72,
+0x3b, 0x4d, 0x61, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74,
+0x3b, 0x4f, 0x74, 0x75, 0x3b, 0x4e, 0x75, 0x76, 0x3b, 0x44, 0x69, 0x7a, 0x3b, 0x4a, 0x61, 0x6e, 0x65, 0x72, 0x75, 0x3b,
+0x46, 0x65, 0x76, 0x65, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x4d, 0x61, 0x72, 0x73, 0x75, 0x3b, 0x41, 0x62, 0x72, 0x69, 0x6c,
+0x3b, 0x4d, 0x61, 0x69, 0x75, 0x3b, 0x4a, 0x75, 0x6e, 0x68, 0x75, 0x3b, 0x4a, 0x75, 0x6c, 0x68, 0x75, 0x3b, 0x41, 0x67,
+0x6f, 0x73, 0x74, 0x75, 0x3b, 0x53, 0x65, 0x74, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4f, 0x74, 0x75, 0x62, 0x72, 0x75,
+0x3b, 0x4e, 0x75, 0x76, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x44, 0x69, 0x7a, 0x65, 0x6e, 0x62, 0x72, 0x75, 0x3b, 0x4a,
+0x41, 0x4e, 0x3b, 0x46, 0x45, 0x42, 0x3b, 0x4d, 0x41, 0x43, 0x3b, 0x128, 0x50, 0x55, 0x3b, 0x4d, 0x128, 0x128, 0x3b, 0x4e,
+0x4a, 0x55, 0x3b, 0x4e, 0x4a, 0x52, 0x3b, 0x41, 0x47, 0x41, 0x3b, 0x53, 0x50, 0x54, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4e,
+0x4f, 0x56, 0x3b, 0x44, 0x45, 0x43, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x129, 0x3b, 0x46, 0x65, 0x62, 0x75, 0x72,
+0x75, 0x61, 0x72, 0x129, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x128, 0x70, 0x75, 0x72, 0x169, 0x3b, 0x4d, 0x129, 0x129,
+0x3b, 0x4e, 0x6a, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x72, 0x61, 0x129, 0x3b, 0x41, 0x67, 0x61, 0x73, 0x74, 0x69,
+0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x169, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x69, 0x63, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4a, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x128,
+0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4d, 0x75, 0x6c,
+0x3b, 0x4e, 0x67, 0x61, 0x3b, 0x4b, 0x69, 0x70, 0x3b, 0x49, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0x65, 0x3b, 0x57, 0x61, 0x6b,
+0x3b, 0x52, 0x6f, 0x70, 0x3b, 0x4b, 0x6f, 0x67, 0x3b, 0x42, 0x75, 0x72, 0x3b, 0x45, 0x70, 0x65, 0x3b, 0x54, 0x61, 0x69,
+0x3b, 0x41, 0x65, 0x6e, 0x3b, 0x4d, 0x75, 0x6c, 0x67, 0x75, 0x6c, 0x3b, 0x4e, 0x67, 0x27, 0x61, 0x74, 0x79, 0x61, 0x74,
+0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x74, 0x61, 0x6d, 0x6f, 0x3b, 0x49, 0x77, 0x61, 0x74, 0x20, 0x6b, 0x75, 0x74, 0x3b, 0x4e,
+0x67, 0x27, 0x65, 0x69, 0x79, 0x65, 0x74, 0x3b, 0x57, 0x61, 0x6b, 0x69, 0x3b, 0x52, 0x6f, 0x70, 0x74, 0x75, 0x69, 0x3b,
+0x4b, 0x69, 0x70, 0x6b, 0x6f, 0x67, 0x61, 0x67, 0x61, 0x3b, 0x42, 0x75, 0x72, 0x65, 0x74, 0x3b, 0x45, 0x70, 0x65, 0x73,
+0x6f, 0x3b, 0x4b, 0x69, 0x70, 0x73, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x74, 0x61, 0x69, 0x3b, 0x4b, 0x69, 0x70,
+0x73, 0x75, 0x6e, 0x64, 0x65, 0x20, 0x6e, 0x65, 0x62, 0x6f, 0x20, 0x61, 0x65, 0x6e, 0x67, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b,
+0x4b, 0x3b, 0x49, 0x3b, 0x4e, 0x3b, 0x57, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x42, 0x3b, 0x45, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b,
+0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x6e, 0x69, 0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x6e, 0x1c0, 0x67, 0xf4, 0x61, 0x62, 0x3b, 0x1c0,
+0x4b, 0x68, 0x75, 0x75, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x1c3, 0x48, 0xf4, 0x61, 0x1c2, 0x6b, 0x68, 0x61, 0x69, 0x62,
+0x3b, 0x1c3, 0x4b, 0x68, 0x61, 0x69, 0x74, 0x73, 0xe2, 0x62, 0x3b, 0x47, 0x61, 0x6d, 0x61, 0x1c0, 0x61, 0x65, 0x62, 0x3b,
+0x1c2, 0x4b, 0x68, 0x6f, 0x65, 0x73, 0x61, 0x6f, 0x62, 0x3b, 0x41, 0x6f, 0x1c1, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1,
+0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x54, 0x61, 0x72, 0x61, 0x1c0, 0x6b, 0x68, 0x75, 0x75, 0x6d, 0xfb, 0x1c1, 0x6b, 0x68, 0xe2,
+0x62, 0x3b, 0x1c2, 0x4e, 0xfb, 0x1c1, 0x6e, 0xe2, 0x69, 0x73, 0x65, 0x62, 0x3b, 0x1c0, 0x48, 0x6f, 0x6f, 0x1c2, 0x67, 0x61,
+0x65, 0x62, 0x3b, 0x48, 0xf4, 0x61, 0x73, 0x6f, 0x72, 0x65, 0x1c1, 0x6b, 0x68, 0xe2, 0x62, 0x3b, 0x4a, 0x61, 0x6e, 0x2e,
+0x3b, 0x46, 0xe4, 0x62, 0x2e, 0x3b, 0x4d, 0xe4, 0x7a, 0x2e, 0x3b, 0x41, 0x70, 0x72, 0x2e, 0x3b, 0x4d, 0xe4, 0x69, 0x3b,
+0x4a, 0x75, 0x6e, 0x2e, 0x3b, 0x4a, 0x75, 0x6c, 0x2e, 0x3b, 0x4f, 0x75, 0x6a, 0x2e, 0x3b, 0x53, 0xe4, 0x70, 0x2e, 0x3b,
+0x4f, 0x6b, 0x74, 0x2e, 0x3b, 0x4e, 0x6f, 0x76, 0x2e, 0x3b, 0x44, 0x65, 0x7a, 0x2e, 0x3b, 0x4a, 0x61, 0x6e, 0x6e, 0x65,
+0x77, 0x61, 0x3b, 0x46, 0xe4, 0x62, 0x72, 0x6f, 0x77, 0x61, 0x3b, 0x4d, 0xe4, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x65,
+0x6c, 0x6c, 0x3b, 0x4d, 0xe4, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x75, 0x6c, 0x69, 0x3b, 0x4f,
+0x75, 0x6a, 0x6f, 0xdf, 0x3b, 0x53, 0x65, 0x70, 0x74, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x6f,
+0x62, 0x65, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0xe4, 0x6d, 0x62, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x7a, 0xe4, 0x6d, 0x62, 0x65,
+0x72, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0xe4, 0x62, 0x3b, 0x4d, 0xe4, 0x7a, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0xe4,
+0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x4f, 0x75, 0x6a, 0x3b, 0x53, 0xe4, 0x70, 0x3b, 0x4f, 0x6b,
+0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x7a, 0x3b, 0x44, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0xe1, 0x3b, 0x186, 0x25b,
+0x6e, 0x3b, 0x44, 0x6f, 0x79, 0x3b, 0x4c, 0xe9, 0x70, 0x3b, 0x52, 0x6f, 0x6b, 0x3b, 0x53, 0xe1, 0x73, 0x3b, 0x42, 0x254,
+0x301, 0x72, 0x3b, 0x4b, 0xfa, 0x73, 0x3b, 0x47, 0xed, 0x73, 0x3b, 0x53, 0x68, 0x289, 0x301, 0x3b, 0x4e, 0x74, 0x289, 0x301,
+0x3b, 0x4f, 0x6c, 0x61, 0x64, 0x61, 0x6c, 0x289, 0x301, 0x3b, 0x41, 0x72, 0xe1, 0x74, 0x3b, 0x186, 0x25b, 0x6e, 0x268, 0x301,
+0x254, 0x268, 0x14b, 0x254, 0x6b, 0x3b, 0x4f, 0x6c, 0x6f, 0x64, 0x6f, 0x79, 0xed, 0xf3, 0x72, 0xed, 0xea, 0x20, 0x69, 0x6e,
+0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4f, 0x6c, 0x6f, 0x69, 0x6c, 0xe9, 0x70, 0x16b, 0x6e, 0x79, 0x12b, 0x113, 0x20, 0x69,
+0x6e, 0x6b, 0xf3, 0x6b, 0xfa, 0xe2, 0x3b, 0x4b, 0xfa, 0x6a, 0xfa, 0x254, 0x72, 0x254, 0x6b, 0x3b, 0x4d, 0xf3, 0x72, 0x75,
+0x73, 0xe1, 0x73, 0x69, 0x6e, 0x3b, 0x186, 0x6c, 0x254, 0x301, 0x268, 0x301, 0x62, 0x254, 0x301, 0x72, 0xe1, 0x72, 0x25b, 0x3b,
+0x4b, 0xfa, 0x73, 0x68, 0xee, 0x6e, 0x3b, 0x4f, 0x6c, 0x67, 0xed, 0x73, 0x61, 0x6e, 0x3b, 0x50, 0x289, 0x73, 0x68, 0x289,
+0x301, 0x6b, 0x61, 0x3b, 0x4e, 0x74, 0x289, 0x301, 0x14b, 0x289, 0x301, 0x73, 0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62,
+0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c,
+0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x73,
+0x3b, 0x4a, 0x61, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x63, 0x3b, 0x41, 0x70, 0x72, 0x3b, 0x4d, 0x65, 0x69,
+0x3b, 0x4a, 0x75, 0x6e, 0x3b, 0x4a, 0x75, 0x6c, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x70, 0x3b, 0x4f, 0x6b, 0x74,
+0x3b, 0x4e, 0x6f, 0x76, 0x3b, 0x44, 0x65, 0x63, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4d, 0x75, 0x6b, 0x3b, 0x4b, 0x77, 0x61,
+0x3b, 0x44, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x6f, 0x64, 0x3b, 0x4a, 0x6f, 0x6c, 0x3b, 0x50, 0x65, 0x64,
+0x3b, 0x53, 0x6f, 0x6b, 0x3b, 0x54, 0x69, 0x62, 0x3b, 0x4c, 0x61, 0x62, 0x3b, 0x50, 0x6f, 0x6f, 0x3b, 0x4f, 0x72, 0x61,
+0x72, 0x61, 0x3b, 0x4f, 0x6d, 0x75, 0x6b, 0x3b, 0x4f, 0x6b, 0x77, 0x61, 0x6d, 0x67, 0x27, 0x3b, 0x4f, 0x64, 0x75, 0x6e,
+0x67, 0x27, 0x65, 0x6c, 0x3b, 0x4f, 0x6d, 0x61, 0x72, 0x75, 0x6b, 0x3b, 0x4f, 0x6d, 0x6f, 0x64, 0x6f, 0x6b, 0x27, 0x6b,
+0x69, 0x6e, 0x67, 0x27, 0x6f, 0x6c, 0x3b, 0x4f, 0x6a, 0x6f, 0x6c, 0x61, 0x3b, 0x4f, 0x70, 0x65, 0x64, 0x65, 0x6c, 0x3b,
+0x4f, 0x73, 0x6f, 0x6b, 0x6f, 0x73, 0x6f, 0x6b, 0x6f, 0x6d, 0x61, 0x3b, 0x4f, 0x74, 0x69, 0x62, 0x61, 0x72, 0x3b, 0x4f,
+0x6c, 0x61, 0x62, 0x6f, 0x72, 0x3b, 0x4f, 0x70, 0x6f, 0x6f, 0x3b, 0x52, 0x3b, 0x4d, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x4d,
+0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x50, 0x3b, 0x17d, 0x61, 0x6e, 0x3b, 0x46,
+0x65, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x77, 0x69, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x3b, 0x17d, 0x75,
+0x79, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x3b, 0x4f, 0x6b, 0x74, 0x3b, 0x4e, 0x6f, 0x6f, 0x3b, 0x44, 0x65, 0x65,
+0x3b, 0x17d, 0x61, 0x6e, 0x77, 0x69, 0x79, 0x65, 0x3b, 0x46, 0x65, 0x65, 0x77, 0x69, 0x72, 0x69, 0x79, 0x65, 0x3b, 0x4d,
+0x61, 0x72, 0x73, 0x69, 0x3b, 0x41, 0x77, 0x69, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x3b, 0x17d, 0x75, 0x77, 0x65, 0x14b,
+0x3b, 0x17d, 0x75, 0x79, 0x79, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x6b, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b,
+0x4f, 0x6b, 0x74, 0x6f, 0x6f, 0x62, 0x75, 0x72, 0x3b, 0x4e, 0x6f, 0x6f, 0x77, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x44,
+0x65, 0x65, 0x73, 0x61, 0x6e, 0x62, 0x75, 0x72, 0x3b, 0x17d, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x17d,
+0x3b, 0x17d, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x44, 0x41, 0x43, 0x3b, 0x44, 0x41, 0x52,
+0x3b, 0x44, 0x41, 0x44, 0x3b, 0x44, 0x41, 0x4e, 0x3b, 0x44, 0x41, 0x48, 0x3b, 0x44, 0x41, 0x55, 0x3b, 0x44, 0x41, 0x4f,
+0x3b, 0x44, 0x41, 0x42, 0x3b, 0x44, 0x4f, 0x43, 0x3b, 0x44, 0x41, 0x50, 0x3b, 0x44, 0x47, 0x49, 0x3b, 0x44, 0x41, 0x47,
+0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20,
+0x6d, 0x61, 0x72, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x64,
+0x65, 0x6b, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x6e, 0x67, 0x27, 0x77, 0x65, 0x6e, 0x3b, 0x44,
+0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72,
+0x20, 0x41, 0x75, 0x63, 0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x69,
+0x72, 0x69, 0x79, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x62, 0x6f, 0x72, 0x6f, 0x3b, 0x44,
+0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4f, 0x63, 0x68, 0x69, 0x6b, 0x6f, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61,
+0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x67, 0x69, 0x20, 0x61, 0x63,
+0x68, 0x69, 0x65, 0x6c, 0x3b, 0x44, 0x77, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x41, 0x70, 0x61, 0x72, 0x20, 0x67, 0x69,
+0x20, 0x61, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x43, 0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x4e, 0x3b, 0x42, 0x3b, 0x55, 0x3b, 0x42,
+0x3b, 0x42, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x59, 0x65, 0x6e, 0x3b, 0x59, 0x65, 0x62, 0x3b, 0x4d,
+0x61, 0x72, 0x3b, 0x49, 0x62, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x59, 0x75, 0x6e, 0x3b, 0x59, 0x75, 0x6c, 0x3b, 0x194,
+0x75, 0x63, 0x3b, 0x43, 0x75, 0x74, 0x3b, 0x4b, 0x1e6d, 0x75, 0x3b, 0x4e, 0x77, 0x61, 0x3b, 0x44, 0x75, 0x6a, 0x3b, 0x59,
+0x65, 0x6e, 0x6e, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x59, 0x65, 0x62, 0x72, 0x61, 0x79, 0x65, 0x72, 0x3b, 0x4d, 0x61, 0x72,
+0x73, 0x3b, 0x49, 0x62, 0x72, 0x69, 0x72, 0x3b, 0x4d, 0x61, 0x79, 0x79, 0x75, 0x3b, 0x59, 0x75, 0x6e, 0x79, 0x75, 0x3b,
+0x59, 0x75, 0x6c, 0x79, 0x75, 0x7a, 0x3b, 0x194, 0x75, 0x63, 0x74, 0x3b, 0x43, 0x75, 0x74, 0x61, 0x6e, 0x62, 0x69, 0x72,
+0x3b, 0x4b, 0x1e6d, 0x75, 0x62, 0x65, 0x72, 0x3b, 0x4e, 0x77, 0x61, 0x6e, 0x62, 0x69, 0x72, 0x3b, 0x44, 0x75, 0x6a, 0x61,
+0x6e, 0x62, 0x69, 0x72, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x59, 0x3b, 0x194,
+0x3b, 0x43, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x46, 0x65, 0x62,
+0x6c, 0x75, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x3b, 0x41, 0x70, 0x6c, 0x69, 0x6c, 0x69, 0x3b, 0x4d,
+0x65, 0x69, 0x3b, 0x4a, 0x75, 0x6e, 0x69, 0x3b, 0x4a, 0x75, 0x6c, 0x61, 0x69, 0x3b, 0x41, 0x67, 0x6f, 0x73, 0x74, 0x69,
+0x3b, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x4f, 0x6b, 0x74, 0x6f, 0x62, 0x61, 0x3b, 0x4e, 0x6f, 0x76,
+0x65, 0x6d, 0x62, 0x61, 0x3b, 0x44, 0x65, 0x73, 0x65, 0x6d, 0x62, 0x61, 0x3b, 0x91c, 0x93e, 0x928, 0x941, 0x935, 0x93e, 0x930,
+0x940, 0x3b, 0x92b, 0x947, 0x92c, 0x94d, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x940, 0x3b, 0x92e, 0x93e, 0x930, 0x94d, 0x938, 0x3b, 0x90f,
+0x92b, 0x94d, 0x930, 0x93f, 0x932, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x928, 0x3b, 0x91c, 0x941, 0x932, 0x93e, 0x907, 0x3b, 0x906,
+0x917, 0x938, 0x94d, 0x925, 0x3b, 0x938, 0x947, 0x92c, 0x925, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x905, 0x916, 0x925, 0x92c,
+0x930, 0x3b, 0x928, 0x92c, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930, 0x3b, 0x926, 0x93f, 0x938, 0x947, 0x91c, 0x94d, 0x92c, 0x93c, 0x930,
+0x3b, 0x91c, 0x3b, 0x92b, 0x947, 0x3b, 0x92e, 0x93e, 0x3b, 0x90f, 0x3b, 0x92e, 0x947, 0x3b, 0x91c, 0x941, 0x3b, 0x91c, 0x941, 0x3b,
+0x906, 0x3b, 0x938, 0x947, 0x3b, 0x905, 0x3b, 0x928, 0x3b, 0x926, 0x93f, 0x3b, 0x43, 0x69, 0x6f, 0x3b, 0x4c, 0x75, 0x69, 0x3b,
+0x4c, 0x75, 0x73, 0x3b, 0x4d, 0x75, 0x75, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x66, 0x3b, 0x4b, 0x61, 0x62, 0x3b,
+0x4c, 0x75, 0x73, 0x68, 0x3b, 0x4c, 0x75, 0x74, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x43, 0x69, 0x73,
+0x3b, 0x43, 0x69, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0xf9, 0x69, 0x73, 0x68, 0x69, 0x3b, 0x4c, 0x75, 0x73, 0xf2, 0x6c,
+0x6f, 0x3b, 0x4d, 0xf9, 0x75, 0x79, 0xe0, 0x3b, 0x4c, 0x75, 0x6d, 0xf9, 0x6e, 0x67, 0xf9, 0x6c, 0xf9, 0x3b, 0x4c, 0x75,
+0x66, 0x75, 0x69, 0x6d, 0x69, 0x3b, 0x4b, 0x61, 0x62, 0xe0, 0x6c, 0xe0, 0x73, 0x68, 0xec, 0x70, 0xf9, 0x3b, 0x4c, 0xf9,
+0x73, 0x68, 0xec, 0x6b, 0xe0, 0x3b, 0x4c, 0x75, 0x74, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x67,
+0xf9, 0x64, 0x69, 0x3b, 0x4b, 0x61, 0x73, 0x77, 0xe8, 0x6b, 0xe8, 0x73, 0xe8, 0x3b, 0x43, 0x69, 0x73, 0x77, 0xe0, 0x3b,
+0x43, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b,
+0x4b, 0x3b, 0x43, 0x3b, 0x6e, 0xf9, 0x6d, 0x3b, 0x6b, 0x268, 0x7a, 0x3b, 0x74, 0x268, 0x64, 0x3b, 0x74, 0x61, 0x61, 0x3b,
+0x73, 0x65, 0x65, 0x3b, 0x6e, 0x7a, 0x75, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x66, 0x254, 0x65, 0x3b, 0x64, 0x7a, 0x75, 0x3b,
+0x6c, 0x254, 0x6d, 0x3b, 0x6b, 0x61, 0x61, 0x3b, 0x66, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300,
+0x6e, 0xf9, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6b, 0x197, 0x300, 0x7a, 0xf9, 0x294, 0x3b, 0x6e,
+0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x197, 0x300, 0x64, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x3b, 0x6e, 0x64, 0x7a,
+0x254, 0x300, 0x14b, 0x254, 0x300, 0x74, 0x1ce, 0x61, 0x66, 0x289, 0x304, 0x67, 0x68, 0x101, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
+0x14b, 0xe8, 0x73, 0xe8, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x6e, 0x7a, 0xf9, 0x67, 0x68, 0xf2,
+0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x64, 0xf9, 0x6d, 0x6c, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
+0x14b, 0x254, 0x300, 0x6b, 0x77, 0xee, 0x66, 0x254, 0x300, 0x65, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b, 0x254, 0x300, 0x74,
+0x197, 0x300, 0x66, 0x289, 0x300, 0x67, 0x68, 0xe0, 0x64, 0x7a, 0x75, 0x67, 0x68, 0xf9, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
+0x14b, 0x254, 0x300, 0x67, 0x68, 0x1d4, 0x75, 0x77, 0x65, 0x6c, 0x254, 0x300, 0x6d, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300, 0x14b,
+0x254, 0x300, 0x63, 0x68, 0x77, 0x61, 0x294, 0xe0, 0x6b, 0x61, 0x61, 0x20, 0x77, 0x6f, 0x3b, 0x6e, 0x64, 0x7a, 0x254, 0x300,
+0x14b, 0xe8, 0x66, 0x77, 0xf2, 0x6f, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x74, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6b,
+0x3b, 0x66, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x63, 0x3b, 0x66, 0x3b, 0x6b, 0x254, 0x6e, 0x3b, 0x6d, 0x61, 0x63, 0x3b, 0x6d,
+0x61, 0x74, 0x3b, 0x6d, 0x74, 0x6f, 0x3b, 0x6d, 0x70, 0x75, 0x3b, 0x68, 0x69, 0x6c, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x68,
+0x69, 0x6b, 0x3b, 0x64, 0x69, 0x70, 0x3b, 0x62, 0x69, 0x6f, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x6c, 0x69, 0x253, 0x3b, 0x4b,
+0x254, 0x6e, 0x64, 0x254, 0x14b, 0x3b, 0x4d, 0xe0, 0x63, 0x25b, 0x302, 0x6c, 0x3b, 0x4d, 0xe0, 0x74, 0xf9, 0x6d, 0x62, 0x3b,
+0x4d, 0xe0, 0x74, 0x6f, 0x70, 0x3b, 0x4d, 0x300, 0x70, 0x75, 0x79, 0x25b, 0x3b, 0x48, 0xec, 0x6c, 0xf2, 0x6e, 0x64, 0x25b,
+0x300, 0x3b, 0x4e, 0x6a, 0xe8, 0x62, 0xe0, 0x3b, 0x48, 0xec, 0x6b, 0x61, 0x14b, 0x3b, 0x44, 0xec, 0x70, 0x254, 0x300, 0x73,
+0x3b, 0x42, 0xec, 0xf2, 0xf4, 0x6d, 0x3b, 0x4d, 0xe0, 0x79, 0x25b, 0x73, 0xe8, 0x70, 0x3b, 0x4c, 0xec, 0x62, 0x75, 0x79,
+0x20, 0x6c, 0x69, 0x20, 0x144, 0x79, 0xe8, 0x65, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x68,
+0x3b, 0x6e, 0x3b, 0x68, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6d, 0x3b, 0x6c, 0x3b, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e,
+0x3b, 0x73, 0x254, 0x14b, 0x3b, 0x64, 0x69, 0x253, 0x3b, 0x65, 0x6d, 0x69, 0x3b, 0x65, 0x73, 0x254, 0x3b, 0x6d, 0x61, 0x64,
+0x3b, 0x64, 0x69, 0x14b, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x3b, 0x6d, 0x61, 0x79, 0x3b, 0x74, 0x69, 0x6e, 0x3b, 0x65, 0x6c,
+0xe1, 0x3b, 0x64, 0x69, 0x6d, 0x254, 0x301, 0x64, 0x69, 0x3b, 0x14b, 0x67, 0x254, 0x6e, 0x64, 0x25b, 0x3b, 0x73, 0x254, 0x14b,
+0x25b, 0x3b, 0x64, 0x69, 0x253, 0xe1, 0x253, 0xe1, 0x3b, 0x65, 0x6d, 0x69, 0x61, 0x73, 0x65, 0x6c, 0x65, 0x3b, 0x65, 0x73,
+0x254, 0x70, 0x25b, 0x73, 0x254, 0x70, 0x25b, 0x3b, 0x6d, 0x61, 0x64, 0x69, 0x253, 0x25b, 0x301, 0x64, 0xed, 0x253, 0x25b, 0x301,
+0x3b, 0x64, 0x69, 0x14b, 0x67, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6e, 0x79, 0x25b, 0x74, 0x25b, 0x6b, 0x69, 0x3b, 0x6d, 0x61,
+0x79, 0xe9, 0x73, 0x25b, 0x301, 0x3b, 0x74, 0x69, 0x6e, 0xed, 0x6e, 0xed, 0x3b, 0x65, 0x6c, 0xe1, 0x14b, 0x67, 0x25b, 0x301,
+0x3b, 0x64, 0x3b, 0x14b, 0x3b, 0x73, 0x3b, 0x64, 0x3b, 0x65, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x64, 0x3b, 0x6e, 0x3b, 0x6d,
+0x3b, 0x74, 0x3b, 0x65, 0x3b, 0x53, 0x61, 0x3b, 0x46, 0x65, 0x3b, 0x4d, 0x61, 0x3b, 0x41, 0x62, 0x3b, 0x4d, 0x65, 0x3b,
+0x53, 0x75, 0x3b, 0x53, 0xfa, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x3b, 0x4f, 0x6b, 0x3b, 0x4e, 0x6f, 0x3b, 0x44, 0x65,
+0x3b, 0x53, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x3b, 0x46, 0xe9, 0x62, 0x69, 0x72, 0x69, 0x65, 0x3b, 0x4d, 0x61, 0x72, 0x73,
+0x3b, 0x41, 0x62, 0x75, 0x72, 0x69, 0x6c, 0x3b, 0x4d, 0x65, 0x65, 0x3b, 0x53, 0x75, 0x65, 0x14b, 0x3b, 0x53, 0xfa, 0x75,
+0x79, 0x65, 0x65, 0x3b, 0x55, 0x74, 0x3b, 0x53, 0x65, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x4f, 0x6b, 0x74,
+0x6f, 0x62, 0x61, 0x72, 0x3b, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x3b, 0x44, 0x69, 0x73, 0x61, 0x6d, 0x62,
+0x61, 0x72, 0x3b, 0x53, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x55, 0x3b, 0x53,
+0x3b, 0x4f, 0x3b, 0x4e, 0x3b, 0x44, 0x3b, 0x6e, 0x67, 0x6f, 0x3b, 0x6e, 0x67, 0x62, 0x3b, 0x6e, 0x67, 0x6c, 0x3b, 0x6e,
+0x67, 0x6e, 0x3b, 0x6e, 0x67, 0x74, 0x3b, 0x6e, 0x67, 0x73, 0x3b, 0x6e, 0x67, 0x7a, 0x3b, 0x6e, 0x67, 0x6d, 0x3b, 0x6e,
+0x67, 0x65, 0x3b, 0x6e, 0x67, 0x61, 0x3b, 0x6e, 0x67, 0x61, 0x64, 0x3b, 0x6e, 0x67, 0x61, 0x62, 0x3b, 0x6e, 0x67, 0x254,
+0x6e, 0x20, 0x6f, 0x73, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20,
+0x6c, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6e, 0x79, 0x69, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e,
+0x20, 0x74, 0xe1, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x73, 0x61, 0x6d, 0x259, 0x6e, 0x61, 0x3b, 0x6e, 0x67,
+0x254, 0x6e, 0x20, 0x7a, 0x61, 0x6d, 0x67, 0x62, 0xe1, 0x6c, 0x61, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x6d, 0x77, 0x6f,
+0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x65, 0x62, 0x75, 0x6c, 0xfa, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77,
+0xf3, 0x6d, 0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x64, 0x7a, 0x69, 0xe1,
+0x3b, 0x6e, 0x67, 0x254, 0x6e, 0x20, 0x61, 0x77, 0xf3, 0x6d, 0x20, 0x61, 0x69, 0x20, 0x62, 0x25b, 0x30c, 0x3b, 0x6f, 0x3b,
+0x62, 0x3b, 0x6c, 0x3b, 0x6e, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x7a, 0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x61, 0x3b, 0x64, 0x3b,
+0x62, 0x3b, 0x14b, 0x31, 0x3b, 0x14b, 0x32, 0x3b, 0x14b, 0x33, 0x3b, 0x14b, 0x34, 0x3b, 0x14b, 0x35, 0x3b, 0x14b, 0x36, 0x3b,
+0x14b, 0x37, 0x3b, 0x14b, 0x38, 0x3b, 0x14b, 0x39, 0x3b, 0x14b, 0x31, 0x30, 0x3b, 0x14b, 0x31, 0x31, 0x3b, 0x14b, 0x31, 0x32,
+0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x20, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x74, 0x254, 0x3b, 0x14b, 0x77, 0xed, 0xed,
+0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x72,
+0xe1, 0xe1, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed,
+0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74,
+0xe1, 0x61, 0x66, 0x254, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x62, 0x25b,
+0x25b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x72, 0x61, 0x61, 0x3b, 0x14b, 0x77,
+0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x74, 0xe1, 0x61, 0x6e, 0x69, 0x6e, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61,
+0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e, 0x74, 0x25b,
+0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x254, 0x301, 0x6b, 0x3b, 0x14b, 0x77, 0xed, 0xed, 0x20, 0x61, 0x6b, 0x1dd, 0x20, 0x6e,
+0x74, 0x25b, 0x6b, 0x20, 0x64, 0x69, 0x20, 0x62, 0x25b, 0x301, 0x25b, 0x3b, 0x4b, 0x77, 0x61, 0x3b, 0x55, 0x6e, 0x61, 0x3b,
+0x52, 0x61, 0x72, 0x3b, 0x43, 0x68, 0x65, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4d, 0x6f, 0x63, 0x3b, 0x53, 0x61, 0x62, 0x3b,
+0x4e, 0x61, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4b, 0x75, 0x6d, 0x3b, 0x4d, 0x6f, 0x6a, 0x3b, 0x59, 0x65, 0x6c, 0x3b,
+0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72,
+0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e, 0x61, 0x79, 0x65, 0x6c, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
+0x6f, 0x20, 0x75, 0x6e, 0x65, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75,
+0x6e, 0x65, 0x63, 0x68, 0x65, 0x73, 0x68, 0x65, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x75, 0x6e,
+0x65, 0x74, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x68, 0x61, 0x6e,
+0x75, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x63, 0x68, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20,
+0x73, 0x61, 0x62, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6e, 0x61, 0x6e, 0x65, 0x3b, 0x4d,
+0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77,
+0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75, 0x6d, 0x69,
+0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x6a, 0x61, 0x3b, 0x4d, 0x77, 0x65, 0x72, 0x69, 0x20, 0x77, 0x6f, 0x20, 0x6b, 0x75,
+0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x79, 0x65, 0x6c, 0x27, 0x6c, 0x69, 0x3b, 0x4b, 0x3b, 0x55, 0x3b, 0x52, 0x3b, 0x43,
+0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x59, 0x3b, 0x46, 0x4c, 0x4f,
+0x3b, 0x43, 0x4c, 0x41, 0x3b, 0x43, 0x4b, 0x49, 0x3b, 0x46, 0x4d, 0x46, 0x3b, 0x4d, 0x41, 0x44, 0x3b, 0x4d, 0x42, 0x49,
+0x3b, 0x4d, 0x4c, 0x49, 0x3b, 0x4d, 0x41, 0x4d, 0x3b, 0x46, 0x44, 0x45, 0x3b, 0x46, 0x4d, 0x55, 0x3b, 0x46, 0x47, 0x57,
+0x3b, 0x46, 0x59, 0x55, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4c, 0x6f, 0x6f, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b,
+0x6c, 0x61, 0x14b, 0x6e, 0x65, 0x3b, 0x43, 0x6f, 0x6b, 0x63, 0x77, 0x61, 0x6b, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69,
+0x20, 0x4d, 0x61, 0x72, 0x66, 0x6f, 0x6f, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x1dd, 0x75, 0x75, 0x74, 0x1dd, 0x62, 0x69, 0x6a,
+0x61, 0x14b, 0x3b, 0x4d, 0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x66, 0x61, 0x68, 0x62, 0x69, 0x69, 0x3b, 0x4d,
+0x61, 0x6d, 0x1dd, 0x14b, 0x67, 0x77, 0xe3, 0x61, 0x6c, 0x69, 0x69, 0x3b, 0x4d, 0x61, 0x64, 0x1dd, 0x6d, 0x62, 0x69, 0x69,
+0x3b, 0x46, 0x129, 0x69, 0x20, 0x44, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x4d, 0x75, 0x6e, 0x64,
+0x61, 0x14b, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x47, 0x77, 0x61, 0x68, 0x6c, 0x6c, 0x65, 0x3b, 0x46, 0x129, 0x69, 0x20, 0x59,
+0x75, 0x72, 0x75, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x46, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b,
+0x45, 0x3b, 0x55, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x6e, 0x67, 0x31, 0x3b, 0x6e, 0x67, 0x32, 0x3b, 0x6e, 0x67, 0x33, 0x3b,
+0x6e, 0x67, 0x34, 0x3b, 0x6e, 0x67, 0x35, 0x3b, 0x6e, 0x67, 0x36, 0x3b, 0x6e, 0x67, 0x37, 0x3b, 0x6e, 0x67, 0x38, 0x3b,
+0x6e, 0x67, 0x39, 0x3b, 0x6e, 0x67, 0x31, 0x30, 0x3b, 0x6e, 0x67, 0x31, 0x31, 0x3b, 0x6b, 0x72, 0x69, 0x73, 0x3b, 0x6e,
+0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6d, 0x61, 0x74, 0xe1, 0x68, 0x72, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144,
+0x6d, 0x62, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x6c, 0x61, 0x6c, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e,
+0x20, 0x144, 0x6e, 0x61, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x144, 0x74, 0x61, 0x6e, 0x3b, 0x6e, 0x67, 0x77, 0x25b,
+0x6e, 0x20, 0x144, 0x74, 0x75, 0xf3, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x68, 0x25b, 0x6d, 0x62, 0x75, 0x25b, 0x72,
+0xed, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x6c, 0x254, 0x6d, 0x62, 0x69, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20,
+0x72, 0x25b, 0x62, 0x76, 0x75, 0xe2, 0x3b, 0x6e, 0x67, 0x77, 0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x3b, 0x6e, 0x67, 0x77,
+0x25b, 0x6e, 0x20, 0x77, 0x75, 0x6d, 0x20, 0x6e, 0x61, 0x76, 0x16d, 0x72, 0x3b, 0x6b, 0x72, 0xed, 0x73, 0x69, 0x6d, 0x69,
+0x6e, 0x3b, 0x54, 0x69, 0x6f, 0x70, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331, 0x3b, 0x47, 0x75,
+0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x3b, 0x4b, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x54, 0x68, 0x6f, 0x6f, 0x3b,
+0x54, 0x25b, 0x25b, 0x3b, 0x4c, 0x61, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x64, 0x3b, 0x54, 0x69, 0x6f, 0x70,
+0x20, 0x74, 0x68, 0x61, 0x72, 0x20, 0x70, 0x25b, 0x74, 0x3b, 0x50, 0x25b, 0x74, 0x3b, 0x44, 0x75, 0x254, 0x331, 0x254, 0x331,
+0x14b, 0x3b, 0x47, 0x75, 0x61, 0x6b, 0x3b, 0x44, 0x75, 0xe4, 0x74, 0x3b, 0x4b, 0x6f, 0x72, 0x6e, 0x79, 0x6f, 0x6f, 0x74,
+0x3b, 0x50, 0x61, 0x79, 0x20, 0x79, 0x69, 0x65, 0x331, 0x74, 0x6e, 0x69, 0x3b, 0x54, 0x68, 0x6f, 0x331, 0x6f, 0x331, 0x72,
+0x3b, 0x54, 0x25b, 0x25b, 0x72, 0x3b, 0x4c, 0x61, 0x61, 0x74, 0x68, 0x3b, 0x4b, 0x75, 0x72, 0x3b, 0x54, 0x69, 0x6f, 0x331,
+0x70, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x69, 0x331, 0x69, 0x331, 0x74, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x44, 0x3b, 0x47, 0x3b,
+0x44, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x422, 0x43e, 0x445, 0x441,
+0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x3b, 0x41a, 0x43b, 0x43d, 0x5f, 0x442, 0x442, 0x440, 0x3b, 0x41c, 0x443, 0x441, 0x5f, 0x443, 0x441,
+0x442, 0x3b, 0x42b, 0x430, 0x43c, 0x5f, 0x439, 0x43d, 0x3b, 0x411, 0x44d, 0x441, 0x5f, 0x439, 0x43d, 0x3b, 0x41e, 0x442, 0x5f, 0x439,
+0x43d, 0x3b, 0x410, 0x442, 0x440, 0x434, 0x44c, 0x5f, 0x439, 0x43d, 0x3b, 0x411, 0x43b, 0x495, 0x43d, 0x5f, 0x439, 0x43d, 0x3b, 0x410,
+0x43b, 0x442, 0x3b, 0x421, 0x44d, 0x442, 0x3b, 0x410, 0x445, 0x441, 0x3b, 0x422, 0x43e, 0x445, 0x441, 0x443, 0x43d, 0x43d, 0x44c, 0x443,
+0x3b, 0x41e, 0x43b, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x3b, 0x41a, 0x443, 0x43b, 0x443, 0x43d, 0x20, 0x442, 0x443, 0x442, 0x430, 0x440,
+0x3b, 0x41c, 0x443, 0x443, 0x441, 0x20, 0x443, 0x441, 0x442, 0x430, 0x440, 0x3b, 0x42b, 0x430, 0x43c, 0x20, 0x44b, 0x439, 0x44b, 0x43d,
+0x3b, 0x411, 0x44d, 0x441, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x41e, 0x442, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x442,
+0x44b, 0x440, 0x434, 0x44c, 0x44b, 0x445, 0x20, 0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x411, 0x430, 0x43b, 0x430, 0x495, 0x430, 0x43d, 0x20,
+0x44b, 0x439, 0x44b, 0x43d, 0x3b, 0x410, 0x43b, 0x442, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x421, 0x44d, 0x442, 0x438, 0x43d, 0x43d,
+0x44c, 0x438, 0x3b, 0x410, 0x445, 0x441, 0x44b, 0x43d, 0x43d, 0x44c, 0x44b, 0x3b, 0x422, 0x3b, 0x41e, 0x3b, 0x41a, 0x3b, 0x41c, 0x3b,
+0x42b, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x410, 0x3b, 0x411, 0x3b, 0x410, 0x3b, 0x421, 0x3b, 0x410, 0x3b, 0x4d, 0x75, 0x70, 0x3b,
+0x4d, 0x77, 0x69, 0x3b, 0x4d, 0x73, 0x68, 0x3b, 0x4d, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x67, 0x3b, 0x4d, 0x75, 0x6a, 0x3b,
+0x4d, 0x73, 0x70, 0x3b, 0x4d, 0x70, 0x67, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x4d, 0x75, 0x73, 0x3b,
+0x4d, 0x75, 0x68, 0x3b, 0x4d, 0x75, 0x70, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x77, 0x61, 0x3b, 0x4d, 0x77, 0x69,
+0x74, 0x6f, 0x70, 0x65, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x69, 0x3b,
+0x4d, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x67, 0x61, 0x6c, 0x69, 0x3b, 0x4d, 0x75, 0x6a, 0x69,
+0x6d, 0x62, 0x69, 0x3b, 0x4d, 0x75, 0x73, 0x68, 0x69, 0x70, 0x65, 0x70, 0x6f, 0x3b, 0x4d, 0x75, 0x70, 0x75, 0x67, 0x75,
+0x74, 0x6f, 0x3b, 0x4d, 0x75, 0x6e, 0x79, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x4d, 0x6f, 0x6b, 0x68, 0x75, 0x3b, 0x4d, 0x75,
+0x73, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x6d, 0x62, 0x77, 0x65, 0x3b, 0x4d, 0x75, 0x68, 0x61, 0x61, 0x6e, 0x6f,
+0x3b, 0x6d, 0x6b, 0x77, 0x3b, 0x6d, 0x70, 0x69, 0x3b, 0x6d, 0x74, 0x75, 0x3b, 0x6d, 0x69, 0x6e, 0x3b, 0x6d, 0x74, 0x6e,
+0x3b, 0x6d, 0x73, 0x74, 0x3b, 0x6d, 0x73, 0x62, 0x3b, 0x6d, 0x75, 0x6e, 0x3b, 0x6d, 0x74, 0x73, 0x3b, 0x6d, 0x6b, 0x75,
+0x3b, 0x6d, 0x6b, 0x6d, 0x3b, 0x6d, 0x6b, 0x62, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x77,
+0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x6d,
+0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79,
+0x61, 0x20, 0x69, 0x6e, 0x65, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b,
+0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20,
+0x79, 0x61, 0x20, 0x73, 0x61, 0x62, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x75, 0x6e,
+0x61, 0x6e, 0x65, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x74, 0x69, 0x73, 0x61, 0x3b, 0x6d, 0x77,
+0x65, 0x7a, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20, 0x79, 0x61,
+0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x6f, 0x79, 0x61, 0x3b, 0x6d, 0x77, 0x65, 0x7a, 0x69, 0x20,
+0x79, 0x61, 0x20, 0x6b, 0x75, 0x6d, 0x69, 0x20, 0x79, 0x61, 0x20, 0x6d, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x6b, 0x3b, 0x70,
+0x3b, 0x74, 0x3b, 0x69, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x74, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x6d,
+0x3b, 0xa5a8, 0xa56a, 0xa583, 0x20, 0xa51e, 0xa56e, 0x3b, 0xa552, 0xa561, 0xa59d, 0xa595, 0x3b, 0xa57e, 0xa5ba, 0x3b, 0xa5a2, 0xa595, 0x3b, 0xa591,
+0xa571, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0xa5db, 0xa515, 0x3b, 0xa562, 0xa54c, 0x3b, 0xa56d, 0xa583, 0x3b, 0xa51e, 0xa60b, 0xa554, 0xa57f, 0x20,
+0xa578, 0xa583, 0xa5cf, 0x3b, 0xa5a8, 0xa56a, 0xa571, 0x20, 0xa5cf, 0xa56e, 0x3b, 0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6b, 0x65,
+0x6d, 0xe3, 0x3b, 0x253, 0x61, 0x6e, 0x64, 0x61, 0x253, 0x75, 0x3b, 0x76, 0x254, 0x254, 0x3b, 0x66, 0x75, 0x6c, 0x75, 0x3b,
+0x67, 0x6f, 0x6f, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x6b, 0x254, 0x6e, 0x64, 0x65, 0x3b, 0x73, 0x61, 0x61, 0x68, 0x3b, 0x67,
+0x61, 0x6c, 0x6f, 0x3b, 0x6b, 0x65, 0x6e, 0x70, 0x6b, 0x61, 0x74, 0x6f, 0x20, 0x253, 0x6f, 0x6c, 0x6f, 0x6c, 0x254, 0x3b,
+0x6c, 0x75, 0x75, 0x6b, 0x61, 0x6f, 0x20, 0x6c, 0x254, 0x6d, 0x61, 0x3b, 0x4a, 0x65, 0x6e, 0x3b, 0x48, 0x6f, 0x72, 0x3b,
+0x4d, 0xe4, 0x72, 0x3b, 0x41, 0x62, 0x72, 0x3b, 0x4d, 0x65, 0x69, 0x3b, 0x42, 0x72, 0xe1, 0x3b, 0x48, 0x65, 0x69, 0x3b,
+0xd6, 0x69, 0x67, 0x3b, 0x48, 0x65, 0x72, 0x3b, 0x57, 0xed, 0x6d, 0x3b, 0x57, 0x69, 0x6e, 0x3b, 0x43, 0x68, 0x72, 0x3b,
+0x4a, 0x65, 0x6e, 0x6e, 0x65, 0x72, 0x3b, 0x48, 0x6f, 0x72, 0x6e, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0x72, 0x7a, 0x65, 0x3b,
+0x41, 0x62, 0x72, 0x69, 0x6c, 0x6c, 0x65, 0x3b, 0x4d, 0x65, 0x69, 0x6a, 0x65, 0x3b, 0x42, 0x72, 0xe1, 0x10d, 0x65, 0x74,
+0x3b, 0x48, 0x65, 0x69, 0x77, 0x65, 0x74, 0x3b, 0xd6, 0x69, 0x67, 0x161, 0x74, 0x65, 0x3b, 0x48, 0x65, 0x72, 0x62, 0x161,
+0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0xed, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x57, 0x69, 0x6e, 0x74, 0x65,
+0x72, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x43, 0x68, 0x72, 0x69, 0x161, 0x74, 0x6d, 0xe1, 0x6e, 0x65, 0x74, 0x3b, 0x4a,
+0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x48, 0x3b, 0xd6, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x57,
+0x3b, 0x43, 0x3b, 0x6f, 0x2e, 0x31, 0x3b, 0x6f, 0x2e, 0x32, 0x3b, 0x6f, 0x2e, 0x33, 0x3b, 0x6f, 0x2e, 0x34, 0x3b, 0x6f,
+0x2e, 0x35, 0x3b, 0x6f, 0x2e, 0x36, 0x3b, 0x6f, 0x2e, 0x37, 0x3b, 0x6f, 0x2e, 0x38, 0x3b, 0x6f, 0x2e, 0x39, 0x3b, 0x6f,
+0x2e, 0x31, 0x30, 0x3b, 0x6f, 0x2e, 0x31, 0x31, 0x3b, 0x6f, 0x2e, 0x31, 0x32, 0x3b, 0x70, 0x69, 0x6b, 0xed, 0x74, 0xed,
+0x6b, 0xed, 0x74, 0x69, 0x65, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0xed, 0x20, 0xfa, 0x20, 0x6b, 0x75, 0x74, 0xfa, 0x61, 0x6e,
+0x3b, 0x73, 0x69, 0x25b, 0x79, 0x25b, 0x301, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20, 0x6b, 0xe1, 0x6e, 0x64,
+0xed, 0x25b, 0x3b, 0x254, 0x6e, 0x73, 0xfa, 0x6d, 0x62, 0x254, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20,
+0x6b, 0xe1, 0x74, 0xe1, 0x74, 0xfa, 0x25b, 0x3b, 0x6d, 0x65, 0x73, 0x69, 0x14b, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20,
+0xfa, 0x20, 0x6b, 0xe9, 0x6e, 0x69, 0x65, 0x3b, 0x65, 0x6e, 0x73, 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0xf3, 0x6c, 0x69, 0x20,
+0xfa, 0x20, 0x6b, 0xe1, 0x74, 0xe1, 0x6e, 0x75, 0x25b, 0x3b, 0x254, 0x73, 0x254, 0x6e, 0x3b, 0x65, 0x66, 0x75, 0x74, 0x65,
+0x3b, 0x70, 0x69, 0x73, 0x75, 0x79, 0xfa, 0x3b, 0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x254, 0x73, 0x3b,
+0x69, 0x6d, 0x25b, 0x14b, 0x20, 0x69, 0x20, 0x70, 0x75, 0x74, 0xfa, 0x6b, 0x2c, 0x6f, 0xf3, 0x6c, 0x69, 0x20, 0xfa, 0x20,
+0x6b, 0xe1, 0x74, 0xed, 0x25b, 0x3b, 0x6d, 0x61, 0x6b, 0x61, 0x6e, 0x64, 0x69, 0x6b, 0x25b, 0x3b, 0x70, 0x69, 0x6c, 0x254,
+0x6e, 0x64, 0x254, 0x301, 0x3b, 0x58, 0x69, 0x6e, 0x3b, 0x46, 0x65, 0x62, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x41, 0x62, 0x72,
+0x3b, 0x4d, 0x61, 0x79, 0x3b, 0x58, 0x75, 0x6e, 0x3b, 0x58, 0x6e, 0x74, 0x3b, 0x41, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x74,
+0x3b, 0x4f, 0x63, 0x68, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x41, 0x76, 0x69, 0x3b, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b,
+0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x7a, 0x75, 0x3b, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b,
+0x6d, 0x61, 0x79, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x75, 0x3b, 0x78, 0x75, 0x6e, 0x65, 0x74, 0x75, 0x3b, 0x61, 0x67, 0x6f,
+0x73, 0x74, 0x75, 0x3b, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x6f, 0x63, 0x68, 0x6f, 0x62, 0x72,
+0x65, 0x3b, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x61, 0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x58, 0x3b,
+0x46, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x58, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x4f, 0x3b, 0x50, 0x3b,
+0x41, 0x3b, 0x78, 0x69, 0x6e, 0x3b, 0x66, 0x65, 0x62, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x61, 0x62, 0x72, 0x3b, 0x6d, 0x61,
+0x79, 0x3b, 0x78, 0x75, 0x6e, 0x3b, 0x78, 0x6e, 0x74, 0x3b, 0x61, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x74, 0x3b, 0x6f, 0x63,
+0x68, 0x3b, 0x70, 0x61, 0x79, 0x3b, 0x61, 0x76, 0x69, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x69, 0x6e, 0x65, 0x72, 0x75, 0x3b,
+0x64, 0x65, 0x20, 0x66, 0x65, 0x62, 0x72, 0x65, 0x72, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x7a, 0x75, 0x3b,
+0x64, 0x27, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x3b, 0x64, 0x65, 0x20, 0x6d, 0x61, 0x79, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78,
+0x75, 0x6e, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x78, 0x75, 0x6e, 0x65, 0x74, 0x75, 0x3b, 0x64, 0x27, 0x61, 0x67, 0x6f, 0x73,
+0x74, 0x75, 0x3b, 0x64, 0x65, 0x20, 0x73, 0x65, 0x74, 0x69, 0x65, 0x6d, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x27, 0x6f, 0x63,
+0x68, 0x6f, 0x62, 0x72, 0x65, 0x3b, 0x64, 0x65, 0x20, 0x70, 0x61, 0x79, 0x61, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x27, 0x61,
+0x76, 0x69, 0x65, 0x6e, 0x74, 0x75, 0x3b, 0x4e, 0x64, 0x75, 0x14b, 0x6d, 0x62, 0x69, 0x20, 0x53, 0x61, 0x14b, 0x3b, 0x50,
+0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x70, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301,
+0x74, 0xe1, 0x74, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x6b, 0x77, 0x61, 0x3b,
+0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x61, 0x74, 0x61, 0x61, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b,
+0x301, 0x6e, 0x25b, 0x301, 0x6e, 0x74, 0xfa, 0x6b, 0xfa, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x53, 0x61, 0x61, 0x6d,
+0x62, 0xe1, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x66, 0x254, 0x6d, 0x3b, 0x50,
+0x25b, 0x73, 0x61, 0x14b, 0x20, 0x50, 0x25b, 0x301, 0x6e, 0x25b, 0x301, 0x70, 0x66, 0xfa, 0xa78b, 0xfa, 0x3b, 0x50, 0x25b, 0x73,
+0x61, 0x14b, 0x20, 0x4e, 0x25b, 0x67, 0x25b, 0x301, 0x6d, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254,
+0x30c, 0x70, 0x6d, 0x254, 0x301, 0x3b, 0x50, 0x25b, 0x73, 0x61, 0x14b, 0x20, 0x4e, 0x74, 0x73, 0x254, 0x30c, 0x70, 0x70, 0xe1,
+0x3b, 0x70, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x77, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6d, 0x62, 0x69, 0x79, 0x254, 0x20, 0x6d,
+0x25b, 0x6e, 0x64, 0x6f, 0x14b, 0x67, 0x254, 0x3b, 0x4e, 0x79, 0x254, 0x6c, 0x254, 0x6d, 0x62, 0x254, 0x14b, 0x67, 0x254, 0x3b,
+0x4d, 0x254, 0x6e, 0x254, 0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x4e, 0x79, 0x61, 0x14b, 0x67, 0x77, 0x25b,
+0x20, 0x14b, 0x67, 0x62, 0x61, 0x6e, 0x6a, 0x61, 0x3b, 0x6b, 0x75, 0x14b, 0x67, 0x77, 0x25b, 0x3b, 0x66, 0x25b, 0x3b, 0x6e,
+0x6a, 0x61, 0x70, 0x69, 0x3b, 0x6e, 0x79, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x31, 0x31, 0x3b, 0x253, 0x75, 0x6c, 0x253, 0x75,
+0x73, 0x25b, 0x3b, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0xe0, 0x62, 0xf9, 0x62,
+0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75, 0x62, 0x69, 0x3b, 0x69, 0x6d, 0x259,
+0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x66, 0x6f, 0x67, 0x3b, 0x69, 0x6d,
+0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0xe0, 0x64, 0xf9,
+0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x6b, 0x61, 0x3b, 0x69, 0x6d,
+0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8, 0x73, 0x69, 0x2bc, 0x65, 0x3b, 0x69,
+0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65, 0x64, 0x3b,
+0x69, 0x6d, 0x259, 0x67, 0x20, 0x6d, 0x62, 0x65, 0x67, 0x74, 0x75, 0x67, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0xe0, 0x62,
+0xf9, 0x62, 0xec, 0x3b, 0x69, 0x6d, 0x65, 0x67, 0x20, 0x6d, 0x62, 0x259, 0x14b, 0x63, 0x68, 0x75, 0x62, 0x69, 0x3b, 0x69,
+0x6d, 0x259, 0x67, 0x20, 0x6e, 0x67, 0x77, 0x259, 0x300, 0x74, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x66, 0x6f, 0x67, 0x3b,
+0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x69, 0x62, 0x254, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0xe0,
+0x64, 0xf9, 0x6d, 0x62, 0x259, 0x300, 0x14b, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x69, 0x63, 0x68, 0x69, 0x6b, 0x61, 0x3b,
+0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x75, 0x64, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x74, 0xe8, 0x73, 0x69, 0x2bc, 0x65,
+0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x7a, 0xf2, 0x3b, 0x69, 0x6d, 0x259, 0x67, 0x20, 0x6b, 0x72, 0x69, 0x7a, 0x6d, 0x65,
+0x64, 0x3b, 0x4d, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x4d, 0x33, 0x3b, 0x4e, 0x34, 0x3b, 0x46, 0x35, 0x3b, 0x49, 0x36, 0x3b,
+0x41, 0x37, 0x3b, 0x49, 0x38, 0x3b, 0x4b, 0x39, 0x3b, 0x31, 0x30, 0x3b, 0x31, 0x31, 0x3b, 0x31, 0x32, 0x3b, 0x73, 0x61,
+0x14b, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0xf9, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6b,
+0xe0, 0x67, 0x20, 0x6e, 0x67, 0x77, 0xf3, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6c, 0x65, 0x70, 0x79, 0xe8, 0x20, 0x73,
+0x68, 0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0x73, 0x25b, 0x300,
+0x25b, 0x20, 0x63, 0xff, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, 0x6a, 0xff, 0x6f, 0x6c, 0xe1, 0x2bc, 0x3b, 0x73, 0x61,
+0x14b, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x74, 0x79, 0x25b, 0x300, 0x62, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x3b, 0x73,
+0x61, 0x14b, 0x20, 0x6d, 0x62, 0x289, 0x300, 0x14b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6e, 0x67, 0x77, 0x254, 0x300, 0x2bc, 0x20,
+0x6d, 0x62, 0xff, 0x25b, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x74, 0xe0, 0x14b, 0x61, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0xe1,
+0x2bc, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6d, 0x65, 0x6a, 0x77, 0x6f, 0x14b, 0xf3, 0x3b, 0x73, 0x61, 0x14b, 0x20, 0x6c, 0xf9,
+0x6d, 0x3b, 0x57, 0x69, 0xf3, 0x74, 0x68, 0x65, 0x21f, 0x69, 0x6b, 0x61, 0x20, 0x57, 0xed, 0x3b, 0x54, 0x68, 0x69, 0x79,
+0xf3, 0x21f, 0x65, 0x79, 0x75, 0x14b, 0x6b, 0x61, 0x20, 0x57, 0xed, 0x3b, 0x49, 0x161, 0x74, 0xe1, 0x77, 0x69, 0x10d, 0x68,
+0x61, 0x79, 0x61, 0x7a, 0x61, 0x14b, 0x20, 0x57, 0xed, 0x3b, 0x50, 0x21f, 0x65, 0x17e, 0xed, 0x74, 0x21f, 0x6f, 0x20, 0x57,
+0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, 0x65, 0x74, 0x21f, 0x6f, 0x20, 0x57, 0xed, 0x3b, 0x57, 0xed, 0x70,
+0x61, 0x7a, 0x75, 0x6b, 0x21f, 0x61, 0x2d, 0x77, 0x61, 0x161, 0x74, 0xe9, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b,
+0x70, 0x21f, 0xe1, 0x73, 0x61, 0x70, 0x61, 0x20, 0x57, 0xed, 0x3b, 0x57, 0x61, 0x73, 0xfa, 0x74, 0x21f, 0x75, 0x14b, 0x20,
+0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61, 0x14b, 0x77, 0xe1, 0x70, 0x65, 0x1e7, 0x69, 0x20, 0x57, 0xed, 0x3b, 0x10c, 0x68, 0x61,
+0x14b, 0x77, 0xe1, 0x70, 0x65, 0x2d, 0x6b, 0x61, 0x73, 0x6e, 0xe1, 0x20, 0x57, 0xed, 0x3b, 0x57, 0x61, 0x6e, 0xed, 0x79,
+0x65, 0x74, 0x75, 0x20, 0x57, 0xed, 0x3b, 0x54, 0x21f, 0x61, 0x68, 0xe9, 0x6b, 0x61, 0x70, 0x161, 0x75, 0x14b, 0x20, 0x57,
+0xed, 0x3b
};
static const ushort days_data[] = {
@@ -3462,8 +3530,8 @@ static const ushort days_data[] = {
0x627, 0x62b, 0x646, 0x64a, 0x646, 0x3b, 0x627, 0x644, 0x62b, 0x644, 0x627, 0x62b, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x623, 0x631, 0x628,
0x639, 0x627, 0x621, 0x3b, 0x627, 0x644, 0x62e, 0x645, 0x64a, 0x633, 0x3b, 0x627, 0x644, 0x62c, 0x645, 0x639, 0x629, 0x3b, 0x627, 0x644,
0x633, 0x628, 0x62a, 0x3b, 0x62d, 0x3b, 0x646, 0x3b, 0x62b, 0x3b, 0x631, 0x3b, 0x62e, 0x3b, 0x62c, 0x3b, 0x633, 0x3b, 0x56f, 0x56b,
-0x580, 0x3b, 0x565, 0x580, 0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x578, 0x580, 0x3b, 0x570, 0x576, 0x563, 0x3b, 0x578, 0x582,
-0x580, 0x3b, 0x577, 0x561, 0x562, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565, 0x580, 0x56f, 0x578, 0x582, 0x577, 0x561,
+0x580, 0x3b, 0x565, 0x580, 0x56f, 0x3b, 0x565, 0x580, 0x584, 0x3b, 0x579, 0x580, 0x584, 0x3b, 0x570, 0x576, 0x563, 0x3b, 0x578, 0x582,
+0x580, 0x3b, 0x577, 0x562, 0x569, 0x3b, 0x56f, 0x56b, 0x580, 0x561, 0x56f, 0x56b, 0x3b, 0x565, 0x580, 0x56f, 0x578, 0x582, 0x577, 0x561,
0x562, 0x569, 0x56b, 0x3b, 0x565, 0x580, 0x565, 0x584, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x579, 0x578, 0x580, 0x565, 0x584, 0x577,
0x561, 0x562, 0x569, 0x56b, 0x3b, 0x570, 0x56b, 0x576, 0x563, 0x577, 0x561, 0x562, 0x569, 0x56b, 0x3b, 0x578, 0x582, 0x580, 0x562, 0x561,
0x569, 0x3b, 0x577, 0x561, 0x562, 0x561, 0x569, 0x3b, 0x53f, 0x3b, 0x535, 0x3b, 0x535, 0x3b, 0x549, 0x3b, 0x540, 0x3b, 0x548, 0x582,
@@ -3480,1036 +3548,1061 @@ static const ushort days_data[] = {
0x430, 0x440, 0x20, 0x435, 0x440, 0x442, 0x4d9, 0x441, 0x438, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x20, 0x430,
0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x447, 0x4d9, 0x440, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x20,
0x430, 0x445, 0x448, 0x430, 0x43c, 0x44b, 0x3b, 0x4b9, 0x4af, 0x43c, 0x4d9, 0x3b, 0x448, 0x4d9, 0x43d, 0x431, 0x4d9, 0x3b, 0x69, 0x67,
-0x3b, 0x61, 0x6c, 0x3b, 0x61, 0x73, 0x3b, 0x61, 0x7a, 0x3b, 0x6f, 0x67, 0x3b, 0x6f, 0x72, 0x3b, 0x6c, 0x72, 0x3b, 0x69,
-0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61, 0x73,
-0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x6f,
-0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x69, 0x72, 0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61, 0x72,
-0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x49,
-0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x3b, 0x9b8,
-0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4,
-0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8,
-0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be,
-0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac,
-0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x9c1, 0x3b,
-0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42,
-0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49, 0xf72,
-0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b,
-0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b,
-0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42,
-0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b,
-0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62, 0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xfb6, 0x3b,
-0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72, 0x3b, 0x73, 0x75, 0x6c, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x65, 0x75, 0x2e,
-0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x79, 0x61, 0x6f, 0x75, 0x3b, 0x67, 0x77, 0x65, 0x2e, 0x3b, 0x73, 0x61, 0x64, 0x2e,
-0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x4d, 0x65, 0x72, 0x63,
-0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61, 0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x53, 0x61, 0x64,
-0x6f, 0x72, 0x6e, 0x3b, 0x73, 0x75, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x7a, 0x3b, 0x6d, 0x63, 0x3b, 0x79, 0x61, 0x3b, 0x67,
-0x77, 0x3b, 0x73, 0x61, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b,
-0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b,
-0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, 0x447, 0x435,
-0x442, 0x432, 0x44a, 0x440, 0x442, 0x44a, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, 0x442, 0x430,
-0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x432, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x1014, 0x103d, 0x1031, 0x3b, 0x101c,
-0x102c, 0x3b, 0x1002, 0x102b, 0x3b, 0x101f, 0x1030, 0x1038, 0x3b, 0x1010, 0x1031, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x3b, 0x1014, 0x1031, 0x3b,
-0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014, 0x103d, 0x1031, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x101c, 0x102c, 0x3b, 0x1021, 0x1004,
-0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f, 0x1012, 0x1039, 0x1013, 0x101f, 0x1030, 0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x101e, 0x1015, 0x1010,
-0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000, 0x103c, 0x102c, 0x3b, 0x1005, 0x1014, 0x1031, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b,
-0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005, 0x3b, 0x43d, 0x434, 0x3b, 0x43f, 0x43d, 0x3b, 0x430, 0x45e, 0x3b, 0x441, 0x440, 0x3b,
-0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x430, 0x43d,
-0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a, 0x3b, 0x430, 0x45e, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x430,
-0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x456, 0x446, 0x430, 0x3b, 0x441, 0x443,
-0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x430, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x17a2,
-0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x1793, 0x17d2, 0x1791, 0x3b, 0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796,
-0x17bb, 0x1792, 0x3b, 0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7, 0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b,
-0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x64,
-0x67, 0x3b, 0x64, 0x6c, 0x3b, 0x64, 0x74, 0x3b, 0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64, 0x73, 0x3b,
-0x44, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, 0x44, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x44, 0x69, 0x6d,
-0x61, 0x72, 0x74, 0x73, 0x3b, 0x44, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65, 0x73, 0x3b, 0x44, 0x69, 0x6a, 0x6f, 0x75, 0x73,
-0x3b, 0x44, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x44, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b,
-0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, 0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64, 0x63, 0x2e, 0x3b, 0x64, 0x6a, 0x2e, 0x3b,
-0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, 0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x65, 0x3b, 0x64, 0x69, 0x6c,
-0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65,
-0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, 0x73, 0x3b, 0x64, 0x69, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x64,
-0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468, 0x4e00, 0x3b, 0x5468, 0x4e8c, 0x3b, 0x5468, 0x4e09, 0x3b,
-0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b, 0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5, 0x3b, 0x661f, 0x671f, 0x4e00, 0x3b, 0x661f, 0x671f, 0x4e8c,
-0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f, 0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94, 0x3b, 0x661f, 0x671f, 0x516d, 0x3b, 0x65e5, 0x3b, 0x4e00,
-0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, 0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031, 0x65e5, 0x3b, 0x9031, 0x4e00, 0x3b, 0x9031, 0x4e8c, 0x3b,
-0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b, 0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b,
-0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b,
-0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x6b,
-0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76,
-0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b,
-0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b,
-0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b, 0xfa, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x10d, 0x74,
-0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c, 0x65, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x11b, 0x6c,
-0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72, 0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x74, 0x76, 0x72, 0x74,
-0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b,
-0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0x61, 0x6e, 0x3b, 0x74, 0x69,
-0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf8, 0x72, 0x3b, 0x73, 0xf8,
-0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b,
-0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61,
-0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x46,
-0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e, 0x3b, 0x74, 0x69, 0x72, 0x2e, 0x3b, 0x6f, 0x6e,
-0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e, 0x3b, 0x6c, 0xf8, 0x72, 0x2e, 0x3b, 0x7a, 0x6f,
-0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f, 0x3b, 0x76, 0x72, 0x3b, 0x7a, 0x61, 0x3b, 0x7a,
-0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x69, 0x6e, 0x73, 0x64, 0x61,
-0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67,
-0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, 0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x5a, 0x3b,
-0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0x3b, 0xd801,
-0xdc23, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc13, 0xd801, 0xdc2d, 0xd801, 0xdc46, 0x3b, 0xd801, 0xdc0e, 0xd801, 0xdc2f, 0xd801, 0xdc4c, 0x3b,
-0xd801, 0xdc1b, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc49, 0xd801, 0xdc34, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc30, 0xd801, 0xdc3b,
-0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0xd801, 0xdc3c,
-0xd801, 0xdc29, 0x3b, 0xd801, 0xdc13, 0xd801, 0xdc2d, 0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc0e, 0xd801, 0xdc2f, 0xd801, 0xdc4c,
-0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc1b, 0xd801, 0xdc32, 0xd801, 0xdc49, 0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b,
-0xd801, 0xdc19, 0xd801, 0xdc49, 0xd801, 0xdc34, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc30, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801,
-0xdc49, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc1d, 0x3b, 0xd801, 0xdc23, 0x3b, 0xd801, 0xdc13, 0x3b, 0xd801, 0xdc0e, 0x3b, 0xd801, 0xdc1b,
-0x3b, 0xd801, 0xdc19, 0x3b, 0xd801, 0xdc1d, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x4c,
-0x3b, 0x70, 0xfc, 0x68, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73, 0x6d, 0x61, 0x73, 0x70, 0xe4, 0x65, 0x76, 0x3b,
-0x74, 0x65, 0x69, 0x73, 0x69, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f, 0x6c, 0x6d, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b,
-0x6e, 0x65, 0x6c, 0x6a, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65, 0x65, 0x64, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x70,
-0xe4, 0x65, 0x76, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b, 0x74, 0xfd, 0x73, 0x3b, 0x6d, 0x69, 0x6b, 0x3b,
-0x68, 0xf3, 0x73, 0x3b, 0x66, 0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67,
-0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x74, 0xfd, 0x73, 0x64, 0x61, 0x67, 0x75,
-0x72, 0x3b, 0x6d, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x68, 0xf3, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72,
-0x3b, 0x66, 0x72, 0xed, 0x67, 0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x65, 0x79, 0x67, 0x61, 0x72,
-0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x46, 0x3b, 0x4c, 0x3b,
-0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b, 0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61,
-0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69,
-0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f,
-0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6c,
-0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b,
-0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e,
-0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b,
-0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b,
-0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69,
-0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65,
-0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e, 0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69,
-0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d,
-0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65,
-0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b,
-0x56, 0x3b, 0x53, 0x3b, 0x44, 0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b, 0x44, 0x69, 0x4d, 0x3b, 0x44, 0x69, 0x43, 0x3b,
-0x44, 0x69, 0x61, 0x3b, 0x44, 0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b, 0x44, 0x69, 0x44, 0xf2, 0x6d, 0x68, 0x6e, 0x61,
-0x69, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x4d, 0xe0, 0x69, 0x72, 0x74, 0x3b,
-0x44, 0x69, 0x43, 0x69, 0x61, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b,
-0x44, 0x69, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x65,
-0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x3b, 0x4c,
-0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0xe9, 0x72, 0x3b, 0x58, 0x6f, 0x76, 0x3b, 0x56, 0x65, 0x6e, 0x3b, 0x53,
-0xe1, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74,
-0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x65,
-0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b,
-0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7,
-0x10ee, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b,
-0x10dd, 0x10e0, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd,
-0x10d7, 0x10ee, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de,
-0x10d0, 0x10e0, 0x10d0, 0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b,
-0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8, 0x3b, 0x53, 0x6f, 0x3b, 0x4d, 0x6f, 0x3b, 0x44, 0x69, 0x3b, 0x4d,
-0x69, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d,
-0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77,
-0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x69, 0x74,
-0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x4d, 0x3b, 0x44,
-0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e,
-0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5,
-0x3b, 0x3a4, 0x3c1, 0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2,
-0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4, 0x3ad, 0x3c1, 0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af,
-0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3c0, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1,
-0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1, 0x3c4, 0x3bf, 0x3b, 0x39a, 0x3b, 0x394, 0x3b,
-0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x61, 0x74, 0x61, 0x3b, 0x6d, 0x61,
-0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x61, 0x6c, 0x3b, 0x61, 0x72, 0x66, 0x3b, 0x73, 0x61,
-0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b,
-0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x70, 0x69, 0x6e, 0x67, 0x61, 0x73,
-0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x73, 0x69, 0x73, 0x61, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f,
-0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71,
-0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x53, 0x3b, 0x41, 0x3b,
-0x4d, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0xab0, 0xab5, 0xabf, 0x3b, 0xab8, 0xacb, 0xaae, 0x3b, 0xaae, 0xa82,
-0xa97, 0xab3, 0x3b, 0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0x3b, 0xab6, 0xaa8,
-0xabf, 0x3b, 0xab0, 0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5, 0xabe, 0xab0, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3,
-0xab5, 0xabe, 0xab0, 0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6,
-0xac1, 0xa95, 0xacd, 0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab0, 0x3b, 0xab8, 0xacb, 0x3b,
-0xaae, 0xa82, 0x3b, 0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b, 0xab6, 0xac1, 0x3b, 0xab6, 0x3b, 0x4c, 0x68, 0x3b, 0x4c, 0x69, 0x3b,
-0x54, 0x61, 0x3b, 0x4c, 0x72, 0x3b, 0x41, 0x6c, 0x3b, 0x4a, 0x75, 0x3b, 0x41, 0x73, 0x3b, 0x4c, 0x61, 0x68, 0x61, 0x64,
-0x69, 0x3b, 0x4c, 0x69, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x4c, 0x61, 0x72,
-0x61, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x6d, 0x61, 0x27, 0x61, 0x3b,
-0x41, 0x73, 0x61, 0x62, 0x61, 0x72, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x41,
-0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d0, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d2,
-0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20,
-0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5, 0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd,
-0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8,
-0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9,
-0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b, 0x5d1, 0x5f3, 0x3b, 0x5d2, 0x5f3,
-0x3b, 0x5d3, 0x5f3, 0x3b, 0x5d4, 0x5f3, 0x3b, 0x5d5, 0x3b, 0x5e9, 0x3b, 0x5d0, 0x27, 0x3b, 0x5d1, 0x27, 0x3b, 0x5d2, 0x27, 0x3b,
-0x5d3, 0x27, 0x3b, 0x5d4, 0x27, 0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935, 0x93f, 0x2e, 0x3b, 0x938, 0x94b, 0x92e,
-0x2e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x2e, 0x3b, 0x92c, 0x941, 0x927, 0x2e, 0x3b, 0x92c, 0x943, 0x939, 0x2e, 0x3b, 0x936, 0x941,
-0x915, 0x94d, 0x930, 0x2e, 0x3b, 0x936, 0x928, 0x93f, 0x2e, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e,
-0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x92c,
-0x943, 0x939, 0x938, 0x94d, 0x92a, 0x924, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b,
-0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941,
-0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x65, 0x3b, 0x43, 0x73, 0x3b, 0x50,
-0x3b, 0x53, 0x7a, 0x6f, 0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61, 0x70, 0x3b, 0x68, 0xe9, 0x74, 0x66, 0x151, 0x3b,
-0x6b, 0x65, 0x64, 0x64, 0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b, 0x63, 0x73, 0xfc, 0x74, 0xf6, 0x72, 0x74, 0xf6,
-0x6b, 0x3b, 0x70, 0xe9, 0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x56, 0x3b, 0x48,
-0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1,
-0x6e, 0x3b, 0xfe, 0x72, 0x69, 0x3b, 0x6d, 0x69, 0xf0, 0x3b, 0x66, 0x69, 0x6d, 0x3b, 0x66, 0xf6, 0x73, 0x3b, 0x6c, 0x61,
-0x75, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75, 0x64, 0x61, 0x67,
-0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0xf0, 0x76, 0x69,
-0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b,
-0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67,
-0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0xfe, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4d,
-0x3b, 0xde, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53,
-0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d,
-0x69, 0x6e, 0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52,
-0x61, 0x62, 0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74,
-0x75, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b,
-0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x6a, 0x6f, 0x76, 0x3b, 0x76, 0x65, 0x6e, 0x3b,
-0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0x69, 0x3b,
-0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x64, 0x69, 0x3b, 0x6a, 0x6f,
-0x76, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x62, 0x62, 0x61, 0x74, 0x6f,
-0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x3b, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61,
-0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9,
-0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x67, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b,
-0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x44, 0xe9, 0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e,
-0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65,
-0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43,
-0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d,
-0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x65, 0x6e,
-0x69, 0x63, 0x61, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x4d,
-0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x47, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x56, 0x65, 0x6e,
-0x65, 0x72, 0x64, 0xec, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b,
-0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64,
-0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b,
-0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61, 0x62, 0x61,
-0x74, 0x6f, 0x3b, 0x65e5, 0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b, 0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5,
-0x3b, 0x6708, 0x66dc, 0x65e5, 0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc, 0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5,
-0x3b, 0x571f, 0x66dc, 0x65e5, 0x3b, 0xcb0, 0x2e, 0x3b, 0xcb8, 0xccb, 0x2e, 0x3b, 0xcae, 0xc82, 0x2e, 0x3b, 0xcac, 0xcc1, 0x2e, 0x3b,
-0xc97, 0xcc1, 0x2e, 0x3b, 0xcb6, 0xcc1, 0x2e, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x2e, 0x3b, 0xcb0, 0xcb5, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b,
-0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7, 0xcb5, 0xcbe,
-0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6,
-0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb0, 0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82, 0x3b, 0xcac, 0xcc1, 0x3b, 0xc97, 0xcc1, 0x3b,
-0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, 0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x655, 0x631, 0x648,
-0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631,
-0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627,
-0x64e, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631, 0x655, 0x631, 0x648, 0x627, 0x631, 0x3b, 0x628,
-0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea, 0x633,
-0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x3b, 0x698, 0x3b, 0x628,
-0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x62c, 0x3b, 0x628, 0x3b, 0x436, 0x441, 0x2e, 0x3b, 0x434, 0x441, 0x2e, 0x3b, 0x441, 0x441, 0x2e,
-0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x431, 0x441, 0x2e, 0x3b, 0x436, 0x43c, 0x2e, 0x3b, 0x441, 0x4bb, 0x2e, 0x3b, 0x436, 0x435, 0x43a,
-0x441, 0x435, 0x43d, 0x456, 0x3b, 0x434, 0x443, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x435, 0x439, 0x441, 0x435, 0x43d,
-0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x431, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b,
-0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x63, 0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e,
-0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e,
-0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75, 0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75,
-0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69,
-0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61,
-0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20,
-0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x416, 0x43a, 0x2e, 0x3b, 0x414, 0x448, 0x2e, 0x3b, 0x428, 0x435,
-0x2e, 0x3b, 0x428, 0x430, 0x2e, 0x3b, 0x411, 0x448, 0x2e, 0x3b, 0x416, 0x43c, 0x2e, 0x3b, 0x418, 0x448, 0x2e, 0x3b, 0x416, 0x435,
-0x43a, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x414, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x428, 0x435, 0x439, 0x448,
-0x435, 0x43c, 0x431, 0x438, 0x3b, 0x428, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x411, 0x435, 0x439, 0x448, 0x435, 0x43c,
-0x431, 0x438, 0x3b, 0x416, 0x443, 0x43c, 0x430, 0x3b, 0x418, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x436, 0x43a, 0x2e, 0x3b, 0x434,
-0x448, 0x2e, 0x3b, 0x448, 0x435, 0x2e, 0x3b, 0x448, 0x430, 0x2e, 0x3b, 0x431, 0x448, 0x2e, 0x3b, 0x436, 0x43c, 0x2e, 0x3b, 0x438,
-0x448, 0x2e, 0x3b, 0x436, 0x435, 0x43a, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x434, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af,
-0x3b, 0x448, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x448, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x431,
-0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x438, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b,
-0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0, 0x3b, 0xc77c, 0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694,
-0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c, 0x3b, 0xae08, 0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694,
-0xc77c, 0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62, 0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e,
-0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64, 0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77,
-0x27, 0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6d, 0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b,
-0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61,
-0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77,
-0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e,
-0x64, 0x61, 0x74, 0x75, 0x3b, 0xe97, 0x2e, 0x3b, 0xe88, 0x2e, 0x3b, 0xead, 0x2e, 0x3b, 0xe9e, 0x2e, 0x3b, 0xe9e, 0xeab, 0x2e,
-0x3b, 0xeaa, 0xe81, 0x2e, 0x3b, 0xeaa, 0x2e, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99,
-0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb8, 0xe94,
-0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b, 0xea7, 0xeb1, 0xe99,
-0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xe97, 0x3b, 0xe88, 0x3b, 0xe84, 0x3b, 0x200b, 0xe9e, 0xeb8, 0x3b, 0xe9e, 0x3b, 0x200b, 0xeaa, 0xeb8,
-0x3b, 0xeaa, 0x3b, 0xead, 0xeb2, 0x2e, 0x3b, 0xe88, 0x2e, 0x3b, 0xead, 0x2e, 0x3b, 0xe9e, 0x2e, 0x3b, 0xe9e, 0xeab, 0x2e, 0x3b,
-0xeaa, 0xe81, 0x2e, 0x3b, 0xeaa, 0x2e, 0x3b, 0x53, 0x76, 0x3b, 0x50, 0x72, 0x3b, 0x4f, 0x74, 0x3b, 0x54, 0x72, 0x3b, 0x43,
-0x65, 0x3b, 0x50, 0x6b, 0x3b, 0x53, 0x65, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69,
-0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x54, 0x72, 0x65,
-0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50,
-0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b,
-0x53, 0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69,
-0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65,
-0x6e, 0x61, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64,
-0x69, 0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74,
-0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, 0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73,
-0x74, 0x3b, 0x6d, 0x69, 0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61,
-0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f,
-0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254,
-0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254,
-0x20, 0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20,
-0x6d, 0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b,
-0x6d, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, 0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b,
-0x6b, 0x74, 0x3b, 0x70, 0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73,
-0x3b, 0x70, 0x69, 0x72, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69,
-0x65, 0x6e, 0x69, 0x73, 0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65,
-0x74, 0x76, 0x69, 0x72, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64,
-0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b,
-0x50, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d,
-0x2e, 0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e,
-0x3b, 0x441, 0x430, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b,
-0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435,
-0x442, 0x432, 0x440, 0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430, 0x3b,
-0x41, 0x6c, 0x61, 0x68, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x3b,
-0x41, 0x6c, 0x61, 0x6b, 0x3b, 0x5a, 0x6f, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x64,
-0x79, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61,
-0x3b, 0x41, 0x6c, 0x61, 0x72, 0x6f, 0x62, 0x69, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, 0x73, 0x79, 0x3b,
-0x5a, 0x6f, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x54, 0x3b,
-0x41, 0x3b, 0x41, 0x3b, 0x5a, 0x3b, 0x41, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b,
-0x52, 0x61, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64,
-0x3b, 0x49, 0x73, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b,
-0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41,
-0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, 0x3b, 0xd24, 0xd3f,
-0xd19, 0xd4d, 0xd15, 0xd7e, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e,
-0xd34, 0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34,
-0xd4d, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e,
-0xd34, 0xd4d, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e, 0xd34,
-0xd4d, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0xd1a, 0x3b, 0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e,
-0xd34, 0xd4d, 0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c, 0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e,
-0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b, 0x45, 0x72,
-0x62, 0x3b, 0x126, 0x61, 0x6d, 0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x64,
-0x64, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65, 0x74, 0x61,
-0x3b, 0x4c, 0x2d, 0x45, 0x72, 0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x49,
-0x6c, 0x2d, 0x120, 0x69, 0x6d, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x126, 0x3b, 0x54,
-0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x126, 0x3b, 0x120, 0x3b, 0x53, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e,
-0x902, 0x917, 0x933, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936,
-0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917,
-0x933, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b,
-0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x41d, 0x44f, 0x3b, 0x414,
-0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x43d, 0x44f, 0x43c,
-0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, 0x445, 0x430, 0x433, 0x432, 0x430,
-0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, 0x44f, 0x43c, 0x431, 0x430, 0x3b,
-0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x92c, 0x93f,
-0x939, 0x940, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906, 0x907, 0x924, 0x92c, 0x93e, 0x930, 0x3b,
-0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x92c,
-0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x940, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x92c, 0x93e, 0x930, 0x3b,
-0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x967, 0x3b, 0x968, 0x3b, 0x969, 0x3b, 0x96a, 0x3b, 0x96b, 0x3b, 0x96c, 0x3b, 0x96d,
-0x3b, 0x906, 0x907, 0x924, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932,
-0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x940, 0x935, 0x93e, 0x930, 0x3b, 0x936,
-0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d,
-0x61, 0x2e, 0x3b, 0x74, 0x69, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c,
-0xf8, 0x2e, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, 0x3b, 0xb2c, 0xb41, 0xb27,
-0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0x3b, 0xb30, 0xb2c, 0xb3f, 0xb2c,
-0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17, 0xb33, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2c,
-0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0xb2c,
-0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b, 0xb38, 0xb4b, 0x3b, 0xb2e, 0x3b, 0xb2c, 0xb41, 0x3b,
-0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62f, 0x648, 0x634, 0x646, 0x628,
-0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647, 0x627, 0x631, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x67e,
-0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x6cc, 0x3b, 0x62f,
-0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x2e, 0x3b, 0x70, 0x6f,
-0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77, 0x2e, 0x3b, 0x70, 0x74, 0x2e, 0x3b,
-0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x69, 0x65,
-0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x15b, 0x72, 0x6f, 0x64, 0x61,
-0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62,
-0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x64, 0x6f,
-0x6d, 0x3b, 0x73, 0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x3b, 0x73, 0x65,
-0x78, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x73, 0x65, 0x67, 0x75, 0x6e, 0x64,
-0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b,
-0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d,
-0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0xe1,
-0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x44,
-0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x53, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61,
-0x3b, 0x54, 0x65, 0x72, 0xe7, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x51, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d,
-0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x51, 0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x53,
-0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0xa10, 0xa24,
-0x2e, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x2e, 0x3b, 0xa2c, 0xa41, 0xa27, 0x2e, 0x3b, 0xa35, 0xa40,
-0xa30, 0x2e, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa15, 0xa30, 0x2e, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa40, 0x2e, 0x3b, 0xa10, 0xa24, 0xa35, 0xa3e,
-0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2c, 0xa41, 0xa27,
-0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30,
-0x3b, 0xa38, 0xa3c, 0xa28, 0xa40, 0xa1a, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa10, 0x3b, 0xa38, 0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c,
-0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0x3b, 0xa38, 0xa3c, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b,
-0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x64f, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a,
-0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x64, 0x75, 0x3b, 0x67, 0x6c, 0x69, 0x3b, 0x6d, 0x61,
-0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f, 0x3b, 0x64, 0x75, 0x6d, 0x65, 0x6e, 0x67,
-0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d,
-0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69, 0x61, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x65,
-0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b,
-0x56, 0x3b, 0x53, 0x3b, 0x44, 0x75, 0x3b, 0x4c, 0x75, 0x3b, 0x4d, 0x61, 0x3b, 0x4d, 0x69, 0x3b, 0x4a, 0x6f, 0x3b, 0x56,
-0x69, 0x3b, 0x53, 0xe2, 0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d,
-0x61, 0x72, 0x21b, 0x69, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69,
-0x6e, 0x65, 0x72, 0x69, 0x3b, 0x73, 0xe2, 0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x412, 0x441, 0x3b, 0x41f, 0x43d, 0x3b, 0x412,
-0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442, 0x3b, 0x41f, 0x442, 0x3b, 0x421, 0x431, 0x3b, 0x412, 0x43e, 0x441, 0x43a, 0x440, 0x435,
-0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x41f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x412, 0x442,
-0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x421, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x427, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b,
-0x41f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x421, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, 0x41f, 0x3b,
-0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x432, 0x441, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441,
-0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d,
-0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d,
-0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x43f, 0x44f, 0x442,
-0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b, 0x32,
-0x3b, 0x42, 0x6b, 0x33, 0x3b, 0x42, 0x6b, 0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2, 0x79,
-0x3b, 0x42, 0x69, 0x6b, 0x75, 0x61, 0x2d, 0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73, 0x65,
-0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73, 0xef,
-0xf6, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b, 0x4c,
-0xe2, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x59,
-0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442,
-0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435,
-0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447,
-0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430,
-0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b, 0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70,
-0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73,
-0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61,
-0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72,
-0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434,
-0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442,
-0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430,
-0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442,
-0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425,
-0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b, 0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c,
-0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b, 0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443,
-0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446,
-0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x41c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e,
-0x43d, 0x3b, 0x421, 0x430, 0x431, 0x430, 0x442, 0x3b, 0x425, 0x3b, 0x41a, 0x3b, 0x414, 0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b,
-0x421, 0x3b, 0x445, 0x446, 0x431, 0x3b, 0x43a, 0x440, 0x441, 0x3b, 0x434, 0x446, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f,
-0x440, 0x3b, 0x43c, 0x440, 0x431, 0x3b, 0x441, 0x431, 0x442, 0x3b, 0x445, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b,
-0x43a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b, 0x434, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442,
-0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x446, 0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5,
-0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x441, 0x430, 0x431, 0x430, 0x442, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x6d, 0x61, 0x3b, 0x42,
-0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x6f, 0x71, 0x3b, 0x53, 0x6f,
-0x6e, 0x74, 0x61, 0x68, 0x61, 0x3b, 0x4d, 0x6d, 0x61, 0x6e, 0x74, 0x61, 0x68, 0x61, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62,
-0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b,
-0x4c, 0x61, 0x62, 0x6f, 0x68, 0x6c, 0x61, 0x6e, 0x65, 0x3b, 0x4d, 0x6f, 0x71, 0x65, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x54,
-0x73, 0x68, 0x3b, 0x4d, 0x6f, 0x73, 0x3b, 0x42, 0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c,
-0x61, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x54, 0x73, 0x68, 0x69, 0x70, 0x69, 0x3b, 0x4d, 0x6f, 0x73, 0x6f, 0x70, 0x75, 0x6c,
-0x6f, 0x67, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62, 0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72,
-0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x6f, 0x3b,
-0x4d, 0x61, 0x74, 0x6c, 0x68, 0x61, 0x74, 0x73, 0x6f, 0x3b, 0x53, 0x76, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68,
-0x69, 0x70, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x3b, 0x4d, 0x75,
-0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e, 0x64, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x68, 0x75, 0x72, 0x6f, 0x3b, 0x43, 0x68, 0x69,
-0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x43,
-0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x3b, 0x53, 0x3b, 0x4d,
-0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x4d, 0x3b, 0xd89, 0xdbb, 0xdd2, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0x3b, 0xd85,
-0xd9f, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0x3b, 0xdc3, 0xdd9, 0xdb1,
-0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0xdbb, 0xdd4, 0xdc0, 0xdcf,
-0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0xdb4, 0xdad, 0xdd2, 0xdb1,
-0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0xdc3, 0xdd4, 0xdbb, 0xdcf,
-0xdaf, 0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0x3b, 0xdc3, 0xdd2, 0x3b, 0xdc3,
-0xdd9, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x73, 0x61, 0x3b, 0x4e, 0x65,
-0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x63, 0x3b, 0x4c, 0x69, 0x73, 0x6f, 0x6e, 0x74, 0x66, 0x6f, 0x3b, 0x75, 0x4d,
-0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c,
-0x65, 0x73, 0x69, 0x74, 0x73, 0x61, 0x74, 0x66, 0x75, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x65, 0x73,
-0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x75, 0x4d, 0x67, 0x63, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x6e, 0x65, 0x3b,
-0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161, 0x74, 0x3b, 0x70, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65,
-0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x6c, 0x6f, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6b,
-0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, 0x70, 0x69, 0x61, 0x74,
-0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x160, 0x3b,
-0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x73, 0x72, 0x65, 0x3b,
-0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x3b,
-0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73, 0x72, 0x65,
-0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62,
-0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b, 0x6e, 0x65,
-0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b, 0x10d, 0x65,
-0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49, 0x73, 0x6e,
-0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53, 0x61, 0x62,
-0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61, 0x64, 0x6f,
-0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69, 0x6d, 0x63,
-0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b,
-0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0xe9, 0x3b, 0x6a, 0x75,
-0x65, 0x3b, 0x76, 0x69, 0x65, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75,
-0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73,
-0x3b, 0x6a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61,
-0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x4a, 0x32, 0x3b,
-0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a,
-0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d,
-0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69,
-0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32,
-0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x31, 0x3b, 0x53, 0xf6, 0x6e, 0x3b, 0x4d, 0xe5, 0x6e,
-0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4f, 0x6e, 0x73, 0x3b, 0x54, 0x6f, 0x72, 0x3b, 0x46, 0x72, 0x65, 0x3b, 0x4c, 0xf6, 0x72,
-0x3b, 0x53, 0xf6, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x54, 0x69, 0x73, 0x64, 0x61,
-0x67, 0x3b, 0x4f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x65,
-0x64, 0x61, 0x67, 0x3b, 0x4c, 0xf6, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf6, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74,
-0x69, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0xf6, 0x72, 0x3b,
-0x73, 0xf6, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x69, 0x73, 0x64, 0x61, 0x67,
-0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64,
-0x61, 0x67, 0x3b, 0x6c, 0xf6, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x42f, 0x448, 0x431, 0x3b, 0x414, 0x448, 0x431, 0x3b, 0x421, 0x448,
-0x431, 0x3b, 0x427, 0x448, 0x431, 0x3b, 0x41f, 0x448, 0x431, 0x3b, 0x4b6, 0x43c, 0x44a, 0x3b, 0x428, 0x43d, 0x431, 0x3b, 0x42f, 0x43a,
-0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x414, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x421, 0x435, 0x448, 0x430, 0x43d, 0x431,
-0x435, 0x3b, 0x427, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x41f, 0x430, 0x43d, 0x4b7, 0x448, 0x430, 0x43d, 0x431, 0x435,
-0x3b, 0x4b6, 0x443, 0x43c, 0x44a, 0x430, 0x3b, 0x428, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0xb9e, 0xbbe, 0x3b, 0xba4, 0xbbf, 0x3b, 0xb9a,
-0xbc6, 0x3b, 0xbaa, 0xbc1, 0x3b, 0xbb5, 0xbbf, 0x3b, 0xbb5, 0xbc6, 0x3b, 0xb9a, 0x3b, 0xb9e, 0xbbe, 0xbaf, 0xbbf, 0xbb1, 0xbc1, 0x3b,
-0xba4, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbb5, 0xbcd, 0xbb5, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0xbaa, 0xbc1, 0xba4,
-0xba9, 0xbcd, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0xbb4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbc6, 0xbb3, 0xbcd, 0xbb3, 0xbbf, 0x3b, 0xb9a, 0xba9,
-0xbbf, 0x3b, 0xc06, 0xc26, 0xc3f, 0x3b, 0xc38, 0xc4b, 0xc2e, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0x3b, 0xc2c, 0xc41, 0xc27, 0x3b, 0xc17,
-0xc41, 0xc30, 0xc41, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0x3b, 0xc36, 0xc28, 0xc3f, 0x3b, 0xc06, 0xc26, 0xc3f, 0xc35, 0xc3e, 0xc30,
-0xc02, 0x3b, 0xc38, 0xc4b, 0xc2e, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2c,
-0xc41, 0xc27, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d,
-0xc30, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc28, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc06, 0x3b, 0xc38, 0xc4b, 0x3b, 0xc2e,
-0x3b, 0xc2c, 0xc41, 0x3b, 0xc17, 0xc41, 0x3b, 0xc36, 0xc41, 0x3b, 0xc36, 0x3b, 0xe2d, 0xe32, 0x2e, 0x3b, 0xe08, 0x2e, 0x3b, 0xe2d,
-0x2e, 0x3b, 0xe1e, 0x2e, 0x3b, 0xe1e, 0xe24, 0x2e, 0x3b, 0xe28, 0x2e, 0x3b, 0xe2a, 0x2e, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe32,
-0xe17, 0xe34, 0xe15, 0xe22, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe08, 0xe31, 0xe19, 0xe17, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d,
-0xe31, 0xe07, 0xe04, 0xe32, 0xe23, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe38, 0xe18, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe24, 0xe2b, 0xe31,
-0xe2a, 0xe1a, 0xe14, 0xe35, 0x3b, 0xe27, 0xe31, 0xe19, 0xe28, 0xe38, 0xe01, 0xe23, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe40, 0xe2a, 0xe32,
-0xe23, 0xe4c, 0x3b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51,
-0xf58, 0xf62, 0xf0b, 0x3b, 0xf67, 0xfb3, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf66,
-0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58,
-0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b,
-0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf67, 0xfb3, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b,
-0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60,
-0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0x3b, 0xf67, 0xfb3,
-0x3b, 0xf55, 0xf74, 0x3b, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0x3b, 0xf67,
-0xfb3, 0xf42, 0x3b, 0xf55, 0xf74, 0x3b, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230, 0x1291, 0x12ed,
-0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240, 0x12f3, 0x121d,
-0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1283, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b,
-0x1230, 0x1291, 0x12ed, 0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b,
-0x1240, 0x12f3, 0x121d, 0x3b, 0x53, 0x101, 0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x16b, 0x73, 0x3b, 0x50, 0x75, 0x6c, 0x3b,
-0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46, 0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74, 0x65, 0x3b,
-0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x16b, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65, 0x6c, 0x75,
-0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61, 0x6c, 0x61,
-0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f, 0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b, 0x50,
-0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x42, 0x69, 0x72, 0x3b, 0x48,
-0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b,
-0x4d, 0x75, 0x73, 0x75, 0x6d, 0x62, 0x68, 0x75, 0x6e, 0x75, 0x6b, 0x75, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6d, 0x62, 0x69,
-0x72, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x68, 0x61, 0x72, 0x68, 0x75, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6d,
-0x75, 0x6e, 0x65, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x71,
-0x69, 0x76, 0x65, 0x6c, 0x61, 0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0xc7, 0x61,
-0x72, 0x3b, 0x50, 0x65, 0x72, 0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x3b,
-0x50, 0x61, 0x7a, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72, 0x15f, 0x61,
-0x6d, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b, 0x43, 0x75,
-0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b, 0x43, 0x3b,
-0x43, 0x3b, 0x41d, 0x434, 0x3b, 0x41f, 0x43d, 0x3b, 0x412, 0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442, 0x3b, 0x41f, 0x442, 0x3b,
-0x421, 0x431, 0x3b, 0x41d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x41f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, 0x43a, 0x3b,
-0x412, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x421, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x427, 0x435, 0x442, 0x432,
-0x435, 0x440, 0x3b, 0x41f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x421, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x41d,
-0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e,
-0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c,
-0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x42f, 0x43a, 0x448, 0x3b, 0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448,
-0x3b, 0x427, 0x43e, 0x440, 0x3b, 0x41f, 0x430, 0x439, 0x3b, 0x416, 0x443, 0x43c, 0x3b, 0x428, 0x430, 0x43d, 0x3b, 0x44f, 0x43a, 0x448,
-0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x441, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430,
-0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43f, 0x430, 0x439, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x436,
-0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x42f, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b,
-0x416, 0x3b, 0x428, 0x3b, 0x6cc, 0x2e, 0x3b, 0x62f, 0x2e, 0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, 0x3b, 0x67e, 0x2e, 0x3b, 0x62c,
-0x2e, 0x3b, 0x634, 0x2e, 0x3b, 0x59, 0x61, 0x6b, 0x73, 0x68, 0x3b, 0x44, 0x75, 0x73, 0x68, 0x3b, 0x53, 0x65, 0x73, 0x68,
-0x3b, 0x43, 0x68, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x53, 0x68, 0x61, 0x6e, 0x3b, 0x79,
-0x61, 0x6b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x73, 0x65,
-0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x70, 0x61,
-0x79, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b,
-0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x53, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68, 0x20,
-0x32, 0x3b, 0x54, 0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x20,
-0x36, 0x3b, 0x54, 0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x6e, 0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9, 0x20,
-0x68, 0x61, 0x69, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x62, 0x61, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x74, 0x1b0, 0x3b, 0x54, 0x68,
-0x1ee9, 0x20, 0x6e, 0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x73, 0xe1, 0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x62, 0x1ea3,
-0x79, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, 0x33, 0x3b, 0x54, 0x34, 0x3b, 0x54, 0x35, 0x3b, 0x54, 0x36, 0x3b,
-0x54, 0x37, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b,
-0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c,
-0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72,
-0x74, 0x68, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64,
-0x20, 0x49, 0x61, 0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64,
-0x64, 0x20, 0x53, 0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b,
-0x47, 0x3b, 0x53, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72,
-0x3b, 0x49, 0x61, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x43, 0x61, 0x77, 0x3b, 0x4d, 0x76,
-0x75, 0x3b, 0x42, 0x69, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67,
-0x71, 0x3b, 0x43, 0x61, 0x77, 0x65, 0x3b, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69,
-0x6e, 0x69, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69,
-0x6e, 0x65, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65,
-0x6c, 0x6f, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b,
-0x1ecc, 0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62,
-0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
-0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc,
-0x6a, 0x1ecd, 0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74,
-0xec, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x3b,
-0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b,
-0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f,
-0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74,
-0x68, 0x75, 0x3b, 0x75, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61,
-0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b,
-0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x79, 0x73, 0x3b, 0x6f, 0x6e,
-0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67,
-0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61,
-0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0x61, 0x75,
-0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, 0x2e, 0x3b, 0x74, 0x79, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e,
-0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61, 0x2e, 0x3b, 0x4a, 0x65, 0x64, 0x3b, 0x4a, 0x65, 0x6c,
-0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65, 0x68, 0x3b, 0x4a,
-0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f, 0x6f, 0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65, 0x69, 0x6e, 0x3b,
-0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a, 0x65, 0x72, 0x64,
-0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68, 0x65, 0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61, 0x72, 0x6e, 0x3b,
-0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59, 0x6f, 0x77, 0x3b,
-0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x65, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x65, 0x20, 0x4c, 0x75,
-0x6e, 0x3b, 0x44, 0x65, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x65, 0x20, 0x4d, 0x65, 0x72, 0x68, 0x65, 0x72,
-0x3b, 0x44, 0x65, 0x20, 0x59, 0x6f, 0x77, 0x3b, 0x44, 0x65, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x65,
-0x20, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42, 0x65, 0x6e, 0x3b,
-0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61, 0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b, 0x77, 0x65, 0x73,
-0x69, 0x64, 0x61, 0x3b, 0x44, 0x77, 0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x3b, 0x57, 0x75,
-0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59, 0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x65,
-0x6e, 0x65, 0x64, 0x61, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b, 0x4d, 0x3b, 0x906,
-0x926, 0x93f, 0x924, 0x94d, 0x92f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x933,
-0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941,
-0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd,
-0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x3b, 0x53,
-0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x64, 0x65, 0x3b, 0x54,
-0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x7a,
-0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x1ecd, 0x64, 0x65, 0x65, 0x3b,
-0x57, 0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b, 0x57, 0x74, 0x169, 0x3b, 0x57, 0x6b, 0x6e, 0x3b,
-0x57, 0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x79, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x57, 0x61,
-0x20, 0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x65, 0x6c, 0x129,
-0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x57,
-0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74, 0x68, 0x61, 0x74,
-0x169, 0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x1230, 0x2f, 0x1245, 0x3b,
-0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d, 0x3b, 0x1208, 0x1313, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265, 0x3b, 0x1230, 0x2f,
-0x123d, 0x3b, 0x1230, 0x1295, 0x1260, 0x122d, 0x20, 0x1245, 0x12f3, 0x12c5, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d, 0x3b, 0x1208, 0x1313,
-0x20, 0x12c8, 0x122a, 0x20, 0x1208, 0x1265, 0x12cb, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265, 0x3b, 0x1230, 0x1295, 0x1260, 0x122d,
-0x20, 0x123d, 0x1313, 0x12c5, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1208, 0x3b, 0x12a3, 0x3b, 0x12a3, 0x3b, 0x1230, 0x3b, 0x1230,
-0x2f, 0x12d3, 0x3b, 0x1230, 0x1296, 0x3b, 0x1273, 0x120b, 0x1238, 0x3b, 0x12a3, 0x1228, 0x122d, 0x3b, 0x12a8, 0x121a, 0x123d, 0x3b, 0x1305, 0x121d,
-0x12d3, 0x3b, 0x1230, 0x2f, 0x1295, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x20, 0x12d3, 0x1263, 0x12ed, 0x3b, 0x1230, 0x1296, 0x3b, 0x1273, 0x120b,
-0x1238, 0x1296, 0x3b, 0x12a3, 0x1228, 0x122d, 0x1263, 0x12d3, 0x3b, 0x12a8, 0x121a, 0x123d, 0x3b, 0x1305, 0x121d, 0x12d3, 0x1275, 0x3b, 0x1230, 0x1295,
-0x1260, 0x1275, 0x20, 0x1295, 0x12a2, 0x123d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1273, 0x3b, 0x12a3, 0x3b, 0x12a8, 0x3b, 0x1305, 0x3b, 0x1230,
-0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, 0x6a, 0x6f, 0x69,
-0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b, 0x6c, 0x75, 0x6e,
-0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75, 0x73, 0x3b, 0x6a,
-0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64, 0x65, 0x3b, 0x53,
-0x77, 0x6f, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x56, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x1e4a, 0x61, 0x3b, 0x1e70, 0x61,
-0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x77, 0x6f, 0x6e, 0x64, 0x61, 0x68, 0x61, 0x3b, 0x4d, 0x75, 0x73, 0x75, 0x6d,
-0x62, 0x75, 0x6c, 0x75, 0x77, 0x6f, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x69, 0x6c, 0x69, 0x3b, 0x1e3c, 0x61,
-0x76, 0x68, 0x75, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x1e4b, 0x61, 0x3b, 0x1e3c, 0x61, 0x76, 0x68,
-0x75, 0x1e71, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x69, 0x76, 0x68, 0x65, 0x6c, 0x61, 0x3b, 0x6b, 0x254, 0x73, 0x3b,
-0x64, 0x7a, 0x6f, 0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61, 0x77, 0x3b, 0x66, 0x69, 0x256, 0x3b,
-0x6d, 0x65, 0x6d, 0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f, 0x256, 0x61, 0x3b, 0x62, 0x6c, 0x61,
-0x256, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61, 0x3b, 0x66, 0x69, 0x256, 0x61, 0x3b,
-0x6d, 0x65, 0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6b, 0x3b, 0x79, 0x3b, 0x66, 0x3b,
-0x6d, 0x3b, 0x12c8, 0x130b, 0x3b, 0x1233, 0x12ed, 0x1296, 0x3b, 0x121b, 0x1246, 0x1233, 0x129b, 0x3b, 0x12a0, 0x1229, 0x12cb, 0x3b, 0x1203, 0x1219,
-0x1233, 0x3b, 0x12a0, 0x122d, 0x1263, 0x3b, 0x1244, 0x122b, 0x3b, 0x12c8, 0x3b, 0x1233, 0x3b, 0x121b, 0x3b, 0x12a0, 0x3b, 0x1203, 0x3b, 0x12a0,
-0x3b, 0x1244, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, 0x50, 0x34, 0x3b, 0x50, 0x35,
-0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x61, 0x68, 0x69, 0x3b,
-0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, 0x75, 0x3b, 0x50, 0x6f, 0x2bb,
-0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6f, 0x6e, 0x6f,
-0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0x79, 0x3b, 0x48, 0x75, 0x77,
-0x3b, 0x42, 0x69, 0x79, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x65,
-0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b, 0x75, 0x6c, 0x65, 0x73, 0x3b,
-0x48, 0x75, 0x77, 0x65, 0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x62,
-0x61, 0x64, 0x6f, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4c, 0x69,
-0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x79, 0x65, 0x3b, 0x48, 0x75, 0x77, 0x3b, 0x42, 0x79,
-0x65, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e, 0x3b, 0x4d, 0x69,
-0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x69,
-0x67, 0x3b, 0x4d, 0xe4, 0xe4, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b,
-0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0x46,
-0x72, 0x69, 0x69, 0x74, 0x69, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0xa46d, 0xa18f, 0x3b,
-0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8, 0x3b, 0xa46d, 0xa18f,
-0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd, 0x3b, 0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6, 0x3b, 0xa18f, 0xa282,
-0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8, 0x3b, 0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c, 0x3b, 0xa0d8, 0x3b,
-0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4e, 0x65, 0x3b, 0x48,
-0x6c, 0x61, 0x3b, 0x47, 0x71, 0x69, 0x3b, 0x75, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x75, 0x4d, 0x76, 0x75, 0x6c, 0x6f,
-0x3b, 0x75, 0x4c, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68,
-0x75, 0x3b, 0x75, 0x4c, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x6e, 0x67, 0x6f, 0x4c, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61,
-0x6e, 0x75, 0x3b, 0x75, 0x6d, 0x47, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x6f, 0x73,
-0x3b, 0x42, 0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b,
-0x53, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x61, 0x3b, 0x4d, 0x6f, 0x73, 0x75, 0x70, 0x61, 0x6c, 0x6f, 0x67, 0x6f, 0x3b, 0x4c,
-0x61, 0x62, 0x6f, 0x62, 0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72, 0x6f, 0x3b, 0x4c, 0x61, 0x62,
-0x6f, 0x6e, 0x65, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x68, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x6f, 0x6b, 0x69, 0x62, 0x65,
-0x6c, 0x6f, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b, 0x3b, 0x67, 0x61, 0x73,
-0x6b, 0x3b, 0x64, 0x75, 0x6f, 0x72, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x73, 0x6f, 0x74, 0x6e,
-0x61, 0x62, 0x65, 0x61, 0x69, 0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x6d, 0x61,
-0x14b, 0x14b, 0x65, 0x62, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75,
-0x3b, 0x64, 0x75, 0x6f, 0x72, 0x61, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74,
-0x3b, 0x6c, 0xe1, 0x76, 0x76, 0x61, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x44,
-0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x61, 0x65, 0x6a, 0x6c, 0x65, 0x67, 0x65, 0x3b, 0x6d, 0xe5, 0x61, 0x6e, 0x74, 0x61, 0x3b,
-0x64, 0xe4, 0x6a, 0x73, 0x74, 0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x65, 0x76, 0x61, 0x68, 0x6b, 0x6f, 0x65, 0x3b, 0x64,
-0xe5, 0x61, 0x72, 0x73, 0x74, 0x61, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x68, 0x6b, 0x65, 0x3b, 0x6c,
-0x61, 0x61, 0x76, 0x61, 0x64, 0x61, 0x68, 0x6b, 0x65, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b,
-0x42, 0x3b, 0x4c, 0x3b, 0x43, 0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b,
-0x41, 0x72, 0x73, 0x3b, 0x49, 0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72,
-0x69, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65,
-0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49,
-0x63, 0x68, 0x75, 0x6d, 0x61, 0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b,
-0x43, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b,
-0x4b, 0x61, 0x64, 0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b,
-0x75, 0x20, 0x6a, 0x61, 0x20, 0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20,
-0x6a, 0x69, 0x6d, 0x77, 0x65, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77,
-0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75,
-0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61,
-0x20, 0x6b, 0x61, 0x73, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f,
-0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61,
-0x61, 0x253, 0x3b, 0x6d, 0x61, 0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68,
-0x62, 0x69, 0x3b, 0x64, 0x65, 0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61,
-0x61, 0x72, 0x65, 0x3b, 0x6e, 0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61,
-0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69,
-0x72, 0x3b, 0x64, 0x3b, 0x61, 0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b,
-0x4e, 0x54, 0x54, 0x3b, 0x4e, 0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b,
-0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169,
-0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b,
-0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d,
-0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e,
-0x3b, 0x41, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65,
-0x3b, 0x53, 0x61, 0x70, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61,
-0x72, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64,
-0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72,
-0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65,
-0x20, 0x69, 0x6c, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b,
-0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b,
-0x49, 0x3b, 0x49, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b,
-0x54, 0x61, 0x74, 0x3b, 0x4e, 0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69,
-0x6e, 0x67, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b,
-0x43, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68,
-0x61, 0x6e, 0x75, 0x3b, 0x53, 0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e,
-0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74,
-0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d,
-0x76, 0x75, 0x6c, 0x6f, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75,
-0x3b, 0x53, 0x69, 0x6e, 0x65, 0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65,
-0x6c, 0x6f, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70,
-0x3b, 0x49, 0x6a, 0x74, 0x3b, 0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a,
-0x75, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d,
-0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61,
-0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61,
-0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36,
-0x3b, 0x37, 0x3b, 0x31, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55,
-0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30,
-0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59,
-0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30,
-0x2d59, 0x3b, 0x61, 0x73, 0x61, 0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b,
-0x77, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61,
-0x79, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b,
-0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b,
-0x59, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d,
-0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e,
-0x61, 0x73, 0x73, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53,
-0x61, 0x6d, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73,
-0x3b, 0x59, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f,
-0x52, 0x4b, 0x3b, 0x4f, 0x4b, 0x42, 0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f,
-0x4d, 0x4b, 0x3b, 0x53, 0x61, 0x6e, 0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61,
-0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68,
-0x61, 0x74, 0x75, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74,
-0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b,
-0x3b, 0x52, 0x3b, 0x53, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48,
-0x69, 0x76, 0x3b, 0x48, 0x69, 0x64, 0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70,
-0x61, 0x20, 0x6d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69,
-0x6c, 0x75, 0x68, 0x61, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69,
-0x64, 0x61, 0x74, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69,
-0x68, 0x61, 0x6e, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61,
-0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a,
-0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a,
-0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74,
-0x75, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b,
+0x2e, 0x3b, 0x61, 0x6c, 0x2e, 0x3b, 0x61, 0x72, 0x2e, 0x3b, 0x61, 0x7a, 0x2e, 0x3b, 0x6f, 0x67, 0x2e, 0x3b, 0x6f, 0x72,
+0x2e, 0x3b, 0x6c, 0x72, 0x2e, 0x3b, 0x69, 0x67, 0x61, 0x6e, 0x64, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x6c, 0x65,
+0x68, 0x65, 0x6e, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61, 0x72, 0x74, 0x65, 0x61, 0x3b, 0x61, 0x73, 0x74, 0x65, 0x61,
+0x7a, 0x6b, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x65, 0x67, 0x75, 0x6e, 0x61, 0x3b, 0x6f, 0x73, 0x74, 0x69, 0x72,
+0x61, 0x6c, 0x61, 0x3b, 0x6c, 0x61, 0x72, 0x75, 0x6e, 0x62, 0x61, 0x74, 0x61, 0x3b, 0x49, 0x3b, 0x41, 0x3b, 0x41, 0x3b,
+0x41, 0x3b, 0x4f, 0x3b, 0x4f, 0x3b, 0x4c, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x3b, 0x9ae, 0x999, 0x9cd, 0x997,
+0x9b2, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b8, 0x9cd, 0x9aa, 0x9a4, 0x9bf, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0,
+0x3b, 0x9b6, 0x9a8, 0x9bf, 0x3b, 0x9b0, 0x9ac, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x9ae, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ae,
+0x999, 0x9cd, 0x997, 0x9b2, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c1, 0x9a7, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9ac, 0x9c3, 0x9b9, 0x9b7, 0x9cd,
+0x9aa, 0x9a4, 0x9bf, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9c1, 0x995, 0x9cd, 0x9b0, 0x9ac, 0x9be, 0x9b0, 0x3b, 0x9b6, 0x9a8, 0x9bf, 0x9ac,
+0x9be, 0x9b0, 0x3b, 0x9b0, 0x3b, 0x9b8, 0x9cb, 0x3b, 0x9ae, 0x3b, 0x9ac, 0x9c1, 0x3b, 0x9ac, 0x9c3, 0x3b, 0x9b6, 0x9c1, 0x3b, 0x9b6,
+0x3b, 0xf5f, 0xfb3, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf62, 0xf0b, 0x3b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0x3b,
+0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0x3b, 0xf49, 0xf72, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f,
+0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72, 0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f,
+0xf60, 0xf0b, 0xf63, 0xfb7, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b,
+0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf54, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53,
+0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0xf62,
+0x3b, 0xf63, 0xfb7, 0xf42, 0x3b, 0xf55, 0xf74, 0xf62, 0x3b, 0xf66, 0xf44, 0xfb6, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0x3b, 0xf49, 0xf72,
+0x3b, 0x73, 0x75, 0x6c, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x65, 0x75, 0x2e, 0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x79,
+0x61, 0x6f, 0x75, 0x3b, 0x67, 0x77, 0x65, 0x2e, 0x3b, 0x73, 0x61, 0x64, 0x2e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75,
+0x6e, 0x3b, 0x4d, 0x65, 0x75, 0x72, 0x7a, 0x68, 0x3b, 0x4d, 0x65, 0x72, 0x63, 0x2bc, 0x68, 0x65, 0x72, 0x3b, 0x59, 0x61,
+0x6f, 0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x73, 0x75, 0x3b,
+0x6c, 0x75, 0x3b, 0x6d, 0x7a, 0x3b, 0x6d, 0x63, 0x3b, 0x79, 0x61, 0x3b, 0x67, 0x77, 0x3b, 0x73, 0x61, 0x3b, 0x43d, 0x434,
+0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d,
+0x435, 0x434, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e,
+0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x44f, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x44a, 0x440, 0x442, 0x44a, 0x43a,
+0x3b, 0x43f, 0x435, 0x442, 0x44a, 0x43a, 0x3b, 0x441, 0x44a, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x432, 0x3b,
+0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x1010, 0x1014, 0x1004, 0x103a, 0x1039, 0x1002, 0x1014, 0x103d, 0x1031, 0x3b, 0x1010, 0x1014,
+0x1004, 0x103a, 0x1039, 0x101c, 0x102c, 0x3b, 0x1021, 0x1004, 0x103a, 0x1039, 0x1002, 0x102b, 0x3b, 0x1017, 0x102f, 0x1012, 0x1039, 0x1013, 0x101f, 0x1030,
+0x1038, 0x3b, 0x1000, 0x103c, 0x102c, 0x101e, 0x1015, 0x1010, 0x1031, 0x1038, 0x3b, 0x101e, 0x1031, 0x102c, 0x1000, 0x103c, 0x102c, 0x3b, 0x1005, 0x1014,
+0x1031, 0x3b, 0x1010, 0x3b, 0x1010, 0x3b, 0x1021, 0x3b, 0x1017, 0x3b, 0x1000, 0x3b, 0x101e, 0x3b, 0x1005, 0x3b, 0x43d, 0x434, 0x3b, 0x43f,
+0x43d, 0x3b, 0x430, 0x45e, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x446, 0x3b, 0x43f, 0x442, 0x3b, 0x441, 0x431, 0x3b, 0x43d, 0x44f, 0x434,
+0x437, 0x435, 0x43b, 0x44f, 0x3b, 0x43f, 0x430, 0x43d, 0x44f, 0x434, 0x437, 0x435, 0x43b, 0x430, 0x43a, 0x3b, 0x430, 0x45e, 0x442, 0x43e,
+0x440, 0x430, 0x43a, 0x3b, 0x441, 0x435, 0x440, 0x430, 0x434, 0x430, 0x3b, 0x447, 0x430, 0x446, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x44f,
+0x442, 0x43d, 0x456, 0x446, 0x430, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x430, 0x3b, 0x441,
+0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x17a2, 0x17b6, 0x1791, 0x17b7, 0x178f, 0x17d2, 0x1799, 0x3b, 0x1785, 0x1793, 0x17d2, 0x1791, 0x3b,
+0x17a2, 0x1784, 0x17d2, 0x1782, 0x17b6, 0x179a, 0x3b, 0x1796, 0x17bb, 0x1792, 0x3b, 0x1796, 0x17d2, 0x179a, 0x17a0, 0x179f, 0x17d2, 0x1794, 0x178f, 0x17b7,
+0x17cd, 0x3b, 0x179f, 0x17bb, 0x1780, 0x17d2, 0x179a, 0x3b, 0x179f, 0x17c5, 0x179a, 0x17cd, 0x3b, 0x31, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34,
+0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x64, 0x67, 0x2e, 0x3b, 0x64, 0x6c, 0x2e, 0x3b, 0x64, 0x74, 0x2e, 0x3b, 0x64,
+0x63, 0x2e, 0x3b, 0x64, 0x6a, 0x2e, 0x3b, 0x64, 0x76, 0x2e, 0x3b, 0x64, 0x73, 0x2e, 0x3b, 0x64, 0x69, 0x75, 0x6d, 0x65,
+0x6e, 0x67, 0x65, 0x3b, 0x64, 0x69, 0x6c, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x72, 0x74, 0x73, 0x3b,
+0x64, 0x69, 0x6d, 0x65, 0x63, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x6a, 0x6f, 0x75, 0x73, 0x3b, 0x64, 0x69, 0x76, 0x65,
+0x6e, 0x64, 0x72, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x73, 0x73, 0x61, 0x62, 0x74, 0x65, 0x3b, 0x64, 0x67, 0x3b, 0x64, 0x6c,
+0x3b, 0x64, 0x74, 0x3b, 0x64, 0x63, 0x3b, 0x64, 0x6a, 0x3b, 0x64, 0x76, 0x3b, 0x64, 0x73, 0x3b, 0x5468, 0x65e5, 0x3b, 0x5468,
+0x4e00, 0x3b, 0x5468, 0x4e8c, 0x3b, 0x5468, 0x4e09, 0x3b, 0x5468, 0x56db, 0x3b, 0x5468, 0x4e94, 0x3b, 0x5468, 0x516d, 0x3b, 0x661f, 0x671f, 0x65e5,
+0x3b, 0x661f, 0x671f, 0x4e00, 0x3b, 0x661f, 0x671f, 0x4e8c, 0x3b, 0x661f, 0x671f, 0x4e09, 0x3b, 0x661f, 0x671f, 0x56db, 0x3b, 0x661f, 0x671f, 0x4e94,
+0x3b, 0x661f, 0x671f, 0x516d, 0x3b, 0x65e5, 0x3b, 0x4e00, 0x3b, 0x4e8c, 0x3b, 0x4e09, 0x3b, 0x56db, 0x3b, 0x4e94, 0x3b, 0x516d, 0x3b, 0x9031,
+0x65e5, 0x3b, 0x9031, 0x4e00, 0x3b, 0x9031, 0x4e8c, 0x3b, 0x9031, 0x4e09, 0x3b, 0x9031, 0x56db, 0x3b, 0x9031, 0x4e94, 0x3b, 0x9031, 0x516d, 0x3b,
+0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b, 0x73, 0x72, 0x69, 0x3b, 0x10d, 0x65, 0x74, 0x3b,
+0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e,
+0x65, 0x64, 0x6a, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61, 0x6b, 0x3b, 0x73, 0x72, 0x69, 0x6a,
+0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x61, 0x6b, 0x3b, 0x73,
+0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x75, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b,
+0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x3b,
+0xfa, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x10d, 0x74, 0x3b, 0x70, 0xe1, 0x3b, 0x73, 0x6f, 0x3b, 0x6e, 0x65, 0x64, 0x11b, 0x6c,
+0x65, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x11b, 0x6c, 0xed, 0x3b, 0xfa, 0x74, 0x65, 0x72, 0xfd, 0x3b, 0x73, 0x74, 0x159, 0x65,
+0x64, 0x61, 0x3b, 0x10d, 0x74, 0x76, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0xe1, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62,
+0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0xda, 0x3b, 0x53, 0x3b, 0x10c, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0xf8,
+0x6e, 0x3b, 0x6d, 0x61, 0x6e, 0x3b, 0x74, 0x69, 0x72, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72,
+0x65, 0x3b, 0x6c, 0xf8, 0x72, 0x3b, 0x73, 0xf8, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x67, 0x3b,
+0x74, 0x69, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64,
+0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf8, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d,
+0x3b, 0x54, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0xf8, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x6e, 0x2e,
+0x3b, 0x74, 0x69, 0x72, 0x2e, 0x3b, 0x6f, 0x6e, 0x73, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x66, 0x72, 0x65, 0x2e,
+0x3b, 0x6c, 0xf8, 0x72, 0x2e, 0x3b, 0x7a, 0x6f, 0x3b, 0x6d, 0x61, 0x3b, 0x64, 0x69, 0x3b, 0x77, 0x6f, 0x3b, 0x64, 0x6f,
+0x3b, 0x76, 0x72, 0x3b, 0x7a, 0x61, 0x3b, 0x7a, 0x6f, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x64, 0x61,
+0x67, 0x3b, 0x64, 0x69, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x77, 0x6f, 0x65, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x64,
+0x6f, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x76, 0x72, 0x69, 0x6a, 0x64, 0x61, 0x67, 0x3b, 0x7a, 0x61, 0x74,
+0x65, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x56, 0x3b, 0x5a, 0x3b,
+0xd801, 0xdc1d, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc23, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc13, 0xd801, 0xdc2d, 0xd801, 0xdc46,
+0x3b, 0xd801, 0xdc0e, 0xd801, 0xdc2f, 0xd801, 0xdc4c, 0x3b, 0xd801, 0xdc1b, 0xd801, 0xdc32, 0xd801, 0xdc49, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc49, 0xd801,
+0xdc34, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc30, 0xd801, 0xdc3b, 0x3b, 0xd801, 0xdc1d, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b,
+0xd801, 0xdc23, 0xd801, 0xdc32, 0xd801, 0xdc4c, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc13, 0xd801, 0xdc2d, 0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801,
+0xdc29, 0x3b, 0xd801, 0xdc0e, 0xd801, 0xdc2f, 0xd801, 0xdc4c, 0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc1b, 0xd801, 0xdc32, 0xd801,
+0xdc49, 0xd801, 0xdc46, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc19, 0xd801, 0xdc49, 0xd801, 0xdc34, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801,
+0xdc1d, 0xd801, 0xdc30, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc49, 0xd801, 0xdc3c, 0xd801, 0xdc29, 0x3b, 0xd801, 0xdc1d, 0x3b, 0xd801, 0xdc23, 0x3b,
+0xd801, 0xdc13, 0x3b, 0xd801, 0xdc0e, 0x3b, 0xd801, 0xdc1b, 0x3b, 0xd801, 0xdc19, 0x3b, 0xd801, 0xdc1d, 0x3b, 0x50, 0x3b, 0x45, 0x3b, 0x54,
+0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x52, 0x3b, 0x4c, 0x3b, 0x70, 0xfc, 0x68, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x65, 0x73,
+0x6d, 0x61, 0x73, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x74, 0x65, 0x69, 0x73, 0x69, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6b, 0x6f,
+0x6c, 0x6d, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x6e, 0x65, 0x6c, 0x6a, 0x61, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x72, 0x65,
+0x65, 0x64, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x70, 0xe4, 0x65, 0x76, 0x3b, 0x73, 0x75, 0x6e, 0x3b, 0x6d, 0xe1, 0x6e, 0x3b,
+0x74, 0xfd, 0x73, 0x3b, 0x6d, 0x69, 0x6b, 0x3b, 0x68, 0xf3, 0x73, 0x3b, 0x66, 0x72, 0xed, 0x3b, 0x6c, 0x65, 0x79, 0x3b,
+0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x61, 0x64, 0x61, 0x67, 0x75, 0x72,
+0x3b, 0x74, 0xfd, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b,
+0x68, 0xf3, 0x73, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x72, 0xed, 0x67, 0x67, 0x6a, 0x61, 0x64, 0x61, 0x67, 0x75,
+0x72, 0x3b, 0x6c, 0x65, 0x79, 0x67, 0x61, 0x72, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54, 0x3b,
+0x4d, 0x3b, 0x48, 0x3b, 0x46, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x74, 0x69, 0x3b, 0x6b, 0x65, 0x3b,
+0x74, 0x6f, 0x3b, 0x70, 0x65, 0x3b, 0x6c, 0x61, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6d,
+0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x6b, 0x65, 0x73,
+0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x74, 0x61, 0x69, 0x3b, 0x70, 0x65, 0x72,
+0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b,
+0x54, 0x3b, 0x4b, 0x3b, 0x54, 0x3b, 0x50, 0x3b, 0x4c, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+0x61, 0x3b, 0x6d, 0x61, 0x61, 0x6e, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x74, 0x69, 0x69, 0x73, 0x74, 0x61,
+0x69, 0x6e, 0x61, 0x3b, 0x6b, 0x65, 0x73, 0x6b, 0x69, 0x76, 0x69, 0x69, 0x6b, 0x6b, 0x6f, 0x6e, 0x61, 0x3b, 0x74, 0x6f,
+0x72, 0x73, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x70, 0x65, 0x72, 0x6a, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b,
+0x6c, 0x61, 0x75, 0x61, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x61, 0x3b, 0x64, 0x69, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e,
+0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x65, 0x72, 0x2e, 0x3b, 0x6a, 0x65, 0x75, 0x2e, 0x3b, 0x76, 0x65, 0x6e, 0x2e,
+0x3b, 0x73, 0x61, 0x6d, 0x2e, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69,
+0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x63, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x6a, 0x65, 0x75, 0x64,
+0x69, 0x3b, 0x76, 0x65, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x69, 0x3b, 0x44, 0x3b,
+0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x44, 0x69, 0x44, 0x3b, 0x44, 0x69, 0x4c, 0x3b,
+0x44, 0x69, 0x4d, 0x3b, 0x44, 0x69, 0x43, 0x3b, 0x44, 0x69, 0x61, 0x3b, 0x44, 0x69, 0x68, 0x3b, 0x44, 0x69, 0x53, 0x3b,
+0x44, 0x69, 0x44, 0xf2, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b,
+0x44, 0x69, 0x4d, 0xe0, 0x69, 0x72, 0x74, 0x3b, 0x44, 0x69, 0x43, 0x69, 0x61, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0x69,
+0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0x69, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0x69, 0x53,
+0x61, 0x74, 0x68, 0x61, 0x69, 0x72, 0x6e, 0x65, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x48,
+0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0xe9, 0x72, 0x3b, 0x58,
+0x6f, 0x76, 0x3b, 0x56, 0x65, 0x6e, 0x3b, 0x53, 0xe1, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c,
+0x75, 0x6e, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b,
+0x58, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b,
+0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75,
+0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0xe9, 0x72, 0x3b, 0x78, 0x6f, 0x76, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0xe1,
+0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65,
+0x73, 0x3b, 0x6d, 0xe9, 0x72, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x3b, 0x78, 0x6f, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x65, 0x6e,
+0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x10d9, 0x10d5, 0x10d8, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x3b, 0x10e1,
+0x10d0, 0x10db, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x3b, 0x10d9,
+0x10d5, 0x10d8, 0x10e0, 0x10d0, 0x3b, 0x10dd, 0x10e0, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10e1, 0x10d0, 0x10db, 0x10e8, 0x10d0, 0x10d1,
+0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10dd, 0x10d7, 0x10ee, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10ee, 0x10e3, 0x10d7, 0x10e8, 0x10d0, 0x10d1,
+0x10d0, 0x10d7, 0x10d8, 0x3b, 0x10de, 0x10d0, 0x10e0, 0x10d0, 0x10e1, 0x10d9, 0x10d4, 0x10d5, 0x10d8, 0x3b, 0x10e8, 0x10d0, 0x10d1, 0x10d0, 0x10d7, 0x10d8,
+0x3b, 0x10d9, 0x3b, 0x10dd, 0x3b, 0x10e1, 0x3b, 0x10dd, 0x3b, 0x10ee, 0x3b, 0x10de, 0x3b, 0x10e8, 0x3b, 0x53, 0x6f, 0x3b, 0x4d, 0x6f,
+0x3b, 0x44, 0x69, 0x3b, 0x4d, 0x69, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x6e,
+0x74, 0x61, 0x67, 0x3b, 0x4d, 0x6f, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x44, 0x69, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x67, 0x3b,
+0x4d, 0x69, 0x74, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x6f, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, 0x67, 0x3b,
+0x46, 0x72, 0x65, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b,
+0x44, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x53, 0x6f, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69,
+0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x6f, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x39a, 0x3c5,
+0x3c1, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3b, 0x3a0, 0x3b1,
+0x3c1, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b, 0x39a, 0x3c5, 0x3c1, 0x3b9, 0x3b1, 0x3ba, 0x3ae, 0x3b, 0x394, 0x3b5, 0x3c5, 0x3c4, 0x3ad, 0x3c1,
+0x3b1, 0x3b, 0x3a4, 0x3c1, 0x3af, 0x3c4, 0x3b7, 0x3b, 0x3a4, 0x3b5, 0x3c4, 0x3ac, 0x3c1, 0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3ad, 0x3bc, 0x3c0,
+0x3c4, 0x3b7, 0x3b, 0x3a0, 0x3b1, 0x3c1, 0x3b1, 0x3c3, 0x3ba, 0x3b5, 0x3c5, 0x3ae, 0x3b, 0x3a3, 0x3ac, 0x3b2, 0x3b2, 0x3b1, 0x3c4, 0x3bf,
+0x3b, 0x39a, 0x3b, 0x394, 0x3b, 0x3a4, 0x3b, 0x3a4, 0x3b, 0x3a0, 0x3b, 0x3a0, 0x3b, 0x3a3, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x61,
+0x74, 0x61, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x70, 0x69, 0x6e, 0x3b, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x61, 0x6c, 0x3b, 0x61,
+0x72, 0x66, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x61, 0x74, 0x3b, 0x61, 0x74, 0x61, 0x61, 0x73, 0x69, 0x6e, 0x6e, 0x67, 0x6f,
+0x72, 0x6e, 0x65, 0x71, 0x3b, 0x6d, 0x61, 0x72, 0x6c, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x70,
+0x69, 0x6e, 0x67, 0x61, 0x73, 0x75, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x73, 0x69, 0x73, 0x61, 0x6d,
+0x61, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x74, 0x61, 0x6c, 0x6c, 0x69, 0x6d, 0x61, 0x6e, 0x6e, 0x67,
+0x6f, 0x72, 0x6e, 0x65, 0x71, 0x3b, 0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x6e, 0x6e, 0x67, 0x6f, 0x72, 0x6e, 0x65, 0x71,
+0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0xab0, 0xab5, 0xabf, 0x3b, 0xab8,
+0xacb, 0xaae, 0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0x3b, 0xaac, 0xac1, 0xaa7, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1, 0x3b, 0xab6, 0xac1, 0xa95,
+0xacd, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0x3b, 0xab0, 0xab5, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b, 0xab8, 0xacb, 0xaae, 0xab5, 0xabe, 0xab0,
+0x3b, 0xaae, 0xa82, 0xa97, 0xab3, 0xab5, 0xabe, 0xab0, 0x3b, 0xaac, 0xac1, 0xaa7, 0xab5, 0xabe, 0xab0, 0x3b, 0xa97, 0xac1, 0xab0, 0xac1,
+0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xac1, 0xa95, 0xacd, 0xab0, 0xab5, 0xabe, 0xab0, 0x3b, 0xab6, 0xaa8, 0xabf, 0xab5, 0xabe, 0xab0, 0x3b,
+0xab0, 0x3b, 0xab8, 0xacb, 0x3b, 0xaae, 0xa82, 0x3b, 0xaac, 0xac1, 0x3b, 0xa97, 0xac1, 0x3b, 0xab6, 0xac1, 0x3b, 0xab6, 0x3b, 0x4c,
+0x68, 0x3b, 0x4c, 0x69, 0x3b, 0x54, 0x61, 0x3b, 0x4c, 0x72, 0x3b, 0x41, 0x6c, 0x3b, 0x4a, 0x75, 0x3b, 0x41, 0x73, 0x3b,
+0x4c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x4c, 0x69, 0x74, 0x69, 0x6e, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74,
+0x61, 0x3b, 0x4c, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d,
+0x6d, 0x61, 0x27, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x61, 0x72, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x54, 0x3b, 0x4c, 0x3b,
+0x41, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d0, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d1, 0x5f3, 0x3b,
+0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d2, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d3, 0x5f3, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d4, 0x5f3,
+0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d0, 0x5e9, 0x5d5,
+0x5df, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5e0, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5dc, 0x5d9, 0x5e9, 0x5d9, 0x3b,
+0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e8, 0x5d1, 0x5d9, 0x5e2, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5d7, 0x5de, 0x5d9, 0x5e9, 0x5d9, 0x3b,
+0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d9, 0x5e9, 0x5d9, 0x3b, 0x5d9, 0x5d5, 0x5dd, 0x20, 0x5e9, 0x5d1, 0x5ea, 0x3b, 0x5d0, 0x5f3, 0x3b,
+0x5d1, 0x5f3, 0x3b, 0x5d2, 0x5f3, 0x3b, 0x5d3, 0x5f3, 0x3b, 0x5d4, 0x5f3, 0x3b, 0x5d5, 0x5f3, 0x3b, 0x5e9, 0x5f3, 0x3b, 0x930, 0x935,
+0x93f, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b,
+0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e,
+0x935, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917,
+0x941, 0x930, 0x941, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935,
+0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x917, 0x941, 0x3b, 0x936, 0x941, 0x3b,
+0x936, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53, 0x7a, 0x65, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x6f,
+0x3b, 0x76, 0x61, 0x73, 0xe1, 0x72, 0x6e, 0x61, 0x70, 0x3b, 0x68, 0xe9, 0x74, 0x66, 0x151, 0x3b, 0x6b, 0x65, 0x64, 0x64,
+0x3b, 0x73, 0x7a, 0x65, 0x72, 0x64, 0x61, 0x3b, 0x63, 0x73, 0xfc, 0x74, 0xf6, 0x72, 0x74, 0xf6, 0x6b, 0x3b, 0x70, 0xe9,
+0x6e, 0x74, 0x65, 0x6b, 0x3b, 0x73, 0x7a, 0x6f, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x56, 0x3b, 0x48, 0x3b, 0x4b, 0x3b, 0x53,
+0x7a, 0x3b, 0x43, 0x73, 0x3b, 0x50, 0x3b, 0x53, 0x7a, 0x3b, 0x73, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0xe1, 0x6e, 0x2e, 0x3b,
+0xfe, 0x72, 0x69, 0x2e, 0x3b, 0x6d, 0x69, 0xf0, 0x2e, 0x3b, 0x66, 0x69, 0x6d, 0x2e, 0x3b, 0x66, 0xf6, 0x73, 0x2e, 0x3b,
+0x6c, 0x61, 0x75, 0x2e, 0x3b, 0x73, 0x75, 0x6e, 0x6e, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0xe1, 0x6e, 0x75,
+0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0xfe, 0x72, 0x69, 0xf0, 0x6a, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6d, 0x69,
+0xf0, 0x76, 0x69, 0x6b, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x66, 0x69, 0x6d, 0x6d, 0x74, 0x75, 0x64, 0x61, 0x67,
+0x75, 0x72, 0x3b, 0x66, 0xf6, 0x73, 0x74, 0x75, 0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x6c, 0x61, 0x75, 0x67, 0x61, 0x72,
+0x64, 0x61, 0x67, 0x75, 0x72, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0xde, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x4c, 0x3b,
+0x4d, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x4b, 0x61, 0x6d, 0x3b,
+0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4d, 0x69, 0x6e, 0x67, 0x67, 0x75, 0x3b, 0x53, 0x65, 0x6e, 0x69, 0x6e,
+0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a,
+0x75, 0x6d, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b,
+0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72,
+0x3b, 0x6a, 0x6f, 0x76, 0x3b, 0x76, 0x65, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63,
+0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72,
+0x63, 0x75, 0x72, 0x69, 0x64, 0x69, 0x3b, 0x6a, 0x6f, 0x76, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x65, 0x6e, 0x65, 0x72, 0x64,
+0x69, 0x3b, 0x73, 0x61, 0x62, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x44, 0x6f, 0x6d, 0x68, 0x3b, 0x4c, 0x75, 0x61, 0x6e, 0x3b,
+0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x43, 0xe9, 0x61, 0x64, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x3b, 0x41, 0x6f, 0x69, 0x6e,
+0x65, 0x3b, 0x53, 0x61, 0x74, 0x68, 0x3b, 0x44, 0xe9, 0x20, 0x44, 0x6f, 0x6d, 0x68, 0x6e, 0x61, 0x69, 0x67, 0x68, 0x3b,
+0x44, 0xe9, 0x20, 0x4c, 0x75, 0x61, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x20, 0x4d, 0xe1, 0x69, 0x72, 0x74, 0x3b, 0x44, 0xe9,
+0x20, 0x43, 0xe9, 0x61, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b, 0x44, 0xe9, 0x61, 0x72, 0x64, 0x61, 0x6f, 0x69, 0x6e, 0x3b,
+0x44, 0xe9, 0x20, 0x68, 0x41, 0x6f, 0x69, 0x6e, 0x65, 0x3b, 0x44, 0xe9, 0x20, 0x53, 0x61, 0x74, 0x68, 0x61, 0x69, 0x72,
+0x6e, 0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x44, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b,
+0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x67, 0x69, 0x6f, 0x3b, 0x76, 0x65, 0x6e, 0x3b,
+0x73, 0x61, 0x62, 0x3b, 0x44, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x63, 0x61, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b,
+0x4d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x4d, 0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x47, 0x69,
+0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x56, 0x65, 0x6e, 0x65, 0x72, 0x64, 0xec, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74, 0x6f,
+0x3b, 0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e,
+0x69, 0x63, 0x61, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x64, 0xec, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x64, 0xec, 0x3b, 0x6d,
+0x65, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x64, 0xec, 0x3b, 0x67, 0x69, 0x6f, 0x76, 0x65, 0x64, 0xec, 0x3b, 0x76, 0x65, 0x6e,
+0x65, 0x72, 0x64, 0xec, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x65e5, 0x3b, 0x6708, 0x3b, 0x706b, 0x3b, 0x6c34, 0x3b,
+0x6728, 0x3b, 0x91d1, 0x3b, 0x571f, 0x3b, 0x65e5, 0x66dc, 0x65e5, 0x3b, 0x6708, 0x66dc, 0x65e5, 0x3b, 0x706b, 0x66dc, 0x65e5, 0x3b, 0x6c34, 0x66dc,
+0x65e5, 0x3b, 0x6728, 0x66dc, 0x65e5, 0x3b, 0x91d1, 0x66dc, 0x65e5, 0x3b, 0x571f, 0x66dc, 0x65e5, 0x3b, 0xcb0, 0xcb5, 0xcbf, 0x3b, 0xcb8, 0xccb,
+0xcae, 0x3b, 0xcae, 0xc82, 0xc97, 0xcb3, 0x3b, 0xcac, 0xcc1, 0xca7, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd,
+0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0x3b, 0xcb0, 0xcb5, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb8, 0xccb, 0xcae, 0xcb5, 0xcbe, 0xcb0, 0x3b,
+0xcae, 0xc82, 0xc97, 0xcb3, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcac, 0xcc1, 0xca7, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xc97, 0xcc1, 0xcb0, 0xcc1, 0xcb5,
+0xcbe, 0xcb0, 0x3b, 0xcb6, 0xcc1, 0xc95, 0xccd, 0xcb0, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb6, 0xca8, 0xcbf, 0xcb5, 0xcbe, 0xcb0, 0x3b, 0xcb0,
+0x3b, 0xcb8, 0xccb, 0x3b, 0xcae, 0xc82, 0x3b, 0xcac, 0xcc1, 0x3b, 0xc97, 0xcc1, 0x3b, 0xcb6, 0xcc1, 0x3b, 0xcb6, 0x3b, 0xcb0, 0x2e,
+0x3b, 0xcb8, 0xccb, 0x2e, 0x3b, 0xcae, 0xc82, 0x2e, 0x3b, 0xcac, 0xcc1, 0x2e, 0x3b, 0xc97, 0xcc1, 0x2e, 0x3b, 0xcb6, 0xcc1, 0x2e,
+0x3b, 0xcb6, 0xca8, 0xcbf, 0x2e, 0x3b, 0x622, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x655, 0x631,
+0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628,
+0x631, 0x65b, 0x66e, 0x6ea, 0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b,
+0x627, 0x64e, 0x62a, 0x6be, 0x648, 0x627, 0x631, 0x3b, 0x698, 0x654, 0x646, 0x65b, 0x62f, 0x631, 0x655, 0x631, 0x648, 0x627, 0x631, 0x3b,
+0x628, 0x648, 0x65a, 0x645, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x648, 0x62f, 0x648, 0x627, 0x631, 0x3b, 0x628, 0x631, 0x65b, 0x66e, 0x6ea,
+0x633, 0x648, 0x627, 0x631, 0x3b, 0x62c, 0x64f, 0x645, 0x6c1, 0x3b, 0x628, 0x679, 0x648, 0x627, 0x631, 0x3b, 0x627, 0x3b, 0x698, 0x3b,
+0x628, 0x3b, 0x628, 0x3b, 0x628, 0x3b, 0x62c, 0x3b, 0x628, 0x3b, 0x436, 0x441, 0x2e, 0x3b, 0x434, 0x441, 0x2e, 0x3b, 0x441, 0x441,
+0x2e, 0x3b, 0x441, 0x440, 0x2e, 0x3b, 0x431, 0x441, 0x2e, 0x3b, 0x436, 0x43c, 0x2e, 0x3b, 0x441, 0x431, 0x2e, 0x3b, 0x436, 0x435,
+0x43a, 0x441, 0x435, 0x43d, 0x456, 0x3b, 0x434, 0x443, 0x439, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x441, 0x435, 0x439, 0x441, 0x435,
+0x43d, 0x431, 0x456, 0x3b, 0x441, 0x4d9, 0x440, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x431, 0x435, 0x439, 0x441, 0x435, 0x43d, 0x431,
+0x456, 0x3b, 0x436, 0x4b1, 0x43c, 0x430, 0x3b, 0x441, 0x435, 0x43d, 0x431, 0x456, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x421, 0x3b, 0x421,
+0x3b, 0x411, 0x3b, 0x416, 0x3b, 0x421, 0x3b, 0x63, 0x79, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62,
+0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64,
+0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x63, 0x79, 0x75, 0x6d, 0x77, 0x65, 0x72, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6d,
+0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75, 0x77,
+0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e, 0x65, 0x3b, 0x4b,
+0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61,
+0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0x416, 0x435, 0x43a, 0x3b, 0x414, 0x4af, 0x439, 0x3b, 0x428, 0x435, 0x439, 0x3b, 0x428, 0x430,
+0x440, 0x3b, 0x411, 0x435, 0x439, 0x3b, 0x416, 0x443, 0x43c, 0x3b, 0x418, 0x448, 0x43c, 0x3b, 0x416, 0x435, 0x43a, 0x448, 0x435, 0x43c,
+0x431, 0x438, 0x3b, 0x414, 0x4af, 0x439, 0x448, 0x4e9, 0x43c, 0x431, 0x4af, 0x3b, 0x428, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438,
+0x3b, 0x428, 0x430, 0x440, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x411, 0x435, 0x439, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416,
+0x443, 0x43c, 0x430, 0x3b, 0x418, 0x448, 0x435, 0x43c, 0x431, 0x438, 0x3b, 0x416, 0x3b, 0x414, 0x3b, 0x428, 0x3b, 0x428, 0x3b, 0x411,
+0x3b, 0x416, 0x3b, 0x418, 0x3b, 0x416, 0x43a, 0x3b, 0x414, 0x448, 0x3b, 0x428, 0x435, 0x3b, 0x428, 0x430, 0x3b, 0x411, 0x448, 0x3b,
+0x416, 0x43c, 0x3b, 0x418, 0x448, 0x3b, 0xc77c, 0x3b, 0xc6d4, 0x3b, 0xd654, 0x3b, 0xc218, 0x3b, 0xbaa9, 0x3b, 0xae08, 0x3b, 0xd1a0, 0x3b,
+0xc77c, 0xc694, 0xc77c, 0x3b, 0xc6d4, 0xc694, 0xc77c, 0x3b, 0xd654, 0xc694, 0xc77c, 0x3b, 0xc218, 0xc694, 0xc77c, 0x3b, 0xbaa9, 0xc694, 0xc77c, 0x3b,
+0xae08, 0xc694, 0xc77c, 0x3b, 0xd1a0, 0xc694, 0xc77c, 0x3b, 0x63, 0x75, 0x2e, 0x3b, 0x6d, 0x62, 0x65, 0x2e, 0x3b, 0x6b, 0x61, 0x62,
+0x2e, 0x3b, 0x67, 0x74, 0x75, 0x2e, 0x3b, 0x6b, 0x61, 0x6e, 0x2e, 0x3b, 0x67, 0x6e, 0x75, 0x2e, 0x3b, 0x67, 0x6e, 0x64,
+0x2e, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x27, 0x69, 0x6e, 0x64, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6d,
+0x62, 0x65, 0x72, 0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x75,
+0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x6b, 0x61, 0x6e,
+0x65, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61, 0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x4b, 0x75, 0x20, 0x77, 0x61,
+0x20, 0x67, 0x61, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x75, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb2, 0xe97, 0xeb4, 0xe94, 0x3b,
+0xea7, 0xeb1, 0xe99, 0xe88, 0xeb1, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99, 0xead, 0xeb1, 0xe87, 0xe84, 0xeb2, 0xe99, 0x3b, 0xea7, 0xeb1, 0xe99,
+0xe9e, 0xeb8, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xe9e, 0xeb0, 0xeab, 0xeb1, 0xe94, 0x3b, 0xea7, 0xeb1, 0xe99, 0xeaa, 0xeb8, 0xe81, 0x3b,
+0xea7, 0xeb1, 0xe99, 0xec0, 0xeaa, 0xebb, 0xeb2, 0x3b, 0xe97, 0x3b, 0xe88, 0x3b, 0xe84, 0x3b, 0x200b, 0xe9e, 0xeb8, 0x3b, 0xe9e, 0x3b,
+0x200b, 0xeaa, 0xeb8, 0x3b, 0xeaa, 0x3b, 0x53, 0x76, 0x3b, 0x50, 0x72, 0x3b, 0x4f, 0x74, 0x3b, 0x54, 0x72, 0x3b, 0x43, 0x65,
+0x3b, 0x50, 0x6b, 0x3b, 0x53, 0x65, 0x3b, 0x53, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69, 0x72,
+0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x4f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x54, 0x72, 0x65, 0x161,
+0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x43, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x50, 0x69,
+0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53, 0x65, 0x73, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x53,
+0x3b, 0x50, 0x3b, 0x4f, 0x3b, 0x54, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x73, 0x76, 0x113, 0x74, 0x64, 0x69, 0x65,
+0x6e, 0x61, 0x3b, 0x70, 0x69, 0x72, 0x6d, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x6f, 0x74, 0x72, 0x64, 0x69, 0x65, 0x6e,
+0x61, 0x3b, 0x74, 0x72, 0x65, 0x161, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x63, 0x65, 0x74, 0x75, 0x72, 0x74, 0x64, 0x69,
+0x65, 0x6e, 0x61, 0x3b, 0x70, 0x69, 0x65, 0x6b, 0x74, 0x64, 0x69, 0x65, 0x6e, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x64,
+0x69, 0x65, 0x6e, 0x61, 0x3b, 0x65, 0x79, 0x65, 0x3b, 0x79, 0x62, 0x6f, 0x3b, 0x6d, 0x62, 0x6c, 0x3b, 0x6d, 0x73, 0x74,
+0x3b, 0x6d, 0x69, 0x6e, 0x3b, 0x6d, 0x74, 0x6e, 0x3b, 0x6d, 0x70, 0x73, 0x3b, 0x65, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b,
+0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x79, 0x61, 0x6d, 0x62, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b,
+0x254, 0x6c, 0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x62, 0x61, 0x6c, 0xe9, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c,
+0x254, 0x20, 0x6d, 0x77, 0x61, 0x20, 0x6d, 0xed, 0x73, 0xe1, 0x74, 0x6f, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20,
+0x79, 0x61, 0x20, 0x6d, 0xed, 0x6e, 0xe9, 0x69, 0x3b, 0x6d, 0x6f, 0x6b, 0x254, 0x6c, 0x254, 0x20, 0x79, 0x61, 0x20, 0x6d,
+0xed, 0x74, 0xe1, 0x6e, 0x6f, 0x3b, 0x6d, 0x70, 0x254, 0x301, 0x73, 0x254, 0x3b, 0x65, 0x3b, 0x79, 0x3b, 0x6d, 0x3b, 0x6d,
+0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x70, 0x3b, 0x73, 0x6b, 0x3b, 0x70, 0x72, 0x3b, 0x61, 0x6e, 0x3b, 0x74, 0x72, 0x3b, 0x6b,
+0x74, 0x3b, 0x70, 0x6e, 0x3b, 0x161, 0x74, 0x3b, 0x73, 0x65, 0x6b, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b,
+0x70, 0x69, 0x72, 0x6d, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x61, 0x6e, 0x74, 0x72, 0x61, 0x64, 0x69, 0x65,
+0x6e, 0x69, 0x73, 0x3b, 0x74, 0x72, 0x65, 0x10d, 0x69, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x6b, 0x65, 0x74,
+0x76, 0x69, 0x72, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x70, 0x65, 0x6e, 0x6b, 0x74, 0x61, 0x64, 0x69,
+0x65, 0x6e, 0x69, 0x73, 0x3b, 0x161, 0x65, 0x161, 0x74, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x69, 0x73, 0x3b, 0x53, 0x3b, 0x50,
+0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x160, 0x3b, 0x43d, 0x435, 0x434, 0x2e, 0x3b, 0x43f, 0x43e, 0x43d, 0x2e,
+0x3b, 0x432, 0x442, 0x2e, 0x3b, 0x441, 0x440, 0x435, 0x2e, 0x3b, 0x447, 0x435, 0x442, 0x2e, 0x3b, 0x43f, 0x435, 0x442, 0x2e, 0x3b,
+0x441, 0x430, 0x431, 0x2e, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x43d,
+0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442,
+0x432, 0x440, 0x442, 0x43e, 0x43a, 0x3b, 0x43f, 0x435, 0x442, 0x43e, 0x43a, 0x3b, 0x441, 0x430, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x41,
+0x6c, 0x61, 0x68, 0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x3b, 0x41,
+0x6c, 0x61, 0x6b, 0x3b, 0x5a, 0x6f, 0x6d, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x79,
+0x3b, 0x41, 0x6c, 0x61, 0x74, 0x73, 0x69, 0x6e, 0x61, 0x69, 0x6e, 0x79, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b,
+0x41, 0x6c, 0x61, 0x72, 0x6f, 0x62, 0x69, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x6b, 0x61, 0x6d, 0x69, 0x73, 0x79, 0x3b, 0x5a,
+0x6f, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x61, 0x62, 0x6f, 0x74, 0x73, 0x79, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x54, 0x3b, 0x41,
+0x3b, 0x41, 0x3b, 0x5a, 0x3b, 0x41, 0x3b, 0x41, 0x68, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x3b, 0x52,
+0x61, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x41, 0x68, 0x61, 0x64, 0x3b,
+0x49, 0x73, 0x6e, 0x69, 0x6e, 0x3b, 0x53, 0x65, 0x6c, 0x61, 0x73, 0x61, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x3b, 0x4b, 0x68,
+0x61, 0x6d, 0x69, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x75, 0x3b, 0x41, 0x3b,
+0x49, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x4b, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd7c, 0x3b, 0xd24, 0xd3f, 0xd19,
+0xd4d, 0xd15, 0xd7e, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd7b, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34,
+0xd02, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0x3b, 0xd36, 0xd28, 0xd3f, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d,
+0x200c, 0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35,
+0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e,
+0xd34, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b,
+0xd36, 0xd28, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1e, 0xd3e, 0x3b, 0xd24, 0xd3f, 0x3b, 0xd1a, 0xd4a, 0x3b, 0xd2c,
+0xd41, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0x3b, 0xd35, 0xd46, 0x3b, 0xd36, 0x3b, 0xd1e, 0xd3e, 0xd2f, 0xd31, 0xd3e, 0xd34, 0xd4d, 0x200c,
+0xd1a, 0x3b, 0xd24, 0xd3f, 0xd19, 0xd4d, 0xd15, 0xd33, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd1a, 0xd4a, 0xd35, 0xd4d, 0xd35, 0xd3e,
+0xd34, 0xd4d, 0xd1a, 0x3b, 0xd2c, 0xd41, 0xd27, 0xd28, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd4d, 0xd2f, 0xd3e, 0xd34, 0xd3e,
+0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd35, 0xd46, 0xd33, 0xd4d, 0xd33, 0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0xd36, 0xd28,
+0xd3f, 0xd2f, 0xd3e, 0xd34, 0xd4d, 0x200c, 0xd1a, 0x3b, 0x126, 0x61, 0x64, 0x3b, 0x54, 0x6e, 0x65, 0x3b, 0x54, 0x6c, 0x69, 0x3b,
+0x45, 0x72, 0x62, 0x3b, 0x126, 0x61, 0x6d, 0x3b, 0x120, 0x69, 0x6d, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x49, 0x6c, 0x2d, 0x126,
+0x61, 0x64, 0x64, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6e, 0x65, 0x6a, 0x6e, 0x3b, 0x49, 0x74, 0x2d, 0x54, 0x6c, 0x69, 0x65,
+0x74, 0x61, 0x3b, 0x4c, 0x2d, 0x45, 0x72, 0x62, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x6c, 0x2d, 0x126, 0x61, 0x6d, 0x69, 0x73,
+0x3b, 0x49, 0x6c, 0x2d, 0x120, 0x69, 0x6d, 0x67, 0x127, 0x61, 0x3b, 0x49, 0x73, 0x2d, 0x53, 0x69, 0x62, 0x74, 0x3b, 0x126,
+0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x126, 0x3b, 0x120, 0x3b, 0x53, 0x3b, 0x930, 0x935, 0x93f, 0x3b, 0x938, 0x94b, 0x92e,
+0x3b, 0x92e, 0x902, 0x917, 0x933, 0x3b, 0x92c, 0x941, 0x927, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930,
+0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x930, 0x935, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e,
+0x902, 0x917, 0x933, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e,
+0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x41d, 0x44f,
+0x3b, 0x414, 0x430, 0x3b, 0x41c, 0x44f, 0x3b, 0x41b, 0x445, 0x3b, 0x41f, 0x4af, 0x3b, 0x411, 0x430, 0x3b, 0x411, 0x44f, 0x3b, 0x43d,
+0x44f, 0x43c, 0x3b, 0x434, 0x430, 0x432, 0x430, 0x430, 0x3b, 0x43c, 0x44f, 0x433, 0x43c, 0x430, 0x440, 0x3b, 0x43b, 0x445, 0x430, 0x433,
+0x432, 0x430, 0x3b, 0x43f, 0x4af, 0x440, 0x44d, 0x432, 0x3b, 0x431, 0x430, 0x430, 0x441, 0x430, 0x43d, 0x3b, 0x431, 0x44f, 0x43c, 0x431,
+0x430, 0x3b, 0x906, 0x907, 0x924, 0x3b, 0x938, 0x94b, 0x92e, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x927, 0x3b,
+0x92c, 0x93f, 0x939, 0x940, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x3b, 0x906, 0x907, 0x924, 0x92c, 0x93e,
+0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941,
+0x927, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939, 0x940, 0x92c, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x92c, 0x93e,
+0x930, 0x3b, 0x936, 0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x906, 0x3b, 0x938, 0x94b, 0x3b, 0x92e, 0x3b, 0x92c, 0x941, 0x3b, 0x92c,
+0x93f, 0x3b, 0x936, 0x941, 0x3b, 0x936, 0x3b, 0x906, 0x907, 0x924, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930,
+0x3b, 0x92e, 0x919, 0x94d, 0x917, 0x932, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x939,
+0x940, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930,
+0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0x61, 0x2e, 0x3b, 0x74, 0x69, 0x2e, 0x3b, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e,
+0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0xf8, 0x2e, 0x3b, 0xb30, 0xb2c, 0xb3f, 0x3b, 0xb38, 0xb4b, 0xb2e, 0x3b, 0xb2e, 0xb19, 0xb4d,
+0xb17, 0xb33, 0x3b, 0xb2c, 0xb41, 0xb27, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0x3b, 0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0x3b, 0xb36, 0xb28,
+0xb3f, 0x3b, 0xb30, 0xb2c, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb38, 0xb4b, 0xb2e, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2e, 0xb19, 0xb4d, 0xb17,
+0xb33, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb2c, 0xb41, 0xb27, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb17, 0xb41, 0xb30, 0xb41, 0xb2c, 0xb3e, 0xb30, 0x3b,
+0xb36, 0xb41, 0xb15, 0xb4d, 0xb30, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb36, 0xb28, 0xb3f, 0xb2c, 0xb3e, 0xb30, 0x3b, 0xb30, 0x3b, 0xb38, 0xb4b,
+0x3b, 0xb2e, 0x3b, 0xb2c, 0xb41, 0x3b, 0xb17, 0xb41, 0x3b, 0xb36, 0xb41, 0x3b, 0xb36, 0x3b, 0x6cc, 0x6a9, 0x634, 0x646, 0x628, 0x647,
+0x3b, 0x62f, 0x648, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x633, 0x647, 0x200c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x686, 0x647, 0x627, 0x631,
+0x634, 0x646, 0x628, 0x647, 0x3b, 0x67e, 0x646, 0x62c, 0x634, 0x646, 0x628, 0x647, 0x3b, 0x62c, 0x645, 0x639, 0x647, 0x3b, 0x634, 0x646,
+0x628, 0x647, 0x3b, 0x6cc, 0x3b, 0x62f, 0x3b, 0x633, 0x3b, 0x686, 0x3b, 0x67e, 0x3b, 0x62c, 0x3b, 0x634, 0x3b, 0x6e, 0x69, 0x65,
+0x64, 0x7a, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x77, 0x74, 0x2e, 0x3b, 0x15b, 0x72, 0x2e, 0x3b, 0x63, 0x7a, 0x77,
+0x2e, 0x3b, 0x70, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x65, 0x6c, 0x61,
+0x3b, 0x70, 0x6f, 0x6e, 0x69, 0x65, 0x64, 0x7a, 0x69, 0x61, 0x142, 0x65, 0x6b, 0x3b, 0x77, 0x74, 0x6f, 0x72, 0x65, 0x6b,
+0x3b, 0x15b, 0x72, 0x6f, 0x64, 0x61, 0x3b, 0x63, 0x7a, 0x77, 0x61, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x69, 0x105, 0x74,
+0x65, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x57, 0x3b, 0x15a, 0x3b, 0x43, 0x3b,
+0x50, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x73, 0x65, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b, 0x71, 0x75, 0x61, 0x3b,
+0x71, 0x75, 0x69, 0x3b, 0x73, 0x65, 0x78, 0x3b, 0x73, 0xe1, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b,
+0x73, 0x65, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72, 0xe7, 0x61, 0x2d,
+0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x71,
+0x75, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x69, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x78, 0x74, 0x61, 0x2d, 0x66, 0x65,
+0x69, 0x72, 0x61, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x51, 0x3b, 0x51,
+0x3b, 0x53, 0x3b, 0x53, 0x3b, 0xa10, 0xa24, 0x2e, 0x3b, 0xa38, 0xa4b, 0xa2e, 0x2e, 0x3b, 0xa2e, 0xa70, 0xa17, 0xa32, 0x2e, 0x3b,
+0xa2c, 0xa41, 0xa27, 0x2e, 0x3b, 0xa35, 0xa40, 0xa30, 0x2e, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0x2e, 0x3b, 0xa38, 0xa3c,
+0xa28, 0xa40, 0x2e, 0x3b, 0xa10, 0xa24, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa4b, 0xa2e, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2e, 0xa70, 0xa17,
+0xa32, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa2c, 0xa41, 0xa27, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa35, 0xa40, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38,
+0xa3c, 0xa41, 0xa71, 0xa15, 0xa30, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa38, 0xa3c, 0xa28, 0xa40, 0xa35, 0xa3e, 0xa30, 0x3b, 0xa10, 0x3b, 0xa38,
+0xa4b, 0x3b, 0xa2e, 0xa70, 0x3b, 0xa2c, 0xa41, 0xa71, 0x3b, 0xa35, 0xa40, 0x3b, 0xa38, 0xa3c, 0xa41, 0xa71, 0x3b, 0xa38, 0xa3c, 0x3b,
+0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x64f, 0x62f, 0x6be, 0x3b,
+0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x64, 0x75, 0x3b,
+0x67, 0x6c, 0x69, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x65, 0x3b, 0x67, 0x69, 0x65, 0x3b, 0x76, 0x65, 0x3b, 0x73, 0x6f, 0x3b,
+0x64, 0x75, 0x6d, 0x65, 0x6e, 0x67, 0x69, 0x61, 0x3b, 0x67, 0x6c, 0x69, 0x6e, 0x64, 0x65, 0x73, 0x64, 0x69, 0x3b, 0x6d,
+0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x73, 0x65, 0x6d, 0x6e, 0x61, 0x3b, 0x67, 0x69, 0x65, 0x76, 0x67, 0x69, 0x61,
+0x3b, 0x76, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x6e, 0x64, 0x61, 0x3b, 0x44, 0x3b, 0x47, 0x3b,
+0x4d, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x44, 0x75, 0x6d, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61,
+0x72, 0x3b, 0x4d, 0x69, 0x65, 0x3b, 0x4a, 0x6f, 0x69, 0x3b, 0x56, 0x69, 0x6e, 0x3b, 0x53, 0xe2, 0x6d, 0x3b, 0x64, 0x75,
+0x6d, 0x69, 0x6e, 0x69, 0x63, 0x103, 0x3b, 0x6c, 0x75, 0x6e, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x21b, 0x69, 0x3b, 0x6d, 0x69,
+0x65, 0x72, 0x63, 0x75, 0x72, 0x69, 0x3b, 0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x65, 0x72, 0x69, 0x3b, 0x73, 0xe2,
+0x6d, 0x62, 0x103, 0x74, 0x103, 0x3b, 0x412, 0x441, 0x3b, 0x41f, 0x43d, 0x3b, 0x412, 0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442,
+0x3b, 0x41f, 0x442, 0x3b, 0x421, 0x431, 0x3b, 0x412, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x41f,
+0x43e, 0x43d, 0x435, 0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x412, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x421,
+0x440, 0x435, 0x434, 0x430, 0x3b, 0x427, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x41f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430,
+0x3b, 0x421, 0x443, 0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x412, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f,
+0x3b, 0x421, 0x3b, 0x432, 0x441, 0x3b, 0x43f, 0x43d, 0x3b, 0x432, 0x442, 0x3b, 0x441, 0x440, 0x3b, 0x447, 0x442, 0x3b, 0x43f, 0x442,
+0x3b, 0x441, 0x431, 0x3b, 0x432, 0x43e, 0x441, 0x43a, 0x440, 0x435, 0x441, 0x435, 0x43d, 0x44c, 0x435, 0x3b, 0x43f, 0x43e, 0x43d, 0x435,
+0x434, 0x435, 0x43b, 0x44c, 0x43d, 0x438, 0x43a, 0x3b, 0x432, 0x442, 0x43e, 0x440, 0x43d, 0x438, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434,
+0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x433, 0x3b, 0x43f, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x430, 0x3b, 0x441, 0x443,
+0x431, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x42, 0x6b, 0x31, 0x3b, 0x42, 0x6b, 0x32, 0x3b, 0x42, 0x6b, 0x33, 0x3b, 0x42, 0x6b,
+0x34, 0x3b, 0x42, 0x6b, 0x35, 0x3b, 0x4c, 0xe2, 0x70, 0x3b, 0x4c, 0xe2, 0x79, 0x3b, 0x42, 0x69, 0x6b, 0x75, 0x61, 0x2d,
+0xf4, 0x6b, 0x6f, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0xfb, 0x73, 0x65, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d,
+0x70, 0x74, 0xe2, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61, 0x2d, 0x75, 0x73, 0xef, 0xf6, 0x3b, 0x42, 0xef, 0x6b, 0x75, 0x61,
+0x2d, 0x6f, 0x6b, 0xfc, 0x3b, 0x4c, 0xe2, 0x70, 0xf4, 0x73, 0xf6, 0x3b, 0x4c, 0xe2, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b,
+0x4b, 0x3b, 0x53, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x50, 0x3b, 0x59, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e,
+0x43d, 0x3b, 0x443, 0x442, 0x43e, 0x3b, 0x441, 0x440, 0x435, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443,
+0x431, 0x3b, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443,
+0x442, 0x43e, 0x440, 0x430, 0x43a, 0x3b, 0x441, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a,
+0x3b, 0x43f, 0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x43d, 0x3b, 0x43f, 0x3b, 0x443, 0x3b,
+0x441, 0x3b, 0x447, 0x3b, 0x43f, 0x3b, 0x441, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x75, 0x74, 0x6f, 0x3b,
+0x73, 0x72, 0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x75, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65,
+0x6c, 0x6a, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x61, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72, 0x61,
+0x6b, 0x3b, 0x73, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x76, 0x72, 0x74, 0x61, 0x6b, 0x3b, 0x70, 0x65, 0x74,
+0x61, 0x6b, 0x3b, 0x73, 0x75, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x43d, 0x435, 0x434, 0x3b, 0x43f, 0x43e, 0x43d, 0x3b, 0x443, 0x442,
+0x43e, 0x3b, 0x441, 0x440, 0x438, 0x3b, 0x447, 0x435, 0x442, 0x3b, 0x43f, 0x435, 0x442, 0x3b, 0x441, 0x443, 0x431, 0x3b, 0x43d, 0x435,
+0x434, 0x435, 0x459, 0x430, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x435, 0x459, 0x430, 0x43a, 0x3b, 0x443, 0x442, 0x43e, 0x440, 0x430,
+0x43a, 0x3b, 0x441, 0x440, 0x438, 0x458, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x440, 0x442, 0x430, 0x43a, 0x3b, 0x43f,
+0x435, 0x442, 0x430, 0x43a, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x425, 0x446, 0x431, 0x3b, 0x41a, 0x440, 0x441, 0x3b,
+0x414, 0x446, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x3b, 0x426, 0x43f, 0x440, 0x3b, 0x41c, 0x440, 0x431, 0x3b, 0x421, 0x431, 0x442, 0x3b,
+0x425, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x41a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441, 0x4d5, 0x440, 0x3b,
+0x414, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d4, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x426, 0x44b, 0x43f, 0x43f,
+0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x41c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x421, 0x430, 0x431, 0x430, 0x442,
+0x3b, 0x425, 0x3b, 0x41a, 0x3b, 0x414, 0x3b, 0x4d4, 0x3b, 0x426, 0x3b, 0x41c, 0x3b, 0x421, 0x3b, 0x445, 0x446, 0x431, 0x3b, 0x43a,
+0x440, 0x441, 0x3b, 0x434, 0x446, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x3b, 0x446, 0x43f, 0x440, 0x3b, 0x43c, 0x440, 0x431, 0x3b, 0x441,
+0x431, 0x442, 0x3b, 0x445, 0x443, 0x44b, 0x446, 0x430, 0x443, 0x431, 0x43e, 0x43d, 0x3b, 0x43a, 0x44a, 0x443, 0x44b, 0x440, 0x438, 0x441,
+0x4d5, 0x440, 0x3b, 0x434, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x4d5, 0x440, 0x442, 0x44b, 0x446, 0x446, 0x4d5, 0x433, 0x3b, 0x446,
+0x44b, 0x43f, 0x43f, 0x4d5, 0x440, 0x4d5, 0x43c, 0x3b, 0x43c, 0x430, 0x439, 0x440, 0x4d5, 0x43c, 0x431, 0x43e, 0x43d, 0x3b, 0x441, 0x430,
+0x431, 0x430, 0x442, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x6d, 0x61, 0x3b, 0x42, 0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b,
+0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x6f, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x68, 0x61, 0x3b, 0x4d,
+0x6d, 0x61, 0x6e, 0x74, 0x61, 0x68, 0x61, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62, 0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62,
+0x6f, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x68, 0x6c, 0x61,
+0x6e, 0x65, 0x3b, 0x4d, 0x6f, 0x71, 0x65, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x54, 0x73, 0x68, 0x3b, 0x4d, 0x6f, 0x73, 0x3b,
+0x42, 0x65, 0x64, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c, 0x61, 0x3b, 0x4d, 0x61, 0x74, 0x3b, 0x54,
+0x73, 0x68, 0x69, 0x70, 0x69, 0x3b, 0x4d, 0x6f, 0x73, 0x6f, 0x70, 0x75, 0x6c, 0x6f, 0x67, 0x6f, 0x3b, 0x4c, 0x61, 0x62,
+0x6f, 0x62, 0x65, 0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e,
+0x65, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x61, 0x74, 0x6c, 0x68, 0x61, 0x74,
+0x73, 0x6f, 0x3b, 0x53, 0x76, 0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x3b, 0x43, 0x68, 0x69, 0x74,
+0x3b, 0x43, 0x68, 0x69, 0x6e, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x76, 0x6f, 0x6e, 0x64,
+0x6f, 0x3b, 0x4d, 0x75, 0x76, 0x68, 0x75, 0x72, 0x6f, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68,
+0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75,
+0x3b, 0x4d, 0x75, 0x67, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b,
+0x43, 0x3b, 0x4d, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0x3b,
+0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0x3b, 0xdc3,
+0xdd9, 0xdb1, 0x3b, 0xd89, 0xdbb, 0xdd2, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdb3, 0xdd4, 0xdaf, 0xdcf, 0x3b, 0xd85, 0xd9f, 0xdc4, 0xdbb, 0xdd4,
+0xdc0, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdaf, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0xdc4, 0xdc3, 0xdca, 0xdb4, 0xdad,
+0xdd2, 0xdb1, 0xdca, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd2, 0xd9a, 0xdd4, 0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xdc3, 0xdd9, 0xdb1, 0xdc3, 0xdd4,
+0xdbb, 0xdcf, 0xdaf, 0xdcf, 0x3b, 0xd89, 0x3b, 0xdc3, 0x3b, 0xd85, 0x3b, 0xdb6, 0x3b, 0xdb6, 0xdca, 0x200d, 0xdbb, 0x3b, 0xdc3, 0xdd2,
+0x3b, 0xdc3, 0xdd9, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x73, 0x61, 0x3b,
+0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x63, 0x3b, 0x4c, 0x69, 0x73, 0x6f, 0x6e, 0x74, 0x66, 0x6f, 0x3b,
+0x75, 0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69,
+0x3b, 0x4c, 0x65, 0x73, 0x69, 0x74, 0x73, 0x61, 0x74, 0x66, 0x75, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b, 0x4c,
+0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x75, 0x4d, 0x67, 0x63, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x6e,
+0x65, 0x3b, 0x70, 0x6f, 0x3b, 0x75, 0x74, 0x3b, 0x73, 0x74, 0x3b, 0x161, 0x74, 0x3b, 0x70, 0x69, 0x3b, 0x73, 0x6f, 0x3b,
+0x6e, 0x65, 0x64, 0x65, 0x13e, 0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x64, 0x65, 0x6c, 0x6f, 0x6b, 0x3b, 0x75, 0x74, 0x6f, 0x72,
+0x6f, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x65, 0x64, 0x61, 0x3b, 0x161, 0x74, 0x76, 0x72, 0x74, 0x6f, 0x6b, 0x3b, 0x70, 0x69,
+0x61, 0x74, 0x6f, 0x6b, 0x3b, 0x73, 0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x4e, 0x3b, 0x50, 0x3b, 0x55, 0x3b, 0x53, 0x3b,
+0x160, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0x6e, 0x65, 0x64, 0x3b, 0x70, 0x6f, 0x6e, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x73, 0x72,
+0x65, 0x3b, 0x10d, 0x65, 0x74, 0x3b, 0x70, 0x65, 0x74, 0x3b, 0x73, 0x6f, 0x62, 0x3b, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a,
+0x61, 0x3b, 0x70, 0x6f, 0x6e, 0x65, 0x64, 0x65, 0x6c, 0x6a, 0x65, 0x6b, 0x3b, 0x74, 0x6f, 0x72, 0x65, 0x6b, 0x3b, 0x73,
+0x72, 0x65, 0x64, 0x61, 0x3b, 0x10d, 0x65, 0x74, 0x72, 0x74, 0x65, 0x6b, 0x3b, 0x70, 0x65, 0x74, 0x65, 0x6b, 0x3b, 0x73,
+0x6f, 0x62, 0x6f, 0x74, 0x61, 0x3b, 0x6e, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0x10d, 0x3b, 0x70, 0x3b, 0x73, 0x3b,
+0x6e, 0x65, 0x64, 0x2e, 0x3b, 0x70, 0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x72, 0x2e, 0x3b, 0x73, 0x72, 0x65, 0x2e, 0x3b,
+0x10d, 0x65, 0x74, 0x2e, 0x3b, 0x70, 0x65, 0x74, 0x2e, 0x3b, 0x73, 0x6f, 0x62, 0x2e, 0x3b, 0x41, 0x78, 0x64, 0x3b, 0x49,
+0x73, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x72, 0x62, 0x3b, 0x4b, 0x68, 0x61, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x53,
+0x61, 0x62, 0x3b, 0x41, 0x78, 0x61, 0x64, 0x3b, 0x49, 0x73, 0x6e, 0x69, 0x69, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x61,
+0x64, 0x6f, 0x3b, 0x41, 0x72, 0x62, 0x61, 0x63, 0x6f, 0x3b, 0x4b, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x3b, 0x4a, 0x69,
+0x6d, 0x63, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x74, 0x69, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x4b, 0x3b,
+0x4a, 0x3b, 0x53, 0x3b, 0x44, 0x6f, 0x6d, 0x2e, 0x3b, 0x4c, 0x75, 0x6e, 0x2e, 0x3b, 0x4d, 0x61, 0x72, 0x2e, 0x3b, 0x4d,
+0x69, 0xe9, 0x2e, 0x3b, 0x4a, 0x75, 0x65, 0x2e, 0x3b, 0x56, 0x69, 0x65, 0x2e, 0x3b, 0x53, 0xe1, 0x62, 0x2e, 0x3b, 0x44,
+0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x4c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b,
+0x4d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x4a, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x56, 0x69, 0x65,
+0x72, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e,
+0x2e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69, 0xe9, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65,
+0x2e, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x3b, 0x6c, 0x75, 0x6e, 0x65, 0x73,
+0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x6a, 0x75,
+0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x6f, 0x3b,
+0x44, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x58, 0x3b, 0x4a, 0x3b, 0x56, 0x3b, 0x53, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c,
+0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x2e, 0x3b, 0x6d, 0x69, 0xe9, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69,
+0x65, 0x3b, 0x73, 0xe1, 0x62, 0x2e, 0x3b, 0x64, 0x6f, 0x6d, 0x2e, 0x3b, 0x6c, 0x75, 0x6e, 0x2e, 0x3b, 0x6d, 0x61, 0x72,
+0x2e, 0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x2e, 0x3b, 0x6a, 0x75, 0x65, 0x2e, 0x3b, 0x76, 0x69, 0x65, 0x72, 0x2e, 0x3b, 0x73,
+0xe1, 0x62, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49,
+0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61,
+0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b,
0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b,
-0x61, 0x72, 0x3b, 0x6e, 0x74, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a,
-0x75, 0x6d, 0x3b, 0x73, 0x69, 0x62, 0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61,
-0x72, 0x61, 0x74, 0x61, 0x3b, 0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a,
-0x75, 0x6d, 0x61, 0x3b, 0x73, 0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41,
-0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x4b, 0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e,
-0x3b, 0x41, 0x72, 0x6d, 0x3b, 0x4d, 0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b,
-0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e,
-0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a,
-0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e,
-0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4,
-0x13b5, 0x13c1, 0x3b, 0x13e6, 0x13a2, 0x13c1, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4,
-0x13be, 0x13d9, 0x13d3, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6,
-0x3b, 0x13e6, 0x13a2, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b,
-0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b,
-0x13a4, 0x3b, 0x64, 0x69, 0x6d, 0x3b, 0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65,
-0x3b, 0x76, 0x61, 0x6e, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64,
-0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64,
-0x69, 0x3b, 0x76, 0x61, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c,
-0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x7a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c,
-0x6c, 0x34, 0x3b, 0x4c, 0x6c, 0x35, 0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c,
-0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61,
-0x20, 0x6c, 0x79, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e,
-0x63, 0x68, 0x65, 0x63, 0x68, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79,
-0x61, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f,
-0x20, 0x6e, 0x61, 0x20, 0x6c, 0x69, 0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61,
-0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64,
-0x75, 0x76, 0x61, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1,
-0x61, 0x74, 0x75, 0x3b, 0xcd, 0x6e, 0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a,
-0x6d, 0x3b, 0x4d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74,
-0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41,
-0x3b, 0x49, 0x3b, 0x4d, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33,
-0x3b, 0x4c, 0x77, 0x34, 0x3b, 0x4c, 0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74,
-0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c,
-0x77, 0x61, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61,
-0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53,
-0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75,
-0x6e, 0x67, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68,
-0x69, 0x62, 0x75, 0x6c, 0x69, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61,
-0x6c, 0x69, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b,
-0x50, 0x61, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67,
-0x3b, 0x74, 0x65, 0x72, 0x3b, 0x6b, 0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62,
-0x3b, 0x64, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72,
-0x61, 0x3b, 0x74, 0x65, 0x72, 0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d,
-0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74,
-0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x64, 0x3b, 0x73, 0x3b, 0x74, 0x3b,
-0x6b, 0x3b, 0x6b, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x4b, 0x49, 0x55, 0x3b, 0x4d, 0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b,
-0x57, 0x45, 0x54, 0x3b, 0x57, 0x45, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x4a, 0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d,
-0x69, 0x61, 0x3b, 0x4d, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x6f, 0x3b, 0x57, 0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65,
-0x74, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x61, 0x3b, 0x57, 0x65, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a,
-0x3b, 0x54, 0x69, 0x73, 0x3b, 0x54, 0x61, 0x69, 0x3b, 0x41, 0x65, 0x6e, 0x3b, 0x53, 0x6f, 0x6d, 0x3b, 0x41, 0x6e, 0x67,
-0x3b, 0x4d, 0x75, 0x74, 0x3b, 0x4c, 0x6f, 0x68, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x74, 0x69, 0x73,
-0x61, 0x70, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x20, 0x6e, 0x65, 0x74, 0x61, 0x69, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74,
-0x61, 0x62, 0x20, 0x61, 0x65, 0x6e, 0x67, 0x27, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x73, 0x6f, 0x6d,
-0x6f, 0x6b, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x61, 0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x42,
-0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x6d, 0x75, 0x74, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x6c,
-0x6f, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b,
-0x4d, 0x61, 0x3b, 0x44, 0x65, 0x3b, 0x57, 0x75, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53,
-0x6f, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65,
-0x65, 0x73, 0x3b, 0x44, 0x65, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73,
-0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73,
-0x65, 0x65, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x69, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74,
-0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44,
-0x3b, 0x46, 0x3b, 0x41, 0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e,
-0x3b, 0x44, 0x75, 0x2e, 0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61,
-0x63, 0x68, 0x3b, 0x4d, 0x6f, 0x6f, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61,
-0x61, 0x63, 0x68, 0x3b, 0x4d, 0x65, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64,
-0x61, 0x61, 0x63, 0x68, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64,
-0x61, 0x61, 0x63, 0x68, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x6c, 0xed, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1,
-0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41,
-0x6c, 0x61, 0xe1, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3,
-0x73, 0x69, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x3b, 0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75,
-0x73, 0x61, 0x3b, 0x4b, 0x75, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x74, 0x61, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61,
-0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69,
-0x6c, 0x69, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61,
-0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x74, 0x61, 0x61, 0x6e, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61,
-0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b,
-0x4a, 0x33, 0x3b, 0x4a, 0x34, 0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x3b, 0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77,
-0x61, 0x20, 0x4b, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74,
-0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74,
-0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f,
-0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x42, 0x61, 0x72, 0x3b, 0x41, 0x61, 0x72, 0x3b, 0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67,
-0x3b, 0x4b, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e,
-0x61, 0x6b, 0x61, 0x65, 0x62, 0x61, 0x72, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e,
-0x61, 0x6b, 0x61, 0x75, 0x6e, 0x69, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x67, 0x27, 0x6f, 0x6e, 0x3b, 0x4e, 0x61,
-0x6b, 0x61, 0x6b, 0x61, 0x6e, 0x79, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x73, 0x61, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b,
-0x42, 0x3b, 0x41, 0x3b, 0x55, 0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x6e, 0x3b,
-0x53, 0x61, 0x6c, 0x3b, 0x52, 0x61, 0x62, 0x3b, 0x43, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x51, 0x75, 0x6e, 0x3b,
-0x4e, 0x61, 0x62, 0x61, 0x20, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x6e, 0x69, 0x3b, 0x53, 0x61, 0x6c,
-0x75, 0x73, 0x3b, 0x52, 0x61, 0x62, 0x75, 0x71, 0x3b, 0x43, 0x61, 0x6d, 0x75, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x71, 0x61,
-0x74, 0x61, 0x3b, 0x51, 0x75, 0x6e, 0x78, 0x61, 0x20, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x4e, 0x3b, 0x53, 0x3b,
-0x53, 0x3b, 0x52, 0x3b, 0x43, 0x3b, 0x4a, 0x3b, 0x51, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74,
-0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c,
-0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41,
-0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75,
-0x6d, 0x61, 0x3b, 0x41, 0x73, 0x73, 0x61, 0x62, 0x64, 0x75, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c,
-0x3b, 0x4c, 0x3b, 0x53, 0x3b, 0x4a, 0x4d, 0x50, 0x3b, 0x57, 0x55, 0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44,
-0x3b, 0x54, 0x41, 0x4e, 0x3b, 0x54, 0x41, 0x42, 0x3b, 0x4e, 0x47, 0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c,
-0x3b, 0x57, 0x75, 0x6f, 0x6b, 0x20, 0x54, 0x69, 0x63, 0x68, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79,
-0x6f, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67,
-0x27, 0x77, 0x65, 0x6e, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73,
-0x6f, 0x3b, 0x4a, 0x3b, 0x57, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b,
-0x41, 0x79, 0x6e, 0x3b, 0x41, 0x73, 0x6e, 0x3b, 0x41, 0x6b, 0x72, 0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b,
-0x41, 0x73, 0x1e0d, 0x3b, 0x41, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69,
-0x6e, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x72, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d,
-0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b,
-0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c,
-0x61, 0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x7a, 0x3b, 0x41, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69,
-0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61,
-0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61,
-0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b,
-0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
-0x61, 0x70, 0x69, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61,
-0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73,
-0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x930,
-0x92c, 0x93f, 0x3b, 0x938, 0x92e, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x926, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f,
-0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930, 0x92c, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938,
-0x92e, 0x92c, 0x93e, 0x930, 0x3b, 0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x926, 0x92c, 0x93e, 0x930, 0x3b,
-0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941,
-0x928, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x92c, 0x93f, 0x3b, 0x938,
-0x941, 0x3b, 0x938, 0x941, 0x3b, 0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e, 0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67,
-0x3b, 0x4e, 0x6a, 0x77, 0x3b, 0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75,
-0x3b, 0x4e, 0x6b, 0x6f, 0x64, 0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0, 0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67,
-0xf9, 0x3b, 0x4e, 0x6a, 0xf2, 0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61, 0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e,
-0x67, 0x75, 0x3b, 0x4c, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x6e, 0x74, 0x73,
-0x3b, 0x6b, 0x70, 0x61, 0x3b, 0x67, 0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65, 0x3b, 0x67, 0x68, 0x268,
-0x3b, 0x64, 0x7a, 0x6b, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6b,
-0x70, 0xe0, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x74, 0x254,
-0x300, 0x6d, 0x6c, 0xf2, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68,
-0x268, 0x302, 0x6d, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254, 0x3b, 0x6e, 0x3b, 0x6b,
-0x3b, 0x67, 0x3b, 0x74, 0x3b, 0x75, 0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e, 0x6a, 0x61, 0x3b, 0x75,
-0x75, 0x6d, 0x3b, 0x14b, 0x67, 0x65, 0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a, 0x6f, 0x6e, 0x3b, 0x14b,
-0x67, 0x77, 0xe0, 0x20, 0x6e, 0x254, 0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a, 0x61, 0x14b, 0x67, 0x75,
-0x6d, 0x62, 0x61, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x14b, 0x67, 0xea,
-0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6b, 0x254, 0x254, 0x3b,
-0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6a, 0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b, 0x3b, 0x6d, 0x3b, 0x6b,
-0x3b, 0x6a, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61,
-0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73,
-0x69, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x48, 0x3b, 0x54, 0x3b,
-0x54, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0x3b, 0x6b, 0x77,
-0x61, 0x3b, 0x6d, 0x75, 0x6b, 0x3b, 0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73, 0x61, 0x3b, 0xe9, 0x74,
-0x69, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75, 0x6b, 0x254, 0x301, 0x73,
-0xfa, 0x3b, 0x14b, 0x67, 0x69, 0x73, 0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65, 0x73, 0x61, 0x253, 0x61,
-0x73, 0xfa, 0x3b, 0x65, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65, 0x3b, 0x44, 0x69, 0x6d,
-0x3b, 0x54, 0x65, 0x6e, 0x3b, 0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x72, 0x6a,
-0x3b, 0x53, 0x69, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b, 0x3b, 0x54, 0x61, 0x6c,
-0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x79,
-0x3b, 0x41, 0x72, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x54,
-0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73,
-0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73, 0xe9, 0x72, 0x3b, 0x73,
-0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20,
-0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d,
-0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259,
-0x6c, 0xfa, 0x20, 0x6d, 0x259, 0x301, 0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0xe9, 0x72,
-0x61, 0x64, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x73, 0x254,
-0x301, 0x6e, 0x3b, 0x6c, 0x1dd, 0x6e, 0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x3b, 0x6a,
-0xfa, 0x6d, 0x3b, 0x73, 0x61, 0x6d, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd, 0x6e, 0x64, 0xed, 0x3b,
-0x6d, 0x61, 0x61, 0x64, 0xed, 0x3b, 0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x64, 0xed, 0x3b,
-0x6a, 0xfa, 0x6d, 0x62, 0xe1, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b,
-0x6a, 0x3b, 0x6a, 0x3b, 0x73, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74,
-0x6e, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74, 0x6f,
-0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75,
-0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75,
-0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a,
-0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43, 0x7a, 0x69, 0x3b, 0x43,
-0x6b, 0x6f, 0x3b, 0x43, 0x6b, 0x61, 0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x27, 0x79,
-0x61, 0x6b, 0x6b, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79,
-0x69, 0x69, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x61,
-0x6c, 0x64, 0x1dd, 0x253, 0x6c, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75, 0x75, 0x3b, 0x43, 0x6f,
-0x6d, 0x7a, 0x79, 0x65, 0x253, 0x73, 0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x47,
-0x3b, 0x45, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c,
-0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x6d, 0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b,
-0x6d, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d,
-0xe1, 0x62, 0x61, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6c, 0x61,
-0x6c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6e, 0x61, 0x3b, 0x6d,
-0x61, 0x62, 0xe1, 0x67, 0xe1, 0x20, 0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73, 0xe1, 0x73, 0x61, 0x64,
-0x69, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x43, 0xe4, 0x14b, 0x3b,
-0x4a, 0x69, 0x65, 0x63, 0x3b, 0x52, 0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a, 0x75, 0x61, 0x61, 0x6e,
-0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4, 0x14b, 0x20, 0x6b, 0x75,
-0x254, 0x74, 0x68, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b, 0x77, 0x20, 0x6c, 0xe4,
-0x74, 0x6e, 0x69, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x14a, 0x75, 0x61, 0x61,
-0x6e, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69,
-0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a, 0x3b, 0x52, 0x3b, 0x44,
-0x3b, 0x14a, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x411, 0x441, 0x3b, 0x411, 0x43d, 0x3b, 0x41e, 0x43f, 0x3b, 0x421, 0x44d, 0x3b, 0x427,
-0x43f, 0x3b, 0x411, 0x44d, 0x3b, 0x421, 0x431, 0x3b, 0x411, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430, 0x43d, 0x43d, 0x44c, 0x430,
-0x3b, 0x411, 0x44d, 0x43d, 0x438, 0x434, 0x438, 0x44d, 0x43b, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x41e, 0x43f, 0x442, 0x443,
-0x43e, 0x440, 0x443, 0x43d, 0x43d, 0x44c, 0x443, 0x43a, 0x3b, 0x421, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x427, 0x44d, 0x43f, 0x43f,
-0x438, 0x44d, 0x440, 0x3b, 0x411, 0x44d, 0x44d, 0x442, 0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x421, 0x443, 0x431, 0x443, 0x43e, 0x442, 0x430,
-0x3b, 0x411, 0x3b, 0x411, 0x3b, 0x41e, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4a,
-0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a,
-0x6d, 0x6f, 0x3b, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b,
-0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61,
-0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f,
-0x73, 0x69, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x79, 0x65, 0x6e,
-0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x70, 0x69, 0x6c, 0x3b, 0x74, 0x61, 0x74, 0x3b, 0x69, 0x6e, 0x65, 0x3b, 0x74, 0x61, 0x6e,
-0x3b, 0x73, 0x69, 0x74, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x73,
-0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79,
-0x61, 0x20, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x74, 0x75, 0x3b,
-0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x69, 0x6e, 0x65, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20,
-0x74, 0x61, 0x6e, 0x75, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x79, 0x3b,
-0x6b, 0x3b, 0x70, 0x3b, 0x74, 0x3b, 0x69, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0xa55e, 0xa54c, 0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b,
-0xa55a, 0xa55e, 0xa55a, 0x3b, 0xa549, 0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b, 0xa549, 0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c,
-0xa533, 0x3b, 0x6c, 0x61, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e, 0x25b, 0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61,
-0x74, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69,
-0x6d, 0x61, 0x3b, 0x73, 0x69, 0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69,
-0x161, 0x3b, 0x4d, 0x69, 0x74, 0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75,
-0x6e, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x5a, 0x69, 0x161, 0x74, 0x61, 0x67, 0x3b,
-0x4d, 0x69, 0x74, 0x74, 0x77, 0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x74,
-0x61, 0x67, 0x3b, 0x53, 0x61, 0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46,
-0x3b, 0x46, 0x3b, 0x53, 0x3b, 0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77, 0x3b, 0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b,
-0x66, 0x6c, 0x3b, 0x73, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b, 0x3b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65,
-0x3b, 0x6d, 0x75, 0xe1, 0x6e, 0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b,
-0x70, 0xed, 0xe1, 0x70, 0x25b, 0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61,
-0x70, 0x25b, 0x3b, 0x66, 0x65, 0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73, 0x65, 0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d,
-0x3b, 0x6d, 0x3b, 0x65, 0x3b, 0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d,
-0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69, 0x65, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64,
-0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73,
-0x3b, 0x6d, 0x69, 0xe9, 0x72, 0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69,
-0x65, 0x6e, 0x72, 0x65, 0x73, 0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x53, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b,
-0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57,
-0x25b, 0x301, 0x6e, 0x25b, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c,
-0xe2, 0x79, 0x25b, 0x64, 0x25b, 0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b, 0x53, 0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301,
-0x3b, 0xc1, 0x4d, 0x3b, 0x57, 0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46, 0x25b, 0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254,
-0x6e, 0x64, 0x69, 0x3b, 0x6c, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b,
-0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x14b, 0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69,
-0x3b, 0x6d, 0x254, 0x6e, 0x254, 0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61,
-0x3b, 0x6d, 0x25b, 0x3b, 0x79, 0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b,
-0x41, 0x6e, 0x65, 0x67, 0x20, 0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x34,
-0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x36, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20,
-0x37, 0x3b, 0x41, 0x31, 0x3b, 0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34, 0x3b, 0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b,
-0x41, 0x37, 0x3b, 0x6c, 0x79, 0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed, 0x14b, 0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66,
-0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66,
-0xf2, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b,
-0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b,
-0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b,
-0x30c, 0x2bc, 0x3b, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b
+0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x31, 0x3b, 0x53,
+0xf6, 0x6e, 0x3b, 0x4d, 0xe5, 0x6e, 0x3b, 0x54, 0x69, 0x73, 0x3b, 0x4f, 0x6e, 0x73, 0x3b, 0x54, 0x6f, 0x72, 0x3b, 0x46,
+0x72, 0x65, 0x3b, 0x4c, 0xf6, 0x72, 0x3b, 0x53, 0xf6, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x4d, 0xe5, 0x6e, 0x64, 0x61, 0x67,
+0x3b, 0x54, 0x69, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x4f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x54, 0x6f, 0x72, 0x73, 0x64,
+0x61, 0x67, 0x3b, 0x46, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x4c, 0xf6, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf6, 0x6e,
+0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x69, 0x73, 0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x3b, 0x66, 0x72,
+0x65, 0x3b, 0x6c, 0xf6, 0x72, 0x3b, 0x73, 0xf6, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b,
+0x74, 0x69, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61,
+0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b, 0x6c, 0xf6, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x42f, 0x448, 0x431, 0x3b,
+0x414, 0x448, 0x431, 0x3b, 0x421, 0x448, 0x431, 0x3b, 0x427, 0x448, 0x431, 0x3b, 0x41f, 0x448, 0x431, 0x3b, 0x4b6, 0x43c, 0x44a, 0x3b,
+0x428, 0x43d, 0x431, 0x3b, 0x42f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x414, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b,
+0x421, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x427, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x41f, 0x430, 0x43d,
+0x4b7, 0x448, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0x4b6, 0x443, 0x43c, 0x44a, 0x430, 0x3b, 0x428, 0x430, 0x43d, 0x431, 0x435, 0x3b, 0xb9e,
+0xbbe, 0x3b, 0xba4, 0xbbf, 0x3b, 0xb9a, 0xbc6, 0x3b, 0xbaa, 0xbc1, 0x3b, 0xbb5, 0xbbf, 0x3b, 0xbb5, 0xbc6, 0x3b, 0xb9a, 0x3b, 0xb9e,
+0xbbe, 0xbaf, 0xbbf, 0xbb1, 0xbc1, 0x3b, 0xba4, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbb3, 0xbcd, 0x3b, 0xb9a, 0xbc6, 0xbb5, 0xbcd, 0xbb5, 0xbbe,
+0xbaf, 0xbcd, 0x3b, 0xbaa, 0xbc1, 0xba4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbbf, 0xbaf, 0xbbe, 0xbb4, 0xba9, 0xbcd, 0x3b, 0xbb5, 0xbc6, 0xbb3,
+0xbcd, 0xbb3, 0xbbf, 0x3b, 0xb9a, 0xba9, 0xbbf, 0x3b, 0xc06, 0xc26, 0xc3f, 0x3b, 0xc38, 0xc4b, 0xc2e, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33,
+0x3b, 0xc2c, 0xc41, 0xc27, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0x3b, 0xc36, 0xc28, 0xc3f, 0x3b,
+0xc06, 0xc26, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc38, 0xc4b, 0xc2e, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2e, 0xc02, 0xc17, 0xc33,
+0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc2c, 0xc41, 0xc27, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc17, 0xc41, 0xc30, 0xc41, 0xc35, 0xc3e, 0xc30,
+0xc02, 0x3b, 0xc36, 0xc41, 0xc15, 0xc4d, 0xc30, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b, 0xc36, 0xc28, 0xc3f, 0xc35, 0xc3e, 0xc30, 0xc02, 0x3b,
+0xc06, 0x3b, 0xc38, 0xc4b, 0x3b, 0xc2e, 0x3b, 0xc2c, 0xc41, 0x3b, 0xc17, 0xc41, 0x3b, 0xc36, 0xc41, 0x3b, 0xc36, 0x3b, 0xe2d, 0xe32,
+0x2e, 0x3b, 0xe08, 0x2e, 0x3b, 0xe2d, 0x2e, 0x3b, 0xe1e, 0x2e, 0x3b, 0xe1e, 0xe24, 0x2e, 0x3b, 0xe28, 0x2e, 0x3b, 0xe2a, 0x2e,
+0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe32, 0xe17, 0xe34, 0xe15, 0xe22, 0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe08, 0xe31, 0xe19, 0xe17, 0xe23,
+0xe4c, 0x3b, 0xe27, 0xe31, 0xe19, 0xe2d, 0xe31, 0xe07, 0xe04, 0xe32, 0xe23, 0x3b, 0xe27, 0xe31, 0xe19, 0xe1e, 0xe38, 0xe18, 0x3b, 0xe27,
+0xe31, 0xe19, 0xe1e, 0xe24, 0xe2b, 0xe31, 0xe2a, 0xe1a, 0xe14, 0xe35, 0x3b, 0xe27, 0xe31, 0xe19, 0xe28, 0xe38, 0xe01, 0xe23, 0xe4c, 0x3b,
+0xe27, 0xe31, 0xe19, 0xe40, 0xe2a, 0xe32, 0xe23, 0xe4c, 0x3b, 0xe2d, 0xe32, 0x3b, 0xe08, 0x3b, 0xe2d, 0x3b, 0xe1e, 0x3b, 0xe1e, 0xe24,
+0x3b, 0xe28, 0x3b, 0xe2a, 0x3b, 0xf49, 0xf72, 0xf0b, 0xf58, 0xf0b, 0x3b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf58, 0xf72, 0xf42,
+0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf67, 0xfb3, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b,
+0x3b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf49, 0xf72,
+0xf0b, 0xf58, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf5f, 0xfb3, 0xf0b, 0xf56, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf58, 0xf72,
+0xf42, 0xf0b, 0xf51, 0xf58, 0xf62, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf67, 0xfb3, 0xf42, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf42, 0xf5f,
+0xf60, 0xf0b, 0xf55, 0xf74, 0xf62, 0xf0b, 0xf56, 0xf74, 0xf0b, 0x3b, 0xf42, 0xf5f, 0xf60, 0xf0b, 0xf66, 0xf44, 0xf66, 0xf0b, 0x3b, 0xf42,
+0xf5f, 0xf60, 0xf0b, 0xf66, 0xfa4, 0xf7a, 0xf53, 0xf0b, 0xf54, 0xf0b, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72, 0x3b,
+0xf67, 0xfb3, 0x3b, 0xf55, 0xf74, 0x3b, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0x3b, 0xf49, 0xf72, 0x3b, 0xf5f, 0xfb3, 0x3b, 0xf58, 0xf72,
+0x3b, 0xf67, 0xfb3, 0xf42, 0x3b, 0xf55, 0xf74, 0x3b, 0xf66, 0x3b, 0xf66, 0xfa4, 0xf7a, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x3b, 0x1230,
+0x1291, 0x12ed, 0x3b, 0x1220, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1283, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d, 0x1262, 0x3b, 0x1240,
+0x12f3, 0x121d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1220, 0x3b, 0x1228, 0x3b, 0x1283, 0x3b, 0x12d3, 0x3b, 0x1240, 0x3b, 0x1230, 0x1295, 0x1260,
+0x1275, 0x3b, 0x1230, 0x1291, 0x12ed, 0x3b, 0x1230, 0x1209, 0x1235, 0x3b, 0x1228, 0x1261, 0x12d5, 0x3b, 0x1213, 0x1219, 0x1235, 0x3b, 0x12d3, 0x122d,
+0x1262, 0x3b, 0x1240, 0x12f3, 0x121d, 0x3b, 0x53, 0x101, 0x70, 0x3b, 0x4d, 0x14d, 0x6e, 0x3b, 0x54, 0x16b, 0x73, 0x3b, 0x50, 0x75,
+0x6c, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x3b, 0x46, 0x61, 0x6c, 0x3b, 0x54, 0x6f, 0x6b, 0x3b, 0x53, 0x101, 0x70, 0x61, 0x74,
+0x65, 0x3b, 0x4d, 0x14d, 0x6e, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x16b, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x50, 0x75, 0x6c, 0x65,
+0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x54, 0x75, 0x2bb, 0x61, 0x70, 0x75, 0x6c, 0x65, 0x6c, 0x75, 0x6c, 0x75, 0x3b, 0x46, 0x61,
+0x6c, 0x61, 0x69, 0x74, 0x65, 0x3b, 0x54, 0x6f, 0x6b, 0x6f, 0x6e, 0x61, 0x6b, 0x69, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54,
+0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x46, 0x3b, 0x54, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x42, 0x69, 0x72,
+0x3b, 0x48, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x54, 0x6c, 0x68, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x6f, 0x6e, 0x74,
+0x6f, 0x3b, 0x4d, 0x75, 0x73, 0x75, 0x6d, 0x62, 0x68, 0x75, 0x6e, 0x75, 0x6b, 0x75, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6d,
+0x62, 0x69, 0x72, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x68, 0x61, 0x72, 0x68, 0x75, 0x3b, 0x52, 0x61, 0x76,
+0x75, 0x6d, 0x75, 0x6e, 0x65, 0x3b, 0x52, 0x61, 0x76, 0x75, 0x6e, 0x74, 0x6c, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75,
+0x67, 0x71, 0x69, 0x76, 0x65, 0x6c, 0x61, 0x3b, 0x50, 0x61, 0x7a, 0x3b, 0x50, 0x7a, 0x74, 0x3b, 0x53, 0x61, 0x6c, 0x3b,
+0xc7, 0x61, 0x72, 0x3b, 0x50, 0x65, 0x72, 0x3b, 0x43, 0x75, 0x6d, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x50, 0x61, 0x7a, 0x61,
+0x72, 0x3b, 0x50, 0x61, 0x7a, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x131, 0x3b, 0xc7, 0x61, 0x72,
+0x15f, 0x61, 0x6d, 0x62, 0x61, 0x3b, 0x50, 0x65, 0x72, 0x15f, 0x65, 0x6d, 0x62, 0x65, 0x3b, 0x43, 0x75, 0x6d, 0x61, 0x3b,
+0x43, 0x75, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x50, 0x3b, 0x53, 0x3b, 0xc7, 0x3b, 0x50, 0x3b,
+0x43, 0x3b, 0x43, 0x3b, 0x41d, 0x434, 0x3b, 0x41f, 0x43d, 0x3b, 0x412, 0x442, 0x3b, 0x421, 0x440, 0x3b, 0x427, 0x442, 0x3b, 0x41f,
+0x442, 0x3b, 0x421, 0x431, 0x3b, 0x41d, 0x435, 0x434, 0x456, 0x43b, 0x44f, 0x3b, 0x41f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e,
+0x43a, 0x3b, 0x412, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a, 0x3b, 0x421, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x427, 0x435,
+0x442, 0x432, 0x435, 0x440, 0x3b, 0x41f, 0x2bc, 0x44f, 0x442, 0x43d, 0x438, 0x446, 0x44f, 0x3b, 0x421, 0x443, 0x431, 0x43e, 0x442, 0x430,
+0x3b, 0x41d, 0x3b, 0x41f, 0x3b, 0x412, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x421, 0x3b, 0x43d, 0x435, 0x434, 0x456, 0x43b,
+0x44f, 0x3b, 0x43f, 0x43e, 0x43d, 0x435, 0x434, 0x456, 0x43b, 0x43e, 0x43a, 0x3b, 0x432, 0x456, 0x432, 0x442, 0x43e, 0x440, 0x43e, 0x43a,
+0x3b, 0x441, 0x435, 0x440, 0x435, 0x434, 0x430, 0x3b, 0x447, 0x435, 0x442, 0x432, 0x435, 0x440, 0x3b, 0x43f, 0x2bc, 0x44f, 0x442, 0x43d,
+0x438, 0x446, 0x44f, 0x3b, 0x441, 0x443, 0x431, 0x43e, 0x442, 0x430, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x633, 0x648, 0x645,
+0x648, 0x627, 0x631, 0x3b, 0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b,
+0x62c, 0x645, 0x639, 0x6c1, 0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x627, 0x62a, 0x648, 0x627, 0x631, 0x3b, 0x67e, 0x6cc, 0x631, 0x3b,
+0x645, 0x646, 0x6af, 0x644, 0x3b, 0x628, 0x62f, 0x6be, 0x3b, 0x62c, 0x645, 0x639, 0x631, 0x627, 0x62a, 0x3b, 0x62c, 0x645, 0x639, 0x6c1,
+0x3b, 0x6c1, 0x641, 0x62a, 0x6c1, 0x3b, 0x59, 0x61, 0x6b, 0x73, 0x68, 0x3b, 0x44, 0x75, 0x73, 0x68, 0x3b, 0x53, 0x65, 0x73,
+0x68, 0x3b, 0x43, 0x68, 0x6f, 0x72, 0x3b, 0x50, 0x61, 0x79, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x53, 0x68, 0x61, 0x6e, 0x3b,
+0x79, 0x61, 0x6b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x64, 0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x73,
+0x65, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x63, 0x68, 0x6f, 0x72, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x70,
+0x61, 0x79, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x61,
+0x3b, 0x59, 0x3b, 0x44, 0x3b, 0x53, 0x3b, 0x43, 0x3b, 0x50, 0x3b, 0x4a, 0x3b, 0x53, 0x3b, 0x6cc, 0x2e, 0x3b, 0x62f, 0x2e,
+0x3b, 0x633, 0x2e, 0x3b, 0x686, 0x2e, 0x3b, 0x67e, 0x2e, 0x3b, 0x62c, 0x2e, 0x3b, 0x634, 0x2e, 0x3b, 0x42f, 0x43a, 0x448, 0x3b,
+0x414, 0x443, 0x448, 0x3b, 0x421, 0x435, 0x448, 0x3b, 0x427, 0x43e, 0x440, 0x3b, 0x41f, 0x430, 0x439, 0x3b, 0x416, 0x443, 0x43c, 0x3b,
+0x428, 0x430, 0x43d, 0x3b, 0x44f, 0x43a, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x434, 0x443, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b,
+0x441, 0x435, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x447, 0x43e, 0x440, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x43f, 0x430, 0x439,
+0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x436, 0x443, 0x43c, 0x430, 0x3b, 0x448, 0x430, 0x43d, 0x431, 0x430, 0x3b, 0x42f, 0x3b, 0x414,
+0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x41f, 0x3b, 0x416, 0x3b, 0x428, 0x3b, 0x43, 0x4e, 0x3b, 0x54, 0x68, 0x20, 0x32, 0x3b, 0x54,
+0x68, 0x20, 0x33, 0x3b, 0x54, 0x68, 0x20, 0x34, 0x3b, 0x54, 0x68, 0x20, 0x35, 0x3b, 0x54, 0x68, 0x20, 0x36, 0x3b, 0x54,
+0x68, 0x20, 0x37, 0x3b, 0x43, 0x68, 0x1ee7, 0x20, 0x4e, 0x68, 0x1ead, 0x74, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x48, 0x61, 0x69,
+0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x61, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x54, 0x1b0, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x4e,
+0x103, 0x6d, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x53, 0xe1, 0x75, 0x3b, 0x54, 0x68, 0x1ee9, 0x20, 0x42, 0x1ea3, 0x79, 0x3b, 0x43,
+0x4e, 0x3b, 0x54, 0x32, 0x3b, 0x54, 0x33, 0x3b, 0x54, 0x34, 0x3b, 0x54, 0x35, 0x3b, 0x54, 0x36, 0x3b, 0x54, 0x37, 0x3b,
+0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61, 0x75,
+0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x79,
+0x64, 0x64, 0x20, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x61, 0x77, 0x72, 0x74, 0x68, 0x3b,
+0x44, 0x79, 0x64, 0x64, 0x20, 0x4d, 0x65, 0x72, 0x63, 0x68, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x49, 0x61,
+0x75, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72, 0x3b, 0x44, 0x79, 0x64, 0x64, 0x20, 0x53,
+0x61, 0x64, 0x77, 0x72, 0x6e, 0x3b, 0x53, 0x3b, 0x4c, 0x6c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x49, 0x3b, 0x47, 0x3b, 0x53,
+0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x6c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x77, 0x3b, 0x4d, 0x65, 0x72, 0x3b, 0x49, 0x61,
+0x75, 0x3b, 0x47, 0x77, 0x65, 0x6e, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x43, 0x61, 0x77, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x42,
+0x69, 0x6e, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x43,
+0x61, 0x77, 0x65, 0x3b, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6e, 0x69, 0x3b,
+0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65, 0x3b,
+0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b,
+0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a, 0xe9, 0x3b, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd,
+0x301, 0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1eb8, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9,
+0x301, 0x74, 0x61, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x41,
+0x6a, 0xe9, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0xcc, 0x73, 0x1eb9, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301,
+0x72, 0xfa, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x62, 0x1ecd, 0x3b, 0x1ecc, 0x6a, 0x1ecd, 0x301, 0x20, 0x1eb8, 0x74, 0xec, 0x3b, 0x1ecc,
+0x6a, 0x1ecd, 0x301, 0x20, 0xc0, 0x62, 0xe1, 0x6d, 0x1eb9, 0x301, 0x74, 0x61, 0x3b, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x41, 0x6a,
+0xe9, 0x3b, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254,
+0x301, 0x62, 0x254, 0x3b, 0x190, 0x74, 0xec, 0x3b, 0xc0, 0x62, 0xe1, 0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x186, 0x6a, 0x254,
+0x301, 0x20, 0xc0, 0xec, 0x6b, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0x41, 0x6a, 0xe9, 0x3b, 0x186, 0x6a, 0x254, 0x301,
+0x20, 0xcc, 0x73, 0x25b, 0x301, 0x67, 0x75, 0x6e, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x72, 0xfa, 0x3b, 0x186, 0x6a, 0x254, 0x301,
+0x62, 0x254, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0x190, 0x74, 0xec, 0x3b, 0x186, 0x6a, 0x254, 0x301, 0x20, 0xc0, 0x62, 0xe1,
+0x6d, 0x25b, 0x301, 0x74, 0x61, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x73, 0x6f, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68,
+0x61, 0x3b, 0x53, 0x69, 0x6e, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b,
+0x4d, 0x73, 0x6f, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x6b, 0x6f, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69,
+0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x6e, 0x65,
+0x3b, 0x4c, 0x77, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f,
+0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x42, 0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x54,
+0x3b, 0x54, 0x3b, 0x53, 0x3b, 0x48, 0x3b, 0x4d, 0x3b, 0x73, 0xf8, 0x6e, 0x3b, 0x6d, 0xe5, 0x6e, 0x3b, 0x74, 0x79, 0x73,
+0x3b, 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x6f, 0x72, 0x3b, 0x66, 0x72, 0x65, 0x3b, 0x6c, 0x61, 0x75, 0x3b, 0x73, 0xf8, 0x6e,
+0x64, 0x61, 0x67, 0x3b, 0x6d, 0xe5, 0x6e, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x79, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x6f, 0x6e,
+0x73, 0x64, 0x61, 0x67, 0x3b, 0x74, 0x6f, 0x72, 0x73, 0x64, 0x61, 0x67, 0x3b, 0x66, 0x72, 0x65, 0x64, 0x61, 0x67, 0x3b,
+0x6c, 0x61, 0x75, 0x72, 0x64, 0x61, 0x67, 0x3b, 0x73, 0xf8, 0x2e, 0x3b, 0x6d, 0xe5, 0x2e, 0x3b, 0x74, 0x79, 0x2e, 0x3b,
+0x6f, 0x6e, 0x2e, 0x3b, 0x74, 0x6f, 0x2e, 0x3b, 0x66, 0x72, 0x2e, 0x3b, 0x6c, 0x61, 0x2e, 0x3b, 0x4a, 0x65, 0x64, 0x3b,
+0x4a, 0x65, 0x6c, 0x3b, 0x4a, 0x65, 0x6d, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x3b, 0x4a, 0x65, 0x72, 0x64, 0x3b, 0x4a, 0x65,
+0x68, 0x3b, 0x4a, 0x65, 0x73, 0x3b, 0x4a, 0x65, 0x64, 0x6f, 0x6f, 0x6e, 0x65, 0x65, 0x3b, 0x4a, 0x65, 0x6c, 0x68, 0x65,
+0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x6d, 0x61, 0x79, 0x72, 0x74, 0x3b, 0x4a, 0x65, 0x72, 0x63, 0x65, 0x61, 0x6e, 0x3b, 0x4a,
+0x65, 0x72, 0x64, 0x65, 0x69, 0x6e, 0x3b, 0x4a, 0x65, 0x68, 0x65, 0x69, 0x6e, 0x65, 0x79, 0x3b, 0x4a, 0x65, 0x73, 0x61,
+0x72, 0x6e, 0x3b, 0x53, 0x75, 0x6c, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x74, 0x68, 0x3b, 0x4d, 0x68, 0x72, 0x3b, 0x59,
+0x6f, 0x77, 0x3b, 0x47, 0x77, 0x65, 0x3b, 0x53, 0x61, 0x64, 0x3b, 0x44, 0x65, 0x20, 0x53, 0x75, 0x6c, 0x3b, 0x44, 0x65,
+0x20, 0x4c, 0x75, 0x6e, 0x3b, 0x44, 0x65, 0x20, 0x4d, 0x65, 0x72, 0x74, 0x68, 0x3b, 0x44, 0x65, 0x20, 0x4d, 0x65, 0x72,
+0x68, 0x65, 0x72, 0x3b, 0x44, 0x65, 0x20, 0x59, 0x6f, 0x77, 0x3b, 0x44, 0x65, 0x20, 0x47, 0x77, 0x65, 0x6e, 0x65, 0x72,
+0x3b, 0x44, 0x65, 0x20, 0x53, 0x61, 0x64, 0x6f, 0x72, 0x6e, 0x3b, 0x4b, 0x77, 0x65, 0x3b, 0x44, 0x77, 0x6f, 0x3b, 0x42,
+0x65, 0x6e, 0x3b, 0x57, 0x75, 0x6b, 0x3b, 0x59, 0x61, 0x77, 0x3b, 0x46, 0x69, 0x61, 0x3b, 0x4d, 0x65, 0x6d, 0x3b, 0x4b,
+0x77, 0x65, 0x73, 0x69, 0x64, 0x61, 0x3b, 0x44, 0x77, 0x6f, 0x77, 0x64, 0x61, 0x3b, 0x42, 0x65, 0x6e, 0x61, 0x64, 0x61,
+0x3b, 0x57, 0x75, 0x6b, 0x75, 0x64, 0x61, 0x3b, 0x59, 0x61, 0x77, 0x64, 0x61, 0x3b, 0x46, 0x69, 0x64, 0x61, 0x3b, 0x4d,
+0x65, 0x6d, 0x65, 0x6e, 0x65, 0x64, 0x61, 0x3b, 0x4b, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x57, 0x3b, 0x59, 0x3b, 0x46, 0x3b,
+0x4d, 0x3b, 0x906, 0x926, 0x93f, 0x924, 0x94d, 0x92f, 0x935, 0x93e, 0x930, 0x3b, 0x938, 0x94b, 0x92e, 0x935, 0x93e, 0x930, 0x3b, 0x92e,
+0x902, 0x917, 0x933, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x927, 0x935, 0x93e, 0x930, 0x3b, 0x917, 0x941, 0x930, 0x941, 0x935, 0x93e, 0x930,
+0x3b, 0x936, 0x941, 0x915, 0x94d, 0x930, 0x935, 0x93e, 0x930, 0x3b, 0x936, 0x928, 0x93f, 0x935, 0x93e, 0x930, 0x3b, 0x1ee4, 0x6b, 0x61,
+0x3b, 0x4d, 0x1ecd, 0x6e, 0x3b, 0x54, 0x69, 0x75, 0x3b, 0x57, 0x65, 0x6e, 0x3b, 0x54, 0x1ecd, 0x1ecd, 0x3b, 0x46, 0x72, 0x61,
+0x1ecb, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x4d, 0x62, 0x1ecd, 0x73, 0x1ecb, 0x20, 0x1ee4, 0x6b, 0x61, 0x3b, 0x4d, 0x1ecd, 0x6e, 0x64,
+0x65, 0x3b, 0x54, 0x69, 0x75, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x57, 0x65, 0x6e, 0x65, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x54,
+0x1ecd, 0x1ecd, 0x7a, 0x64, 0x65, 0x65, 0x3b, 0x46, 0x72, 0x61, 0x1ecb, 0x64, 0x65, 0x65, 0x3b, 0x53, 0x61, 0x74, 0x1ecd, 0x64,
+0x65, 0x65, 0x3b, 0x57, 0x6b, 0x79, 0x3b, 0x57, 0x6b, 0x77, 0x3b, 0x57, 0x6b, 0x6c, 0x3b, 0x57, 0x74, 0x169, 0x3b, 0x57,
+0x6b, 0x6e, 0x3b, 0x57, 0x74, 0x6e, 0x3b, 0x57, 0x74, 0x68, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x79, 0x75, 0x6d, 0x77, 0x61,
+0x3b, 0x57, 0x61, 0x20, 0x6b, 0x77, 0x61, 0x6d, 0x62, 0x129, 0x6c, 0x129, 0x6c, 0x79, 0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b,
+0x65, 0x6c, 0x129, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x6e,
+0x61, 0x3b, 0x57, 0x61, 0x20, 0x6b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x57, 0x61, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x74,
+0x68, 0x61, 0x74, 0x169, 0x3b, 0x59, 0x3b, 0x57, 0x3b, 0x45, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x1230,
+0x2f, 0x1245, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d, 0x3b, 0x1208, 0x1313, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265,
+0x3b, 0x1230, 0x2f, 0x123d, 0x3b, 0x1230, 0x1295, 0x1260, 0x122d, 0x20, 0x1245, 0x12f3, 0x12c5, 0x3b, 0x1230, 0x1291, 0x3b, 0x1230, 0x120a, 0x131d,
+0x3b, 0x1208, 0x1313, 0x20, 0x12c8, 0x122a, 0x20, 0x1208, 0x1265, 0x12cb, 0x3b, 0x12a3, 0x121d, 0x12f5, 0x3b, 0x12a3, 0x122d, 0x1265, 0x3b, 0x1230,
+0x1295, 0x1260, 0x122d, 0x20, 0x123d, 0x1313, 0x12c5, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1208, 0x3b, 0x12a3, 0x3b, 0x12a3, 0x3b,
+0x1230, 0x3b, 0x1230, 0x2f, 0x12d3, 0x3b, 0x1230, 0x1296, 0x3b, 0x1273, 0x120b, 0x1238, 0x3b, 0x12a3, 0x1228, 0x122d, 0x3b, 0x12a8, 0x121a, 0x123d,
+0x3b, 0x1305, 0x121d, 0x12d3, 0x3b, 0x1230, 0x2f, 0x1295, 0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x20, 0x12d3, 0x1263, 0x12ed, 0x3b, 0x1230, 0x1296,
+0x3b, 0x1273, 0x120b, 0x1238, 0x1296, 0x3b, 0x12a3, 0x1228, 0x122d, 0x1263, 0x12d3, 0x3b, 0x12a8, 0x121a, 0x123d, 0x3b, 0x1305, 0x121d, 0x12d3, 0x1275,
+0x3b, 0x1230, 0x1295, 0x1260, 0x1275, 0x20, 0x1295, 0x12a2, 0x123d, 0x3b, 0x1230, 0x3b, 0x1230, 0x3b, 0x1273, 0x3b, 0x12a3, 0x3b, 0x12a8, 0x3b,
+0x1305, 0x3b, 0x1230, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x75, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69, 0x65, 0x3b,
+0x6a, 0x6f, 0x69, 0x3b, 0x76, 0x69, 0x6e, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x65, 0x6e, 0x69, 0x65, 0x3b,
+0x6c, 0x75, 0x6e, 0x69, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x61, 0x72, 0x73, 0x3b, 0x6d, 0x69, 0x65, 0x72, 0x63, 0x75,
+0x73, 0x3b, 0x6a, 0x6f, 0x69, 0x62, 0x65, 0x3b, 0x76, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x69, 0x64,
+0x65, 0x3b, 0x53, 0x77, 0x6f, 0x3b, 0x4d, 0x75, 0x73, 0x3b, 0x56, 0x68, 0x69, 0x3b, 0x52, 0x61, 0x72, 0x3b, 0x1e4a, 0x61,
+0x3b, 0x1e70, 0x61, 0x6e, 0x3b, 0x4d, 0x75, 0x67, 0x3b, 0x53, 0x77, 0x6f, 0x6e, 0x64, 0x61, 0x68, 0x61, 0x3b, 0x4d, 0x75,
+0x73, 0x75, 0x6d, 0x62, 0x75, 0x6c, 0x75, 0x77, 0x6f, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x76, 0x68, 0x69, 0x6c, 0x69,
+0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x72, 0x61, 0x72, 0x75, 0x3b, 0x1e3c, 0x61, 0x76, 0x68, 0x75, 0x1e4b, 0x61, 0x3b, 0x1e3c,
+0x61, 0x76, 0x68, 0x75, 0x1e71, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x75, 0x67, 0x69, 0x76, 0x68, 0x65, 0x6c, 0x61, 0x3b, 0x6b,
+0x254, 0x73, 0x3b, 0x64, 0x7a, 0x6f, 0x3b, 0x62, 0x6c, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x3b, 0x79, 0x61, 0x77, 0x3b, 0x66,
+0x69, 0x256, 0x3b, 0x6d, 0x65, 0x6d, 0x3b, 0x6b, 0x254, 0x73, 0x69, 0x256, 0x61, 0x3b, 0x64, 0x7a, 0x6f, 0x256, 0x61, 0x3b,
+0x62, 0x6c, 0x61, 0x256, 0x61, 0x3b, 0x6b, 0x75, 0x256, 0x61, 0x3b, 0x79, 0x61, 0x77, 0x6f, 0x256, 0x61, 0x3b, 0x66, 0x69,
+0x256, 0x61, 0x3b, 0x6d, 0x65, 0x6d, 0x6c, 0x65, 0x256, 0x61, 0x3b, 0x6b, 0x3b, 0x64, 0x3b, 0x62, 0x3b, 0x6b, 0x3b, 0x79,
+0x3b, 0x66, 0x3b, 0x6d, 0x3b, 0x12c8, 0x130b, 0x3b, 0x1233, 0x12ed, 0x1296, 0x3b, 0x121b, 0x1246, 0x1233, 0x129b, 0x3b, 0x12a0, 0x1229, 0x12cb,
+0x3b, 0x1203, 0x1219, 0x1233, 0x3b, 0x12a0, 0x122d, 0x1263, 0x3b, 0x1244, 0x122b, 0x3b, 0x12c8, 0x3b, 0x1233, 0x3b, 0x121b, 0x3b, 0x12a0, 0x3b,
+0x1203, 0x3b, 0x12a0, 0x3b, 0x1244, 0x3b, 0x4c, 0x50, 0x3b, 0x50, 0x31, 0x3b, 0x50, 0x32, 0x3b, 0x50, 0x33, 0x3b, 0x50, 0x34,
+0x3b, 0x50, 0x35, 0x3b, 0x50, 0x36, 0x3b, 0x4c, 0x101, 0x70, 0x75, 0x6c, 0x65, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x61,
+0x68, 0x69, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x75, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6b, 0x6f, 0x6c, 0x75, 0x3b,
+0x50, 0x6f, 0x2bb, 0x61, 0x68, 0x101, 0x3b, 0x50, 0x6f, 0x2bb, 0x61, 0x6c, 0x69, 0x6d, 0x61, 0x3b, 0x50, 0x6f, 0x2bb, 0x61,
+0x6f, 0x6e, 0x6f, 0x3b, 0x4c, 0x69, 0x6e, 0x3b, 0x4c, 0x75, 0x6e, 0x3b, 0x4d, 0x61, 0x72, 0x3b, 0x4d, 0x69, 0x79, 0x3b,
+0x48, 0x75, 0x77, 0x3b, 0x42, 0x69, 0x79, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4c, 0x69, 0x6e, 0x67, 0x67, 0x6f, 0x3b, 0x4c,
+0x75, 0x6e, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x4d, 0x69, 0x79, 0x65, 0x72, 0x6b, 0x75, 0x6c,
+0x65, 0x73, 0x3b, 0x48, 0x75, 0x77, 0x65, 0x62, 0x65, 0x73, 0x3b, 0x42, 0x69, 0x79, 0x65, 0x72, 0x6e, 0x65, 0x73, 0x3b,
+0x53, 0x61, 0x62, 0x61, 0x64, 0x6f, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4d, 0x3b, 0x4d, 0x3b, 0x48, 0x3b, 0x42, 0x3b, 0x53,
+0x3b, 0x53, 0x75, 0x2e, 0x3b, 0x4d, 0xe4, 0x2e, 0x3b, 0x5a, 0x69, 0x2e, 0x3b, 0x4d, 0x69, 0x2e, 0x3b, 0x44, 0x75, 0x2e,
+0x3b, 0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0xe4, 0xe4,
+0x6e, 0x74, 0x69, 0x67, 0x3b, 0x5a, 0x69, 0x69, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77,
+0x75, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x69, 0x74, 0x69,
+0x67, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x63, 0x68, 0x74, 0x69, 0x67, 0x3b, 0xa46d, 0xa18f, 0x3b, 0xa18f, 0xa2cd, 0x3b, 0xa18f, 0xa44d,
+0x3b, 0xa18f, 0xa315, 0x3b, 0xa18f, 0xa1d6, 0x3b, 0xa18f, 0xa26c, 0x3b, 0xa18f, 0xa0d8, 0x3b, 0xa46d, 0xa18f, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa2cd,
+0x3b, 0xa18f, 0xa282, 0xa44d, 0x3b, 0xa18f, 0xa282, 0xa315, 0x3b, 0xa18f, 0xa282, 0xa1d6, 0x3b, 0xa18f, 0xa282, 0xa26c, 0x3b, 0xa18f, 0xa282, 0xa0d8,
+0x3b, 0xa18f, 0x3b, 0xa2cd, 0x3b, 0xa44d, 0x3b, 0xa315, 0x3b, 0xa1d6, 0x3b, 0xa26c, 0x3b, 0xa0d8, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d,
+0x76, 0x75, 0x3b, 0x42, 0x69, 0x6c, 0x3b, 0x54, 0x68, 0x61, 0x3b, 0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x47, 0x71,
+0x69, 0x3b, 0x75, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x75, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b, 0x75, 0x4c, 0x65, 0x73,
+0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x65, 0x73, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x75, 0x4c, 0x65,
+0x73, 0x69, 0x6e, 0x65, 0x3b, 0x6e, 0x67, 0x6f, 0x4c, 0x65, 0x73, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x75, 0x6d,
+0x47, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x6f, 0x73, 0x3b, 0x42, 0x65, 0x64, 0x3b,
+0x52, 0x61, 0x72, 0x3b, 0x4e, 0x65, 0x3b, 0x48, 0x6c, 0x61, 0x3b, 0x4d, 0x6f, 0x6b, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61,
+0x67, 0x61, 0x3b, 0x4d, 0x6f, 0x73, 0x75, 0x70, 0x61, 0x6c, 0x6f, 0x67, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x62, 0x65,
+0x64, 0x69, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x72, 0x61, 0x72, 0x6f, 0x3b, 0x4c, 0x61, 0x62, 0x6f, 0x6e, 0x65, 0x3b, 0x4c,
+0x61, 0x62, 0x6f, 0x68, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x6f, 0x6b, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x73, 0x6f,
+0x74, 0x6e, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x3b, 0x6d, 0x61, 0x14b, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x3b, 0x64, 0x75, 0x6f,
+0x72, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x3b, 0x6c, 0xe1, 0x76, 0x3b, 0x73, 0x6f, 0x74, 0x6e, 0x61, 0x62, 0x65, 0x61, 0x69,
+0x76, 0x69, 0x3b, 0x76, 0x75, 0x6f, 0x73, 0x73, 0xe1, 0x72, 0x67, 0x61, 0x3b, 0x6d, 0x61, 0x14b, 0x14b, 0x65, 0x62, 0xe1,
+0x72, 0x67, 0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x61, 0x76, 0x61, 0x68, 0x6b, 0x6b, 0x75, 0x3b, 0x64, 0x75, 0x6f, 0x72,
+0x61, 0x73, 0x64, 0x61, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x74, 0x3b, 0x6c, 0xe1, 0x76, 0x76,
+0x61, 0x72, 0x64, 0x61, 0x74, 0x3b, 0x53, 0x3b, 0x56, 0x3b, 0x4d, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b,
+0x61, 0x65, 0x6a, 0x6c, 0x65, 0x67, 0x65, 0x3b, 0x6d, 0xe5, 0x61, 0x6e, 0x74, 0x61, 0x3b, 0x64, 0xe4, 0x6a, 0x73, 0x74,
+0x61, 0x3b, 0x67, 0x61, 0x73, 0x6b, 0x65, 0x76, 0x61, 0x68, 0x6b, 0x6f, 0x65, 0x3b, 0x64, 0xe5, 0x61, 0x72, 0x73, 0x74,
+0x61, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x6a, 0x61, 0x64, 0x61, 0x68, 0x6b, 0x65, 0x3b, 0x6c, 0x61, 0x61, 0x76, 0x61, 0x64,
+0x61, 0x68, 0x6b, 0x65, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x44, 0x3b, 0x47, 0x3b, 0x44, 0x3b, 0x42, 0x3b, 0x4c, 0x3b, 0x43,
+0x70, 0x72, 0x3b, 0x43, 0x74, 0x74, 0x3b, 0x43, 0x6d, 0x6e, 0x3b, 0x43, 0x6d, 0x74, 0x3b, 0x41, 0x72, 0x73, 0x3b, 0x49,
+0x63, 0x6d, 0x3b, 0x45, 0x73, 0x74, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x75,
+0x6d, 0x61, 0x74, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x68, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x43, 0x68, 0x75, 0x6d,
+0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x63, 0x68, 0x75, 0x6d, 0x61,
+0x3b, 0x45, 0x73, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x43, 0x3b, 0x41, 0x3b, 0x49,
+0x3b, 0x45, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x4a, 0x69, 0x6d, 0x3b, 0x4b, 0x61, 0x77, 0x3b, 0x4b, 0x61, 0x64, 0x3b, 0x4b,
+0x61, 0x6e, 0x3b, 0x4b, 0x61, 0x73, 0x3b, 0x4e, 0x67, 0x75, 0x3b, 0x49, 0x74, 0x75, 0x6b, 0x75, 0x20, 0x6a, 0x61, 0x20,
+0x6a, 0x75, 0x6d, 0x77, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6a, 0x69, 0x6d, 0x77, 0x65,
+0x72, 0x69, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x77, 0x69, 0x3b, 0x4b, 0x75, 0x72,
+0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x64, 0x61, 0x64, 0x75, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b,
+0x61, 0x20, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x72, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x20, 0x6b, 0x61, 0x73, 0x61,
+0x6e, 0x75, 0x3b, 0x4b, 0x69, 0x66, 0x75, 0x6c, 0x61, 0x20, 0x6e, 0x67, 0x75, 0x77, 0x6f, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b,
+0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x64, 0x65, 0x77, 0x3b, 0x61, 0x61, 0x253, 0x3b, 0x6d, 0x61,
+0x77, 0x3b, 0x6e, 0x6a, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x3b, 0x6d, 0x77, 0x64, 0x3b, 0x68, 0x62, 0x69, 0x3b, 0x64, 0x65,
+0x77, 0x6f, 0x3b, 0x61, 0x61, 0x253, 0x6e, 0x64, 0x65, 0x3b, 0x6d, 0x61, 0x77, 0x62, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e,
+0x6a, 0x65, 0x73, 0x6c, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x6e, 0x61, 0x61, 0x73, 0x61, 0x61, 0x6e, 0x64, 0x65, 0x3b, 0x6d,
+0x61, 0x77, 0x6e, 0x64, 0x65, 0x3b, 0x68, 0x6f, 0x6f, 0x72, 0x65, 0x2d, 0x62, 0x69, 0x69, 0x72, 0x3b, 0x64, 0x3b, 0x61,
+0x3b, 0x6d, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x6d, 0x3b, 0x68, 0x3b, 0x4b, 0x4d, 0x41, 0x3b, 0x4e, 0x54, 0x54, 0x3b, 0x4e,
+0x4d, 0x4e, 0x3b, 0x4e, 0x4d, 0x54, 0x3b, 0x41, 0x52, 0x54, 0x3b, 0x4e, 0x4d, 0x41, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b,
+0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x169, 0x3b, 0x4e, 0x6a, 0x75, 0x6d,
+0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x61, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69,
+0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68,
+0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x41, 0x72, 0x65, 0x3b,
+0x4b, 0x75, 0x6e, 0x3b, 0x4f, 0x6e, 0x67, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x49, 0x6c, 0x65, 0x3b, 0x53, 0x61, 0x70, 0x3b,
+0x4b, 0x77, 0x65, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x61, 0x72, 0x65, 0x3b, 0x4d, 0x64,
+0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x69, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20,
+0x65, 0x65, 0x20, 0x6f, 0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65,
+0x20, 0x69, 0x6e, 0x65, 0x74, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x69, 0x6c, 0x65, 0x3b,
+0x4d, 0x64, 0x65, 0x72, 0x6f, 0x74, 0x20, 0x65, 0x65, 0x20, 0x73, 0x61, 0x70, 0x61, 0x3b, 0x4d, 0x64, 0x65, 0x72, 0x6f,
+0x74, 0x20, 0x65, 0x65, 0x20, 0x6b, 0x77, 0x65, 0x3b, 0x41, 0x3b, 0x4b, 0x3b, 0x4f, 0x3b, 0x49, 0x3b, 0x49, 0x3b, 0x53,
+0x3b, 0x4b, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x50, 0x6f, 0x73, 0x3b, 0x50, 0x69, 0x72, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x4e,
+0x61, 0x69, 0x3b, 0x53, 0x68, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x3b, 0x44, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x43,
+0x68, 0x69, 0x70, 0x6f, 0x73, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x70, 0x69, 0x72, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x74, 0x61,
+0x74, 0x75, 0x3b, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x69, 0x3b, 0x43, 0x68, 0x69, 0x73, 0x68, 0x61, 0x6e, 0x75, 0x3b, 0x53,
+0x61, 0x62, 0x75, 0x64, 0x75, 0x3b, 0x44, 0x3b, 0x50, 0x3b, 0x43, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x53, 0x3b, 0x53, 0x3b,
+0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x76, 0x75, 0x3b, 0x53, 0x69, 0x62, 0x3b, 0x53, 0x69, 0x74, 0x3b, 0x53, 0x69, 0x6e, 0x3b,
+0x53, 0x69, 0x68, 0x3b, 0x4d, 0x67, 0x71, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x6f, 0x3b, 0x4d, 0x76, 0x75, 0x6c, 0x6f, 0x3b,
+0x53, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x53, 0x69, 0x74, 0x68, 0x61, 0x74, 0x68, 0x75, 0x3b, 0x53, 0x69, 0x6e, 0x65,
+0x3b, 0x53, 0x69, 0x68, 0x6c, 0x61, 0x6e, 0x75, 0x3b, 0x4d, 0x67, 0x71, 0x69, 0x62, 0x65, 0x6c, 0x6f, 0x3b, 0x53, 0x3b,
+0x4d, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x49, 0x6a, 0x70, 0x3b, 0x49, 0x6a, 0x74, 0x3b,
+0x49, 0x6a, 0x6e, 0x3b, 0x49, 0x6a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x49, 0x6a, 0x6d,
+0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75,
+0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b,
+0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x49, 0x6a, 0x75, 0x6d,
+0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x32, 0x3b, 0x33, 0x3b, 0x34, 0x3b, 0x35, 0x3b, 0x36, 0x3b, 0x37, 0x3b, 0x31, 0x3b,
+0x2d30, 0x2d59, 0x2d30, 0x3b, 0x2d30, 0x2d62, 0x2d4f, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x3b,
+0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f,
+0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30,
+0x2d59, 0x3b, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b, 0x61, 0x73, 0x61,
+0x3b, 0x61, 0x79, 0x6e, 0x3b, 0x61, 0x73, 0x69, 0x3b, 0x61, 0x6b, 0x1e5b, 0x3b, 0x61, 0x6b, 0x77, 0x3b, 0x61, 0x73, 0x69,
+0x6d, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x3b, 0x61, 0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x61, 0x79, 0x6e, 0x61, 0x73, 0x3b,
+0x61, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x1e5b, 0x61, 0x73, 0x3b, 0x61, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x61,
+0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x61, 0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x59, 0x61, 0x6e, 0x3b, 0x53,
+0x61, 0x6e, 0x3b, 0x4b, 0x72, 0x61, 0x1e0d, 0x3b, 0x4b, 0x75, 0x1e93, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x1e0d, 0x69, 0x73,
+0x3b, 0x53, 0x61, 0x79, 0x3b, 0x59, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6e, 0x61, 0x73, 0x73, 0x3b, 0x4b,
+0x72, 0x61, 0x1e0d, 0x61, 0x73, 0x73, 0x3b, 0x4b, 0x75, 0x1e93, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x61, 0x73, 0x73,
+0x3b, 0x53, 0x1e0d, 0x69, 0x73, 0x61, 0x73, 0x73, 0x3b, 0x53, 0x61, 0x79, 0x61, 0x73, 0x73, 0x3b, 0x59, 0x3b, 0x53, 0x3b,
+0x4b, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x53, 0x41, 0x4e, 0x3b, 0x4f, 0x52, 0x4b, 0x3b, 0x4f, 0x4b,
+0x42, 0x3b, 0x4f, 0x4b, 0x53, 0x3b, 0x4f, 0x4b, 0x4e, 0x3b, 0x4f, 0x4b, 0x54, 0x3b, 0x4f, 0x4d, 0x4b, 0x3b, 0x53, 0x61,
+0x6e, 0x64, 0x65, 0x3b, 0x4f, 0x72, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61,
+0x6b, 0x61, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x73, 0x68, 0x61, 0x74, 0x75, 0x3b, 0x4f,
+0x72, 0x77, 0x61, 0x6b, 0x61, 0x6e, 0x61, 0x3b, 0x4f, 0x72, 0x77, 0x61, 0x6b, 0x61, 0x74, 0x61, 0x61, 0x6e, 0x6f, 0x3b,
+0x4f, 0x72, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x52, 0x3b, 0x53, 0x3b,
+0x4e, 0x3b, 0x54, 0x3b, 0x4d, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x56, 0x69, 0x6c, 0x3b, 0x48, 0x69, 0x76, 0x3b, 0x48, 0x69,
+0x64, 0x3b, 0x48, 0x69, 0x74, 0x3b, 0x48, 0x69, 0x68, 0x3b, 0x4c, 0x65, 0x6d, 0x3b, 0x70, 0x61, 0x20, 0x6d, 0x75, 0x6c,
+0x75, 0x6e, 0x67, 0x75, 0x3b, 0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x76, 0x69, 0x6c, 0x75, 0x68, 0x61, 0x3b,
+0x70, 0x61, 0x20, 0x68, 0x69, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x64, 0x61, 0x74, 0x75, 0x3b,
+0x70, 0x61, 0x20, 0x68, 0x69, 0x74, 0x61, 0x79, 0x69, 0x3b, 0x70, 0x61, 0x20, 0x68, 0x69, 0x68, 0x61, 0x6e, 0x75, 0x3b,
+0x70, 0x61, 0x20, 0x73, 0x68, 0x61, 0x68, 0x75, 0x6c, 0x65, 0x6d, 0x62, 0x65, 0x6c, 0x61, 0x3b, 0x4d, 0x3b, 0x4a, 0x3b,
+0x48, 0x3b, 0x48, 0x3b, 0x48, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e,
+0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x70, 0x69, 0x6c, 0x79, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x75, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x75, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d,
+0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b,
+0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x6b, 0x61, 0x72, 0x3b, 0x6e, 0x74,
+0x25b, 0x3b, 0x74, 0x61, 0x72, 0x3b, 0x61, 0x72, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x3b, 0x73, 0x69,
+0x62, 0x3b, 0x6b, 0x61, 0x72, 0x69, 0x3b, 0x6e, 0x74, 0x25b, 0x6e, 0x25b, 0x3b, 0x74, 0x61, 0x72, 0x61, 0x74, 0x61, 0x3b,
+0x61, 0x72, 0x61, 0x62, 0x61, 0x3b, 0x61, 0x6c, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x73,
+0x69, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x4a, 0x3b, 0x53, 0x3b,
+0x4b, 0x6d, 0x61, 0x3b, 0x54, 0x61, 0x74, 0x3b, 0x49, 0x6e, 0x65, 0x3b, 0x54, 0x61, 0x6e, 0x3b, 0x41, 0x72, 0x6d, 0x3b,
+0x4d, 0x61, 0x61, 0x3b, 0x4e, 0x4d, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x69, 0x6e, 0x65, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x74,
+0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x74, 0x68, 0x69, 0x3b, 0x4e, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b,
+0x4e, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x74, 0x68, 0x69, 0x69, 0x3b, 0x4b, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b,
+0x41, 0x3b, 0x4d, 0x3b, 0x4e, 0x3b, 0x13c6, 0x13cd, 0x13ac, 0x3b, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x3b, 0x13e6, 0x13a2,
+0x13c1, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x3b, 0x13c8, 0x13d5, 0x13be, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c6, 0x13cd,
+0x13ac, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c9, 0x13c5, 0x13af, 0x3b, 0x13d4, 0x13b5, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e6, 0x13a2, 0x13c1, 0x13a2,
+0x13a6, 0x3b, 0x13c5, 0x13a9, 0x13c1, 0x13a2, 0x13a6, 0x3b, 0x13e7, 0x13be, 0x13a9, 0x13b6, 0x13cd, 0x13d7, 0x3b, 0x13a4, 0x13be, 0x13d9, 0x13d3, 0x13c8,
+0x13d5, 0x13be, 0x3b, 0x13c6, 0x3b, 0x13c9, 0x3b, 0x13d4, 0x3b, 0x13e6, 0x3b, 0x13c5, 0x3b, 0x13e7, 0x3b, 0x13a4, 0x3b, 0x64, 0x69, 0x6d,
+0x3b, 0x6c, 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x65, 0x72, 0x3b, 0x7a, 0x65, 0x3b, 0x76, 0x61, 0x6e, 0x3b,
+0x73, 0x61, 0x6d, 0x3b, 0x64, 0x69, 0x6d, 0x61, 0x6e, 0x73, 0x3b, 0x6c, 0x69, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72,
+0x64, 0x69, 0x3b, 0x6d, 0x65, 0x72, 0x6b, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x7a, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x6e,
+0x64, 0x72, 0x65, 0x64, 0x69, 0x3b, 0x73, 0x61, 0x6d, 0x64, 0x69, 0x3b, 0x64, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b,
+0x7a, 0x3b, 0x76, 0x3b, 0x73, 0x3b, 0x4c, 0x6c, 0x32, 0x3b, 0x4c, 0x6c, 0x33, 0x3b, 0x4c, 0x6c, 0x34, 0x3b, 0x4c, 0x6c,
+0x35, 0x3b, 0x4c, 0x6c, 0x36, 0x3b, 0x4c, 0x6c, 0x37, 0x3b, 0x4c, 0x6c, 0x31, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61,
+0x20, 0x6c, 0x79, 0x61, 0x70, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x74,
+0x61, 0x74, 0x75, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x63, 0x68,
+0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x3b, 0x4c,
+0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e, 0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6c,
+0x69, 0x6e, 0x6a, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c, 0x79, 0x61, 0x6e, 0x6e, 0x79, 0x61, 0x6e,
+0x6f, 0x20, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x76, 0x69, 0x6c, 0x69, 0x3b, 0x4c, 0x69, 0x64, 0x75, 0x76, 0x61, 0x20, 0x6c,
+0x69, 0x74, 0x61, 0x6e, 0x64, 0x69, 0x3b, 0x50, 0xed, 0x69, 0x6c, 0x69, 0x3b, 0x54, 0xe1, 0x61, 0x74, 0x75, 0x3b, 0xcd,
+0x6e, 0x65, 0x3b, 0x54, 0xe1, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4d, 0xf3, 0x6f,
+0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x69, 0x72, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74,
+0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0xed, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x61, 0x6e, 0x6f, 0x3b,
+0x41, 0x6c, 0x61, 0x6d, 0xed, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x6d, 0xf3, 0x6f, 0x73, 0x69, 0x3b, 0x50, 0x3b, 0x54, 0x3b, 0x45, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4d, 0x3b,
+0x53, 0x61, 0x62, 0x3b, 0x42, 0x61, 0x6c, 0x3b, 0x4c, 0x77, 0x32, 0x3b, 0x4c, 0x77, 0x33, 0x3b, 0x4c, 0x77, 0x34, 0x3b,
+0x4c, 0x77, 0x35, 0x3b, 0x4c, 0x77, 0x36, 0x3b, 0x53, 0x61, 0x62, 0x62, 0x69, 0x69, 0x74, 0x69, 0x3b, 0x42, 0x61, 0x6c,
+0x61, 0x7a, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x62, 0x69, 0x72, 0x69, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x73,
+0x61, 0x74, 0x75, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4c, 0x77, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x61,
+0x6e, 0x6f, 0x3b, 0x4c, 0x77, 0x61, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b, 0x42, 0x3b, 0x4c, 0x3b,
+0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x50, 0x61, 0x20, 0x4d, 0x75, 0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x50,
+0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x6d, 0x6f, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x62, 0x75, 0x6c, 0x69,
+0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69,
+0x6e, 0x65, 0x3b, 0x50, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x6f, 0x3b, 0x50, 0x61, 0x63, 0x68, 0x69,
+0x62, 0x65, 0x6c, 0x75, 0x73, 0x68, 0x69, 0x3b, 0x64, 0x75, 0x6d, 0x3b, 0x73, 0x69, 0x67, 0x3b, 0x74, 0x65, 0x72, 0x3b,
+0x6b, 0x75, 0x61, 0x3b, 0x6b, 0x69, 0x6e, 0x3b, 0x73, 0x65, 0x73, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x75, 0x6d, 0x69,
+0x6e, 0x67, 0x75, 0x3b, 0x73, 0x69, 0x67, 0x75, 0x6e, 0x64, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x74, 0x65, 0x72,
+0x73, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x6b, 0x75, 0x61, 0x72, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b,
+0x6b, 0x69, 0x6e, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72, 0x61, 0x3b, 0x73, 0x65, 0x73, 0x74, 0x61, 0x2d, 0x66, 0x65, 0x72,
+0x61, 0x3b, 0x73, 0x61, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x64, 0x3b, 0x73, 0x3b, 0x74, 0x3b, 0x6b, 0x3b, 0x6b, 0x3b, 0x73,
+0x3b, 0x73, 0x3b, 0x4b, 0x49, 0x55, 0x3b, 0x4d, 0x52, 0x41, 0x3b, 0x57, 0x41, 0x49, 0x3b, 0x57, 0x45, 0x54, 0x3b, 0x57,
+0x45, 0x4e, 0x3b, 0x57, 0x54, 0x4e, 0x3b, 0x4a, 0x55, 0x4d, 0x3b, 0x4b, 0x69, 0x75, 0x6d, 0x69, 0x61, 0x3b, 0x4d, 0x75,
+0x72, 0x61, 0x6d, 0x75, 0x6b, 0x6f, 0x3b, 0x57, 0x61, 0x69, 0x72, 0x69, 0x3b, 0x57, 0x65, 0x74, 0x68, 0x61, 0x74, 0x75,
+0x3b, 0x57, 0x65, 0x6e, 0x61, 0x3b, 0x57, 0x65, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73,
+0x69, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x57, 0x3b, 0x4a, 0x3b, 0x54, 0x69, 0x73, 0x3b,
+0x54, 0x61, 0x69, 0x3b, 0x41, 0x65, 0x6e, 0x3b, 0x53, 0x6f, 0x6d, 0x3b, 0x41, 0x6e, 0x67, 0x3b, 0x4d, 0x75, 0x74, 0x3b,
+0x4c, 0x6f, 0x68, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x74, 0x69, 0x73, 0x61, 0x70, 0x3b, 0x42, 0x65,
+0x74, 0x75, 0x74, 0x20, 0x6e, 0x65, 0x74, 0x61, 0x69, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x61, 0x65,
+0x6e, 0x67, 0x27, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x73, 0x6f, 0x6d, 0x6f, 0x6b, 0x3b, 0x42, 0x65,
+0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x61, 0x6e, 0x67, 0x27, 0x77, 0x61, 0x6e, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61,
+0x62, 0x20, 0x6d, 0x75, 0x74, 0x3b, 0x42, 0x65, 0x74, 0x75, 0x74, 0x61, 0x62, 0x20, 0x6c, 0x6f, 0x3b, 0x54, 0x3b, 0x54,
+0x3b, 0x41, 0x3b, 0x53, 0x3b, 0x41, 0x3b, 0x4d, 0x3b, 0x4c, 0x3b, 0x53, 0x6f, 0x6e, 0x3b, 0x4d, 0x61, 0x3b, 0x44, 0x65,
+0x3b, 0x57, 0x75, 0x3b, 0x44, 0x6f, 0x3b, 0x46, 0x72, 0x3b, 0x53, 0x61, 0x74, 0x3b, 0x53, 0x6f, 0x6e, 0x74, 0x61, 0x78,
+0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6e, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x44, 0x65,
+0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x57, 0x75, 0x6e, 0x73, 0x74, 0x61, 0x78, 0x74, 0x73,
+0x65, 0x65, 0x73, 0x3b, 0x44, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x46,
+0x72, 0x61, 0x69, 0x74, 0x61, 0x78, 0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x61, 0x74, 0x65, 0x72, 0x74, 0x61, 0x78,
+0x74, 0x73, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x45, 0x3b, 0x57, 0x3b, 0x44, 0x3b, 0x46, 0x3b, 0x41, 0x3b,
+0x53, 0x75, 0x2e, 0x3b, 0x4d, 0x6f, 0x2e, 0x3b, 0x44, 0x69, 0x2e, 0x3b, 0x4d, 0x65, 0x2e, 0x3b, 0x44, 0x75, 0x2e, 0x3b,
+0x46, 0x72, 0x2e, 0x3b, 0x53, 0x61, 0x2e, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d, 0x6f,
+0x6f, 0x6e, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x44, 0x69, 0x6e, 0x6e, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x4d,
+0x65, 0x74, 0x77, 0x6f, 0x63, 0x68, 0x3b, 0x44, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b,
+0x46, 0x72, 0x69, 0x69, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b, 0x53, 0x61, 0x6d, 0x73, 0x64, 0x61, 0x61, 0x63, 0x68, 0x3b,
+0x4a, 0x75, 0x6d, 0x61, 0x70, 0xed, 0x6c, 0xed, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x74, 0x75, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0xe1, 0x6e, 0x254, 0x3b, 0x41, 0x6c, 0x61, 0xe1, 0x6d, 0x69,
+0x73, 0x69, 0x3b, 0x4a, 0x75, 0x6d, 0xe1, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0xf3, 0x73, 0x69, 0x3b, 0x53, 0x61,
+0x62, 0x69, 0x3b, 0x42, 0x61, 0x6c, 0x61, 0x3b, 0x4b, 0x75, 0x62, 0x69, 0x3b, 0x4b, 0x75, 0x73, 0x61, 0x3b, 0x4b, 0x75,
+0x6e, 0x61, 0x3b, 0x4b, 0x75, 0x74, 0x61, 0x3b, 0x4d, 0x75, 0x6b, 0x61, 0x3b, 0x53, 0x61, 0x62, 0x69, 0x69, 0x74, 0x69,
+0x3b, 0x42, 0x61, 0x6c, 0x61, 0x7a, 0x61, 0x3b, 0x4f, 0x77, 0x6f, 0x6b, 0x75, 0x62, 0x69, 0x6c, 0x69, 0x3b, 0x4f, 0x77,
+0x6f, 0x6b, 0x75, 0x73, 0x61, 0x74, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x4f, 0x6c, 0x6f, 0x6b,
+0x75, 0x74, 0x61, 0x61, 0x6e, 0x75, 0x3b, 0x4f, 0x6c, 0x6f, 0x6d, 0x75, 0x6b, 0x61, 0x61, 0x67, 0x61, 0x3b, 0x53, 0x3b,
+0x42, 0x3b, 0x42, 0x3b, 0x53, 0x3b, 0x4b, 0x3b, 0x4b, 0x3b, 0x4d, 0x3b, 0x4a, 0x32, 0x3b, 0x4a, 0x33, 0x3b, 0x4a, 0x34,
+0x3b, 0x4a, 0x35, 0x3b, 0x41, 0x6c, 0x3b, 0x49, 0x6a, 0x3b, 0x4a, 0x31, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x72,
+0x69, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a,
+0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x6e,
+0x6e, 0x65, 0x3b, 0x4d, 0x75, 0x72, 0x77, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x4a,
+0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b,
+0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x6d, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x3b,
+0x42, 0x61, 0x72, 0x3b, 0x41, 0x61, 0x72, 0x3b, 0x55, 0x6e, 0x69, 0x3b, 0x55, 0x6e, 0x67, 0x3b, 0x4b, 0x61, 0x6e, 0x3b,
+0x53, 0x61, 0x62, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x65, 0x62,
+0x61, 0x72, 0x61, 0x73, 0x61, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x61, 0x72, 0x65, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e,
+0x69, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x75, 0x6e, 0x67, 0x27, 0x6f, 0x6e, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x6b, 0x61, 0x6e,
+0x79, 0x3b, 0x4e, 0x61, 0x6b, 0x61, 0x73, 0x61, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x4a, 0x3b, 0x42, 0x3b, 0x41, 0x3b, 0x55,
+0x3b, 0x55, 0x3b, 0x4b, 0x3b, 0x53, 0x3b, 0x4e, 0x61, 0x62, 0x3b, 0x53, 0x61, 0x6e, 0x3b, 0x53, 0x61, 0x6c, 0x3b, 0x52,
+0x61, 0x62, 0x3b, 0x43, 0x61, 0x6d, 0x3b, 0x4a, 0x75, 0x6d, 0x3b, 0x51, 0x75, 0x6e, 0x3b, 0x4e, 0x61, 0x62, 0x61, 0x20,
+0x53, 0x61, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x53, 0x61, 0x6e, 0x69, 0x3b, 0x53, 0x61, 0x6c, 0x75, 0x73, 0x3b, 0x52, 0x61,
+0x62, 0x75, 0x71, 0x3b, 0x43, 0x61, 0x6d, 0x75, 0x73, 0x3b, 0x4a, 0x75, 0x6d, 0x71, 0x61, 0x74, 0x61, 0x3b, 0x51, 0x75,
+0x6e, 0x78, 0x61, 0x20, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x74, 0x3b, 0x4e, 0x3b, 0x53, 0x3b, 0x53, 0x3b, 0x52, 0x3b, 0x43,
+0x3b, 0x4a, 0x3b, 0x51, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61,
+0x3b, 0x41, 0x6c, 0x6d, 0x3b, 0x41, 0x6c, 0x6a, 0x3b, 0x41, 0x73, 0x73, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b,
+0x41, 0x74, 0x69, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61,
+0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x6a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73,
+0x73, 0x61, 0x62, 0x64, 0x75, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x4c, 0x3b, 0x53, 0x3b,
+0x4a, 0x4d, 0x50, 0x3b, 0x57, 0x55, 0x54, 0x3b, 0x54, 0x41, 0x52, 0x3b, 0x54, 0x41, 0x44, 0x3b, 0x54, 0x41, 0x4e, 0x3b,
+0x54, 0x41, 0x42, 0x3b, 0x4e, 0x47, 0x53, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x70, 0x69, 0x6c, 0x3b, 0x57, 0x75, 0x6f, 0x6b,
+0x20, 0x54, 0x69, 0x63, 0x68, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x72, 0x69, 0x79, 0x6f, 0x3b, 0x54, 0x69, 0x63,
+0x68, 0x20, 0x41, 0x64, 0x65, 0x6b, 0x3b, 0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x6e, 0x67, 0x27, 0x77, 0x65, 0x6e, 0x3b,
+0x54, 0x69, 0x63, 0x68, 0x20, 0x41, 0x62, 0x69, 0x63, 0x68, 0x3b, 0x4e, 0x67, 0x65, 0x73, 0x6f, 0x3b, 0x4a, 0x3b, 0x57,
+0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4e, 0x3b, 0x41, 0x73, 0x61, 0x3b, 0x41, 0x79, 0x6e, 0x3b, 0x41,
+0x73, 0x6e, 0x3b, 0x41, 0x6b, 0x72, 0x3b, 0x41, 0x6b, 0x77, 0x3b, 0x41, 0x73, 0x6d, 0x3b, 0x41, 0x73, 0x1e0d, 0x3b, 0x41,
+0x73, 0x61, 0x6d, 0x61, 0x73, 0x3b, 0x41, 0x79, 0x6e, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6e, 0x61, 0x73, 0x3b, 0x41,
+0x6b, 0x72, 0x61, 0x73, 0x3b, 0x41, 0x6b, 0x77, 0x61, 0x73, 0x3b, 0x41, 0x73, 0x69, 0x6d, 0x77, 0x61, 0x73, 0x3b, 0x41,
+0x73, 0x69, 0x1e0d, 0x79, 0x61, 0x73, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41, 0x3b, 0x41,
+0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x41, 0x74, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x6c, 0x6d,
+0x3b, 0x41, 0x6c, 0x7a, 0x3b, 0x41, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e,
+0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61, 0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41,
+0x6c, 0x68, 0x61, 0x6d, 0x69, 0x69, 0x73, 0x61, 0x3b, 0x41, 0x6c, 0x7a, 0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62,
+0x74, 0x69, 0x3b, 0x4a, 0x70, 0x69, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6d, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41,
+0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x70, 0x69, 0x69, 0x3b,
+0x4a, 0x75, 0x6d, 0x61, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6e, 0x65, 0x3b, 0x4a, 0x75,
+0x6d, 0x61, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75,
+0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x930, 0x92c, 0x93f, 0x3b, 0x938, 0x92e,
+0x3b, 0x92e, 0x902, 0x917, 0x932, 0x3b, 0x92c, 0x941, 0x926, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f, 0x3b, 0x938, 0x941, 0x916, 0x941,
+0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x3b, 0x930, 0x92c, 0x93f, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x92e, 0x92c, 0x93e, 0x930, 0x3b,
+0x92e, 0x902, 0x917, 0x932, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x941, 0x926, 0x92c, 0x93e, 0x930, 0x3b, 0x92c, 0x93f, 0x938, 0x925, 0x93f,
+0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x916, 0x941, 0x930, 0x92c, 0x93e, 0x930, 0x3b, 0x938, 0x941, 0x928, 0x93f, 0x92c, 0x93e, 0x930,
+0x3b, 0x930, 0x3b, 0x938, 0x3b, 0x92e, 0x902, 0x3b, 0x92c, 0x941, 0x3b, 0x92c, 0x93f, 0x3b, 0x938, 0x941, 0x3b, 0x938, 0x941, 0x3b,
+0x4c, 0x75, 0x6d, 0x3b, 0x4e, 0x6b, 0x6f, 0x3b, 0x4e, 0x64, 0x79, 0x3b, 0x4e, 0x64, 0x67, 0x3b, 0x4e, 0x6a, 0x77, 0x3b,
+0x4e, 0x67, 0x76, 0x3b, 0x4c, 0x75, 0x62, 0x3b, 0x4c, 0x75, 0x6d, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4e, 0x6b, 0x6f, 0x64,
+0x79, 0x61, 0x3b, 0x4e, 0x64, 0xe0, 0x61, 0x79, 0xe0, 0x3b, 0x4e, 0x64, 0x61, 0x6e, 0x67, 0xf9, 0x3b, 0x4e, 0x6a, 0xf2,
+0x77, 0x61, 0x3b, 0x4e, 0x67, 0xf2, 0x76, 0x79, 0x61, 0x3b, 0x4c, 0x75, 0x62, 0x69, 0x6e, 0x67, 0x75, 0x3b, 0x4c, 0x3b,
+0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4e, 0x3b, 0x4c, 0x3b, 0x6e, 0x74, 0x73, 0x3b, 0x6b, 0x70, 0x61, 0x3b,
+0x67, 0x68, 0x254, 0x3b, 0x74, 0x254, 0x6d, 0x3b, 0x75, 0x6d, 0x65, 0x3b, 0x67, 0x68, 0x268, 0x3b, 0x64, 0x7a, 0x6b, 0x3b,
+0x74, 0x73, 0x75, 0x294, 0x6e, 0x74, 0x73, 0x268, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x6b, 0x70, 0xe0, 0x3b, 0x74, 0x73,
+0x75, 0x294, 0x75, 0x67, 0x68, 0x254, 0x65, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x74, 0x254, 0x300, 0x6d, 0x6c, 0xf2, 0x3b,
+0x74, 0x73, 0x75, 0x294, 0x75, 0x6d, 0xe8, 0x3b, 0x74, 0x73, 0x75, 0x294, 0x75, 0x67, 0x68, 0x268, 0x302, 0x6d, 0x3b, 0x74,
+0x73, 0x75, 0x294, 0x6e, 0x64, 0x7a, 0x268, 0x6b, 0x254, 0x294, 0x254, 0x3b, 0x6e, 0x3b, 0x6b, 0x3b, 0x67, 0x3b, 0x74, 0x3b,
+0x75, 0x3b, 0x67, 0x3b, 0x64, 0x3b, 0x6e, 0x254, 0x79, 0x3b, 0x6e, 0x6a, 0x61, 0x3b, 0x75, 0x75, 0x6d, 0x3b, 0x14b, 0x67,
+0x65, 0x3b, 0x6d, 0x62, 0x254, 0x3b, 0x6b, 0x254, 0x254, 0x3b, 0x6a, 0x6f, 0x6e, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e,
+0x254, 0x302, 0x79, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6e, 0x6a, 0x61, 0x14b, 0x67, 0x75, 0x6d, 0x62, 0x61, 0x3b, 0x14b,
+0x67, 0x77, 0xe0, 0x20, 0xfb, 0x6d, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x14b, 0x67, 0xea, 0x3b, 0x14b, 0x67, 0x77, 0xe0,
+0x20, 0x6d, 0x62, 0x254, 0x6b, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20, 0x6b, 0x254, 0x254, 0x3b, 0x14b, 0x67, 0x77, 0xe0, 0x20,
+0x6a, 0xf4, 0x6e, 0x3b, 0x6e, 0x3b, 0x6e, 0x3b, 0x75, 0x3b, 0x14b, 0x3b, 0x6d, 0x3b, 0x6b, 0x3b, 0x6a, 0x3b, 0x41, 0x6c,
+0x68, 0x61, 0x64, 0x69, 0x3b, 0x41, 0x74, 0x69, 0x6e, 0x6e, 0x69, 0x3b, 0x41, 0x74, 0x61, 0x6c, 0x61, 0x61, 0x74, 0x61,
+0x3b, 0x41, 0x6c, 0x61, 0x72, 0x62, 0x61, 0x3b, 0x41, 0x6c, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x41, 0x6c, 0x7a,
+0x75, 0x6d, 0x61, 0x3b, 0x41, 0x73, 0x69, 0x62, 0x74, 0x69, 0x3b, 0x48, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x4c, 0x3b, 0x4d,
+0x3b, 0x5a, 0x3b, 0x53, 0x3b, 0xe9, 0x74, 0x3b, 0x6d, 0x254, 0x301, 0x73, 0x3b, 0x6b, 0x77, 0x61, 0x3b, 0x6d, 0x75, 0x6b,
+0x3b, 0x14b, 0x67, 0x69, 0x3b, 0x257, 0xf3, 0x6e, 0x3b, 0x65, 0x73, 0x61, 0x3b, 0xe9, 0x74, 0x69, 0x3b, 0x6d, 0x254, 0x301,
+0x73, 0xfa, 0x3b, 0x6b, 0x77, 0x61, 0x73, 0xfa, 0x3b, 0x6d, 0x75, 0x6b, 0x254, 0x301, 0x73, 0xfa, 0x3b, 0x14b, 0x67, 0x69,
+0x73, 0xfa, 0x3b, 0x257, 0xf3, 0x6e, 0x25b, 0x73, 0xfa, 0x3b, 0x65, 0x73, 0x61, 0x253, 0x61, 0x73, 0xfa, 0x3b, 0x65, 0x3b,
+0x6d, 0x3b, 0x6b, 0x3b, 0x6d, 0x3b, 0x14b, 0x3b, 0x257, 0x3b, 0x65, 0x3b, 0x44, 0x69, 0x6d, 0x3b, 0x54, 0x65, 0x6e, 0x3b,
+0x54, 0x61, 0x6c, 0x3b, 0x41, 0x6c, 0x61, 0x3b, 0x41, 0x72, 0x61, 0x3b, 0x41, 0x72, 0x6a, 0x3b, 0x53, 0x69, 0x62, 0x3b,
+0x44, 0x69, 0x6d, 0x61, 0x73, 0x3b, 0x54, 0x65, 0x6e, 0x65, 0x14b, 0x3b, 0x54, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x41,
+0x6c, 0x61, 0x72, 0x62, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x61, 0x79, 0x3b, 0x41, 0x72, 0x6a, 0x75,
+0x6d, 0x61, 0x3b, 0x53, 0x69, 0x62, 0x69, 0x74, 0x69, 0x3b, 0x44, 0x3b, 0x54, 0x3b, 0x54, 0x3b, 0x41, 0x3b, 0x41, 0x3b,
+0x41, 0x3b, 0x53, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d,
+0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b, 0x66, 0xfa, 0x6c, 0x3b, 0x73, 0xe9, 0x72, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254,
+0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20,
+0x6d, 0x259, 0x301, 0x62, 0x25b, 0x30c, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d,
+0x259, 0x301, 0x6c, 0x25b, 0x301, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x259, 0x6c, 0xfa, 0x20, 0x6d, 0x259,
+0x301, 0x6e, 0x79, 0x69, 0x3b, 0x66, 0xfa, 0x6c, 0x61, 0x64, 0xe9, 0x3b, 0x73, 0xe9, 0x72, 0x61, 0x64, 0xe9, 0x3b, 0x73,
+0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x3b, 0x6c, 0x1dd,
+0x6e, 0x3b, 0x6d, 0x61, 0x61, 0x3b, 0x6d, 0x25b, 0x6b, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x3b, 0x6a, 0xfa, 0x6d, 0x3b, 0x73, 0x61,
+0x6d, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x1dd, 0x3b, 0x6c, 0x1dd, 0x6e, 0x64, 0xed, 0x3b, 0x6d, 0x61, 0x61, 0x64, 0xed,
+0x3b, 0x6d, 0x25b, 0x6b, 0x72, 0x25b, 0x64, 0xed, 0x3b, 0x6a, 0x1dd, 0x1dd, 0x64, 0xed, 0x3b, 0x6a, 0xfa, 0x6d, 0x62, 0xe1,
+0x3b, 0x73, 0x61, 0x6d, 0x64, 0xed, 0x3b, 0x73, 0x3b, 0x6c, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x6a, 0x3b, 0x6a, 0x3b, 0x73,
+0x3b, 0x53, 0x61, 0x62, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e, 0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x72, 0x61,
+0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x53, 0x61, 0x62, 0x61, 0x74, 0x6f, 0x3b, 0x4a, 0x75, 0x6d, 0x61,
+0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e,
+0x6f, 0x3b, 0x41, 0x72, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a,
+0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x53, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b,
+0x4a, 0x3b, 0x43, 0x79, 0x61, 0x3b, 0x43, 0x6c, 0x61, 0x3b, 0x43, 0x7a, 0x69, 0x3b, 0x43, 0x6b, 0x6f, 0x3b, 0x43, 0x6b,
+0x61, 0x3b, 0x43, 0x67, 0x61, 0x3b, 0x43, 0x7a, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x27, 0x79, 0x61, 0x6b, 0x6b, 0x65, 0x3b,
+0x43, 0x6f, 0x6d, 0x6c, 0x61, 0x61, 0x257, 0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x69, 0x69, 0x257, 0x69, 0x69,
+0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x6f, 0x6c, 0x6c, 0x65, 0x3b, 0x43, 0x6f, 0x6d, 0x6b, 0x61, 0x6c, 0x64, 0x1dd, 0x253, 0x6c,
+0x69, 0x69, 0x3b, 0x43, 0x6f, 0x6d, 0x67, 0x61, 0x69, 0x73, 0x75, 0x75, 0x3b, 0x43, 0x6f, 0x6d, 0x7a, 0x79, 0x65, 0x253,
+0x73, 0x75, 0x75, 0x3b, 0x59, 0x3b, 0x4c, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, 0x41, 0x3b, 0x47, 0x3b, 0x45, 0x3b, 0x73, 0x254,
+0x301, 0x6e, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x3b, 0x73, 0x6d, 0x62, 0x3b, 0x73, 0x6d, 0x6c, 0x3b, 0x73, 0x6d, 0x6e, 0x3b,
+0x6d, 0x62, 0x73, 0x3b, 0x73, 0x61, 0x73, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x3b, 0x6d, 0x254, 0x301, 0x6e, 0x64,
+0x254, 0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x62, 0x61, 0x3b, 0x73,
+0x254, 0x301, 0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6c, 0x61, 0x6c, 0x3b, 0x73, 0x254, 0x301,
+0x6e, 0x64, 0x254, 0x20, 0x6d, 0x61, 0x66, 0xfa, 0x20, 0x6d, 0xe1, 0x6e, 0x61, 0x3b, 0x6d, 0x61, 0x62, 0xe1, 0x67, 0xe1,
+0x20, 0x6d, 0xe1, 0x20, 0x73, 0x75, 0x6b, 0x75, 0x6c, 0x3b, 0x73, 0xe1, 0x73, 0x61, 0x64, 0x69, 0x3b, 0x73, 0x3b, 0x6d,
+0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x73, 0x3b, 0x43, 0xe4, 0x14b, 0x3b, 0x4a, 0x69, 0x65, 0x63, 0x3b,
+0x52, 0x25b, 0x77, 0x3b, 0x44, 0x69, 0x254, 0x331, 0x6b, 0x3b, 0x14a, 0x75, 0x61, 0x61, 0x6e, 0x3b, 0x44, 0x68, 0x69, 0x65,
+0x65, 0x63, 0x3b, 0x42, 0xe4, 0x6b, 0x25b, 0x6c, 0x3b, 0x43, 0xe4, 0x14b, 0x20, 0x6b, 0x75, 0x254, 0x74, 0x68, 0x3b, 0x4a,
+0x69, 0x65, 0x63, 0x20, 0x6c, 0x61, 0x331, 0x74, 0x3b, 0x52, 0x25b, 0x77, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x44,
+0x69, 0x254, 0x331, 0x6b, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x14a, 0x75, 0x61, 0x61, 0x6e, 0x20, 0x6c, 0xe4, 0x74,
+0x6e, 0x69, 0x3b, 0x44, 0x68, 0x69, 0x65, 0x65, 0x63, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x42, 0xe4, 0x6b, 0x25b,
+0x6c, 0x20, 0x6c, 0xe4, 0x74, 0x6e, 0x69, 0x3b, 0x43, 0x3b, 0x4a, 0x3b, 0x52, 0x3b, 0x44, 0x3b, 0x14a, 0x3b, 0x44, 0x3b,
+0x42, 0x3b, 0x411, 0x441, 0x3b, 0x411, 0x43d, 0x3b, 0x41e, 0x43f, 0x3b, 0x421, 0x44d, 0x3b, 0x427, 0x43f, 0x3b, 0x411, 0x44d, 0x3b,
+0x421, 0x431, 0x3b, 0x411, 0x430, 0x441, 0x43a, 0x44b, 0x4bb, 0x44b, 0x430, 0x43d, 0x43d, 0x44c, 0x430, 0x3b, 0x411, 0x44d, 0x43d, 0x438,
+0x434, 0x438, 0x44d, 0x43b, 0x438, 0x43d, 0x43d, 0x44c, 0x438, 0x43a, 0x3b, 0x41e, 0x43f, 0x442, 0x443, 0x43e, 0x440, 0x443, 0x43d, 0x43d,
+0x44c, 0x443, 0x43a, 0x3b, 0x421, 0x44d, 0x440, 0x44d, 0x434, 0x44d, 0x3b, 0x427, 0x44d, 0x43f, 0x43f, 0x438, 0x44d, 0x440, 0x3b, 0x411,
+0x44d, 0x44d, 0x442, 0x438, 0x4a5, 0x441, 0x44d, 0x3b, 0x421, 0x443, 0x431, 0x443, 0x43e, 0x442, 0x430, 0x3b, 0x411, 0x3b, 0x411, 0x3b,
+0x41e, 0x3b, 0x421, 0x3b, 0x427, 0x3b, 0x411, 0x3b, 0x421, 0x3b, 0x4d, 0x75, 0x6c, 0x3b, 0x4a, 0x74, 0x74, 0x3b, 0x4a, 0x6e,
+0x6e, 0x3b, 0x4a, 0x74, 0x6e, 0x3b, 0x41, 0x6c, 0x68, 0x3b, 0x49, 0x6a, 0x75, 0x3b, 0x4a, 0x6d, 0x6f, 0x3b, 0x4d, 0x75,
+0x6c, 0x75, 0x6e, 0x67, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6e,
+0x6e, 0x65, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x74, 0x61, 0x6e, 0x6f, 0x3b, 0x41, 0x6c, 0x61, 0x68, 0x61, 0x6d, 0x69, 0x73,
+0x69, 0x3b, 0x49, 0x6a, 0x75, 0x6d, 0x61, 0x61, 0x3b, 0x4a, 0x75, 0x6d, 0x61, 0x6d, 0x6f, 0x73, 0x69, 0x3b, 0x4d, 0x3b,
+0x4a, 0x3b, 0x4a, 0x3b, 0x4a, 0x3b, 0x41, 0x3b, 0x49, 0x3b, 0x4a, 0x3b, 0x79, 0x65, 0x6e, 0x3b, 0x6b, 0x77, 0x61, 0x3b,
+0x70, 0x69, 0x6c, 0x3b, 0x74, 0x61, 0x74, 0x3b, 0x69, 0x6e, 0x65, 0x3b, 0x74, 0x61, 0x6e, 0x3b, 0x73, 0x69, 0x74, 0x3b,
+0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x79, 0x65, 0x6e, 0x67, 0x61, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79,
+0x61, 0x20, 0x6b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x70, 0x69, 0x6c,
+0x69, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x74, 0x75, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20,
+0x79, 0x61, 0x20, 0x69, 0x6e, 0x65, 0x3b, 0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x74, 0x61, 0x6e, 0x75, 0x3b,
+0x73, 0x69, 0x6b, 0x75, 0x20, 0x79, 0x61, 0x20, 0x73, 0x69, 0x74, 0x61, 0x3b, 0x79, 0x3b, 0x6b, 0x3b, 0x70, 0x3b, 0x74,
+0x3b, 0x69, 0x3b, 0x74, 0x3b, 0x73, 0x3b, 0xa55e, 0xa54c, 0xa535, 0x3b, 0xa5f3, 0xa5e1, 0xa609, 0x3b, 0xa55a, 0xa55e, 0xa55a, 0x3b, 0xa549,
+0xa55e, 0xa552, 0x3b, 0xa549, 0xa524, 0xa546, 0xa562, 0x3b, 0xa549, 0xa524, 0xa540, 0xa56e, 0x3b, 0xa53b, 0xa52c, 0xa533, 0x3b, 0x6c, 0x61, 0x68,
+0x61, 0x64, 0x69, 0x3b, 0x74, 0x25b, 0x25b, 0x6e, 0x25b, 0x25b, 0x3b, 0x74, 0x61, 0x6c, 0x61, 0x74, 0x61, 0x3b, 0x61, 0x6c,
+0x61, 0x62, 0x61, 0x3b, 0x61, 0x69, 0x6d, 0x69, 0x73, 0x61, 0x3b, 0x61, 0x69, 0x6a, 0x69, 0x6d, 0x61, 0x3b, 0x73, 0x69,
+0x253, 0x69, 0x74, 0x69, 0x3b, 0x53, 0x75, 0x6e, 0x3b, 0x4d, 0xe4, 0x6e, 0x3b, 0x5a, 0x69, 0x161, 0x3b, 0x4d, 0x69, 0x74,
+0x3b, 0x46, 0x72, 0xf3, 0x3b, 0x46, 0x72, 0x69, 0x3b, 0x53, 0x61, 0x6d, 0x3b, 0x53, 0x75, 0x6e, 0x6e, 0x74, 0x61, 0x67,
+0x3b, 0x4d, 0xe4, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x5a, 0x69, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x4d, 0x69, 0x74, 0x74, 0x77,
+0x75, 0x10d, 0x3b, 0x46, 0x72, 0xf3, 0x6e, 0x74, 0x61, 0x67, 0x3b, 0x46, 0x72, 0x69, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x61,
+0x6d, 0x161, 0x74, 0x61, 0x67, 0x3b, 0x53, 0x3b, 0x4d, 0x3b, 0x5a, 0x3b, 0x4d, 0x3b, 0x46, 0x3b, 0x46, 0x3b, 0x53, 0x3b,
+0x73, 0x64, 0x3b, 0x6d, 0x64, 0x3b, 0x6d, 0x77, 0x3b, 0x65, 0x74, 0x3b, 0x6b, 0x6c, 0x3b, 0x66, 0x6c, 0x3b, 0x73, 0x73,
+0x3b, 0x73, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x25b, 0x3b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x75, 0xe1, 0x6e,
+0x79, 0xe1, 0x14b, 0x6d, 0xf3, 0x6e, 0x64, 0x69, 0x65, 0x3b, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0xed, 0xe1, 0x70, 0x25b,
+0x3b, 0x6b, 0xfa, 0x70, 0xe9, 0x6c, 0x69, 0x6d, 0x65, 0x74, 0xfa, 0x6b, 0x70, 0x69, 0x61, 0x70, 0x25b, 0x3b, 0x66, 0x65,
+0x6c, 0xe9, 0x74, 0x65, 0x3b, 0x73, 0xe9, 0x73, 0x65, 0x6c, 0xe9, 0x3b, 0x73, 0x3b, 0x6d, 0x3b, 0x6d, 0x3b, 0x65, 0x3b,
+0x6b, 0x3b, 0x66, 0x3b, 0x73, 0x3b, 0x64, 0x6f, 0x6d, 0x3b, 0x6c, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x72, 0x3b, 0x6d, 0x69,
+0x65, 0x3b, 0x78, 0x75, 0x65, 0x3b, 0x76, 0x69, 0x65, 0x3b, 0x73, 0x61, 0x62, 0x3b, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x67,
+0x75, 0x3b, 0x6c, 0x6c, 0x75, 0x6e, 0x65, 0x73, 0x3b, 0x6d, 0x61, 0x72, 0x74, 0x65, 0x73, 0x3b, 0x6d, 0x69, 0xe9, 0x72,
+0x63, 0x6f, 0x6c, 0x65, 0x73, 0x3b, 0x78, 0x75, 0x65, 0x76, 0x65, 0x73, 0x3b, 0x76, 0x69, 0x65, 0x6e, 0x72, 0x65, 0x73,
+0x3b, 0x73, 0xe1, 0x62, 0x61, 0x64, 0x75, 0x3b, 0x53, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x4d, 0x254, 0x301, 0x6e, 0x64,
+0x69, 0x3b, 0xc1, 0x70, 0x74, 0x61, 0x20, 0x4d, 0x254, 0x301, 0x6e, 0x64, 0x69, 0x3b, 0x57, 0x25b, 0x301, 0x6e, 0x25b, 0x73,
+0x25b, 0x64, 0x25b, 0x3b, 0x54, 0x254, 0x301, 0x73, 0x25b, 0x64, 0x25b, 0x3b, 0x46, 0x25b, 0x6c, 0xe2, 0x79, 0x25b, 0x64, 0x25b,
+0x3b, 0x53, 0xe1, 0x73, 0x69, 0x64, 0x25b, 0x3b, 0x53, 0x254, 0x301, 0x3b, 0x4d, 0x254, 0x301, 0x3b, 0xc1, 0x4d, 0x3b, 0x57,
+0x25b, 0x301, 0x3b, 0x54, 0x254, 0x301, 0x3b, 0x46, 0x25b, 0x3b, 0x53, 0xe1, 0x3b, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x6c,
+0x75, 0x6e, 0x64, 0x69, 0x3b, 0x6d, 0x61, 0x72, 0x64, 0x69, 0x3b, 0x6d, 0x25b, 0x72, 0x6b, 0x25b, 0x72, 0x25b, 0x64, 0x69,
+0x3b, 0x79, 0x65, 0x64, 0x69, 0x3b, 0x76, 0x61, 0x14b, 0x64, 0x25b, 0x72, 0x25b, 0x64, 0x69, 0x3b, 0x6d, 0x254, 0x6e, 0x254,
+0x20, 0x73, 0x254, 0x6e, 0x64, 0x69, 0x3b, 0x73, 0x6f, 0x3b, 0x6c, 0x75, 0x3b, 0x6d, 0x61, 0x3b, 0x6d, 0x25b, 0x3b, 0x79,
+0x65, 0x3b, 0x76, 0x61, 0x3b, 0x6d, 0x73, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x31, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20,
+0x32, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x33, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x34, 0x3b, 0x41, 0x6e, 0x65, 0x67,
+0x20, 0x35, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x36, 0x3b, 0x41, 0x6e, 0x65, 0x67, 0x20, 0x37, 0x3b, 0x41, 0x31, 0x3b,
+0x41, 0x32, 0x3b, 0x41, 0x33, 0x3b, 0x41, 0x34, 0x3b, 0x41, 0x35, 0x3b, 0x41, 0x36, 0x3b, 0x41, 0x37, 0x3b, 0x6c, 0x79,
+0x25b, 0x2bc, 0x25b, 0x301, 0x20, 0x73, 0x1e85, 0xed, 0x14b, 0x74, 0xe8, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b,
+0x30c, 0x2bc, 0x3b, 0x6d, 0x62, 0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6c, 0x79, 0x25b,
+0x30c, 0x2bc, 0x3b, 0x74, 0x73, 0xe8, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0x62,
+0x254, 0x301, 0x254, 0x6e, 0x74, 0xe8, 0x20, 0x74, 0x73, 0x65, 0x74, 0x73, 0x25b, 0x300, 0x25b, 0x20, 0x6c, 0x79, 0x25b, 0x30c,
+0x2bc, 0x3b, 0x6d, 0x76, 0x66, 0xf2, 0x20, 0x6d, 0xe0, 0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x6d, 0xe0,
+0x67, 0x61, 0x20, 0x6c, 0x79, 0x25b, 0x30c, 0x2bc, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x6b, 0x21f, 0x61,
+0x14b, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x77, 0x61, 0x14b, 0x17e, 0x69, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75,
+0x6e, 0x75, 0x14b, 0x70, 0x61, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x79, 0x61, 0x6d, 0x6e, 0x69, 0x3b, 0x41, 0x14b,
+0x70, 0xe9, 0x74, 0x75, 0x74, 0x6f, 0x70, 0x61, 0x3b, 0x41, 0x14b, 0x70, 0xe9, 0x74, 0x75, 0x7a, 0x61, 0x70, 0x74, 0x61,
+0x14b, 0x3b, 0x4f, 0x77, 0xe1, 0x14b, 0x67, 0x79, 0x75, 0x17e, 0x61, 0x17e, 0x61, 0x70, 0x69, 0x3b, 0x41, 0x3b, 0x57, 0x3b,
+0x4e, 0x3b, 0x59, 0x3b, 0x54, 0x3b, 0x5a, 0x3b, 0x4f, 0x3b, 0x2d30, 0x2d59, 0x2d30, 0x2d4e, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d62, 0x2d4f,
+0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4f, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d55, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d3d, 0x2d61, 0x2d30,
+0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d4e, 0x2d61, 0x2d30, 0x2d59, 0x3b, 0x2d30, 0x2d59, 0x2d49, 0x2d39, 0x2d62, 0x2d30, 0x2d59, 0x3b
};
static const ushort am_data[] = {
-0x41, 0x4d, 0x57, 0x44, 0x76, 0x6d, 0x2e, 0x50, 0x44, 0x1325, 0x12cb, 0x1275, 0x635, 0x56f, 0x565, 0x57d, 0x585, 0x580, 0x56b, 0x581,
-0x20, 0x561, 0x57c, 0x561, 0x57b, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x9aa, 0x9c2, 0x9b0, 0x9cd, 0x9ac, 0x9be,
-0x9b9, 0x9cd, 0x9a3, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b, 0x43f, 0x440, 0x2e, 0x20, 0x43e, 0x431, 0x2e, 0x1014, 0x1036, 0x1014, 0x1000, 0x103a,
-0x434, 0x430, 0x20, 0x43f, 0x430, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x1796, 0x17d2, 0x179a, 0x17b9, 0x1780, 0x61, 0x2e, 0x6d, 0x2e, 0x4e0a,
-0x5348, 0x64, 0x6f, 0x70, 0x2e, 0xd801, 0xdc08, 0xd801, 0xdc23, 0x61, 0x6d, 0x61, 0x70, 0x2e, 0x76, 0x6f, 0x72, 0x6d, 0x2e, 0x3c0,
-0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x65,
-0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x5348, 0x524d, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, 0xec8, 0xead, 0xe99, 0xe97, 0xec8,
-0xebd, 0xe87, 0x70, 0x72, 0x69, 0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6e, 0x74, 0x254, 0x301,
-0x6e, 0x67, 0x254, 0x301, 0x70, 0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, 0x435, 0x442, 0x43f, 0x43b, 0x430,
-0x434, 0x43d, 0x435, 0x50, 0x47, 0x51, 0x4e, 0x4ae, 0x4e8, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x20, 0x92e, 0x927, 0x94d, 0x92f, 0x93e,
-0x928, 0x94d, 0x939, 0x63a, 0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0xa2a, 0xa42, 0xa30, 0xa35,
-0x20, 0xa26, 0xa41, 0xa2a, 0xa39, 0xa3f, 0xa30, 0x434, 0x43e, 0x20, 0x43f, 0x43e, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x4e, 0x44, 0x43f,
-0x440, 0x435, 0x20, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0xdb4, 0xdd9, 0x2e,
-0xdc0, 0x2e, 0x64, 0x6f, 0x70, 0x6f, 0x6c, 0x75, 0x64, 0x6e, 0x69, 0x61, 0x73, 0x6e, 0x2e, 0x61, 0x73, 0x75, 0x62, 0x75,
-0x68, 0x69, 0x66, 0x6d, 0xe01, 0xe48, 0xe2d, 0xe19, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c,
-0xf0b, 0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270, 0xd6, 0xd6, 0x434, 0x43f, 0x642, 0x628, 0x644, 0x20, 0x62f, 0x648, 0x67e, 0x6c1,
-0x631, 0x53, 0x41, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0x45, 0x6b, 0x75, 0x73, 0x65, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x69,
-0x64, 0x64, 0x61, 0x67, 0x41, 0x4e, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x41, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x6b, 0x77,
-0x61, 0x6b, 0x79, 0x61, 0x14b, 0x64, 0x69, 0xa3b8, 0xa111, 0x4d, 0x61, 0x2f, 0x4d, 0x6f, 0x4c, 0x75, 0x6d, 0x61, 0x20, 0x6c,
-0x77, 0x61, 0x20, 0x4b, 0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, 0x72, 0x6f, 0x6b, 0x6f, 0x54, 0x65, 0x73, 0x69,
-0x72, 0x61, 0x6e, 0x6b, 0x61, 0x6e, 0x67, 0x27, 0x61, 0x6d, 0x61, 0x2d5c, 0x2d49, 0x2d3c, 0x2d30, 0x2d61, 0x2d5c, 0x74, 0x69, 0x66,
-0x61, 0x77, 0x74, 0x6e, 0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x75, 0x75, 0x74, 0x75,
-0x6b, 0x6f, 0x4b, 0x49, 0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, 0x4f, 0x4f, 0x75, 0x6c, 0x75, 0x63, 0x68, 0x65,
-0x6c, 0x6f, 0x52, 0x168, 0x42, 0x65, 0x65, 0x74, 0x1c1, 0x67, 0x6f, 0x61, 0x67, 0x61, 0x73, 0x190, 0x6e, 0x6b, 0x61, 0x6b,
-0x25b, 0x6e, 0x79, 0xe1, 0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, 0x68, 0x65, 0x61, 0x76, 0x6f, 0x54,
-0x61, 0x70, 0x61, 0x72, 0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, 0x4f, 0x44, 0x5a, 0x64, 0x61, 0x74,
-0x20, 0x61, 0x7a, 0x61, 0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, 0x69, 0x6e, 0x64, 0x61, 0x61, 0x2e,
-0x67, 0x49, 0x20, 0x62, 0x69, 0x6b, 0x25b, 0x302, 0x67, 0x6c, 0xe0, 0x53, 0x75, 0x62, 0x62, 0x61, 0x61, 0x68, 0x69, 0x69,
-0x64, 0x69, 0x253, 0x61, 0x6b, 0xed, 0x6b, 0xed, 0x72, 0xed, 0x67, 0x73, 0xe1, 0x72, 0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63,
-0x68, 0x69, 0x73, 0x68, 0x75, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6d, 0x61, 0x6e, 0xe1, 0x52, 0x57, 0x4c, 0x77, 0x61, 0x6d,
-0x69, 0x6c, 0x61, 0x77, 0x75, 0x79, 0x61, 0x20, 0x61, 0x73, 0x75, 0x62, 0x75, 0x79, 0x69, 0x6b, 0x69, 0x25b, 0x6d, 0x25b,
-0x301, 0x25b, 0x6d, 0x6d, 0x62, 0x61, 0x2019, 0x6d, 0x62, 0x61, 0x2019, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc,
-
+0x41, 0x4d, 0x57, 0x44, 0x76, 0x6d, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x64, 0x69, 0x74, 0x65, 0x1325, 0x12cb, 0x1275, 0x635, 0x56f,
+0x565, 0x57d, 0x585, 0x580, 0x56b, 0x581, 0x20, 0x561, 0x57c, 0x561, 0x57b, 0x9aa, 0x9c2, 0x9f0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a3,
+0x9aa, 0x9c2, 0x9b0, 0x9cd, 0x9ac, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0xf66, 0xf94, 0xf0b, 0xf46, 0xf0b, 0x43f, 0x440, 0x2e, 0x43e, 0x431, 0x2e,
+0x1014, 0x1036, 0x1014, 0x1000, 0x103a, 0x434, 0x430, 0x20, 0x43f, 0x430, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x1796, 0x17d2, 0x179a, 0x17b9, 0x1780,
+0x61, 0x2e, 0x20, 0x6d, 0x2e, 0x4e0a, 0x5348, 0xd801, 0xdc08, 0xd801, 0xdc23, 0x61, 0x6d, 0x61, 0x2e, 0x6d, 0x2e, 0x61, 0x70, 0x2e,
+0x10d3, 0x10d8, 0x10da, 0x10d8, 0x10e1, 0x76, 0x6f, 0x72, 0x6d, 0x2e, 0x3c0, 0x2e, 0x3bc, 0x2e, 0x5dc, 0x5e4, 0x5e0, 0x5d4, 0x5f4, 0x5e6,
+0x92a, 0x942, 0x930, 0x94d, 0x935, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x65, 0x2e, 0x66, 0x2e, 0x68, 0x2e, 0x5348, 0x524d, 0x442, 0x4af,
+0x441, 0x43a, 0x435, 0x20, 0x434, 0x435, 0x439, 0x456, 0x43d, 0x442, 0x4af, 0x448, 0x43a, 0x4e9, 0x20, 0x447, 0x435, 0x439, 0x438, 0x43d,
+0x43a, 0x438, 0xc624, 0xc804, 0x5a, 0x2e, 0x4d, 0x55, 0x2e, 0xe81, 0xec8, 0xead, 0xe99, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x72, 0x69,
+0x65, 0x6b, 0x161, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6e, 0x74, 0x254, 0x301, 0x6e, 0x67, 0x254, 0x301, 0x70,
+0x72, 0x69, 0x65, 0x161, 0x70, 0x69, 0x65, 0x74, 0x43f, 0x440, 0x435, 0x442, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x47,
+0x51, 0x4e, 0x5b, 0x41, 0x4d, 0x5d, 0x4ae, 0x4e8, 0x92a, 0x942, 0x930, 0x94d, 0x935, 0x20, 0x92e, 0x927, 0x94d, 0x92f, 0x93e, 0x928,
+0x94d, 0x939, 0x63a, 0x2e, 0x645, 0x2e, 0x642, 0x628, 0x644, 0x200c, 0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x6d, 0x61,
+0x6e, 0x68, 0xe3, 0x434, 0x43e, 0x20, 0x43f, 0x43e, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x4e, 0x44, 0x43f, 0x440, 0x435, 0x20, 0x43f,
+0x43e, 0x434, 0x43d, 0x435, 0x70, 0x72, 0x65, 0x20, 0x70, 0x6f, 0x64, 0x6e, 0x65, 0xdb4, 0xdd9, 0x2e, 0xdc0, 0x2e, 0x64, 0x6f,
+0x70, 0x2e, 0x73, 0x6e, 0x2e, 0x66, 0x6d, 0xbae, 0xbc1, 0xbb1, 0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe01, 0xe48, 0xe2d, 0xe19, 0xe40,
+0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf66, 0xf94, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x1295, 0x1309, 0x1206, 0x20, 0x1230, 0x12d3, 0x1270, 0xd6,
+0xd6, 0x434, 0x43f, 0x642, 0x628, 0x644, 0x20, 0x62f, 0x648, 0x67e, 0x6c1, 0x631, 0x53, 0x41, 0xc0, 0xe1, 0x72, 0x1ecd, 0x300, 0xc0,
+0xe1, 0x72, 0x254, 0x300, 0x45, 0x6b, 0x75, 0x73, 0x65, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67,
+0x41, 0x4e, 0x92e, 0x2e, 0x92a, 0x942, 0x2e, 0x41, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x6b, 0x77, 0x61, 0x6b, 0x79, 0x61,
+0x14b, 0x64, 0x69, 0xa3b8, 0xa111, 0x4d, 0x61, 0x2f, 0x4d, 0x6f, 0x4c, 0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x4b,
+0x73, 0x75, 0x62, 0x61, 0x6b, 0x61, 0x4b, 0x69, 0x72, 0x6f, 0x6b, 0x6f, 0x54, 0x65, 0x73, 0x69, 0x72, 0x61, 0x6e, 0x6b,
+0x61, 0x6e, 0x67, 0x27, 0x61, 0x6d, 0x61, 0x2d5c, 0x2d49, 0x2d3c, 0x2d30, 0x2d61, 0x2d5c, 0x74, 0x69, 0x66, 0x61, 0x77, 0x74, 0x6e,
+0x20, 0x74, 0x75, 0x66, 0x61, 0x74, 0x70, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x75, 0x75, 0x74, 0x75, 0x6b, 0x6f, 0x4b, 0x49,
+0x13cc, 0x13be, 0x13b4, 0x4d, 0x75, 0x68, 0x69, 0x54, 0x4f, 0x4f, 0x75, 0x6c, 0x75, 0x63, 0x68, 0x65, 0x6c, 0x6f, 0x52, 0x168,
+0x42, 0x65, 0x65, 0x74, 0x1c1, 0x67, 0x6f, 0x61, 0x67, 0x61, 0x73, 0x190, 0x6e, 0x6b, 0x61, 0x6b, 0x25b, 0x6e, 0x79, 0xe1,
+0x4d, 0x75, 0x6e, 0x6b, 0x79, 0x6f, 0x69, 0x63, 0x68, 0x65, 0x68, 0x65, 0x61, 0x76, 0x6f, 0x54, 0x61, 0x70, 0x61, 0x72,
+0x61, 0x63, 0x68, 0x75, 0x41, 0x64, 0x64, 0x75, 0x68, 0x61, 0x4f, 0x44, 0x5a, 0x64, 0x61, 0x74, 0x20, 0x61, 0x7a, 0x61,
+0x6c, 0x6d, 0x61, 0x6b, 0x65, 0x6f, 0x92b, 0x941, 0x902, 0x44, 0x69, 0x6e, 0x64, 0x61, 0x61, 0x2e, 0x67, 0x49, 0x20, 0x62,
+0x69, 0x6b, 0x25b, 0x302, 0x67, 0x6c, 0xe0, 0x53, 0x75, 0x62, 0x62, 0x61, 0x61, 0x68, 0x69, 0x69, 0x64, 0x69, 0x253, 0x61,
+0x6b, 0xed, 0x6b, 0xed, 0x72, 0xed, 0x67, 0x73, 0xe1, 0x72, 0xfa, 0x77, 0xe1, 0x77, 0x69, 0x63, 0x68, 0x69, 0x73, 0x68,
+0x75, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6d, 0x61, 0x6e, 0xe1, 0x52, 0x57, 0x4c, 0x77, 0x61, 0x6d, 0x69, 0x6c, 0x61, 0x77,
+0x75, 0x79, 0x61, 0x20, 0x61, 0x73, 0x75, 0x62, 0x75, 0x79, 0x69, 0x6b, 0x69, 0x25b, 0x6d, 0x25b, 0x301, 0x25b, 0x6d, 0x6d,
+0x62, 0x61, 0x2019, 0x6d, 0x62, 0x61, 0x2019, 0x6d, 0x62, 0x61, 0x2bc, 0xe1, 0x6d, 0x62, 0x61, 0x2bc
};
static const ushort pm_data[] = {
-0x50, 0x4d, 0x57, 0x42, 0x6e, 0x6d, 0x2e, 0x4d, 0x44, 0x12a8, 0x1230, 0x12d3, 0x1275, 0x645, 0x56f, 0x565, 0x57d, 0x585, 0x580, 0x56b,
-0x581, 0x20, 0x570, 0x565, 0x57f, 0x578, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x985, 0x9aa, 0x9b0, 0x9be, 0x9b9, 0x9cd, 0x9a3,
-0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x441, 0x43b, 0x2e, 0x20, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031, 0x43f, 0x430, 0x441, 0x43b,
-0x44f, 0x20, 0x43f, 0x430, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x179b, 0x17d2, 0x1784, 0x17b6, 0x1785, 0x70, 0x2e, 0x6d, 0x2e, 0x4e0b, 0x5348,
-0x6f, 0x64, 0x70, 0x2e, 0xd801, 0xdc11, 0xd801, 0xdc23, 0x70, 0x6d, 0x69, 0x70, 0x2e, 0x6e, 0x61, 0x63, 0x68, 0x6d, 0x2e, 0x3bc,
-0x2e, 0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6, 0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e, 0x65, 0x2e,
-0x68, 0x2e, 0x5348, 0x5f8c, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, 0xeab, 0xebc, 0xeb1, 0xe87, 0xe97, 0xec8, 0xebd, 0xe87, 0x70,
-0x113, 0x63, 0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, 0x70, 0xf3, 0x6b, 0x77, 0x61, 0x70, 0x6f, 0x70, 0x69,
-0x65, 0x74, 0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x54, 0x47, 0x57, 0x4e, 0x4ae, 0x425, 0x909, 0x924, 0x94d,
-0x924, 0x930, 0x20, 0x92e, 0x927, 0x94d, 0x92f, 0x93e, 0x928, 0x94d, 0x939, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f, 0x627, 0x632,
-0x638, 0x647, 0x631, 0xa2c, 0xa3e, 0xa05, 0xa26, 0x20, 0xa26, 0xa41, 0xa2a, 0xa39, 0xa3f, 0xa30, 0x73, 0x6d, 0x43f, 0x43e, 0x441, 0x43b,
-0x435, 0x20, 0x43f, 0x43e, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x4c, 0x4b, 0x43f, 0x43e, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x6f,
-0x70, 0x6f, 0x64, 0x6e, 0x65, 0xdb4, 0x2e, 0xdc0, 0x2e, 0x70, 0x6f, 0x70, 0x6f, 0x6c, 0x75, 0x64, 0x6e, 0xed, 0x70, 0x6f,
-0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x72, 0x69, 0x65, 0x6d, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17,
-0xe35, 0xe48, 0xe22, 0xe07, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf51, 0xfb2, 0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0xd6,
-0x53, 0x43f, 0x43f, 0x628, 0x639, 0x62f, 0x20, 0x62f, 0x648, 0x67e, 0x6c1, 0x631, 0x43, 0x48, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x4e,
-0x74, 0x61, 0x6d, 0x62, 0x61, 0x6d, 0x61, 0x65, 0x74, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x45, 0x57,
-0x92e, 0x2e, 0x928, 0x902, 0x2e, 0x50, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x77, 0x129, 0x6f, 0x6f, 0x263, 0x65, 0x74, 0x72,
-0x254, 0x6e, 0x61, 0x6d, 0x2e, 0xa06f, 0xa2d2, 0x4d, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x2f, 0x4d, 0x6f, 0x67, 0x6c, 0x75, 0x6d,
-0x61, 0x20, 0x6c, 0x77, 0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, 0x61, 0x129, 0x2d, 0x69,
-0x6e, 0x129, 0x54, 0x65, 0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, 0x2d37, 0x2d33, 0x2d33, 0x2d6f,
-0x2d30, 0x2d5c, 0x74, 0x61, 0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, 0x64, 0x69, 0x74, 0x70,
-0x61, 0x6d, 0x75, 0x6e, 0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, 0x54, 0x13d2, 0x13af, 0x13f1,
-0x13a2, 0x13d7, 0x13e2, 0x43, 0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, 0x62, 0x61, 0x168, 0x47,
-0x4b, 0x65, 0x6d, 0x6f, 0x1c3, 0x75, 0x69, 0x61, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, 0xe2, 0x45, 0x69, 0x67, 0x75, 0x6c,
-0x6f, 0x69, 0x63, 0x68, 0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, 0x69, 0x41, 0x6c, 0x75, 0x75, 0x6c,
-0x61, 0x4f, 0x54, 0x1e0c, 0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, 0x79, 0x69, 0x61, 0x67, 0x68, 0x75,
-0x6f, 0x92c, 0x947, 0x932, 0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75,
-0x67, 0x61, 0x6a, 0x254, 0x70, 0x5a, 0x61, 0x61, 0x72, 0x69, 0x6b, 0x61, 0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d,
-0x75, 0x6e, 0x67, 0x259, 0x67, 0xf3, 0x67, 0x259, 0x6c, 0x65, 0x63, 0x25b, 0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68,
-0x6f, 0x63, 0x68, 0x69, 0x6c, 0x27, 0x6c, 0x6c, 0x69, 0x6c, 0x6c, 0x69, 0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x50, 0x61,
-0x73, 0x68, 0x61, 0x6d, 0x69, 0x68, 0x65, 0x79, 0x61, 0x20, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x6e, 0x61, 0x6b, 0x69, 0x73,
-0x25b, 0x301, 0x6e, 0x64, 0x25b, 0x14b, 0x6b, 0x61, 0x20, 0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63,
-0x77, 0xf2, 0x6e, 0x7a, 0xe9, 0x6d
+0x50, 0x4d, 0x57, 0x42, 0x6e, 0x6d, 0x2e, 0x70, 0x61, 0x73, 0x64, 0x69, 0x74, 0x65, 0x12a8, 0x1230, 0x12d3, 0x1275, 0x645, 0x56f,
+0x565, 0x57d, 0x585, 0x580, 0x56b, 0x581, 0x20, 0x570, 0x565, 0x57f, 0x578, 0x985, 0x9aa, 0x9f0, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0x985, 0x9aa,
+0x9b0, 0x9be, 0x9b9, 0x9cd, 0x9a3, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf46, 0xf0b, 0x441, 0x43b, 0x2e, 0x43e, 0x431, 0x2e, 0x100a, 0x1014, 0x1031,
+0x43f, 0x430, 0x441, 0x43b, 0x44f, 0x20, 0x43f, 0x430, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x179b, 0x17d2, 0x1784, 0x17b6, 0x1785, 0x70, 0x2e,
+0x20, 0x6d, 0x2e, 0x4e0b, 0x5348, 0xd801, 0xdc11, 0xd801, 0xdc23, 0x70, 0x6d, 0x70, 0x2e, 0x6d, 0x2e, 0x69, 0x70, 0x2e, 0x10e1, 0x10d0,
+0x10e6, 0x10d0, 0x10db, 0x10dd, 0x10e1, 0x6e, 0x61, 0x63, 0x68, 0x6d, 0x2e, 0x3bc, 0x2e, 0x3bc, 0x2e, 0x5d0, 0x5d7, 0x5d4, 0x5f4, 0x5e6,
+0x905, 0x92a, 0x930, 0x93e, 0x939, 0x94d, 0x928, 0x64, 0x75, 0x2e, 0x65, 0x2e, 0x68, 0x2e, 0x5348, 0x5f8c, 0x442, 0x4af, 0x441, 0x442,
+0x435, 0x43d, 0x20, 0x43a, 0x435, 0x439, 0x456, 0x43d, 0x442, 0x4af, 0x448, 0x442, 0x4e9, 0x43d, 0x20, 0x43a, 0x438, 0x439, 0x438, 0x43d,
+0x43a, 0x438, 0xc624, 0xd6c4, 0x5a, 0x2e, 0x4d, 0x57, 0x2e, 0xeab, 0xebc, 0xeb1, 0xe87, 0xe97, 0xec8, 0xebd, 0xe87, 0x70, 0x113, 0x63,
+0x70, 0x75, 0x73, 0x64, 0x69, 0x65, 0x6e, 0x101, 0x6d, 0x70, 0xf3, 0x6b, 0x77, 0x61, 0x70, 0x6f, 0x70, 0x69, 0x65, 0x74,
+0x43f, 0x43e, 0x43f, 0x43b, 0x430, 0x434, 0x43d, 0x435, 0x50, 0x54, 0x47, 0x57, 0x4e, 0x5b, 0x50, 0x4d, 0x5d, 0x4ae, 0x425, 0x909,
+0x924, 0x94d, 0x924, 0x930, 0x20, 0x92e, 0x927, 0x94d, 0x92f, 0x93e, 0x928, 0x94d, 0x939, 0x63a, 0x2e, 0x648, 0x2e, 0x628, 0x639, 0x62f,
+0x627, 0x632, 0x638, 0x647, 0x631, 0x64, 0x61, 0x20, 0x74, 0x61, 0x72, 0x64, 0x65, 0x73, 0x6d, 0x43f, 0x43e, 0x441, 0x43b, 0x435,
+0x20, 0x43f, 0x43e, 0x43b, 0x443, 0x434, 0x43d, 0x44f, 0x4c, 0x4b, 0x43f, 0x43e, 0x43f, 0x43e, 0x434, 0x43d, 0x435, 0x70, 0x6f, 0x70,
+0x6f, 0x64, 0x6e, 0x65, 0xdb4, 0x2e, 0xdc0, 0x2e, 0x70, 0x6f, 0x70, 0x2e, 0x67, 0x6e, 0x2e, 0x65, 0x6d, 0xbaa, 0xbbf, 0xbb1,
+0xbcd, 0xbaa, 0xb95, 0xbb2, 0xbcd, 0xe2b, 0xe25, 0xe31, 0xe07, 0xe40, 0xe17, 0xe35, 0xe48, 0xe22, 0xe07, 0xf55, 0xfb1, 0xf72, 0xf0b, 0xf51,
+0xfb2, 0xf7c, 0xf0b, 0x12f5, 0x1215, 0x122d, 0x20, 0x1230, 0x12d3, 0x1275, 0xd6, 0x53, 0x43f, 0x43f, 0x628, 0x639, 0x62f, 0x20, 0x62f, 0x648,
+0x67e, 0x6c1, 0x631, 0x43, 0x48, 0x1ecc, 0x300, 0x73, 0xe1, 0x6e, 0x186, 0x300, 0x73, 0xe1, 0x6e, 0x4e, 0x74, 0x61, 0x6d, 0x62,
+0x61, 0x6d, 0x61, 0x65, 0x74, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x64, 0x64, 0x61, 0x67, 0x45, 0x57, 0x92e, 0x2e, 0x928, 0x902,
+0x2e, 0x50, 0x2e, 0x4d, 0x2e, 0x128, 0x79, 0x61, 0x77, 0x129, 0x6f, 0x6f, 0x263, 0x65, 0x74, 0x72, 0x254, 0x6e, 0x61, 0x6d,
+0x2e, 0xa06f, 0xa2d2, 0x4d, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x2f, 0x4d, 0x6f, 0x67, 0x6c, 0x75, 0x6d, 0x61, 0x20, 0x6c, 0x77,
+0x61, 0x20, 0x70, 0x6b, 0x69, 0x6b, 0x69, 0x69, 0x257, 0x65, 0x48, 0x77, 0x61, 0x129, 0x2d, 0x69, 0x6e, 0x129, 0x54, 0x65,
+0x69, 0x70, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6f, 0x74, 0x6f, 0x2d5c, 0x2d30, 0x2d37, 0x2d33, 0x2d33, 0x2d6f, 0x2d30, 0x2d5c, 0x74, 0x61,
+0x64, 0x67, 0x67, 0x2b7, 0x61, 0x74, 0x6e, 0x20, 0x74, 0x6d, 0x65, 0x64, 0x64, 0x69, 0x74, 0x70, 0x61, 0x6d, 0x75, 0x6e,
+0x79, 0x69, 0x6b, 0x79, 0x69, 0x75, 0x6b, 0x6f, 0x6e, 0x79, 0x69, 0x55, 0x54, 0x13d2, 0x13af, 0x13f1, 0x13a2, 0x13d7, 0x13e2, 0x43,
+0x68, 0x69, 0x6c, 0x6f, 0x4d, 0x55, 0x55, 0x61, 0x6b, 0x61, 0x73, 0x75, 0x62, 0x61, 0x168, 0x47, 0x4b, 0x65, 0x6d, 0x6f,
+0x1c3, 0x75, 0x69, 0x61, 0x73, 0x190, 0x6e, 0x64, 0xe1, 0x6d, 0xe2, 0x45, 0x69, 0x67, 0x75, 0x6c, 0x6f, 0x69, 0x63, 0x68,
+0x61, 0x6d, 0x74, 0x68, 0x69, 0x45, 0x62, 0x6f, 0x6e, 0x67, 0x69, 0x41, 0x6c, 0x75, 0x75, 0x6c, 0x61, 0x4f, 0x54, 0x1e0c,
+0x65, 0x66, 0x66, 0x69, 0x72, 0x20, 0x61, 0x7a, 0x61, 0x6e, 0x79, 0x69, 0x61, 0x67, 0x68, 0x75, 0x6f, 0x92c, 0x947, 0x932,
+0x93e, 0x938, 0x947, 0x44, 0x69, 0x6c, 0x6f, 0x6c, 0x6f, 0x61, 0x2e, 0x6b, 0x49, 0x20, 0x253, 0x75, 0x67, 0x61, 0x6a, 0x254,
+0x70, 0x5a, 0x61, 0x61, 0x72, 0x69, 0x6b, 0x61, 0x79, 0x20, 0x62, 0x65, 0x62, 0x79, 0xe1, 0x6d, 0x75, 0x6e, 0x67, 0x259,
+0x67, 0xf3, 0x67, 0x259, 0x6c, 0x65, 0x63, 0x25b, 0x25b, 0x301, 0x6e, 0x6b, 0x6f, 0x6d, 0x63, 0x68, 0x6f, 0x63, 0x68, 0x69,
+0x6c, 0x27, 0x6c, 0x6c, 0x69, 0x6c, 0x6c, 0x69, 0x6b, 0x75, 0x67, 0xfa, 0x54, 0x14a, 0x50, 0x61, 0x73, 0x68, 0x61, 0x6d,
+0x69, 0x68, 0x65, 0x79, 0x61, 0x20, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x6e, 0x61, 0x6b, 0x69, 0x73, 0x25b, 0x301, 0x6e, 0x64,
+0x25b, 0x14b, 0x6b, 0x61, 0x20, 0x6d, 0x62, 0x254, 0x301, 0x74, 0x20, 0x6e, 0x6a, 0x69, 0x6e, 0x63, 0x77, 0xf2, 0x6e, 0x7a,
+0xe9, 0x6d
};
static const ushort currency_symbol_data[] = {
-0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0x64, 0x65, 0x6e, 0x20ac,
-0x1265, 0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43, 0x46,
-0x41, 0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f, 0x62f,
-0x2e, 0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f, 0x62f,
-0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f, 0x53,
-0x644, 0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f, 0x631, 0x2e, 0x64a, 0x2e, 0x200f,
-0x564, 0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x9f3, 0x4e, 0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b,
-0x440, 0x2e, 0x17db, 0xffe5, 0x4d, 0x4f, 0x50, 0x24, 0x4e, 0x54, 0x24, 0x6b, 0x6e, 0x4b, 0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x41,
-0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x45, 0x43, 0x24, 0x50, 0xa3, 0x44, 0x47, 0x48, 0x20b5, 0x41, 0x72, 0x4d, 0x4b,
-0x52, 0x73, 0x20a6, 0x20b1, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c, 0x65, 0x45, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68,
-0x56, 0x54, 0x4b, 0x52, 0x55, 0x53, 0x24, 0x44, 0x41, 0x43, 0x46, 0x41, 0x46, 0x42, 0x75, 0x43, 0x46, 0x46, 0x43, 0x46,
-0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x52, 0x46, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54, 0x46, 0x74, 0x52,
-0x70, 0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x20ad, 0x4c, 0x73, 0x4b, 0x7a, 0x4c, 0x74, 0x434, 0x435, 0x43d, 0x52, 0x4d, 0x20ae, 0x928,
-0x947, 0x930, 0x942, 0x60b, 0xfdfc, 0x7a, 0x142, 0x52, 0x24, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x440, 0x443, 0x431, 0x2e, 0x20b4,
-0x434, 0x438, 0x43d, 0x2e, 0x64, 0x69, 0x6e, 0x2e, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73, 0x20a1, 0x51, 0x4c, 0x43, 0x24,
-0x42, 0x2f, 0x2e, 0x20b2, 0x53, 0x2f, 0x2e, 0x42, 0x73, 0x2e, 0x52, 0x73, 0x2e, 0xe3f, 0xa5, 0x20ba, 0x441, 0x45e, 0x43c, 0x73,
-0x6f, 0x2bb, 0x6d, 0x20ab
+0x42, 0x72, 0x4b, 0x73, 0x68, 0x46, 0x64, 0x6a, 0x4e, 0x66, 0x6b, 0x52, 0x24, 0x4c, 0x65, 0x6b, 0xeb, 0x64, 0x65, 0x6e,
+0x20ac, 0x1265, 0x122d, 0x62c, 0x2e, 0x645, 0x2e, 0x200f, 0x62f, 0x2e, 0x62c, 0x2e, 0x200f, 0x62f, 0x2e, 0x628, 0x2e, 0x200f, 0x46, 0x43,
+0x46, 0x41, 0x641, 0x2e, 0x62c, 0x2e, 0x642, 0x2e, 0x200f, 0x62f, 0x2e, 0x639, 0x2e, 0x200f, 0x20aa, 0x62f, 0x2e, 0x623, 0x2e, 0x200f,
+0x62f, 0x2e, 0x643, 0x2e, 0x200f, 0x644, 0x2e, 0x644, 0x2e, 0x200f, 0x62f, 0x2e, 0x644, 0x2e, 0x200f, 0x623, 0x2e, 0x645, 0x2e, 0x200f,
+0x62f, 0x2e, 0x645, 0x2e, 0x200f, 0x631, 0x2e, 0x639, 0x2e, 0x200f, 0x631, 0x2e, 0x642, 0x2e, 0x200f, 0x631, 0x2e, 0x633, 0x2e, 0x200f,
+0x53, 0x62c, 0x2e, 0x633, 0x2e, 0x644, 0x2e, 0x633, 0x2e, 0x200f, 0x62f, 0x2e, 0x62a, 0x2e, 0x200f, 0x62f, 0x2e, 0x625, 0x2e, 0x200f,
+0x631, 0x2e, 0x64a, 0x2e, 0x200f, 0xa3, 0x564, 0x580, 0x2e, 0x20b9, 0x6d, 0x61, 0x6e, 0x2e, 0x43c, 0x430, 0x43d, 0x2e, 0x9f3, 0x4e,
+0x75, 0x2e, 0x43b, 0x432, 0x2e, 0x4b, 0x440, 0x2e, 0x17db, 0xffe5, 0x4d, 0x4f, 0x50, 0x24, 0x4e, 0x54, 0x24, 0x6b, 0x6e, 0x4b,
+0x4d, 0x4b, 0x10d, 0x6b, 0x72, 0x41, 0x66, 0x6c, 0x2e, 0x4e, 0x41, 0x66, 0x2e, 0x45, 0x43, 0x24, 0x50, 0x44, 0x47, 0x48,
+0x20b5, 0x41, 0x72, 0x4d, 0x4b, 0x52, 0x73, 0x55, 0x53, 0x24, 0x20a6, 0x20b1, 0x52, 0x46, 0x57, 0x53, 0x24, 0x53, 0x52, 0x4c,
+0x65, 0x45, 0x54, 0x53, 0x68, 0x54, 0x24, 0x55, 0x53, 0x68, 0x56, 0x54, 0x44, 0x41, 0x43, 0x46, 0x41, 0x46, 0x42, 0x75,
+0x43, 0x46, 0x46, 0x43, 0x46, 0x43, 0x46, 0x50, 0x46, 0x47, 0x47, 0x55, 0x4d, 0x43, 0x48, 0x46, 0x4c, 0x53, 0x44, 0x54,
+0x46, 0x74, 0x52, 0x70, 0x20b8, 0x441, 0x43e, 0x43c, 0x20a9, 0x20ad, 0x4b, 0x7a, 0x4c, 0x74, 0x434, 0x435, 0x43d, 0x52, 0x4d, 0x20ae,
+0x928, 0x947, 0x930, 0x942, 0x60b, 0x631, 0x6cc, 0x627, 0x644, 0x7a, 0x142, 0x52, 0x24, 0x4d, 0x54, 0x6e, 0x44, 0x62, 0x631, 0x4c,
+0x440, 0x443, 0x431, 0x2e, 0x20b4, 0x434, 0x438, 0x43d, 0x2e, 0x64, 0x69, 0x6e, 0x2e, 0x41a, 0x41c, 0xdbb, 0xdd4, 0x2e, 0x42, 0x73,
+0x20a1, 0x51, 0x43, 0x24, 0x42, 0x2f, 0x2e, 0x20b2, 0x53, 0x2f, 0x2e, 0x42, 0x73, 0x2e, 0x52, 0x73, 0x2e, 0xe3f, 0xa5, 0x20ba,
+0x73, 0x6f, 0x2bb, 0x6d, 0x441, 0x45e, 0x43c, 0x20ab
};
static const ushort currency_display_name_data[] = {
@@ -4517,153 +4610,173 @@ static const ushort currency_display_name_data[] = {
0x72, 0x72, 0x69, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69,
0x6b, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61,
0x6d, 0x69, 0x62, 0x69, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265,
-0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee,
-0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
-0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
-0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
-0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
-0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631,
+0x3b, 0x4c, 0x65, 0x6b, 0x75, 0x20, 0x73, 0x68, 0x71, 0x69, 0x70, 0x74, 0x61, 0x72, 0x3b, 0x3b, 0x6c, 0x65, 0x6b, 0x20,
+0x73, 0x68, 0x71, 0x69, 0x70, 0x74, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x65, 0x6b, 0xeb, 0x20, 0x73, 0x68, 0x71,
+0x69, 0x70, 0x74, 0x61, 0x72, 0x3b, 0x44, 0x65, 0x6e, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x61,
+0x73, 0x3b, 0x3b, 0x64, 0x65, 0x6e, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x61, 0x73, 0x3b, 0x3b,
+0x3b, 0x3b, 0x64, 0x65, 0x6e, 0x61, 0x72, 0xeb, 0x20, 0x6d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x61, 0x73, 0x3b, 0x45,
+0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x12e8, 0x12a2,
+0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b,
+0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631,
+0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631,
+0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631,
+0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x645, 0x635, 0x631,
0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a,
0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
-0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b,
-0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628,
+0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628,
0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f,
0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d,
-0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631,
-0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
-0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623,
-0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631,
-0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642,
-0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
-0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
-0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645,
-0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646,
-0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631,
-0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648,
-0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20,
-0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641,
-0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a,
-0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643,
+0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a,
+0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x628, 0x62d, 0x631,
+0x64a, 0x646, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643,
+0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b,
+0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631,
+0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643,
+0x20, 0x623, 0x641, 0x631, 0x64a, 0x642, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642,
+0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632,
+0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642,
+0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631,
+0x646, 0x643, 0x20, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a,
+0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646,
+0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a,
+0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a,
+0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x641, 0x631, 0x646, 0x643, 0x20, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x3b, 0x646, 0x627, 0x643,
0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a,
0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641,
0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631,
-0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
-0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a,
-0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642,
-0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20,
-0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20,
-0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c,
-0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f,
-0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a,
-0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f,
-0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b,
-0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
-0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f,
-0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a,
-0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627,
-0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20,
-0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c,
-0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628,
-0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644,
-0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631,
-0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
-0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
-0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
-0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a,
-0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648,
-0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627,
-0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b,
-0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628,
-0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a,
-0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
-0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
-0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631,
-0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a,
-0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627,
-0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
-0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
-0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
-0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642,
-0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20,
-0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
-0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631,
-0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a,
-0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627,
-0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648,
-0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20,
-0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646,
-0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
-0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633,
-0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646,
-0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646,
-0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648,
-0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20,
-0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631,
-0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f,
-0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a,
-0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646,
-0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a,
-0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645,
-0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a,
+0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627, 0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x646, 0x627, 0x643, 0x641, 0x627,
+0x20, 0x623, 0x631, 0x64a, 0x62a, 0x631, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631,
+0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
+0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x639, 0x631, 0x627, 0x642, 0x64a, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631,
+0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627,
+0x626, 0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626,
+0x64a, 0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a,
+0x644, 0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644,
+0x64a, 0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a,
+0x20, 0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x634, 0x64a, 0x643, 0x644, 0x20, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x64a, 0x20,
+0x62c, 0x62f, 0x64a, 0x62f, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623,
+0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x623, 0x631, 0x62f, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643,
+0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x643, 0x648, 0x64a, 0x62a, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628,
+0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a,
+0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a,
+0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628,
+0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x629, 0x20, 0x644, 0x628, 0x646, 0x627, 0x646, 0x64a, 0x3b, 0x62f, 0x64a, 0x646,
+0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f,
+0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a,
+0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a,
+0x628, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x20, 0x644, 0x64a, 0x628, 0x64a, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20,
+0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a,
+0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a,
+0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648,
+0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20,
+0x645, 0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x623, 0x648, 0x642, 0x64a, 0x629, 0x20, 0x645, 0x648, 0x631, 0x64a,
+0x62a, 0x627, 0x646, 0x64a, 0x629, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647,
+0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f,
+0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a,
+0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631, 0x628, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x645, 0x63a, 0x631,
+0x628, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639,
+0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
+0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a,
+0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x639, 0x645, 0x627, 0x646, 0x64a, 0x3b,
+0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b,
+0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b,
+0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b,
+0x631, 0x64a, 0x627, 0x644, 0x20, 0x642, 0x637, 0x631, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a,
+0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648,
+0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633,
+0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644,
+0x20, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644,
+0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b,
+0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644,
+0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645, 0x627, 0x644, 0x64a, 0x3b, 0x634, 0x644, 0x646, 0x20, 0x635, 0x648, 0x645,
+0x627, 0x644, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b,
+0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f,
+0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647,
+0x20, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x64a, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644,
+0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629,
+0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631,
+0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633, 0x648, 0x631, 0x64a, 0x629, 0x3b, 0x644, 0x64a, 0x631, 0x629, 0x20, 0x633,
+0x648, 0x631, 0x64a, 0x629, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627,
+0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a,
+0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b,
+0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633, 0x64a, 0x3b, 0x62f, 0x64a, 0x646, 0x627, 0x631, 0x62a, 0x648, 0x646, 0x633,
0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20,
0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a,
0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625,
-0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
-0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
-0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627,
-0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x540, 0x561, 0x575,
-0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576,
-0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580,
-0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e,
-0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
-0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be,
-0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa,
-0x9bf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf51, 0xf44, 0xf74, 0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440,
-0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b,
-0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430,
-0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x20, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x431,
-0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b,
-0x4eba, 0x6c11, 0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3,
-0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74,
-0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b,
-0x75, 0x6e, 0x65, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x68,
-0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72,
-0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65,
-0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
-0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x6b, 0x6f, 0x6e, 0x76,
-0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x6b, 0x6f,
-0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b,
-0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20,
-0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79,
-0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b, 0x44, 0x61, 0x6e, 0x73,
-0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65,
-0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x45, 0x75,
-0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x41, 0x72, 0x75,
-0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
-0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61,
-0x61, 0x6e, 0x73, 0x65, 0x20, 0x66, 0x6c, 0x6f, 0x72, 0x69, 0x6e, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e,
-0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64,
-0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c,
-0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65,
-0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73,
-0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61, 0x6d, 0x73, 0x65, 0x20,
-0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b,
+0x62f, 0x631, 0x647, 0x645, 0x20, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645,
+0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645,
+0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645,
+0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645, 0x646, 0x64a, 0x3b, 0x631, 0x64a, 0x627, 0x644, 0x20, 0x64a, 0x645,
+0x646, 0x64a, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646,
+0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c,
+0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a,
+0x647, 0x20, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20,
+0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646,
+0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x62c, 0x646, 0x64a, 0x647, 0x20, 0x62c, 0x646, 0x648, 0x628,
+0x20, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580,
+0x561, 0x574, 0x3b, 0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x3b, 0x3b,
+0x3b, 0x540, 0x561, 0x575, 0x56f, 0x561, 0x56f, 0x561, 0x576, 0x20, 0x564, 0x580, 0x561, 0x574, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
+0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62, 0x61,
+0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x7a, 0x259, 0x72, 0x62,
+0x61, 0x79, 0x63, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x74, 0x131, 0x3b, 0x43c, 0x430, 0x43d, 0x430, 0x442, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
+0x65, 0x75, 0x72, 0x6f, 0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b,
+0x3b, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x3b, 0x3b, 0x3b, 0x9ac,
+0x9be, 0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9c0, 0x20, 0x99f, 0x9be, 0x995, 0x9be, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af,
+0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf,
+0x3b, 0x3b, 0x3b, 0x3b, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0x9c0, 0x9af, 0x9bc, 0x20, 0x9b0, 0x9c1, 0x9aa, 0x9bf, 0x3b, 0xf51, 0xf44, 0xf74,
+0xf63, 0xf0b, 0xf40, 0xfb2, 0xf58, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x431, 0x44a,
+0x43b, 0x433, 0x430, 0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x3b, 0x3b, 0x3b, 0x3b, 0x431, 0x44a, 0x43b, 0x433, 0x430,
+0x440, 0x441, 0x43a, 0x438, 0x20, 0x43b, 0x435, 0x432, 0x430, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x1000, 0x103b, 0x1015, 0x103a,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c, 0x1000, 0x103b, 0x1015, 0x103a, 0x3b, 0x431, 0x435, 0x43b,
+0x430, 0x440, 0x443, 0x441, 0x43a, 0x456, 0x20, 0x440, 0x443, 0x431, 0x435, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x179a, 0x17c0, 0x179b, 0x20, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75,
+0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x4eba, 0x6c11,
+0x5e01, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4eba, 0x6c11, 0x5e01, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f,
+0x5143, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x95e8, 0x5143, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65b0, 0x52a0, 0x5761, 0x5143, 0x3b, 0x6e2f, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e2f, 0x5e63,
+0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6fb3, 0x9580, 0x5143, 0x3b, 0x65b0, 0x81fa, 0x5e63, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x65b0, 0x81fa, 0x5e63, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61,
+0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x68, 0x72, 0x76,
+0x61, 0x74, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x75, 0x6e, 0x65, 0x3b, 0x3b, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69,
+0x68, 0x20, 0x6b, 0x75, 0x6e, 0x61, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61,
+0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e,
+0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
+0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x3b, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69,
+0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f,
+0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x61, 0x3b, 0x3b,
+0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xe9, 0x20, 0x6b,
+0x6f, 0x72, 0x75, 0x6e, 0x79, 0x3b, 0x10d, 0x65, 0x73, 0x6b, 0xfd, 0x63, 0x68, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x6e, 0x3b,
+0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x20, 0x6b,
+0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x61, 0x6e, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65,
+0x72, 0x3b, 0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b,
+0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b,
+0x41, 0x72, 0x75, 0x62, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x4e, 0x65, 0x64,
+0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65,
+0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d,
+0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b,
+0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x2d, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c,
+0x69, 0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x67, 0x75, 0x6c, 0x64, 0x65, 0x6e, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61,
+0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x61,
+0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61,
+0x61, 0x6d, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61,
+0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x61,
+0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b,
+0x61, 0x61, 0x6e, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x55, 0x53, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
0x61, 0x72, 0x3b, 0x3b, 0x55, 0x53, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x53, 0x20,
0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69, 0x62, 0x62, 0x65,
0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x45, 0x61, 0x73, 0x74, 0x20, 0x43, 0x61, 0x72, 0x69,
@@ -4677,7 +4790,8 @@ static const ushort currency_display_name_data[] = {
0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e,
0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b,
+0x3b, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
0x3b, 0x3b, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x42,
0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64,
0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x6e, 0x20,
@@ -4693,213 +4807,247 @@ static const ushort currency_display_name_data[] = {
0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61,
0x72, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f,
0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
-0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x42, 0x72,
-0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
-0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f,
-0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b,
-0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47,
-0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x73, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61,
-0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63,
-0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69,
-0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47,
-0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69,
-0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e,
-0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
-0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65,
-0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67,
-0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b,
-0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64,
-0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20,
-0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b,
-0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b,
-0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75,
-0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75,
-0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
-0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69,
-0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72,
-0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69,
-0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20,
-0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69,
-0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61,
-0x72, 0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61,
-0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61,
-0x75, 0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69,
-0x74, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74,
-0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20,
-0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c,
-0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
-0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f,
-0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61,
-0x3b, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
-0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69,
-0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61,
-0x6e, 0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e,
-0x69, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47,
-0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e,
-0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50,
-0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e,
-0x61, 0x3b, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70,
-0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65,
-0x73, 0x6f, 0x73, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d,
-0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74,
-0x61, 0x6c, 0x61, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65,
-0x65, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65,
-0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65,
-0x65, 0x73, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65,
-0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20,
-0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e,
-0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65,
-0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64,
-0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e,
-0x64, 0x73, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49,
-0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c,
-0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73,
-0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77,
-0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61,
-0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
-0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
-0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a,
-0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67,
-0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70,
-0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb,
-0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f,
-0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61,
-0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
-0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61,
-0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53,
-0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
-0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69,
-0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b,
-0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e,
-0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b,
-0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68,
-0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73,
-0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e,
-0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f,
-0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73,
-0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b,
-0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61,
-0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6e,
-0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67,
-0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65,
-0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e,
-0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b,
-0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29,
-0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
-0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46,
-0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43,
-0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e,
-0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69,
-0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
-0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f,
-0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f,
-0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75,
-0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74,
-0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
-0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x50, 0x3b,
-0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x67,
-0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69,
-0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65, 0x6e,
-0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69, 0x65,
-0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65,
-0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b, 0x3b, 0x3b,
-0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73, 0x3b, 0x6f,
-0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b, 0x3b,
-0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e, 0x3b,
-0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e,
-0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
-0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x69, 0x65,
-0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69,
-0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63,
-0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61, 0x69, 0x6e,
-0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
-0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x64,
-0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69,
-0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x3b, 0x3b,
-0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c,
-0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66, 0x72, 0x61,
-0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20,
-0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e,
-0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64,
-0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72,
-0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20,
-0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61,
-0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e,
-0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x73,
-0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72,
-0x6f, 0x73, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
-0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b,
-0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b,
-0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395,
-0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61,
-0x6e, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61,
-0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64,
-0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0,
-0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xac0, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x69,
-0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75, 0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20,
-0x6e, 0x61, 0x20, 0x41, 0x66, 0x69, 0x72, 0x6b, 0x61, 0x20, 0x54, 0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9,
-0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd,
-0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d,
-0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61,
-0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcd, 0x73,
-0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b,
-0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x72, 0x20,
-0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
-0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66,
-0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x68, 0x69, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xcad, 0xcbe, 0xcb0, 0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0, 0xcc1, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c1, 0x650, 0x646, 0x62f, 0x64f, 0x633, 0x62a, 0x672, 0x646, 0x6cd, 0x20, 0x631, 0x6c4, 0x67e, 0x64e,
-0x6d2, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x442, 0x435,
-0x4a3, 0x433, 0x435, 0x441, 0x456, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x20,
-0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x72, 0x79, 0x27,
-0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe81, 0xeb5, 0xe9a, 0x20, 0xea5,
-0xeb2, 0xea7, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x73, 0x20, 0x6c, 0x61,
-0x74, 0x73, 0x3b, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a, 0x61, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x3b, 0x4c, 0x61, 0x74,
-0x76, 0x69, 0x6a, 0x61, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a,
-0x61, 0x73, 0x20, 0x6c, 0x61, 0x74, 0x69, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b,
-0x6f, 0x6e, 0x67, 0xf3, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x79, 0x61,
-0x20, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67,
-0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x65,
-0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x73, 0x3b, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f,
-0x73, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x73, 0x3b, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69,
-0x74, 0x61, 0x69, 0x3b, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x173, 0x3b, 0x41c,
-0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x41, 0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x69, 0x6e, 0x67, 0x67,
-0x69, 0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f,
-0x6c, 0x61, 0x72, 0x20, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c,
-0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xd07,
-0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20,
-0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x45,
-0x77, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a,
-0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x422, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x442, 0x4e9, 0x433,
+0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61,
+0x6e, 0x64, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61,
+0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61,
+0x6c, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61,
+0x6e, 0x20, 0x4e, 0x61, 0x6b, 0x66, 0x61, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x6e, 0x61,
+0x6b, 0x66, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x72, 0x69, 0x74, 0x72, 0x65, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x6b, 0x66,
+0x61, 0x73, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20,
+0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61,
+0x6e, 0x64, 0x73, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e,
+0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x46, 0x69, 0x6a,
+0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x69, 0x6a, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x73, 0x3b, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x42,
+0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x72, 0x69, 0x74,
+0x69, 0x73, 0x68, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44,
+0x61, 0x6c, 0x61, 0x73, 0x69, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73,
+0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x61, 0x6c, 0x61, 0x73, 0x69, 0x73,
+0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61, 0x6e, 0x20, 0x43, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e,
+0x61, 0x69, 0x61, 0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x69, 0x61,
+0x6e, 0x20, 0x63, 0x65, 0x64, 0x69, 0x73, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x50, 0x6f,
+0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64,
+0x3b, 0x3b, 0x3b, 0x3b, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73,
+0x3b, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x47,
+0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x47,
+0x75, 0x79, 0x61, 0x6e, 0x61, 0x65, 0x73, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x48, 0x6f, 0x6e,
+0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20,
+0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x48, 0x6f, 0x6e, 0x67, 0x20,
+0x4b, 0x6f, 0x6e, 0x67, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20,
+0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b,
+0x3b, 0x3b, 0x3b, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4a, 0x61, 0x6d,
+0x61, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63,
+0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61,
+0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69,
+0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69,
+0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
+0x67, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x52, 0x61, 0x6e,
+0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72, 0x61, 0x6e,
+0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x72,
+0x61, 0x6e, 0x64, 0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b,
+0x3b, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x4d, 0x61, 0x63,
+0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x3b, 0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65,
+0x73, 0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x63, 0x61, 0x6e, 0x65, 0x73,
+0x65, 0x20, 0x70, 0x61, 0x74, 0x61, 0x63, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41,
+0x72, 0x69, 0x61, 0x72, 0x79, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61,
+0x72, 0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x20, 0x41, 0x72, 0x69, 0x61, 0x72,
+0x69, 0x65, 0x73, 0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b,
+0x3b, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x4d, 0x61, 0x75,
+0x72, 0x69, 0x74, 0x69, 0x61, 0x6e, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74,
+0x69, 0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69,
+0x61, 0x6e, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x44,
+0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61,
+0x72, 0x73, 0x3b, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x4e,
+0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x69, 0x67,
+0x65, 0x72, 0x69, 0x61, 0x6e, 0x20, 0x6e, 0x61, 0x69, 0x72, 0x61, 0x73, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61,
+0x6e, 0x69, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20,
+0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x69, 0x20, 0x72,
+0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e,
+0x65, 0x61, 0x6e, 0x20, 0x4b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20,
+0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x70, 0x75,
+0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6b, 0x69, 0x6e, 0x61, 0x3b, 0x50,
+0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c,
+0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69,
+0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20,
+0x46, 0x72, 0x61, 0x6e, 0x63, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x3b, 0x53,
+0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x54, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74,
+0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x6e, 0x20, 0x74, 0x61, 0x6c, 0x61, 0x3b, 0x53,
+0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x52, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x53, 0x65,
+0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
+0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x69, 0x73, 0x20, 0x72, 0x75, 0x70, 0x65, 0x65, 0x73, 0x3b, 0x53, 0x69,
+0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x3b, 0x3b,
+0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c, 0x65, 0x6f, 0x6e, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x61, 0x6e, 0x20, 0x6c,
+0x65, 0x6f, 0x6e, 0x65, 0x73, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x44, 0x6f, 0x6c, 0x6c,
+0x61, 0x72, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72,
+0x73, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x44, 0x6f,
+0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x20,
+0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x53, 0x61, 0x69, 0x6e,
+0x74, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x61, 0x69, 0x6e,
+0x74, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x61,
+0x69, 0x6e, 0x74, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x53, 0x75,
+0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65,
+0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65,
+0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x4c, 0x69, 0x6c, 0x61, 0x6e, 0x67,
+0x65, 0x6e, 0x69, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x6c, 0x69, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69,
+0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x20, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x65, 0x6e, 0x69,
+0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b,
+0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b,
+0x3b, 0x3b, 0x3b, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e,
+0x67, 0x73, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x50, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x54,
+0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e,
+0x67, 0x61, 0x6e, 0x20, 0x70, 0x61, 0x2bb, 0x61, 0x6e, 0x67, 0x61, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64,
+0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b,
+0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20,
+0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61,
+0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62, 0x61, 0x67, 0x6f, 0x20, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x3b, 0x55, 0x67,
+0x61, 0x6e, 0x64, 0x61, 0x6e, 0x20, 0x53, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e,
+0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x3b, 0x3b, 0x3b, 0x3b, 0x55, 0x67, 0x61, 0x6e,
+0x64, 0x61, 0x6e, 0x20, 0x73, 0x68, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74,
+0x75, 0x20, 0x56, 0x61, 0x74, 0x75, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75,
+0x3b, 0x3b, 0x3b, 0x3b, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x74, 0x75, 0x73, 0x3b, 0x5a, 0x61,
+0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20, 0x4b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61,
+0x6e, 0x20, 0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x20,
+0x6b, 0x77, 0x61, 0x63, 0x68, 0x61, 0x73, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65,
+0x73, 0x65, 0x20, 0x50, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61,
+0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20,
+0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x73, 0x65, 0x20, 0x70, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3b, 0x4e, 0x65, 0x74, 0x68,
+0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x47, 0x75,
+0x69, 0x6c, 0x64, 0x65, 0x72, 0x3b, 0x3b, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41,
+0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61, 0x6e, 0x20, 0x67, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b,
+0x4e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x20, 0x41, 0x6e, 0x74, 0x69, 0x6c, 0x6c, 0x65, 0x61,
+0x6e, 0x20, 0x67, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x73, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72,
+0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3,
+0x6e, 0x61, 0x3b, 0x3b, 0x64, 0x6f, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x64,
+0x6f, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65,
+0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x61, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61,
+0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72,
+0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x73, 0x20, 0x61, 0x6c, 0x67, 0xe9, 0x72, 0x69,
+0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f,
+0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29,
+0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41,
+0x4f, 0x29, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73,
+0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63,
+0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x20, 0x63, 0x61, 0x6e, 0x61,
+0x64, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61,
+0x64, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e,
+0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x63, 0x6f, 0x6d, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20,
+0x63, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x69, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62,
+0x6f, 0x75, 0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f, 0x75,
+0x74, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x64, 0x6a, 0x69, 0x62, 0x6f,
+0x75, 0x74, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x50, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73, 0x20, 0x43, 0x46,
+0x50, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x73,
+0x20, 0x67, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x6e, 0x73, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef,
+0x74, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x20, 0x68, 0x61, 0xef, 0x74, 0x69,
+0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x6f, 0x75, 0x72, 0x64, 0x65, 0x73, 0x20, 0x68, 0x61, 0xef, 0x74,
+0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63,
+0x68, 0x65, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x3b,
+0x3b, 0x3b, 0x3b, 0x61, 0x72, 0x69, 0x61, 0x72, 0x79, 0x73, 0x20, 0x6d, 0x61, 0x6c, 0x67, 0x61, 0x63, 0x68, 0x65, 0x73,
+0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x6e,
+0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65,
+0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x6f, 0x75, 0x67, 0x75, 0x69, 0x79, 0x61, 0x73, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x74,
+0x61, 0x6e, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63,
+0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x20, 0x6d, 0x61, 0x75, 0x72, 0x69, 0x63,
+0x69, 0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x75,
+0x72, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72,
+0x6f, 0x63, 0x61, 0x69, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61,
+0x69, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x72, 0x68, 0x61, 0x6d, 0x73, 0x20, 0x6d, 0x61, 0x72, 0x6f, 0x63, 0x61,
+0x69, 0x6e, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72,
+0x61, 0x6e, 0x63, 0x73, 0x20, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x69, 0x73, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65,
+0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b, 0x72, 0x6f, 0x75,
+0x70, 0x69, 0x65, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x3b,
+0x3b, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x65, 0x73, 0x20, 0x64, 0x65, 0x73, 0x20, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65,
+0x6c, 0x6c, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
+0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x73, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69,
+0x65, 0x6e, 0x6e, 0x65, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65,
+0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x69, 0x76, 0x72, 0x65, 0x73, 0x20, 0x73, 0x79, 0x72, 0x69, 0x65, 0x6e, 0x6e, 0x65, 0x73,
+0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x64, 0x69, 0x6e,
+0x61, 0x72, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x69, 0x6e, 0x61, 0x72,
+0x73, 0x20, 0x74, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x73, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e,
+0x75, 0x61, 0x74, 0x75, 0x61, 0x6e, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75,
+0x61, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x76, 0x61, 0x74, 0x75, 0x73, 0x20, 0x76, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x61,
+0x6e, 0x73, 0x3b, 0x50, 0x75, 0x6e, 0x6e, 0x64, 0x20, 0x53, 0x61, 0x73, 0x61, 0x6e, 0x6e, 0x61, 0x63, 0x68, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x10e5,
+0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x3b, 0x3b, 0x3b, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3,
+0x10da, 0x10d8, 0x20, 0x10da, 0x10d0, 0x10e0, 0x10d8, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b,
+0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61,
+0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e,
+0x6b, 0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61,
+0x6e, 0x6b, 0x65, 0x6e, 0x3b, 0x395, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b5, 0x3c5, 0x3c1, 0x3ce, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b5,
+0x3c5, 0x3c1, 0x3ce, 0x3b, 0x64, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75,
+0x75, 0x6e, 0x69, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x6e, 0x75, 0x74, 0x20, 0x6b, 0x6f, 0x72, 0x75, 0x75,
+0x6e, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6d, 0x75, 0x74, 0x20, 0x6b, 0x6f,
+0x72, 0x75, 0x75, 0x6e, 0x69, 0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b,
+0x3b, 0xaad, 0xabe, 0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x3b, 0x3b, 0x3b, 0xaad, 0xabe,
+0xab0, 0xaa4, 0xac0, 0xaaf, 0x20, 0xab0, 0xac2, 0xaaa, 0xabf, 0xaaf, 0xabe, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x75, 0x257, 0x69, 0x6e, 0x20, 0x53, 0x65, 0x66, 0x61, 0x20, 0x6e, 0x61, 0x20, 0x41, 0x66,
+0x69, 0x72, 0x6b, 0x61, 0x20, 0x54, 0x61, 0x20, 0x59, 0x61, 0x6d, 0x6d, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x5e9, 0x5f4, 0x5d7, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc,
+0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9,
+0x5dd, 0x3b, 0x5e9, 0x5e7, 0x5dc, 0x5d9, 0x5dd, 0x20, 0x5d7, 0x5d3, 0x5e9, 0x5d9, 0x5dd, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f,
+0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e,
+0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x942, 0x92a, 0x90f, 0x3b, 0x6d, 0x61, 0x67, 0x79,
+0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f,
+0x72, 0x69, 0x6e, 0x74, 0x3b, 0x3b, 0x3b, 0x3b, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, 0x69, 0x6e,
+0x74, 0x3b, 0xcd, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0xed, 0x73, 0x6c,
+0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73,
+0x6b, 0x61, 0x72, 0x20, 0x6b, 0x72, 0xf3, 0x6e, 0x75, 0x72, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20, 0x49, 0x6e,
+0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x75, 0x70, 0x69, 0x61, 0x68, 0x20,
+0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20,
+0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x73, 0x76, 0x69,
+0x7a, 0x7a, 0x65, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x69, 0x20, 0x73, 0x76, 0x69,
+0x7a, 0x7a, 0x65, 0x72, 0x69, 0x3b, 0x65e5, 0x672c, 0x5186, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x5186, 0x3b, 0xcad, 0xcbe, 0xcb0,
+0xca4, 0xcc0, 0xcaf, 0x20, 0xcb0, 0xcc1, 0xcaa, 0xcbe, 0xcaf, 0xcbf, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c1, 0x650, 0x646,
+0x62f, 0x64f, 0x633, 0x62a, 0x672, 0x646, 0x6cd, 0x20, 0x631, 0x6c4, 0x67e, 0x64e, 0x6d2, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x442, 0x435, 0x4a3, 0x433, 0x435, 0x441, 0x456, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b,
+0x3b, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b, 0x3b, 0x3b, 0x3b,
+0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0x20, 0x441, 0x43e, 0x43c, 0x443, 0x3b, 0xb300, 0xd55c, 0xbbfc, 0xad6d,
+0x20, 0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20,
+0xacf5, 0xd654, 0xad6d, 0x20, 0xc6d0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x66, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61,
+0x20, 0x72, 0x79, 0x27, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe81,
+0xeb5, 0xe9a, 0x20, 0xea5, 0xeb2, 0xea7, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x65, 0x69,
+0x72, 0x6f, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x46, 0x61, 0x6c, 0xe1,
+0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b,
+0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x79, 0x61, 0x20, 0x41, 0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x46, 0x61, 0x6c, 0xe1, 0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x73, 0x3b,
+0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x73, 0x3b, 0x3b, 0x4c, 0x69, 0x65,
+0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x61, 0x69, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73,
+0x20, 0x6c, 0x69, 0x74, 0x6f, 0x3b, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x6f, 0x73, 0x20, 0x6c, 0x69, 0x74, 0x173, 0x3b,
+0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x41c, 0x430,
+0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x41c, 0x430,
+0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x435, 0x43d, 0x430, 0x440, 0x3b, 0x41, 0x72, 0x69, 0x61, 0x72,
+0x79, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x20, 0x4d, 0x61, 0x6c, 0x61,
+0x79, 0x73, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x69, 0x6e, 0x67, 0x67, 0x69, 0x74, 0x20, 0x4d, 0x61,
+0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x72, 0x20, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x3b, 0x44, 0x6f,
+0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44,
+0x6f, 0x6c, 0x61, 0x72, 0x20, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d,
+0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b,
+0x3b, 0x3b, 0x3b, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0xd7b, 0x20, 0xd30, 0xd42, 0xd2a, 0x3b, 0x45, 0x77, 0x72, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b,
+0x92d, 0x93e, 0x930, 0x924, 0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x3b, 0x3b, 0x3b, 0x92d, 0x93e, 0x930, 0x924,
+0x940, 0x92f, 0x20, 0x930, 0x941, 0x92a, 0x92f, 0x93e, 0x3b, 0x422, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x442, 0x4e9, 0x433,
0x440, 0x4e9, 0x433, 0x3b, 0x3b, 0x3b, 0x3b, 0x442, 0x4e9, 0x433, 0x440, 0x4e9, 0x433, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940,
0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a,
0x948, 0x92f, 0x93e, 0x901, 0x3b, 0x3b, 0x3b, 0x3b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x20, 0x930, 0x942, 0x92a, 0x948, 0x92f,
@@ -4909,41 +5057,45 @@ static const ushort currency_display_name_data[] = {
0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e,
0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0xb1f,
0xb19, 0xb15, 0xb3e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cd, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f,
-0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c,
-0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x63,
-0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x67, 0x6f, 0x3b,
-0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x52, 0x65, 0x61,
-0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x65, 0x61, 0x69,
-0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61,
-0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e,
-0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73, 0x20, 0x61, 0x6e,
-0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d,
-0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62,
-0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f,
-0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x44, 0xf3, 0x6c,
-0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f,
-0x73, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73,
-0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x64,
-0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x46, 0x72,
-0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e,
-0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x46,
-0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b,
-0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x6d, 0x61, 0x63, 0x61, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x50, 0x61, 0x74,
-0x61, 0x63, 0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61,
-0x63, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c,
-0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69,
-0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b,
-0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62,
-0x69, 0x71, 0x75, 0x65, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45,
-0x75, 0x72, 0x6f, 0x73, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f,
-0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61,
-0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63,
-0x69, 0x70, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f,
-0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0xa30, 0xa41, 0xa2a,
-0xa3f, 0xa2f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20,
+0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x631, 0x6cc, 0x627, 0x644, 0x20, 0x627, 0x6cc, 0x631, 0x627, 0x646, 0x3b,
+0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x627, 0x641,
+0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x641,
+0x63a, 0x627, 0x646, 0x6cc, 0x20, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79,
+0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x79, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b,
+0x69, 0x3b, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x3b, 0x7a, 0x142, 0x6f,
+0x74, 0x79, 0x63, 0x68, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x63, 0x68, 0x3b, 0x7a, 0x142, 0x6f, 0x74, 0x65, 0x67,
+0x6f, 0x20, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x65, 0x67, 0x6f, 0x3b, 0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61,
+0x73, 0x69, 0x6c, 0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x52, 0x65, 0x61, 0x6c, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c,
+0x65, 0x69, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x52, 0x65, 0x61, 0x69, 0x73, 0x20, 0x62, 0x72, 0x61, 0x73, 0x69, 0x6c,
+0x65, 0x69, 0x72, 0x6f, 0x73, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e,
+0x6f, 0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b,
+0x3b, 0x3b, 0x4b, 0x77, 0x61, 0x6e, 0x7a, 0x61, 0x73, 0x20, 0x61, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b,
+0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f,
+0x3b, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61,
+0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x73, 0x63, 0x75, 0x64, 0x6f, 0x73, 0x20, 0x63, 0x61, 0x62, 0x6f, 0x2d, 0x76,
+0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45,
+0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72,
+0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b,
+0x3b, 0x3b, 0x3b, 0x44, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x64, 0x6f, 0x73, 0x20, 0x45, 0x73, 0x74, 0x61, 0x64,
+0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41,
+0x20, 0x64, 0x65, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46,
+0x41, 0x20, 0x64, 0x65, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x6f,
+0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x64, 0x65, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63,
+0x61, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x20, 0x64,
+0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x61, 0x74, 0x61, 0x63, 0x61, 0x73, 0x20, 0x64,
+0x65, 0x20, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d,
+0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64,
+0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69,
+0x63, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x3b,
+0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x73, 0x3b,
+0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20,
+0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x20, 0x64, 0x65, 0x20, 0x53,
+0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0x3b,
+0x3b, 0x3b, 0x44, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x20, 0x64, 0x65, 0x20, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9,
+0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70, 0x65, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41,
+0xa2a, 0xa0f, 0x3b, 0x3b, 0xa2d, 0xa3e, 0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa0f, 0x3b, 0x3b, 0x3b, 0x3b, 0xa2d, 0xa3e,
+0xa30, 0xa24, 0xa40, 0x20, 0xa30, 0xa41, 0xa2a, 0xa0f, 0x3b, 0x631, 0x648, 0x67e, 0x626, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x73, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x75, 0x20,
0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65, 0x73, 0x63, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x72, 0x6f, 0x6d, 0xe2, 0x6e, 0x65,
@@ -4953,516 +5105,531 @@ static const ushort currency_display_name_data[] = {
0x64, 0x6f, 0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x3b, 0x6c, 0x65, 0x69, 0x20, 0x6d, 0x6f, 0x6c, 0x64, 0x6f,
0x76, 0x65, 0x6e, 0x65, 0x219, 0x74, 0x69, 0x3b, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440,
0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431,
-0x43b, 0x44c, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f,
-0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x440,
-0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x411, 0x435, 0x43b,
-0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e,
-0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440,
-0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441,
-0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441,
-0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439,
-0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435,
-0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435,
-0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437,
-0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437,
-0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439,
-0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c,
-0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43a, 0x438,
-0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x41c, 0x43e, 0x43b, 0x434, 0x430,
-0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438,
-0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435,
-0x44f, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432, 0x3b, 0x43c, 0x43e,
-0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d,
-0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441,
-0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a,
-0x438, 0x435, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x438, 0x445,
-0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x441, 0x43a, 0x43e, 0x439, 0x20, 0x433,
-0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, 0x61, 0x72, 0xe2, 0x6e, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42,
-0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438,
-0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441,
-0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445,
-0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430,
-0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72,
-0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f,
-0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20,
-0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c,
-0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65,
-0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x61,
-0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73,
-0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e,
-0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x45,
-0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x61,
-0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b,
-0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x61,
-0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61,
-0x72, 0x61, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41a, 0x43e,
-0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x41c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431,
-0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430,
-0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430,
-0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430,
-0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430,
-0x440, 0x43a, 0x65, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e,
-0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430, 0x431, 0x438, 0x43b, 0x43d, 0x438,
-0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
-0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438,
-0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b,
-0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x435, 0x432, 0x440, 0x430,
-0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b, 0x421, 0x43e,
-0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72, 0x61, 0x20,
-0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xdbd, 0xd82, 0xd9a,
-0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0xdca, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f,
-0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0xe1, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x2c, 0x20, 0x65,
-0x75, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b,
-0x65, 0x76, 0x72, 0x69, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x76, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x20, 0x73,
-0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x20,
-0x4a, 0x61, 0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x42, 0x69, 0x72, 0x74, 0x61,
-0x20, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73,
-0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72,
-0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x61, 0x72, 0x67,
-0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62,
-0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e,
-0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73,
-0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63,
-0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69,
-0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f,
-0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f,
-0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73,
-0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e,
-0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72,
-0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f,
-0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73,
-0x6f, 0x73, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69,
-0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63,
-0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63,
-0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69,
-0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75,
-0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x65, 0x73, 0x20, 0x65,
-0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63,
-0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43,
-0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x73, 0x20, 0x43,
-0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x20, 0x67, 0x75, 0x61, 0x74,
-0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63, 0x6f, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x20, 0x67, 0x75,
-0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61,
-0x6c, 0x65, 0x73, 0x20, 0x67, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63, 0x6f, 0x73, 0x3b, 0x6c, 0x65,
-0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x6c, 0x65, 0x6d,
-0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6c, 0x65,
-0x6d, 0x70, 0x69, 0x72, 0x61, 0x73, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x70, 0x65,
-0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65,
-0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x6d, 0x65, 0x78, 0x69,
-0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61,
-0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e, 0x69, 0x63, 0x61,
-0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x73,
-0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f,
-0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70,
-0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x73, 0x20, 0x70,
-0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72,
-0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x20, 0x70, 0x61, 0x72, 0x61,
-0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed, 0x65, 0x73, 0x20, 0x70,
-0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f, 0x20, 0x73, 0x6f, 0x6c, 0x20,
-0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f, 0x20, 0x73, 0x6f, 0x6c, 0x20, 0x70,
-0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f, 0x73, 0x20, 0x73, 0x6f, 0x6c,
-0x65, 0x73, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c,
-0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f,
-0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x73, 0x3b,
-0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20,
-0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x75, 0x72,
-0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65,
-0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x20, 0x76, 0x65, 0x6e, 0x65,
-0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72, 0x65, 0x73, 0x20,
-0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69,
-0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73,
-0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64,
-0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61,
-0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x76,
-0x65, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x6f, 0x72, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65,
-0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x421, 0x43e, 0x43c, 0x43e, 0x43d, 0x4e3, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xbae, 0xbb2,
-0xbc7, 0xb9a, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2, 0xbb0, 0xbcd, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b,
-0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc32, 0xc41, 0x3b, 0xe1a, 0xe32, 0xe17, 0xe44, 0xe17, 0xe22, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0xf61, 0xf74, 0xf0b, 0xf68, 0xf53, 0xf0b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf62, 0xf92, 0xfb1, 0xf0b,
-0xf42, 0xf62, 0xf0b, 0xf66, 0xf92, 0xf7c, 0xf62, 0xf0b, 0xf58, 0xf7c, 0xf0b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2,
-0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x4c,
-0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c,
-0x43a, 0x430, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433,
-0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456,
-0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x627, 0x646, 0x688, 0x6cc, 0x646, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
-0x69, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2bb, 0x6d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x110, 0x1ed3, 0x6e,
-0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x50, 0x75, 0x6e,
-0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50,
-0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e,
-0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61,
-0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79,
-0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50,
-0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67,
-0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69,
-0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x61, 0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20,
-0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e,
-0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72,
-0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b, 0x3b,
-0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73,
-0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e, 0x76,
-0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73,
-0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b,
-0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b,
-0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b,
-0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b,
-0x65, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61,
+0x43b, 0x44c, 0x3b, 0x3b, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b,
+0x435, 0x439, 0x3b, 0x440, 0x43e, 0x441, 0x441, 0x438, 0x439, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f,
+0x3b, 0x411, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b,
+0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44c, 0x3b, 0x3b, 0x3b,
+0x431, 0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x435, 0x439, 0x3b, 0x431,
+0x435, 0x43b, 0x43e, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x440, 0x443, 0x431, 0x43b, 0x44f, 0x3b, 0x41a, 0x430,
+0x437, 0x430, 0x445, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445,
+0x441, 0x43a, 0x438, 0x439, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x3b, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a,
+0x438, 0x445, 0x20, 0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x43a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20,
+0x442, 0x435, 0x43d, 0x433, 0x435, 0x3b, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c,
+0x3b, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x43a,
+0x438, 0x440, 0x433, 0x438, 0x437, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x43a, 0x438, 0x440, 0x433, 0x438,
+0x437, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x441, 0x43e, 0x43c, 0x430, 0x3b, 0x41c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a,
+0x438, 0x439, 0x20, 0x43b, 0x435, 0x439, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x439, 0x20, 0x43b,
+0x435, 0x439, 0x3b, 0x3b, 0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x43b, 0x435, 0x435, 0x432,
+0x3b, 0x43c, 0x43e, 0x43b, 0x434, 0x430, 0x432, 0x441, 0x43a, 0x43e, 0x433, 0x43e, 0x20, 0x43b, 0x435, 0x44f, 0x3b, 0x423, 0x43a, 0x440,
+0x430, 0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430,
+0x438, 0x43d, 0x441, 0x43a, 0x430, 0x44f, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x430, 0x3b, 0x3b, 0x3b, 0x443, 0x43a, 0x440, 0x430,
+0x438, 0x43d, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x438, 0x43d,
+0x441, 0x43a, 0x43e, 0x439, 0x20, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44b, 0x3b, 0x66, 0x61, 0x72, 0xe2, 0x6e, 0x67, 0x61, 0x20,
+0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x421, 0x440, 0x43f,
+0x441, 0x43a, 0x438, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x20, 0x434, 0x438,
+0x43d, 0x430, 0x440, 0x3b, 0x3b, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x430, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x3b,
+0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x445, 0x20, 0x434, 0x438, 0x43d, 0x430, 0x440, 0x430, 0x3b, 0x4b, 0x6f, 0x6e, 0x76, 0x65,
+0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61,
+0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f,
+0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62,
+0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x65,
+0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x65,
+0x3b, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61,
0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20,
-0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63,
-0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69,
-0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438,
-0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a,
-0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435,
-0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430,
-0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e,
-0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x3b, 0x431, 0x43e, 0x441,
-0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20,
-0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a,
-0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430,
-0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20,
-0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69,
-0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x67,
-0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256,
-0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x263, 0x65, 0x74, 0x6f,
-0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72,
-0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20,
-0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42,
-0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72,
-0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41,
-0x4f, 0x3b, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x20, 0x50, 0x65, 0x73, 0x6f, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65,
-0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b,
-0x3b, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x6e,
-0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67,
-0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75,
-0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e,
-0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b,
-0x65, 0x75, 0x72, 0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e,
-0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66,
-0x61, 0x61, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x69, 0x72, 0x69, 0x6e,
-0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x6a,
-0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62,
-0x69, 0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x73, 0x65,
-0x20, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x65, 0x6c, 0x65, 0x72,
-0x69, 0x20, 0x73, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x2d30, 0x2d37, 0x2d54, 0x2d49, 0x2d4e, 0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x61, 0x64, 0x72, 0x69, 0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e,
-0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61,
-0x20, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68,
-0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41,
-0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x13a4, 0x13c3, 0x13cd, 0x13d7, 0x3b, 0x3b, 0x13a4, 0x13c3, 0x13cd, 0x13d7, 0x3b,
-0x3b, 0x3b, 0x3b, 0x13e7, 0x13c3, 0x13cd, 0x13d7, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69,
-0x65, 0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0xed, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79,
-0x61, 0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
-0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x79, 0x61, 0x20, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61,
-0x6e, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x74, 0x61, 0x62, 0x20,
-0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62,
-0x69, 0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f,
-0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61,
-0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, 0x79, 0x61,
-0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67,
-0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x27, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x27, 0x20, 0x55, 0x67, 0x61, 0x6e,
-0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x27, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c,
-0x6f, 0x6b, 0x27, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20,
-0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53,
-0x69, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x44, 0x65, 0x72, 0x68, 0x65, 0x6d, 0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e,
-0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46,
-0x41, 0x20, 0x46, 0xe0, 0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46,
-0x72, 0x1ce, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x73, 0x65, 0x65, 0x66, 0x61, 0x20, 0x79, 0x61, 0x74, 0x69, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f,
-0x6c, 0x61, 0x69, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20,
-0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x68, 0x65, 0x6c, 0x61,
-0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
-0x46, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b,
-0x3b, 0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x20, 0xa55c, 0xa55e, 0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61,
-0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b,
-0x6c, 0xe2, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b,
-0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x72, 0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65,
-0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b
+0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x45, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65,
+0x76, 0x72, 0x61, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x61, 0x3b, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e,
+0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x3b, 0x3b, 0x73, 0x72,
+0x70, 0x73, 0x6b, 0x61, 0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x3b, 0x73, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x68,
+0x20, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d,
+0x430, 0x20, 0x41c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435,
+0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431,
+0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e,
+0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440,
+0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x65, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d,
+0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e,
+0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b,
+0x415, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x43e, 0x3b, 0x3b, 0x435, 0x432, 0x440, 0x430, 0x3b, 0x3b, 0x435, 0x432,
+0x440, 0x430, 0x3b, 0x41b, 0x430, 0x440, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x3b, 0x3b, 0x3b, 0x3b, 0x43b, 0x430, 0x440, 0x44b, 0x3b,
+0x421, 0x43e, 0x43c, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x441, 0x43e, 0x43c, 0x44b, 0x3b, 0x44, 0x6f, 0x72,
+0x61, 0x20, 0x72, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xdc1,
+0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0x20, 0xdbb, 0xdd4, 0xdb4, 0xdd2, 0xdba, 0xdbd, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x45, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0xe1, 0x3b,
+0x65, 0x75, 0x72, 0x61, 0x3b, 0x65, 0x75, 0x72, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x3b,
+0x65, 0x76, 0x72, 0x61, 0x3b, 0x65, 0x76, 0x72, 0x69, 0x3b, 0x3b, 0x65, 0x76, 0x72, 0x6f, 0x76, 0x3b, 0x53, 0x68, 0x69,
+0x6c, 0x69, 0x6e, 0x20, 0x73, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46,
+0x61, 0x72, 0x61, 0x6e, 0x20, 0x4a, 0x61, 0x62, 0x62, 0x75, 0x75, 0x74, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x42, 0x69, 0x72, 0x74, 0x61, 0x20, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x62, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65,
+0x73, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f,
+0x73, 0x20, 0x61, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61,
+0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c,
+0x69, 0x76, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f,
+0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65,
+0x73, 0x6f, 0x73, 0x20, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f,
+0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d,
+0x62, 0x69, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x6d,
+0x62, 0x69, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72, 0x72,
+0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0xf3, 0x6e, 0x20, 0x63, 0x6f, 0x73, 0x74, 0x61, 0x72,
+0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x65, 0x73, 0x20, 0x63,
+0x6f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63,
+0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x3b, 0x3b,
+0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x63, 0x75, 0x62, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f,
+0x20, 0x64, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x64, 0x6f,
+0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x64, 0x6f,
+0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73, 0x74, 0x61,
+0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61, 0x72, 0x20, 0x65, 0x73,
+0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x64, 0xf3, 0x6c, 0x61,
+0x72, 0x65, 0x73, 0x20, 0x65, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x75, 0x6e, 0x69, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b,
+0x66, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x66, 0x72, 0x61,
+0x6e, 0x63, 0x6f, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0x61, 0x6e,
+0x63, 0x6f, 0x73, 0x20, 0x43, 0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c,
+0x20, 0x67, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63, 0x6f, 0x3b, 0x3b, 0x71, 0x75, 0x65, 0x74, 0x7a,
+0x61, 0x6c, 0x20, 0x67, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x71,
+0x75, 0x65, 0x74, 0x7a, 0x61, 0x6c, 0x65, 0x73, 0x20, 0x67, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x74, 0x65, 0x63,
+0x6f, 0x73, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f,
+0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1, 0x6f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x6c, 0x65, 0x6d, 0x70, 0x69, 0x72, 0x61, 0x73, 0x20, 0x68, 0x6f, 0x6e, 0x64, 0x75, 0x72, 0x65, 0xf1,
+0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65,
+0x73, 0x6f, 0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73,
+0x20, 0x6d, 0x65, 0x78, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61, 0x20, 0x6e,
+0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x63, 0xf3, 0x72, 0x64, 0x6f, 0x62, 0x61,
+0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x63, 0xf3, 0x72,
+0x64, 0x6f, 0x62, 0x61, 0x73, 0x20, 0x6e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0xfc, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x3b,
+0x62, 0x61, 0x6c, 0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x62, 0x61, 0x6c,
+0x62, 0x6f, 0x61, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x61, 0x6c, 0x62,
+0x6f, 0x61, 0x73, 0x20, 0x70, 0x61, 0x6e, 0x61, 0x6d, 0x65, 0xf1, 0x6f, 0x73, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e,
+0xed, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e, 0xed,
+0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x75, 0x61, 0x72, 0x61, 0x6e,
+0xed, 0x65, 0x73, 0x20, 0x70, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f,
+0x20, 0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f, 0x20,
+0x73, 0x6f, 0x6c, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x75, 0x65, 0x76, 0x6f,
+0x73, 0x20, 0x73, 0x6f, 0x6c, 0x65, 0x73, 0x20, 0x70, 0x65, 0x72, 0x75, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73,
+0x6f, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x66, 0x69, 0x6c,
+0x69, 0x70, 0x69, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x20, 0x66, 0x69, 0x6c, 0x69, 0x70,
+0x69, 0x6e, 0x6f, 0x73, 0x3b, 0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b,
+0x70, 0x65, 0x73, 0x6f, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x70, 0x65, 0x73,
+0x6f, 0x73, 0x20, 0x75, 0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x6f, 0x73, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72,
+0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76, 0x61, 0x72,
+0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x62, 0x6f, 0x6c, 0xed, 0x76,
+0x61, 0x72, 0x65, 0x73, 0x20, 0x76, 0x65, 0x6e, 0x65, 0x7a, 0x6f, 0x6c, 0x61, 0x6e, 0x6f, 0x73, 0x3b, 0x73, 0x68, 0x69,
+0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20,
+0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20,
+0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x61, 0x3b,
+0x3b, 0x3b, 0x3b, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x6f, 0x72, 0x3b, 0x65, 0x75,
+0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x421, 0x43e, 0x43c,
+0x43e, 0x43d, 0x4e3, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xbb0, 0xbc2, 0xbaa, 0xbbe, 0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0xbae, 0xbb2, 0xbc7, 0xb9a, 0xbbf, 0xbaf, 0x20, 0xbb0, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbbf, 0xb9f, 0xbcd, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0x20, 0xb9f, 0xbbe, 0xbb2,
+0xbb0, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0x20, 0xbb0, 0xbc2, 0xbaa, 0xbbe,
+0xbaf, 0xbcd, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a,
+0xc3e, 0xc2f, 0xc3f, 0x3b, 0x3b, 0x3b, 0x3b, 0xc30, 0xc42, 0xc2a, 0xc3e, 0xc2f, 0xc32, 0xc41, 0x3b, 0xe1a, 0xe32, 0xe17, 0xe44, 0xe17,
+0xe22, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xe1a, 0xe32, 0xe17, 0xe44, 0xe17, 0xe22, 0x3b, 0xf61, 0xf74, 0xf0b, 0xf68, 0xf53, 0xf0b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0xf66, 0xf92, 0xf7c, 0xf62, 0xf0b, 0xf58,
+0xf7c, 0xf0b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x12e8, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x20, 0x1265, 0x122d, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x6e, 0x20, 0x50, 0x61, 0x27, 0x61, 0x6e, 0x67, 0x61, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x4c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x54,
+0xfc, 0x72, 0x6b, 0x20, 0x6c, 0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x3b, 0x3b, 0x3b, 0x54, 0xfc, 0x72, 0x6b, 0x20, 0x6c,
+0x69, 0x72, 0x61, 0x73, 0x131, 0x3b, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x20, 0x433, 0x440, 0x438,
+0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x44f, 0x3b, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b,
+0x433, 0x440, 0x438, 0x432, 0x435, 0x43d, 0x44c, 0x3b, 0x433, 0x440, 0x438, 0x432, 0x43d, 0x456, 0x3b, 0x67e, 0x627, 0x6a9, 0x633, 0x62a,
+0x627, 0x646, 0x6cc, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x627, 0x646, 0x688, 0x6cc,
+0x646, 0x20, 0x631, 0x648, 0x67e, 0x6cc, 0x6c1, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
+0x69, 0x73, 0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2bb, 0x6d, 0x3b, 0x3b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73,
+0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2bb, 0x6d, 0x3b, 0x3b, 0x3b, 0x3b, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73,
+0x74, 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x2bb, 0x6d, 0x3b, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x6cc, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x40e, 0x437,
+0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x3b, 0x3b, 0x3b, 0x40e, 0x437, 0x431, 0x435,
+0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x20, 0x441, 0x45e, 0x43c, 0x3b, 0x110, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74,
+0x20, 0x4e, 0x61, 0x6d, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x111, 0x1ed3, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x20,
+0x4e, 0x61, 0x6d, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72,
+0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20,
+0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e,
+0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65, 0x72, 0x6c,
+0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53, 0x74, 0x65,
+0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74, 0x20, 0x53,
+0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x50, 0x75, 0x6e, 0x74,
+0x20, 0x53, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x79, 0x64, 0x61, 0x69, 0x6e, 0x3b, 0x4e, 0x61,
+0x69, 0x72, 0x61, 0x20, 0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec,
+0x6a, 0xed, 0x72, 0xed, 0xe0, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x61, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x20,
+0x74, 0x69, 0x20, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x42, 0x49, 0x4b, 0x45, 0x41, 0x4f, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x69, 0x2d, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
+0x6e, 0x20, 0x52, 0x61, 0x6e, 0x64, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b,
+0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x65, 0x20, 0x6b, 0x72, 0x6f, 0x6e, 0x65, 0x72, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e,
+0x73, 0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20, 0x6b, 0x6f, 0x6e,
+0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b, 0x3b, 0x62, 0x6f,
+0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x61, 0x20,
+0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x61, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x3b,
+0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d,
+0x6b, 0x65, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x65, 0x20, 0x6d, 0x61, 0x72,
+0x6b, 0x65, 0x3b, 0x42, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76,
+0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62, 0x69, 0x6c, 0x6e, 0x69, 0x68,
+0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x6f, 0x2d, 0x68, 0x65, 0x72,
+0x63, 0x65, 0x67, 0x6f, 0x76, 0x61, 0x10d, 0x6b, 0x69, 0x68, 0x20, 0x6b, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x69, 0x62,
+0x69, 0x6c, 0x6e, 0x69, 0x68, 0x20, 0x6d, 0x61, 0x72, 0x61, 0x6b, 0x61, 0x3b, 0x41a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442,
+0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441,
+0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x430, 0x20, 0x43a, 0x43e, 0x43d, 0x432,
+0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x430, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x430, 0x3b, 0x3b, 0x431, 0x43e, 0x441,
+0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x435, 0x20, 0x43a,
+0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x435, 0x20, 0x43c, 0x430, 0x440, 0x43a, 0x3b, 0x431, 0x43e,
+0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x430, 0x447, 0x43a, 0x438, 0x445,
+0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x430, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445, 0x20, 0x43c, 0x430, 0x440, 0x430,
+0x43a, 0x430, 0x3b, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x43e, 0x2d, 0x445, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432,
+0x430, 0x447, 0x43a, 0x438, 0x445, 0x20, 0x43a, 0x43e, 0x43d, 0x432, 0x435, 0x440, 0x442, 0x438, 0x431, 0x438, 0x43b, 0x43d, 0x438, 0x445,
+0x20, 0x43c, 0x430, 0x440, 0x430, 0x43a, 0x430, 0x3b, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x53, 0x69, 0x64, 0x69, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x1ecb, 0x72, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c,
+0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69,
+0x256, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x67, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x73, 0x69, 0x256, 0x69, 0x3b, 0x263, 0x65, 0x74,
+0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66,
+0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65,
+0x20, 0x61, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20,
+0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x263, 0x65, 0x74, 0x6f, 0x256, 0x6f, 0x66, 0x65, 0x20, 0x61, 0x66,
+0x72, 0x69, 0x6b, 0x61, 0x67, 0x61, 0x20, 0x43, 0x46, 0x41, 0x20, 0x66, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x42, 0x43, 0x45,
+0x41, 0x4f, 0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x3b, 0x3b,
+0x3b, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x6b, 0x65, 0x3b, 0x6e, 0x6f,
+0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61,
+0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76,
+0x64, 0x6e, 0x6f, 0x3b, 0x3b, 0x3b, 0x6e, 0x6f, 0x72, 0x67, 0x67, 0x61, 0x20, 0x6b, 0x72, 0x75, 0x76, 0x64, 0x6e, 0x6f,
+0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x65, 0x75, 0x72, 0x6f, 0x3b, 0x3b, 0x3b, 0x65,
+0x75, 0x72, 0x6f, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4d, 0x62, 0x75, 0x75, 0x257, 0x75, 0x20, 0x53, 0x65, 0x65, 0x66, 0x61,
+0x61, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x69, 0x72, 0x69, 0x6e, 0x67,
+0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x6a, 0x69,
+0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x65, 0x6c, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x4d, 0x65, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69,
+0x71, 0x75, 0x65, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x44, 0x6f, 0x6c, 0x61, 0x20, 0x79, 0x61, 0x73, 0x65, 0x20,
+0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x68, 0x65, 0x6c, 0x65, 0x72, 0x69,
+0x20, 0x73, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x2d30,
+0x2d37, 0x2d54, 0x2d49, 0x2d4e, 0x20, 0x2d4f, 0x20, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x61, 0x64, 0x72, 0x69, 0x6d, 0x20, 0x6e, 0x20, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x41, 0x64, 0x69, 0x6e, 0x61, 0x72, 0x20, 0x41, 0x7a, 0x7a, 0x61, 0x79, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x45, 0x73, 0x68, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20,
+0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69,
+0x6c, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x65, 0x66, 0x61, 0x20, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f,
+0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x13a4, 0x13c3, 0x13cd, 0x13d7, 0x3b, 0x3b, 0x13a4, 0x13c3, 0x13cd, 0x13d7, 0x3b, 0x3b,
+0x3b, 0x3b, 0x13e7, 0x13c3, 0x13cd, 0x13d7, 0x3b, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65,
+0x6e, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x68, 0x69, 0x6c, 0xed, 0x69, 0x6e, 0x67, 0x69, 0x20, 0x79, 0x61,
+0x20, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c,
+0x69, 0x6e, 0x67, 0x69, 0x20, 0x65, 0x79, 0x61, 0x20, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x53, 0x6b, 0x75, 0x64, 0x75, 0x20, 0x4b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e,
+0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69, 0x74, 0x61, 0x62, 0x20, 0x79,
+0x61, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69,
+0x61, 0x20, 0x44, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x69, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x72, 0x6f, 0x70,
+0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x49, 0x72, 0x6f, 0x70, 0x69, 0x79, 0x69, 0x61, 0x6e, 0xed, 0x20, 0x65, 0x20, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e,
+0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69, 0x72, 0x69, 0x6e, 0x6a, 0x69, 0x20, 0x79, 0x61, 0x20,
+0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x6c, 0x69, 0x6e, 0x67, 0x69,
+0x20, 0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x41, 0x6e, 0x67, 0x6f, 0x27, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f, 0x6b, 0x27, 0x20, 0x55, 0x67, 0x61, 0x6e, 0x64,
+0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x41, 0x6e, 0x67, 0x6f, 0x27, 0x6f, 0x74, 0x6f, 0x6c, 0x20, 0x6c, 0x6f,
+0x6b, 0x27, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41, 0x20, 0x46,
+0x72, 0x61, 0x14b, 0x20, 0x28, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x53, 0x69,
+0x6c, 0x69, 0x6e, 0x67, 0x20, 0x6d, 0x61, 0x72, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x44, 0x65, 0x72, 0x68, 0x65, 0x6d, 0x20, 0x55, 0x6d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x69, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x930, 0x93e, 0x902, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4e, 0x66, 0x61, 0x6c, 0x61, 0x6e, 0x67,
+0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x43, 0x46, 0x41,
+0x20, 0x46, 0xe0, 0x6c, 0xe2, 0x14b, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72,
+0x1ce, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x73, 0x65, 0x65, 0x66, 0x61, 0x20, 0x79, 0x61, 0x74, 0x69, 0x20, 0x42, 0x43, 0x45, 0x41, 0x4f, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x46, 0x259, 0x6c, 0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x20, 0x28, 0x42, 0x45, 0x41, 0x43, 0x29, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x72, 0xe1, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x6f, 0x6c,
+0x61, 0x69, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x14b, 0x20, 0x43,
+0x46, 0x41, 0x20, 0x42, 0x45, 0x41, 0x43, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x49, 0x68, 0x65, 0x6c, 0x61, 0x20,
+0x79, 0x61, 0x20, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46,
+0x61, 0x72, 0x61, 0x6e, 0x67, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
+0x3b, 0x3b, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x20, 0xa55c, 0xa55e, 0xa54c, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x4c, 0x61, 0x69,
+0x62, 0x68, 0x69, 0x79, 0x61, 0x20, 0x44, 0x61, 0x6c, 0x61, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x25b, 0x6c,
+0xe2, 0x14b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b,
+0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x73, 0x68, 0x69, 0x72, 0xe8, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x66, 0x65, 0x6c,
+0xe1, 0x14b, 0x20, 0x43, 0x46, 0x41, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b
};
static const ushort currency_format_data[] = {
-0x25, 0x31, 0x25, 0x32, 0x25, 0x32, 0x25, 0x31, 0x28, 0x25, 0x32, 0x25, 0x31, 0x29, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x25,
-0x32, 0xa0, 0x25, 0x31, 0x2d, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x28, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x29, 0x28, 0x25, 0x31,
-0x25, 0x32, 0x29, 0x25, 0x32, 0x2212, 0x25, 0x31, 0x25, 0x32, 0x2d, 0x25, 0x31, 0x200e, 0x25, 0x32, 0x25, 0x31, 0x200e, 0x28,
-0x25, 0x32, 0x25, 0x31, 0x29, 0x25, 0x32, 0xa0, 0x2d, 0x25, 0x31, 0x28, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x29, 0x2d, 0x25,
-0x31, 0x25, 0x32, 0x25, 0x32, 0x2d, 0xa0, 0x25, 0x31
+0x25, 0x31, 0x25, 0x32, 0x25, 0x32, 0x25, 0x31, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x25, 0x31, 0xa0, 0x25, 0x32, 0x28, 0x25,
+0x31, 0x25, 0x32, 0x29, 0x25, 0x32, 0xa0, 0x25, 0x31, 0x2d, 0x25, 0x32, 0x2212, 0x25, 0x31, 0x25, 0x32, 0x2d, 0x25, 0x31,
+0x28, 0x25, 0x32, 0x25, 0x31, 0x29, 0x200e, 0x25, 0x32, 0x25, 0x31, 0x25, 0x32, 0xa0, 0x2d, 0x25, 0x31, 0x25, 0x32, 0x25,
+0x31, 0x200e, 0x25, 0x32, 0x2d, 0xa0, 0x25, 0x31
};
static const ushort endonyms_data[] = {
0x4f, 0x72, 0x6f, 0x6d, 0x6f, 0x6f, 0x49, 0x74, 0x6f, 0x6f, 0x70, 0x68, 0x69, 0x79, 0x61, 0x61, 0x4b, 0x65, 0x65, 0x6e,
0x69, 0x79, 0x61, 0x61, 0x51, 0x61, 0x66, 0x61, 0x72, 0x4f, 0x74, 0x6f, 0x62, 0x62, 0x69, 0x61, 0x59, 0x61, 0x62, 0x75,
0x75, 0x74, 0x69, 0x45, 0x72, 0x65, 0x74, 0x72, 0x69, 0x61, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x61, 0x6e, 0x73, 0x53,
-0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0xeb, 0x73, 0x68, 0x71,
-0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x4b,
-0x6f, 0x73, 0x6f, 0x76, 0xeb, 0x12a0, 0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a,
-0x629, 0x645, 0x635, 0x631, 0x627, 0x644, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634,
-0x627, 0x62f, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a,
-0x62a, 0x631, 0x64a, 0x627, 0x627, 0x644, 0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623,
-0x631, 0x62f, 0x646, 0x627, 0x644, 0x643, 0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645,
-0x648, 0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x641,
-0x644, 0x633, 0x637, 0x64a, 0x646, 0x642, 0x637, 0x631, 0x627, 0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631,
-0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x633, 0x639, 0x648, 0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627,
-0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x633, 0x648, 0x631, 0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627,
-0x631, 0x627, 0x62a, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627,
-0x644, 0x635, 0x62d, 0x631, 0x627, 0x621, 0x20, 0x627, 0x644, 0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x570,
-0x561, 0x575, 0x565, 0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae, 0x9c0, 0x9af, 0x9bc,
-0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x63, 0x61, 0x41, 0x7a, 0x259,
-0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75, 0x73,
-0x6b, 0x61, 0x72, 0x61, 0x45, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be, 0x982,
-0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74, 0xf42,
-0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f, 0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430, 0x440,
-0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019, 0x102c,
-0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781, 0x17d2,
-0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70, 0x61,
-0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f,
-0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d, 0x56fd, 0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d,
-0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171,
-0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48,
-0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61, 0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65,
-0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d, 0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72,
-0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b, 0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b,
-0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x41,
-0x72, 0x75, 0x62, 0x61, 0x56, 0x6c, 0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72, 0x61,
-0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72,
-0x74, 0x65, 0x6e, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65,
-0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e, 0xd801, 0xdc47, 0xd801, 0xdc0f,
-0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801, 0xdc3b, 0xd801, 0xdc29, 0xd801,
-0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x53,
-0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62,
-0x75, 0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73,
-0x68, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72,
-0x62, 0x61, 0x64, 0x6f, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65,
-0x72, 0x6d, 0x75, 0x64, 0x61, 0x42, 0x6f, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6f,
-0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43, 0x61, 0x6e,
-0x61, 0x64, 0x61, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d,
-0x69, 0x6e, 0x69, 0x63, 0x61, 0x46, 0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d,
-0x62, 0x69, 0x61, 0x47, 0x68, 0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65,
-0x6e, 0x61, 0x64, 0x61, 0x47, 0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b,
-0x6f, 0x6e, 0x67, 0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72,
-0x65, 0x6c, 0x61, 0x6e, 0x64, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72,
-0x69, 0x62, 0x61, 0x74, 0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d,
-0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x63, 0x61, 0x72, 0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61,
-0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62,
-0x69, 0x61, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x69, 0x61,
-0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61, 0x20, 0x49, 0x73, 0x6c,
-0x61, 0x6e, 0x64, 0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x50, 0x61, 0x70,
-0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x70,
-0x69, 0x6e, 0x65, 0x73, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x53, 0x61, 0x69, 0x6e, 0x74,
-0x20, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76, 0x69, 0x73, 0x53, 0x61, 0x69, 0x6e,
-0x74, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74,
-0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53,
-0x61, 0x6d, 0x6f, 0x61, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61,
-0x20, 0x4c, 0x65, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d,
-0x6f, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x53, 0x77, 0x61, 0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54,
-0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54, 0x6f, 0x62,
-0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f, 0x73, 0x20,
-0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
-0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 0x6e, 0x67, 0x64,
-0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49, 0x73, 0x6c, 0x61,
-0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x56, 0x69,
-0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x56, 0x69, 0x72,
-0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x5a, 0x69, 0x6d,
-0x62, 0x61, 0x62, 0x77, 0x65, 0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73,
-0x65, 0x79, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65,
-0x73, 0x74, 0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8, 0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75,
-0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e,
-0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e,
-0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73, 0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64,
-0x69, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61,
-0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e,
-0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63, 0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f,
-0x72, 0x65, 0x73, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0xe9, 0x6d, 0x6f, 0x63, 0x72,
-0x61, 0x74, 0x69, 0x71, 0x75, 0x65, 0x20, 0x64, 0x75, 0x20, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x43, 0x6f, 0x6e, 0x67, 0x6f,
-0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49,
-0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20,
-0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x65, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72,
-0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x79, 0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61,
-0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47, 0x61, 0x62, 0x6f, 0x6e, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70,
-0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x48, 0x61, 0xef, 0x74, 0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75,
-0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72,
-0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65,
-0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d, 0x61, 0x72, 0x6f, 0x63, 0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d,
-0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e, 0x69, 0x65, 0x4e, 0x69, 0x67, 0x65, 0x72, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f,
-0x6e, 0x52, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61,
-0x69, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65,
-0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x69, 0x65, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72,
-0x74, 0x68, 0xe9, 0x6c, 0xe9, 0x6d, 0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x20,
-0x5b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x5d, 0x47, 0xe0,
-0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68, 0x61, 0x63, 0x68, 0x64, 0x20, 0x41,
-0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61,
-0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5, 0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75,
-0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0xd6, 0x73, 0x74, 0x65, 0x72,
-0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0xd6,
-0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69, 0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63,
-0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x75, 0x72, 0x67, 0x53, 0x63,
-0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x53,
-0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac, 0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1,
-0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c,
-0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97, 0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0,
-0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72, 0x69, 0x79, 0x61, 0x47, 0x61, 0x6e,
-0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8, 0x5d0, 0x5dc, 0x939, 0x93f, 0x928, 0x94d,
-0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x6f, 0x72,
-0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x42, 0x61,
-0x68, 0x61, 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65,
-0x73, 0x69, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69,
-0x61, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x6e, 0x6f,
-0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x53, 0x76, 0x69, 0x7a,
-0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad, 0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672,
-0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430, 0x437, 0x430, 0x49b, 0x20, 0x442,
-0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e, 0x79, 0x61, 0x72, 0x77, 0x61,
-0x6e, 0x64, 0x61, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x41a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c,
-0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758, 0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d,
-0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0xeaa,
-0x2e, 0xe9b, 0x2e, 0xe9b, 0x20, 0xea5, 0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76,
-0x69, 0x6a, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64,
-0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41,
-0x6e, 0x67, 0xf3, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72,
-0xed, 0x6b, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74,
-0x75, 0x76, 0x69, 0x173, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a,
-0x438, 0x41c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d,
-0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65,
-0x6c, 0x61, 0x79, 0x75, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69,
-0x6e, 0x67, 0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d,
-0x61, 0x6c, 0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e,
-0x43b, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f,
-0x6b, 0x6d, 0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a,
-0x62a, 0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627,
-0x646, 0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74,
-0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69,
-0x6c, 0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f,
-0x20, 0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69,
-0x6e, 0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20,
-0x64, 0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f,
-0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75,
-0x67, 0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69,
-0x70, 0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633,
-0x62a, 0x627, 0x646, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f,
-0x6d, 0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61,
-0x20, 0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438,
-0x44f, 0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e,
-0x43b, 0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64,
-0xf6, 0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421,
-0x440, 0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e,
-0x61, 0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e,
-0x441, 0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d,
-0x430, 0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440,
-0x43e, 0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x53,
-0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f,
-0x6e, 0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x53, 0x69,
-0x73, 0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
-0x6e, 0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65,
-0x6e, 0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69,
-0x79, 0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x69,
-0x6e, 0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1,
-0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x6f, 0x6c,
-0x69, 0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73,
-0x74, 0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61,
-0x20, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x45, 0x6c,
-0x20, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61,
-0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75,
-0x72, 0x61, 0x73, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61,
-0x6e, 0x61, 0x6d, 0xe1, 0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69, 0x6c, 0x69,
-0x70, 0x69, 0x6e, 0x61, 0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55,
-0x72, 0x75, 0x67, 0x75, 0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x49, 0x73, 0x6c, 0x61, 0x73,
-0x20, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x6c, 0x61, 0x74,
-0x69, 0x6e, 0x6f, 0x61, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x6f, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d,
-0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61,
-0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, 0x72,
-0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e, 0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7, 0x438, 0x43a,
-0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4,
-0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf, 0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0,
-0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46, 0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20, 0xc26, 0xc47,
-0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b, 0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62,
-0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d, 0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61,
-0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69, 0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7,
-0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47, 0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72, 0x131, 0x73,
-0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69, 0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a,
-0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627, 0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x628,
-0x6be, 0x627, 0x631, 0x62a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x627,
-0x648, 0x632, 0x628, 0x6cc, 0x6a9, 0x6f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b,
-0x69, 0x73, 0x74, 0x6f, 0x6e, 0x54, 0x69, 0x1ebf, 0x6e, 0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, 0x74, 0x20,
-0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65, 0x67, 0x79, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20,
-0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69, 0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f,
-0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9, 0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72,
-0xed, 0xe0, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x4e, 0x69, 0x6e, 0x67, 0x69, 0x7a, 0x69, 0x6d, 0x75, 0x20,
-0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72, 0x65, 0x67, 0x62, 0x6f,
-0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61, 0x65, 0x6c, 0x67, 0x52,
-0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x77, 0x65,
-0x6b, 0x41, 0x6b, 0x61, 0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f,
-0x4b, 0x69, 0x6b, 0x61, 0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49,
-0x74, 0x61, 0x6c, 0x69, 0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67, 0x62, 0x65,
-0x47, 0x68, 0x61, 0x6e, 0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74,
-0x6f, 0x6d, 0x65, 0x12c8, 0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77, 0x61, 0x69,
-0x2bb, 0x69, 0x2bb, 0x41, 0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20, 0x2bb, 0x49,
-0x61, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x53, 0x63,
-0x68, 0x77, 0x69, 0x69, 0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69,
-0x7a, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64, 0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x6f,
-0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f, 0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d,
-0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67, 0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x45, 0x6b,
-0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69, 0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61, 0x72, 0x53,
-0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75, 0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75,
-0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f, 0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49,
-0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6d, 0x263,
-0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69, 0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72,
-0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48, 0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61,
-0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75, 0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61,
-0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3, 0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72, 0x65, 0x6f,
-0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d, 0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61,
-0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e, 0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e,
-0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69,
-0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62,
-0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129, 0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69,
-0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f,
-0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68,
-0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64,
-0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61, 0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75,
-0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65, 0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b,
-0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e,
-0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77, 0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75,
-0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263, 0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f,
-0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62,
-0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c, 0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67,
-0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41, 0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c,
-0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b, 0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61,
-0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64, 0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61,
-0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e, 0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e,
-0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa, 0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f,
-0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44, 0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b,
-0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61,
-0x74, 0x68, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430, 0x49, 0x73, 0x68, 0x69,
-0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68,
-0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68, 0x75, 0x72, 0x69, 0x20,
-0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20, 0x79, 0x61, 0x20, 0x4b,
-0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e, 0x69, 0xa559, 0xa524, 0xa55e,
-0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61, 0x6c, 0x73, 0x65, 0x72,
-0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65, 0x6c, 0xfa, 0x6e, 0x61,
-0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d, 0x25b, 0x6c, 0xfb, 0x6e,
-0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc, 0x4b, 0x61, 0x6d, 0x61,
-0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62, 0x254, 0x254, 0x6e, 0x4b,
-0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d
+0x75, 0x69, 0x64, 0x2d, 0x41, 0x66, 0x72, 0x69, 0x6b, 0x61, 0x4e, 0x61, 0x6d, 0x69, 0x62, 0x69, 0xeb, 0x53, 0x68, 0x71,
+0x69, 0x70, 0x53, 0x68, 0x71, 0x69, 0x70, 0xeb, 0x72, 0x69, 0x4d, 0x61, 0x71, 0x65, 0x64, 0x6f, 0x6e, 0x69, 0x4b, 0x6f,
+0x73, 0x6f, 0x76, 0xeb, 0x12a0, 0x121b, 0x122d, 0x129b, 0x12a2, 0x1275, 0x12ee, 0x1335, 0x12eb, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629,
+0x645, 0x635, 0x631, 0x627, 0x644, 0x62c, 0x632, 0x627, 0x626, 0x631, 0x627, 0x644, 0x628, 0x62d, 0x631, 0x64a, 0x646, 0x62a, 0x634, 0x627,
+0x62f, 0x62c, 0x632, 0x631, 0x20, 0x627, 0x644, 0x642, 0x645, 0x631, 0x62c, 0x64a, 0x628, 0x648, 0x62a, 0x64a, 0x623, 0x631, 0x64a, 0x62a,
+0x631, 0x64a, 0x627, 0x627, 0x644, 0x639, 0x631, 0x627, 0x642, 0x625, 0x633, 0x631, 0x627, 0x626, 0x64a, 0x644, 0x627, 0x644, 0x623, 0x631,
+0x62f, 0x646, 0x627, 0x644, 0x643, 0x648, 0x64a, 0x62a, 0x644, 0x628, 0x646, 0x627, 0x646, 0x644, 0x64a, 0x628, 0x64a, 0x627, 0x645, 0x648,
+0x631, 0x64a, 0x62a, 0x627, 0x646, 0x64a, 0x627, 0x627, 0x644, 0x645, 0x63a, 0x631, 0x628, 0x639, 0x64f, 0x645, 0x627, 0x646, 0x627, 0x644,
+0x623, 0x631, 0x627, 0x636, 0x64a, 0x20, 0x627, 0x644, 0x641, 0x644, 0x633, 0x637, 0x64a, 0x646, 0x64a, 0x629, 0x642, 0x637, 0x631, 0x627,
+0x644, 0x645, 0x645, 0x644, 0x643, 0x629, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628, 0x64a, 0x629, 0x20, 0x627, 0x644, 0x633, 0x639, 0x648,
+0x62f, 0x64a, 0x629, 0x627, 0x644, 0x635, 0x648, 0x645, 0x627, 0x644, 0x627, 0x644, 0x633, 0x648, 0x62f, 0x627, 0x646, 0x633, 0x648, 0x631,
+0x64a, 0x627, 0x62a, 0x648, 0x646, 0x633, 0x627, 0x644, 0x625, 0x645, 0x627, 0x631, 0x627, 0x62a, 0x20, 0x627, 0x644, 0x639, 0x631, 0x628,
+0x64a, 0x629, 0x20, 0x627, 0x644, 0x645, 0x62a, 0x62d, 0x62f, 0x629, 0x627, 0x644, 0x635, 0x62d, 0x631, 0x627, 0x621, 0x20, 0x627, 0x644,
+0x63a, 0x631, 0x628, 0x64a, 0x629, 0x627, 0x644, 0x64a, 0x645, 0x646, 0x62c, 0x646, 0x648, 0x628, 0x20, 0x627, 0x644, 0x633, 0x648, 0x62f,
+0x627, 0x646, 0x570, 0x561, 0x575, 0x565, 0x580, 0x565, 0x576, 0x540, 0x561, 0x575, 0x561, 0x57d, 0x57f, 0x561, 0x576, 0x985, 0x9b8, 0x9ae,
+0x9c0, 0x9af, 0x9bc, 0x9be, 0x9ad, 0x9be, 0x9f0, 0x9a4, 0x61, 0x7a, 0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x41, 0x7a,
+0x259, 0x72, 0x62, 0x61, 0x79, 0x63, 0x61, 0x6e, 0x410, 0x437, 0x4d9, 0x440, 0x431, 0x430, 0x458, 0x4b9, 0x430, 0x43d, 0x65, 0x75,
+0x73, 0x6b, 0x61, 0x72, 0x61, 0x45, 0x73, 0x70, 0x61, 0x69, 0x6e, 0x69, 0x61, 0x9ac, 0x9be, 0x982, 0x9b2, 0x9be, 0x9ac, 0x9be,
+0x982, 0x9b2, 0x9be, 0x9a6, 0x9c7, 0x9b6, 0x9ad, 0x9be, 0x9b0, 0x9a4, 0xf62, 0xfab, 0xf7c, 0xf44, 0xf0b, 0xf41, 0xf60, 0xf56, 0xfb2, 0xf74,
+0xf42, 0x62, 0x72, 0x65, 0x7a, 0x68, 0x6f, 0x6e, 0x65, 0x67, 0x46, 0x72, 0x61, 0xf1, 0x73, 0x431, 0x44a, 0x43b, 0x433, 0x430,
+0x440, 0x441, 0x43a, 0x438, 0x411, 0x44a, 0x43b, 0x433, 0x430, 0x440, 0x438, 0x44f, 0x1017, 0x1019, 0x102c, 0x1019, 0x103c, 0x1014, 0x103a, 0x1019,
+0x102c, 0x431, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x43a, 0x430, 0x44f, 0x411, 0x435, 0x43b, 0x430, 0x440, 0x443, 0x441, 0x44c, 0x1781,
+0x17d2, 0x1798, 0x17c2, 0x179a, 0x1780, 0x1798, 0x17d2, 0x1796, 0x17bb, 0x1787, 0x17b6, 0x63, 0x61, 0x74, 0x61, 0x6c, 0xe0, 0x45, 0x73, 0x70,
+0x61, 0x6e, 0x79, 0x61, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x46, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x49, 0x74, 0xe0,
+0x6c, 0x69, 0x61, 0x7b80, 0x4f53, 0x4e2d, 0x6587, 0x4e2d, 0x56fd, 0x4e2d, 0x56fd, 0x9999, 0x6e2f, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x4e2d, 0x56fd,
+0x6fb3, 0x95e8, 0x7279, 0x522b, 0x884c, 0x653f, 0x533a, 0x65b0, 0x52a0, 0x5761, 0x7e41, 0x9ad4, 0x4e2d, 0x6587, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c,
+0x570b, 0x9999, 0x6e2f, 0x7279, 0x5225, 0x884c, 0x653f, 0x5340, 0x4e2d, 0x83ef, 0x4eba, 0x6c11, 0x5171, 0x548c, 0x570b, 0x6fb3, 0x9580, 0x7279, 0x5225, 0x884c,
+0x653f, 0x5340, 0x53f0, 0x7063, 0x68, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x69, 0x48, 0x72, 0x76, 0x61, 0x74, 0x73, 0x6b, 0x61,
+0x42, 0x6f, 0x73, 0x6e, 0x61, 0x20, 0x69, 0x20, 0x48, 0x65, 0x72, 0x63, 0x65, 0x67, 0x6f, 0x76, 0x69, 0x6e, 0x61, 0x10d,
+0x65, 0x161, 0x74, 0x69, 0x6e, 0x61, 0x10c, 0x65, 0x73, 0x6b, 0xe1, 0x20, 0x72, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x6b,
+0x61, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x47, 0x72, 0xf8, 0x6e, 0x6c, 0x61, 0x6e,
+0x64, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64,
+0x41, 0x72, 0x75, 0x62, 0x61, 0x56, 0x6c, 0x61, 0x61, 0x6d, 0x73, 0x42, 0x65, 0x6c, 0x67, 0x69, 0xeb, 0x43, 0x75, 0x72,
+0x61, 0xe7, 0x61, 0x6f, 0x53, 0x75, 0x72, 0x69, 0x6e, 0x61, 0x6d, 0x65, 0x43, 0x61, 0x72, 0x69, 0x62, 0x69, 0x73, 0x63,
+0x68, 0x20, 0x4e, 0x65, 0x64, 0x65, 0x72, 0x6c, 0x61, 0x6e, 0x64, 0x53, 0x69, 0x6e, 0x74, 0x2d, 0x4d, 0x61, 0x61, 0x72,
+0x74, 0x65, 0x6e, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55,
+0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0xd801, 0xdc00, 0xd801, 0xdc4d, 0xd801, 0xdc4a, 0xd801, 0xdc2e,
+0xd801, 0xdc47, 0xd801, 0xdc0f, 0xd801, 0xdc2d, 0xd801, 0xdc4c, 0xd801, 0xdc34, 0xd801, 0xdc3b, 0xd801, 0xdc32, 0xd801, 0xdc3c, 0x20, 0xd801, 0xdc1d, 0xd801,
+0xdc3b, 0xd801, 0xdc29, 0xd801, 0xdc3b, 0xd801, 0xdc45, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x6e, 0x20, 0x53, 0x61, 0x6d, 0x6f, 0x61, 0x41, 0x6e, 0x67, 0x75, 0x69, 0x6c, 0x6c, 0x61, 0x41, 0x6e, 0x74, 0x69,
+0x67, 0x75, 0x61, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x42, 0x61, 0x72, 0x62, 0x75, 0x64, 0x61, 0x41, 0x75, 0x73, 0x74, 0x72,
+0x61, 0x6c, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c,
+0x69, 0x61, 0x42, 0x61, 0x68, 0x61, 0x6d, 0x61, 0x73, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x42, 0x65, 0x6c,
+0x67, 0x69, 0x75, 0x6d, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x42, 0x6f, 0x74,
+0x73, 0x77, 0x61, 0x6e, 0x61, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x20,
+0x4f, 0x63, 0x65, 0x61, 0x6e, 0x20, 0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x43, 0x61, 0x6d, 0x65, 0x72,
+0x6f, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x61, 0x6e, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x43,
+0x61, 0x6e, 0x61, 0x64, 0x61, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43,
+0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x63, 0x6f, 0x73,
+0x20, 0x28, 0x4b, 0x65, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x6f,
+0x6f, 0x6b, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x45, 0x72,
+0x69, 0x74, 0x72, 0x65, 0x61, 0x46, 0x61, 0x6c, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64,
+0x73, 0x46, 0x69, 0x6a, 0x69, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x47, 0x61, 0x6d, 0x62, 0x69, 0x61, 0x47,
+0x68, 0x61, 0x6e, 0x61, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61,
+0x47, 0x75, 0x61, 0x6d, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x48, 0x6f, 0x6e, 0x67, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x20,
+0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x49, 0x72, 0x65, 0x6c, 0x61, 0x6e,
+0x64, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x4b, 0x65, 0x6e, 0x79, 0x61, 0x4b, 0x69, 0x72, 0x69, 0x62, 0x61, 0x74,
+0x69, 0x4c, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x4c, 0x69, 0x62, 0x65, 0x72, 0x69, 0x61, 0x4d, 0x61, 0x63, 0x61, 0x75,
+0x20, 0x53, 0x41, 0x52, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x61, 0x64, 0x61, 0x67, 0x61, 0x73, 0x63, 0x61, 0x72,
+0x4d, 0x61, 0x6c, 0x61, 0x77, 0x69, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20,
+0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x4d, 0x69, 0x63, 0x72,
+0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x4d, 0x6f, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x69,
+0x62, 0x69, 0x61, 0x4e, 0x61, 0x75, 0x72, 0x75, 0x4e, 0x65, 0x77, 0x20, 0x5a, 0x65, 0x61, 0x6c, 0x61, 0x6e, 0x64, 0x4e,
+0x69, 0x67, 0x65, 0x72, 0x69, 0x61, 0x4e, 0x69, 0x75, 0x65, 0x4e, 0x6f, 0x72, 0x66, 0x6f, 0x6c, 0x6b, 0x20, 0x49, 0x73,
+0x6c, 0x61, 0x6e, 0x64, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x61,
+0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x50, 0x61, 0x6b, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x50, 0x61, 0x6c, 0x61,
+0x75, 0x50, 0x61, 0x70, 0x75, 0x61, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x50, 0x68, 0x69,
+0x6c, 0x69, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x50, 0x69, 0x74, 0x63, 0x61, 0x69, 0x72, 0x6e, 0x20, 0x49, 0x73, 0x6c,
+0x61, 0x6e, 0x64, 0x73, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f, 0x20, 0x52, 0x69, 0x63, 0x6f, 0x52, 0x77, 0x61, 0x6e, 0x64,
+0x61, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x4e, 0x65, 0x76,
+0x69, 0x73, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x53, 0x74, 0x2e, 0x20, 0x56, 0x69, 0x6e,
+0x63, 0x65, 0x6e, 0x74, 0x20, 0x26, 0x20, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x69, 0x6e, 0x65, 0x73, 0x53, 0x61, 0x6d,
+0x6f, 0x61, 0x53, 0x65, 0x79, 0x63, 0x68, 0x65, 0x6c, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x4c,
+0x65, 0x6f, 0x6e, 0x65, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x53, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e,
+0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
+0x53, 0x61, 0x69, 0x6e, 0x74, 0x20, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x53, 0x77, 0x61,
+0x7a, 0x69, 0x6c, 0x61, 0x6e, 0x64, 0x54, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x54, 0x6f, 0x6b, 0x65, 0x6c, 0x61,
+0x75, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0x72, 0x69, 0x6e, 0x69, 0x64, 0x61, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x54,
+0x6f, 0x62, 0x61, 0x67, 0x6f, 0x54, 0x75, 0x72, 0x6b, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43, 0x61, 0x69, 0x63, 0x6f,
+0x73, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x54, 0x75, 0x76, 0x61, 0x6c, 0x75, 0x55, 0x67, 0x61, 0x6e, 0x64,
+0x61, 0x55, 0x4b, 0x20, 0x45, 0x6e, 0x67, 0x6c, 0x69, 0x73, 0x68, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69,
+0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x4f, 0x75, 0x74, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x49,
+0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x56, 0x61, 0x6e, 0x75, 0x61, 0x74, 0x75, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68,
+0x20, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x55, 0x2e, 0x53, 0x2e, 0x20,
+0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x49, 0x73, 0x6c, 0x61, 0x6e, 0x64, 0x73, 0x5a, 0x61, 0x6d, 0x62, 0x69, 0x61,
+0x5a, 0x69, 0x6d, 0x62, 0x61, 0x62, 0x77, 0x65, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x20, 0x47, 0x61, 0x72, 0x63, 0x69, 0x61,
+0x49, 0x73, 0x6c, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x4d, 0x61, 0x6e, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x53, 0x6f, 0x75,
+0x74, 0x68, 0x20, 0x53, 0x75, 0x64, 0x61, 0x6e, 0x53, 0x69, 0x6e, 0x74, 0x20, 0x4d, 0x61, 0x61, 0x72, 0x74, 0x65, 0x6e,
+0x65, 0x65, 0x73, 0x74, 0x69, 0x45, 0x65, 0x73, 0x74, 0x69, 0x66, 0xf8, 0x72, 0x6f, 0x79, 0x73, 0x6b, 0x74, 0x46, 0xf8,
+0x72, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x75, 0x6f, 0x6d, 0x69, 0x53, 0x75, 0x6f, 0x6d, 0x69, 0x66, 0x72, 0x61, 0x6e, 0xe7,
+0x61, 0x69, 0x73, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x6c, 0x67, 0xe9, 0x72, 0x69, 0x65, 0x42, 0x65, 0x6c, 0x67,
+0x69, 0x71, 0x75, 0x65, 0x42, 0xe9, 0x6e, 0x69, 0x6e, 0x42, 0x75, 0x72, 0x6b, 0x69, 0x6e, 0x61, 0x20, 0x46, 0x61, 0x73,
+0x6f, 0x42, 0x75, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x43, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x75, 0x6e, 0x66, 0x72, 0x61, 0x6e,
+0xe7, 0x61, 0x69, 0x73, 0x20, 0x63, 0x61, 0x6e, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x52, 0xe9, 0x70, 0x75, 0x62, 0x6c, 0x69,
+0x71, 0x75, 0x65, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x66, 0x72, 0x69, 0x63, 0x61, 0x69, 0x6e, 0x65, 0x54, 0x63,
+0x68, 0x61, 0x64, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x4b, 0x69, 0x6e, 0x73,
+0x68, 0x61, 0x73, 0x61, 0x43, 0x6f, 0x6e, 0x67, 0x6f, 0x2d, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c,
+0x65, 0x43, 0xf4, 0x74, 0x65, 0x20, 0x64, 0x2019, 0x49, 0x76, 0x6f, 0x69, 0x72, 0x65, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75,
+0x74, 0x69, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x20, 0xe9, 0x71, 0x75, 0x61, 0x74, 0x6f, 0x72, 0x69, 0x61, 0x6c, 0x65,
+0x47, 0x75, 0x79, 0x61, 0x6e, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x50, 0x6f, 0x6c, 0x79,
+0x6e, 0xe9, 0x73, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x65, 0x47, 0x61, 0x62, 0x6f, 0x6e,
+0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x47, 0x75, 0x69, 0x6e, 0xe9, 0x65, 0x48, 0x61, 0xef, 0x74,
+0x69, 0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x4d, 0x61, 0x6c, 0x69, 0x4d, 0x61, 0x72, 0x74, 0x69,
+0x6e, 0x69, 0x71, 0x75, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x61, 0x6e, 0x69, 0x65, 0x4d, 0x61, 0x75, 0x72, 0x69,
+0x63, 0x65, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x4d, 0x61, 0x72, 0x6f, 0x63,
+0x4e, 0x6f, 0x75, 0x76, 0x65, 0x6c, 0x6c, 0x65, 0x2d, 0x43, 0x61, 0x6c, 0xe9, 0x64, 0x6f, 0x6e, 0x69, 0x65, 0x4e, 0x69,
+0x67, 0x65, 0x72, 0x4c, 0x61, 0x20, 0x52, 0xe9, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x53, 0xe9, 0x6e, 0xe9, 0x67, 0x61, 0x6c,
+0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x50, 0x69, 0x65, 0x72, 0x72, 0x65, 0x2d, 0x65, 0x74, 0x2d, 0x4d, 0x69, 0x71, 0x75,
+0x65, 0x6c, 0x6f, 0x6e, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61, 0x69, 0x73, 0x20, 0x73, 0x75, 0x69, 0x73, 0x73, 0x65, 0x53,
+0x75, 0x69, 0x73, 0x73, 0x65, 0x53, 0x79, 0x72, 0x69, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x69,
+0x65, 0x57, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x2d, 0x65, 0x74, 0x2d, 0x46, 0x75, 0x74, 0x75, 0x6e, 0x61, 0x53, 0x61, 0x69,
+0x6e, 0x74, 0x2d, 0x42, 0x61, 0x72, 0x74, 0x68, 0xe9, 0x6c, 0x65, 0x6d, 0x79, 0x53, 0x61, 0x69, 0x6e, 0x74, 0x2d, 0x4d,
+0x61, 0x72, 0x74, 0x69, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x72, 0x74, 0x69, 0x65, 0x20, 0x66, 0x72, 0x61, 0x6e, 0xe7, 0x61,
+0x69, 0x73, 0x65, 0x29, 0x47, 0xe0, 0x69, 0x64, 0x68, 0x6c, 0x69, 0x67, 0x41, 0x6e, 0x20, 0x52, 0xec, 0x6f, 0x67, 0x68,
+0x61, 0x63, 0x68, 0x64, 0x20, 0x41, 0x6f, 0x6e, 0x61, 0x69, 0x63, 0x68, 0x74, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f,
+0x45, 0x73, 0x70, 0x61, 0xf1, 0x61, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, 0x10e1, 0x10d0, 0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10d5,
+0x10d4, 0x10da, 0x10dd, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e,
+0x64, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x69, 0x73, 0x63, 0x68, 0x65, 0x73, 0x20, 0x44, 0x65,
+0x75, 0x74, 0x73, 0x63, 0x68, 0xd6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68, 0x42, 0x65, 0x6c, 0x67, 0x69,
+0x65, 0x6e, 0x4c, 0x69, 0x65, 0x63, 0x68, 0x74, 0x65, 0x6e, 0x73, 0x74, 0x65, 0x69, 0x6e, 0x4c, 0x75, 0x78, 0x65, 0x6d,
+0x62, 0x75, 0x72, 0x67, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x65, 0x72, 0x20, 0x48, 0x6f, 0x63, 0x68, 0x64, 0x65,
+0x75, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x65, 0x69, 0x7a, 0x395, 0x3bb, 0x3bb, 0x3b7, 0x3bd, 0x3b9, 0x3ba, 0x3ac,
+0x395, 0x3bb, 0x3bb, 0x3ac, 0x3b4, 0x3b1, 0x39a, 0x3cd, 0x3c0, 0x3c1, 0x3bf, 0x3c2, 0x6b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69,
+0x73, 0x75, 0x74, 0x4b, 0x61, 0x6c, 0x61, 0x61, 0x6c, 0x6c, 0x69, 0x74, 0x20, 0x4e, 0x75, 0x6e, 0x61, 0x61, 0x74, 0xa97,
+0xac1, 0xa9c, 0xab0, 0xabe, 0xaa4, 0xac0, 0xaad, 0xabe, 0xab0, 0xaa4, 0x48, 0x61, 0x75, 0x73, 0x61, 0x4e, 0x61, 0x6a, 0x65, 0x72,
+0x69, 0x79, 0x61, 0x47, 0x61, 0x6e, 0x61, 0x4e, 0x69, 0x6a, 0x61, 0x72, 0x5e2, 0x5d1, 0x5e8, 0x5d9, 0x5ea, 0x5d9, 0x5e9, 0x5e8,
+0x5d0, 0x5dc, 0x939, 0x93f, 0x902, 0x926, 0x940, 0x92d, 0x93e, 0x930, 0x924, 0x6d, 0x61, 0x67, 0x79, 0x61, 0x72, 0x4d, 0x61, 0x67,
+0x79, 0x61, 0x72, 0x6f, 0x72, 0x73, 0x7a, 0xe1, 0x67, 0xed, 0x73, 0x6c, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0xcd, 0x73, 0x6c,
+0x61, 0x6e, 0x64, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x49, 0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x49,
+0x6e, 0x64, 0x6f, 0x6e, 0x65, 0x73, 0x69, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x67, 0x75, 0x61, 0x46,
+0x72, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x47, 0x61, 0x65, 0x69, 0x6c, 0x67, 0x65, 0xc9, 0x69, 0x72, 0x65, 0x69, 0x74, 0x61,
+0x6c, 0x69, 0x61, 0x6e, 0x6f, 0x49, 0x74, 0x61, 0x6c, 0x69, 0x61, 0x53, 0x61, 0x6e, 0x20, 0x4d, 0x61, 0x72, 0x69, 0x6e,
+0x6f, 0x53, 0x76, 0x69, 0x7a, 0x7a, 0x65, 0x72, 0x61, 0x65e5, 0x672c, 0x8a9e, 0x65e5, 0x672c, 0xc95, 0xca8, 0xccd, 0xca8, 0xca1, 0xcad,
+0xcbe, 0xcb0, 0xca4, 0x6a9, 0x672, 0x634, 0x64f, 0x631, 0x6c1, 0x650, 0x646, 0x65b, 0x62f, 0x648, 0x633, 0x62a, 0x627, 0x646, 0x49b, 0x430,
+0x437, 0x430, 0x49b, 0x20, 0x442, 0x456, 0x43b, 0x456, 0x49a, 0x430, 0x437, 0x430, 0x49b, 0x441, 0x442, 0x430, 0x43d, 0x4b, 0x69, 0x6e,
+0x79, 0x61, 0x72, 0x77, 0x61, 0x6e, 0x64, 0x61, 0x43a, 0x44b, 0x440, 0x433, 0x44b, 0x437, 0x447, 0x430, 0x41a, 0x44b, 0x440, 0x433,
+0x44b, 0x437, 0x441, 0x442, 0x430, 0x43d, 0xd55c, 0xad6d, 0xc5b4, 0xb300, 0xd55c, 0xbbfc, 0xad6d, 0xc870, 0xc120, 0x20, 0xbbfc, 0xc8fc, 0xc8fc, 0xc758,
+0x20, 0xc778, 0xbbfc, 0x20, 0xacf5, 0xd654, 0xad6d, 0x49, 0x6b, 0x69, 0x72, 0x75, 0x6e, 0x64, 0x69, 0x55, 0x62, 0x75, 0x72, 0x75,
+0x6e, 0x64, 0x69, 0xea5, 0xeb2, 0xea7, 0x6c, 0x61, 0x74, 0x76, 0x69, 0x65, 0x161, 0x75, 0x4c, 0x61, 0x74, 0x76, 0x69, 0x6a,
+0x61, 0x6c, 0x69, 0x6e, 0x67, 0xe1, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x64, 0x65, 0x6d,
+0x6f, 0x6b, 0x72, 0x61, 0x74, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0xf3, 0x41, 0x6e, 0x67,
+0xf3, 0x6c, 0x61, 0x52, 0x65, 0x70, 0x69, 0x62, 0x69, 0x6b, 0x69, 0x20, 0x79, 0x61, 0x20, 0x41, 0x66, 0x72, 0xed, 0x6b,
+0x61, 0x20, 0x79, 0x61, 0x20, 0x4b, 0xe1, 0x74, 0x69, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x6c, 0x69, 0x65, 0x74, 0x75, 0x76,
+0x69, 0x173, 0x4c, 0x69, 0x65, 0x74, 0x75, 0x76, 0x61, 0x43c, 0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x441, 0x43a, 0x438, 0x41c,
+0x430, 0x43a, 0x435, 0x434, 0x43e, 0x43d, 0x438, 0x458, 0x430, 0x4d, 0x61, 0x6c, 0x61, 0x67, 0x61, 0x73, 0x79, 0x4d, 0x61, 0x64,
+0x61, 0x67, 0x61, 0x73, 0x69, 0x6b, 0x61, 0x72, 0x61, 0x42, 0x61, 0x68, 0x61, 0x73, 0x61, 0x20, 0x4d, 0x65, 0x6c, 0x61,
+0x79, 0x75, 0x4d, 0x61, 0x6c, 0x61, 0x79, 0x73, 0x69, 0x61, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x53, 0x69, 0x6e, 0x67,
+0x61, 0x70, 0x75, 0x72, 0x61, 0xd2e, 0xd32, 0xd2f, 0xd3e, 0xd33, 0xd02, 0xd07, 0xd28, 0xd4d, 0xd24, 0xd4d, 0xd2f, 0x4d, 0x61, 0x6c,
+0x74, 0x69, 0x92e, 0x930, 0x93e, 0x920, 0x940, 0x43c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x41c, 0x43e, 0x43d, 0x433, 0x43e, 0x43b, 0x928,
+0x947, 0x92a, 0x93e, 0x932, 0x940, 0x928, 0x947, 0x92a, 0x93e, 0x932, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x20, 0x62, 0x6f, 0x6b, 0x6d,
+0xe5, 0x6c, 0x4e, 0x6f, 0x72, 0x67, 0x65, 0x53, 0x76, 0x61, 0x6c, 0x62, 0x61, 0x72, 0x64, 0x20, 0x6f, 0x67, 0x20, 0x4a,
+0x61, 0x6e, 0x20, 0x4d, 0x61, 0x79, 0x65, 0x6e, 0xb13, 0xb21, 0xb3c, 0xb3f, 0xb06, 0xb2d, 0xb3e, 0xb30, 0xb24, 0x67e, 0x69a, 0x62a,
+0x648, 0x627, 0x641, 0x63a, 0x627, 0x646, 0x633, 0x62a, 0x627, 0x646, 0x641, 0x627, 0x631, 0x633, 0x6cc, 0x627, 0x6cc, 0x631, 0x627, 0x646,
+0x62f, 0x631, 0x6cc, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x50, 0x6f, 0x6c, 0x73, 0x6b, 0x61, 0x70, 0x6f, 0x72, 0x74, 0x75,
+0x67, 0x75, 0xea, 0x73, 0x20, 0x64, 0x6f, 0x20, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x42, 0x72, 0x61, 0x73, 0x69, 0x6c,
+0x70, 0x6f, 0x72, 0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x41, 0x6e, 0x67, 0x6f, 0x6c, 0x61, 0x43, 0x61, 0x62, 0x6f, 0x20,
+0x56, 0x65, 0x72, 0x64, 0x65, 0x54, 0x69, 0x6d, 0x6f, 0x72, 0x2d, 0x4c, 0x65, 0x73, 0x74, 0x65, 0x47, 0x75, 0x69, 0x6e,
+0xe9, 0x2d, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x2c, 0x20, 0x52, 0x41, 0x45, 0x20, 0x64,
+0x61, 0x20, 0x43, 0x68, 0x69, 0x6e, 0x61, 0x4d, 0x6f, 0xe7, 0x61, 0x6d, 0x62, 0x69, 0x71, 0x75, 0x65, 0x70, 0x6f, 0x72,
+0x74, 0x75, 0x67, 0x75, 0xea, 0x73, 0x20, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x75, 0x50, 0x6f, 0x72, 0x74, 0x75, 0x67,
+0x61, 0x6c, 0x53, 0xe3, 0x6f, 0x20, 0x54, 0x6f, 0x6d, 0xe9, 0x20, 0x65, 0x20, 0x50, 0x72, 0xed, 0x6e, 0x63, 0x69, 0x70,
+0x65, 0xa2a, 0xa70, 0xa1c, 0xa3e, 0xa2c, 0xa40, 0xa2d, 0xa3e, 0xa30, 0xa24, 0x67e, 0x646, 0x62c, 0x627, 0x628, 0x67e, 0x6a9, 0x633, 0x62a,
+0x627, 0x646, 0x72, 0x75, 0x6d, 0x61, 0x6e, 0x74, 0x73, 0x63, 0x68, 0x53, 0x76, 0x69, 0x7a, 0x72, 0x61, 0x72, 0x6f, 0x6d,
+0xe2, 0x6e, 0x103, 0x52, 0x6f, 0x6d, 0xe2, 0x6e, 0x69, 0x61, 0x52, 0x65, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20,
+0x4d, 0x6f, 0x6c, 0x64, 0x6f, 0x76, 0x61, 0x440, 0x443, 0x441, 0x441, 0x43a, 0x438, 0x439, 0x420, 0x43e, 0x441, 0x441, 0x438, 0x44f,
+0x41a, 0x430, 0x437, 0x430, 0x445, 0x441, 0x442, 0x430, 0x43d, 0x41a, 0x438, 0x440, 0x433, 0x438, 0x437, 0x438, 0x44f, 0x41c, 0x43e, 0x43b,
+0x434, 0x43e, 0x432, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x438, 0x43d, 0x430, 0x53, 0xe4, 0x6e, 0x67, 0xf6, 0x4b, 0xf6, 0x64, 0xf6,
+0x72, 0xf6, 0x73, 0xea, 0x73, 0x65, 0x20, 0x74, 0xee, 0x20, 0x42, 0xea, 0x61, 0x66, 0x72, 0xee, 0x6b, 0x61, 0x421, 0x440,
+0x43f, 0x441, 0x43a, 0x438, 0x421, 0x440, 0x431, 0x438, 0x458, 0x430, 0x53, 0x72, 0x70, 0x73, 0x6b, 0x69, 0x43, 0x72, 0x6e, 0x61,
+0x20, 0x47, 0x6f, 0x72, 0x61, 0x53, 0x72, 0x62, 0x69, 0x6a, 0x61, 0x441, 0x440, 0x43f, 0x441, 0x43a, 0x438, 0x411, 0x43e, 0x441,
+0x43d, 0x430, 0x20, 0x438, 0x20, 0x425, 0x435, 0x440, 0x446, 0x435, 0x433, 0x43e, 0x432, 0x438, 0x43d, 0x430, 0x426, 0x440, 0x43d, 0x430,
+0x20, 0x413, 0x43e, 0x440, 0x430, 0x41a, 0x43e, 0x441, 0x43e, 0x432, 0x43e, 0x4b, 0x6f, 0x73, 0x6f, 0x76, 0x6f, 0x438, 0x440, 0x43e,
+0x43d, 0x413, 0x443, 0x44b, 0x440, 0x434, 0x437, 0x44b, 0x441, 0x442, 0x43e, 0x43d, 0x423, 0x4d5, 0x440, 0x4d5, 0x441, 0x435, 0x53, 0x65,
+0x73, 0x6f, 0x74, 0x68, 0x6f, 0x53, 0x65, 0x74, 0x73, 0x77, 0x61, 0x6e, 0x61, 0x63, 0x68, 0x69, 0x53, 0x68, 0x6f, 0x6e,
+0x61, 0xdc3, 0xdd2, 0xd82, 0xdc4, 0xdbd, 0xdc1, 0xdca, 0x200d, 0xdbb, 0xdd3, 0x20, 0xdbd, 0xd82, 0xd9a, 0xdcf, 0xdc0, 0x53, 0x69, 0x73,
+0x77, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e,
+0x73, 0x6b, 0x6f, 0x73, 0x6c, 0x6f, 0x76, 0x65, 0x6e, 0x161, 0x10d, 0x69, 0x6e, 0x61, 0x53, 0x6c, 0x6f, 0x76, 0x65, 0x6e,
+0x69, 0x6a, 0x61, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x53, 0x6f, 0x6f, 0x6d, 0x61, 0x61, 0x6c, 0x69, 0x79,
+0x61, 0x4a, 0x61, 0x62, 0x75, 0x75, 0x74, 0x69, 0x49, 0x74, 0x6f, 0x6f, 0x62, 0x69, 0x79, 0x61, 0x4b, 0x69, 0x69, 0x6e,
+0x69, 0x79, 0x61, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x45, 0x73, 0x70, 0x61, 0xf1, 0x61,
+0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x42, 0x6f, 0x6c, 0x69,
+0x76, 0x69, 0x61, 0x43, 0x68, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x69, 0x61, 0x43, 0x6f, 0x73, 0x74,
+0x61, 0x20, 0x52, 0x69, 0x63, 0x61, 0x43, 0x75, 0x62, 0x61, 0x52, 0x65, 0x70, 0xfa, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x20,
+0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x6e, 0x61, 0x45, 0x63, 0x75, 0x61, 0x64, 0x6f, 0x72, 0x45, 0x6c, 0x20,
+0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x47, 0x75, 0x69, 0x6e, 0x65, 0x61, 0x20, 0x45, 0x63, 0x75, 0x61, 0x74,
+0x6f, 0x72, 0x69, 0x61, 0x6c, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c, 0x61, 0x48, 0x6f, 0x6e, 0x64, 0x75, 0x72,
+0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x4d, 0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4d,
+0xe9, 0x78, 0x69, 0x63, 0x6f, 0x4e, 0x69, 0x63, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x50, 0x61, 0x6e, 0x61, 0x6d, 0xe1,
+0x50, 0x61, 0x72, 0x61, 0x67, 0x75, 0x61, 0x79, 0x50, 0x65, 0x72, 0xfa, 0x46, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61,
+0x73, 0x45, 0x73, 0x74, 0x61, 0x64, 0x6f, 0x73, 0x20, 0x55, 0x6e, 0x69, 0x64, 0x6f, 0x73, 0x55, 0x72, 0x75, 0x67, 0x75,
+0x61, 0x79, 0x56, 0x65, 0x6e, 0x65, 0x7a, 0x75, 0x65, 0x6c, 0x61, 0x69, 0x73, 0x6c, 0x61, 0x73, 0x20, 0x43, 0x61, 0x6e,
+0x61, 0x72, 0x69, 0x61, 0x73, 0x65, 0x73, 0x70, 0x61, 0xf1, 0x6f, 0x6c, 0x20, 0x64, 0x65, 0x20, 0x41, 0x6d, 0xe9, 0x72,
+0x69, 0x63, 0x61, 0x4c, 0x61, 0x74, 0x69, 0x6e, 0x6f, 0x61, 0x6d, 0xe9, 0x72, 0x69, 0x63, 0x61, 0x43, 0x65, 0x75, 0x74,
+0x61, 0x20, 0x79, 0x20, 0x4d, 0x65, 0x6c, 0x69, 0x6c, 0x6c, 0x61, 0x4b, 0x69, 0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69,
+0x73, 0x76, 0x65, 0x6e, 0x73, 0x6b, 0x61, 0x53, 0x76, 0x65, 0x72, 0x69, 0x67, 0x65, 0x46, 0x69, 0x6e, 0x6c, 0x61, 0x6e,
+0x64, 0xc5, 0x6c, 0x61, 0x6e, 0x64, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x4e3, 0x422, 0x43e, 0x4b7, 0x438, 0x43a, 0x438, 0x441, 0x442,
+0x43e, 0x43d, 0xba4, 0xbae, 0xbbf, 0xbb4, 0xbcd, 0xb87, 0xba8, 0xbcd, 0xba4, 0xbbf, 0xbaf, 0xbbe, 0xbae, 0xbb2, 0xbc7, 0xbb7, 0xbbf, 0xbaf,
+0xbbe, 0xb9a, 0xbbf, 0xb99, 0xbcd, 0xb95, 0xbaa, 0xbcd, 0xbaa, 0xbc2, 0xbb0, 0xbcd, 0xb87, 0xbb2, 0xb99, 0xbcd, 0xb95, 0xbc8, 0xc24, 0xc46,
+0xc32, 0xc41, 0xc17, 0xc41, 0xc2d, 0xc3e, 0xc30, 0xc24, 0x20, 0xc26, 0xc47, 0xc36, 0xc02, 0xe44, 0xe17, 0xe22, 0xf54, 0xf7c, 0xf51, 0xf0b,
+0xf66, 0xf90, 0xf51, 0xf0b, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf53, 0xf42, 0xf62, 0xf92, 0xfb1, 0xf0b, 0xf42, 0xf62, 0xf0b, 0x1275, 0x130d, 0x122d,
+0x129b, 0x12a4, 0x122d, 0x1275, 0x122b, 0x6c, 0x65, 0x61, 0x20, 0x66, 0x61, 0x6b, 0x61, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x58, 0x69,
+0x74, 0x73, 0x6f, 0x6e, 0x67, 0x61, 0x54, 0xfc, 0x72, 0x6b, 0xe7, 0x65, 0x54, 0xfc, 0x72, 0x6b, 0x69, 0x79, 0x65, 0x47,
+0xfc, 0x6e, 0x65, 0x79, 0x20, 0x4b, 0x131, 0x62, 0x72, 0x131, 0x73, 0x20, 0x52, 0x75, 0x6d, 0x20, 0x4b, 0x65, 0x73, 0x69,
+0x6d, 0x69, 0x443, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x441, 0x44c, 0x43a, 0x430, 0x423, 0x43a, 0x440, 0x430, 0x457, 0x43d, 0x430, 0x627,
+0x631, 0x62f, 0x648, 0x67e, 0x627, 0x6a9, 0x633, 0x62a, 0x627, 0x646, 0x628, 0x6be, 0x627, 0x631, 0x62a, 0x6f, 0x2bb, 0x7a, 0x62, 0x65,
+0x6b, 0x63, 0x68, 0x61, 0x4f, 0x2bb, 0x7a, 0x62, 0x65, 0x6b, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x627, 0x648, 0x632, 0x628, 0x6cc,
+0x6a9, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x40e, 0x437, 0x431, 0x435, 0x43a, 0x438, 0x441, 0x442, 0x43e, 0x43d, 0x54, 0x69, 0x1ebf, 0x6e,
+0x67, 0x20, 0x56, 0x69, 0x1ec7, 0x74, 0x56, 0x69, 0x1ec7, 0x74, 0x20, 0x4e, 0x61, 0x6d, 0x43, 0x79, 0x6d, 0x72, 0x61, 0x65,
+0x67, 0x59, 0x20, 0x44, 0x65, 0x79, 0x72, 0x6e, 0x61, 0x73, 0x20, 0x55, 0x6e, 0x65, 0x64, 0x69, 0x67, 0x69, 0x73, 0x69,
+0x58, 0x68, 0x6f, 0x73, 0x61, 0xc8, 0x64, 0xe8, 0x20, 0x59, 0x6f, 0x72, 0xf9, 0x62, 0xe1, 0x4f, 0x72, 0xed, 0x6c, 0x1eb9,
+0x301, 0xe8, 0x64, 0x65, 0x20, 0x4e, 0xe0, 0xec, 0x6a, 0xed, 0x72, 0xed, 0xe0, 0x4f, 0x72, 0xed, 0x6c, 0x25b, 0x301, 0xe8,
+0x64, 0x65, 0x20, 0x42, 0x25b, 0x300, 0x6e, 0x25b, 0x300, 0x69, 0x73, 0x69, 0x5a, 0x75, 0x6c, 0x75, 0x69, 0x2d, 0x53, 0x6f,
+0x75, 0x74, 0x68, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x6e, 0x79, 0x6e, 0x6f, 0x72, 0x73, 0x6b, 0x4e, 0x6f, 0x72,
+0x65, 0x67, 0x62, 0x6f, 0x73, 0x61, 0x6e, 0x73, 0x6b, 0x69, 0x431, 0x43e, 0x441, 0x430, 0x43d, 0x441, 0x43a, 0x438, 0x47, 0x61,
+0x65, 0x6c, 0x67, 0x45, 0x6c, 0x6c, 0x61, 0x6e, 0x20, 0x56, 0x61, 0x6e, 0x6e, 0x69, 0x6e, 0x6b, 0x65, 0x72, 0x6e, 0x65,
+0x77, 0x65, 0x6b, 0x52, 0x79, 0x77, 0x76, 0x61, 0x6e, 0x65, 0x74, 0x68, 0x20, 0x55, 0x6e, 0x79, 0x73, 0x41, 0x6b, 0x61,
+0x6e, 0x47, 0x61, 0x61, 0x6e, 0x61, 0x915, 0x94b, 0x902, 0x915, 0x923, 0x940, 0x49, 0x67, 0x62, 0x6f, 0x4b, 0x69, 0x6b, 0x61,
+0x6d, 0x62, 0x61, 0x1265, 0x120a, 0x1295, 0x1275, 0x130d, 0x1228, 0x66, 0x75, 0x72, 0x6c, 0x61, 0x6e, 0x49, 0x74, 0x61, 0x6c, 0x69,
+0x65, 0x54, 0x73, 0x68, 0x69, 0x76, 0x65, 0x6e, 0x1e13, 0x61, 0x65, 0x28b, 0x65, 0x67, 0x62, 0x65, 0x47, 0x68, 0x61, 0x6e,
+0x61, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x54, 0x6f, 0x67, 0x6f, 0x20, 0x6e, 0x75, 0x74, 0x6f, 0x6d, 0x65, 0x12c8,
+0x120b, 0x12ed, 0x1273, 0x1271, 0x2bb, 0x14c, 0x6c, 0x65, 0x6c, 0x6f, 0x20, 0x48, 0x61, 0x77, 0x61, 0x69, 0x2bb, 0x69, 0x2bb, 0x41,
+0x6d, 0x65, 0x6c, 0x69, 0x6b, 0x61, 0x20, 0x48, 0x75, 0x69, 0x20, 0x50, 0x16b, 0x20, 0x2bb, 0x49, 0x61, 0x46, 0x69, 0x6c,
+0x69, 0x70, 0x69, 0x6e, 0x6f, 0x50, 0x69, 0x6c, 0x69, 0x70, 0x69, 0x6e, 0x61, 0x73, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69,
+0x7a, 0x65, 0x72, 0x74, 0xfc, 0xfc, 0x74, 0x73, 0x63, 0x68, 0x53, 0x63, 0x68, 0x77, 0x69, 0x69, 0x7a, 0x4c, 0x69, 0xe4,
+0x63, 0x68, 0x74, 0x65, 0x73, 0x63, 0x68, 0x74, 0xe4, 0x69, 0xa188, 0xa320, 0xa259, 0xa34f, 0xa1e9, 0x69, 0x73, 0x69, 0x4e, 0x64,
+0x65, 0x62, 0x65, 0x6c, 0x65, 0x53, 0x65, 0x73, 0x6f, 0x74, 0x68, 0x6f, 0x20, 0x73, 0x61, 0x20, 0x4c, 0x65, 0x62, 0x6f,
+0x61, 0x64, 0x61, 0x76, 0x76, 0x69, 0x73, 0xe1, 0x6d, 0x65, 0x67, 0x69, 0x65, 0x6c, 0x6c, 0x61, 0x4e, 0x6f, 0x72, 0x67,
+0x61, 0x53, 0x75, 0x6f, 0x70, 0x6d, 0x61, 0x45, 0x6b, 0x65, 0x67, 0x75, 0x73, 0x69, 0x69, 0x4b, 0x69, 0x74, 0x61, 0x69,
+0x74, 0x61, 0x50, 0x75, 0x6c, 0x61, 0x61, 0x72, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x61, 0x6c, 0x47, 0x69, 0x6b, 0x75,
+0x79, 0x75, 0x4b, 0x69, 0x73, 0x61, 0x6d, 0x70, 0x75, 0x72, 0x73, 0x65, 0x6e, 0x61, 0x4b, 0x69, 0x68, 0x6f, 0x72, 0x6f,
+0x6d, 0x62, 0x6f, 0x2d5c, 0x2d30, 0x2d4e, 0x2d30, 0x2d63, 0x2d49, 0x2d56, 0x2d5c, 0x2d4d, 0x2d4e, 0x2d56, 0x2d54, 0x2d49, 0x2d31, 0x74, 0x61, 0x6d,
+0x61, 0x7a, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6d, 0x263, 0x72, 0x69, 0x62, 0x54, 0x61, 0x71, 0x62, 0x61, 0x79, 0x6c, 0x69,
+0x74, 0x4c, 0x65, 0x7a, 0x7a, 0x61, 0x79, 0x65, 0x72, 0x52, 0x75, 0x6e, 0x79, 0x61, 0x6e, 0x6b, 0x6f, 0x72, 0x65, 0x48,
+0x69, 0x62, 0x65, 0x6e, 0x61, 0x48, 0x75, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x79, 0x69, 0x76, 0x75,
+0x6e, 0x6a, 0x6f, 0x62, 0x61, 0x6d, 0x61, 0x6e, 0x61, 0x6b, 0x61, 0x6e, 0x4b, 0x129, 0x65, 0x6d, 0x62, 0x75, 0x13e3, 0x13b3,
+0x13a9, 0x13a0, 0x13b9, 0x13f0, 0x13df, 0x6b, 0x72, 0x65, 0x6f, 0x6c, 0x20, 0x6d, 0x6f, 0x72, 0x69, 0x73, 0x69, 0x65, 0x6e, 0x4d,
+0x6f, 0x72, 0x69, 0x73, 0x43, 0x68, 0x69, 0x6d, 0x61, 0x6b, 0x6f, 0x6e, 0x64, 0x65, 0x4b, 0x268, 0x6c, 0x61, 0x61, 0x6e,
+0x67, 0x69, 0x54, 0x61, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0xed, 0x61, 0x4c, 0x75, 0x67, 0x61, 0x6e, 0x64, 0x61, 0x59, 0x75,
+0x67, 0x61, 0x6e, 0x64, 0x61, 0x49, 0x63, 0x68, 0x69, 0x62, 0x65, 0x6d, 0x62, 0x61, 0x6b, 0x61, 0x62, 0x75, 0x76, 0x65,
+0x72, 0x64, 0x69, 0x61, 0x6e, 0x75, 0x4b, 0x61, 0x62, 0x75, 0x20, 0x56, 0x65, 0x72, 0x64, 0x69, 0x4b, 0x129, 0x6d, 0x129,
+0x72, 0x169, 0x4b, 0x61, 0x6c, 0x65, 0x6e, 0x6a, 0x69, 0x6e, 0x45, 0x6d, 0x65, 0x74, 0x61, 0x62, 0x20, 0x4b, 0x65, 0x6e,
+0x79, 0x61, 0x4b, 0x68, 0x6f, 0x65, 0x6b, 0x68, 0x6f, 0x65, 0x67, 0x6f, 0x77, 0x61, 0x62, 0x4e, 0x61, 0x6d, 0x69, 0x62,
+0x69, 0x61, 0x62, 0x4b, 0x69, 0x6d, 0x61, 0x63, 0x68, 0x61, 0x6d, 0x65, 0x4b, 0xf6, 0x6c, 0x73, 0x63, 0x68, 0x44, 0x6f,
+0xfc, 0x74, 0x73, 0x63, 0x68, 0x6c, 0x61, 0x6e, 0x64, 0x4d, 0x61, 0x61, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x61,
+0x4f, 0x6c, 0x75, 0x73, 0x6f, 0x67, 0x61, 0x4c, 0x75, 0x6c, 0x75, 0x68, 0x69, 0x61, 0x4b, 0x69, 0x70, 0x61, 0x72, 0x65,
+0x54, 0x61, 0x64, 0x68, 0x61, 0x6e, 0x69, 0x61, 0x4b, 0x69, 0x74, 0x65, 0x73, 0x6f, 0x4b, 0x65, 0x6e, 0x69, 0x61, 0x4b,
+0x6f, 0x79, 0x72, 0x61, 0x20, 0x63, 0x69, 0x69, 0x6e, 0x69, 0x4d, 0x61, 0x61, 0x6c, 0x69, 0x4b, 0x69, 0x72, 0x75, 0x77,
+0x61, 0x44, 0x68, 0x6f, 0x6c, 0x75, 0x6f, 0x52, 0x75, 0x6b, 0x69, 0x67, 0x61, 0x54, 0x61, 0x6d, 0x61, 0x7a, 0x69, 0x263,
+0x74, 0x4d, 0x65, 0x1e5b, 0x1e5b, 0x75, 0x6b, 0x4b, 0x6f, 0x79, 0x72, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x20, 0x73, 0x65, 0x6e,
+0x6e, 0x69, 0x4b, 0x69, 0x73, 0x68, 0x61, 0x6d, 0x62, 0x61, 0x61, 0x92c, 0x921, 0x93c, 0x94b, 0x54, 0x73, 0x68, 0x69, 0x6c,
+0x75, 0x62, 0x61, 0x44, 0x69, 0x74, 0x75, 0x6e, 0x67, 0x61, 0x20, 0x77, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x75, 0x41,
+0x67, 0x68, 0x65, 0x6d, 0x4b, 0xe0, 0x6d, 0xe0, 0x6c, 0xfb, 0x14b, 0x181, 0xe0, 0x73, 0xe0, 0x61, 0x4b, 0xe0, 0x6d, 0x25b,
+0x300, 0x72, 0xfb, 0x6e, 0x5a, 0x61, 0x72, 0x6d, 0x61, 0x63, 0x69, 0x69, 0x6e, 0x65, 0x4e, 0x69, 0x17e, 0x65, 0x72, 0x64,
+0x75, 0xe1, 0x6c, 0xe1, 0x6a, 0x6f, 0x6f, 0x6c, 0x61, 0x53, 0x65, 0x6e, 0x65, 0x67, 0x61, 0x6c, 0x65, 0x77, 0x6f, 0x6e,
+0x64, 0x6f, 0x4b, 0x61, 0x6d, 0x259, 0x72, 0xfa, 0x6e, 0x72, 0x69, 0x6b, 0x70, 0x61, 0x6b, 0x61, 0x6d, 0x25b, 0x72, 0xfa,
+0x6e, 0x4d, 0x61, 0x6b, 0x75, 0x61, 0x55, 0x6d, 0x6f, 0x7a, 0x61, 0x6d, 0x62, 0x69, 0x6b, 0x69, 0x4d, 0x55, 0x4e, 0x44,
+0x41, 0x14a, 0x6b, 0x61, 0x6d, 0x65, 0x72, 0x75, 0x14b, 0x4b, 0x77, 0x61, 0x73, 0x69, 0x6f, 0x4b, 0x61, 0x6d, 0x65, 0x72,
+0x75, 0x6e, 0x54, 0x68, 0x6f, 0x6b, 0x20, 0x4e, 0x61, 0x74, 0x68, 0x441, 0x430, 0x445, 0x430, 0x20, 0x442, 0x44b, 0x43b, 0x430,
+0x49, 0x73, 0x68, 0x69, 0x73, 0x61, 0x6e, 0x67, 0x75, 0x54, 0x61, 0x6e, 0x73, 0x61, 0x6e, 0x69, 0x79, 0x61, 0x4b, 0x69,
+0x73, 0x77, 0x61, 0x68, 0x69, 0x6c, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x4a, 0x61, 0x6d, 0x68,
+0x75, 0x72, 0x69, 0x20, 0x79, 0x61, 0x20, 0x4b, 0x69, 0x64, 0x65, 0x6d, 0x6f, 0x6b, 0x72, 0x61, 0x73, 0x69, 0x61, 0x20,
+0x79, 0x61, 0x20, 0x4b, 0x6f, 0x6e, 0x67, 0x6f, 0x54, 0x61, 0x73, 0x61, 0x77, 0x61, 0x71, 0x20, 0x73, 0x65, 0x6e, 0x6e,
+0x69, 0xa559, 0xa524, 0xa55e, 0xa524, 0xa52b, 0xa569, 0x56, 0x61, 0x69, 0x4c, 0x61, 0x69, 0x62, 0x68, 0x69, 0x79, 0x61, 0x57, 0x61,
+0x6c, 0x73, 0x65, 0x72, 0x53, 0x63, 0x68, 0x77, 0x69, 0x7a, 0x6e, 0x75, 0x61, 0x73, 0x75, 0x65, 0x4b, 0x65, 0x6d, 0x65,
+0x6c, 0xfa, 0x6e, 0x61, 0x73, 0x74, 0x75, 0x72, 0x69, 0x61, 0x6e, 0x75, 0x4e, 0x64, 0x61, 0xa78c, 0x61, 0x4b, 0x61, 0x6d,
+0x25b, 0x6c, 0xfb, 0x6e, 0x6b, 0x61, 0x6b, 0x254, 0x4b, 0x61, 0x6d, 0x25b, 0x72, 0x75, 0x6e, 0x6d, 0x65, 0x74, 0x61, 0x2bc,
+0x4b, 0x61, 0x6d, 0x61, 0x6c, 0x75, 0x6e, 0x53, 0x68, 0x77, 0xf3, 0x14b, 0xf2, 0x20, 0x6e, 0x67, 0x69, 0x65, 0x6d, 0x62,
+0x254, 0x254, 0x6e, 0x4b, 0xe0, 0x6d, 0x61, 0x6c, 0xfb, 0x6d, 0x4c, 0x61, 0x6b, 0x21f, 0xf3, 0x6c, 0x2bc, 0x69, 0x79, 0x61,
+0x70, 0x69, 0x4d, 0xed, 0x6c, 0x61, 0x68, 0x61, 0x14b, 0x73, 0x6b, 0x61, 0x20, 0x54, 0x21f, 0x61, 0x6d, 0xe1, 0x6b, 0x21f,
+0x6f, 0x10d, 0x68, 0x65
};
static const char language_name_list[] =
@@ -5778,6 +5945,9 @@ static const char language_name_list[] =
"TaiDam\0"
"TaiNua\0"
"Ugaritic\0"
+"Akoose\0"
+"Lakota\0"
+"Standard Moroccan Tamazight\0"
;
static const quint16 language_name_index[] = {
@@ -6093,6 +6263,9 @@ static const quint16 language_name_index[] = {
2504, // TaiDam
2511, // TaiNua
2518, // Ugaritic
+ 2527, // Akoose
+ 2534, // Lakota
+ 2541, // Standard Moroccan Tamazight
};
static const char script_name_list[] =
@@ -7146,6 +7319,9 @@ static const unsigned char language_code_list[] =
"blt" // TaiDam
"tdd" // TaiNua
"uga" // Ugaritic
+"bss" // Akoose
+"lkt" // Lakota
+"zgh" // Standard Moroccan Tamazight
;
static const unsigned char script_code_list[] =
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index 581a12e0c7..917e83834a 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -56,9 +56,13 @@
#include "QtCore/qstring.h"
#include "QtCore/qvarlengtharray.h"
#include "QtCore/qvariant.h"
+#include "QtCore/qnumeric.h"
#include "qlocale.h"
+#include <limits>
+#include <cmath>
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_SYSTEMLOCALE
@@ -166,6 +170,98 @@ public:
QLocale::Country country);
static const QLocaleData *c();
+ enum DoubleForm {
+ DFExponent = 0,
+ DFDecimal,
+ DFSignificantDigits,
+ _DFMax = DFSignificantDigits
+ };
+
+ enum Flags {
+ NoFlags = 0,
+ Alternate = 0x01,
+ ZeroPadded = 0x02,
+ LeftAdjusted = 0x04,
+ BlankBeforePositive = 0x08,
+ AlwaysShowSign = 0x10,
+ ThousandsGroup = 0x20,
+ CapitalEorX = 0x40,
+
+ ShowBase = 0x80,
+ UppercaseBase = 0x100,
+ ForcePoint = Alternate
+ };
+
+ enum GroupSeparatorMode {
+ FailOnGroupSeparators,
+ ParseGroupSeparators
+ };
+
+ enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
+
+ typedef QVarLengthArray<char, 256> CharBuff;
+
+ static QString doubleToString(const QChar zero, const QChar plus,
+ const QChar minus, const QChar exponent,
+ const QChar group, const QChar decimal,
+ double d, int precision,
+ DoubleForm form,
+ int width, unsigned flags);
+ static QString longLongToString(const QChar zero, const QChar group,
+ const QChar plus, const QChar minus,
+ qint64 l, int precision, int base,
+ int width, unsigned flags);
+ static QString unsLongLongToString(const QChar zero, const QChar group,
+ const QChar plus,
+ quint64 l, int precision,
+ int base, int width,
+ unsigned flags);
+
+ QString doubleToString(double d,
+ int precision = -1,
+ DoubleForm form = DFSignificantDigits,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ QString longLongToString(qint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ QString unsLongLongToString(quint64 l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+
+ // this function is meant to be called with the result of stringToDouble or bytearrayToDouble
+ static float convertDoubleToFloat(double d, bool *ok)
+ {
+ if (qIsInf(d))
+ return float(d);
+ if (std::fabs(d) > std::numeric_limits<float>::max()) {
+ if (ok != 0)
+ *ok = false;
+ return 0.0f;
+ }
+ return float(d);
+ }
+
+ double stringToDouble(const QChar *begin, int len, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ qint64 stringToLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ quint64 stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+
+ // these functions are used in QIntValidator (QtGui)
+ Q_CORE_EXPORT static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
+ Q_CORE_EXPORT static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);
+ Q_CORE_EXPORT static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
+
+ bool numberToCLocale(const QChar *str, int len,
+ GroupSeparatorMode group_sep_mode,
+ CharBuff *result) const;
+ inline char digitToCLocale(QChar c) const;
+
+ // this function is used in QIntValidator (QtGui)
+ Q_CORE_EXPORT bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
+
+public:
quint16 m_language_id, m_script_id, m_country_id;
quint16 m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential;
@@ -250,86 +346,8 @@ public:
QLocale::MeasurementSystem measurementSystem() const;
- enum DoubleForm {
- DFExponent = 0,
- DFDecimal,
- DFSignificantDigits,
- _DFMax = DFSignificantDigits
- };
-
- enum Flags {
- NoFlags = 0,
- Alternate = 0x01,
- ZeroPadded = 0x02,
- LeftAdjusted = 0x04,
- BlankBeforePositive = 0x08,
- AlwaysShowSign = 0x10,
- ThousandsGroup = 0x20,
- CapitalEorX = 0x40,
-
- ShowBase = 0x80,
- UppercaseBase = 0x100,
- ForcePoint = Alternate
- };
-
- enum GroupSeparatorMode {
- FailOnGroupSeparators,
- ParseGroupSeparators
- };
-
- static QString doubleToString(const QChar zero, const QChar plus,
- const QChar minus, const QChar exponent,
- const QChar group, const QChar decimal,
- double d, int precision,
- DoubleForm form,
- int width, unsigned flags);
- static QString longLongToString(const QChar zero, const QChar group,
- const QChar plus, const QChar minus,
- qint64 l, int precision, int base,
- int width, unsigned flags);
- static QString unsLongLongToString(const QChar zero, const QChar group,
- const QChar plus,
- quint64 l, int precision,
- int base, int width,
- unsigned flags);
-
- QString doubleToString(double d,
- int precision = -1,
- DoubleForm form = DFSignificantDigits,
- int width = -1,
- unsigned flags = NoFlags) const;
- QString longLongToString(qint64 l, int precision = -1,
- int base = 10,
- int width = -1,
- unsigned flags = NoFlags) const;
- QString unsLongLongToString(quint64 l, int precision = -1,
- int base = 10,
- int width = -1,
- unsigned flags = NoFlags) const;
- double stringToDouble(const QString &num, bool *ok, GroupSeparatorMode group_sep_mode) const;
- qint64 stringToLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
- quint64 stringToUnsLongLong(const QString &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
-
- double stringToDouble(const QStringRef &num, bool *ok, GroupSeparatorMode group_sep_mode) const;
- qint64 stringToLongLong(const QStringRef &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
- quint64 stringToUnsLongLong(const QStringRef &num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
-
-
- static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0);
- static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0);
- static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok);
-
- typedef QVarLengthArray<char, 256> CharBuff;
- bool numberToCLocale(const QChar *str, int len,
- GroupSeparatorMode group_sep_mode,
- CharBuff *result) const;
- inline char digitToCLocale(QChar c) const;
-
static void updateSystemPrivate();
- enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode };
- bool validateChars(const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1) const;
-
QString dateTimeToString(const QString &format, const QDateTime &datetime,
const QDate &dateOnly, const QTime &timeOnly,
const QLocale *q) const;
@@ -347,37 +365,34 @@ inline QLocalePrivate *QSharedDataPointer<QLocalePrivate>::clone()
return QLocalePrivate::create(d->m_data, d->m_numberOptions);
}
-inline char QLocalePrivate::digitToCLocale(QChar in) const
+inline char QLocaleData::digitToCLocale(QChar in) const
{
- const QChar _zero = zero();
- const QChar _group = group();
- const ushort zeroUnicode = _zero.unicode();
- const ushort tenUnicode = zeroUnicode + 10;
+ const ushort tenUnicode = m_zero + 10;
- if (in.unicode() >= zeroUnicode && in.unicode() < tenUnicode)
- return '0' + in.unicode() - zeroUnicode;
+ if (in.unicode() >= m_zero && in.unicode() < tenUnicode)
+ return '0' + in.unicode() - m_zero;
if (in.unicode() >= '0' && in.unicode() <= '9')
return in.toLatin1();
- if (in == plus() || in == QLatin1Char('+'))
+ if (in == m_plus || in == QLatin1Char('+'))
return '+';
- if (in == minus() || in == QLatin1Char('-') || in == QChar(0x2212))
+ if (in == m_minus || in == QLatin1Char('-') || in == QChar(0x2212))
return '-';
- if (in == decimal())
+ if (in == m_decimal)
return '.';
- if (in == group())
+ if (in == m_group)
return ',';
- if (in == exponential() || in == exponential().toUpper())
+ if (in == m_exponential || in == QChar::toUpper(m_exponential))
return 'e';
// In several languages group() is the char 0xA0, which looks like a space.
// People use a regular space instead of it and complain it doesn't work.
- if (_group.unicode() == 0xA0 && in.unicode() == ' ')
+ if (m_group == 0xA0 && in.unicode() == ' ')
return ',';
return 0;
diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp
index 072a35aa4e..c2bae3df9d 100644
--- a/src/corelib/tools/qlocale_tools.cpp
+++ b/src/corelib/tools/qlocale_tools.cpp
@@ -178,86 +178,12 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential,
digits.insert(1, decimal);
digits.append(exponential);
- digits.append(QLocalePrivate::longLongToString(zero, group, plus, minus,
- exp, 2, 10, -1, QLocalePrivate::AlwaysShowSign));
+ digits.append(QLocaleData::longLongToString(zero, group, plus, minus,
+ exp, 2, 10, -1, QLocaleData::AlwaysShowSign));
return digits;
}
-// Removes thousand-group separators in "C" locale.
-bool removeGroupSeparators(QLocalePrivate::CharBuff *num)
-{
- int group_cnt = 0; // counts number of group chars
- int decpt_idx = -1;
-
- char *data = num->data();
- int l = qstrlen(data);
-
- // Find the decimal point and check if there are any group chars
- int i = 0;
- for (; i < l; ++i) {
- char c = data[i];
-
- if (c == ',') {
- if (i == 0 || data[i - 1] < '0' || data[i - 1] > '9')
- return false;
- if (i == l - 1 || data[i + 1] < '0' || data[i + 1] > '9')
- return false;
- ++group_cnt;
- }
- else if (c == '.') {
- // Fail if more than one decimal points
- if (decpt_idx != -1)
- return false;
- decpt_idx = i;
- } else if (c == 'e' || c == 'E') {
- // an 'e' or 'E' - if we have not encountered a decimal
- // point, this is where it "is".
- if (decpt_idx == -1)
- decpt_idx = i;
- }
- }
-
- // If no group chars, we're done
- if (group_cnt == 0)
- return true;
-
- // No decimal point means that it "is" at the end of the string
- if (decpt_idx == -1)
- decpt_idx = l;
-
- i = 0;
- while (i < l && group_cnt > 0) {
- char c = data[i];
-
- if (c == ',') {
- // Don't allow group chars after the decimal point
- if (i > decpt_idx)
- return false;
-
- // Check that it is placed correctly relative to the decpt
- if ((decpt_idx - i) % 4 != 0)
- return false;
-
- // Remove it
- memmove(data + i, data + i + 1, l - i - 1);
- data[--l] = '\0';
-
- --group_cnt;
- --decpt_idx;
- } else {
- // Check that we are not missing a separator
- if (i < decpt_idx
- && (decpt_idx - i) % 4 == 0
- && !(i == 0 && (c == '-' || c == '+'))) // check for negative or positive sign at start of string
- return false;
- ++i;
- }
- }
-
- return true;
-}
-
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h
index cb47bfcb5e..41183560b9 100644
--- a/src/corelib/tools/qlocale_tools_p.h
+++ b/src/corelib/tools/qlocale_tools_p.h
@@ -104,9 +104,6 @@ inline bool isZero(double d)
}
}
-// Removes thousand-group separators in "C" locale.
-bool removeGroupSeparators(QLocalePrivate::CharBuff *num);
-
Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt,
int *sign, char **rve, char **digits_str);
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index c20827a4ae..1690dd83ee 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -55,12 +55,32 @@
# include <time.h>
#endif
+#ifdef Q_OS_WINRT
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#ifndef Q_OS_WINPHONE
+#include <windows.globalization.h>
+#endif
+#endif // Q_OS_WINRT
+
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINRT
static QByteArray getWinLocaleName(LCID id = LOCALE_USER_DEFAULT);
static const char *winLangCodeToIsoName(int code);
static QString winIso639LangName(LCID id = LOCALE_USER_DEFAULT);
static QString winIso3116CtryName(LCID id = LOCALE_USER_DEFAULT);
+#else // !Q_OS_WINRT
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+
+static QByteArray getWinLocaleName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+static const char *winLangCodeToIsoName(int code);
+static QString winIso639LangName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+static QString winIso3116CtryName(LPWSTR id = LOCALE_NAME_USER_DEFAULT);
+#endif // Q_OS_WINRT
#ifndef QT_NO_SYSTEMLOCALE
@@ -124,14 +144,23 @@ private:
};
// cached values:
+#ifndef Q_OS_WINRT
LCID lcid;
+#else
+ WCHAR lcName[LOCALE_NAME_MAX_LENGTH];
+#endif
SubstitutionType substitutionType;
QChar zero;
+ int getLocaleInfo(LCTYPE type, LPWSTR data, int size);
QString getLocaleInfo(LCTYPE type, int maxlen = 0);
int getLocaleInfo_int(LCTYPE type, int maxlen = 0);
QChar getLocaleInfo_qchar(LCTYPE type);
+ int getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size);
+ int getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size);
+ int getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size);
+
SubstitutionType substitution();
QString &substituteDigits(QString &string);
@@ -143,20 +172,60 @@ Q_GLOBAL_STATIC(QSystemLocalePrivate, systemLocalePrivate)
QSystemLocalePrivate::QSystemLocalePrivate()
: substitutionType(SUnknown)
{
+#ifndef Q_OS_WINRT
lcid = GetUserDefaultLCID();
+#else
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+#endif
+}
+
+inline int QSystemLocalePrivate::getCurrencyFormat(DWORD flags, LPCWSTR value, const CURRENCYFMTW *format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetCurrencyFormat(lcid, flags, value, format, data, size);
+#else
+ return GetCurrencyFormatEx(lcName, flags, value, format, data, size);
+#endif
+}
+
+inline int QSystemLocalePrivate::getDateFormat(DWORD flags, const SYSTEMTIME * date, LPCWSTR format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetDateFormat(lcid, flags, date, format, data, size);
+#else
+ return GetDateFormatEx(lcName, flags, date, format, data, size, NULL);
+#endif
+}
+
+inline int QSystemLocalePrivate::getTimeFormat(DWORD flags, const SYSTEMTIME *date, LPCWSTR format, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetTimeFormat(lcid, flags, date, format, data, size);
+#else
+ return GetTimeFormatEx(lcName, flags, date, format, data, size);
+#endif
+}
+
+inline int QSystemLocalePrivate::getLocaleInfo(LCTYPE type, LPWSTR data, int size)
+{
+#ifndef Q_OS_WINRT
+ return GetLocaleInfo(lcid, type, data, size);
+#else
+ return GetLocaleInfoEx(lcName, type, data, size);
+#endif
}
QString QSystemLocalePrivate::getLocaleInfo(LCTYPE type, int maxlen)
{
QVarLengthArray<wchar_t, 64> buf(maxlen ? maxlen : 64);
- if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
+ if (!getLocaleInfo(type, buf.data(), buf.size()))
return QString();
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- int cnt = GetLocaleInfo(lcid, type, 0, 0);
+ int cnt = getLocaleInfo(type, 0, 0);
if (cnt == 0)
return QString();
buf.resize(cnt);
- if (!GetLocaleInfo(lcid, type, buf.data(), buf.size()))
+ if (!getLocaleInfo(type, buf.data(), buf.size()))
return QString();
}
return QString::fromWCharArray(buf.data());
@@ -180,7 +249,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
{
if (substitutionType == SUnknown) {
wchar_t buf[8];
- if (!GetLocaleInfo(lcid, LOCALE_IDIGITSUBSTITUTION, buf, 8)) {
+ if (!getLocaleInfo(LOCALE_IDIGITSUBSTITUTION, buf, 8)) {
substitutionType = QSystemLocalePrivate::SNever;
return substitutionType;
}
@@ -192,7 +261,7 @@ QSystemLocalePrivate::SubstitutionType QSystemLocalePrivate::substitution()
substitutionType = QSystemLocalePrivate::SAlways;
else {
wchar_t digits[11];
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVEDIGITS, digits, 11)) {
+ if (!getLocaleInfo(LOCALE_SNATIVEDIGITS, digits, 11)) {
substitutionType = QSystemLocalePrivate::SNever;
return substitutionType;
}
@@ -340,7 +409,7 @@ QVariant QSystemLocalePrivate::toString(const QDate &date, QLocale::FormatType t
DWORD flags = (type == QLocale::LongFormat ? DATE_LONGDATE : DATE_SHORTDATE);
wchar_t buf[255];
- if (GetDateFormat(lcid, flags, &st, NULL, buf, 255)) {
+ if (getDateFormat(flags, &st, NULL, buf, 255)) {
QString format = QString::fromWCharArray(buf);
if (substitution() == SAlways)
substituteDigits(format);
@@ -364,7 +433,7 @@ QVariant QSystemLocalePrivate::toString(const QTime &time, QLocale::FormatType t
flags = TIME_NOSECONDS;
wchar_t buf[255];
- if (GetTimeFormat(lcid, flags, &st, NULL, buf, 255)) {
+ if (getTimeFormat(flags, &st, NULL, buf, 255)) {
QString format = QString::fromWCharArray(buf);
if (substitution() == SAlways)
substituteDigits(format);
@@ -382,7 +451,7 @@ QVariant QSystemLocalePrivate::measurementSystem()
{
wchar_t output[2];
- if (GetLocaleInfo(lcid, LOCALE_IMEASURE, output, 2)) {
+ if (getLocaleInfo(LOCALE_IMEASURE, output, 2)) {
QString iMeasure = QString::fromWCharArray(output);
if (iMeasure == QLatin1String("1")) {
return QLocale::ImperialSystem;
@@ -396,7 +465,7 @@ QVariant QSystemLocalePrivate::amText()
{
wchar_t output[15]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_S1159, output, 15)) {
+ if (getLocaleInfo(LOCALE_S1159, output, 15)) {
return QString::fromWCharArray(output);
}
@@ -407,7 +476,7 @@ QVariant QSystemLocalePrivate::pmText()
{
wchar_t output[15]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_S2359, output, 15)) {
+ if (getLocaleInfo(LOCALE_S2359, output, 15)) {
return QString::fromWCharArray(output);
}
@@ -418,7 +487,7 @@ QVariant QSystemLocalePrivate::firstDayOfWeek()
{
wchar_t output[4]; // maximum length including terminating zero character for Win2003+
- if (GetLocaleInfo(lcid, LOCALE_IFIRSTDAYOFWEEK, output, 4))
+ if (getLocaleInfo(LOCALE_IFIRSTDAYOFWEEK, output, 4))
return QString::fromWCharArray(output).toUInt()+1;
return 1;
@@ -429,20 +498,20 @@ QVariant QSystemLocalePrivate::currencySymbol(QLocale::CurrencySymbolFormat form
wchar_t buf[13];
switch (format) {
case QLocale::CurrencySymbol:
- if (GetLocaleInfo(lcid, LOCALE_SCURRENCY, buf, 13))
+ if (getLocaleInfo(LOCALE_SCURRENCY, buf, 13))
return QString::fromWCharArray(buf);
break;
case QLocale::CurrencyIsoCode:
- if (GetLocaleInfo(lcid, LOCALE_SINTLSYMBOL, buf, 9))
+ if (getLocaleInfo(LOCALE_SINTLSYMBOL, buf, 9))
return QString::fromWCharArray(buf);
break;
case QLocale::CurrencyDisplayName: {
QVarLengthArray<wchar_t, 64> buf(64);
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) {
+ if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size())) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break;
buf.resize(255); // should be large enough, right?
- if (!GetLocaleInfo(lcid, LOCALE_SNATIVECURRNAME, buf.data(), buf.size()))
+ if (!getLocaleInfo(LOCALE_SNATIVECURRNAME, buf.data(), buf.size()))
break;
}
return QString::fromWCharArray(buf.data());
@@ -458,24 +527,24 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
QString value;
switch (arg.value.type()) {
case QVariant::Int:
- value = QLocalePrivate::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'),
+ value = QLocaleData::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'),
arg.value.toInt(), -1, 10, -1, QLocale::OmitGroupSeparator);
break;
case QVariant::UInt:
- value = QLocalePrivate::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'),
+ value = QLocaleData::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'),
arg.value.toUInt(), -1, 10, -1, QLocale::OmitGroupSeparator);
break;
case QVariant::Double:
- value = QLocalePrivate::doubleToString(QLatin1Char('0'), QLatin1Char('+'), QLatin1Char('-'),
+ value = QLocaleData::doubleToString(QLatin1Char('0'), QLatin1Char('+'), QLatin1Char('-'),
QLatin1Char(' '), QLatin1Char(','), QLatin1Char('.'),
- arg.value.toDouble(), -1, QLocalePrivate::DFDecimal, -1, QLocale::OmitGroupSeparator);
+ arg.value.toDouble(), -1, QLocaleData::DFDecimal, -1, QLocale::OmitGroupSeparator);
break;
case QVariant::LongLong:
- value = QLocalePrivate::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'),
+ value = QLocaleData::longLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'), QLatin1Char('-'),
arg.value.toLongLong(), -1, 10, -1, QLocale::OmitGroupSeparator);
break;
case QVariant::ULongLong:
- value = QLocalePrivate::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'),
+ value = QLocaleData::unsLongLongToString(QLatin1Char('0'), QLatin1Char(','), QLatin1Char('+'),
arg.value.toULongLong(), -1, 10, -1, QLocale::OmitGroupSeparator);
break;
default:
@@ -489,14 +558,14 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
CURRENCYFMT format;
CURRENCYFMT *pformat = NULL;
if (!arg.symbol.isEmpty()) {
- format.NumDigits = getLocaleInfo_int(lcid, LOCALE_ICURRDIGITS);
- format.LeadingZero = getLocaleInfo_int(lcid, LOCALE_ILZERO);
- decimalSep = getLocaleInfo(lcid, LOCALE_SMONDECIMALSEP);
+ format.NumDigits = getLocaleInfo_int(LOCALE_ICURRDIGITS);
+ format.LeadingZero = getLocaleInfo_int(LOCALE_ILZERO);
+ decimalSep = getLocaleInfo(LOCALE_SMONDECIMALSEP);
format.lpDecimalSep = (wchar_t *)decimalSep.utf16();
- thousandSep = getLocaleInfo(lcid, LOCALE_SMONTHOUSANDSEP);
+ thousandSep = getLocaleInfo(LOCALE_SMONTHOUSANDSEP);
format.lpThousandSep = (wchar_t *)thousandSep.utf16();
- format.NegativeOrder = getLocaleInfo_int(lcid, LOCALE_INEGCURR);
- format.PositiveOrder = getLocaleInfo_int(lcid, LOCALE_ICURRENCY);
+ format.NegativeOrder = getLocaleInfo_int(LOCALE_INEGCURR);
+ format.PositiveOrder = getLocaleInfo_int(LOCALE_ICURRENCY);
format.lpCurrencySymbol = (wchar_t *)arg.symbol.utf16();
// grouping is complicated and ugly:
@@ -505,7 +574,7 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
// int(30) == "123456,789.00" == string("3;0;0")
// int(32) == "12,34,56,789.00" == string("3;2;0")
// int(320)== "1234,56,789.00" == string("3;2")
- QString groupingStr = getLocaleInfo(lcid, LOCALE_SMONGROUPING);
+ QString groupingStr = getLocaleInfo(LOCALE_SMONGROUPING);
format.Grouping = groupingStr.remove(QLatin1Char(';')).toInt();
if (format.Grouping % 10 == 0) // magic
format.Grouping /= 10;
@@ -514,13 +583,13 @@ QVariant QSystemLocalePrivate::toCurrencyString(const QSystemLocale::CurrencyToS
pformat = &format;
}
- int ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ int ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), out.size());
if (ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- ret = ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ ret = getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), 0);
out.resize(ret);
- ::GetCurrencyFormat(lcid, 0, reinterpret_cast<const wchar_t *>(value.utf16()),
+ getCurrencyFormat(0, reinterpret_cast<const wchar_t *>(value.utf16()),
pformat, out.data(), out.size());
}
@@ -539,11 +608,13 @@ QVariant QSystemLocalePrivate::uiLanguages()
PWSTR pwszLanguagesBuffer,
PULONG pcchLanguagesBuffer);
static GetUserPreferredUILanguagesFunc GetUserPreferredUILanguages_ptr = 0;
+#ifndef Q_OS_WINRT
if (!GetUserPreferredUILanguages_ptr) {
QSystemLibrary lib(QLatin1String("kernel32"));
if (lib.load())
GetUserPreferredUILanguages_ptr = (GetUserPreferredUILanguagesFunc)lib.resolve("GetUserPreferredUILanguages");
}
+#endif // !Q_OS_WINRT
if (GetUserPreferredUILanguages_ptr) {
unsigned long cnt = 0;
QVarLengthArray<wchar_t, 64> buf(64);
@@ -571,8 +642,39 @@ QVariant QSystemLocalePrivate::uiLanguages()
}
}
+#ifndef Q_OS_WINRT
// old Windows before Vista
return QStringList(QString::fromLatin1(winLangCodeToIsoName(GetUserDefaultUILanguage())));
+#else // !Q_OS_WINRT
+ QStringList result;
+#ifndef Q_OS_WINPHONE
+ ComPtr<ABI::Windows::Globalization::IApplicationLanguagesStatics> appLanguagesStatics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Globalization_ApplicationLanguages).Get(), &appLanguagesStatics))) {
+ qWarning("Could not obtain ApplicationLanguagesStatic");
+ return QStringList();
+ }
+
+ ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING> > languageList;
+ appLanguagesStatics->get_ManifestLanguages(&languageList);
+
+ if (!languageList)
+ return QStringList();
+
+ unsigned int size;
+ languageList->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ HSTRING language;
+ languageList->GetAt(i, &language);
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(language, &length);
+ result << QString::fromWCharArray(rawString, length);
+ }
+#else // !Q_OS_WINPHONE
+ result << QString::fromWCharArray(lcName);
+#endif // Q_OS_WINPHONE
+
+ return result;
+#endif // Q_OS_WINRT
}
QVariant QSystemLocalePrivate::nativeLanguageName()
@@ -592,7 +694,11 @@ QVariant QSystemLocalePrivate::nativeCountryName()
void QSystemLocalePrivate::update()
{
+#ifndef Q_OS_WINRT
lcid = GetUserDefaultLCID();
+#else
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+#endif
substitutionType = SUnknown;
zero = QChar();
}
@@ -906,7 +1012,11 @@ static const char *winLangCodeToIsoName(int code)
}
+#ifndef Q_OS_WINRT
static QString winIso639LangName(LCID id)
+#else
+static QString winIso639LangName(LPWSTR id)
+#endif
{
QString result;
@@ -914,7 +1024,11 @@ static QString winIso639LangName(LCID id)
// the language code
QString lang_code;
wchar_t out[256];
- if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255)) // ### shouldn't use them according to msdn
+#ifndef Q_OS_WINRT
+ if (GetLocaleInfo(id, LOCALE_ILANGUAGE, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_ILANGUAGE, out, 255))
+#endif
lang_code = QString::fromWCharArray(out);
if (!lang_code.isEmpty()) {
@@ -937,27 +1051,47 @@ static QString winIso639LangName(LCID id)
return result;
// not one of the problematic languages - do the usual lookup
- if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME , out, 255))
+#ifndef Q_OS_WINRT
+ if (GetLocaleInfo(id, LOCALE_SISO639LANGNAME, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_SISO639LANGNAME, out, 255))
+#endif
result = QString::fromWCharArray(out);
return result;
}
+#ifndef Q_OS_WINRT
static QString winIso3116CtryName(LCID id)
+#else
+static QString winIso3116CtryName(LPWSTR id)
+#endif
{
QString result;
wchar_t out[256];
+#ifndef Q_OS_WINRT
if (GetLocaleInfo(id, LOCALE_SISO3166CTRYNAME, out, 255))
+#else
+ if (GetLocaleInfoEx(id, LOCALE_SISO3166CTRYNAME, out, 255))
+#endif
result = QString::fromWCharArray(out);
return result;
}
+#ifndef Q_OS_WINRT
static QByteArray getWinLocaleName(LCID id)
+#else
+static QByteArray getWinLocaleName(LPWSTR id)
+#endif
{
QByteArray result;
+#ifndef Q_OS_WINRT
if (id == LOCALE_USER_DEFAULT) {
+#else
+ if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) {
+#endif
static QByteArray langEnvVar = qgetenv("LANG");
result = langEnvVar;
QString lang, script, cntry;
@@ -975,9 +1109,17 @@ static QByteArray getWinLocaleName(LCID id)
#if defined(Q_OS_WINCE)
result = winLangCodeToIsoName(id != LOCALE_USER_DEFAULT ? id : GetUserDefaultLCID());
-#else
+#else // !Q_OS_WINCE
+# ifndef Q_OS_WINRT
if (id == LOCALE_USER_DEFAULT)
id = GetUserDefaultLCID();
+# else // !Q_OS_WINRT
+ WCHAR lcName[LOCALE_NAME_MAX_LENGTH];
+ if (QString::fromWCharArray(id) == QString::fromWCharArray(LOCALE_NAME_USER_DEFAULT)) {
+ GetUserDefaultLocaleName(lcName, LOCALE_NAME_MAX_LENGTH);
+ id = lcName;
+ }
+# endif // Q_OS_WINRT
QString resultuage = winIso639LangName(id);
QString country = winIso3116CtryName(id);
result = resultuage.toLatin1();
@@ -985,14 +1127,20 @@ static QByteArray getWinLocaleName(LCID id)
result += '_';
result += country.toLatin1();
}
-#endif
+#endif // !Q_OS_WINCE
return result;
}
Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id)
{
+#ifndef Q_OS_WINRT
return QLocale(QString::fromLatin1(getWinLocaleName(id)));
+#else // !Q_OS_WINRT
+ WCHAR name[LOCALE_NAME_MAX_LENGTH];
+ LCIDToLocaleName(id, name, LOCALE_NAME_MAX_LENGTH, 0);
+ return QLocale(QString::fromLatin1(getWinLocaleName(name)));
+#endif // Q_OS_WINRT
}
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qregexp.h b/src/corelib/tools/qregexp.h
index 26b0b78317..115fceb18b 100644
--- a/src/corelib/tools/qregexp.h
+++ b/src/corelib/tools/qregexp.h
@@ -68,7 +68,7 @@ public:
QRegExp();
explicit QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive,
- PatternSyntax syntax = RegExp);
+ PatternSyntax syntax = RegExp);
QRegExp(const QRegExp &rx);
~QRegExp();
QRegExp &operator=(const QRegExp &rx);
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index 00c523afe6..2d679e036e 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -54,7 +54,7 @@
# include <intrin.h>
# endif
# endif
-#elif defined(Q_OS_LINUX) && (defined(Q_PROCESSOR_ARM) || defined(QT_COMPILER_SUPPORTS_IWMMXT) || defined(QT_COMPILER_SUPPORTS_NEON))
+#elif defined(Q_OS_LINUX) && (defined(Q_PROCESSOR_ARM) || defined(QT_COMPILER_SUPPORTS_IWMMXT))
#include "private/qcore_unix_p.h"
// the kernel header definitions for HWCAP_*
@@ -102,7 +102,7 @@ static inline uint detectProcessorFeatures()
return features;
}
-#elif defined(Q_PROCESSOR_ARM) || defined(QT_COMPILER_SUPPORTS_IWMMXT) || defined(QT_COMPILER_SUPPORTS_NEON)
+#elif defined(Q_PROCESSOR_ARM) || defined(QT_COMPILER_SUPPORTS_IWMMXT)
static inline uint detectProcessorFeatures()
{
uint features = 0;
@@ -157,7 +157,7 @@ static inline uint detectProcessorFeatures()
static int maxBasicCpuidSupported()
{
#if defined(Q_CC_GNU)
- qintptr tmp1;
+ qregisterint tmp1;
# if Q_PROCESSOR_X86 < 5
// check if the CPUID instruction is supported
@@ -198,7 +198,7 @@ static int maxBasicCpuidSupported()
static void cpuidFeatures01(uint &ecx, uint &edx)
{
#if defined(Q_CC_GNU)
- qintptr tmp1;
+ qregisterint tmp1;
asm ("xchg " PICreg", %2\n"
"cpuid\n"
"xchg " PICreg", %2\n"
@@ -219,7 +219,7 @@ inline void __cpuidex(int info[4], int, __int64) { memset(info, 0, 4*sizeof(int)
static void cpuidFeatures07_00(uint &ebx)
{
#if defined(Q_CC_GNU)
- quintptr rbx; // in case it's 64-bit
+ qregisteruint rbx; // in case it's 64-bit
asm ("xchg " PICreg", %0\n"
"cpuid\n"
"xchg " PICreg", %0\n"
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index b01c47d4ce..d293532f1d 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -56,7 +56,8 @@
*
* We will try to include all headers possible under this configuration.
*
- * MSVC does not define __SSE2__ & family, so we will define them.
+ * MSVC does not define __SSE2__ & family, so we will define them. MSVC 2013 &
+ * up do define __AVX__ if the -arch:AVX option is passed on the command-line.
*
* Supported XXX are:
* Flag | Arch | GCC | Intel CC | MSVC |
@@ -72,7 +73,7 @@
* I = intrinsics; C = code generation
*/
-#ifdef __MINGW64_VERSION_MAJOR
+#if defined(__MINGW64_VERSION_MAJOR) || (defined(Q_CC_MSVC) && !defined(Q_OS_WINCE))
#include <intrin.h>
#endif
@@ -118,31 +119,31 @@
// immintrin.h is the ultimate header, we don't need anything else after this
#include <immintrin.h>
-# if defined(Q_CC_MSVC) && defined(_M_AVX)
+# if defined(Q_CC_MSVC) && (defined(_M_AVX) || defined(__AVX__))
// MS Visual Studio 2010 has no macro pre-defined to identify the use of /arch:AVX
+// MS Visual Studio 2013 adds it: __AVX__
// See: http://connect.microsoft.com/VisualStudio/feedback/details/605858/arch-avx-should-define-a-predefined-macro-in-x64-and-set-a-unique-value-for-m-ix86-fp-in-win32
-// When such a macro exists, add it above, replacing _M_AVX as appropriate
# define __SSE3__ 1
# define __SSSE3__ 1
// no Intel CPU supports SSE4a, so don't define it
# define __SSE4_1__ 1
# define __SSE4_2__ 1
-# define __AVX__ 1
-# ifdef _M_AVX2
-// replace the macro above with the proper MS macro when it exists
-// All processors with AVX2 will support BMI1 and FMA
-# define __AVX2__ 1
-# define __BMI__ 1
-# define __FMA__ 1
-# endif
+# ifndef __AVX__
+# define __AVX__ 1
+# endif
# endif
#endif
// other x86 intrinsics
-#if defined(QT_COMPILER_SUPPORTS_AVX) && defined(Q_CC_GNU) && \
- (!defined(Q_CC_INTEL)|| __INTEL_COMPILER >= 1310 || (__GNUC__ * 100 + __GNUC_MINOR__ < 407))
-#define QT_COMPILER_SUPPORTS_X86INTRIN
-#include <x86intrin.h>
+#if defined(Q_PROCESSOR_X86) && ((defined(Q_CC_GNU) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) \
+ || (defined(Q_CC_CLANG) && (__clang_major__ * 100 + __clang_minor__ >= 208)) \
+ || defined(Q_CC_INTEL))
+# define QT_COMPILER_SUPPORTS_X86INTRIN
+# ifndef Q_CC_INTEL
+// The Intel compiler has no <x86intrin.h> -- all intrinsics are in <immintrin.h>;
+// GCC 4.4 and Clang 2.8 added a few more intrinsics there
+# include <x86intrin.h>
+# endif
#endif
// NEON intrinsics
@@ -241,6 +242,43 @@ static inline uint qCpuFeatures()
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (feature)) || (qCpuFeatures() & (feature)))
+#ifdef Q_PROCESSOR_X86
+// Bit scan functions for x86
+# ifdef Q_CC_MSVC
+// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need
+static __forceinline unsigned long _bit_scan_reverse(uint val)
+{
+ unsigned long result;
+ _BitScanReverse(&result, val);
+ return result;
+}
+static __forceinline unsigned long _bit_scan_forward(uint val)
+{
+ unsigned long result;
+ _BitScanForward(&result, val);
+ return result;
+}
+# elif (defined(Q_CC_CLANG) || (defined(Q_CC_GNU) && __GNUC__ * 100 + __GNUC_MINOR__ < 405)) \
+ && !defined(Q_CC_INTEL)
+// Clang is missing the intrinsic for _bit_scan_reverse
+// GCC only added it in version 4.5
+static inline __attribute__((always_inline))
+unsigned _bit_scan_reverse(unsigned val)
+{
+ unsigned result;
+ asm("bsr %1, %0" : "=r" (result) : "r" (val));
+ return result;
+}
+static inline __attribute__((always_inline))
+unsigned _bit_scan_forward(unsigned val)
+{
+ unsigned result;
+ asm("bsf %1, %0" : "=r" (result) : "r" (val));
+ return result;
+}
+# endif
+#endif // Q_PROCESSOR_X86
+
#define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \
for (; i < static_cast<int>(qMin(static_cast<quintptr>(length), ((4 - ((reinterpret_cast<quintptr>(ptr) >> 2) & 0x3)) & 0x3))); ++i)
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index d22d808a12..50f616a010 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -53,6 +54,7 @@
#include <qlist.h>
#include "qlocale.h"
#include "qlocale_p.h"
+#include "qstringbuilder.h"
#include "qstringmatcher.h"
#include "qvarlengtharray.h"
#include "qtools_p.h"
@@ -75,6 +77,7 @@
#include "qchar.cpp"
#include "qstringmatcher.cpp"
+#include "qstringiterator_p.h"
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -101,6 +104,43 @@
QT_BEGIN_NAMESPACE
+/*
+ * Note on the use of SIMD in qstring.cpp:
+ *
+ * Several operations with strings are improved with the use of SIMD code,
+ * since they are repetitive. For MIPS, we have hand-written assembly code
+ * outside of qstring.cpp targeting MIPS DSP and MIPS DSPr2. For ARM and for
+ * x86, we can only use intrinsics and therefore everything is contained in
+ * qstring.cpp. We need to use intrinsics only for those platforms due to the
+ * different compilers and toolchains used, which have different syntax for
+ * assembly sources.
+ *
+ * ** SSE notes: **
+ *
+ * Whenever multiple alternatives are equivalent or near so, we prefer the one
+ * using instructions from SSE2, since SSE2 is guaranteed to be enabled for all
+ * 64-bit builds and we enable it for 32-bit builds by default. Use of higher
+ * SSE versions should be done when there's a clear performance benefit and
+ * requires fallback code to SSE2, if it exists.
+ *
+ * Performance measurement in the past shows that most strings are short in
+ * size and, therefore, do not benefit from alignment prologues. That is,
+ * trying to find a 16-byte-aligned boundary to operate on is often more
+ * expensive than executing the unaligned operation directly. In addition, note
+ * that the QString private data is designed so that the data is stored on
+ * 16-byte boundaries if the system malloc() returns 16-byte aligned pointers
+ * on its own (64-bit glibc on Linux does; 32-bit glibc on Linux returns them
+ * 50% of the time), so skipping the alignment prologue is actually optimizing
+ * for the common case.
+ */
+
+#if defined(__mips_dsp)
+// From qstring_mips_dsp_asm.S
+extern "C" void qt_fromlatin1_mips_asm_unroll4 (ushort*, const char*, uint);
+extern "C" void qt_fromlatin1_mips_asm_unroll8 (ushort*, const char*, uint);
+extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const ushort *src, int length);
+#endif
+
// internal
int qFindString(const QChar *haystack, int haystackLen, int from,
const QChar *needle, int needleLen, Qt::CaseSensitivity cs);
@@ -124,6 +164,209 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
QLatin1String needle, Qt::CaseSensitivity cs);
+#ifdef Q_COMPILER_LAMBDA
+namespace {
+template <uint MaxCount> struct UnrollTailLoop
+{
+ template <typename RetType, typename Functor1, typename Functor2>
+ static inline RetType exec(int count, RetType returnIfExited, Functor1 loopCheck, Functor2 returnIfFailed, int i = 0)
+ {
+ /* equivalent to:
+ * while (count--) {
+ * if (loopCheck(i))
+ * return returnIfFailed(i);
+ * }
+ * return returnIfExited;
+ */
+
+ if (!count)
+ return returnIfExited;
+
+ bool check = loopCheck(i);
+ if (check) {
+ const RetType &retval = returnIfFailed(i);
+ return retval;
+ }
+
+ return UnrollTailLoop<MaxCount - 1>::exec(count - 1, returnIfExited, loopCheck, returnIfFailed, i + 1);
+ }
+
+ template <typename Functor>
+ static inline void exec(int count, Functor code)
+ {
+ /* equivalent to:
+ * for (int i = 0; i < count; ++i)
+ * code(i);
+ */
+ exec(count, 0, [=](int i) -> bool { code(i); return false; }, [](int) { return 0; });
+ }
+};
+template <> template <typename RetType, typename Functor1, typename Functor2>
+inline RetType UnrollTailLoop<0>::exec(int, RetType returnIfExited, Functor1, Functor2, int)
+{
+ return returnIfExited;
+}
+}
+#endif
+
+// conversion between Latin 1 and UTF-16
+static void qt_from_latin1(ushort *dst, const char *str, size_t size)
+{
+ /* SIMD:
+ * Unpacking with SSE has been shown to improve performance on recent CPUs
+ * The same method gives no improvement with NEON.
+ */
+#if defined(__SSE2__)
+ const char *e = str + size;
+ qptrdiff offset = 0;
+
+ // we're going to read str[offset..offset+15] (16 bytes)
+ for ( ; str + offset + 15 < e; offset += 16) {
+ const __m128i nullMask = _mm_set1_epi32(0);
+ const __m128i chunk = _mm_loadu_si128((__m128i*)(str + offset)); // load
+
+ // unpack the first 8 bytes, padding with zeros
+ const __m128i firstHalf = _mm_unpacklo_epi8(chunk, nullMask);
+ _mm_storeu_si128((__m128i*)(dst + offset), firstHalf); // store
+
+ // unpack the last 8 bytes, padding with zeros
+ const __m128i secondHalf = _mm_unpackhi_epi8 (chunk, nullMask);
+ _mm_storeu_si128((__m128i*)(dst + offset + 8), secondHalf); // store
+ }
+
+ size = size % 16;
+ dst += offset;
+ str += offset;
+# ifdef Q_COMPILER_LAMBDA
+ return UnrollTailLoop<15>::exec(size, [=](int i) { dst[i] = (uchar)str[i]; });
+# endif
+#endif
+#if defined(__mips_dsp)
+ if (size > 20)
+ qt_fromlatin1_mips_asm_unroll8(dst, str, size);
+ else
+ qt_fromlatin1_mips_asm_unroll4(dst, str, size);
+#else
+ while (size--)
+ *dst++ = (uchar)*str++;
+#endif
+}
+
+#if defined(__SSE2__)
+static inline __m128i mergeQuestionMarks(__m128i chunk)
+{
+ const __m128i questionMark = _mm_set1_epi16('?');
+
+# ifdef __SSE4_2__
+ // compare the unsigned shorts for the range 0x0100-0xFFFF
+ // note on the use of _mm_cmpestrm:
+ // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
+ // says for range search the following:
+ // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
+ //
+ // However, all examples on the Internet, including from Intel
+ // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
+ // put the range to be searched first
+ //
+ // Disassembly and instruction-level debugging with GCC and ICC show
+ // that they are doing the right thing. Inverting the arguments in the
+ // instruction does cause a bunch of test failures.
+
+ const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK;
+ const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
+ const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode);
+
+ // replace the non-Latin 1 characters in the chunk with question marks
+ chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
+# else
+ // SSE has no compare instruction for unsigned comparison.
+ // The variables must be shiffted + 0x8000 to be compared
+ const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
+ const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
+
+ const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
+ const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
+
+# ifdef __SSE4_1__
+ // replace the non-Latin 1 characters in the chunk with question marks
+ chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
+# else
+ // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
+ // the 16 bits that were correct contains zeros
+ const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
+
+ // correctBytes contains the bytes that were in limit
+ // the 16 bits that were off limits contains zeros
+ const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk);
+
+ // merge offLimitQuestionMark and correctBytes to have the result
+ chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
+# endif
+# endif
+ return chunk;
+}
+#endif
+
+static void qt_to_latin1(uchar *dst, const ushort *src, int length)
+{
+#if defined(__SSE2__)
+ uchar *e = dst + length;
+ qptrdiff offset = 0;
+
+ // we're going to write to dst[offset..offset+15] (16 bytes)
+ for ( ; dst + offset + 15 < e; offset += 16) {
+ __m128i chunk1 = _mm_loadu_si128((__m128i*)(src + offset)); // load
+ chunk1 = mergeQuestionMarks(chunk1);
+
+ __m128i chunk2 = _mm_loadu_si128((__m128i*)(src + offset + 8)); // load
+ chunk2 = mergeQuestionMarks(chunk2);
+
+ // pack the two vector to 16 x 8bits elements
+ const __m128i result = _mm_packus_epi16(chunk1, chunk2);
+ _mm_storeu_si128((__m128i*)(dst + offset), result); // store
+ }
+
+ length = length % 16;
+ dst += offset;
+ src += offset;
+
+# ifdef Q_COMPILER_LAMBDA
+ return UnrollTailLoop<15>::exec(length, [=](int i) { dst[i] = (src[i]>0xff) ? '?' : (uchar) src[i]; });
+# endif
+#elif defined(__ARM_NEON__)
+ // Refer to the documentation of the SSE2 implementation
+ // this use eactly the same method as for SSE except:
+ // 1) neon has unsigned comparison
+ // 2) packing is done to 64 bits (8 x 8bits component).
+ if (length >= 16) {
+ const int chunkCount = length >> 3; // divided by 8
+ const uint16x8_t questionMark = vdupq_n_u16('?'); // set
+ const uint16x8_t thresholdMask = vdupq_n_u16(0xff); // set
+ for (int i = 0; i < chunkCount; ++i) {
+ uint16x8_t chunk = vld1q_u16((uint16_t *)src); // load
+ src += 8;
+
+ const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
+ const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
+ const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
+ chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
+ const uint8x8_t result = vmovn_u16(chunk); // narrowing move->packing
+ vst1_u8(dst, result); // store
+ dst += 8;
+ }
+ length = length % 8;
+ }
+#endif
+#if defined(__mips_dsp)
+ qt_toLatin1_mips_dsp_asm(dst, src, length);
+#else
+ while (length--) {
+ *dst++ = (*src>0xff) ? '?' : (uchar) *src;
+ ++src;
+ }
+#endif
+}
+
// Unicode case-insensitive comparison
static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be)
{
@@ -205,83 +448,39 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l)
l);
}
#endif // __mips_dsp
- while (l-- && *a == *b)
- a++,b++;
- if (l==-1)
- return 0;
- return a->unicode() - b->unicode();
-}
-
-// Unicode case-sensitive comparison
-static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
-{
- if (a == b && alen == blen)
+#ifdef __SSE2__
+ const char *ptr = reinterpret_cast<const char*>(a);
+ qptrdiff distance = reinterpret_cast<const char*>(b) - ptr;
+ a += l & ~7;
+ b += l & ~7;
+ l &= 7;
+
+ // we're going to read ptr[0..15] (16 bytes)
+ for ( ; ptr + 15 < reinterpret_cast<const char *>(a); ptr += 16) {
+ __m128i a_data = _mm_loadu_si128((__m128i*)ptr);
+ __m128i b_data = _mm_loadu_si128((__m128i*)(ptr + distance));
+ __m128i result = _mm_cmpeq_epi16(a_data, b_data);
+ uint mask = ~_mm_movemask_epi8(result);
+ if (ushort(mask)) {
+ // found a different byte
+ uint idx = uint(_bit_scan_forward(mask));
+ return reinterpret_cast<const QChar *>(ptr + idx)->unicode()
+ - reinterpret_cast<const QChar *>(ptr + distance + idx)->unicode();
+ }
+ }
+# ifdef Q_COMPILER_LAMBDA
+ const auto &lambda = [=](int i) -> int {
+ return reinterpret_cast<const QChar *>(ptr)[i].unicode()
+ - reinterpret_cast<const QChar *>(ptr + distance)[i].unicode();
+ };
+ return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
+# endif
+#endif
+ if (!l)
return 0;
- int l = qMin(alen, blen);
- int cmp = ucstrncmp(a, b, l);
- return cmp ? cmp : (alen-blen);
-}
-
-// Unicode case-insensitive compare two same-sized strings
-static int ucstrnicmp(const ushort *a, const ushort *b, int l)
-{
- return ucstricmp(a, a + l, b, b + l);
-}
-
-// Benchmarking indicates that doing memcmp is much slower than
-// executing the comparison ourselves.
-//
-// The profiling was done on a population of calls to qMemEquals, generated
-// during a run of the demo browser. The profile of the data (32-bit x86
-// Linux) was:
-//
-// total number of comparisons: 21353
-// longest string compared: 95
-// average comparison length: 14.8786
-// cache-line crosses: 5661 (13.3%)
-// alignment histogram:
-// 0xXXX0 = 512 (1.2%) strings, 0 (0.0%) of which same-aligned
-// 0xXXX2 = 15087 (35.3%) strings, 5145 (34.1%) of which same-aligned
-// 0xXXX4 = 525 (1.2%) strings, 0 (0.0%) of which same-aligned
-// 0xXXX6 = 557 (1.3%) strings, 6 (1.1%) of which same-aligned
-// 0xXXX8 = 509 (1.2%) strings, 0 (0.0%) of which same-aligned
-// 0xXXXa = 24358 (57.0%) strings, 9901 (40.6%) of which same-aligned
-// 0xXXXc = 557 (1.3%) strings, 0 (0.0%) of which same-aligned
-// 0xXXXe = 601 (1.4%) strings, 15 (2.5%) of which same-aligned
-// total = 42706 (100%) strings, 15067 (35.3%) of which same-aligned
-//
-// 92% of the strings have alignment of 2 or 10, which is due to malloc on
-// 32-bit Linux returning values aligned to 8 bytes, and offsetof(array, QString::Data) == 18.
-//
-// The profile on 64-bit will be different since offsetof(array, QString::Data) == 26.
-//
-// The benchmark results were, for a Core-i7 @ 2.67 GHz 32-bit, compiled with -O3 -funroll-loops:
-// 16-bit loads only: 872,301 CPU ticks [Qt 4.5 / memcmp]
-// 32- and 16-bit loads: 773,362 CPU ticks [Qt 4.6]
-// SSE2 "movdqu" 128-bit loads: 618,736 CPU ticks
-// SSE3 "lddqu" 128-bit loads: 619,954 CPU ticks
-// SSSE3 "palignr" corrections: 852,147 CPU ticks
-// SSE4.2 "pcmpestrm": 738,702 CPU ticks
-//
-// The same benchmark on an Atom N450 @ 1.66 GHz, is:
-// 16-bit loads only: 2,185,882 CPU ticks
-// 32- and 16-bit loads: 1,805,060 CPU ticks
-// SSE2 "movdqu" 128-bit loads: 2,529,843 CPU ticks
-// SSE3 "lddqu" 128-bit loads: 2,514,858 CPU ticks
-// SSSE3 "palignr" corrections: 2,160,325 CPU ticks
-// SSE4.2 not available
-//
-// The conclusion we reach is that alignment the SSE2 unaligned code can gain
-// 20% improvement in performance in some systems, but suffers a penalty due
-// to the unaligned loads on others.
-
-static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
-{
- if (a == b || !length)
- return true;
union {
- const quint16 *w;
+ const QChar *w;
const quint32 *d;
quintptr value;
} sa, sb;
@@ -295,8 +494,8 @@ static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
// both addresses are not aligned to 4-bytes boundaries
// compare the first character
if (*sa.w != *sb.w)
- return false;
- --length;
+ return sa.w->unicode() - sb.w->unicode();
+ --l;
++sa.w;
++sb.w;
@@ -305,23 +504,128 @@ static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
// both addresses are 4-bytes aligned
// do a fast 32-bit comparison
- const quint32 *e = sa.d + (length >> 1);
+ const quint32 *e = sa.d + (l >> 1);
for ( ; sa.d != e; ++sa.d, ++sb.d) {
- if (*sa.d != *sb.d)
- return false;
+ if (*sa.d != *sb.d) {
+ if (*sa.w != *sb.w)
+ return sa.w->unicode() - sb.w->unicode();
+ return sa.w[1].unicode() - sb.w[1].unicode();
+ }
}
// do we have a tail?
- return (length & 1) ? *sa.w == *sb.w : true;
+ return (l & 1) ? sa.w->unicode() - sb.w->unicode() : 0;
} else {
// one of the addresses isn't 4-byte aligned but the other is
- const quint16 *e = sa.w + length;
+ const QChar *e = sa.w + l;
for ( ; sa.w != e; ++sa.w, ++sb.w) {
if (*sa.w != *sb.w)
- return false;
+ return sa.w->unicode() - sb.w->unicode();
}
}
- return true;
+ return 0;
+}
+
+static int ucstrncmp(const QChar *a, const uchar *c, int l)
+{
+ const ushort *uc = reinterpret_cast<const ushort *>(a);
+ const ushort *e = uc + l;
+
+#ifdef __SSE2__
+ __m128i nullmask = _mm_setzero_si128();
+ qptrdiff offset = 0;
+
+ // we're going to read uc[offset..offset+15] (32 bytes)
+ // and c[offset..offset+15] (16 bytes)
+ for ( ; uc + offset + 15 < e; offset += 16) {
+ // similar to fromLatin1_helper:
+ // load Latin 1 data and expand to UTF-16
+ __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset));
+ __m128i firstHalf = _mm_unpacklo_epi8(chunk, nullmask);
+ __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask);
+
+ // load UTF-16 data and compare
+ __m128i ucdata1 = _mm_loadu_si128((__m128i*)(uc + offset));
+ __m128i ucdata2 = _mm_loadu_si128((__m128i*)(uc + offset + 8));
+ __m128i result1 = _mm_cmpeq_epi16(firstHalf, ucdata1);
+ __m128i result2 = _mm_cmpeq_epi16(secondHalf, ucdata2);
+
+ uint mask = ~(_mm_movemask_epi8(result1) | _mm_movemask_epi8(result2) << 16);
+ if (mask) {
+ // found a different character
+ uint idx = uint(_bit_scan_forward(mask));
+ return uc[offset + idx / 2] - c[offset + idx / 2];
+ }
+ }
+
+ // we'll read uc[offset..offset+7] (16 bytes) and c[offset-8..offset+7] (16 bytes)
+ if (uc + offset + 7 < e) {
+ // same, but we'll throw away half the data
+ __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset - 8));
+ __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask);
+
+ __m128i ucdata = _mm_loadu_si128((__m128i*)(uc + offset));
+ __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata);
+ uint mask = ~_mm_movemask_epi8(result);
+ if (ushort(mask)) {
+ // found a different character
+ uint idx = uint(_bit_scan_forward(mask));
+ return uc[offset + idx / 2] - c[offset + idx / 2];
+ }
+
+ // still matched
+ offset += 8;
+ }
+
+ // reset uc and c
+ uc += offset;
+ c += offset;
+
+# ifdef Q_COMPILER_LAMBDA
+ const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); };
+ return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda);
+# endif
+#endif
+
+ while (uc < e) {
+ int diff = *uc - *c;
+ if (diff)
+ return diff;
+ uc++, c++;
+ }
+
+ return 0;
+}
+
+// Unicode case-sensitive comparison
+static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen)
+{
+ if (a == b && alen == blen)
+ return 0;
+ int l = qMin(alen, blen);
+ int cmp = ucstrncmp(a, b, l);
+ return cmp ? cmp : (alen-blen);
+}
+
+// Unicode case-insensitive compare two same-sized strings
+static int ucstrnicmp(const ushort *a, const ushort *b, int l)
+{
+ return ucstricmp(a, a + l, b, b + l);
+}
+
+static bool qMemEquals(const quint16 *a, const quint16 *b, int length)
+{
+ if (a == b || !length)
+ return true;
+
+ return ucstrncmp(reinterpret_cast<const QChar *>(a), reinterpret_cast<const QChar *>(b), length) == 0;
+}
+
+static int ucstrcmp(const QChar *a, int alen, const uchar *b, int blen)
+{
+ int l = qMin(alen, blen);
+ int cmp = ucstrncmp(a, b, l);
+ return cmp ? cmp : (alen-blen);
}
/*!
@@ -340,14 +644,38 @@ static int findChar(const QChar *str, int len, QChar ch, int from,
if (from < 0)
from = qMax(from + len, 0);
if (from < len) {
- const ushort *n = s + from - 1;
+ const ushort *n = s + from;
const ushort *e = s + len;
if (cs == Qt::CaseSensitive) {
+#ifdef __SSE2__
+ __m128i mch = _mm_set1_epi32(c | (c << 16));
+
+ // we're going to read n[0..7] (16 bytes)
+ for (const ushort *next = n + 8; next <= e; n = next, next += 8) {
+ __m128i data = _mm_loadu_si128((__m128i*)n);
+ __m128i result = _mm_cmpeq_epi16(data, mch);
+ uint mask = _mm_movemask_epi8(result);
+ if (ushort(mask)) {
+ // found a match
+ // same as: return n - s + _bit_scan_forward(mask) / 2
+ return (reinterpret_cast<const char *>(n) - reinterpret_cast<const char *>(s)
+ + _bit_scan_forward(mask)) >> 1;
+ }
+ }
+
+# ifdef Q_COMPILER_LAMBDA
+ return UnrollTailLoop<7>::exec(e - n, -1,
+ [=](int i) { return n[i] == c; },
+ [=](int i) { return n - s + i; });
+# endif
+#endif
+ --n;
while (++n != e)
if (*n == c)
return n - s;
} else {
c = foldCase(c);
+ --n;
while (++n != e)
if (foldCase(*n) == c)
return n - s;
@@ -1014,21 +1342,13 @@ const QString::Null QString::null = { };
int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
{
- int i = 0;
- const ushort *const e = uc + length;
- while (uc < e) {
- uint u = *uc;
- if (QChar::isHighSurrogate(u) && uc + 1 < e) {
- ushort low = uc[1];
- if (QChar::isLowSurrogate(low)) {
- ++uc;
- u = QChar::surrogateToUcs4(u, low);
- }
- }
- out[i++] = u;
- ++uc;
- }
- return i;
+ int count = 0;
+
+ QStringIterator i(reinterpret_cast<const QChar *>(uc), reinterpret_cast<const QChar *>(uc + length));
+ while (i.hasNext())
+ out[count++] = i.next();
+
+ return count;
}
/*! \fn int QString::toWCharArray(wchar_t *array) const
@@ -1463,7 +1783,7 @@ QString &QString::operator=(QChar ch)
*/
QString &QString::insert(int i, QLatin1String str)
{
- const uchar *s = (const uchar *)str.latin1();
+ const char *s = str.latin1();
if (i < 0 || !s || !(*s))
return *this;
@@ -1471,8 +1791,7 @@ QString &QString::insert(int i, QLatin1String str)
expand(qMax(d->size, i) + len - 1);
::memmove(d->data() + i + len, d->data() + i, (d->size - i - len) * sizeof(QChar));
- for (int j = 0; j < len; ++j)
- d->data()[i + j] = s[j];
+ qt_from_latin1(d->data() + i, s, uint(len));
return *this;
}
@@ -1584,14 +1903,14 @@ QString &QString::append(const QChar *str, int len)
*/
QString &QString::append(QLatin1String str)
{
- const uchar *s = (const uchar *)str.latin1();
+ const char *s = str.latin1();
if (s) {
int len = str.size();
if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc)
reallocData(uint(d->size + len) + 1u, true);
ushort *i = d->data() + d->size;
- while ((*i++ = *s++))
- ;
+ qt_from_latin1(i, s, uint(len));
+ i[len] = '\0';
d->size += len;
}
return *this;
@@ -2098,13 +2417,11 @@ QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString &QString::replace(QLatin1String before, QLatin1String after, Qt::CaseSensitivity cs)
{
int alen = after.size();
- QVarLengthArray<ushort> a(alen);
- for (int i = 0; i < alen; ++i)
- a[i] = (uchar)after.latin1()[i];
int blen = before.size();
+ QVarLengthArray<ushort> a(alen);
QVarLengthArray<ushort> b(blen);
- for (int i = 0; i < blen; ++i)
- b[i] = (uchar)before.latin1()[i];
+ qt_from_latin1(a.data(), after.latin1(), alen);
+ qt_from_latin1(b.data(), before.latin1(), blen);
return replace((const QChar *)b.data(), blen, (const QChar *)a.data(), alen, cs);
}
@@ -2124,8 +2441,7 @@ QString &QString::replace(QLatin1String before, const QString &after, Qt::CaseSe
{
int blen = before.size();
QVarLengthArray<ushort> b(blen);
- for (int i = 0; i < blen; ++i)
- b[i] = (uchar)before.latin1()[i];
+ qt_from_latin1(b.data(), before.latin1(), blen);
return replace((const QChar *)b.data(), blen, after.constData(), after.d->size, cs);
}
@@ -2145,8 +2461,7 @@ QString &QString::replace(const QString &before, QLatin1String after, Qt::CaseSe
{
int alen = after.size();
QVarLengthArray<ushort> a(alen);
- for (int i = 0; i < alen; ++i)
- a[i] = (uchar)after.latin1()[i];
+ qt_from_latin1(a.data(), after.latin1(), alen);
return replace(before.constData(), before.d->size, (const QChar *)a.data(), alen, cs);
}
@@ -2166,8 +2481,7 @@ QString &QString::replace(QChar c, QLatin1String after, Qt::CaseSensitivity cs)
{
int alen = after.size();
QVarLengthArray<ushort> a(alen);
- for (int i = 0; i < alen; ++i)
- a[i] = (uchar)after.latin1()[i];
+ qt_from_latin1(a.data(), after.latin1(), alen);
return replace(&c, 1, (const QChar *)a.data(), alen, cs);
}
@@ -2201,17 +2515,7 @@ bool QString::operator==(QLatin1String other) const
if (!other.size())
return isEmpty();
- const ushort *uc = d->data();
- const ushort *e = uc + d->size;
- const uchar *c = (uchar *)other.latin1();
-
- while (uc < e) {
- if (*uc != *c)
- return false;
- ++uc;
- ++c;
- }
- return true;
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) == 0;
}
/*! \fn bool QString::operator==(const QByteArray &other) const
@@ -2265,16 +2569,7 @@ bool QString::operator<(QLatin1String other) const
if (!c || *c == 0)
return false;
- const ushort *uc = d->data();
- const ushort *e = uc + qMin(d->size, other.size());
-
- while (uc < e) {
- if (*uc != *c)
- break;
- ++uc;
- ++c;
- }
- return (uc == e ? d->size < other.size() : *uc < *c);
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) < 0;
}
/*! \fn bool QString::operator<(const QByteArray &other) const
@@ -2367,16 +2662,7 @@ bool QString::operator>(QLatin1String other) const
if (!c || *c == '\0')
return !isEmpty();
- const ushort *uc = d->data();
- const ushort *e = uc + qMin(d->size, other.size());
-
- while (uc < e) {
- if (*uc != *c)
- break;
- ++uc;
- ++c;
- }
- return (uc == e) ? d->size > other.size() : *uc > *c;
+ return compare_helper(data(), size(), other, Qt::CaseSensitive) > 0;
}
/*! \fn bool QString::operator>(const QByteArray &other) const
@@ -2763,8 +3049,7 @@ int QString::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) co
from = delta;
QVarLengthArray<ushort> s(sl);
- for (int i = 0; i < sl; ++i)
- s[i] = str.latin1()[i];
+ qt_from_latin1(s.data(), str.latin1(), sl);
return lastIndexOfHelper(d->data(), from, s.data(), sl, cs);
}
@@ -3172,6 +3457,15 @@ int QString::count(const QStringRef &str, Qt::CaseSensitivity cs) const
\sa indexOf(), count()
*/
+/*! \fn bool QString::contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 5.3
+
+ \overload contains()
+
+ Returns \c true if this string contains an occurrence of the latin-1 string
+ \a str; otherwise returns \c false.
+*/
+
/*! \fn bool QString::contains(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\overload contains()
@@ -3895,131 +4189,58 @@ bool QString::endsWith(QChar c, Qt::CaseSensitivity cs) const
: foldCase(d->data()[d->size - 1]) == foldCase(c.unicode()));
}
-
-#if defined(__SSE2__)
-static inline __m128i mergeQuestionMarks(__m128i chunk)
+QByteArray QString::toLatin1_helper(const QString &string)
{
- const __m128i questionMark = _mm_set1_epi16('?');
-
-# ifdef __SSE4_2__
- // compare the unsigned shorts for the range 0x0100-0xFFFF
- // note on the use of _mm_cmpestrm:
- // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
- // says for range search the following:
- // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
- //
- // However, all examples on the Internet, including from Intel
- // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
- // put the range to be searched first
- //
- // Disassembly and instruction-level debugging with GCC and ICC show
- // that they are doing the right thing. Inverting the arguments in the
- // instruction does cause a bunch of test failures.
-
- const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK;
- const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
- const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode);
-
- // replace the non-Latin 1 characters in the chunk with question marks
- chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
-# else
- // SSE has no compare instruction for unsigned comparison.
- // The variables must be shiffted + 0x8000 to be compared
- const __m128i signedBitOffset = _mm_set1_epi16(short(0x8000));
- const __m128i thresholdMask = _mm_set1_epi16(short(0xff + 0x8000));
-
- const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset);
- const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
+ if (Q_UNLIKELY(string.isNull()))
+ return QByteArray();
-# ifdef __SSE4_1__
- // replace the non-Latin 1 characters in the chunk with question marks
- chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
-# else
- // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
- // the 16 bits that were correct contains zeros
- const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
+ return toLatin1_helper(string.constData(), string.length());
+}
- // correctBytes contains the bytes that were in limit
- // the 16 bits that were off limits contains zeros
- const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk);
+QByteArray QString::toLatin1_helper(const QChar *data, int length)
+{
+ QByteArray ba(length, Qt::Uninitialized);
- // merge offLimitQuestionMark and correctBytes to have the result
- chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
-# endif
-# endif
- return chunk;
+ // since we own the only copy, we're going to const_cast the constData;
+ // that avoids an unnecessary call to detach() and expansion code that will never get used
+ qt_to_latin1(reinterpret_cast<uchar *>(const_cast<char *>(ba.constData())),
+ reinterpret_cast<const ushort *>(data), length);
+ return ba;
}
-#endif
-
-#if defined(__mips_dsp)
-extern "C" void qt_toLatin1_mips_dsp_asm(uchar *dst, const ushort *src, int length);
-#endif
-static QByteArray toLatin1_helper(const QChar *data, int length)
+QByteArray QString::toLatin1_helper_inplace(QString &s)
{
- QByteArray ba;
- if (length) {
- ba.resize(length);
- const ushort *src = reinterpret_cast<const ushort *>(data);
- uchar *dst = (uchar*) ba.data();
-#if defined(__SSE2__)
- if (length >= 16) {
- const int chunkCount = length >> 4; // divided by 16
+ if (!s.isDetached())
+ return s.toLatin1();
- for (int i = 0; i < chunkCount; ++i) {
- __m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load
- chunk1 = mergeQuestionMarks(chunk1);
- src += 8;
+ // We can return our own buffer to the caller.
+ // Conversion to Latin-1 always shrinks the buffer by half.
+ const ushort *data = reinterpret_cast<const ushort *>(s.constData());
+ uint length = s.size();
- __m128i chunk2 = _mm_loadu_si128((__m128i*)src); // load
- chunk2 = mergeQuestionMarks(chunk2);
- src += 8;
+ // Swap the d pointers.
+ // Kids, avert your eyes. Don't try this at home.
+ QArrayData *ba_d = s.d;
- // pack the two vector to 16 x 8bits elements
- const __m128i result = _mm_packus_epi16(chunk1, chunk2);
+ // multiply the allocated capacity by sizeof(ushort)
+ ba_d->alloc *= sizeof(ushort);
- _mm_storeu_si128((__m128i*)dst, result); // store
- dst += 16;
- }
- length = length % 16;
- }
-#elif defined(__ARM_NEON__)
- // Refer to the documentation of the SSE2 implementation
- // this use eactly the same method as for SSE except:
- // 1) neon has unsigned comparison
- // 2) packing is done to 64 bits (8 x 8bits component).
- if (length >= 16) {
- const int chunkCount = length >> 3; // divided by 8
- const uint16x8_t questionMark = vdupq_n_u16('?'); // set
- const uint16x8_t thresholdMask = vdupq_n_u16(0xff); // set
- for (int i = 0; i < chunkCount; ++i) {
- uint16x8_t chunk = vld1q_u16((uint16_t *)src); // load
- src += 8;
-
- const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
- const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
- const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
- chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
- const uint8x8_t result = vmovn_u16(chunk); // narrowing move->packing
- vst1_u8(dst, result); // store
- dst += 8;
- }
- length = length % 8;
- }
-#endif
-#if defined(__mips_dsp)
- qt_toLatin1_mips_dsp_asm(dst, src, length);
-#else
- while (length--) {
- *dst++ = (*src>0xff) ? '?' : (uchar) *src;
- ++src;
- }
-#endif
- }
- return ba;
+ // reset ourselves to QString()
+ s.d = QString().d;
+
+ // do the in-place conversion
+ uchar *dst = reinterpret_cast<uchar *>(ba_d->data());
+ qt_to_latin1(dst, data, length);
+ dst[length] = '\0';
+
+ QByteArrayDataPtr badptr = { ba_d };
+ return QByteArray(badptr);
}
+
/*!
+ \fn QByteArray QString::toLatin1() const
+
Returns a Latin-1 representation of the string as a QByteArray.
The returned byte array is undefined if the string contains non-Latin1
@@ -4028,10 +4249,6 @@ static QByteArray toLatin1_helper(const QChar *data, int length)
\sa fromLatin1(), toUtf8(), toLocal8Bit(), QTextCodec
*/
-QByteArray QString::toLatin1() const
-{
- return toLatin1_helper(unicode(), length());
-}
/*!
\fn QByteArray QString::toAscii() const
@@ -4046,19 +4263,9 @@ QByteArray QString::toLatin1() const
\sa fromAscii(), toLatin1(), toUtf8(), toLocal8Bit(), QTextCodec
*/
-#if !defined(Q_OS_MAC) && defined(Q_OS_UNIX) && !defined(QT_USE_ICU)
-static QByteArray toLocal8Bit_helper(const QChar *data, int length)
-{
-#ifndef QT_NO_TEXTCODEC
- QTextCodec *localeCodec = QTextCodec::codecForLocale();
- if (localeCodec)
- return localeCodec->fromUnicode(data, length);
-#endif // QT_NO_TEXTCODEC
- return toLatin1_helper(data, length);
-}
-#endif
-
/*!
+ \fn QByteArray QString::toLocal8Bit() const
+
Returns the local 8-bit representation of the string as a
QByteArray. The returned byte array is undefined if the string
contains characters not supported by the local 8-bit encoding.
@@ -4073,17 +4280,21 @@ static QByteArray toLocal8Bit_helper(const QChar *data, int length)
\sa fromLocal8Bit(), toLatin1(), toUtf8(), QTextCodec
*/
-QByteArray QString::toLocal8Bit() const
+
+QByteArray QString::toLocal8Bit_helper(const QChar *data, int size)
{
#ifndef QT_NO_TEXTCODEC
QTextCodec *localeCodec = QTextCodec::codecForLocale();
if (localeCodec)
- return localeCodec->fromUnicode(*this);
+ return localeCodec->fromUnicode(data, size);
#endif // QT_NO_TEXTCODEC
- return toLatin1();
+ return toLatin1_helper(data, size);
}
+
/*!
+ \fn QByteArray QString::toUtf8() const
+
Returns a UTF-8 representation of the string as a QByteArray.
UTF-8 is a Unicode codec and can represent all characters in a Unicode
@@ -4099,12 +4310,13 @@ QByteArray QString::toLocal8Bit() const
\sa fromUtf8(), toLatin1(), toLocal8Bit(), QTextCodec
*/
-QByteArray QString::toUtf8() const
+
+QByteArray QString::toUtf8_helper(const QString &str)
{
- if (isNull())
+ if (str.isNull())
return QByteArray();
- return QUtf8::convertFromUnicode(constData(), length(), 0);
+ return QUtf8::convertFromUnicode(str.constData(), str.length());
}
/*!
@@ -4112,8 +4324,12 @@ QByteArray QString::toUtf8() const
Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
- UCS-4 is a Unicode codec and is lossless. All characters from this string
- can be encoded in UCS-4. The vector is not null terminated.
+ UCS-4 is a Unicode codec and therefore it is lossless. All characters from
+ this string will be encoded in UCS-4. Any invalid sequence of code units in
+ this string is replaced by the Unicode's replacement character
+ (QChar::ReplacementCharacter, which corresponds to \c{U+FFFD}).
+
+ The returned vector is not NUL terminated.
\sa fromUtf8(), toUtf8(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray()
*/
@@ -4126,12 +4342,6 @@ QVector<uint> QString::toUcs4() const
return v;
}
-#if defined(__mips_dsp)
-// From qstring_mips_dsp_asm.S
-extern "C" void qt_fromlatin1_mips_asm_unroll4 (ushort*, const char*, uint);
-extern "C" void qt_fromlatin1_mips_asm_unroll8 (ushort*, const char*, uint);
-#endif
-
QString::Data *QString::fromLatin1_helper(const char *str, int size)
{
Data *d;
@@ -4147,40 +4357,8 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
d->size = size;
d->data()[size] = '\0';
ushort *dst = d->data();
- /* SIMD:
- * Unpacking with SSE has been shown to improve performance on recent CPUs
- * The same method gives no improvement with NEON.
- */
-#if defined(__SSE2__)
- if (size >= 16) {
- int chunkCount = size >> 4; // divided by 16
- const __m128i nullMask = _mm_set1_epi32(0);
- for (int i = 0; i < chunkCount; ++i) {
- const __m128i chunk = _mm_loadu_si128((__m128i*)str); // load
- str += 16;
-
- // unpack the first 8 bytes, padding with zeros
- const __m128i firstHalf = _mm_unpacklo_epi8(chunk, nullMask);
- _mm_storeu_si128((__m128i*)dst, firstHalf); // store
- dst += 8;
-
- // unpack the last 8 bytes, padding with zeros
- const __m128i secondHalf = _mm_unpackhi_epi8 (chunk, nullMask);
- _mm_storeu_si128((__m128i*)dst, secondHalf); // store
- dst += 8;
- }
- size = size % 16;
- }
-#endif
-#if defined(__mips_dsp)
- if (size > 20)
- qt_fromlatin1_mips_asm_unroll8(dst, str, size);
- else
- qt_fromlatin1_mips_asm_unroll4(dst, str, size);
-#else
- while (size--)
- *dst++ = (uchar)*str++;
-#endif
+
+ qt_from_latin1(dst, str, uint(size));
}
return d;
}
@@ -4305,7 +4483,7 @@ QString QString::fromUtf8_helper(const char *str, int size)
return QString();
Q_ASSERT(size != -1);
- return QUtf8::convertToUnicode(str, size, 0);
+ return QUtf8::convertToUnicode(str, size);
}
/*!
@@ -5039,22 +5217,7 @@ int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2,
return length1;
if (cs == Qt::CaseSensitive) {
- const ushort *e = uc + length1;
- if (s2.size() < length1)
- e = uc + s2.size();
- while (uc < e) {
- int diff = *uc - *c;
- if (diff)
- return diff;
- uc++, c++;
- }
-
- if (uc == uce) {
- if (c == (const uchar *)s2.latin1() + s2.size())
- return 0;
- return -1;
- }
- return 1;
+ return ucstrcmp(data1, length1, c, s2.size());
} else {
return ucstricmp(uc, uce, c, c + s2.size());
}
@@ -5144,7 +5307,11 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
return ucstrcmp(data1, length1, data2, length2);
#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#ifndef Q_OS_WINRT
int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2);
+#else
+ int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0);
+#endif
switch (res) {
case CSTR_LESS_THAN:
@@ -5553,8 +5720,6 @@ QString &QString::sprintf(const char *cformat, ...)
QString &QString::vsprintf(const char* cformat, va_list ap)
{
- const QLocale locale(QLocale::C);
-
if (!cformat || !*cformat) {
// Qt 1.x compat
*this = fromLatin1("");
@@ -5594,12 +5759,12 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
bool no_more_flags = false;
do {
switch (*c) {
- case '#': flags |= QLocalePrivate::Alternate; break;
- case '0': flags |= QLocalePrivate::ZeroPadded; break;
- case '-': flags |= QLocalePrivate::LeftAdjusted; break;
- case ' ': flags |= QLocalePrivate::BlankBeforePositive; break;
- case '+': flags |= QLocalePrivate::AlwaysShowSign; break;
- case '\'': flags |= QLocalePrivate::ThousandsGroup; break;
+ case '#': flags |= QLocaleData::Alternate; break;
+ case '0': flags |= QLocaleData::ZeroPadded; break;
+ case '-': flags |= QLocaleData::LeftAdjusted; break;
+ case ' ': flags |= QLocaleData::BlankBeforePositive; break;
+ case '+': flags |= QLocaleData::AlwaysShowSign; break;
+ case '\'': flags |= QLocaleData::ThousandsGroup; break;
default: no_more_flags = true; break;
}
@@ -5731,7 +5896,7 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
case lm_t: i = va_arg(ap, int); break;
default: i = 0; break;
}
- subst = locale.d->longLongToString(i, precision, 10, width, flags);
+ subst = QLocaleData::c()->longLongToString(i, precision, 10, width, flags);
++c;
break;
}
@@ -5751,7 +5916,7 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
}
if (qIsUpper(*c))
- flags |= QLocalePrivate::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
int base = 10;
switch (qToLower(*c)) {
@@ -5763,7 +5928,7 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
base = 16; break;
default: break;
}
- subst = locale.d->unsLongLongToString(u, precision, base, width, flags);
+ subst = QLocaleData::c()->unsLongLongToString(u, precision, base, width, flags);
++c;
break;
}
@@ -5782,17 +5947,17 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
d = va_arg(ap, double);
if (qIsUpper(*c))
- flags |= QLocalePrivate::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
switch (qToLower(*c)) {
- case 'e': form = QLocalePrivate::DFExponent; break;
+ case 'e': form = QLocaleData::DFExponent; break;
case 'a': // not supported - decimal form used instead
- case 'f': form = QLocalePrivate::DFDecimal; break;
- case 'g': form = QLocalePrivate::DFSignificantDigits; break;
+ case 'f': form = QLocaleData::DFDecimal; break;
+ case 'g': form = QLocaleData::DFSignificantDigits; break;
default: break;
}
- subst = locale.d->doubleToString(d, precision, form, width, flags);
+ subst = QLocaleData::c()->doubleToString(d, precision, form, width, flags);
++c;
break;
}
@@ -5825,8 +5990,8 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
#else
quint64 i = reinterpret_cast<unsigned long>(arg);
#endif
- flags |= QLocalePrivate::Alternate;
- subst = locale.d->unsLongLongToString(i, precision, 16, width, flags);
+ flags |= QLocaleData::Alternate;
+ subst = QLocaleData::c()->unsLongLongToString(i, precision, 16, width, flags);
++c;
break;
}
@@ -5868,7 +6033,7 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
continue;
}
- if (flags & QLocalePrivate::LeftAdjusted)
+ if (flags & QLocaleData::LeftAdjusted)
result.append(subst.leftJustified(width));
else
result.append(subst.rightJustified(width));
@@ -5903,17 +6068,22 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
qint64 QString::toLongLong(bool *ok, int base) const
{
+ return toIntegral_helper<qlonglong>(constData(), size(), ok, base);
+}
+
+qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int base)
+{
#if defined(QT_CHECK_RANGE)
if (base != 0 && (base < 2 || base > 36)) {
- qWarning("QString::toLongLong: Invalid base (%d)", base);
+ qWarning("QString::toULongLong: Invalid base (%d)", base);
base = 10;
}
#endif
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators);
}
+
/*!
Returns the string converted to an \c{unsigned long long} using base \a
base, which is 10 by default and must be between 2 and 36, or 0.
@@ -5938,6 +6108,11 @@ qint64 QString::toLongLong(bool *ok, int base) const
quint64 QString::toULongLong(bool *ok, int base) const
{
+ return toIntegral_helper<qulonglong>(constData(), size(), ok, base);
+}
+
+qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int base)
+{
#if defined(QT_CHECK_RANGE)
if (base != 0 && (base < 2 || base > 36)) {
qWarning("QString::toULongLong: Invalid base (%d)", base);
@@ -5945,8 +6120,7 @@ quint64 QString::toULongLong(bool *ok, int base) const
}
#endif
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToUnsLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators);
}
/*!
@@ -5975,13 +6149,7 @@ quint64 QString::toULongLong(bool *ok, int base) const
long QString::toLong(bool *ok, int base) const
{
- qint64 v = toLongLong(ok, base);
- if (v < LONG_MIN || v > LONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return (long)v;
+ return toIntegral_helper<long>(constData(), size(), ok, base);
}
/*!
@@ -6010,13 +6178,7 @@ long QString::toLong(bool *ok, int base) const
ulong QString::toULong(bool *ok, int base) const
{
- quint64 v = toULongLong(ok, base);
- if (v > ULONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return (ulong)v;
+ return toIntegral_helper<ulong>(constData(), size(), ok, base);
}
@@ -6044,13 +6206,7 @@ ulong QString::toULong(bool *ok, int base) const
int QString::toInt(bool *ok, int base) const
{
- qint64 v = toLongLong(ok, base);
- if (v < INT_MIN || v > INT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return v;
+ return toIntegral_helper<int>(constData(), size(), ok, base);
}
/*!
@@ -6077,13 +6233,7 @@ int QString::toInt(bool *ok, int base) const
uint QString::toUInt(bool *ok, int base) const
{
- quint64 v = toULongLong(ok, base);
- if (v > UINT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return (uint)v;
+ return toIntegral_helper<uint>(constData(), size(), ok, base);
}
/*!
@@ -6110,13 +6260,7 @@ uint QString::toUInt(bool *ok, int base) const
short QString::toShort(bool *ok, int base) const
{
- long v = toLongLong(ok, base);
- if (v < SHRT_MIN || v > SHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return (short)v;
+ return toIntegral_helper<short>(constData(), size(), ok, base);
}
/*!
@@ -6143,13 +6287,7 @@ short QString::toShort(bool *ok, int base) const
ushort QString::toUShort(bool *ok, int base) const
{
- ulong v = toULongLong(ok, base);
- if (v > USHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return (ushort)v;
+ return toIntegral_helper<ushort>(constData(), size(), ok, base);
}
@@ -6184,8 +6322,7 @@ ushort QString::toUShort(bool *ok, int base) const
double QString::toDouble(bool *ok) const
{
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators);
}
/*!
@@ -6204,27 +6341,9 @@ double QString::toDouble(bool *ok) const
\sa number(), toDouble(), toInt(), QLocale::toFloat()
*/
-#define QT_MAX_FLOAT 3.4028234663852886e+38
-
float QString::toFloat(bool *ok) const
{
- bool myOk;
- double d = toDouble(&myOk);
- if (!myOk) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- if (qIsInf(d))
- return float(d);
- if (d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- if (ok != 0)
- *ok = true;
- return float(d);
+ return QLocaleData::convertDoubleToFloat(toDouble(ok), ok);
}
/*! \fn QString &QString::setNum(int n, int base)
@@ -6268,8 +6387,7 @@ QString &QString::setNum(qlonglong n, int base)
base = 10;
}
#endif
- QLocale locale(QLocale::C);
- *this = locale.d->longLongToString(n, -1, base);
+ *this = QLocaleData::c()->longLongToString(n, -1, base);
return *this;
}
@@ -6284,8 +6402,7 @@ QString &QString::setNum(qulonglong n, int base)
base = 10;
}
#endif
- QLocale locale(QLocale::C);
- *this = locale.d->unsLongLongToString(n, -1, base);
+ *this = QLocaleData::c()->unsLongLongToString(n, -1, base);
return *this;
}
@@ -6317,22 +6434,22 @@ QString &QString::setNum(qulonglong n, int base)
QString &QString::setNum(double n, char f, int prec)
{
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
uint flags = 0;
if (qIsUpper(f))
- flags = QLocalePrivate::CapitalEorX;
+ flags = QLocaleData::CapitalEorX;
f = qToLower(f);
switch (f) {
case 'f':
- form = QLocalePrivate::DFDecimal;
+ form = QLocaleData::DFDecimal;
break;
case 'e':
- form = QLocalePrivate::DFExponent;
+ form = QLocaleData::DFExponent;
break;
case 'g':
- form = QLocalePrivate::DFSignificantDigits;
+ form = QLocaleData::DFSignificantDigits;
break;
default:
#if defined(QT_CHECK_RANGE)
@@ -6341,8 +6458,7 @@ QString &QString::setNum(double n, char f, int prec)
break;
}
- QLocale locale(QLocale::C);
- *this = locale.d->doubleToString(n, prec, form, -1, flags);
+ *this = QLocaleData::c()->doubleToString(n, prec, form, -1, flags);
return *this;
}
@@ -7140,20 +7256,20 @@ QString QString::arg(qlonglong a, int fieldWidth, int base, QChar fillChar) cons
return *this;
}
- unsigned flags = QLocalePrivate::NoFlags;
+ unsigned flags = QLocaleData::NoFlags;
if (fillChar == QLatin1Char('0'))
- flags = QLocalePrivate::ZeroPadded;
+ flags = QLocaleData::ZeroPadded;
QString arg;
if (d.occurrences > d.locale_occurrences)
- arg = QLocale::c().d->longLongToString(a, -1, base, fieldWidth, flags);
+ arg = QLocaleData::c()->longLongToString(a, -1, base, fieldWidth, flags);
QString locale_arg;
if (d.locale_occurrences > 0) {
QLocale locale;
if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
- flags |= QLocalePrivate::ThousandsGroup;
- locale_arg = locale.d->longLongToString(a, -1, base, fieldWidth, flags);
+ flags |= QLocaleData::ThousandsGroup;
+ locale_arg = locale.d->m_data->longLongToString(a, -1, base, fieldWidth, flags);
}
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
@@ -7184,20 +7300,20 @@ QString QString::arg(qulonglong a, int fieldWidth, int base, QChar fillChar) con
return *this;
}
- unsigned flags = QLocalePrivate::NoFlags;
+ unsigned flags = QLocaleData::NoFlags;
if (fillChar == QLatin1Char('0'))
- flags = QLocalePrivate::ZeroPadded;
+ flags = QLocaleData::ZeroPadded;
QString arg;
if (d.occurrences > d.locale_occurrences)
- arg = QLocale::c().d->unsLongLongToString(a, -1, base, fieldWidth, flags);
+ arg = QLocaleData::c()->unsLongLongToString(a, -1, base, fieldWidth, flags);
QString locale_arg;
if (d.locale_occurrences > 0) {
QLocale locale;
if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
- flags |= QLocalePrivate::ThousandsGroup;
- locale_arg = locale.d->unsLongLongToString(a, -1, base, fieldWidth, flags);
+ flags |= QLocaleData::ThousandsGroup;
+ locale_arg = locale.d->m_data->unsLongLongToString(a, -1, base, fieldWidth, flags);
}
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
@@ -7296,24 +7412,24 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
return *this;
}
- unsigned flags = QLocalePrivate::NoFlags;
+ unsigned flags = QLocaleData::NoFlags;
if (fillChar == QLatin1Char('0'))
- flags = QLocalePrivate::ZeroPadded;
+ flags = QLocaleData::ZeroPadded;
if (qIsUpper(fmt))
- flags |= QLocalePrivate::CapitalEorX;
+ flags |= QLocaleData::CapitalEorX;
fmt = qToLower(fmt);
- QLocalePrivate::DoubleForm form = QLocalePrivate::DFDecimal;
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
switch (fmt) {
case 'f':
- form = QLocalePrivate::DFDecimal;
+ form = QLocaleData::DFDecimal;
break;
case 'e':
- form = QLocalePrivate::DFExponent;
+ form = QLocaleData::DFExponent;
break;
case 'g':
- form = QLocalePrivate::DFSignificantDigits;
+ form = QLocaleData::DFSignificantDigits;
break;
default:
#if defined(QT_CHECK_RANGE)
@@ -7324,15 +7440,15 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha
QString arg;
if (d.occurrences > d.locale_occurrences)
- arg = QLocale::c().d->doubleToString(a, prec, form, fieldWidth, flags);
+ arg = QLocaleData::c()->doubleToString(a, prec, form, fieldWidth, flags);
QString locale_arg;
if (d.locale_occurrences > 0) {
QLocale locale;
if (!(locale.numberOptions() & QLocale::OmitGroupSeparator))
- flags |= QLocalePrivate::ThousandsGroup;
- locale_arg = locale.d->doubleToString(a, prec, form, fieldWidth, flags);
+ flags |= QLocaleData::ThousandsGroup;
+ locale_arg = locale.d->m_data->doubleToString(a, prec, form, fieldWidth, flags);
}
return replaceArgEscapes(*this, d, fieldWidth, arg, locale_arg, fillChar);
@@ -8254,19 +8370,10 @@ bool operator==(QLatin1String s1, const QStringRef &s2)
if (s1.size() != s2.size())
return false;
- const ushort *uc = reinterpret_cast<const ushort *>(s2.unicode());
- const ushort *e = uc + s2.size();
const uchar *c = reinterpret_cast<const uchar *>(s1.latin1());
if (!c)
return s2.isEmpty();
-
- while (*c) {
- if (uc == e || *uc != *c)
- return false;
- ++uc;
- ++c;
- }
- return (uc == e);
+ return ucstrncmp(s2.unicode(), c, s2.size()) == 0;
}
/*!
@@ -8854,8 +8961,7 @@ int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs)
from = delta;
QVarLengthArray<ushort> s(sl);
- for (int i = 0; i < sl; ++i)
- s[i] = str.latin1()[i];
+ qt_from_latin1(s.data(), str.latin1(), sl);
return lastIndexOfHelper(reinterpret_cast<const ushort*>(unicode()), from, s.data(), sl, cs);
}
@@ -9193,8 +9299,7 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size,
const char *latin1 = needle.latin1();
int len = needle.size();
QVarLengthArray<ushort> s(len);
- for (int i = 0; i < len; ++i)
- s[i] = latin1[i];
+ qt_from_latin1(s.data(), latin1, len);
return qFindString(haystack, size, from,
reinterpret_cast<const QChar*>(s.constData()), len, cs);
@@ -9238,9 +9343,7 @@ static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
const ushort *data = reinterpret_cast<const ushort*>(haystack);
const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; ++i)
- if (data[i] != latin[i])
- return false;
+ return ucstrncmp(haystack, latin, slen) == 0;
} else {
for (int i = 0; i < slen; ++i)
if (foldCase(data[i]) != foldCase((ushort)latin[i]))
@@ -9290,9 +9393,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
const uchar *latin = reinterpret_cast<const uchar*>(needle.latin1());
const ushort *data = reinterpret_cast<const ushort*>(haystack);
if (cs == Qt::CaseSensitive) {
- for (int i = 0; i < slen; i++)
- if (data[pos+i] != latin[i])
- return false;
+ return ucstrncmp(haystack + pos, latin, slen) == 0;
} else {
for (int i = 0; i < slen; i++)
if (foldCase(data[pos+i]) != foldCase((ushort)latin[i]))
@@ -9314,7 +9415,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
*/
QByteArray QStringRef::toLatin1() const
{
- return toLatin1_helper(unicode(), length());
+ return QString::toLatin1_helper(unicode(), length());
}
/*!
@@ -9390,8 +9491,12 @@ QByteArray QStringRef::toUtf8() const
Returns a UCS-4/UTF-32 representation of the string as a QVector<uint>.
- UCS-4 is a Unicode codec and is lossless. All characters from this string
- can be encoded in UCS-4.
+ UCS-4 is a Unicode codec and therefore it is lossless. All characters from
+ this string will be encoded in UCS-4. Any invalid sequence of code units in
+ this string is replaced by the Unicode's replacement character
+ (QChar::ReplacementCharacter, which corresponds to \c{U+FFFD}).
+
+ The returned vector is not NUL terminated.
\sa toUtf8(), toLatin1(), toLocal8Bit(), QTextCodec
*/
@@ -9458,15 +9563,7 @@ QStringRef QStringRef::trimmed() const
qint64 QStringRef::toLongLong(bool *ok, int base) const
{
-#if defined(QT_CHECK_RANGE)
- if (base != 0 && (base < 2 || base > 36)) {
- qWarning("QString::toLongLong: Invalid base (%d)", base);
- base = 10;
- }
-#endif
-
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QString::toIntegral_helper<qint64>(constData(), size(), ok, base);
}
/*!
@@ -9491,15 +9588,7 @@ qint64 QStringRef::toLongLong(bool *ok, int base) const
quint64 QStringRef::toULongLong(bool *ok, int base) const
{
-#if defined(QT_CHECK_RANGE)
- if (base != 0 && (base < 2 || base > 36)) {
- qWarning("QString::toULongLong: Invalid base (%d)", base);
- base = 10;
- }
-#endif
-
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToUnsLongLong(*this, base, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QString::toIntegral_helper<quint64>(constData(), size(), ok, base);
}
/*!
@@ -9526,13 +9615,7 @@ quint64 QStringRef::toULongLong(bool *ok, int base) const
long QStringRef::toLong(bool *ok, int base) const
{
- qint64 v = toLongLong(ok, base);
- if (v < LONG_MIN || v > LONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return long(v);
+ return QString::toIntegral_helper<long>(constData(), size(), ok, base);
}
/*!
@@ -9559,13 +9642,7 @@ long QStringRef::toLong(bool *ok, int base) const
ulong QStringRef::toULong(bool *ok, int base) const
{
- quint64 v = toULongLong(ok, base);
- if (v > ULONG_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return ulong(v);
+ return QString::toIntegral_helper<ulong>(constData(), size(), ok, base);
}
@@ -9591,13 +9668,7 @@ ulong QStringRef::toULong(bool *ok, int base) const
int QStringRef::toInt(bool *ok, int base) const
{
- qint64 v = toLongLong(ok, base);
- if (v < INT_MIN || v > INT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return int(v);
+ return QString::toIntegral_helper<int>(constData(), size(), ok, base);
}
/*!
@@ -9622,13 +9693,7 @@ int QStringRef::toInt(bool *ok, int base) const
uint QStringRef::toUInt(bool *ok, int base) const
{
- quint64 v = toULongLong(ok, base);
- if (v > UINT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return uint(v);
+ return QString::toIntegral_helper<uint>(constData(), size(), ok, base);
}
/*!
@@ -9653,13 +9718,7 @@ uint QStringRef::toUInt(bool *ok, int base) const
short QStringRef::toShort(bool *ok, int base) const
{
- long v = toLongLong(ok, base);
- if (v < SHRT_MIN || v > SHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return short(v);
+ return QString::toIntegral_helper<short>(constData(), size(), ok, base);
}
/*!
@@ -9684,13 +9743,7 @@ short QStringRef::toShort(bool *ok, int base) const
ushort QStringRef::toUShort(bool *ok, int base) const
{
- ulong v = toULongLong(ok, base);
- if (v > USHRT_MAX) {
- if (ok)
- *ok = false;
- v = 0;
- }
- return ushort(v);
+ return QString::toIntegral_helper<ushort>(constData(), size(), ok, base);
}
@@ -9716,8 +9769,7 @@ ushort QStringRef::toUShort(bool *ok, int base) const
double QStringRef::toDouble(bool *ok) const
{
- QLocale c_locale(QLocale::C);
- return c_locale.d->stringToDouble(*this, ok, QLocalePrivate::FailOnGroupSeparators);
+ return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators);
}
/*!
@@ -9736,23 +9788,7 @@ double QStringRef::toDouble(bool *ok) const
float QStringRef::toFloat(bool *ok) const
{
- bool myOk;
- double d = toDouble(&myOk);
- if (!myOk) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- if (qIsInf(d))
- return float(d);
- if (d > QT_MAX_FLOAT || d < -QT_MAX_FLOAT) {
- if (ok != 0)
- *ok = false;
- return 0.0;
- }
- if (ok)
- *ok = true;
- return float(d);
+ return QLocaleData::convertDoubleToFloat(toDouble(ok), ok);
}
/*!
@@ -9848,4 +9884,13 @@ QString QString::toHtmlEscaped() const
\endlist
*/
+
+/*!
+ \internal
+ */
+void QAbstractConcatenable::appendLatin1To(const char *a, int len, QChar *out)
+{
+ qt_from_latin1(reinterpret_cast<ushort *>(out), a, uint(len));
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 9778d42c1d..9063f59171 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -316,6 +316,7 @@ public:
inline bool contains(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline bool contains(QLatin1String s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
inline bool contains(const QStringRef &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
int count(const QString &s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
@@ -460,9 +461,24 @@ public:
const ushort *utf16() const;
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP)
+ QByteArray toLatin1() const & Q_REQUIRED_RESULT
+ { return toLatin1_helper(*this); }
+ QByteArray toLatin1() && Q_REQUIRED_RESULT
+ { return toLatin1_helper_inplace(*this); }
+ QByteArray toUtf8() const & Q_REQUIRED_RESULT
+ { return toUtf8_helper(*this); }
+ QByteArray toUtf8() && Q_REQUIRED_RESULT
+ { return toUtf8_helper(*this); }
+ QByteArray toLocal8Bit() const & Q_REQUIRED_RESULT
+ { return toLocal8Bit_helper(constData(), size()); }
+ QByteArray toLocal8Bit() && Q_REQUIRED_RESULT
+ { return toLocal8Bit_helper(constData(), size()); }
+#else
QByteArray toLatin1() const Q_REQUIRED_RESULT;
QByteArray toUtf8() const Q_REQUIRED_RESULT;
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT;
+#endif
QVector<uint> toUcs4() const Q_REQUIRED_RESULT;
// note - this are all inline so we can benefit from strlen() compile time optimizations
@@ -489,6 +505,13 @@ public:
static QString fromUcs4(const uint *, int size = -1);
static QString fromRawData(const QChar *, int size);
+#if defined(Q_COMPILER_UNICODE_STRINGS)
+ static QString fromUtf16(const char16_t *str, int size = -1)
+ { return fromUtf16(reinterpret_cast<const ushort *>(str), size); }
+ static QString fromUcs4(const char32_t *str, int size = -1)
+ { return fromUcs4(reinterpret_cast<const uint *>(str), size); }
+#endif
+
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED static inline QString fromAscii(const char *str, int size = -1)
{ return fromLatin1(str, size); }
@@ -529,6 +552,7 @@ public:
int localeAwareCompare(const QStringRef &s) const;
static int localeAwareCompare(const QString& s1, const QStringRef& s2);
+ // ### Qt6: make inline except for the long long versions
short toShort(bool *ok=0, int base=10) const;
ushort toUShort(bool *ok=0, int base=10) const;
int toInt(bool *ok=0, int base=10) const;
@@ -717,7 +741,14 @@ private:
static Data *fromAscii_helper(const char *str, int size = -1);
static QString fromUtf8_helper(const char *str, int size);
static QString fromLocal8Bit_helper(const char *, int size);
+ static QByteArray toLatin1_helper(const QString &);
+ static QByteArray toLatin1_helper(const QChar *data, int size);
+ static QByteArray toLatin1_helper_inplace(QString &);
+ static QByteArray toUtf8_helper(const QString &);
+ static QByteArray toLocal8Bit_helper(const QChar *data, int size);
static int toUcs4_helper(const ushort *uc, int length, uint *out);
+ static qlonglong toIntegral_helper(const QChar *data, int len, bool *ok, int base);
+ static qulonglong toIntegral_helper(const QChar *data, uint len, bool *ok, int base);
void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
friend class QCharRef;
friend class QTextCodec;
@@ -726,6 +757,24 @@ private:
friend class QCollator;
friend struct QAbstractConcatenable;
+ template <typename T> static
+ T toIntegral_helper(const QChar *data, int len, bool *ok, int base)
+ {
+ // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type
+ const bool isUnsigned = T(0) < T(-1);
+ typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;
+ typedef typename QtPrivate::QConditional<isUnsigned, uint, int>::Type Int32;
+
+ // we select the right overload by casting size() to int or uint
+ Int64 val = toIntegral_helper(data, Int32(len), ok, base);
+ if (T(val) != val) {
+ if (ok)
+ *ok = false;
+ val = 0;
+ }
+ return T(val);
+ }
+
public:
typedef Data * DataPtr;
inline DataPtr &data_ptr() { return d; }
@@ -887,7 +936,17 @@ public:
QChar::Category category() const { return QChar(*this).category(); }
QChar::Direction direction() const { return QChar(*this).direction(); }
- QChar::Joining joining() const { return QChar(*this).joining(); }
+ QChar::JoiningType joiningType() const { return QChar(*this).joiningType(); }
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED QChar::Joining joining() const {
+ switch (QChar(*this).joiningType()) {
+ case QChar::Joining_Causing: return QChar::Center;
+ case QChar::Joining_Dual: return QChar::Dual;
+ case QChar::Joining_Right: return QChar::Right;
+ default: return QChar::OtherJoining;
+ }
+ }
+#endif
bool hasMirrored() const { return QChar(*this).hasMirrored(); }
QChar mirroredChar() const { return QChar(*this).mirroredChar(); }
QString decomposition() const { return QChar(*this).decomposition(); }
@@ -969,6 +1028,8 @@ inline bool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
{ return indexOf(s, 0, cs) != -1; }
+inline bool QString::contains(QLatin1String s, Qt::CaseSensitivity cs) const
+{ return indexOf(s, 0, cs) != -1; }
inline bool QString::contains(QChar c, Qt::CaseSensitivity cs) const
{ return indexOf(c, 0, cs) != -1; }
diff --git a/src/corelib/tools/qstring_compat.cpp b/src/corelib/tools/qstring_compat.cpp
new file mode 100644
index 0000000000..6613dfde8e
--- /dev/null
+++ b/src/corelib/tools/qstring_compat.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if defined(QSTRING_H)
+# error "This file cannot be compiled with pre-compiled headers"
+#endif
+#define QT_COMPILING_QSTRING_COMPAT_CPP
+
+#include "qstring.h"
+
+QT_BEGIN_NAMESPACE
+
+// all these implementations must be the same as the inline versions in qstring.h
+QByteArray QString::toLatin1() const
+{
+ return toLatin1_helper(*this);
+}
+
+QByteArray QString::toLocal8Bit() const
+{
+ return toLocal8Bit_helper(constData(), size());
+}
+
+QByteArray QString::toUtf8() const
+{
+ return toUtf8_helper(*this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index e09b02b5a9..f0670999d7 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -65,6 +65,7 @@ protected:
{
*out++ = QLatin1Char(a);
}
+ static void appendLatin1To(const char *a, int len, QChar *out);
};
template <typename T> struct QConcatenable {};
@@ -112,7 +113,9 @@ private:
const uint len = QConcatenable< QStringBuilder<A, B> >::size(*this);
T s(len, Qt::Uninitialized);
- typename T::iterator d = s.data();
+ // we abuse const_cast / constData here because we know we've just
+ // allocated the data and we're the only reference count
+ typename T::iterator d = const_cast<typename T::iterator>(s.constData());
typename T::const_iterator const start = d;
QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
@@ -220,7 +223,7 @@ template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable
{ *out++ = QChar(c); }
};
-template <> struct QConcatenable<QLatin1String>
+template <> struct QConcatenable<QLatin1String> : private QAbstractConcatenable
{
typedef QLatin1String type;
typedef QString ConvertTo;
@@ -228,10 +231,8 @@ template <> struct QConcatenable<QLatin1String>
static int size(const QLatin1String a) { return a.size(); }
static inline void appendTo(const QLatin1String a, QChar *&out)
{
- if (a.data()) {
- for (const char *s = a.data(); *s; )
- *out++ = QLatin1Char(*s++);
- }
+ appendLatin1To(a.latin1(), a.size(), out);
+ out += a.size();
}
static inline void appendTo(const QLatin1String a, char *&out)
{
diff --git a/src/corelib/tools/qstringiterator.qdoc b/src/corelib/tools/qstringiterator.qdoc
new file mode 100644
index 0000000000..510d5fbccf
--- /dev/null
+++ b/src/corelib/tools/qstringiterator.qdoc
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QStringIterator
+ \since 5.3
+ \inmodule QtCore
+ \ingroup tools
+
+ \internal
+
+ \brief The QStringIterator class provides a Unicode-aware iterator over QString.
+
+ \reentrant
+
+ QStringIterator is a Java-like, bidirectional, const iterator over the contents of a
+ QString. Unlike QString's own iterators, which manage the individual UTF-16 code units,
+ QStringIterator is Unicode-aware: it will transparently handle the \e{surrogate pairs}
+ that may be present in a QString, and return the individual Unicode code points.
+
+ You can create a QStringIterator that iterates over a given
+ QString by passing the string to the QStringIterator's constructor:
+
+ \snippet code/src_corelib_tools_qstringiterator.cpp 0
+
+ A newly created QStringIterator will point before the first position in the
+ string. It is possible to check whether the iterator can be advanced by
+ calling hasNext(), and actually advance it (and obtain the next code point)
+ by calling next():
+
+ \snippet code/src_corelib_tools_qstringiterator.cpp 1
+
+ Similarly, the hasPrevious() and previous() functions can be used to iterate backwards.
+
+ The peekNext() and peekPrevious() functions will return the code point
+ respectively after and behind the iterator's current position, but unlike
+ next() and previous() they will not move the iterator.
+ Similarly, the advance() and recede() functions will move the iterator
+ respectively after and behind the iterator's current position, but they
+ will not return the code point the iterator has moved through.
+
+ \section1 Unicode handling
+
+ QString and all of its functions work in terms of UTF-16 code units. Unicode code points
+ that fall outside the Basic Multilingual Plane (U+10000 to U+10FFFF) will therefore
+ be represented by \e{surrogate pairs} in a QString, that is, a sequence of two
+ UTF-16 code units that encode a single code point.
+
+ QStringIterator will automatically handle surrogate pairs inside a QString,
+ and return the correctly decoded code point, while also moving the iterator by
+ the right amount of code units to match the decoded code points.
+
+ For instance:
+
+ \snippet code/src_corelib_tools_qstringiterator.cpp 2
+
+ If the iterator is not able to decode the next code point (or the previous
+ one, when iterating backwards), then it will return \c{0xFFFD}, that is,
+ Unicode's replacement character (see QChar::ReplacementCharacter).
+ It is possible to make QStringIterator return another value when it encounters
+ a decoding problem; please refer to the each function documentation for
+ more details.
+
+ \section1 Unchecked iteration
+
+ It is possible to optimize iterating over a QString contents by skipping
+ some checks. This is in general not safe to do, because a QString is allowed
+ to contain malformed UTF-16 data; however, if we can trust a given QString,
+ then we can use the optimized \e{unchecked} functions.
+
+ QStringIterator provides the \e{unchecked} counterparts for next(),
+ peekNext(), advance(), previous(), peekPrevious(), and recede():
+ they're called, respectively,
+ nextUnchecked(), peekNextUnchecked(), advanceUnchecked(),
+ previousUnchecked(), peekPreviousUnchecked(), recedeUnchecked().
+ The counterparts work exactly like the original ones,
+ but they're faster as they're allowed to make certain assumptions about
+ the string contents.
+
+ \note please be extremely careful when using QStringIterator's unchecked functions,
+ as using them on a string containing malformed data leads to undefined behavior.
+
+ \sa QString, QChar
+*/
+
+/*!
+ \fn QStringIterator::QStringIterator(const QString &string)
+
+ Constructs an iterator over the contents of \a string. The iterator will point
+ before the first position in the string.
+
+ The string \a string must remain valid while the iterator is being used.
+*/
+
+/*!
+ \fn QStringIterator::QStringIterator(const QChar *begin, const QChar *end)
+
+ Constructs an iterator which iterates over the range from \a begin to \a end.
+ The iterator will point before \a begin.
+
+ The range from \a begin to \a end must remain valid while the iterator is being used.
+*/
+
+/*!
+ \fn QString::const_iterator QStringIterator::position() const
+
+ Returns the current position of the iterator.
+*/
+
+/*!
+ \fn void QStringIterator::setPosition(QString::const_iterator position)
+
+ Sets the iterator's current position to \a position, which must be inside
+ of the iterable range.
+*/
+
+/*!
+ \fn bool QStringIterator::hasNext() const
+
+ Returns true if the iterator has not reached the end of the valid iterable range
+ and therefore can move forward; false otherwise.
+
+ \sa next()
+*/
+
+/*!
+ \fn void QStringIterator::advance()
+
+ Advances the iterator by one Unicode code point.
+
+ \note calling this function when the iterator is past the end of the iterable range
+ leads to undefined behavior.
+
+ \sa next(), hasNext()
+*/
+
+/*!
+ \fn void QStringIterator::advanceUnchecked()
+
+ Advances the iterator by one Unicode code point.
+
+ \note calling this function when the iterator is past the end of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa advance(), next(), hasNext()
+*/
+
+/*!
+ \fn uint QStringIterator::peekNextUnchecked() const
+
+ Returns the Unicode code point that is immediately after the iterator's current
+ position. The current position is not changed.
+
+ \note calling this function when the iterator is past the end of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa peekNext(), next(), hasNext()
+*/
+
+/*!
+ \fn uint QStringIterator::peekNext(uint invalidAs = QChar::ReplacementCharacter) const
+
+ Returns the Unicode code point that is immediately after the iterator's current
+ position. The current position is not changed.
+
+ If the iterator is not able to decode the UTF-16 data after the iterator's current
+ position, this function returns \a invalidAs (by default, QChar::ReplacementCharacter,
+ which corresponds to \c{U+FFFD}).
+
+ \note calling this function when the iterator is past the end of the iterable range
+ leads to undefined behavior.
+
+ \sa next(), hasNext()
+*/
+
+/*!
+ \fn uint QStringIterator::nextUnchecked()
+
+ Advances the iterator's current position by one Unicode code point,
+ and returns the Unicode code point that gets pointed by the iterator.
+
+ \note calling this function when the iterator is past the end of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa next(), hasNext()
+*/
+
+/*!
+ \fn uint QStringIterator::next(uint invalidAs = QChar::ReplacementCharacter)
+
+ Advances the iterator's current position by one Unicode code point,
+ and returns the Unicode code point that gets pointed by the iterator.
+
+ If the iterator is not able to decode the UTF-16 data at the iterator's current
+ position, this function returns \a invalidAs (by default, QChar::ReplacementCharacter,
+ which corresponds to \c{U+FFFD}).
+
+ \note calling this function when the iterator is past the end of the iterable range
+ leads to undefined behavior.
+
+ \sa peekNext(), hasNext()
+*/
+
+
+/*!
+ \fn bool QStringIterator::hasPrevious() const
+
+ Returns true if the iterator is after the beginning of the valid iterable range
+ and therefore can move backwards; false otherwise.
+
+ \sa previous()
+*/
+
+/*!
+ \fn void QStringIterator::recede()
+
+ Moves the iterator back by one Unicode code point.
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ leads to undefined behavior.
+
+ \sa previous(), hasPrevious()
+*/
+
+/*!
+ \fn void QStringIterator::recedeUnchecked()
+
+ Moves the iterator back by one Unicode code point.
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa recede(), previous(), hasPrevious()
+*/
+
+/*!
+ \fn uint QStringIterator::peekPreviousUnchecked() const
+
+ Returns the Unicode code point that is immediately before the iterator's current
+ position. The current position is not changed.
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa previous(), hasPrevious()
+*/
+
+/*!
+ \fn uint QStringIterator::peekPrevious(uint invalidAs = QChar::ReplacementCharacter) const
+
+ Returns the Unicode code point that is immediately before the iterator's current
+ position. The current position is not changed.
+
+ If the iterator is not able to decode the UTF-16 data before the iterator's current
+ position, this function returns \a invalidAs (by default, QChar::ReplacementCharacter,
+ which corresponds to \c{U+FFFD}).
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ leads to undefined behavior.
+
+ \sa previous(), hasPrevious()
+*/
+
+/*!
+ \fn uint QStringIterator::previousUnchecked()
+
+ Moves the iterator's current position back by one Unicode code point,
+ and returns the Unicode code point that gets pointed by the iterator.
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ or on a QString containing malformed UTF-16 data leads to undefined behavior.
+
+ \sa previous(), hasPrevious()
+*/
+
+/*!
+ \fn uint QStringIterator::previous(uint invalidAs = QChar::ReplacementCharacter)
+
+ Moves the iterator's current position back by one Unicode code point,
+ and returns the Unicode code point that gets pointed by the iterator.
+
+ If the iterator is not able to decode the UTF-16 data at the iterator's current
+ position, this function returns \a invalidAs (by default, QChar::ReplacementCharacter,
+ which corresponds to \c{U+FFFD}).
+
+ \note calling this function when the iterator is before the beginning of the iterable range
+ leads to undefined behavior.
+
+ \sa peekPrevious(), hasPrevious()
+*/
diff --git a/src/corelib/tools/qstringiterator_p.h b/src/corelib/tools/qstringiterator_p.h
new file mode 100644
index 0000000000..c3986f0477
--- /dev/null
+++ b/src/corelib/tools/qstringiterator_p.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSTRINGITERATOR_H
+#define QSTRINGITERATOR_H
+
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+class QStringIterator
+{
+ QString::const_iterator i, pos, e;
+
+public:
+ inline explicit QStringIterator(const QString &string)
+ : i(string.constBegin()),
+ pos(string.constBegin()),
+ e(string.constEnd())
+ {
+ }
+
+ inline explicit QStringIterator(const QChar *begin, const QChar *end)
+ : i(begin),
+ pos(begin),
+ e(end)
+ {
+ }
+
+ inline QString::const_iterator position() const
+ {
+ return pos;
+ }
+
+ inline void setPosition(QString::const_iterator position)
+ {
+ Q_ASSERT_X(i <= position && position <= e, Q_FUNC_INFO, "position out of bounds");
+ pos = position;
+ }
+
+ // forward iteration
+
+ inline bool hasNext() const
+ {
+ return pos < e;
+ }
+
+ inline void advance()
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ if (Q_UNLIKELY((pos++)->isHighSurrogate())) {
+ if (Q_LIKELY(pos != e && pos->isLowSurrogate()))
+ ++pos;
+ }
+ }
+
+ inline void advanceUnchecked()
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ if (Q_UNLIKELY((pos++)->isHighSurrogate()))
+ ++pos;
+ }
+
+ inline uint peekNextUnchecked() const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ if (Q_UNLIKELY(pos->isHighSurrogate()))
+ return QChar::surrogateToUcs4(pos[0], pos[1]);
+
+ return pos->unicode();
+ }
+
+ inline uint peekNext(uint invalidAs = QChar::ReplacementCharacter) const
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ if (Q_UNLIKELY(pos->isSurrogate())) {
+ if (Q_LIKELY(pos->isHighSurrogate())) {
+ const QChar *low = pos + 1;
+ if (Q_LIKELY(low != e && low->isLowSurrogate()))
+ return QChar::surrogateToUcs4(*pos, *low);
+ }
+ return invalidAs;
+ }
+
+ return pos->unicode();
+ }
+
+ inline uint nextUnchecked()
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar cur = *pos++;
+ if (Q_UNLIKELY(cur.isHighSurrogate()))
+ return QChar::surrogateToUcs4(cur, *pos++);
+ return cur.unicode();
+ }
+
+ inline uint next(uint invalidAs = QChar::ReplacementCharacter)
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar uc = *pos++;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+ if (Q_LIKELY(uc.isHighSurrogate() && pos < e && pos->isLowSurrogate()))
+ return QChar::surrogateToUcs4(uc, *pos++);
+ return invalidAs;
+ }
+
+ return uc.unicode();
+ }
+
+ // backwards iteration
+
+ inline bool hasPrevious() const
+ {
+ return pos > i;
+ }
+
+ inline void recede()
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ if (Q_UNLIKELY((--pos)->isLowSurrogate())) {
+ const QChar *high = pos - 1;
+ if (Q_LIKELY(high != i - 1 && high->isHighSurrogate()))
+ --pos;
+ }
+ }
+
+ inline void recedeUnchecked()
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ if (Q_UNLIKELY((--pos)->isLowSurrogate()))
+ --pos;
+ }
+
+ inline uint peekPreviousUnchecked() const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ if (Q_UNLIKELY(pos[-1].isLowSurrogate()))
+ return QChar::surrogateToUcs4(pos[-2], pos[-1]);
+ return pos[-1].unicode();
+ }
+
+ inline uint peekPrevious(uint invalidAs = QChar::ReplacementCharacter) const
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ if (Q_UNLIKELY(pos[-1].isSurrogate())) {
+ if (Q_LIKELY(pos[-1].isLowSurrogate())) {
+ const QChar *high = pos - 2;
+ if (Q_LIKELY(high != i - 1 && high->isHighSurrogate()))
+ return QChar::surrogateToUcs4(*high, pos[-1]);
+ }
+ return invalidAs;
+ }
+
+ return pos[-1].unicode();
+ }
+
+ inline uint previousUnchecked()
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar cur = *--pos;
+ if (Q_UNLIKELY(cur.isLowSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, cur);
+ return cur.unicode();
+ }
+
+ inline uint previous(uint invalidAs = QChar::ReplacementCharacter)
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar uc = *--pos;
+ if (Q_UNLIKELY(uc.isSurrogate())) {
+ if (Q_LIKELY(uc.isLowSurrogate() && pos > i && pos[-1].isHighSurrogate()))
+ return QChar::surrogateToUcs4(*--pos, uc);
+ return invalidAs;
+ }
+
+ return uc.unicode();
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QSTRINGITERATOR_H
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index 46997b731c..6b0b39c7bb 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -455,7 +455,7 @@ QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, i
QString res;
if (totalLength == 0)
- return res;
+ return res;
res.reserve(totalLength);
for (int i = 0; i < that->size(); ++i) {
if (i)
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index a8ed8739c3..b30caf4289 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -65,7 +65,8 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QMacTimeZonePrivate();
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate();
-#elif defined Q_OS_WIN
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
return new QWinTimeZonePrivate();
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate();
@@ -76,25 +77,26 @@ static QTimeZonePrivate *newBackendTimeZone()
}
// Create named time zone using appropriate backend
-static QTimeZonePrivate *newBackendTimeZone(const QByteArray &olsenId)
+static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
{
#ifdef QT_NO_SYSTEMLOCALE
#ifdef QT_USE_ICU
- return new QIcuTimeZonePrivate(olsenId);
+ return new QIcuTimeZonePrivate(ianaId);
#else
- return new QUtcTimeZonePrivate(olsenId);
+ return new QUtcTimeZonePrivate(ianaId);
#endif // QT_USE_ICU
#else
#if defined Q_OS_MAC
- return new QMacTimeZonePrivate(olsenId);
+ return new QMacTimeZonePrivate(ianaId);
#elif defined Q_OS_UNIX
- return new QTzTimeZonePrivate(olsenId);
-#elif defined Q_OS_WIN
- return new QWinTimeZonePrivate(olsenId);
+ return new QTzTimeZonePrivate(ianaId);
+ // Registry based timezone backend not available on WinRT
+#elif defined Q_OS_WIN && !defined Q_OS_WINRT
+ return new QWinTimeZonePrivate(ianaId);
#elif defined QT_USE_ICU
- return new QIcuTimeZonePrivate(olsenId);
+ return new QIcuTimeZonePrivate(ianaId);
#else
- return new QUtcTimeZonePrivate(olsenId);
+ return new QUtcTimeZonePrivate(ianaId);
#endif // System Locales
#endif // QT_NO_SYSTEMLOCALE
}
@@ -931,18 +933,18 @@ QDataStream &operator<<(QDataStream &ds, const QTimeZone &tz)
QDataStream &operator>>(QDataStream &ds, QTimeZone &tz)
{
- QString olsenId;
- ds >> olsenId;
- if (olsenId == QStringLiteral("OffsetFromUtc")) {
+ QString ianaId;
+ ds >> ianaId;
+ if (ianaId == QStringLiteral("OffsetFromUtc")) {
int utcOffset;
QString name;
QString abbreviation;
int country;
QString comment;
- ds >> olsenId >> utcOffset >> name >> abbreviation >> country >> comment;
- tz = QTimeZone(olsenId.toUtf8(), utcOffset, name, abbreviation, (QLocale::Country) country, comment);
+ ds >> ianaId >> utcOffset >> name >> abbreviation >> country >> comment;
+ tz = QTimeZone(ianaId.toUtf8(), utcOffset, name, abbreviation, (QLocale::Country) country, comment);
} else {
- tz = QTimeZone(olsenId.toUtf8());
+ tz = QTimeZone(ianaId.toUtf8());
}
return ds;
}
diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp
index dffb20b7cf..4286119586 100644
--- a/src/corelib/tools/qtimezoneprivate.cpp
+++ b/src/corelib/tools/qtimezoneprivate.cpp
@@ -85,21 +85,21 @@ static QByteArray windowsId(const QWindowsData *windowsData)
return (windowsIdData + windowsData->windowsIdIndex);
}
-// Return the Olsen ID literal for a given QWindowsData
-static QByteArray olsenId(const QWindowsData *windowsData)
+// Return the IANA ID literal for a given QWindowsData
+static QByteArray ianaId(const QWindowsData *windowsData)
{
- return (olsenIdData + windowsData->olsenIdIndex);
+ return (ianaIdData + windowsData->ianaIdIndex);
}
-// Return the Olsen ID literal for a given QZoneData
-static QByteArray olsenId(const QZoneData *zoneData)
+// Return the IANA ID literal for a given QZoneData
+static QByteArray ianaId(const QZoneData *zoneData)
{
- return (olsenIdData + zoneData->olsenIdIndex);
+ return (ianaIdData + zoneData->ianaIdIndex);
}
static QByteArray utcId(const QUtcData *utcData)
{
- return (olsenIdData + utcData->olsenIdIndex);
+ return (ianaIdData + utcData->ianaIdIndex);
}
static quint16 toWindowsIdKey(const QByteArray &winId)
@@ -172,7 +172,7 @@ QLocale::Country QTimeZonePrivate::country() const
// Default fall-back mode, use the zoneTable to find Region of known Zones
for (int i = 0; i < zoneDataTableSize; ++i) {
const QZoneData *data = zoneData(i);
- if (olsenId(data).split(' ').contains(m_id))
+ if (ianaId(data).split(' ').contains(m_id))
return (QLocale::Country)data->country;
}
return QLocale::AnyCountry;
@@ -361,14 +361,14 @@ QSet<QByteArray> QTimeZonePrivate::availableTimeZoneIds(QLocale::Country country
// First get all Zones in the Zones table belonging to the Region
for (int i = 0; i < zoneDataTableSize; ++i) {
if (zoneData(i)->country == country)
- regionSet += olsenId(zoneData(i)).split(' ').toSet();
+ regionSet += ianaId(zoneData(i)).split(' ').toSet();
}
// Then select just those that are available
QSet<QByteArray> set;
- foreach (const QByteArray &olsenId, availableTimeZoneIds()) {
- if (regionSet.contains(olsenId))
- set << olsenId;
+ foreach (const QByteArray &ianaId, availableTimeZoneIds()) {
+ if (regionSet.contains(ianaId))
+ set << ianaId;
}
return set;
@@ -385,16 +385,16 @@ QSet<QByteArray> QTimeZonePrivate::availableTimeZoneIds(int offsetFromUtc) const
for (int j = 0; j < zoneDataTableSize; ++j) {
const QZoneData *data = zoneData(j);
if (data->windowsIdKey == winData->windowsIdKey)
- offsetSet += olsenId(data).split(' ').toSet();
+ offsetSet += ianaId(data).split(' ').toSet();
}
}
}
// Then select just those that are available
QSet<QByteArray> set;
- foreach (const QByteArray &olsenId, availableTimeZoneIds()) {
- if (offsetSet.contains(olsenId))
- set << olsenId;
+ foreach (const QByteArray &ianaId, availableTimeZoneIds()) {
+ if (offsetSet.contains(ianaId))
+ set << ianaId;
}
return set;
@@ -443,17 +443,17 @@ QTimeZone::OffsetData QTimeZonePrivate::toOffsetData(const QTimeZonePrivate::Dat
}
// If the format of the ID is valid
-bool QTimeZonePrivate::isValidId(const QByteArray &olsenId)
+bool QTimeZonePrivate::isValidId(const QByteArray &ianaId)
{
- // Rules for defining TZ/Olsen names as per ftp://ftp.iana.org/tz/code/Theory
+ // Rules for defining TZ/IANA names as per ftp://ftp.iana.org/tz/code/Theory
// * Use only valid POSIX file name components
// * Within a file name component, use only ASCII letters, `.', `-' and `_'.
// * Do not use digits
// * A file name component must not exceed 14 characters or start with `-'
// Aliases such as "Etc/GMT+7" and "SystemV/EST5EDT" are valid so we need to accept digits
- if (olsenId.contains(' '))
+ if (ianaId.contains(' '))
return false;
- QList<QByteArray> parts = olsenId.split('/');
+ QList<QByteArray> parts = ianaId.split('/');
foreach (const QByteArray &part, parts) {
if (part.size() > 14 || part.size() < 1)
return false;
@@ -487,7 +487,7 @@ QByteArray QTimeZonePrivate::ianaIdToWindowsId(const QByteArray &id)
{
for (int i = 0; i < zoneDataTableSize; ++i) {
const QZoneData *data = zoneData(i);
- if (olsenId(data).split(' ').contains(id))
+ if (ianaId(data).split(' ').contains(id))
return toWindowsIdLiteral(data->windowsIdKey);
}
return QByteArray();
@@ -499,7 +499,7 @@ QByteArray QTimeZonePrivate::windowsIdToDefaultIanaId(const QByteArray &windowsI
for (int i = 0; i < windowsDataTableSize; ++i) {
const QWindowsData *data = windowsData(i);
if (data->windowsIdKey == windowsIdKey)
- return olsenId(data);
+ return ianaId(data);
}
return QByteArray();
}
@@ -522,7 +522,7 @@ QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windows
for (int i = 0; i < zoneDataTableSize; ++i) {
const QZoneData *data = zoneData(i);
if (data->windowsIdKey == windowsIdKey)
- list << olsenId(data).split(' ');
+ list << ianaId(data).split(' ');
}
// Return the full list in alpha order
@@ -538,7 +538,7 @@ QList<QByteArray> QTimeZonePrivate::windowsIdToIanaIds(const QByteArray &windows
const QZoneData *data = zoneData(i);
// Return the region matches in preference order
if (data->windowsIdKey == windowsIdKey && data->country == (quint16) country)
- return olsenId(data).split(' ');
+ return ianaId(data).split(' ');
}
return QList<QByteArray>();
diff --git a/src/corelib/tools/qtimezoneprivate_data_p.h b/src/corelib/tools/qtimezoneprivate_data_p.h
index bb87eab1f3..0ae6f0a722 100644
--- a/src/corelib/tools/qtimezoneprivate_data_p.h
+++ b/src/corelib/tools/qtimezoneprivate_data_p.h
@@ -74,19 +74,19 @@ QT_BEGIN_NAMESPACE
struct QZoneData {
quint16 windowsIdKey; // Windows ID Key
- quint16 country; // Country of Olsen ID's, AnyCountry means No Country
- quint16 olsenIdIndex; // All Olsen ID's for the Windows ID and Country, space separated
+ quint16 country; // Country of IANA ID's, AnyCountry means No Country
+ quint16 ianaIdIndex; // All IANA ID's for the Windows ID and Country, space separated
};
struct QWindowsData {
quint16 windowsIdKey; // Windows ID Key
quint16 windowsIdIndex; // Windows ID Literal
- quint16 olsenIdIndex; // Default Olsen ID for the Windows ID
+ quint16 ianaIdIndex; // Default IANA ID for the Windows ID
qint32 offsetFromUtc; // Standard Time Offset from UTC, used for quick look-ups
};
struct QUtcData {
- quint16 olsenIdIndex; // Olsen ID's
+ quint16 ianaIdIndex; // IANA ID's
qint32 offsetFromUtc; // Offset form UTC is seconds
};
@@ -114,16 +114,16 @@ struct QUtcData {
// GENERATED PART STARTS HERE
/*
- This part of the file was generated on 2013-03-18 from the
+ This part of the file was generated on 2014-01-12 from the
Common Locale Data Repository supplemental/windowsZones.xml file
- $Revision: 7825 $ $Date: 2012-10-10 14:45:31 -0700 (Wed, 10 Oct 2012) $
+ $Revision: 9178 $ $Date: 2013-08-08 13:59:22 -0500 (Thu, 08 Aug 2013) $
http://www.unicode.org/cldr/
Do not change this data, only generate it using cldr2qtimezone.py.
*/
-// Windows ID Key, Country Enum, Olsen ID Index
+// Windows ID Key, Country Enum, IANA ID Index
static const QZoneData zoneDataTable[] = {
{ 95, 157, 0 }, // W. Central Africa Standard Time / Nigeria
{ 36, 73, 13 }, // FLE Standard Time / Finland
@@ -132,482 +132,483 @@ static const QZoneData zoneDataTable[] = {
{ 7, 24, 62 }, // Atlantic Standard Time / Bermuda
{ 82, 101, 79 }, // Tokyo Standard Time / Indonesia
{ 36, 68, 93 }, // FLE Standard Time / Estonia
- { 73, 93, 108 }, // SA Western Standard Time / Guyana
- { 73, 144, 123 }, // SA Western Standard Time / Montserrat
- { 80, 208, 142 }, // Taipei Standard Time / Taiwan
- { 96, 184, 154 }, // W. Europe Standard Time / SanMarino
- { 17, 13, 172 }, // Cen. Australia Standard Time / Australia
- { 72, 166, 213 }, // SA Pacific Standard Time / Panama
- { 72, 47, 228 }, // SA Pacific Standard Time / Colombia
- { 40, 132, 243 }, // Greenwich Standard Time / Mali
- { 61, 38, 257 }, // Newfoundland Standard Time / Canada
- { 18, 96, 274 }, // Central America Standard Time / Honduras
- { 28, 48, 294 }, // E. Africa Standard Time / Comoros
- { 85, 143, 308 }, // Ulaanbaatar Standard Time / Mongolia
- { 73, 180, 341 }, // SA Western Standard Time / SaintKittsAndNevis
- { 40, 236, 358 }, // Greenwich Standard Time / WesternSahara
- { 97, 110, 374 }, // West Asia Standard Time / Kazakhstan
- { 42, 77, 407 }, // Hawaiian Standard Time / FrenchPolynesia
- { 6, 10, 422 }, // Argentina Standard Time / Argentina
- { 20, 30, 695 }, // Central Brazilian Standard Time / Brazil
- { 47, 20, 731 }, // Kaliningrad Standard Time / Belarus
- { 32, 38, 744 }, // Eastern Standard Time / Canada
- { 48, 114, 849 }, // Korea Standard Time / SouthKorea
- { 87, 0, 860 }, // US Mountain Standard Time / AnyCountry
- { 94, 13, 870 }, // W. Australia Standard Time / Australia
- { 60, 8, 886 }, // New Zealand Standard Time / Antarctica
- { 90, 0, 927 }, // UTC / AnyCountry
- { 96, 133, 935 }, // W. Europe Standard Time / Malta
- { 73, 88, 948 }, // SA Western Standard Time / Guadeloupe
- { 56, 46, 967 }, // Myanmar Standard Time / CocosIslands
- { 91, 220, 980 }, // UTC+12 / Tuvalu
- { 1, 1, 997 }, // Afghanistan Standard Time / Afghanistan
- { 41, 177, 1008 }, // GTB Standard Time / Romania
- { 73, 26, 1025 }, // SA Western Standard Time / Bolivia
- { 88, 30, 1040 }, // UTC-02 / Brazil
- { 96, 123, 1056 }, // W. Europe Standard Time / Liechtenstein
- { 25, 139, 1069 }, // Central Standard Time / Mexico
- { 40, 199, 1087 }, // Greenwich Standard Time / SaintHelena
- { 52, 227, 1106 }, // Montevideo Standard Time / Uruguay
- { 55, 139, 1125 }, // Mountain Standard Time / Mexico
- { 98, 8, 1141 }, // West Pacific Standard Time / Antarctica
- { 36, 248, 1167 }, // FLE Standard Time / AlandIslands
- { 25, 38, 1184 }, // Central Standard Time / Canada
- { 32, 219, 1259 }, // Eastern Standard Time / TurksAndCaicosIslands
- { 72, 63, 1278 }, // SA Pacific Standard Time / Ecuador
- { 26, 44, 1296 }, // China Standard Time / China
- { 31, 30, 1362 }, // E. South America Standard Time / Brazil
- { 95, 216, 1380 }, // W. Central Africa Standard Time / Tunisia
- { 97, 228, 1393 }, // West Asia Standard Time / Uzbekistan
- { 42, 0, 1422 }, // Hawaiian Standard Time / AnyCountry
- { 28, 8, 1433 }, // E. Africa Standard Time / Antarctica
- { 36, 33, 1450 }, // FLE Standard Time / Bulgaria
- { 18, 65, 1463 }, // Central America Standard Time / ElSalvador
- { 76, 130, 1483 }, // Singapore Standard Time / Malaysia
- { 73, 0, 1514 }, // SA Western Standard Time / AnyCountry
- { 70, 178, 1524 }, // Russian Standard Time / Russia
- { 89, 158, 1569 }, // UTC-11 / Niue
- { 77, 120, 1582 }, // South Africa Standard Time / Lesotho
- { 87, 139, 1596 }, // US Mountain Standard Time / Mexico
- { 28, 111, 1615 }, // E. Africa Standard Time / Kenya
- { 98, 160, 1630 }, // West Pacific Standard Time / NorthernMarianaIslands
- { 28, 194, 1645 }, // E. Africa Standard Time / Somalia
- { 26, 126, 1662 }, // China Standard Time / Macau
- { 96, 151, 1673 }, // W. Europe Standard Time / Netherlands
- { 87, 225, 1690 }, // US Mountain Standard Time / UnitedStates
- { 38, 251, 1706 }, // GMT Standard Time / IsleOfMan
- { 91, 226, 1725 }, // UTC+12 / UnitedStatesMinorOutlyingIslands
- { 23, 153, 1738 }, // Central Pacific Standard Time / NewCaledonia
- { 73, 135, 1753 }, // SA Western Standard Time / Martinique
- { 19, 8, 1772 }, // Central Asia Standard Time / Antarctica
- { 18, 0, 1790 }, // Central America Standard Time / AnyCountry
- { 23, 229, 1800 }, // Central Pacific Standard Time / Vanuatu
- { 39, 86, 1814 }, // Greenland Standard Time / Greenland
- { 38, 71, 1830 }, // GMT Standard Time / FaroeIslands
- { 82, 108, 1846 }, // Tokyo Standard Time / Japan
- { 21, 192, 1857 }, // Central Europe Standard Time / Slovenia
- { 77, 35, 1874 }, // South Africa Standard Time / Burundi
- { 75, 232, 1891 }, // SE Asia Standard Time / Vietnam
- { 41, 85, 1903 }, // GTB Standard Time / Greece
- { 7, 38, 1917 }, // Atlantic Standard Time / Canada
- { 5, 103, 1985 }, // Arabic Standard Time / Iraq
- { 96, 205, 1998 }, // W. Europe Standard Time / Sweden
- { 73, 233, 2015 }, // SA Western Standard Time / BritishVirginIslands
- { 3, 186, 2031 }, // Arab Standard Time / SaudiArabia
- { 44, 102, 2043 }, // Iran Standard Time / Iran
- { 75, 0, 2055 }, // SE Asia Standard Time / AnyCountry
- { 82, 0, 2065 }, // Tokyo Standard Time / AnyCountry
- { 40, 136, 2075 }, // Greenwich Standard Time / Mauritania
- { 69, 21, 2093 }, // Romance Standard Time / Belgium
- { 42, 225, 2109 }, // Hawaiian Standard Time / UnitedStates
- { 95, 3, 2126 }, // W. Central Africa Standard Time / Algeria
- { 72, 38, 2141 }, // SA Pacific Standard Time / Canada
- { 87, 38, 2163 }, // US Mountain Standard Time / Canada
- { 95, 49, 2200 }, // W. Central Africa Standard Time / CongoKinshasa
- { 18, 52, 2216 }, // Central America Standard Time / CostaRica
- { 23, 140, 2235 }, // Central Pacific Standard Time / Micronesia
- { 28, 254, 2265 }, // E. Africa Standard Time / SouthSudan
- { 95, 156, 2277 }, // W. Central Africa Standard Time / Niger
- { 40, 80, 2291 }, // Greenwich Standard Time / Gambia
- { 75, 36, 2305 }, // SE Asia Standard Time / Cambodia
- { 69, 197, 2321 }, // Romance Standard Time / Spain
- { 97, 218, 2348 }, // West Asia Standard Time / Turkmenistan
- { 37, 81, 2362 }, // Georgian Standard Time / Georgia
- { 75, 101, 2375 }, // SE Asia Standard Time / Indonesia
- { 18, 155, 2403 }, // Central America Standard Time / Nicaragua
- { 73, 9, 2419 }, // SA Western Standard Time / AntiguaAndBarbuda
- { 76, 101, 2435 }, // Singapore Standard Time / Indonesia
- { 98, 167, 2449 }, // West Pacific Standard Time / PapuaNewGuinea
- { 25, 0, 2470 }, // Central Standard Time / AnyCountry
- { 32, 16, 2478 }, // Eastern Standard Time / Bahamas
- { 73, 30, 2493 }, // SA Western Standard Time / Brazil
- { 38, 173, 2582 }, // GMT Standard Time / Portugal
- { 74, 183, 2613 }, // Samoa Standard Time / Samoa
- { 60, 154, 2626 }, // New Zealand Standard Time / NewZealand
- { 33, 64, 2643 }, // Egypt Standard Time / Egypt
- { 73, 19, 2656 }, // SA Western Standard Time / Barbados
- { 71, 8, 2673 }, // SA Eastern Standard Time / Antarctica
- { 97, 209, 2692 }, // West Asia Standard Time / Tajikistan
- { 77, 0, 2706 }, // South Africa Standard Time / AnyCountry
- { 42, 226, 2716 }, // Hawaiian Standard Time / UnitedStatesMinorOutlyingIslands
- { 28, 210, 2733 }, // E. Africa Standard Time / Tanzania
- { 95, 37, 2754 }, // W. Central Africa Standard Time / Cameroon
- { 58, 148, 2768 }, // Namibia Standard Time / Namibia
- { 34, 178, 2784 }, // Ekaterinburg Standard Time / Russia
- { 28, 221, 2803 }, // E. Africa Standard Time / Uganda
- { 28, 138, 2818 }, // E. Africa Standard Time / Mayotte
- { 40, 92, 2833 }, // Greenwich Standard Time / GuineaBissau
- { 97, 78, 2847 }, // West Asia Standard Time / FrenchSouthernTerritories
- { 77, 240, 2864 }, // South Africa Standard Time / Zimbabwe
- { 95, 79, 2878 }, // W. Central Africa Standard Time / Gabon
- { 76, 190, 2896 }, // Singapore Standard Time / Singapore
- { 15, 0, 2911 }, // Cape Verde Standard Time / AnyCountry
- { 89, 226, 2921 }, // UTC-11 / UnitedStatesMinorOutlyingIslands
- { 24, 139, 2936 }, // Central Standard Time (Mexico) / Mexico
- { 78, 198, 3027 }, // Sri Lanka Standard Time / SriLanka
- { 36, 222, 3040 }, // FLE Standard Time / Ukraine
- { 32, 225, 3104 }, // Eastern Standard Time / UnitedStates
- { 9, 13, 3261 }, // AUS Eastern Standard Time / Australia
- { 32, 0, 3298 }, // Eastern Standard Time / AnyCountry
- { 73, 244, 3306 }, // SA Western Standard Time / Saint Barthelemy
- { 3, 115, 3328 }, // Arab Standard Time / Kuwait
- { 95, 41, 3340 }, // W. Central Africa Standard Time / CentralAfricanRepublic
- { 95, 0, 3354 }, // W. Central Africa Standard Time / AnyCountry
- { 72, 107, 3364 }, // SA Pacific Standard Time / Jamaica
- { 68, 168, 3380 }, // Paraguay Standard Time / Paraguay
- { 73, 182, 3397 }, // SA Western Standard Time / SaintVincentAndTheGrenadines
- { 96, 82, 3416 }, // W. Europe Standard Time / Germany
- { 66, 225, 3430 }, // Pacific Standard Time / UnitedStates
- { 73, 61, 3450 }, // SA Western Standard Time / DominicanRepublic
- { 89, 0, 3472 }, // UTC-11 / AnyCountry
- { 19, 110, 3483 }, // Central Asia Standard Time / Kazakhstan
- { 29, 13, 3510 }, // E. Australia Standard Time / Australia
- { 91, 235, 3548 }, // UTC+12 / WallisAndFutunaIslands
- { 13, 25, 3563 }, // Bangladesh Standard Time / Bhutan
- { 54, 139, 3576 }, // Mountain Standard Time (Mexico) / Mexico
- { 73, 152, 3611 }, // SA Western Standard Time / CuraSao
- { 97, 8, 3627 }, // West Asia Standard Time / Antarctica
- { 59, 150, 3645 }, // Nepal Standard Time / Nepal
- { 73, 7, 3659 }, // SA Western Standard Time / Anguilla
- { 40, 121, 3676 }, // Greenwich Standard Time / Liberia
- { 18, 22, 3692 }, // Central America Standard Time / Belize
- { 21, 243, 3707 }, // Central Europe Standard Time / Serbia
- { 4, 162, 3723 }, // Arabian Standard Time / Oman
- { 41, 141, 3735 }, // GTB Standard Time / Moldova
- { 71, 76, 3751 }, // SA Eastern Standard Time / FrenchGuiana
- { 77, 122, 3767 }, // South Africa Standard Time / Libya
- { 50, 176, 3782 }, // Mauritius Standard Time / Reunion
- { 23, 8, 3797 }, // Central Pacific Standard Time / Antarctica
- { 28, 67, 3818 }, // E. Africa Standard Time / Eritrea
- { 40, 212, 3832 }, // Greenwich Standard Time / Togo
- { 10, 15, 3844 }, // Azerbaijan Standard Time / Azerbaijan
- { 8, 13, 3854 }, // AUS Central Standard Time / Australia
- { 28, 128, 3871 }, // E. Africa Standard Time / Madagascar
- { 55, 0, 3891 }, // Mountain Standard Time / AnyCountry
- { 36, 118, 3899 }, // FLE Standard Time / Latvia
- { 28, 59, 3911 }, // E. Africa Standard Time / Djibouti
- { 23, 193, 3927 }, // Central Pacific Standard Time / SolomonIslands
- { 18, 63, 3947 }, // Central America Standard Time / Ecuador
- { 76, 170, 3965 }, // Singapore Standard Time / Philippines
- { 86, 225, 3977 }, // US Eastern Standard Time / UnitedStates
- { 64, 8, 4044 }, // Pacific SA Standard Time / Antarctica
- { 4, 223, 4062 }, // Arabian Standard Time / UnitedArabEmirates
- { 75, 45, 4073 }, // SE Asia Standard Time / ChristmasIsland
- { 91, 0, 4090 }, // UTC+12 / AnyCountry
- { 40, 99, 4101 }, // Greenwich Standard Time / Iceland
- { 88, 0, 4120 }, // UTC-02 / AnyCountry
- { 66, 0, 4130 }, // Pacific Standard Time / AnyCountry
- { 38, 75, 4138 }, // GMT Standard Time / Guernsey
- { 96, 206, 4154 }, // W. Europe Standard Time / Switzerland
- { 71, 70, 4168 }, // SA Eastern Standard Time / FalklandIslands
- { 22, 54, 4185 }, // Central European Standard Time / Croatia
- { 66, 139, 4199 }, // Pacific Standard Time / Mexico
- { 82, 164, 4215 }, // Tokyo Standard Time / Palau
- { 2, 225, 4229 }, // Alaskan Standard Time / UnitedStates
- { 14, 38, 4305 }, // Canada Central Standard Time / Canada
- { 57, 178, 4342 }, // N. Central Asia Standard Time / Russia
- { 77, 146, 4387 }, // South Africa Standard Time / Mozambique
- { 15, 39, 4401 }, // Cape Verde Standard Time / CapeVerde
- { 71, 202, 4421 }, // SA Eastern Standard Time / Suriname
- { 38, 252, 4440 }, // GMT Standard Time / Jersey
- { 40, 189, 4454 }, // Greenwich Standard Time / SierraLeone
- { 92, 231, 4470 }, // Venezuela Standard Time / Venezuela
- { 73, 38, 4486 }, // SA Western Standard Time / Canada
- { 79, 207, 4507 }, // Syria Standard Time / Syria
- { 38, 197, 4521 }, // GMT Standard Time / Spain
- { 75, 117, 4537 }, // SE Asia Standard Time / Laos
- { 22, 172, 4552 }, // Central European Standard Time / Poland
- { 27, 0, 4566 }, // Dateline Standard Time / AnyCountry
- { 16, 11, 4577 }, // Caucasus Standard Time / Armenia
- { 95, 50, 4590 }, // W. Central Africa Standard Time / CongoBrazzaville
- { 76, 32, 4609 }, // Singapore Standard Time / Brunei
- { 81, 13, 4621 }, // Tasmania Standard Time / Australia
- { 96, 84, 4655 }, // W. Europe Standard Time / Gibraltar
- { 72, 0, 4672 }, // SA Pacific Standard Time / AnyCountry
- { 94, 8, 4682 }, // W. Australia Standard Time / Antarctica
- { 82, 62, 4699 }, // Tokyo Standard Time / EastTimor
- { 22, 27, 4709 }, // Central European Standard Time / BosniaAndHerzegowina
- { 72, 94, 4725 }, // SA Pacific Standard Time / Haiti
- { 64, 43, 4748 }, // Pacific SA Standard Time / Chile
- { 66, 38, 4765 }, // Pacific Standard Time / Canada
- { 91, 112, 4817 }, // UTC+12 / Kiribati
- { 46, 109, 4832 }, // Jordan Standard Time / Jordan
- { 84, 217, 4843 }, // Turkey Standard Time / Turkey
- { 51, 119, 4859 }, // Middle East Standard Time / Lebanon
- { 36, 124, 4871 }, // FLE Standard Time / Lithuania
- { 21, 2, 4886 }, // Central Europe Standard Time / Albania
- { 95, 23, 4900 }, // W. Central Africa Standard Time / Benin
- { 55, 38, 4918 }, // Mountain Standard Time / Canada
- { 11, 173, 4992 }, // Azores Standard Time / Portugal
- { 28, 69, 5008 }, // E. Africa Standard Time / Ethiopia
- { 19, 31, 5027 }, // Central Asia Standard Time / BritishIndianOceanTerritory
- { 73, 256, 5041 }, // SA Western Standard Time / SintMaarten
- { 38, 104, 5063 }, // GMT Standard Time / Ireland
- { 89, 4, 5077 }, // UTC-11 / AmericanSamoa
- { 77, 239, 5095 }, // South Africa Standard Time / Zambia
- { 21, 98, 5109 }, // Central Europe Standard Time / Hungary
- { 11, 86, 5125 }, // Azores Standard Time / Greenland
- { 73, 215, 5146 }, // SA Western Standard Time / TrinidadAndTobago
- { 77, 195, 5168 }, // South Africa Standard Time / SouthAfrica
- { 13, 18, 5188 }, // Bangladesh Standard Time / Bangladesh
- { 12, 30, 5199 }, // Bahia Standard Time / Brazil
- { 47, 178, 5213 }, // Kaliningrad Standard Time / Russia
- { 28, 201, 5232 }, // E. Africa Standard Time / Sudan
- { 96, 125, 5248 }, // W. Europe Standard Time / Luxembourg
- { 75, 143, 5266 }, // SE Asia Standard Time / Mongolia
- { 98, 0, 5276 }, // West Pacific Standard Time / AnyCountry
- { 50, 188, 5287 }, // Mauritius Standard Time / Seychelles
- { 21, 57, 5299 }, // Central Europe Standard Time / CzechRepublic
- { 98, 140, 5313 }, // West Pacific Standard Time / Micronesia
- { 90, 86, 5326 }, // UTC / Greenland
- { 43, 100, 5347 }, // India Standard Time / India
- { 83, 214, 5361 }, // Tonga Standard Time / Tonga
- { 96, 142, 5379 }, // W. Europe Standard Time / Monaco
- { 73, 181, 5393 }, // SA Western Standard Time / SaintLucia
- { 95, 6, 5410 }, // W. Central Africa Standard Time / Angola
- { 73, 60, 5424 }, // SA Western Standard Time / Dominica
- { 88, 196, 5441 }, // UTC-02 / SouthGeorgiaAndTheSouthSandwichIslands
- { 19, 0, 5464 }, // Central Asia Standard Time / AnyCountry
- { 77, 28, 5474 }, // South Africa Standard Time / Botswana
- { 21, 242, 5490 }, // Central Europe Standard Time / Montenegro
- { 98, 89, 5507 }, // West Pacific Standard Time / Guam
- { 55, 225, 5520 }, // Mountain Standard Time / UnitedStates
- { 53, 145, 5566 }, // Morocco Standard Time / Morocco
- { 77, 179, 5584 }, // South Africa Standard Time / Rwanda
- { 7, 86, 5598 }, // Atlantic Standard Time / Greenland
- { 30, 56, 5612 }, // E. Europe Standard Time / Cyprus
- { 49, 178, 5625 }, // Magadan Standard Time / Russia
- { 72, 169, 5665 }, // SA Pacific Standard Time / Peru
- { 77, 204, 5678 }, // South Africa Standard Time / Swaziland
- { 3, 17, 5693 }, // Arab Standard Time / Bahrain
- { 73, 174, 5706 }, // SA Western Standard Time / PuertoRico
- { 77, 49, 5726 }, // South Africa Standard Time / CongoKinshasa
- { 75, 8, 5744 }, // SE Asia Standard Time / Antarctica
- { 91, 149, 5761 }, // UTC+12 / Nauru
- { 40, 83, 5775 }, // Greenwich Standard Time / Ghana
- { 75, 211, 5788 }, // SE Asia Standard Time / Thailand
- { 96, 230, 5801 }, // W. Europe Standard Time / VaticanCityState
- { 71, 30, 5816 }, // SA Eastern Standard Time / Brazil
- { 69, 58, 5913 }, // Romance Standard Time / Denmark
- { 25, 225, 5931 }, // Central Standard Time / UnitedStates
- { 73, 245, 6099 }, // SA Western Standard Time / Saint Martin
- { 91, 134, 6115 }, // UTC+12 / MarshallIslands
- { 45, 105, 6148 }, // Israel Standard Time / Israel
- { 73, 12, 6163 }, // SA Western Standard Time / Aruba
- { 67, 163, 6177 }, // Pakistan Standard Time / Pakistan
- { 40, 185, 6190 }, // Greenwich Standard Time / SaoTomeAndPrincipe
- { 48, 113, 6206 }, // Korea Standard Time / NorthKorea
- { 93, 178, 6221 }, // Vladivostok Standard Time / Russia
- { 40, 34, 6252 }, // Greenwich Standard Time / BurkinaFaso
- { 77, 129, 6271 }, // South Africa Standard Time / Malawi
- { 42, 51, 6287 }, // Hawaiian Standard Time / CookIslands
- { 28, 0, 6305 }, // E. Africa Standard Time / AnyCountry
- { 40, 53, 6315 }, // Greenwich Standard Time / IvoryCoast
- { 38, 224, 6330 }, // GMT Standard Time / UnitedKingdom
- { 18, 90, 6344 }, // Central America Standard Time / Guatemala
- { 35, 72, 6362 }, // Fiji Standard Time / Fiji
- { 72, 40, 6375 }, // SA Pacific Standard Time / CaymanIslands
- { 62, 178, 6390 }, // North Asia East Standard Time / Russia
- { 96, 106, 6403 }, // W. Europe Standard Time / Italy
- { 50, 137, 6415 }, // Mauritius Standard Time / Mauritius
- { 4, 0, 6432 }, // Arabian Standard Time / AnyCountry
- { 71, 0, 6442 }, // SA Eastern Standard Time / AnyCountry
- { 40, 91, 6452 }, // Greenwich Standard Time / Guinea
- { 65, 139, 6467 }, // Pacific Standard Time (Mexico) / Mexico
- { 40, 187, 6488 }, // Greenwich Standard Time / Senegal
- { 83, 213, 6501 }, // Tonga Standard Time / Tokelau
- { 96, 5, 6517 }, // W. Europe Standard Time / Andorra
- { 96, 161, 6532 }, // W. Europe Standard Time / Norway
- { 3, 175, 6544 }, // Arab Standard Time / Qatar
- { 56, 147, 6555 }, // Myanmar Standard Time / Myanmar
- { 97, 131, 6568 }, // West Asia Standard Time / Maldives
- { 69, 74, 6584 }, // Romance Standard Time / France
- { 3, 237, 6597 }, // Arab Standard Time / Yemen
- { 63, 178, 6607 }, // North Asia Standard Time / Russia
- { 96, 14, 6624 }, // W. Europe Standard Time / Austria
- { 76, 0, 6638 }, // Singapore Standard Time / AnyCountry
- { 83, 0, 6648 }, // Tonga Standard Time / AnyCountry
- { 96, 203, 6659 }, // W. Europe Standard Time / SvalbardAndJanMayenIslands
- { 73, 87, 6679 }, // SA Western Standard Time / Grenada
- { 73, 234, 6695 }, // SA Western Standard Time / UnitedStatesVirginIslands
- { 33, 165, 6713 }, // Egypt Standard Time / PalestinianTerritories
- { 99, 178, 6735 }, // Yakutsk Standard Time / Russia
- { 21, 191, 6748 }, // Central Europe Standard Time / Slovakia
- { 23, 0, 6766 }, // Central Pacific Standard Time / AnyCountry
- { 95, 66, 6777 }, // W. Central Africa Standard Time / EquatorialGuinea
- { 73, 255, 6791 }, // SA Western Standard Time / Bonaire
- { 97, 0, 6810 }, // West Asia Standard Time / AnyCountry
- { 22, 127, 6820 }, // Central European Standard Time / Macedonia
- { 95, 42, 6834 }, // W. Central Africa Standard Time / Chad
- { 19, 116, 6850 }, // Central Asia Standard Time / Kyrgyzstan
+ { 83, 213, 108 }, // Tonga Standard Time / Tokelau
+ { 73, 93, 124 }, // SA Western Standard Time / Guyana
+ { 73, 144, 139 }, // SA Western Standard Time / Montserrat
+ { 80, 208, 158 }, // Taipei Standard Time / Taiwan
+ { 96, 184, 170 }, // W. Europe Standard Time / SanMarino
+ { 17, 13, 188 }, // Cen. Australia Standard Time / Australia
+ { 72, 166, 229 }, // SA Pacific Standard Time / Panama
+ { 72, 47, 244 }, // SA Pacific Standard Time / Colombia
+ { 40, 132, 259 }, // Greenwich Standard Time / Mali
+ { 61, 38, 273 }, // Newfoundland Standard Time / Canada
+ { 18, 96, 290 }, // Central America Standard Time / Honduras
+ { 28, 48, 310 }, // E. Africa Standard Time / Comoros
+ { 85, 143, 324 }, // Ulaanbaatar Standard Time / Mongolia
+ { 73, 180, 357 }, // SA Western Standard Time / SaintKittsAndNevis
+ { 40, 236, 374 }, // Greenwich Standard Time / WesternSahara
+ { 97, 110, 390 }, // West Asia Standard Time / Kazakhstan
+ { 42, 77, 423 }, // Hawaiian Standard Time / FrenchPolynesia
+ { 6, 10, 438 }, // Argentina Standard Time / Argentina
+ { 20, 30, 711 }, // Central Brazilian Standard Time / Brazil
+ { 47, 20, 747 }, // Kaliningrad Standard Time / Belarus
+ { 32, 38, 760 }, // Eastern Standard Time / Canada
+ { 48, 114, 865 }, // Korea Standard Time / SouthKorea
+ { 87, 0, 876 }, // US Mountain Standard Time / AnyCountry
+ { 100, 122, 886 }, // Libya Standard Time / Libya
+ { 60, 8, 901 }, // New Zealand Standard Time / Antarctica
+ { 90, 0, 942 }, // UTC / AnyCountry
+ { 96, 133, 950 }, // W. Europe Standard Time / Malta
+ { 73, 88, 963 }, // SA Western Standard Time / Guadeloupe
+ { 56, 46, 982 }, // Myanmar Standard Time / CocosIslands
+ { 91, 220, 995 }, // UTC+12 / Tuvalu
+ { 1, 1, 1012 }, // Afghanistan Standard Time / Afghanistan
+ { 41, 177, 1023 }, // GTB Standard Time / Romania
+ { 73, 26, 1040 }, // SA Western Standard Time / Bolivia
+ { 88, 30, 1055 }, // UTC-02 / Brazil
+ { 96, 123, 1071 }, // W. Europe Standard Time / Liechtenstein
+ { 25, 139, 1084 }, // Central Standard Time / Mexico
+ { 40, 199, 1102 }, // Greenwich Standard Time / SaintHelena
+ { 52, 227, 1121 }, // Montevideo Standard Time / Uruguay
+ { 55, 139, 1140 }, // Mountain Standard Time / Mexico
+ { 98, 8, 1156 }, // West Pacific Standard Time / Antarctica
+ { 36, 248, 1182 }, // FLE Standard Time / AlandIslands
+ { 25, 38, 1199 }, // Central Standard Time / Canada
+ { 32, 219, 1274 }, // Eastern Standard Time / TurksAndCaicosIslands
+ { 72, 63, 1293 }, // SA Pacific Standard Time / Ecuador
+ { 26, 44, 1311 }, // China Standard Time / China
+ { 31, 30, 1377 }, // E. South America Standard Time / Brazil
+ { 95, 216, 1413 }, // W. Central Africa Standard Time / Tunisia
+ { 97, 228, 1426 }, // West Asia Standard Time / Uzbekistan
+ { 60, 154, 1455 }, // New Zealand Standard Time / NewZealand
+ { 42, 0, 1472 }, // Hawaiian Standard Time / AnyCountry
+ { 28, 8, 1483 }, // E. Africa Standard Time / Antarctica
+ { 36, 33, 1500 }, // FLE Standard Time / Bulgaria
+ { 18, 65, 1513 }, // Central America Standard Time / ElSalvador
+ { 76, 130, 1533 }, // Singapore Standard Time / Malaysia
+ { 73, 0, 1564 }, // SA Western Standard Time / AnyCountry
+ { 70, 178, 1574 }, // Russian Standard Time / Russia
+ { 89, 158, 1619 }, // UTC-11 / Niue
+ { 77, 120, 1632 }, // South Africa Standard Time / Lesotho
+ { 87, 139, 1646 }, // US Mountain Standard Time / Mexico
+ { 28, 111, 1665 }, // E. Africa Standard Time / Kenya
+ { 98, 160, 1680 }, // West Pacific Standard Time / NorthernMarianaIslands
+ { 26, 126, 1695 }, // China Standard Time / Macau
+ { 96, 151, 1706 }, // W. Europe Standard Time / Netherlands
+ { 87, 225, 1723 }, // US Mountain Standard Time / UnitedStates
+ { 38, 251, 1739 }, // GMT Standard Time / IsleOfMan
+ { 91, 226, 1758 }, // UTC+12 / UnitedStatesMinorOutlyingIslands
+ { 23, 153, 1771 }, // Central Pacific Standard Time / NewCaledonia
+ { 73, 135, 1786 }, // SA Western Standard Time / Martinique
+ { 19, 8, 1805 }, // Central Asia Standard Time / Antarctica
+ { 18, 0, 1823 }, // Central America Standard Time / AnyCountry
+ { 23, 229, 1833 }, // Central Pacific Standard Time / Vanuatu
+ { 39, 86, 1847 }, // Greenland Standard Time / Greenland
+ { 38, 71, 1863 }, // GMT Standard Time / FaroeIslands
+ { 82, 108, 1879 }, // Tokyo Standard Time / Japan
+ { 21, 192, 1890 }, // Central Europe Standard Time / Slovenia
+ { 77, 35, 1907 }, // South Africa Standard Time / Burundi
+ { 75, 232, 1924 }, // SE Asia Standard Time / Vietnam
+ { 41, 85, 1936 }, // GTB Standard Time / Greece
+ { 7, 38, 1950 }, // Atlantic Standard Time / Canada
+ { 5, 103, 2018 }, // Arabic Standard Time / Iraq
+ { 96, 205, 2031 }, // W. Europe Standard Time / Sweden
+ { 73, 233, 2048 }, // SA Western Standard Time / BritishVirginIslands
+ { 3, 186, 2064 }, // Arab Standard Time / SaudiArabia
+ { 44, 102, 2076 }, // Iran Standard Time / Iran
+ { 75, 0, 2088 }, // SE Asia Standard Time / AnyCountry
+ { 82, 0, 2098 }, // Tokyo Standard Time / AnyCountry
+ { 40, 136, 2108 }, // Greenwich Standard Time / Mauritania
+ { 69, 21, 2126 }, // Romance Standard Time / Belgium
+ { 42, 225, 2142 }, // Hawaiian Standard Time / UnitedStates
+ { 95, 3, 2159 }, // W. Central Africa Standard Time / Algeria
+ { 72, 38, 2174 }, // SA Pacific Standard Time / Canada
+ { 87, 38, 2196 }, // US Mountain Standard Time / Canada
+ { 95, 49, 2233 }, // W. Central Africa Standard Time / CongoKinshasa
+ { 18, 52, 2249 }, // Central America Standard Time / CostaRica
+ { 32, 55, 2268 }, // Eastern Standard Time / Cuba
+ { 28, 254, 2283 }, // E. Africa Standard Time / SouthSudan
+ { 95, 156, 2295 }, // W. Central Africa Standard Time / Niger
+ { 40, 80, 2309 }, // Greenwich Standard Time / Gambia
+ { 75, 36, 2323 }, // SE Asia Standard Time / Cambodia
+ { 69, 197, 2339 }, // Romance Standard Time / Spain
+ { 97, 218, 2366 }, // West Asia Standard Time / Turkmenistan
+ { 37, 81, 2380 }, // Georgian Standard Time / Georgia
+ { 75, 101, 2393 }, // SE Asia Standard Time / Indonesia
+ { 18, 155, 2421 }, // Central America Standard Time / Nicaragua
+ { 73, 9, 2437 }, // SA Western Standard Time / AntiguaAndBarbuda
+ { 83, 214, 2453 }, // Tonga Standard Time / Tonga
+ { 76, 101, 2471 }, // Singapore Standard Time / Indonesia
+ { 98, 167, 2485 }, // West Pacific Standard Time / PapuaNewGuinea
+ { 25, 0, 2506 }, // Central Standard Time / AnyCountry
+ { 32, 16, 2514 }, // Eastern Standard Time / Bahamas
+ { 73, 30, 2529 }, // SA Western Standard Time / Brazil
+ { 38, 173, 2618 }, // GMT Standard Time / Portugal
+ { 74, 183, 2649 }, // Samoa Standard Time / Samoa
+ { 32, 94, 2662 }, // Eastern Standard Time / Haiti
+ { 33, 64, 2685 }, // Egypt Standard Time / Egypt
+ { 73, 19, 2698 }, // SA Western Standard Time / Barbados
+ { 71, 8, 2715 }, // SA Eastern Standard Time / Antarctica
+ { 97, 209, 2734 }, // West Asia Standard Time / Tajikistan
+ { 77, 0, 2748 }, // South Africa Standard Time / AnyCountry
+ { 42, 226, 2758 }, // Hawaiian Standard Time / UnitedStatesMinorOutlyingIslands
+ { 28, 210, 2775 }, // E. Africa Standard Time / Tanzania
+ { 95, 37, 2796 }, // W. Central Africa Standard Time / Cameroon
+ { 58, 148, 2810 }, // Namibia Standard Time / Namibia
+ { 34, 178, 2826 }, // Ekaterinburg Standard Time / Russia
+ { 28, 221, 2845 }, // E. Africa Standard Time / Uganda
+ { 28, 138, 2860 }, // E. Africa Standard Time / Mayotte
+ { 40, 92, 2875 }, // Greenwich Standard Time / GuineaBissau
+ { 97, 78, 2889 }, // West Asia Standard Time / FrenchSouthernTerritories
+ { 77, 240, 2906 }, // South Africa Standard Time / Zimbabwe
+ { 95, 79, 2920 }, // W. Central Africa Standard Time / Gabon
+ { 91, 134, 2938 }, // UTC+12 / MarshallIslands
+ { 76, 190, 2971 }, // Singapore Standard Time / Singapore
+ { 15, 0, 2986 }, // Cape Verde Standard Time / AnyCountry
+ { 89, 226, 2996 }, // UTC-11 / UnitedStatesMinorOutlyingIslands
+ { 24, 139, 3011 }, // Central Standard Time (Mexico) / Mexico
+ { 78, 198, 3102 }, // Sri Lanka Standard Time / SriLanka
+ { 36, 222, 3115 }, // FLE Standard Time / Ukraine
+ { 32, 225, 3179 }, // Eastern Standard Time / UnitedStates
+ { 9, 13, 3336 }, // AUS Eastern Standard Time / Australia
+ { 32, 0, 3373 }, // Eastern Standard Time / AnyCountry
+ { 73, 244, 3381 }, // SA Western Standard Time / Saint Barthelemy
+ { 3, 115, 3403 }, // Arab Standard Time / Kuwait
+ { 95, 41, 3415 }, // W. Central Africa Standard Time / CentralAfricanRepublic
+ { 95, 0, 3429 }, // W. Central Africa Standard Time / AnyCountry
+ { 72, 107, 3439 }, // SA Pacific Standard Time / Jamaica
+ { 68, 168, 3455 }, // Paraguay Standard Time / Paraguay
+ { 73, 182, 3472 }, // SA Western Standard Time / SaintVincentAndTheGrenadines
+ { 96, 82, 3491 }, // W. Europe Standard Time / Germany
+ { 66, 225, 3521 }, // Pacific Standard Time / UnitedStates
+ { 73, 61, 3541 }, // SA Western Standard Time / DominicanRepublic
+ { 89, 0, 3563 }, // UTC-11 / AnyCountry
+ { 19, 110, 3574 }, // Central Asia Standard Time / Kazakhstan
+ { 29, 13, 3601 }, // E. Australia Standard Time / Australia
+ { 91, 235, 3639 }, // UTC+12 / WallisAndFutunaIslands
+ { 13, 25, 3654 }, // Bangladesh Standard Time / Bhutan
+ { 54, 139, 3667 }, // Mountain Standard Time (Mexico) / Mexico
+ { 94, 13, 3702 }, // W. Australia Standard Time / Australia
+ { 73, 152, 3718 }, // SA Western Standard Time / CuraSao
+ { 97, 8, 3734 }, // West Asia Standard Time / Antarctica
+ { 59, 150, 3752 }, // Nepal Standard Time / Nepal
+ { 73, 7, 3766 }, // SA Western Standard Time / Anguilla
+ { 40, 121, 3783 }, // Greenwich Standard Time / Liberia
+ { 18, 22, 3799 }, // Central America Standard Time / Belize
+ { 21, 243, 3814 }, // Central Europe Standard Time / Serbia
+ { 4, 162, 3830 }, // Arabian Standard Time / Oman
+ { 41, 141, 3842 }, // GTB Standard Time / Moldova
+ { 71, 76, 3858 }, // SA Eastern Standard Time / FrenchGuiana
+ { 50, 176, 3874 }, // Mauritius Standard Time / Reunion
+ { 28, 67, 3889 }, // E. Africa Standard Time / Eritrea
+ { 40, 212, 3903 }, // Greenwich Standard Time / Togo
+ { 10, 15, 3915 }, // Azerbaijan Standard Time / Azerbaijan
+ { 8, 13, 3925 }, // AUS Central Standard Time / Australia
+ { 28, 128, 3942 }, // E. Africa Standard Time / Madagascar
+ { 55, 0, 3962 }, // Mountain Standard Time / AnyCountry
+ { 36, 118, 3970 }, // FLE Standard Time / Latvia
+ { 28, 59, 3982 }, // E. Africa Standard Time / Djibouti
+ { 23, 193, 3998 }, // Central Pacific Standard Time / SolomonIslands
+ { 18, 63, 4018 }, // Central America Standard Time / Ecuador
+ { 76, 170, 4036 }, // Singapore Standard Time / Philippines
+ { 86, 225, 4048 }, // US Eastern Standard Time / UnitedStates
+ { 64, 8, 4115 }, // Pacific SA Standard Time / Antarctica
+ { 4, 223, 4133 }, // Arabian Standard Time / UnitedArabEmirates
+ { 75, 45, 4144 }, // SE Asia Standard Time / ChristmasIsland
+ { 91, 0, 4161 }, // UTC+12 / AnyCountry
+ { 40, 99, 4172 }, // Greenwich Standard Time / Iceland
+ { 88, 0, 4191 }, // UTC-02 / AnyCountry
+ { 66, 0, 4201 }, // Pacific Standard Time / AnyCountry
+ { 38, 75, 4209 }, // GMT Standard Time / Guernsey
+ { 96, 206, 4225 }, // W. Europe Standard Time / Switzerland
+ { 71, 70, 4239 }, // SA Eastern Standard Time / FalklandIslands
+ { 22, 54, 4256 }, // Central European Standard Time / Croatia
+ { 66, 139, 4270 }, // Pacific Standard Time / Mexico
+ { 82, 164, 4286 }, // Tokyo Standard Time / Palau
+ { 2, 225, 4300 }, // Alaskan Standard Time / UnitedStates
+ { 14, 38, 4376 }, // Canada Central Standard Time / Canada
+ { 57, 178, 4413 }, // N. Central Asia Standard Time / Russia
+ { 77, 146, 4458 }, // South Africa Standard Time / Mozambique
+ { 15, 39, 4472 }, // Cape Verde Standard Time / CapeVerde
+ { 71, 202, 4492 }, // SA Eastern Standard Time / Suriname
+ { 38, 252, 4511 }, // GMT Standard Time / Jersey
+ { 40, 189, 4525 }, // Greenwich Standard Time / SierraLeone
+ { 92, 231, 4541 }, // Venezuela Standard Time / Venezuela
+ { 73, 38, 4557 }, // SA Western Standard Time / Canada
+ { 79, 207, 4578 }, // Syria Standard Time / Syria
+ { 38, 197, 4592 }, // GMT Standard Time / Spain
+ { 75, 117, 4608 }, // SE Asia Standard Time / Laos
+ { 22, 172, 4623 }, // Central European Standard Time / Poland
+ { 27, 0, 4637 }, // Dateline Standard Time / AnyCountry
+ { 16, 11, 4648 }, // Caucasus Standard Time / Armenia
+ { 95, 50, 4661 }, // W. Central Africa Standard Time / CongoBrazzaville
+ { 76, 32, 4680 }, // Singapore Standard Time / Brunei
+ { 81, 13, 4692 }, // Tasmania Standard Time / Australia
+ { 96, 84, 4726 }, // W. Europe Standard Time / Gibraltar
+ { 72, 0, 4743 }, // SA Pacific Standard Time / AnyCountry
+ { 94, 8, 4753 }, // W. Australia Standard Time / Antarctica
+ { 82, 62, 4770 }, // Tokyo Standard Time / EastTimor
+ { 22, 27, 4780 }, // Central European Standard Time / BosniaAndHerzegowina
+ { 63, 178, 4796 }, // North Asia Standard Time / Russia
+ { 64, 43, 4813 }, // Pacific SA Standard Time / Chile
+ { 66, 38, 4830 }, // Pacific Standard Time / Canada
+ { 91, 112, 4882 }, // UTC+12 / Kiribati
+ { 46, 109, 4897 }, // Jordan Standard Time / Jordan
+ { 84, 217, 4908 }, // Turkey Standard Time / Turkey
+ { 51, 119, 4924 }, // Middle East Standard Time / Lebanon
+ { 36, 124, 4936 }, // FLE Standard Time / Lithuania
+ { 21, 2, 4951 }, // Central Europe Standard Time / Albania
+ { 95, 23, 4965 }, // W. Central Africa Standard Time / Benin
+ { 55, 38, 4983 }, // Mountain Standard Time / Canada
+ { 11, 173, 5057 }, // Azores Standard Time / Portugal
+ { 28, 69, 5073 }, // E. Africa Standard Time / Ethiopia
+ { 19, 31, 5092 }, // Central Asia Standard Time / BritishIndianOceanTerritory
+ { 73, 256, 5106 }, // SA Western Standard Time / SintMaarten
+ { 38, 104, 5128 }, // GMT Standard Time / Ireland
+ { 89, 4, 5142 }, // UTC-11 / AmericanSamoa
+ { 77, 239, 5160 }, // South Africa Standard Time / Zambia
+ { 21, 98, 5174 }, // Central Europe Standard Time / Hungary
+ { 11, 86, 5190 }, // Azores Standard Time / Greenland
+ { 73, 215, 5211 }, // SA Western Standard Time / TrinidadAndTobago
+ { 77, 195, 5233 }, // South Africa Standard Time / SouthAfrica
+ { 13, 18, 5253 }, // Bangladesh Standard Time / Bangladesh
+ { 12, 30, 5264 }, // Bahia Standard Time / Brazil
+ { 47, 178, 5278 }, // Kaliningrad Standard Time / Russia
+ { 28, 201, 5297 }, // E. Africa Standard Time / Sudan
+ { 96, 125, 5313 }, // W. Europe Standard Time / Luxembourg
+ { 75, 143, 5331 }, // SE Asia Standard Time / Mongolia
+ { 98, 0, 5341 }, // West Pacific Standard Time / AnyCountry
+ { 50, 188, 5352 }, // Mauritius Standard Time / Seychelles
+ { 21, 57, 5364 }, // Central Europe Standard Time / CzechRepublic
+ { 98, 140, 5378 }, // West Pacific Standard Time / Micronesia
+ { 90, 86, 5391 }, // UTC / Greenland
+ { 43, 100, 5412 }, // India Standard Time / India
+ { 23, 140, 5426 }, // Central Pacific Standard Time / Micronesia
+ { 96, 142, 5456 }, // W. Europe Standard Time / Monaco
+ { 73, 181, 5470 }, // SA Western Standard Time / SaintLucia
+ { 95, 6, 5487 }, // W. Central Africa Standard Time / Angola
+ { 73, 60, 5501 }, // SA Western Standard Time / Dominica
+ { 88, 196, 5518 }, // UTC-02 / SouthGeorgiaAndTheSouthSandwichIslands
+ { 19, 0, 5541 }, // Central Asia Standard Time / AnyCountry
+ { 77, 28, 5551 }, // South Africa Standard Time / Botswana
+ { 21, 242, 5567 }, // Central Europe Standard Time / Montenegro
+ { 98, 89, 5584 }, // West Pacific Standard Time / Guam
+ { 55, 225, 5597 }, // Mountain Standard Time / UnitedStates
+ { 53, 145, 5643 }, // Morocco Standard Time / Morocco
+ { 77, 179, 5661 }, // South Africa Standard Time / Rwanda
+ { 7, 86, 5675 }, // Atlantic Standard Time / Greenland
+ { 30, 56, 5689 }, // E. Europe Standard Time / Cyprus
+ { 49, 178, 5702 }, // Magadan Standard Time / Russia
+ { 73, 234, 5742 }, // SA Western Standard Time / UnitedStatesVirginIslands
+ { 77, 204, 5760 }, // South Africa Standard Time / Swaziland
+ { 3, 17, 5775 }, // Arab Standard Time / Bahrain
+ { 73, 174, 5788 }, // SA Western Standard Time / PuertoRico
+ { 28, 194, 5808 }, // E. Africa Standard Time / Somalia
+ { 75, 8, 5825 }, // SE Asia Standard Time / Antarctica
+ { 91, 149, 5842 }, // UTC+12 / Nauru
+ { 40, 83, 5856 }, // Greenwich Standard Time / Ghana
+ { 75, 211, 5869 }, // SE Asia Standard Time / Thailand
+ { 96, 230, 5882 }, // W. Europe Standard Time / VaticanCityState
+ { 71, 30, 5897 }, // SA Eastern Standard Time / Brazil
+ { 69, 58, 5976 }, // Romance Standard Time / Denmark
+ { 25, 225, 5994 }, // Central Standard Time / UnitedStates
+ { 73, 245, 6162 }, // SA Western Standard Time / Saint Martin
+ { 45, 105, 6178 }, // Israel Standard Time / Israel
+ { 73, 12, 6193 }, // SA Western Standard Time / Aruba
+ { 67, 163, 6207 }, // Pakistan Standard Time / Pakistan
+ { 40, 185, 6220 }, // Greenwich Standard Time / SaoTomeAndPrincipe
+ { 48, 113, 6236 }, // Korea Standard Time / NorthKorea
+ { 93, 178, 6251 }, // Vladivostok Standard Time / Russia
+ { 40, 34, 6296 }, // Greenwich Standard Time / BurkinaFaso
+ { 77, 129, 6315 }, // South Africa Standard Time / Malawi
+ { 42, 51, 6331 }, // Hawaiian Standard Time / CookIslands
+ { 28, 0, 6349 }, // E. Africa Standard Time / AnyCountry
+ { 40, 53, 6359 }, // Greenwich Standard Time / IvoryCoast
+ { 38, 224, 6374 }, // GMT Standard Time / UnitedKingdom
+ { 18, 90, 6388 }, // Central America Standard Time / Guatemala
+ { 35, 72, 6406 }, // Fiji Standard Time / Fiji
+ { 72, 40, 6419 }, // SA Pacific Standard Time / CaymanIslands
+ { 62, 178, 6434 }, // North Asia East Standard Time / Russia
+ { 96, 106, 6447 }, // W. Europe Standard Time / Italy
+ { 50, 137, 6459 }, // Mauritius Standard Time / Mauritius
+ { 4, 0, 6476 }, // Arabian Standard Time / AnyCountry
+ { 71, 0, 6486 }, // SA Eastern Standard Time / AnyCountry
+ { 40, 91, 6496 }, // Greenwich Standard Time / Guinea
+ { 65, 139, 6511 }, // Pacific Standard Time (Mexico) / Mexico
+ { 40, 187, 6532 }, // Greenwich Standard Time / Senegal
+ { 96, 5, 6545 }, // W. Europe Standard Time / Andorra
+ { 96, 161, 6560 }, // W. Europe Standard Time / Norway
+ { 3, 175, 6572 }, // Arab Standard Time / Qatar
+ { 56, 147, 6583 }, // Myanmar Standard Time / Myanmar
+ { 97, 131, 6596 }, // West Asia Standard Time / Maldives
+ { 69, 74, 6612 }, // Romance Standard Time / France
+ { 3, 237, 6625 }, // Arab Standard Time / Yemen
+ { 96, 14, 6635 }, // W. Europe Standard Time / Austria
+ { 76, 0, 6649 }, // Singapore Standard Time / AnyCountry
+ { 83, 0, 6659 }, // Tonga Standard Time / AnyCountry
+ { 96, 203, 6670 }, // W. Europe Standard Time / SvalbardAndJanMayenIslands
+ { 73, 87, 6690 }, // SA Western Standard Time / Grenada
+ { 72, 169, 6706 }, // SA Pacific Standard Time / Peru
+ { 77, 49, 6719 }, // South Africa Standard Time / CongoKinshasa
+ { 99, 178, 6737 }, // Yakutsk Standard Time / Russia
+ { 21, 191, 6764 }, // Central Europe Standard Time / Slovakia
+ { 23, 0, 6782 }, // Central Pacific Standard Time / AnyCountry
+ { 95, 66, 6793 }, // W. Central Africa Standard Time / EquatorialGuinea
+ { 73, 255, 6807 }, // SA Western Standard Time / Bonaire
+ { 97, 0, 6826 }, // West Asia Standard Time / AnyCountry
+ { 23, 13, 6836 }, // Central Pacific Standard Time / Australia
+ { 22, 127, 6857 }, // Central European Standard Time / Macedonia
+ { 95, 42, 6871 }, // W. Central Africa Standard Time / Chad
+ { 19, 116, 6887 }, // Central Asia Standard Time / Kyrgyzstan
{ 0, 0, 0 } // Trailing zeroes
};
-// Windows ID Key, Windows ID Index, Olsen ID Index, UTC Offset
+// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset
static const QWindowsData windowsDataTable[] = {
- { 1, 0, 997, 16200 }, // Afghanistan Standard Time
- { 2, 26, 6863,-32400 }, // Alaskan Standard Time
- { 3, 48, 2031, 10800 }, // Arab Standard Time
- { 4, 67, 4062, 14400 }, // Arabian Standard Time
- { 5, 89, 1985, 10800 }, // Arabic Standard Time
- { 6, 110, 6881, 10800 }, // Argentina Standard Time
- { 7, 134, 6902,-14400 }, // Atlantic Standard Time
- { 8, 157, 3854, 34200 }, // AUS Central Standard Time
- { 9, 183, 6918, 36000 }, // AUS Eastern Standard Time
- { 10, 209, 3844, 14400 }, // Azerbaijan Standard Time
- { 11, 234, 4992, -3600 }, // Azores Standard Time
- { 12, 255, 5199, 10800 }, // Bahia Standard Time
- { 13, 275, 5188, 21600 }, // Bangladesh Standard Time
- { 14, 300, 6935,-21600 }, // Canada Central Standard Time
- { 15, 329, 4401, -3600 }, // Cape Verde Standard Time
- { 16, 354, 4577, 14400 }, // Caucasus Standard Time
- { 17, 377, 6950, 34200 }, // Cen. Australia Standard Time
- { 18, 406, 6344,-21600 }, // Central America Standard Time
- { 19, 436, 6969, 21600 }, // Central Asia Standard Time
- { 20, 463, 6981,-14400 }, // Central Brazilian Standard Time
- { 21, 495, 5109, 3600 }, // Central Europe Standard Time
- { 22, 524, 4552, 3600 }, // Central European Standard Time
- { 23, 555, 3927, 39600 }, // Central Pacific Standard Time
- { 24, 585, 6996,-21600 }, // Central Standard Time (Mexico)
- { 25, 616, 7016,-21600 }, // Central Standard Time
- { 26, 638, 7032, 28800 }, // China Standard Time
- { 27, 658, 4566,-43200 }, // Dateline Standard Time
- { 28, 681, 1615, 10800 }, // E. Africa Standard Time
- { 29, 705, 7046, 36000 }, // E. Australia Standard Time
- { 30, 732, 5612, 7200 }, // E. Europe Standard Time
- { 31, 756, 1362,-10800 }, // E. South America Standard Time
- { 32, 787, 7065,-18000 }, // Eastern Standard Time
- { 33, 809, 2643, 7200 }, // Egypt Standard Time
- { 34, 829, 2784, 21600 }, // Ekaterinburg Standard Time
- { 35, 856, 6362, 43200 }, // Fiji Standard Time
- { 36, 875, 7082, 7200 }, // FLE Standard Time
- { 37, 893, 2362, 14400 }, // Georgian Standard Time
- { 38, 916, 6330, 0 }, // GMT Standard Time
- { 39, 934, 1814, 10800 }, // Greenland Standard Time
- { 40, 958, 4101, 0 }, // Greenwich Standard Time
- { 41, 982, 1008, 7200 }, // GTB Standard Time
- { 42, 1000, 2109,-36000 }, // Hawaiian Standard Time
- { 43, 1023, 5347, 19800 }, // India Standard Time
- { 44, 1043, 2043, 12600 }, // Iran Standard Time
- { 45, 1062, 6148, 7200 }, // Israel Standard Time
- { 46, 1083, 4832, 7200 }, // Jordan Standard Time
- { 47, 1104, 5213, 10800 }, // Kaliningrad Standard Time
- { 48, 1130, 849, 32400 }, // Korea Standard Time
- { 49, 1150, 7094, 43200 }, // Magadan Standard Time
- { 50, 1172, 6415, 14400 }, // Mauritius Standard Time
- { 51, 1196, 4859, 7200 }, // Middle East Standard Time
- { 52, 1222, 1106, 10800 }, // Montevideo Standard Time
- { 53, 1247, 5566, 0 }, // Morocco Standard Time
- { 54, 1269, 7107,-25200 }, // Mountain Standard Time (Mexico)
- { 55, 1301, 7125,-25200 }, // Mountain Standard Time
- { 56, 1324, 6555, 23400 }, // Myanmar Standard Time
- { 57, 1346, 7140, 23400 }, // N. Central Asia Standard Time
- { 58, 1376, 2768, 3600 }, // Namibia Standard Time
- { 59, 1398, 3645, 20700 }, // Nepal Standard Time
- { 60, 1418, 2626, 43200 }, // New Zealand Standard Time
- { 61, 1444, 257,-12600 }, // Newfoundland Standard Time
- { 62, 1471, 6390, 32400 }, // North Asia East Standard Time
- { 63, 1501, 6607, 28800 }, // North Asia Standard Time
- { 64, 1526, 4748,-14400 }, // Pacific SA Standard Time
- { 65, 1551, 6467,-28800 }, // Pacific Standard Time (Mexico)
- { 66, 1582, 3430,-28800 }, // Pacific Standard Time
- { 67, 1604, 6177, 18000 }, // Pakistan Standard Time
- { 68, 1627, 3380,-14400 }, // Paraguay Standard Time
- { 69, 1650, 6584, 3600 }, // Romance Standard Time
- { 70, 1672, 7157, 14400 }, // Russian Standard Time
- { 71, 1694, 3751, 10800 }, // SA Eastern Standard Time
- { 72, 1719, 228,-18000 }, // SA Pacific Standard Time
- { 73, 1744, 1025,-14400 }, // SA Western Standard Time
- { 74, 1769, 2613, 46800 }, // Samoa Standard Time
- { 75, 1789, 5788, 23400 }, // SE Asia Standard Time
- { 76, 1811, 2896, 28800 }, // Singapore Standard Time
- { 77, 1835, 5168, 7200 }, // South Africa Standard Time
- { 78, 1862, 3027, 19800 }, // Sri Lanka Standard Time
- { 79, 1886, 4507, 7200 }, // Syria Standard Time
- { 80, 1906, 142, 28800 }, // Taipei Standard Time
- { 81, 1927, 7171, 36000 }, // Tasmania Standard Time
- { 82, 1950, 1846, 32400 }, // Tokyo Standard Time
- { 83, 1970, 5361, 46800 }, // Tonga Standard Time
- { 84, 1990, 4843, 7200 }, // Turkey Standard Time
- { 85, 2011, 7188, 28800 }, // Ulaanbaatar Standard Time
- { 86, 2037, 7205,-18000 }, // US Eastern Standard Time
- { 87, 2062, 1690,-25200 }, // US Mountain Standard Time
- { 88, 2088, 4120, -7200 }, // UTC-02
- { 89, 2095, 3472,-39600 }, // UTC-11
- { 90, 2102, 927, 0 }, // UTC
- { 91, 2106, 4090, 43200 }, // UTC+12
- { 92, 2113, 4470,-16200 }, // Venezuela Standard Time
- { 93, 2137, 7226, 39600 }, // Vladivostok Standard Time
- { 94, 2163, 870, 28800 }, // W. Australia Standard Time
+ { 1, 0, 1012, 16200 }, // Afghanistan Standard Time
+ { 2, 26, 6900,-32400 }, // Alaskan Standard Time
+ { 3, 48, 2064, 10800 }, // Arab Standard Time
+ { 4, 67, 4133, 14400 }, // Arabian Standard Time
+ { 5, 89, 2018, 10800 }, // Arabic Standard Time
+ { 6, 110, 6918, 10800 }, // Argentina Standard Time
+ { 7, 134, 6939,-14400 }, // Atlantic Standard Time
+ { 8, 157, 3925, 34200 }, // AUS Central Standard Time
+ { 9, 183, 6955, 36000 }, // AUS Eastern Standard Time
+ { 10, 209, 3915, 14400 }, // Azerbaijan Standard Time
+ { 11, 234, 5057, -3600 }, // Azores Standard Time
+ { 12, 255, 5264, 10800 }, // Bahia Standard Time
+ { 13, 275, 5253, 21600 }, // Bangladesh Standard Time
+ { 14, 300, 6972,-21600 }, // Canada Central Standard Time
+ { 15, 329, 4472, -3600 }, // Cape Verde Standard Time
+ { 16, 354, 4648, 14400 }, // Caucasus Standard Time
+ { 17, 377, 6987, 34200 }, // Cen. Australia Standard Time
+ { 18, 406, 6388,-21600 }, // Central America Standard Time
+ { 19, 436, 7006, 21600 }, // Central Asia Standard Time
+ { 20, 463, 7018,-14400 }, // Central Brazilian Standard Time
+ { 21, 495, 5174, 3600 }, // Central Europe Standard Time
+ { 22, 524, 4623, 3600 }, // Central European Standard Time
+ { 23, 555, 3998, 39600 }, // Central Pacific Standard Time
+ { 24, 585, 7033,-21600 }, // Central Standard Time (Mexico)
+ { 25, 616, 7053,-21600 }, // Central Standard Time
+ { 26, 638, 7069, 28800 }, // China Standard Time
+ { 27, 658, 4637,-43200 }, // Dateline Standard Time
+ { 28, 681, 1665, 10800 }, // E. Africa Standard Time
+ { 29, 705, 7083, 36000 }, // E. Australia Standard Time
+ { 30, 732, 5689, 7200 }, // E. Europe Standard Time
+ { 31, 756, 7102,-10800 }, // E. South America Standard Time
+ { 32, 787, 7120,-18000 }, // Eastern Standard Time
+ { 33, 809, 2685, 7200 }, // Egypt Standard Time
+ { 34, 829, 2826, 21600 }, // Ekaterinburg Standard Time
+ { 35, 856, 6406, 43200 }, // Fiji Standard Time
+ { 36, 875, 7137, 7200 }, // FLE Standard Time
+ { 37, 893, 2380, 14400 }, // Georgian Standard Time
+ { 38, 916, 6374, 0 }, // GMT Standard Time
+ { 39, 934, 1847, 10800 }, // Greenland Standard Time
+ { 40, 958, 4172, 0 }, // Greenwich Standard Time
+ { 41, 982, 1023, 7200 }, // GTB Standard Time
+ { 42, 1000, 2142,-36000 }, // Hawaiian Standard Time
+ { 43, 1023, 5412, 19800 }, // India Standard Time
+ { 44, 1043, 2076, 12600 }, // Iran Standard Time
+ { 45, 1062, 6178, 7200 }, // Israel Standard Time
+ { 46, 1083, 4897, 7200 }, // Jordan Standard Time
+ { 47, 1104, 5278, 10800 }, // Kaliningrad Standard Time
+ { 48, 1130, 865, 32400 }, // Korea Standard Time
+ { 49, 1150, 7149, 43200 }, // Magadan Standard Time
+ { 50, 1172, 6459, 14400 }, // Mauritius Standard Time
+ { 51, 1196, 4924, 7200 }, // Middle East Standard Time
+ { 52, 1222, 1121, 10800 }, // Montevideo Standard Time
+ { 53, 1247, 5643, 0 }, // Morocco Standard Time
+ { 54, 1269, 7162,-25200 }, // Mountain Standard Time (Mexico)
+ { 55, 1301, 7180,-25200 }, // Mountain Standard Time
+ { 56, 1324, 6583, 23400 }, // Myanmar Standard Time
+ { 57, 1346, 7195, 23400 }, // N. Central Asia Standard Time
+ { 58, 1376, 2810, 3600 }, // Namibia Standard Time
+ { 59, 1398, 3752, 20700 }, // Nepal Standard Time
+ { 60, 1418, 1455, 43200 }, // New Zealand Standard Time
+ { 61, 1444, 273,-12600 }, // Newfoundland Standard Time
+ { 62, 1471, 6434, 32400 }, // North Asia East Standard Time
+ { 63, 1501, 4796, 28800 }, // North Asia Standard Time
+ { 64, 1526, 4813,-14400 }, // Pacific SA Standard Time
+ { 65, 1551, 6511,-28800 }, // Pacific Standard Time (Mexico)
+ { 66, 1582, 3521,-28800 }, // Pacific Standard Time
+ { 67, 1604, 6207, 18000 }, // Pakistan Standard Time
+ { 68, 1627, 3455,-14400 }, // Paraguay Standard Time
+ { 69, 1650, 6612, 3600 }, // Romance Standard Time
+ { 70, 1672, 7212, 14400 }, // Russian Standard Time
+ { 71, 1694, 3858, 10800 }, // SA Eastern Standard Time
+ { 72, 1719, 244,-18000 }, // SA Pacific Standard Time
+ { 73, 1744, 1040,-14400 }, // SA Western Standard Time
+ { 74, 1769, 2649, 46800 }, // Samoa Standard Time
+ { 75, 1789, 5869, 23400 }, // SE Asia Standard Time
+ { 76, 1811, 2971, 28800 }, // Singapore Standard Time
+ { 77, 1835, 5233, 7200 }, // South Africa Standard Time
+ { 78, 1862, 3102, 19800 }, // Sri Lanka Standard Time
+ { 79, 1886, 4578, 7200 }, // Syria Standard Time
+ { 80, 1906, 158, 28800 }, // Taipei Standard Time
+ { 81, 1927, 7226, 36000 }, // Tasmania Standard Time
+ { 82, 1950, 1879, 32400 }, // Tokyo Standard Time
+ { 83, 1970, 2453, 46800 }, // Tonga Standard Time
+ { 84, 1990, 4908, 7200 }, // Turkey Standard Time
+ { 85, 2011, 7243, 28800 }, // Ulaanbaatar Standard Time
+ { 86, 2037, 7260,-18000 }, // US Eastern Standard Time
+ { 87, 2062, 1723,-25200 }, // US Mountain Standard Time
+ { 88, 2088, 4191, -7200 }, // UTC-02
+ { 89, 2095, 3563,-39600 }, // UTC-11
+ { 90, 2102, 942, 0 }, // UTC
+ { 91, 2106, 4161, 43200 }, // UTC+12
+ { 92, 2113, 4541,-16200 }, // Venezuela Standard Time
+ { 93, 2137, 7281, 39600 }, // Vladivostok Standard Time
+ { 94, 2163, 3702, 28800 }, // W. Australia Standard Time
{ 95, 2190, 0, 3600 }, // W. Central Africa Standard Time
- { 96, 2222, 3416, 3600 }, // W. Europe Standard Time
- { 97, 2246, 7243, 18000 }, // West Asia Standard Time
- { 98, 2270, 2449, 36000 }, // West Pacific Standard Time
- { 99, 2297, 6735, 36000 }, // Yakutsk Standard Time
+ { 96, 2222, 7298, 3600 }, // W. Europe Standard Time
+ { 97, 2246, 7312, 18000 }, // West Asia Standard Time
+ { 98, 2270, 2485, 36000 }, // West Pacific Standard Time
+ { 99, 2297, 7326, 36000 }, // Yakutsk Standard Time
+ { 100, 2319, 886, 3600 }, // Libya Standard Time
{ 0, 0, 0, 0 } // Trailing zeroes
};
-// Olsen ID Index, UTC Offset
+// IANA ID Index, UTC Offset
static const QUtcData utcDataTable[] = {
- { 7257, 0 }, // UTC
- { 7261,-50400 }, // UTC-14:00
- { 7271,-46800 }, // UTC-13:00
- { 7281,-43200 }, // UTC-12:00
- { 7291,-39600 }, // UTC-11:00
- { 7301,-36000 }, // UTC-10:00
- { 7311,-32400 }, // UTC-09:00
- { 7321,-28800 }, // UTC-08:00
- { 7331,-25200 }, // UTC-07:00
- { 7341,-21600 }, // UTC-06:00
- { 7351,-18000 }, // UTC-05:00
- { 7361,-16200 }, // UTC-04:30
- { 7371,-14400 }, // UTC-04:00
- { 7381,-12600 }, // UTC-03:30
- { 7391,-10800 }, // UTC-03:00
- { 7401, -7200 }, // UTC-02:00
- { 7411, -3600 }, // UTC-01:00
- { 7421, 0 }, // UTC-00:00
- { 7431, 0 }, // UTC+00:00
- { 7441, 3600 }, // UTC+01:00
- { 7451, 7200 }, // UTC+02:00
- { 7461, 10800 }, // UTC+03:00
- { 7471, 12600 }, // UTC+03:30
- { 7481, 14400 }, // UTC+04:00
- { 7491, 16200 }, // UTC+04:30
- { 7501, 18000 }, // UTC+05:00
- { 7511, 19800 }, // UTC+05:30
- { 7521, 20700 }, // UTC+05:45
- { 7531, 21600 }, // UTC+06:00
- { 7541, 23400 }, // UTC+06:30
- { 7551, 25200 }, // UTC+07:00
- { 7561, 28800 }, // UTC+08:00
- { 7571, 32400 }, // UTC+09:00
- { 7581, 34200 }, // UTC+09:30
- { 7591, 36000 }, // UTC+10:00
- { 7601, 39600 }, // UTC+11:00
- { 7611, 43200 }, // UTC+12:00
- { 7621, 46800 }, // UTC+13:00
- { 7631, 50400 }, // UTC+14:00
+ { 7339, 0 }, // UTC
+ { 7343,-50400 }, // UTC-14:00
+ { 7353,-46800 }, // UTC-13:00
+ { 7363,-43200 }, // UTC-12:00
+ { 7373,-39600 }, // UTC-11:00
+ { 7383,-36000 }, // UTC-10:00
+ { 7393,-32400 }, // UTC-09:00
+ { 7403,-28800 }, // UTC-08:00
+ { 7413,-25200 }, // UTC-07:00
+ { 7423,-21600 }, // UTC-06:00
+ { 7433,-18000 }, // UTC-05:00
+ { 7443,-16200 }, // UTC-04:30
+ { 7453,-14400 }, // UTC-04:00
+ { 7463,-12600 }, // UTC-03:30
+ { 7473,-10800 }, // UTC-03:00
+ { 7483, -7200 }, // UTC-02:00
+ { 7493, -3600 }, // UTC-01:00
+ { 7503, 0 }, // UTC-00:00
+ { 7513, 0 }, // UTC+00:00
+ { 7523, 3600 }, // UTC+01:00
+ { 7533, 7200 }, // UTC+02:00
+ { 7543, 10800 }, // UTC+03:00
+ { 7553, 12600 }, // UTC+03:30
+ { 7563, 14400 }, // UTC+04:00
+ { 7573, 16200 }, // UTC+04:30
+ { 7583, 18000 }, // UTC+05:00
+ { 7593, 19800 }, // UTC+05:30
+ { 7603, 20700 }, // UTC+05:45
+ { 7613, 21600 }, // UTC+06:00
+ { 7623, 23400 }, // UTC+06:30
+ { 7633, 25200 }, // UTC+07:00
+ { 7643, 28800 }, // UTC+08:00
+ { 7653, 32400 }, // UTC+09:00
+ { 7663, 34200 }, // UTC+09:30
+ { 7673, 36000 }, // UTC+10:00
+ { 7683, 39600 }, // UTC+11:00
+ { 7693, 43200 }, // UTC+12:00
+ { 7703, 46800 }, // UTC+13:00
+ { 7713, 50400 }, // UTC+14:00
{ 0, 0 } // Trailing zeroes
};
@@ -727,393 +728,398 @@ static const char windowsIdData[] = {
0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x65, 0x73, 0x74, 0x20, 0x41, 0x73, 0x69, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e,
0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x57, 0x65, 0x73, 0x74, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66,
0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x59, 0x61, 0x6b,
-0x75, 0x74, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0
+0x75, 0x74, 0x73, 0x6b, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0, 0x4c,
+0x69, 0x62, 0x79, 0x61, 0x20, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x0
};
-static const char olsenIdData[] = {
+static const char ianaIdData[] = {
0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
0x48, 0x65, 0x6c, 0x73, 0x69, 0x6e, 0x6b, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x6e, 0x67, 0x5f, 0x4b,
0x6f, 0x6e, 0x67, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x45, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x75, 0x72,
0x79, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x42, 0x65, 0x72, 0x6d, 0x75, 0x64, 0x61, 0x0, 0x41,
0x73, 0x69, 0x61, 0x2f, 0x4a, 0x61, 0x79, 0x61, 0x70, 0x75, 0x72, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x54, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x79, 0x61,
-0x6e, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61,
-0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
-0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69,
-0x61, 0x2f, 0x41, 0x64, 0x65, 0x6c, 0x61, 0x69, 0x64, 0x65, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
-0x2f, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x48, 0x69, 0x6c, 0x6c, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x50, 0x61, 0x6e, 0x61, 0x6d, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x67, 0x6f,
-0x74, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x6d, 0x61, 0x6b, 0x6f, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x54, 0x65, 0x67, 0x75, 0x63, 0x69, 0x67, 0x61, 0x6c, 0x70, 0x61, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e,
-0x2f, 0x43, 0x6f, 0x6d, 0x6f, 0x72, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61,
-0x61, 0x74, 0x61, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x68, 0x6f, 0x69, 0x62, 0x61, 0x6c, 0x73, 0x61, 0x6e,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x6c, 0x5f, 0x41, 0x61, 0x69, 0x75, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4f,
-0x72, 0x61, 0x6c, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x71, 0x74, 0x61, 0x75, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x41, 0x71, 0x74, 0x6f, 0x62, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x61, 0x68, 0x69, 0x74,
-0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x5f, 0x41, 0x69, 0x72,
-0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61,
-0x2f, 0x4c, 0x61, 0x5f, 0x52, 0x69, 0x6f, 0x6a, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72,
-0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x47, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x6f, 0x73,
+0x54, 0x61, 0x6c, 0x6c, 0x69, 0x6e, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x61, 0x6b, 0x61,
+0x6f, 0x66, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x79, 0x61, 0x6e, 0x61, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x73, 0x65, 0x72, 0x72, 0x61, 0x74, 0x0, 0x41, 0x73,
+0x69, 0x61, 0x2f, 0x54, 0x61, 0x69, 0x70, 0x65, 0x69, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x6e,
+0x5f, 0x4d, 0x61, 0x72, 0x69, 0x6e, 0x6f, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x41, 0x64,
+0x65, 0x6c, 0x61, 0x69, 0x64, 0x65, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x6f,
+0x6b, 0x65, 0x6e, 0x5f, 0x48, 0x69, 0x6c, 0x6c, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6e,
+0x61, 0x6d, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x67, 0x6f, 0x74, 0x61, 0x0, 0x41,
+0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x6d, 0x61, 0x6b, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x53, 0x74, 0x5f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x65,
+0x67, 0x75, 0x63, 0x69, 0x67, 0x61, 0x6c, 0x70, 0x61, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x6d,
+0x6f, 0x72, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61, 0x61, 0x74, 0x61, 0x72,
+0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x68, 0x6f, 0x69, 0x62, 0x61, 0x6c, 0x73, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x4b, 0x69, 0x74, 0x74, 0x73, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x45, 0x6c, 0x5f, 0x41, 0x61, 0x69, 0x75, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4f, 0x72, 0x61, 0x6c, 0x20,
+0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x71, 0x74, 0x61, 0x75, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x71, 0x74, 0x6f,
+0x62, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x61, 0x68, 0x69, 0x74, 0x69, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x5f, 0x41, 0x69, 0x72, 0x65, 0x73, 0x20, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x4c, 0x61, 0x5f,
+0x52, 0x69, 0x6f, 0x6a, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74,
+0x69, 0x6e, 0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x47, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x6f, 0x73, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6c, 0x74, 0x61,
0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53,
-0x61, 0x6c, 0x74, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69,
-0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4c, 0x75, 0x69, 0x73, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x54, 0x75, 0x63,
-0x75, 0x6d, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69,
-0x6e, 0x61, 0x2f, 0x55, 0x73, 0x68, 0x75, 0x61, 0x69, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x61, 0x74, 0x61, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x72,
-0x64, 0x6f, 0x62, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x6a, 0x75, 0x79, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x64, 0x6f, 0x7a, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x43, 0x75, 0x69, 0x61, 0x62, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61,
-0x6d, 0x70, 0x6f, 0x5f, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x69,
-0x6e, 0x73, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x71, 0x61, 0x6c, 0x75, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4e, 0x69, 0x70, 0x69, 0x67, 0x6f, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6e,
-0x67, 0x6e, 0x69, 0x72, 0x74, 0x75, 0x6e, 0x67, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x68, 0x75,
-0x6e, 0x64, 0x65, 0x72, 0x5f, 0x42, 0x61, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x65, 0x6f, 0x75, 0x6c, 0x0,
-0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x37, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f,
-0x50, 0x65, 0x72, 0x74, 0x68, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x6f, 0x75,
-0x74, 0x68, 0x5f, 0x50, 0x6f, 0x6c, 0x65, 0x20, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d,
-0x63, 0x4d, 0x75, 0x72, 0x64, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x4d, 0x61, 0x6c, 0x74, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x64,
-0x65, 0x6c, 0x6f, 0x75, 0x70, 0x65, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x63, 0x6f, 0x73, 0x0,
-0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x75, 0x6e, 0x61, 0x66, 0x75, 0x74, 0x69, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x4b, 0x61, 0x62, 0x75, 0x6c, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x63, 0x68, 0x61,
-0x72, 0x65, 0x73, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x61, 0x5f, 0x50, 0x61, 0x7a, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x6f, 0x6e, 0x68, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f,
-0x70, 0x65, 0x2f, 0x56, 0x61, 0x64, 0x75, 0x7a, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x74,
-0x61, 0x6d, 0x6f, 0x72, 0x6f, 0x73, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x74, 0x5f, 0x48,
-0x65, 0x6c, 0x65, 0x6e, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x65, 0x76,
-0x69, 0x64, 0x65, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4f, 0x6a, 0x69, 0x6e, 0x61, 0x67, 0x61,
-0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x75, 0x6d, 0x6f, 0x6e, 0x74, 0x44, 0x55,
-0x72, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x65, 0x68,
-0x61, 0x6d, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69, 0x6e, 0x6e, 0x69, 0x70, 0x65, 0x67,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x69, 0x6e, 0x79, 0x5f, 0x52, 0x69, 0x76, 0x65, 0x72,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x5f, 0x49, 0x6e, 0x6c, 0x65,
-0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x54, 0x75, 0x72, 0x6b, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x79, 0x61, 0x71, 0x75, 0x69, 0x6c, 0x0, 0x41, 0x73, 0x69, 0x61,
-0x2f, 0x53, 0x68, 0x61, 0x6e, 0x67, 0x68, 0x61, 0x69, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x68, 0x6f, 0x6e, 0x67,
-0x71, 0x69, 0x6e, 0x67, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x61, 0x72, 0x62, 0x69, 0x6e, 0x20, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x4b, 0x61, 0x73, 0x68, 0x67, 0x61, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x72, 0x75, 0x6d, 0x71,
-0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f, 0x5f, 0x50, 0x61, 0x75, 0x6c, 0x6f, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x75, 0x6e, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61,
-0x73, 0x68, 0x6b, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x6e,
-0x64, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x30, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74,
-0x69, 0x63, 0x61, 0x2f, 0x53, 0x79, 0x6f, 0x77, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6f, 0x66,
-0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x6c, 0x5f, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64,
-0x6f, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x61, 0x6c, 0x61, 0x5f, 0x4c, 0x75, 0x6d, 0x70, 0x75, 0x72,
-0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d,
-0x54, 0x2b, 0x34, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x20, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72, 0x61, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56,
-0x6f, 0x6c, 0x67, 0x6f, 0x67, 0x72, 0x61, 0x64, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x69, 0x75,
-0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x73, 0x65, 0x72, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x48, 0x65, 0x72, 0x6d, 0x6f, 0x73, 0x69, 0x6c, 0x6c, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4e, 0x61, 0x69, 0x72, 0x6f, 0x62, 0x69, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x53, 0x61,
-0x69, 0x70, 0x61, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x67, 0x61, 0x64, 0x69, 0x73, 0x68,
-0x75, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x61, 0x75, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64, 0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x68,
-0x6f, 0x65, 0x6e, 0x69, 0x78, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49, 0x73, 0x6c, 0x65, 0x5f, 0x6f, 0x66,
-0x5f, 0x4d, 0x61, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6b, 0x65, 0x0, 0x50, 0x61,
-0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x6f, 0x75, 0x6d, 0x65, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69,
-0x63, 0x61, 0x2f, 0x56, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x36, 0x0,
-0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x45, 0x66, 0x61, 0x74, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x47, 0x6f, 0x64, 0x74, 0x68, 0x61, 0x62, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x46,
-0x61, 0x65, 0x72, 0x6f, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x6a, 0x75, 0x62, 0x6c, 0x6a, 0x61, 0x6e, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x42, 0x75, 0x6a, 0x75, 0x6d, 0x62, 0x75, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x69, 0x67,
-0x6f, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x74, 0x68, 0x65, 0x6e, 0x73, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x6c, 0x69, 0x66, 0x61, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x47, 0x6c, 0x61, 0x63, 0x65, 0x5f, 0x42, 0x61, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47,
-0x6f, 0x6f, 0x73, 0x65, 0x5f, 0x42, 0x61, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e,
-0x63, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x67, 0x68, 0x64, 0x61, 0x64, 0x0, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x54, 0x6f, 0x72, 0x74, 0x6f, 0x6c, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x52, 0x69, 0x79, 0x61,
-0x64, 0x68, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x65, 0x68, 0x72, 0x61, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47,
-0x4d, 0x54, 0x2d, 0x37, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x39, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4e, 0x6f, 0x75, 0x61, 0x6b, 0x63, 0x68, 0x6f, 0x74, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x42, 0x72, 0x75, 0x73, 0x73, 0x65, 0x6c, 0x73, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x48, 0x6f, 0x6e,
-0x6f, 0x6c, 0x75, 0x6c, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6c, 0x67, 0x69, 0x65, 0x72, 0x73,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x72, 0x61, 0x6c, 0x5f, 0x48, 0x61, 0x72, 0x62, 0x6f,
-0x75, 0x72, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x5f, 0x43, 0x72,
-0x65, 0x65, 0x6b, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x69, 0x6e, 0x73, 0x68, 0x61, 0x73, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x73, 0x74, 0x61, 0x5f, 0x52, 0x69, 0x63, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
-0x69, 0x63, 0x2f, 0x50, 0x6f, 0x6e, 0x61, 0x70, 0x65, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4b, 0x6f,
-0x73, 0x72, 0x61, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x62, 0x61, 0x0, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4e, 0x69, 0x61, 0x6d, 0x65, 0x79, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61,
-0x6e, 0x6a, 0x75, 0x6c, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x68, 0x6e, 0x6f, 0x6d, 0x5f, 0x50, 0x65, 0x6e, 0x68,
-0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x64, 0x72, 0x69, 0x64, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x43, 0x65, 0x75, 0x74, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x73, 0x68, 0x67, 0x61, 0x62, 0x61,
-0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x62, 0x69, 0x6c, 0x69, 0x73, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x4a, 0x61, 0x6b, 0x61, 0x72, 0x74, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x6f, 0x6e, 0x74, 0x69, 0x61, 0x6e,
-0x61, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x75, 0x61, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x4d, 0x61, 0x6b, 0x61, 0x73, 0x73, 0x61, 0x72, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x6f, 0x72,
-0x74, 0x5f, 0x4d, 0x6f, 0x72, 0x65, 0x73, 0x62, 0x79, 0x0, 0x43, 0x53, 0x54, 0x36, 0x43, 0x44, 0x54, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x61, 0x73, 0x73, 0x61, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4d, 0x61, 0x6e, 0x61, 0x75, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x61, 0x5f,
-0x56, 0x69, 0x73, 0x74, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x69, 0x72, 0x75, 0x6e, 0x65,
-0x70, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x5f, 0x56, 0x65, 0x6c,
-0x68, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x42, 0x72, 0x61, 0x6e, 0x63,
-0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x69, 0x73, 0x62, 0x6f, 0x6e, 0x20, 0x41, 0x74, 0x6c, 0x61,
-0x6e, 0x74, 0x69, 0x63, 0x2f, 0x4d, 0x61, 0x64, 0x65, 0x69, 0x72, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
-0x2f, 0x41, 0x70, 0x69, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x41, 0x75, 0x63, 0x6b, 0x6c, 0x61,
-0x6e, 0x64, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x69, 0x72, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74,
-0x69, 0x63, 0x61, 0x2f, 0x52, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x75, 0x73,
-0x68, 0x61, 0x6e, 0x62, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x32, 0x0, 0x50, 0x61, 0x63, 0x69,
-0x66, 0x69, 0x63, 0x2f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x44, 0x61, 0x72, 0x5f, 0x65, 0x73, 0x5f, 0x53, 0x61, 0x6c, 0x61, 0x61, 0x6d, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x44, 0x6f, 0x75, 0x61, 0x6c, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69, 0x6e, 0x64, 0x68,
-0x6f, 0x65, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x65, 0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x62, 0x75,
-0x72, 0x67, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x70, 0x61, 0x6c, 0x61, 0x0, 0x49, 0x6e,
-0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4b, 0x65, 0x72, 0x67, 0x75, 0x65,
-0x6c, 0x65, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x72, 0x61, 0x72, 0x65, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61,
-0x2f, 0x53, 0x69, 0x6e, 0x67, 0x61, 0x70, 0x6f, 0x72, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4d, 0x69, 0x64, 0x77, 0x61, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x69, 0x61, 0x5f, 0x42, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x61, 0x73, 0x20, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x65, 0x72, 0x69, 0x64, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e,
-0x74, 0x65, 0x72, 0x72, 0x65, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x6f, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53,
-0x69, 0x6d, 0x66, 0x65, 0x72, 0x6f, 0x70, 0x6f, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x55, 0x7a, 0x68,
-0x67, 0x6f, 0x72, 0x6f, 0x64, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x61, 0x70, 0x6f, 0x72, 0x6f, 0x7a,
-0x68, 0x79, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x59, 0x6f, 0x72, 0x6b,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x74, 0x72, 0x6f, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x50, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62,
-0x75, 0x72, 0x67, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f,
-0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x6e, 0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e,
-0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x57, 0x69, 0x6e, 0x61, 0x6d, 0x61, 0x63, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4b, 0x65, 0x6e, 0x74, 0x75, 0x63, 0x6b, 0x79, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x69, 0x63, 0x65, 0x6c, 0x6c,
-0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x75, 0x69, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x65,
-0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x20, 0x41, 0x75,
-0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x4d, 0x65, 0x6c, 0x62, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x0, 0x45, 0x53,
-0x54, 0x35, 0x45, 0x44, 0x54, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x42, 0x61, 0x72,
-0x74, 0x68, 0x65, 0x6c, 0x65, 0x6d, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x77, 0x61, 0x69, 0x74, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x67, 0x75, 0x69, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d,
-0x54, 0x2d, 0x31, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x73, 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f,
-0x70, 0x65, 0x2f, 0x42, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f,
-0x73, 0x5f, 0x41, 0x6e, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61,
-0x6e, 0x74, 0x6f, 0x5f, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b,
-0x31, 0x31, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6c, 0x6d, 0x61, 0x74, 0x79, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x51, 0x79, 0x7a, 0x79, 0x6c, 0x6f, 0x72, 0x64, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f,
-0x42, 0x72, 0x69, 0x73, 0x62, 0x61, 0x6e, 0x65, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x4c,
-0x69, 0x6e, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6c, 0x6c,
-0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x68, 0x69, 0x6d, 0x70, 0x68, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x61, 0x7a, 0x61, 0x74, 0x6c, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x75, 0x72, 0x61, 0x63, 0x61, 0x6f, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61,
-0x77, 0x73, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x74, 0x6d, 0x61, 0x6e, 0x64, 0x75, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x67, 0x75, 0x69, 0x6c, 0x6c, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x72, 0x6f, 0x76, 0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x65, 0x6c, 0x67, 0x72, 0x61,
-0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x75, 0x73, 0x63, 0x61, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x43, 0x68, 0x69, 0x73, 0x69, 0x6e, 0x61, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x61, 0x79, 0x65, 0x6e, 0x6e, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x72, 0x69, 0x70, 0x6f, 0x6c,
-0x69, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x52, 0x65, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x0, 0x41, 0x6e, 0x74,
-0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x71, 0x75, 0x61, 0x72, 0x69, 0x65, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x73, 0x6d, 0x65, 0x72, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c,
-0x6f, 0x6d, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x6b, 0x75, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61,
-0x6c, 0x69, 0x61, 0x2f, 0x44, 0x61, 0x72, 0x77, 0x69, 0x6e, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x41, 0x6e,
-0x74, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x76, 0x6f, 0x0, 0x4d, 0x53, 0x54, 0x37, 0x4d, 0x44, 0x54, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x52, 0x69, 0x67, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x6a,
-0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x64, 0x61,
-0x6c, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x61, 0x6c, 0x61, 0x70,
-0x61, 0x67, 0x6f, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x69, 0x6c, 0x61, 0x0, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x20, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x65, 0x6e, 0x67,
-0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x56, 0x65,
-0x76, 0x61, 0x79, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6c, 0x6d, 0x65,
-0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x75, 0x62, 0x61, 0x69, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f,
-0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x32,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x52, 0x65, 0x79, 0x6b, 0x6a, 0x61, 0x76, 0x69, 0x6b, 0x0,
-0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x32, 0x0, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x0, 0x45, 0x75,
-0x72, 0x6f, 0x70, 0x65, 0x2f, 0x47, 0x75, 0x65, 0x72, 0x6e, 0x73, 0x65, 0x79, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
-0x2f, 0x5a, 0x75, 0x72, 0x69, 0x63, 0x68, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x74, 0x61,
-0x6e, 0x6c, 0x65, 0x79, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x61, 0x67, 0x72, 0x65, 0x62, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x69, 0x6a, 0x75, 0x61, 0x6e, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
-0x69, 0x63, 0x2f, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x63,
-0x68, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x6e, 0x65, 0x61,
-0x75, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x6d, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x53, 0x69, 0x74, 0x6b, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x59, 0x61, 0x6b,
-0x75, 0x74, 0x61, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x77, 0x69, 0x66, 0x74, 0x5f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e,
-0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x20, 0x41,
-0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f, 0x6b, 0x75, 0x7a, 0x6e, 0x65, 0x74, 0x73, 0x6b, 0x20, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x4f, 0x6d, 0x73, 0x6b, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x70, 0x75, 0x74, 0x6f,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x43, 0x61, 0x70, 0x65, 0x5f, 0x56, 0x65, 0x72, 0x64, 0x65,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x62, 0x6f, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4a, 0x65, 0x72, 0x73, 0x65, 0x79, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x46, 0x72, 0x65, 0x65, 0x74, 0x6f, 0x77, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61,
-0x72, 0x61, 0x63, 0x61, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6c, 0x61, 0x6e, 0x63, 0x2d,
-0x53, 0x61, 0x62, 0x6c, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x61, 0x6d, 0x61, 0x73, 0x63, 0x75, 0x73,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6e, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x57,
-0x61, 0x72, 0x73, 0x61, 0x77, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x32, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x59, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x72, 0x61,
-0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69,
-0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x62, 0x61, 0x72, 0x74, 0x20, 0x41, 0x75,
-0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x43, 0x75, 0x72, 0x72, 0x69, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
-0x65, 0x2f, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74, 0x61, 0x72, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b,
-0x35, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x65, 0x79, 0x0, 0x41,
-0x73, 0x69, 0x61, 0x2f, 0x44, 0x69, 0x6c, 0x69, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x72, 0x61,
-0x6a, 0x65, 0x76, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x2d, 0x61, 0x75,
-0x2d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74,
-0x69, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x56, 0x61, 0x6e, 0x63, 0x6f, 0x75, 0x76,
-0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x20, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x68, 0x69, 0x74, 0x65, 0x68, 0x6f, 0x72, 0x73, 0x65, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x61, 0x72, 0x61, 0x77, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6d, 0x6d,
-0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49, 0x73, 0x74, 0x61, 0x6e, 0x62, 0x75, 0x6c, 0x0, 0x41,
-0x73, 0x69, 0x61, 0x2f, 0x42, 0x65, 0x69, 0x72, 0x75, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x69,
-0x6c, 0x6e, 0x69, 0x75, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x54, 0x69, 0x72, 0x61, 0x6e, 0x65, 0x0,
-0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x2d, 0x4e, 0x6f, 0x76, 0x6f, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x64, 0x6d, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x42, 0x61, 0x79, 0x20, 0x41, 0x6d, 0x65,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x75, 0x76, 0x69, 0x6b, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x59, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6b, 0x6e, 0x69, 0x66, 0x65, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63,
-0x2f, 0x41, 0x7a, 0x6f, 0x72, 0x65, 0x73, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x64, 0x64, 0x69, 0x73,
-0x5f, 0x41, 0x62, 0x61, 0x62, 0x61, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x68, 0x61, 0x67, 0x6f, 0x73,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x50, 0x72, 0x69, 0x6e, 0x63,
-0x65, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x44, 0x75, 0x62, 0x6c, 0x69, 0x6e, 0x0, 0x50, 0x61, 0x63,
-0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x61, 0x67, 0x6f, 0x5f, 0x50, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4c, 0x75, 0x73, 0x61, 0x6b, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x64, 0x61,
-0x70, 0x65, 0x73, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x62,
-0x79, 0x73, 0x75, 0x6e, 0x64, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x5f, 0x6f,
-0x66, 0x5f, 0x53, 0x70, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x6f, 0x68, 0x61, 0x6e,
-0x6e, 0x65, 0x73, 0x62, 0x75, 0x72, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x68, 0x61, 0x6b, 0x61, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x69, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x4b, 0x61, 0x6c, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x72, 0x61, 0x64, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b,
-0x68, 0x61, 0x72, 0x74, 0x6f, 0x75, 0x6d, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x75, 0x78, 0x65, 0x6d,
-0x62, 0x6f, 0x75, 0x72, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x76, 0x64, 0x0, 0x45, 0x74, 0x63, 0x2f,
-0x47, 0x4d, 0x54, 0x2d, 0x31, 0x30, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x68, 0x65, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x72, 0x61, 0x67, 0x75, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
-0x2f, 0x54, 0x72, 0x75, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x72,
-0x6b, 0x73, 0x68, 0x61, 0x76, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x74, 0x74, 0x61,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x74, 0x61, 0x70, 0x75, 0x0, 0x45,
-0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x53, 0x74, 0x5f, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x61,
-0x6e, 0x64, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61,
-0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x5f, 0x47, 0x65, 0x6f, 0x72,
-0x67, 0x69, 0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x36, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x47, 0x61, 0x62, 0x6f, 0x72, 0x6f, 0x6e, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x6f, 0x64,
-0x67, 0x6f, 0x72, 0x69, 0x63, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x6d, 0x0,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x42, 0x6f, 0x69, 0x73, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x68, 0x69,
-0x70, 0x72, 0x6f, 0x63, 0x6b, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x61, 0x62, 0x6c, 0x61,
-0x6e, 0x63, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x69, 0x67, 0x61, 0x6c, 0x69, 0x0, 0x41, 0x6d,
-0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x68, 0x75, 0x6c, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x69, 0x63,
-0x6f, 0x73, 0x69, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x67, 0x61, 0x64, 0x61, 0x6e, 0x20, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x41, 0x6e, 0x61, 0x64, 0x79, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x63, 0x68,
-0x61, 0x74, 0x6b, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x6d, 0x61, 0x0, 0x41, 0x66,
-0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x62, 0x61, 0x62, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61,
-0x68, 0x72, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x75, 0x65, 0x72, 0x74, 0x6f,
-0x5f, 0x52, 0x69, 0x63, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x62, 0x75, 0x6d, 0x62, 0x61,
-0x73, 0x68, 0x69, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x76, 0x69, 0x73,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x61, 0x75, 0x72, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x41, 0x63, 0x63, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x67, 0x6b, 0x6f, 0x6b,
-0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x46, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x65, 0x7a, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x41, 0x72, 0x61, 0x67, 0x75, 0x61, 0x69, 0x6e, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x42, 0x65, 0x6c, 0x65, 0x6d, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x65, 0x69, 0x6f,
-0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x63, 0x69, 0x66, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x6d, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
-0x43, 0x6f, 0x70, 0x65, 0x6e, 0x68, 0x61, 0x67, 0x65, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61,
-0x6e, 0x61, 0x2f, 0x4b, 0x6e, 0x6f, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69,
-0x61, 0x6e, 0x61, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
-0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x42, 0x65, 0x75, 0x6c, 0x61, 0x68, 0x20,
-0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61,
-0x2f, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74,
-0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x53, 0x61, 0x6c, 0x65, 0x6d, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x67, 0x6f, 0x74, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
-0x69, 0x63, 0x2f, 0x4d, 0x61, 0x6a, 0x75, 0x72, 0x6f, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4b, 0x77,
-0x61, 0x6a, 0x61, 0x6c, 0x65, 0x69, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4a, 0x65, 0x72, 0x75, 0x73, 0x61, 0x6c,
-0x65, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x75, 0x62, 0x61, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x4b, 0x61, 0x72, 0x61, 0x63, 0x68, 0x69, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f,
-0x5f, 0x54, 0x6f, 0x6d, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x79, 0x6f, 0x6e, 0x67, 0x79, 0x61, 0x6e, 0x67,
-0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x20, 0x41, 0x73,
-0x69, 0x61, 0x2f, 0x53, 0x61, 0x6b, 0x68, 0x61, 0x6c, 0x69, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4f,
-0x75, 0x61, 0x67, 0x61, 0x64, 0x6f, 0x75, 0x67, 0x6f, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6c,
-0x61, 0x6e, 0x74, 0x79, 0x72, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x52, 0x61, 0x72, 0x6f, 0x74,
-0x6f, 0x6e, 0x67, 0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x33, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
-0x61, 0x2f, 0x41, 0x62, 0x69, 0x64, 0x6a, 0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x6f, 0x6e,
-0x64, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x74, 0x65, 0x6d, 0x61, 0x6c,
-0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x69, 0x6a, 0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x49, 0x72, 0x6b, 0x75, 0x74,
-0x73, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x52, 0x6f, 0x6d, 0x65, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61,
-0x6e, 0x2f, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d,
-0x34, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x33, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
-0x6f, 0x6e, 0x61, 0x6b, 0x72, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x61,
-0x5f, 0x49, 0x73, 0x61, 0x62, 0x65, 0x6c, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x6b, 0x61, 0x72,
-0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x61, 0x6b, 0x61, 0x6f, 0x66, 0x6f, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4f,
-0x73, 0x6c, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x61, 0x74, 0x61, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x52, 0x61, 0x6e, 0x67, 0x6f, 0x6f, 0x6e, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x6c, 0x64, 0x69,
-0x76, 0x65, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x61, 0x72, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69,
-0x61, 0x2f, 0x41, 0x64, 0x65, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x72, 0x61, 0x73, 0x6e, 0x6f, 0x79, 0x61,
-0x72, 0x73, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x6e, 0x61, 0x0, 0x45, 0x74,
-0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x38, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x33, 0x0, 0x41,
-0x72, 0x63, 0x74, 0x69, 0x63, 0x2f, 0x4c, 0x6f, 0x6e, 0x67, 0x79, 0x65, 0x61, 0x72, 0x62, 0x79, 0x65, 0x6e, 0x0, 0x41,
-0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x72, 0x65, 0x6e, 0x61, 0x64, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x54, 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x47, 0x61,
-0x7a, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x65, 0x62, 0x72, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
-0x59, 0x61, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x72, 0x61, 0x74, 0x69,
-0x73, 0x6c, 0x61, 0x76, 0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x31, 0x0, 0x41, 0x66, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b,
-0x72, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6a, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x35, 0x0,
-0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6b, 0x6f, 0x70, 0x6a, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61,
-0x2f, 0x4e, 0x64, 0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x69, 0x73, 0x68, 0x6b,
-0x65, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, 0x67, 0x65,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x5f, 0x41, 0x69, 0x72, 0x65,
-0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x6c, 0x69, 0x66, 0x61, 0x78, 0x0, 0x41, 0x75,
-0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
-0x63, 0x61, 0x2f, 0x52, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f,
-0x41, 0x64, 0x65, 0x6c, 0x61, 0x69, 0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6c, 0x6d, 0x61, 0x74, 0x79,
-0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75, 0x69, 0x61, 0x62, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72,
-0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x68, 0x61,
-0x6e, 0x67, 0x68, 0x61, 0x69, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x69, 0x73,
-0x62, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x59, 0x6f, 0x72,
-0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d,
-0x61, 0x67, 0x61, 0x64, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75,
-0x61, 0x68, 0x75, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x0,
-0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x0, 0x45, 0x75, 0x72,
-0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61,
-0x2f, 0x48, 0x6f, 0x62, 0x61, 0x72, 0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61,
-0x61, 0x74, 0x61, 0x72, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61,
-0x70, 0x6f, 0x6c, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f, 0x73, 0x74,
-0x6f, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x73, 0x68, 0x6b, 0x65, 0x6e, 0x74, 0x0, 0x55, 0x54, 0x43,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x33, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x31, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x39, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x37, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x36, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x35, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x31, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x30, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a, 0x33, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a, 0x33, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x33, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x34, 0x35, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x37, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x30, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x32, 0x3a, 0x30, 0x30,
-0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x34, 0x3a, 0x30, 0x30,
-0x0
+0x61, 0x6e, 0x5f, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65,
+0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x5f, 0x4c, 0x75, 0x69, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x54, 0x75, 0x63, 0x75, 0x6d, 0x61, 0x6e,
+0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x72, 0x67, 0x65, 0x6e, 0x74, 0x69, 0x6e, 0x61, 0x2f, 0x55,
+0x73, 0x68, 0x75, 0x61, 0x69, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x74, 0x61, 0x6d,
+0x61, 0x72, 0x63, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x72, 0x64, 0x6f, 0x62, 0x61,
+0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x6a, 0x75, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x64, 0x6f, 0x7a, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43,
+0x75, 0x69, 0x61, 0x62, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6d, 0x70, 0x6f, 0x5f,
+0x47, 0x72, 0x61, 0x6e, 0x64, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x69, 0x6e, 0x73, 0x6b, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x6f, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x49, 0x71, 0x61, 0x6c, 0x75, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x4d, 0x6f, 0x6e, 0x74, 0x72, 0x65, 0x61, 0x6c, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x69, 0x70,
+0x69, 0x67, 0x6f, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6e, 0x67, 0x6e, 0x69, 0x72,
+0x74, 0x75, 0x6e, 0x67, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x68, 0x75, 0x6e, 0x64, 0x65, 0x72,
+0x5f, 0x42, 0x61, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x65, 0x6f, 0x75, 0x6c, 0x0, 0x45, 0x74, 0x63, 0x2f,
+0x47, 0x4d, 0x54, 0x2b, 0x37, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x72, 0x69, 0x70, 0x6f, 0x6c, 0x69,
+0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x5f, 0x50, 0x6f,
+0x6c, 0x65, 0x20, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x63, 0x4d, 0x75, 0x72, 0x64,
+0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x6c,
+0x74, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x64, 0x65, 0x6c, 0x6f, 0x75, 0x70,
+0x65, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x6f, 0x63, 0x6f, 0x73, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
+0x69, 0x63, 0x2f, 0x46, 0x75, 0x6e, 0x61, 0x66, 0x75, 0x74, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x62,
+0x75, 0x6c, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x63, 0x68, 0x61, 0x72, 0x65, 0x73, 0x74, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x61, 0x5f, 0x50, 0x61, 0x7a, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x6f, 0x6e, 0x68, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x61,
+0x64, 0x75, 0x7a, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x74, 0x61, 0x6d, 0x6f, 0x72, 0x6f,
+0x73, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x74, 0x5f, 0x48, 0x65, 0x6c, 0x65, 0x6e, 0x61,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4f, 0x6a, 0x69, 0x6e, 0x61, 0x67, 0x61, 0x0, 0x41, 0x6e, 0x74, 0x61,
+0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x75, 0x6d, 0x6f, 0x6e, 0x74, 0x44, 0x55, 0x72, 0x76, 0x69, 0x6c, 0x6c,
+0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x65, 0x68, 0x61, 0x6d, 0x6e, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69, 0x6e, 0x6e, 0x69, 0x70, 0x65, 0x67, 0x20, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x69, 0x6e, 0x79, 0x5f, 0x52, 0x69, 0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x52, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x5f, 0x49, 0x6e, 0x6c, 0x65, 0x74, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x47, 0x72, 0x61, 0x6e, 0x64, 0x5f, 0x54, 0x75, 0x72, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x47, 0x75, 0x61, 0x79, 0x61, 0x71, 0x75, 0x69, 0x6c, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x68, 0x61, 0x6e,
+0x67, 0x68, 0x61, 0x69, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x68, 0x6f, 0x6e, 0x67, 0x71, 0x69, 0x6e, 0x67, 0x20,
+0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x61, 0x72, 0x62, 0x69, 0x6e, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x73,
+0x68, 0x67, 0x61, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x72, 0x75, 0x6d, 0x71, 0x69, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f, 0x5f, 0x50, 0x61, 0x75, 0x6c, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x41, 0x72, 0x61, 0x67, 0x75, 0x61, 0x69, 0x6e, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x54, 0x75, 0x6e, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x73, 0x68, 0x6b, 0x65, 0x6e, 0x74, 0x20,
+0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x6e, 0x64, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66,
+0x69, 0x63, 0x2f, 0x41, 0x75, 0x63, 0x6b, 0x6c, 0x61, 0x6e, 0x64, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b,
+0x31, 0x30, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x79, 0x6f, 0x77, 0x61, 0x0,
+0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6f, 0x66, 0x69, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x45, 0x6c, 0x5f, 0x53, 0x61, 0x6c, 0x76, 0x61, 0x64, 0x6f, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75,
+0x61, 0x6c, 0x61, 0x5f, 0x4c, 0x75, 0x6d, 0x70, 0x75, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x63, 0x68,
+0x69, 0x6e, 0x67, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x34, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
+0x2f, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x6d, 0x61, 0x72,
+0x61, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x6f, 0x6c, 0x67, 0x6f, 0x67, 0x72, 0x61, 0x64, 0x0, 0x50,
+0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x69, 0x75, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d,
+0x61, 0x73, 0x65, 0x72, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x65, 0x72, 0x6d, 0x6f, 0x73,
+0x69, 0x6c, 0x6c, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x61, 0x69, 0x72, 0x6f, 0x62, 0x69, 0x0,
+0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x53, 0x61, 0x69, 0x70, 0x61, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
+0x4d, 0x61, 0x63, 0x61, 0x75, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64,
+0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x68, 0x6f, 0x65, 0x6e, 0x69, 0x78, 0x0, 0x45,
+0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49, 0x73, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x5f, 0x4d, 0x61, 0x6e, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6b, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e,
+0x6f, 0x75, 0x6d, 0x65, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x74, 0x69, 0x6e,
+0x69, 0x71, 0x75, 0x65, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x56, 0x6f, 0x73, 0x74,
+0x6f, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x36, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
+0x2f, 0x45, 0x66, 0x61, 0x74, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6f, 0x64, 0x74, 0x68,
+0x61, 0x62, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x46, 0x61, 0x65, 0x72, 0x6f, 0x65, 0x0, 0x41,
+0x73, 0x69, 0x61, 0x2f, 0x54, 0x6f, 0x6b, 0x79, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x6a, 0x75,
+0x62, 0x6c, 0x6a, 0x61, 0x6e, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x6a, 0x75, 0x6d, 0x62,
+0x75, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x69, 0x67, 0x6f, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x2f, 0x41, 0x74, 0x68, 0x65, 0x6e, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61,
+0x6c, 0x69, 0x66, 0x61, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6c, 0x61, 0x63, 0x65, 0x5f,
+0x42, 0x61, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x6f, 0x6f, 0x73, 0x65, 0x5f, 0x42, 0x61,
+0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x63, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x73,
+0x69, 0x61, 0x2f, 0x42, 0x61, 0x67, 0x68, 0x64, 0x61, 0x64, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x74,
+0x6f, 0x63, 0x6b, 0x68, 0x6f, 0x6c, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x6f, 0x72, 0x74,
+0x6f, 0x6c, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x52, 0x69, 0x79, 0x61, 0x64, 0x68, 0x0, 0x41, 0x73, 0x69, 0x61,
+0x2f, 0x54, 0x65, 0x68, 0x72, 0x61, 0x6e, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x37, 0x0, 0x45, 0x74,
+0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x39, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x75, 0x61, 0x6b,
+0x63, 0x68, 0x6f, 0x74, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x72, 0x75, 0x73, 0x73, 0x65, 0x6c,
+0x73, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x48, 0x6f, 0x6e, 0x6f, 0x6c, 0x75, 0x6c, 0x75, 0x0, 0x41,
+0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6c, 0x67, 0x69, 0x65, 0x72, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x43, 0x6f, 0x72, 0x61, 0x6c, 0x5f, 0x48, 0x61, 0x72, 0x62, 0x6f, 0x75, 0x72, 0x0, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x5f, 0x43, 0x72, 0x65, 0x65, 0x6b, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x4b, 0x69, 0x6e, 0x73, 0x68, 0x61, 0x73, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x6f, 0x73,
+0x74, 0x61, 0x5f, 0x52, 0x69, 0x63, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x76, 0x61,
+0x6e, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x62, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x4e, 0x69, 0x61, 0x6d, 0x65, 0x79, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x6a,
+0x75, 0x6c, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x68, 0x6e, 0x6f, 0x6d, 0x5f, 0x50, 0x65, 0x6e, 0x68, 0x0, 0x45,
+0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d, 0x61, 0x64, 0x72, 0x69, 0x64, 0x20, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x43, 0x65, 0x75, 0x74, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x73, 0x68, 0x67, 0x61, 0x62, 0x61, 0x74, 0x0,
+0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x62, 0x69, 0x6c, 0x69, 0x73, 0x69, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4a, 0x61,
+0x6b, 0x61, 0x72, 0x74, 0x61, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x50, 0x6f, 0x6e, 0x74, 0x69, 0x61, 0x6e, 0x61, 0x6b,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x75, 0x61, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x74, 0x69, 0x67, 0x75, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
+0x2f, 0x54, 0x6f, 0x6e, 0x67, 0x61, 0x74, 0x61, 0x70, 0x75, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x6b, 0x61,
+0x73, 0x73, 0x61, 0x72, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x5f, 0x4d, 0x6f,
+0x72, 0x65, 0x73, 0x62, 0x79, 0x0, 0x43, 0x53, 0x54, 0x36, 0x43, 0x44, 0x54, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x4e, 0x61, 0x73, 0x73, 0x61, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x6e,
+0x61, 0x75, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6f, 0x61, 0x5f, 0x56, 0x69, 0x73, 0x74,
+0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x69, 0x72, 0x75, 0x6e, 0x65, 0x70, 0x65, 0x20, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x5f, 0x56, 0x65, 0x6c, 0x68, 0x6f, 0x20, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x69, 0x6f, 0x5f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x6f, 0x0, 0x45, 0x75,
+0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4c, 0x69, 0x73, 0x62, 0x6f, 0x6e, 0x20, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63,
+0x2f, 0x4d, 0x61, 0x64, 0x65, 0x69, 0x72, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x41, 0x70, 0x69,
+0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x2d, 0x61, 0x75, 0x2d, 0x50, 0x72,
+0x69, 0x6e, 0x63, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x69, 0x72, 0x6f, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x72, 0x62, 0x61, 0x64, 0x6f, 0x73, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72,
+0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44,
+0x75, 0x73, 0x68, 0x61, 0x6e, 0x62, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x32, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4a, 0x6f, 0x68, 0x6e, 0x73, 0x74, 0x6f, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x44, 0x61, 0x72, 0x5f, 0x65, 0x73, 0x5f, 0x53, 0x61, 0x6c, 0x61, 0x61, 0x6d, 0x0, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x44, 0x6f, 0x75, 0x61, 0x6c, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x69, 0x6e,
+0x64, 0x68, 0x6f, 0x65, 0x6b, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x65, 0x6b, 0x61, 0x74, 0x65, 0x72, 0x69, 0x6e,
+0x62, 0x75, 0x72, 0x67, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x70, 0x61, 0x6c, 0x61, 0x0,
+0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x79, 0x6f, 0x74, 0x74, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x42, 0x69, 0x73, 0x73, 0x61, 0x75, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4b, 0x65, 0x72, 0x67,
+0x75, 0x65, 0x6c, 0x65, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x72, 0x61, 0x72, 0x65, 0x0,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x62, 0x72, 0x65, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4d, 0x61, 0x6a, 0x75, 0x72, 0x6f, 0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63,
+0x2f, 0x4b, 0x77, 0x61, 0x6a, 0x61, 0x6c, 0x65, 0x69, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x69, 0x6e, 0x67,
+0x61, 0x70, 0x6f, 0x72, 0x65, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x0, 0x50, 0x61, 0x63, 0x69,
+0x66, 0x69, 0x63, 0x2f, 0x4d, 0x69, 0x64, 0x77, 0x61, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d,
+0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42,
+0x61, 0x68, 0x69, 0x61, 0x5f, 0x42, 0x61, 0x6e, 0x64, 0x65, 0x72, 0x61, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x43, 0x61, 0x6e, 0x63, 0x75, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x72,
+0x69, 0x64, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x65,
+0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x6f, 0x6c, 0x6f, 0x6d, 0x62, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
+0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x69, 0x6d, 0x66, 0x65, 0x72,
+0x6f, 0x70, 0x6f, 0x6c, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x55, 0x7a, 0x68, 0x67, 0x6f, 0x72, 0x6f, 0x64,
+0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x61, 0x70, 0x6f, 0x72, 0x6f, 0x7a, 0x68, 0x79, 0x65, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x59, 0x6f, 0x72, 0x6b, 0x20, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x74, 0x72, 0x6f, 0x69, 0x74, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x50, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x20, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x56, 0x69, 0x6e, 0x63, 0x65,
+0x6e, 0x6e, 0x65, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61,
+0x2f, 0x57, 0x69, 0x6e, 0x61, 0x6d, 0x61, 0x63, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x65, 0x6e,
+0x74, 0x75, 0x63, 0x6b, 0x79, 0x2f, 0x4d, 0x6f, 0x6e, 0x74, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x75, 0x69, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0, 0x41, 0x75, 0x73, 0x74,
+0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c,
+0x69, 0x61, 0x2f, 0x4d, 0x65, 0x6c, 0x62, 0x6f, 0x75, 0x72, 0x6e, 0x65, 0x0, 0x45, 0x53, 0x54, 0x35, 0x45, 0x44, 0x54,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x42, 0x61, 0x72, 0x74, 0x68, 0x65, 0x6c, 0x65,
+0x6d, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x75, 0x77, 0x61, 0x69, 0x74, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x42, 0x61, 0x6e, 0x67, 0x75, 0x69, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x61, 0x6d, 0x61, 0x69, 0x63, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x41, 0x73, 0x75, 0x6e, 0x63, 0x69, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x53, 0x74, 0x5f, 0x56, 0x69, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x65,
+0x72, 0x6c, 0x69, 0x6e, 0x20, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x65, 0x6e,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x73, 0x5f, 0x41, 0x6e, 0x67, 0x65, 0x6c, 0x65, 0x73,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x6f, 0x5f, 0x44, 0x6f, 0x6d, 0x69, 0x6e,
+0x67, 0x6f, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x31, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41,
+0x6c, 0x6d, 0x61, 0x74, 0x79, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x79, 0x7a, 0x79, 0x6c, 0x6f, 0x72, 0x64, 0x61,
+0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x69, 0x73, 0x62, 0x61, 0x6e, 0x65, 0x20,
+0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x4c, 0x69, 0x6e, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x0, 0x50,
+0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x57, 0x61, 0x6c, 0x6c, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54,
+0x68, 0x69, 0x6d, 0x70, 0x68, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75,
+0x61, 0x68, 0x75, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x7a, 0x61, 0x74, 0x6c, 0x61,
+0x6e, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x50, 0x65, 0x72, 0x74, 0x68, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75, 0x72, 0x61, 0x63, 0x61, 0x6f, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63,
+0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x77, 0x73, 0x6f, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x74,
+0x6d, 0x61, 0x6e, 0x64, 0x75, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x67, 0x75, 0x69, 0x6c,
+0x6c, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x6e, 0x72, 0x6f, 0x76, 0x69, 0x61, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
+0x2f, 0x42, 0x65, 0x6c, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x75, 0x73, 0x63, 0x61,
+0x74, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x43, 0x68, 0x69, 0x73, 0x69, 0x6e, 0x61, 0x75, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x79, 0x65, 0x6e, 0x6e, 0x65, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e,
+0x2f, 0x52, 0x65, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x73, 0x6d, 0x65,
+0x72, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x6d, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
+0x42, 0x61, 0x6b, 0x75, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x44, 0x61, 0x72, 0x77, 0x69,
+0x6e, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x41, 0x6e, 0x74, 0x61, 0x6e, 0x61, 0x6e, 0x61, 0x72, 0x69, 0x76,
+0x6f, 0x0, 0x4d, 0x53, 0x54, 0x37, 0x4d, 0x44, 0x54, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x52, 0x69, 0x67,
+0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x6a, 0x69, 0x62, 0x6f, 0x75, 0x74, 0x69, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x64, 0x61, 0x6c, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x61, 0x6c, 0x61, 0x70, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61,
+0x2f, 0x4d, 0x61, 0x6e, 0x69, 0x6c, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69,
+0x61, 0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64,
+0x69, 0x61, 0x6e, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x65, 0x6e, 0x67, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x56, 0x65, 0x76, 0x61, 0x79, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72,
+0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x61, 0x6c, 0x6d, 0x65, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x75,
+0x62, 0x61, 0x69, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43, 0x68, 0x72, 0x69, 0x73, 0x74, 0x6d, 0x61, 0x73,
+0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x32, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63,
+0x2f, 0x52, 0x65, 0x79, 0x6b, 0x6a, 0x61, 0x76, 0x69, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x32,
+0x0, 0x50, 0x53, 0x54, 0x38, 0x50, 0x44, 0x54, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x47, 0x75, 0x65, 0x72,
+0x6e, 0x73, 0x65, 0x79, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x5a, 0x75, 0x72, 0x69, 0x63, 0x68, 0x0, 0x41,
+0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x74, 0x61, 0x6e, 0x6c, 0x65, 0x79, 0x0, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x2f, 0x5a, 0x61, 0x67, 0x72, 0x65, 0x62, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x54, 0x69,
+0x6a, 0x75, 0x61, 0x6e, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x61, 0x6c, 0x61, 0x75, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x20, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4a, 0x75, 0x6e, 0x65, 0x61, 0x75, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x4e, 0x6f, 0x6d, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x69, 0x74, 0x6b, 0x61, 0x20,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x59, 0x61, 0x6b, 0x75, 0x74, 0x61, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53,
+0x77, 0x69, 0x66, 0x74, 0x5f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f,
+0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x6f, 0x76, 0x6f, 0x6b,
+0x75, 0x7a, 0x6e, 0x65, 0x74, 0x73, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4f, 0x6d, 0x73, 0x6b, 0x0, 0x41, 0x66,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x70, 0x75, 0x74, 0x6f, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63,
+0x2f, 0x43, 0x61, 0x70, 0x65, 0x5f, 0x56, 0x65, 0x72, 0x64, 0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x50, 0x61, 0x72, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x62, 0x6f, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4a, 0x65,
+0x72, 0x73, 0x65, 0x79, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x46, 0x72, 0x65, 0x65, 0x74, 0x6f, 0x77, 0x6e,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x72, 0x61, 0x63, 0x61, 0x73, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x6c, 0x61, 0x6e, 0x63, 0x2d, 0x53, 0x61, 0x62, 0x6c, 0x6f, 0x6e, 0x0, 0x41, 0x73,
+0x69, 0x61, 0x2f, 0x44, 0x61, 0x6d, 0x61, 0x73, 0x63, 0x75, 0x73, 0x0, 0x41, 0x74, 0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63,
+0x2f, 0x43, 0x61, 0x6e, 0x61, 0x72, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x74, 0x69, 0x61,
+0x6e, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x57, 0x61, 0x72, 0x73, 0x61, 0x77, 0x0, 0x45, 0x74, 0x63,
+0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x31, 0x32, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x65, 0x72, 0x65, 0x76, 0x61, 0x6e,
+0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x72, 0x61, 0x7a, 0x7a, 0x61, 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x0,
+0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x75, 0x6e, 0x65, 0x69, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69,
+0x61, 0x2f, 0x48, 0x6f, 0x62, 0x61, 0x72, 0x74, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x43,
+0x75, 0x72, 0x72, 0x69, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x47, 0x69, 0x62, 0x72, 0x61, 0x6c, 0x74,
+0x61, 0x72, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x35, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74,
+0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x65, 0x79, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x69, 0x6c, 0x69, 0x0,
+0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x53, 0x61, 0x72, 0x61, 0x6a, 0x65, 0x76, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61,
+0x2f, 0x4b, 0x72, 0x61, 0x73, 0x6e, 0x6f, 0x79, 0x61, 0x72, 0x73, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x53, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x56, 0x61,
+0x6e, 0x63, 0x6f, 0x75, 0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x77, 0x73,
+0x6f, 0x6e, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x57, 0x68, 0x69, 0x74, 0x65, 0x68, 0x6f, 0x72, 0x73,
+0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x61, 0x72, 0x61, 0x77, 0x61, 0x0, 0x41, 0x73, 0x69,
+0x61, 0x2f, 0x41, 0x6d, 0x6d, 0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x49, 0x73, 0x74, 0x61, 0x6e,
+0x62, 0x75, 0x6c, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x65, 0x69, 0x72, 0x75, 0x74, 0x0, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x2f, 0x56, 0x69, 0x6c, 0x6e, 0x69, 0x75, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x54, 0x69,
+0x72, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x6f, 0x72, 0x74, 0x6f, 0x2d, 0x4e, 0x6f,
+0x76, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x45, 0x64, 0x6d, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x20,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x6d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x5f, 0x42, 0x61,
+0x79, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x75, 0x76, 0x69, 0x6b, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x59, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6b, 0x6e, 0x69, 0x66, 0x65, 0x0, 0x41, 0x74, 0x6c,
+0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x41, 0x7a, 0x6f, 0x72, 0x65, 0x73, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x41, 0x64, 0x64, 0x69, 0x73, 0x5f, 0x41, 0x62, 0x61, 0x62, 0x61, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x43,
+0x68, 0x61, 0x67, 0x6f, 0x73, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x5f,
+0x50, 0x72, 0x69, 0x6e, 0x63, 0x65, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x44, 0x75, 0x62, 0x6c, 0x69,
+0x6e, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x61, 0x67, 0x6f, 0x5f, 0x50, 0x61, 0x67, 0x6f, 0x0,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x73, 0x61, 0x6b, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
+0x2f, 0x42, 0x75, 0x64, 0x61, 0x70, 0x65, 0x73, 0x74, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x63,
+0x6f, 0x72, 0x65, 0x73, 0x62, 0x79, 0x73, 0x75, 0x6e, 0x64, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50,
+0x6f, 0x72, 0x74, 0x5f, 0x6f, 0x66, 0x5f, 0x53, 0x70, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x4a, 0x6f, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x73, 0x62, 0x75, 0x72, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x44, 0x68,
+0x61, 0x6b, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x61, 0x68, 0x69, 0x61, 0x0, 0x45, 0x75,
+0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x61, 0x6c, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x72, 0x61, 0x64, 0x0, 0x41, 0x66, 0x72,
+0x69, 0x63, 0x61, 0x2f, 0x4b, 0x68, 0x61, 0x72, 0x74, 0x6f, 0x75, 0x6d, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f,
+0x4c, 0x75, 0x78, 0x65, 0x6d, 0x62, 0x6f, 0x75, 0x72, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x76, 0x64,
+0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x30, 0x0, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d,
+0x61, 0x68, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x72, 0x61, 0x67, 0x75, 0x65, 0x0, 0x50, 0x61,
+0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x54, 0x72, 0x75, 0x6b, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44,
+0x61, 0x6e, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x68, 0x61, 0x76, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x43, 0x61, 0x6c,
+0x63, 0x75, 0x74, 0x74, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x50, 0x6f, 0x6e, 0x61, 0x70, 0x65,
+0x20, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4b, 0x6f, 0x73, 0x72, 0x61, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x2f, 0x4d, 0x6f, 0x6e, 0x61, 0x63, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74,
+0x5f, 0x4c, 0x75, 0x63, 0x69, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x61, 0x6e, 0x64, 0x61,
+0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x6f, 0x6d, 0x69, 0x6e, 0x69, 0x63, 0x61, 0x0, 0x41, 0x74,
+0x6c, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x2f, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x5f, 0x47, 0x65, 0x6f, 0x72, 0x67, 0x69, 0x61,
+0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x36, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x61,
+0x62, 0x6f, 0x72, 0x6f, 0x6e, 0x65, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50, 0x6f, 0x64, 0x67, 0x6f, 0x72,
+0x69, 0x63, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x47, 0x75, 0x61, 0x6d, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x42, 0x6f, 0x69, 0x73, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x68, 0x69, 0x70, 0x72, 0x6f,
+0x63, 0x6b, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x73, 0x61, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x61,
+0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x69, 0x67, 0x61, 0x6c, 0x69, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x54, 0x68, 0x75, 0x6c, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4e, 0x69, 0x63, 0x6f, 0x73, 0x69,
+0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x67, 0x61, 0x64, 0x61, 0x6e, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f,
+0x41, 0x6e, 0x61, 0x64, 0x79, 0x72, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x6d, 0x63, 0x68, 0x61, 0x74, 0x6b,
+0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x74, 0x5f, 0x54, 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x0,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x62, 0x61, 0x62, 0x61, 0x6e, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
+0x42, 0x61, 0x68, 0x72, 0x61, 0x69, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x50, 0x75, 0x65, 0x72,
+0x74, 0x6f, 0x5f, 0x52, 0x69, 0x63, 0x6f, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x6f, 0x67, 0x61, 0x64,
+0x69, 0x73, 0x68, 0x75, 0x0, 0x41, 0x6e, 0x74, 0x61, 0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x61, 0x76, 0x69,
+0x73, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x4e, 0x61, 0x75, 0x72, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x41, 0x63, 0x63, 0x72, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x61, 0x6e, 0x67, 0x6b, 0x6f,
+0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x56, 0x61, 0x74, 0x69, 0x63, 0x61, 0x6e, 0x0, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x46, 0x6f, 0x72, 0x74, 0x61, 0x6c, 0x65, 0x7a, 0x61, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x42, 0x65, 0x6c, 0x65, 0x6d, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x63,
+0x65, 0x69, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x52, 0x65, 0x63, 0x69, 0x66, 0x65, 0x20, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6e, 0x74, 0x61, 0x72, 0x65, 0x6d, 0x0, 0x45, 0x75, 0x72, 0x6f,
+0x70, 0x65, 0x2f, 0x43, 0x6f, 0x70, 0x65, 0x6e, 0x68, 0x61, 0x67, 0x65, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e,
+0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x4b, 0x6e, 0x6f, 0x78, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49,
+0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x2f, 0x54, 0x65, 0x6c, 0x6c, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x20, 0x41, 0x6d, 0x65,
+0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x65, 0x6e, 0x6f, 0x6d, 0x69, 0x6e, 0x65, 0x65, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x42, 0x65, 0x75, 0x6c,
+0x61, 0x68, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b,
+0x6f, 0x74, 0x61, 0x2f, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e,
+0x6f, 0x72, 0x74, 0x68, 0x5f, 0x44, 0x61, 0x6b, 0x6f, 0x74, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x53, 0x61, 0x6c, 0x65,
+0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x72, 0x69, 0x67, 0x6f, 0x74, 0x0, 0x41, 0x73,
+0x69, 0x61, 0x2f, 0x4a, 0x65, 0x72, 0x75, 0x73, 0x61, 0x6c, 0x65, 0x6d, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x41, 0x72, 0x75, 0x62, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x61, 0x72, 0x61, 0x63, 0x68, 0x69, 0x0,
+0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f, 0x5f, 0x54, 0x6f, 0x6d, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61,
+0x2f, 0x50, 0x79, 0x6f, 0x6e, 0x67, 0x79, 0x61, 0x6e, 0x67, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x6c, 0x61, 0x64,
+0x69, 0x76, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x61, 0x6b, 0x68, 0x61, 0x6c, 0x69,
+0x6e, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x73, 0x74, 0x2d, 0x4e, 0x65, 0x72, 0x61, 0x0, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x4f, 0x75, 0x61, 0x67, 0x61, 0x64, 0x6f, 0x75, 0x67, 0x6f, 0x75, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63,
+0x61, 0x2f, 0x42, 0x6c, 0x61, 0x6e, 0x74, 0x79, 0x72, 0x65, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x52,
+0x61, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x67, 0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x33, 0x0, 0x41,
+0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x62, 0x69, 0x64, 0x6a, 0x61, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65,
+0x2f, 0x4c, 0x6f, 0x6e, 0x64, 0x6f, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x75, 0x61, 0x74,
+0x65, 0x6d, 0x61, 0x6c, 0x61, 0x0, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x2f, 0x46, 0x69, 0x6a, 0x69, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x61, 0x79, 0x6d, 0x61, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x49,
+0x72, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x52, 0x6f, 0x6d, 0x65, 0x0, 0x49,
+0x6e, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x75, 0x72, 0x69, 0x74, 0x69, 0x75, 0x73, 0x0, 0x45, 0x74, 0x63, 0x2f,
+0x47, 0x4d, 0x54, 0x2d, 0x34, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2b, 0x33, 0x0, 0x41, 0x66, 0x72, 0x69,
+0x63, 0x61, 0x2f, 0x43, 0x6f, 0x6e, 0x61, 0x6b, 0x72, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53,
+0x61, 0x6e, 0x74, 0x61, 0x5f, 0x49, 0x73, 0x61, 0x62, 0x65, 0x6c, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44,
+0x61, 0x6b, 0x61, 0x72, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x41, 0x6e, 0x64, 0x6f, 0x72, 0x72, 0x61, 0x0,
+0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4f, 0x73, 0x6c, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x51, 0x61, 0x74,
+0x61, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x52, 0x61, 0x6e, 0x67, 0x6f, 0x6f, 0x6e, 0x0, 0x49, 0x6e, 0x64, 0x69,
+0x61, 0x6e, 0x2f, 0x4d, 0x61, 0x6c, 0x64, 0x69, 0x76, 0x65, 0x73, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x50,
+0x61, 0x72, 0x69, 0x73, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x64, 0x65, 0x6e, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70,
+0x65, 0x2f, 0x56, 0x69, 0x65, 0x6e, 0x6e, 0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x38, 0x0, 0x45,
+0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x33, 0x0, 0x41, 0x72, 0x63, 0x74, 0x69, 0x63, 0x2f, 0x4c, 0x6f, 0x6e,
+0x67, 0x79, 0x65, 0x61, 0x72, 0x62, 0x79, 0x65, 0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x47, 0x72,
+0x65, 0x6e, 0x61, 0x64, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x69, 0x6d, 0x61, 0x0, 0x41,
+0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4c, 0x75, 0x62, 0x75, 0x6d, 0x62, 0x61, 0x73, 0x68, 0x69, 0x0, 0x41, 0x73, 0x69,
+0x61, 0x2f, 0x59, 0x61, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x20, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4b, 0x68, 0x61, 0x6e, 0x64,
+0x79, 0x67, 0x61, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x72, 0x61, 0x74, 0x69, 0x73, 0x6c, 0x61, 0x76,
+0x61, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x31, 0x31, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x4d, 0x61, 0x6c, 0x61, 0x62, 0x6f, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4b, 0x72, 0x61, 0x6c, 0x65,
+0x6e, 0x64, 0x69, 0x6a, 0x6b, 0x0, 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0x2d, 0x35, 0x0, 0x41, 0x6e, 0x74, 0x61,
+0x72, 0x63, 0x74, 0x69, 0x63, 0x61, 0x2f, 0x4d, 0x61, 0x63, 0x71, 0x75, 0x61, 0x72, 0x69, 0x65, 0x0, 0x45, 0x75, 0x72,
+0x6f, 0x70, 0x65, 0x2f, 0x53, 0x6b, 0x6f, 0x70, 0x6a, 0x65, 0x0, 0x41, 0x66, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x64,
+0x6a, 0x61, 0x6d, 0x65, 0x6e, 0x61, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x42, 0x69, 0x73, 0x68, 0x6b, 0x65, 0x6b, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x41, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x42, 0x75, 0x65, 0x6e, 0x6f, 0x73, 0x5f, 0x41, 0x69, 0x72, 0x65, 0x73, 0x0, 0x41,
+0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x48, 0x61, 0x6c, 0x69, 0x66, 0x61, 0x78, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72,
+0x61, 0x6c, 0x69, 0x61, 0x2f, 0x53, 0x79, 0x64, 0x6e, 0x65, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f,
+0x52, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x41, 0x64, 0x65,
+0x6c, 0x61, 0x69, 0x64, 0x65, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x41, 0x6c, 0x6d, 0x61, 0x74, 0x79, 0x0, 0x41, 0x6d,
+0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x75, 0x69, 0x61, 0x62, 0x61, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61,
+0x2f, 0x43, 0x68, 0x69, 0x63, 0x61, 0x67, 0x6f, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x53, 0x68, 0x61, 0x6e, 0x67, 0x68,
+0x61, 0x69, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x42, 0x72, 0x69, 0x73, 0x62, 0x61, 0x6e,
+0x65, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x53, 0x61, 0x6f, 0x5f, 0x50, 0x61, 0x75, 0x6c, 0x6f, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x4e, 0x65, 0x77, 0x5f, 0x59, 0x6f, 0x72, 0x6b, 0x0, 0x45, 0x75, 0x72,
+0x6f, 0x70, 0x65, 0x2f, 0x4b, 0x69, 0x65, 0x76, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x4d, 0x61, 0x67, 0x61, 0x64, 0x61,
+0x6e, 0x0, 0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x43, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x44, 0x65, 0x6e, 0x76, 0x65, 0x72, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f,
+0x4e, 0x6f, 0x76, 0x6f, 0x73, 0x69, 0x62, 0x69, 0x72, 0x73, 0x6b, 0x0, 0x45, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x2f, 0x4d,
+0x6f, 0x73, 0x63, 0x6f, 0x77, 0x0, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6c, 0x69, 0x61, 0x2f, 0x48, 0x6f, 0x62, 0x61,
+0x72, 0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x55, 0x6c, 0x61, 0x61, 0x6e, 0x62, 0x61, 0x61, 0x74, 0x61, 0x72, 0x0,
+0x41, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x61, 0x2f, 0x49, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x6f, 0x6c, 0x69, 0x73,
+0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x56, 0x6c, 0x61, 0x64, 0x69, 0x76, 0x6f, 0x73, 0x74, 0x6f, 0x6b, 0x0, 0x45, 0x75,
+0x72, 0x6f, 0x70, 0x65, 0x2f, 0x42, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x54, 0x61, 0x73,
+0x68, 0x6b, 0x65, 0x6e, 0x74, 0x0, 0x41, 0x73, 0x69, 0x61, 0x2f, 0x59, 0x61, 0x6b, 0x75, 0x74, 0x73, 0x6b, 0x0, 0x55,
+0x54, 0x43, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x33, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x31, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x31, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x39, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x37, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x36, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x35, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x34, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x33, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x32, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x31, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2d, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x30, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x32, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x33, 0x3a,
+0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x34, 0x3a,
+0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a,
+0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x35, 0x3a, 0x34, 0x35, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x36, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x37, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x38, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x30, 0x39, 0x3a, 0x33, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x30, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x31, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x32, 0x3a,
+0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x33, 0x3a, 0x30, 0x30, 0x0, 0x55, 0x54, 0x43, 0x2b, 0x31, 0x34, 0x3a,
+0x30, 0x30, 0x0
};
// GENERATED PART ENDS HERE
diff --git a/src/corelib/tools/qtimezoneprivate_icu.cpp b/src/corelib/tools/qtimezoneprivate_icu.cpp
index f43b9276a1..254900eb96 100644
--- a/src/corelib/tools/qtimezoneprivate_icu.cpp
+++ b/src/corelib/tools/qtimezoneprivate_icu.cpp
@@ -277,12 +277,12 @@ QIcuTimeZonePrivate::QIcuTimeZonePrivate()
}
// Create a named time zone
-QIcuTimeZonePrivate::QIcuTimeZonePrivate(const QByteArray &olsenId)
+QIcuTimeZonePrivate::QIcuTimeZonePrivate(const QByteArray &ianaId)
: m_ucal(0)
{
// Need to check validity here as ICu will create a GMT tz if name is invalid
- if (availableTimeZoneIds().contains(olsenId))
- init(olsenId);
+ if (availableTimeZoneIds().contains(ianaId))
+ init(ianaId);
}
QIcuTimeZonePrivate::QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other)
@@ -307,9 +307,9 @@ QTimeZonePrivate *QIcuTimeZonePrivate::clone()
return new QIcuTimeZonePrivate(*this);
}
-void QIcuTimeZonePrivate::init(const QByteArray &olsenId)
+void QIcuTimeZonePrivate::init(const QByteArray &ianaId)
{
- m_id = olsenId;
+ m_id = ianaId;
const QString id = QString::fromUtf8(m_id);
UErrorCode status = U_ZERO_ERROR;
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
index 69d2c42d27..3d95377850 100644
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ b/src/corelib/tools/qtimezoneprivate_mac.mm
@@ -64,10 +64,10 @@ QMacTimeZonePrivate::QMacTimeZonePrivate()
}
// Create a named time zone
-QMacTimeZonePrivate::QMacTimeZonePrivate(const QByteArray &olsenId)
+QMacTimeZonePrivate::QMacTimeZonePrivate(const QByteArray &ianaId)
: m_nstz(0)
{
- init(olsenId);
+ init(ianaId);
}
QMacTimeZonePrivate::QMacTimeZonePrivate(const QMacTimeZonePrivate &other)
@@ -86,12 +86,12 @@ QTimeZonePrivate *QMacTimeZonePrivate::clone()
return new QMacTimeZonePrivate(*this);
}
-void QMacTimeZonePrivate::init(const QByteArray &olsenId)
+void QMacTimeZonePrivate::init(const QByteArray &ianaId)
{
- if (availableTimeZoneIds().contains(olsenId)) {
- m_nstz = [NSTimeZone timeZoneWithName:QCFString::toNSString(QString::fromUtf8(olsenId))];
+ if (availableTimeZoneIds().contains(ianaId)) {
+ m_nstz = [NSTimeZone timeZoneWithName:QCFString::toNSString(QString::fromUtf8(ianaId))];
if (m_nstz)
- m_id = olsenId;
+ m_id = ianaId;
}
}
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index 4fbb3ff6e0..417ee2efbf 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -143,7 +143,7 @@ public:
static Data invalidData();
static QTimeZone::OffsetData invalidOffsetData();
static QTimeZone::OffsetData toOffsetData(const Data &data);
- static bool isValidId(const QByteArray &olsenId);
+ static bool isValidId(const QByteArray &ianaId);
static QString isoOffsetFormat(int offsetFromUtc);
static QByteArray ianaIdToWindowsId(const QByteArray &ianaId);
@@ -217,7 +217,7 @@ public:
// Create default time zone
QIcuTimeZonePrivate();
// Create named time zone
- QIcuTimeZonePrivate(const QByteArray &olsenId);
+ QIcuTimeZonePrivate(const QByteArray &ianaId);
QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other);
~QIcuTimeZonePrivate();
@@ -247,7 +247,7 @@ public:
QSet<QByteArray> availableTimeZoneIds(int offsetFromUtc) const Q_DECL_OVERRIDE;
private:
- void init(const QByteArray &olsenId);
+ void init(const QByteArray &ianaId);
UCalendar *m_ucal;
};
@@ -260,7 +260,7 @@ public:
// Create default time zone
QTzTimeZonePrivate();
// Create named time zone
- QTzTimeZonePrivate(const QByteArray &olsenId);
+ QTzTimeZonePrivate(const QByteArray &ianaId);
QTzTimeZonePrivate(const QTzTimeZonePrivate &other);
~QTzTimeZonePrivate();
@@ -296,7 +296,7 @@ public:
QSet<QByteArray> availableTimeZoneIds(QLocale::Country country) const Q_DECL_OVERRIDE;
private:
- void init(const QByteArray &olsenId);
+ void init(const QByteArray &ianaId);
struct QTzTransitionTime {
qint64 atMSecsSinceEpoch;
@@ -327,7 +327,7 @@ public:
// Create default time zone
QMacTimeZonePrivate();
// Create named time zone
- QMacTimeZonePrivate(const QByteArray &olsenId);
+ QMacTimeZonePrivate(const QByteArray &ianaId);
QMacTimeZonePrivate(const QMacTimeZonePrivate &other);
~QMacTimeZonePrivate();
@@ -378,7 +378,7 @@ public:
// Create default time zone
QWinTimeZonePrivate();
// Create named time zone
- QWinTimeZonePrivate(const QByteArray &olsenId);
+ QWinTimeZonePrivate(const QByteArray &ianaId);
QWinTimeZonePrivate(const QWinTimeZonePrivate &other);
~QWinTimeZonePrivate();
@@ -408,7 +408,7 @@ public:
QSet<QByteArray> availableTimeZoneIds() const Q_DECL_OVERRIDE;
private:
- void init(const QByteArray &olsenId);
+ void init(const QByteArray &ianaId);
QWinTransitionRule ruleForYear(int year) const;
QTimeZonePrivate::Data ruleToData(const QWinTransitionRule &rule, qint64 atMSecsSinceEpoch,
QTimeZone::TimeType type) const;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 1fb6bb1b5a..b4ea91e626 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -134,6 +134,8 @@ struct QTzType {
bool tz_ttisgmt; // Is in UTC time
bool tz_ttisstd; // Is in Standard time
};
+Q_DECLARE_TYPEINFO(QTzType, Q_PRIMITIVE_TYPE);
+
// TZ File parsing
@@ -521,12 +523,12 @@ QTzTimeZonePrivate::QTzTimeZonePrivate()
}
// Create a named time zone
-QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &olsenId)
+QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId)
#ifdef QT_USE_ICU
: m_icu(0)
#endif // QT_USE_ICU
{
- init(olsenId);
+ init(ianaId);
}
QTzTimeZonePrivate::QTzTimeZonePrivate(const QTzTimeZonePrivate &other)
@@ -548,19 +550,19 @@ QTimeZonePrivate *QTzTimeZonePrivate::clone()
return new QTzTimeZonePrivate(*this);
}
-void QTzTimeZonePrivate::init(const QByteArray &olsenId)
+void QTzTimeZonePrivate::init(const QByteArray &ianaId)
{
QFile tzif;
- if (olsenId.isEmpty()) {
+ if (ianaId.isEmpty()) {
// Open system tz
tzif.setFileName(QStringLiteral("/etc/localtime"));
if (!tzif.open(QIODevice::ReadOnly))
return;
} else {
// Open named tz, try modern path first, if fails try legacy path
- tzif.setFileName(QLatin1String("/usr/share/zoneinfo/") + QString::fromLocal8Bit(olsenId));
+ tzif.setFileName(QLatin1String("/usr/share/zoneinfo/") + QString::fromLocal8Bit(ianaId));
if (!tzif.open(QIODevice::ReadOnly)) {
- tzif.setFileName(QLatin1String("/usr/lib/zoneinfo/") + QString::fromLocal8Bit(olsenId));
+ tzif.setFileName(QLatin1String("/usr/lib/zoneinfo/") + QString::fromLocal8Bit(ianaId));
if (!tzif.open(QIODevice::ReadOnly))
return;
}
@@ -665,10 +667,10 @@ void QTzTimeZonePrivate::init(const QByteArray &olsenId)
m_tranTimes.append(tran);
}
- if (olsenId.isEmpty())
+ if (ianaId.isEmpty())
m_id = systemTimeZoneId();
else
- m_id = olsenId;
+ m_id = ianaId;
}
QLocale::Country QTzTimeZonePrivate::country() const
@@ -910,55 +912,55 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs
QByteArray QTzTimeZonePrivate::systemTimeZoneId() const
{
// Check TZ env var first, if not populated try find it
- QByteArray olsenId = qgetenv("TZ");
- if (!olsenId.isEmpty() && olsenId.at(0) == ':')
- olsenId = olsenId.mid(1);
+ QByteArray ianaId = qgetenv("TZ");
+ if (!ianaId.isEmpty() && ianaId.at(0) == ':')
+ ianaId = ianaId.mid(1);
// On Debian Etch and later /etc/localtime is real file with name held in /etc/timezone
- if (olsenId.isEmpty()) {
+ if (ianaId.isEmpty()) {
QFile tzif(QStringLiteral("/etc/timezone"));
if (tzif.open(QIODevice::ReadOnly)) {
// TODO QTextStream inefficient, replace later
QTextStream ts(&tzif);
if (!ts.atEnd())
- olsenId = ts.readLine().toUtf8();
+ ianaId = ts.readLine().toUtf8();
}
}
// On other distros /etc/localtime is symlink to real file so can extract name from the path
- if (olsenId.isEmpty()) {
+ if (ianaId.isEmpty()) {
const QString path = QFile::symLinkTarget(QStringLiteral("/etc/localtime"));
if (!path.isEmpty()) {
// /etc/localtime is a symlink to the current TZ file, so extract from path
int index = path.indexOf(QLatin1String("/zoneinfo/")) + 10;
- olsenId = path.mid(index).toUtf8();
+ ianaId = path.mid(index).toUtf8();
}
}
// On some Red Hat distros /etc/localtime is real file with name held in /etc/sysconfig/clock
// in a line like ZONE="Europe/Oslo" or TIMEZONE="Europe/Oslo"
- if (olsenId.isEmpty()) {
+ if (ianaId.isEmpty()) {
QFile tzif(QStringLiteral("/etc/sysconfig/clock"));
if (tzif.open(QIODevice::ReadOnly)) {
// TODO QTextStream inefficient, replace later
QTextStream ts(&tzif);
QString line;
- while (olsenId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
+ while (ianaId.isEmpty() && !ts.atEnd() && ts.status() == QTextStream::Ok) {
line = ts.readLine();
if (line.left(5) == QStringLiteral("ZONE=")) {
- olsenId = line.mid(6, line.size() - 7).toUtf8();
+ ianaId = line.mid(6, line.size() - 7).toUtf8();
} else if (line.left(9) == QStringLiteral("TIMEZONE=")) {
- olsenId = line.mid(10, line.size() - 11).toUtf8();
+ ianaId = line.mid(10, line.size() - 11).toUtf8();
}
}
}
}
// Give up for now and return UTC
- if (olsenId.isEmpty())
- olsenId = QByteArrayLiteral("UTC");
+ if (ianaId.isEmpty())
+ ianaId = QByteArrayLiteral("UTC");
- return olsenId;
+ return ianaId;
}
QSet<QByteArray> QTzTimeZonePrivate::availableTimeZoneIds() const
diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp
index 04588b2ba8..052e584855 100644
--- a/src/corelib/tools/qtimezoneprivate_win.cpp
+++ b/src/corelib/tools/qtimezoneprivate_win.cpp
@@ -334,10 +334,10 @@ QWinTimeZonePrivate::QWinTimeZonePrivate()
}
// Create a named time zone
-QWinTimeZonePrivate::QWinTimeZonePrivate(const QByteArray &olsenId)
+QWinTimeZonePrivate::QWinTimeZonePrivate(const QByteArray &ianaId)
: QTimeZonePrivate()
{
- init(olsenId);
+ init(ianaId);
}
QWinTimeZonePrivate::QWinTimeZonePrivate(const QWinTimeZonePrivate &other)
@@ -356,14 +356,14 @@ QTimeZonePrivate *QWinTimeZonePrivate::clone()
return new QWinTimeZonePrivate(*this);
}
-void QWinTimeZonePrivate::init(const QByteArray &olsenId)
+void QWinTimeZonePrivate::init(const QByteArray &ianaId)
{
- if (olsenId.isEmpty()) {
+ if (ianaId.isEmpty()) {
m_windowsId = windowsSystemZoneId();
m_id = systemTimeZoneId();
} else {
- m_windowsId = ianaIdToWindowsId(olsenId);
- m_id = olsenId;
+ m_windowsId = ianaIdToWindowsId(ianaId);
+ m_id = ianaId;
}
if (!m_windowsId.isEmpty()) {
@@ -626,26 +626,26 @@ QByteArray QWinTimeZonePrivate::systemTimeZoneId() const
{
const QLocale::Country country = userCountry();
const QByteArray windowsId = windowsSystemZoneId();
- QByteArray olsenId;
+ QByteArray ianaId;
// If we have a real country, then try get a specific match for that country
if (country != QLocale::AnyCountry)
- olsenId = windowsIdToDefaultIanaId(windowsId, country);
+ ianaId = windowsIdToDefaultIanaId(windowsId, country);
// If we don't have a real country, or there wasn't a specific match, try the global default
- if (olsenId.isEmpty()) {
- olsenId = windowsIdToDefaultIanaId(windowsId);
+ if (ianaId.isEmpty()) {
+ ianaId = windowsIdToDefaultIanaId(windowsId);
// If no global default then probably an unknown Windows ID so return UTC
- if (olsenId.isEmpty())
+ if (ianaId.isEmpty())
return QByteArrayLiteral("UTC");
}
- return olsenId;
+ return ianaId;
}
QSet<QByteArray> QWinTimeZonePrivate::availableTimeZoneIds() const
{
QSet<QByteArray> set;
foreach (const QByteArray &winId, availableWindowsIds()) {
- foreach (const QByteArray &olsenId, windowsIdToIanaIds(winId))
- set << olsenId;
+ foreach (const QByteArray &ianaId, windowsIdToIanaIds(winId))
+ set << ianaId;
}
return set;
}
diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/tools/qunicodetables.cpp
index 568f3aa1fb..41a22a779a 100644
--- a/src/corelib/tools/qunicodetables.cpp
+++ b/src/corelib/tools/qunicodetables.cpp
@@ -75,227 +75,210 @@ static const unsigned short uc_property_trie[] = {
11184, 11184, 11184, 11184, 11184, 11184, 11184, 11184,
11184, 11184, 11184, 11216, 11248, 11280, 11280, 11312,
11344, 11376, 11408, 11440, 11472, 11504, 11536, 11568,
- 11600, 11632, 11664, 11696, 11632, 11728, 11760, 11792,
- 11824, 11856, 11888, 11920, 11952, 11984, 12016, 12048,
- 12080, 12112, 12144, 12176, 12208, 12240, 9904, 9904,
- 12272, 12304, 12336, 12368, 12400, 12432, 12464, 12496,
- 12528, 12560, 12592, 12624, 9904, 9904, 12656, 12688,
- 12720, 12752, 12784, 12816, 12848, 12880, 12912, 12944,
- 12976, 12976, 12976, 12976, 13008, 12976, 12976, 13040,
- 13072, 13104, 13136, 13168, 13200, 13232, 13264, 13296,
-
- 13328, 13360, 13392, 13424, 13456, 13488, 13520, 13552,
- 13584, 13616, 13648, 13680, 13712, 13744, 13776, 13808,
- 13840, 13872, 13904, 13936, 13968, 14000, 14032, 14064,
- 14096, 14128, 14160, 14192, 14224, 14256, 14288, 14320,
- 14352, 14384, 14416, 14448, 14480, 14512, 14544, 14576,
- 14352, 14352, 14352, 14352, 14608, 14640, 14672, 14704,
- 14736, 14768, 14352, 14800, 14832, 14864, 14896, 14928,
- 14960, 14992, 15024, 15056, 15088, 15120, 15152, 15184,
- 15216, 15216, 15216, 15216, 15216, 15216, 15216, 15216,
- 15248, 15248, 15248, 15248, 15280, 15312, 15344, 15376,
- 15408, 15440, 15248, 15472, 15504, 15536, 15568, 15600,
- 15632, 15664, 15696, 9904, 9904, 9904, 9904, 9904,
- 15728, 15760, 15792, 15824, 15856, 15856, 15856, 15888,
- 15920, 15952, 15984, 16016, 16048, 16080, 16080, 16112,
- 16144, 16176, 9904, 9904, 16208, 16240, 16240, 16272,
- 16304, 16304, 16304, 16304, 16304, 16304, 16336, 16368,
-
- 16400, 16432, 16464, 16496, 16528, 16560, 16592, 16624,
- 16656, 16688, 16720, 16720, 16752, 16784, 16816, 16848,
- 16880, 16912, 16944, 16976, 16912, 17008, 17040, 17072,
- 17104, 17104, 17136, 17168, 17200, 17200, 17232, 17264,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
-
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17296, 17296, 17296,
- 17296, 17296, 17296, 17296, 17296, 17328, 17360, 17360,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
-
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
-
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
-
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
-
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
-
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17392, 17392, 17392,
- 17392, 17392, 17392, 17392, 17392, 17424, 17456, 17488,
-
- 17520, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
- 17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
- 17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
- 17552, 17552, 17552, 17552, 17552, 17552, 17552, 17552,
- 17552, 17552, 17552, 17552, 17584, 17616, 17648, 17680,
- 17712, 17712, 17712, 17712, 17712, 17712, 17712, 17712,
- 17744, 17776, 17808, 17840, 17872, 17904, 17904, 17936,
- 17968, 18000, 18032, 18064, 18096, 18128, 9904, 18160,
- 18192, 18224, 18256, 18288, 18320, 18352, 18384, 18416,
- 18448, 18480, 18512, 18544, 18576, 18608, 18640, 9904,
- 18672, 18704, 18736, 18768, 18800, 18832, 18864, 18896,
- 18928, 18960, 9904, 9904, 9904, 9904, 18992, 19024,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
-
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
-
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
-
- 19088, 19120, 19152, 19184, 19216, 19248, 19056, 19088,
- 19120, 19152, 19184, 19216, 19248, 19056, 19088, 19120,
- 19152, 19184, 19216, 19248, 19056, 19088, 19120, 19152,
- 19184, 19216, 19248, 19056, 19088, 19120, 19152, 19184,
- 19216, 19248, 19056, 19088, 19120, 19152, 19184, 19216,
- 19248, 19056, 19088, 19120, 19152, 19184, 19216, 19248,
- 19056, 19088, 19120, 19152, 19184, 19216, 19248, 19056,
- 19088, 19120, 19152, 19184, 19216, 19280, 19312, 19344,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
- 19376, 19376, 19376, 19376, 19376, 19376, 19376, 19376,
-
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
+ 11600, 11632, 11664, 11696, 11728, 11760, 11792, 11824,
+ 11856, 11888, 11920, 11952, 11984, 12016, 12048, 12080,
+ 12112, 12144, 12176, 12208, 12240, 12272, 9904, 9904,
+ 12304, 12336, 12368, 12400, 12432, 12464, 12496, 12528,
+ 12560, 12592, 12624, 12656, 9904, 9904, 12688, 12720,
+ 12752, 12784, 12816, 12848, 12880, 12912, 12944, 12976,
+ 13008, 13008, 13008, 13008, 13040, 13008, 13008, 13072,
+ 13104, 13136, 13168, 13200, 13232, 13264, 13296, 13328,
+
+ 13360, 13392, 13424, 13456, 13488, 13520, 13552, 13584,
+ 13616, 13648, 13680, 13712, 13744, 13776, 13808, 13840,
+ 13872, 13904, 13936, 13968, 14000, 14032, 14064, 14096,
+ 14128, 14160, 14192, 14224, 14256, 14288, 14320, 14352,
+ 14384, 14416, 14448, 14480, 14512, 14544, 14576, 14608,
+ 14384, 14384, 14384, 14384, 14640, 14672, 14704, 14736,
+ 14768, 14800, 14384, 14832, 14864, 14896, 14928, 14960,
+ 14992, 15024, 15056, 15088, 15120, 15152, 15184, 15216,
+ 15248, 15248, 15248, 15248, 15248, 15248, 15248, 15248,
+ 15280, 15280, 15280, 15280, 15312, 15344, 15376, 15408,
+ 15440, 15472, 15280, 15504, 15536, 15568, 15600, 15632,
+ 15664, 15696, 15728, 9904, 9904, 9904, 9904, 9904,
+ 15760, 15792, 15824, 15856, 15888, 15888, 15888, 15920,
+ 15952, 15984, 16016, 16048, 16080, 16112, 16112, 16144,
+ 16176, 16208, 9904, 9904, 16240, 16272, 16272, 16304,
+ 16336, 16336, 16336, 16336, 16336, 16336, 16368, 16400,
+
+ 16432, 16464, 16496, 16528, 16560, 16592, 16624, 16656,
+ 16688, 16720, 16752, 16752, 16784, 16816, 16848, 16880,
+ 16912, 16944, 16976, 17008, 16944, 17040, 17072, 17104,
+ 17136, 17136, 17168, 17200, 17232, 17232, 17264, 17296,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17328, 17328, 17328,
+ 17328, 17328, 17328, 17328, 17328, 17360, 17392, 17392,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17424, 17424, 17424,
+ 17424, 17424, 17424, 17424, 17424, 17456, 17488, 17520,
+
+ 17552, 17584, 17584, 17584, 17584, 17584, 17584, 17584,
+ 17584, 17584, 17584, 17584, 17584, 17584, 17584, 17584,
+ 17584, 17584, 17584, 17584, 17584, 17584, 17584, 17584,
+ 17584, 17584, 17584, 17584, 17584, 17584, 17584, 17584,
+ 17584, 17584, 17584, 17584, 17616, 17648, 17680, 17712,
+ 17744, 17744, 17744, 17744, 17744, 17744, 17744, 17744,
+ 17776, 17808, 17840, 17872, 17904, 17936, 17936, 17968,
+ 18000, 18032, 18064, 18096, 18128, 18160, 9904, 18192,
+ 18224, 18256, 18288, 18320, 18352, 18384, 18416, 18448,
+ 18480, 18512, 18544, 18576, 18608, 18640, 18672, 9904,
+ 18704, 18736, 18768, 18800, 18832, 18864, 18896, 18928,
+ 18960, 18992, 9904, 9904, 9904, 9904, 19024, 19056,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+
+ 19120, 19152, 19184, 19216, 19248, 19280, 19088, 19120,
+ 19152, 19184, 19216, 19248, 19280, 19088, 19120, 19152,
+ 19184, 19216, 19248, 19280, 19088, 19120, 19152, 19184,
+ 19216, 19248, 19280, 19088, 19120, 19152, 19184, 19216,
+ 19248, 19280, 19088, 19120, 19152, 19184, 19216, 19248,
+ 19280, 19088, 19120, 19152, 19184, 19216, 19248, 19280,
+ 19088, 19120, 19152, 19184, 19216, 19248, 19280, 19088,
+ 19120, 19152, 19184, 19216, 19248, 19312, 19344, 19376,
19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
@@ -305,568 +288,585 @@ static const unsigned short uc_property_trie[] = {
19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
- 19408, 19408, 19408, 19408, 19408, 19408, 19408, 19408,
19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
- 19472, 19504, 19536, 19568, 19600, 19600, 19632, 17488,
- 19664, 19696, 19728, 19760, 19760, 19792, 19824, 19760,
- 19760, 19760, 19760, 19760, 19760, 19760, 19760, 19760,
- 19760, 19856, 19888, 19760, 19920, 19760, 19952, 19984,
- 20016, 20048, 20080, 20112, 19760, 19760, 19760, 20144,
- 20176, 20208, 20240, 20272, 20304, 20336, 20368, 20400,
-
- 20432, 20464, 20496, 9904, 20528, 20528, 20528, 20560,
- 20592, 20624, 20656, 20688, 20720, 9904, 20752, 20784,
- 9904, 9904, 9904, 9904, 20816, 20848, 20880, 9904,
- 20912, 20944, 20976, 9904, 21008, 21040, 21072, 9904,
- 21104, 21136, 21168, 21200, 21232, 21264, 9904, 9904,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440,
+ 19472, 19472, 19472, 19472, 19472, 19472, 19472, 19472,
+ 19504, 19536, 19568, 19600, 19632, 19632, 19664, 17520,
+ 19696, 19728, 19760, 19792, 19792, 19824, 19856, 19792,
+ 19792, 19792, 19792, 19792, 19792, 19792, 19792, 19792,
+ 19792, 19888, 19920, 19792, 19952, 19792, 19984, 20016,
+ 20048, 20080, 20112, 20144, 19792, 19792, 19792, 20176,
+ 20208, 20240, 20272, 20304, 20336, 20368, 20400, 20432,
+
+ 20464, 20496, 20528, 9904, 20560, 20560, 20560, 20592,
+ 20624, 20656, 20688, 20720, 20752, 9904, 20784, 20816,
+ 9904, 9904, 9904, 9904, 20848, 20880, 20912, 9904,
+ 20944, 20976, 21008, 9904, 21040, 21072, 21104, 9904,
+ 21136, 21168, 21200, 21232, 21264, 21296, 9904, 9904,
9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
9904, 9904, 9904, 9904, 9904, 9904, 9904, 9904,
- 21296, 21328, 21360, 8400, 8400, 8400, 8400, 8400,
- 21392, 21424, 8400, 8400, 21456, 21488, 8400, 8400,
- 21520, 21552, 21584, 21616, 8400, 8400, 8400, 8400,
- 21648, 21680, 21712, 21744, 8400, 8400, 8400, 8400,
- 21776, 21776, 21808, 8400, 8400, 8400, 8400, 8400,
+ 21328, 21360, 21392, 8400, 8400, 8400, 8400, 8400,
+ 21424, 21456, 8400, 8400, 21488, 21520, 8400, 8400,
+ 21552, 21584, 21616, 21648, 8400, 8400, 8400, 8400,
+ 21680, 21712, 21744, 21776, 8400, 8400, 8400, 8400,
+ 21808, 21808, 21840, 8400, 8400, 8400, 8400, 8400,
8400, 8400, 8400, 8400, 8400, 8400, 8400, 8400,
- 8400, 8400, 8400, 21840, 8400, 8400, 8400, 8400,
+ 8400, 8400, 8400, 21872, 8400, 8400, 8400, 8400,
8400, 8400, 8400, 8400, 8400, 8400, 8400, 8400,
// 0x11000 - 0x110000
- 21872, 22128, 22384, 22384, 22384, 22384, 22640, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22896, 22896, 22896, 23152, 23408, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 23664, 23664, 23920, 24176, 24432, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 24688, 24688, 24944, 22384, 22384, 22384, 22384, 25200,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 25456, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 25712, 25968, 26224, 26480, 26736, 26992, 27248, 27504,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 27760, 27760, 27760, 27760, 27760, 27760, 28016, 27760,
- 28272, 28528, 28784, 29040, 29296, 29552, 29808, 30064,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
-
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30576, 30576,
- 30576, 30576, 30576, 30576, 30576, 30576, 30832, 31088,
- 31088, 31088, 31088, 31088, 31088, 31088, 31088, 31088,
- 31088, 31088, 31088, 31088, 31088, 31088, 31088, 31344,
- 31600, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 32112, 32112, 32368, 31856, 31856, 31856, 31856, 32624,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
-
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 31856,
- 31856, 31856, 31856, 31856, 31856, 31856, 31856, 32624,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 32880, 33136, 33392, 33392, 33392, 33392, 33392, 33392,
- 33392, 33392, 33392, 33392, 33392, 33392, 33392, 33392,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
-
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 22384,
- 22384, 22384, 22384, 22384, 22384, 22384, 22384, 30320,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
-
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33904,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
-
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33648,
- 33648, 33648, 33648, 33648, 33648, 33648, 33648, 33904,
+ 21904, 22160, 22416, 22416, 22416, 22416, 22672, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22928, 22928, 22928, 23184, 23440, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 23696, 23696, 23952, 24208, 24464, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 24720, 24720, 24976, 22416, 22416, 22416, 22416, 25232,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 25488, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 25744, 26000, 26256, 26512, 26768, 27024, 27280, 27536,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 27792, 27792, 27792, 27792, 27792, 27792, 28048, 27792,
+ 28304, 28560, 28816, 29072, 29328, 29584, 29840, 30096,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30608, 30608,
+ 30608, 30608, 30608, 30608, 30608, 30608, 30864, 31120,
+ 31120, 31120, 31120, 31120, 31120, 31120, 31120, 31120,
+ 31120, 31120, 31120, 31120, 31120, 31120, 31120, 31376,
+ 31632, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 32144, 32144, 32400, 31888, 31888, 31888, 31888, 32656,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 31888,
+ 31888, 31888, 31888, 31888, 31888, 31888, 31888, 32656,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 32912, 33168, 33424, 33424, 33424, 33424, 33424, 33424,
+ 33424, 33424, 33424, 33424, 33424, 33424, 33424, 33424,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 22416,
+ 22416, 22416, 22416, 22416, 22416, 22416, 22416, 30352,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33936,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33680,
+ 33680, 33680, 33680, 33680, 33680, 33680, 33680, 33936,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -981,663 +981,648 @@ static const unsigned short uc_property_trie[] = {
154, 154, 42, 42, 42, 42, 152, 152,
155, 152, 152, 152, 155, 152, 152, 152,
- 153, 153, 42, 42, 42, 42, 42, 42,
- 52, 52, 52, 52, 52, 52, 42, 156,
+ 153, 153, 42, 42, 42, 42, 42, 156,
+ 52, 52, 52, 52, 52, 52, 42, 157,
151, 151, 151, 151, 151, 42, 42, 42,
- 42, 42, 157, 157, 158, 159, 160, 161,
- 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 161, 161, 161, 161, 161, 161,
-
- 162, 162, 162, 162, 162, 163, 162, 162,
- 162, 162, 162, 162, 162, 163, 163, 162,
- 163, 162, 163, 162, 162, 164, 165, 165,
- 165, 165, 164, 166, 165, 165, 165, 165,
-
- 165, 167, 167, 168, 168, 168, 168, 169,
- 169, 165, 165, 165, 165, 168, 168, 165,
- 168, 168, 165, 165, 170, 170, 170, 170,
- 171, 165, 165, 165, 165, 163, 163, 163,
-
- 172, 172, 162, 172, 172, 173, 174, 175,
- 175, 175, 174, 174, 174, 175, 175, 176,
- 177, 177, 177, 178, 178, 178, 178, 177,
- 179, 180, 180, 181, 182, 183, 183, 184,
-
- 185, 185, 186, 187, 187, 187, 187, 187,
- 187, 187, 187, 187, 187, 187, 187, 187,
- 188, 189, 188, 189, 190, 191, 188, 189,
- 192, 192, 193, 194, 194, 194, 195, 192,
-
- 192, 192, 192, 192, 196, 197, 198, 199,
- 200, 200, 200, 192, 201, 192, 202, 202,
- 203, 204, 204, 204, 204, 204, 204, 204,
- 204, 204, 204, 204, 204, 204, 204, 204,
-
- 204, 204, 192, 204, 204, 204, 204, 204,
- 204, 204, 205, 205, 206, 207, 207, 207,
- 208, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209,
-
- 209, 209, 210, 209, 209, 209, 209, 209,
- 209, 209, 211, 211, 212, 213, 213, 214,
- 215, 216, 217, 218, 218, 219, 220, 221,
- 222, 223, 224, 225, 224, 225, 224, 225,
-
- 224, 225, 226, 227, 226, 227, 226, 227,
- 226, 227, 226, 227, 226, 227, 226, 227,
- 228, 229, 230, 231, 232, 233, 234, 235,
- 236, 237, 235, 236, 238, 239, 239, 239,
-
- 240, 241, 242, 241, 242, 242, 242, 241,
- 242, 242, 242, 242, 241, 240, 241, 242,
- 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 244, 243, 243, 243, 243, 243, 243,
-
- 243, 243, 243, 243, 243, 243, 243, 243,
- 243, 243, 243, 243, 243, 243, 243, 243,
- 245, 245, 245, 245, 245, 245, 245, 245,
- 245, 246, 245, 245, 245, 245, 245, 245,
-
- 245, 245, 245, 245, 245, 245, 245, 245,
- 245, 245, 245, 245, 245, 245, 245, 245,
- 247, 248, 249, 248, 249, 249, 249, 248,
- 249, 249, 249, 249, 248, 247, 248, 249,
-
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 252, 253,
- 250, 251, 250, 251, 250, 251, 250, 251,
-
- 250, 251, 254, 255, 255, 163, 163, 256,
- 257, 257, 258, 259, 260, 261, 260, 261,
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 250, 251,
-
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 250, 251,
- 250, 251, 250, 251, 250, 251, 250, 251,
-
- 262, 252, 253, 250, 251, 258, 259, 250,
- 251, 258, 259, 250, 251, 258, 259, 263,
- 252, 253, 252, 253, 250, 251, 252, 253,
- 250, 251, 252, 253, 252, 253, 252, 253,
-
- 250, 251, 252, 253, 252, 253, 252, 253,
- 250, 251, 252, 253, 264, 265, 252, 253,
- 252, 253, 252, 253, 252, 253, 266, 267,
- 252, 253, 268, 269, 268, 269, 268, 269,
-
- 258, 259, 258, 259, 258, 259, 258, 259,
- 258, 259, 258, 259, 258, 259, 258, 259,
- 268, 269, 268, 269, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
-
- 270, 271, 270, 271, 272, 273, 274, 275,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 276, 276, 276, 276, 276, 276, 276,
- 276, 276, 276, 276, 276, 276, 276, 276,
-
- 276, 276, 276, 276, 276, 276, 276, 276,
- 276, 276, 276, 276, 276, 276, 276, 276,
- 276, 276, 276, 276, 276, 276, 276, 192,
- 192, 277, 278, 278, 279, 280, 279, 278,
-
- 192, 281, 281, 281, 281, 281, 281, 281,
- 281, 281, 281, 281, 281, 281, 281, 281,
- 281, 281, 281, 281, 281, 281, 281, 281,
- 281, 281, 281, 281, 281, 281, 281, 281,
-
- 281, 281, 281, 281, 281, 281, 281, 282,
- 192, 283, 284, 192, 192, 192, 192, 285,
- 286, 287, 288, 288, 288, 288, 287, 288,
- 288, 288, 289, 287, 288, 288, 288, 288,
-
- 288, 288, 290, 287, 287, 287, 287, 287,
- 288, 288, 287, 288, 288, 289, 291, 288,
- 292, 293, 294, 295, 296, 297, 298, 299,
- 300, 301, 302, 303, 304, 305, 306, 307,
-
- 308, 309, 310, 308, 288, 290, 311, 312,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 313, 313, 313, 313, 313, 313, 313, 313,
- 313, 313, 313, 313, 313, 313, 313, 313,
-
- 313, 313, 313, 313, 313, 313, 313, 313,
- 313, 313, 313, 286, 286, 286, 286, 286,
- 313, 313, 313, 314, 315, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
-
- 316, 316, 316, 316, 317, 318, 319, 319,
- 320, 321, 321, 322, 19, 323, 324, 324,
- 325, 325, 325, 325, 325, 325, 326, 326,
- 327, 328, 329, 330, 318, 318, 331, 332,
-
- 333, 334, 335, 335, 335, 335, 336, 337,
- 338, 337, 338, 338, 338, 338, 338, 337,
- 337, 337, 337, 338, 338, 338, 338, 338,
- 338, 338, 338, 339, 339, 339, 339, 339,
-
- 340, 338, 338, 338, 338, 338, 338, 338,
- 337, 338, 338, 341, 342, 343, 344, 345,
- 346, 347, 348, 349, 349, 350, 351, 325,
- 325, 352, 352, 352, 353, 352, 352, 354,
-
- 355, 356, 357, 358, 359, 360, 361, 362,
- 363, 364, 365, 366, 367, 368, 369, 369,
- 370, 337, 337, 337, 334, 371, 371, 371,
- 372, 338, 338, 338, 338, 338, 338, 338,
-
- 338, 338, 338, 338, 338, 338, 338, 338,
- 337, 337, 337, 337, 337, 337, 337, 337,
- 337, 337, 337, 337, 337, 337, 337, 337,
- 337, 337, 338, 338, 338, 338, 338, 338,
-
- 338, 338, 338, 338, 338, 338, 338, 338,
- 338, 338, 338, 338, 338, 338, 338, 338,
- 338, 338, 338, 338, 338, 338, 338, 338,
- 373, 373, 338, 338, 338, 338, 338, 373,
-
- 335, 338, 336, 337, 337, 337, 337, 337,
- 337, 337, 337, 337, 338, 337, 338, 374,
- 338, 338, 337, 335, 375, 337, 376, 376,
- 376, 376, 376, 376, 376, 377, 378, 376,
-
- 376, 376, 376, 379, 376, 380, 380, 376,
- 376, 378, 379, 376, 376, 379, 381, 381,
- 382, 383, 384, 385, 386, 387, 388, 389,
- 390, 391, 373, 373, 373, 392, 392, 393,
-
- 394, 394, 394, 395, 395, 395, 395, 395,
- 395, 395, 395, 395, 395, 395, 318, 396,
- 397, 398, 399, 399, 399, 397, 397, 397,
- 397, 397, 399, 399, 399, 399, 397, 399,
-
- 399, 399, 399, 399, 399, 399, 399, 399,
- 397, 399, 397, 399, 397, 400, 400, 401,
- 402, 403, 402, 402, 403, 402, 402, 403,
- 403, 403, 402, 403, 403, 402, 403, 402,
-
- 402, 402, 403, 402, 403, 402, 403, 402,
- 403, 402, 402, 318, 318, 401, 400, 400,
- 404, 404, 404, 404, 404, 404, 404, 404,
- 404, 405, 405, 405, 404, 404, 404, 404,
-
- 404, 404, 404, 404, 404, 404, 404, 404,
- 404, 404, 404, 405, 405, 404, 339, 339,
- 339, 406, 339, 406, 406, 339, 339, 339,
- 406, 406, 339, 339, 339, 339, 339, 339,
-
- 407, 407, 407, 407, 407, 407, 407, 407,
- 407, 407, 407, 407, 407, 407, 407, 407,
- 407, 407, 407, 407, 407, 407, 407, 407,
- 407, 407, 407, 407, 407, 407, 407, 407,
-
- 407, 407, 407, 407, 407, 407, 408, 408,
- 408, 408, 408, 408, 408, 408, 408, 408,
- 408, 409, 318, 318, 318, 318, 318, 318,
- 318, 318, 318, 318, 318, 318, 318, 318,
-
- 410, 411, 412, 413, 414, 415, 416, 417,
- 418, 419, 420, 420, 420, 420, 420, 420,
- 420, 420, 420, 420, 420, 420, 420, 420,
- 420, 420, 420, 420, 420, 420, 420, 420,
-
- 420, 420, 420, 420, 420, 420, 420, 420,
- 420, 420, 420, 421, 421, 421, 421, 421,
- 421, 421, 422, 421, 423, 423, 424, 425,
- 426, 427, 428, 286, 286, 286, 286, 286,
-
- 429, 429, 429, 429, 429, 429, 429, 429,
- 429, 429, 429, 429, 429, 429, 429, 429,
- 429, 429, 429, 429, 429, 429, 430, 430,
- 430, 430, 431, 430, 430, 430, 430, 430,
-
- 430, 430, 430, 430, 431, 430, 430, 430,
- 431, 430, 430, 430, 430, 430, 286, 286,
- 432, 432, 432, 432, 432, 432, 432, 432,
- 432, 432, 432, 432, 432, 432, 432, 286,
-
- 433, 434, 434, 434, 434, 434, 433, 434,
- 434, 433, 434, 434, 434, 434, 434, 433,
- 434, 434, 434, 434, 433, 434, 435, 435,
- 435, 436, 436, 436, 286, 286, 437, 286,
-
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
-
- 438, 318, 438, 438, 438, 438, 438, 438,
- 438, 438, 439, 439, 439, 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, 318, 318, 318, 318,
-
- 318, 318, 318, 318, 440, 440, 441, 440,
- 440, 441, 440, 440, 440, 441, 441, 441,
- 442, 443, 444, 440, 440, 440, 441, 440,
- 440, 441, 441, 440, 440, 440, 440, 318,
-
- 445, 446, 446, 447, 448, 449, 449, 449,
- 449, 449, 449, 449, 449, 449, 449, 449,
- 449, 449, 449, 449, 449, 449, 449, 449,
- 449, 449, 449, 449, 449, 449, 449, 449,
-
- 449, 449, 449, 449, 449, 449, 449, 449,
- 449, 450, 449, 449, 449, 449, 449, 449,
- 449, 450, 449, 449, 450, 449, 449, 449,
- 449, 449, 451, 452, 453, 449, 447, 447,
-
- 447, 446, 446, 446, 446, 446, 446, 446,
- 446, 447, 447, 447, 447, 454, 455, 452,
- 449, 163, 165, 456, 456, 445, 451, 451,
- 457, 457, 457, 457, 457, 457, 457, 457,
-
- 449, 449, 446, 446, 458, 458, 459, 460,
- 461, 462, 463, 464, 465, 466, 467, 468,
- 469, 470, 471, 472, 472, 472, 472, 472,
- 192, 473, 473, 474, 474, 475, 474, 474,
-
- 192, 476, 477, 477, 192, 478, 478, 478,
- 478, 478, 478, 478, 478, 192, 192, 478,
- 478, 192, 192, 478, 478, 478, 478, 478,
- 478, 478, 478, 478, 478, 478, 478, 478,
-
- 478, 478, 478, 478, 478, 478, 478, 478,
- 478, 192, 478, 478, 478, 478, 478, 478,
- 478, 192, 478, 192, 192, 192, 478, 478,
- 478, 478, 192, 192, 479, 480, 481, 477,
-
- 477, 476, 476, 476, 476, 192, 192, 477,
- 477, 192, 192, 482, 482, 483, 484, 192,
- 192, 192, 192, 192, 192, 192, 192, 481,
- 192, 192, 192, 192, 485, 485, 192, 485,
-
- 478, 478, 476, 476, 192, 192, 486, 487,
- 488, 489, 490, 491, 492, 493, 494, 495,
- 478, 478, 496, 496, 497, 497, 497, 497,
- 497, 498, 499, 500, 192, 192, 192, 192,
-
- 192, 501, 502, 503, 192, 504, 504, 504,
- 504, 504, 504, 192, 192, 192, 192, 504,
- 504, 192, 192, 504, 504, 504, 504, 504,
- 504, 504, 504, 504, 504, 504, 504, 504,
-
- 504, 504, 504, 504, 504, 504, 504, 504,
- 504, 192, 504, 504, 504, 504, 504, 504,
- 504, 192, 504, 505, 192, 504, 505, 192,
- 504, 504, 192, 192, 506, 192, 507, 507,
-
- 507, 502, 502, 192, 192, 192, 192, 502,
- 502, 192, 192, 502, 502, 508, 192, 192,
- 192, 509, 192, 192, 192, 192, 192, 192,
- 192, 505, 505, 505, 504, 192, 505, 192,
-
- 192, 192, 192, 192, 192, 192, 510, 511,
- 512, 513, 514, 515, 516, 517, 518, 519,
- 502, 502, 504, 504, 504, 509, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 520, 520, 521, 192, 522, 522, 522,
- 522, 522, 522, 522, 523, 522, 192, 522,
- 522, 522, 192, 522, 522, 522, 522, 522,
- 522, 522, 522, 522, 522, 522, 522, 522,
-
- 522, 522, 522, 522, 522, 522, 522, 522,
- 522, 192, 522, 522, 522, 522, 522, 522,
- 522, 192, 522, 522, 192, 522, 522, 522,
- 522, 522, 192, 192, 524, 522, 521, 521,
-
- 521, 520, 520, 520, 520, 520, 192, 520,
- 520, 521, 192, 521, 521, 525, 192, 192,
- 522, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 522, 523, 526, 526, 192, 192, 527, 528,
- 529, 530, 531, 532, 533, 534, 535, 536,
- 537, 538, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 539, 540, 540, 192, 541, 541, 541,
- 541, 541, 541, 541, 541, 192, 192, 541,
- 541, 192, 192, 541, 541, 541, 541, 541,
- 541, 541, 541, 541, 541, 541, 541, 541,
-
- 541, 541, 541, 541, 541, 541, 541, 541,
- 541, 192, 541, 541, 541, 541, 541, 541,
- 541, 192, 541, 541, 192, 542, 541, 541,
- 541, 541, 192, 192, 543, 541, 544, 539,
-
- 540, 539, 539, 539, 545, 192, 192, 540,
- 546, 192, 192, 546, 546, 547, 192, 192,
- 192, 192, 192, 192, 192, 192, 548, 544,
- 192, 192, 192, 192, 549, 549, 192, 541,
-
- 541, 541, 545, 545, 192, 192, 550, 551,
- 552, 553, 554, 555, 556, 557, 558, 559,
- 560, 542, 561, 561, 561, 561, 561, 561,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 562, 563, 192, 563, 563, 563,
- 563, 563, 563, 192, 192, 192, 563, 563,
- 563, 192, 563, 563, 564, 563, 192, 192,
- 192, 563, 563, 192, 563, 192, 563, 563,
-
- 192, 192, 192, 563, 563, 192, 192, 192,
- 563, 563, 563, 192, 192, 192, 563, 563,
- 563, 563, 563, 563, 563, 563, 565, 563,
- 563, 563, 192, 192, 192, 192, 566, 567,
-
- 562, 567, 567, 192, 192, 192, 567, 567,
- 567, 192, 568, 568, 568, 569, 192, 192,
- 570, 192, 192, 192, 192, 192, 192, 566,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 571, 572,
- 573, 574, 575, 576, 577, 578, 579, 580,
- 581, 581, 581, 582, 582, 582, 582, 582,
- 582, 583, 582, 192, 192, 192, 192, 192,
-
- 192, 584, 584, 584, 192, 585, 585, 585,
- 585, 585, 585, 585, 585, 192, 585, 585,
- 585, 192, 585, 585, 585, 585, 585, 585,
- 585, 585, 585, 585, 585, 585, 585, 585,
-
- 585, 585, 585, 585, 585, 585, 585, 585,
- 585, 192, 585, 585, 585, 585, 585, 585,
- 585, 585, 585, 585, 192, 585, 585, 585,
- 585, 585, 192, 192, 192, 586, 587, 587,
-
- 587, 584, 584, 584, 584, 192, 587, 587,
- 588, 192, 587, 587, 587, 589, 192, 192,
- 192, 192, 192, 192, 192, 590, 591, 192,
- 586, 586, 192, 192, 192, 192, 192, 192,
-
- 585, 585, 592, 592, 192, 192, 593, 594,
- 595, 596, 597, 598, 599, 600, 601, 602,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 603, 603, 603, 603, 603, 603, 603, 604,
-
- 192, 192, 605, 605, 192, 606, 606, 606,
- 606, 606, 606, 606, 606, 192, 606, 606,
- 606, 192, 606, 606, 606, 606, 606, 606,
- 606, 606, 606, 606, 606, 606, 606, 606,
-
- 606, 606, 606, 606, 606, 606, 606, 606,
- 606, 192, 606, 606, 606, 606, 606, 606,
- 606, 606, 606, 606, 192, 606, 606, 606,
- 606, 606, 192, 192, 607, 608, 605, 609,
-
- 610, 605, 611, 605, 605, 192, 609, 610,
- 610, 192, 610, 610, 612, 613, 192, 192,
- 192, 192, 192, 192, 192, 611, 611, 192,
- 192, 192, 192, 192, 192, 192, 606, 192,
-
- 606, 606, 614, 614, 192, 192, 615, 616,
- 617, 618, 619, 620, 621, 622, 623, 624,
- 192, 625, 625, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 626, 626, 192, 627, 627, 627,
- 627, 627, 627, 627, 627, 192, 627, 627,
- 627, 192, 627, 627, 627, 627, 627, 627,
- 627, 627, 627, 627, 627, 627, 627, 627,
-
- 627, 627, 627, 627, 627, 627, 627, 627,
- 627, 628, 627, 627, 627, 627, 627, 627,
- 627, 627, 627, 627, 627, 627, 627, 627,
- 627, 627, 628, 192, 192, 629, 630, 626,
-
- 626, 631, 631, 631, 632, 192, 626, 626,
- 626, 192, 633, 633, 633, 634, 628, 192,
- 192, 192, 192, 192, 192, 192, 192, 630,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 627, 627, 632, 632, 192, 192, 635, 636,
- 637, 638, 639, 640, 641, 642, 643, 644,
- 645, 645, 645, 645, 645, 645, 192, 192,
- 192, 646, 629, 629, 629, 629, 629, 629,
-
- 192, 192, 647, 647, 192, 648, 648, 648,
- 648, 648, 648, 648, 648, 648, 648, 648,
- 648, 648, 648, 648, 648, 648, 648, 192,
- 192, 192, 648, 648, 648, 648, 648, 648,
-
- 648, 648, 648, 648, 648, 648, 648, 648,
- 648, 648, 648, 648, 648, 648, 648, 648,
- 648, 648, 192, 648, 648, 648, 648, 648,
- 648, 648, 648, 648, 192, 648, 192, 192,
-
- 648, 648, 648, 648, 648, 648, 648, 192,
- 192, 192, 649, 192, 192, 192, 192, 650,
- 647, 647, 651, 651, 651, 192, 651, 192,
- 647, 647, 652, 647, 652, 652, 652, 650,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 647, 647, 653, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 654, 654, 654, 654, 654, 654, 654,
- 654, 654, 654, 654, 654, 654, 654, 654,
- 654, 654, 654, 654, 654, 654, 654, 654,
- 654, 654, 654, 654, 654, 654, 654, 654,
-
- 654, 654, 654, 654, 654, 654, 654, 654,
- 654, 654, 654, 654, 654, 654, 654, 654,
- 654, 655, 654, 656, 655, 655, 655, 655,
- 657, 657, 658, 192, 192, 192, 192, 12,
-
- 654, 654, 654, 654, 654, 654, 659, 655,
- 660, 660, 660, 660, 655, 655, 655, 661,
- 662, 663, 664, 665, 666, 667, 668, 669,
- 670, 671, 672, 672, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 673, 673, 192, 673, 192, 192, 673,
- 673, 192, 673, 192, 192, 673, 192, 192,
- 192, 192, 192, 192, 673, 673, 673, 673,
- 192, 673, 673, 673, 673, 673, 673, 673,
-
- 192, 673, 673, 673, 192, 673, 192, 673,
- 192, 192, 673, 673, 192, 673, 673, 673,
- 673, 674, 673, 675, 674, 674, 674, 674,
- 676, 676, 192, 674, 674, 673, 192, 192,
-
- 673, 673, 673, 673, 673, 192, 677, 192,
- 678, 678, 678, 678, 674, 674, 192, 192,
- 679, 680, 681, 682, 683, 684, 685, 686,
- 687, 688, 192, 192, 689, 689, 690, 690,
-
- 691, 692, 692, 692, 693, 694, 693, 693,
- 695, 693, 693, 696, 697, 698, 698, 698,
- 698, 698, 695, 699, 698, 699, 699, 699,
- 700, 700, 699, 699, 699, 699, 699, 699,
-
- 701, 702, 703, 704, 705, 706, 707, 708,
- 709, 710, 711, 711, 711, 711, 711, 711,
- 711, 711, 711, 711, 712, 700, 699, 700,
- 699, 713, 714, 715, 714, 715, 716, 716,
-
- 691, 691, 691, 717, 691, 691, 691, 691,
- 192, 691, 691, 691, 691, 717, 691, 691,
- 691, 691, 717, 691, 691, 691, 691, 717,
- 691, 691, 691, 691, 717, 691, 691, 691,
-
- 691, 691, 691, 691, 691, 691, 691, 691,
- 691, 717, 718, 719, 719, 192, 192, 192,
- 192, 720, 721, 722, 723, 722, 722, 724,
- 722, 724, 721, 721, 721, 721, 725, 726,
-
- 721, 722, 727, 727, 728, 696, 727, 727,
- 691, 691, 691, 691, 729, 730, 730, 730,
- 725, 725, 725, 722, 725, 725, 731, 725,
- 192, 725, 725, 725, 725, 722, 725, 725,
-
- 725, 725, 722, 725, 725, 725, 725, 722,
- 725, 725, 725, 725, 722, 725, 731, 731,
- 731, 725, 725, 725, 725, 725, 725, 725,
- 731, 722, 731, 731, 731, 192, 732, 732,
-
- 733, 733, 733, 733, 733, 733, 734, 733,
- 733, 733, 733, 733, 733, 192, 735, 733,
- 736, 736, 737, 738, 739, 740, 740, 740,
- 740, 741, 741, 192, 192, 192, 192, 192,
-
- 742, 742, 742, 742, 742, 742, 742, 742,
- 742, 742, 742, 742, 742, 742, 742, 742,
- 742, 742, 742, 742, 742, 742, 742, 742,
- 742, 742, 742, 742, 742, 742, 742, 742,
-
- 742, 742, 743, 742, 742, 742, 744, 742,
- 743, 742, 742, 745, 746, 747, 748, 747,
- 747, 749, 747, 750, 750, 750, 747, 751,
- 746, 752, 753, 754, 754, 750, 750, 743,
-
- 755, 756, 757, 758, 759, 760, 761, 762,
- 763, 764, 765, 765, 766, 766, 766, 766,
- 742, 742, 742, 742, 742, 742, 749, 749,
- 747, 747, 743, 743, 743, 743, 750, 750,
-
- 750, 743, 745, 745, 745, 743, 743, 745,
- 745, 745, 745, 745, 745, 745, 743, 743,
- 743, 750, 750, 750, 750, 743, 743, 743,
- 743, 743, 743, 743, 743, 743, 743, 743,
-
- 743, 743, 750, 745, 754, 750, 750, 745,
- 745, 745, 745, 745, 745, 767, 743, 745,
- 768, 769, 770, 771, 772, 773, 774, 775,
- 776, 777, 778, 778, 778, 779, 780, 780,
-
- 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 781, 781, 781, 781,
- 781, 781, 781, 781, 781, 781, 781, 781,
-
- 781, 781, 781, 781, 781, 781, 192, 782,
- 192, 192, 192, 192, 192, 782, 192, 192,
+ 42, 42, 158, 158, 159, 160, 161, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162,
+ 162, 162, 162, 162, 162, 162, 162, 162,
+
+ 163, 163, 163, 163, 163, 164, 163, 163,
+ 163, 163, 163, 163, 163, 164, 164, 163,
+ 164, 163, 164, 163, 163, 165, 166, 166,
+ 166, 166, 165, 167, 166, 166, 166, 166,
+
+ 166, 168, 168, 169, 169, 169, 169, 170,
+ 170, 166, 166, 166, 166, 169, 169, 166,
+ 169, 169, 166, 166, 171, 171, 171, 171,
+ 172, 166, 166, 166, 166, 164, 164, 164,
+
+ 173, 173, 163, 173, 173, 174, 175, 176,
+ 176, 176, 175, 175, 175, 176, 176, 177,
+ 178, 178, 178, 179, 179, 179, 179, 178,
+ 180, 181, 181, 182, 183, 184, 184, 185,
+
+ 186, 186, 187, 188, 188, 188, 188, 188,
+ 188, 188, 188, 188, 188, 188, 188, 188,
+ 189, 190, 189, 190, 191, 192, 189, 190,
+ 193, 193, 194, 195, 195, 195, 196, 193,
+
+ 193, 193, 193, 193, 197, 198, 199, 200,
+ 201, 201, 201, 193, 202, 193, 203, 203,
+ 204, 205, 205, 205, 205, 205, 205, 205,
+ 205, 205, 205, 205, 205, 205, 205, 205,
+
+ 205, 205, 193, 205, 205, 205, 205, 205,
+ 205, 205, 206, 206, 207, 208, 208, 208,
+ 209, 210, 210, 210, 210, 210, 210, 210,
+ 210, 210, 210, 210, 210, 210, 210, 210,
+
+ 210, 210, 211, 210, 210, 210, 210, 210,
+ 210, 210, 212, 212, 213, 214, 214, 215,
+ 216, 217, 218, 219, 219, 220, 221, 222,
+ 223, 224, 225, 226, 225, 226, 225, 226,
+
+ 225, 226, 227, 228, 227, 228, 227, 228,
+ 227, 228, 227, 228, 227, 228, 227, 228,
+ 229, 230, 231, 232, 233, 234, 235, 236,
+ 237, 238, 236, 237, 239, 240, 240, 240,
+
+ 241, 242, 243, 242, 243, 243, 243, 242,
+ 243, 243, 243, 243, 242, 241, 242, 243,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 244, 245, 244, 244, 244, 244, 244, 244,
+
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 244, 244, 244, 244, 244, 244, 244, 244,
+ 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 247, 246, 246, 246, 246, 246, 246,
+
+ 246, 246, 246, 246, 246, 246, 246, 246,
+ 246, 246, 246, 246, 246, 246, 246, 246,
+ 248, 249, 250, 249, 250, 250, 250, 249,
+ 250, 250, 250, 250, 249, 248, 249, 250,
+
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 253, 254,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+
+ 251, 252, 255, 256, 256, 164, 164, 257,
+ 258, 258, 259, 260, 261, 262, 261, 262,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+ 251, 252, 251, 252, 251, 252, 251, 252,
+
+ 263, 253, 254, 251, 252, 259, 260, 251,
+ 252, 259, 260, 251, 252, 259, 260, 264,
+ 253, 254, 253, 254, 251, 252, 253, 254,
+ 251, 252, 253, 254, 253, 254, 253, 254,
+
+ 251, 252, 253, 254, 253, 254, 253, 254,
+ 251, 252, 253, 254, 265, 266, 253, 254,
+ 253, 254, 253, 254, 253, 254, 267, 268,
+ 253, 254, 269, 270, 269, 270, 269, 270,
+
+ 259, 260, 259, 260, 259, 260, 259, 260,
+ 259, 260, 259, 260, 259, 260, 259, 260,
+ 269, 270, 269, 270, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+
+ 271, 272, 271, 272, 273, 274, 275, 276,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 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, 193,
+ 193, 278, 279, 279, 280, 281, 280, 279,
+
+ 193, 282, 282, 282, 282, 282, 282, 282,
+ 282, 282, 282, 282, 282, 282, 282, 282,
+ 282, 282, 282, 282, 282, 282, 282, 282,
+ 282, 282, 282, 282, 282, 282, 282, 282,
+
+ 282, 282, 282, 282, 282, 282, 282, 283,
+ 193, 284, 285, 193, 193, 193, 193, 286,
+ 287, 288, 289, 289, 289, 289, 288, 289,
+ 289, 289, 290, 288, 289, 289, 289, 289,
+
+ 289, 289, 291, 288, 288, 288, 288, 288,
+ 289, 289, 288, 289, 289, 290, 292, 289,
+ 293, 294, 295, 296, 297, 298, 299, 300,
+ 301, 302, 303, 304, 305, 306, 307, 308,
+
+ 309, 310, 311, 309, 289, 291, 312, 313,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 314, 314, 314, 314, 314, 314, 314, 314,
+ 314, 314, 314, 314, 314, 314, 314, 314,
+
+ 314, 314, 314, 314, 314, 314, 314, 314,
+ 314, 314, 314, 287, 287, 287, 287, 287,
+ 314, 314, 314, 315, 316, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+
+ 317, 317, 317, 317, 318, 319, 320, 320,
+ 321, 322, 322, 323, 19, 324, 325, 325,
+ 326, 326, 326, 326, 326, 326, 327, 327,
+ 328, 329, 330, 331, 332, 319, 333, 334,
+
+ 335, 336, 337, 337, 337, 337, 338, 339,
+ 340, 339, 340, 340, 340, 340, 340, 339,
+ 339, 339, 339, 340, 340, 340, 340, 340,
+ 340, 340, 340, 341, 341, 341, 341, 341,
+
+ 342, 340, 340, 340, 340, 340, 340, 340,
+ 339, 340, 340, 343, 344, 345, 346, 347,
+ 348, 349, 350, 351, 351, 352, 353, 326,
+ 326, 354, 354, 354, 355, 354, 354, 356,
+
+ 357, 358, 359, 360, 361, 362, 363, 364,
+ 365, 366, 367, 368, 369, 370, 371, 371,
+ 372, 339, 339, 339, 336, 373, 373, 373,
+ 374, 340, 340, 340, 340, 340, 340, 340,
+
+ 340, 340, 340, 340, 340, 340, 340, 340,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 339, 339, 339, 339,
+ 339, 339, 340, 340, 340, 340, 340, 340,
+
+ 340, 340, 340, 340, 340, 340, 340, 340,
+ 340, 340, 340, 340, 340, 340, 340, 340,
+ 340, 340, 340, 340, 340, 340, 340, 340,
+ 375, 375, 340, 340, 340, 340, 340, 375,
+
+ 337, 340, 338, 339, 339, 339, 339, 339,
+ 339, 339, 339, 339, 340, 339, 340, 376,
+ 340, 340, 339, 337, 377, 339, 378, 378,
+ 378, 378, 378, 378, 378, 379, 380, 378,
+
+ 378, 378, 378, 381, 378, 382, 382, 378,
+ 378, 380, 381, 378, 378, 381, 383, 383,
+ 384, 385, 386, 387, 388, 389, 390, 391,
+ 392, 393, 375, 375, 375, 394, 394, 395,
+
+ 396, 396, 396, 397, 397, 397, 397, 397,
+ 397, 397, 397, 397, 397, 397, 319, 398,
+ 399, 400, 401, 401, 401, 399, 399, 399,
+ 399, 399, 401, 401, 401, 401, 399, 401,
+
+ 401, 401, 401, 401, 401, 401, 401, 401,
+ 399, 401, 399, 401, 399, 402, 402, 403,
+ 404, 405, 404, 404, 405, 404, 404, 405,
+ 405, 405, 404, 405, 405, 404, 405, 404,
+
+ 404, 404, 405, 404, 405, 404, 405, 404,
+ 405, 404, 404, 319, 319, 403, 402, 402,
+ 406, 406, 406, 406, 406, 406, 406, 406,
+ 406, 407, 407, 407, 406, 406, 406, 406,
+
+ 406, 406, 406, 406, 406, 406, 406, 406,
+ 406, 406, 406, 407, 407, 406, 341, 341,
+ 341, 408, 341, 408, 408, 341, 341, 341,
+ 408, 408, 341, 341, 341, 341, 341, 341,
+
+ 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409,
+ 409, 409, 409, 409, 409, 409, 409, 409,
+
+ 409, 409, 409, 409, 409, 409, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 411, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+
+ 412, 413, 414, 415, 416, 417, 418, 419,
+ 420, 421, 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, 423, 423, 423, 423, 423,
+ 423, 423, 424, 423, 425, 425, 426, 427,
+ 428, 429, 430, 287, 287, 287, 287, 287,
+
+ 431, 431, 431, 431, 431, 431, 431, 431,
+ 431, 431, 431, 431, 431, 431, 431, 431,
+ 431, 431, 431, 431, 431, 431, 432, 432,
+ 432, 432, 433, 432, 432, 432, 432, 432,
+
+ 432, 432, 432, 432, 433, 432, 432, 432,
+ 433, 432, 432, 432, 432, 432, 287, 287,
+ 434, 434, 434, 434, 434, 434, 434, 434,
+ 434, 434, 434, 434, 434, 434, 434, 287,
+
+ 435, 436, 436, 436, 436, 436, 435, 436,
+ 436, 435, 436, 436, 436, 436, 436, 435,
+ 436, 436, 436, 436, 435, 436, 437, 437,
+ 437, 438, 438, 438, 287, 287, 439, 287,
+
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+
+ 440, 319, 440, 440, 440, 440, 440, 440,
+ 440, 440, 441, 441, 441, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+
+ 319, 319, 319, 319, 442, 442, 443, 442,
+ 442, 443, 442, 442, 442, 443, 443, 443,
+ 444, 445, 446, 442, 442, 442, 443, 442,
+ 442, 443, 443, 442, 442, 442, 442, 319,
+
+ 447, 448, 448, 449, 450, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 451, 451, 451, 451, 451, 451, 451,
+
+ 451, 451, 451, 451, 451, 451, 451, 451,
+ 451, 452, 451, 451, 451, 451, 451, 451,
+ 451, 452, 451, 451, 452, 451, 451, 451,
+ 451, 451, 453, 454, 455, 451, 449, 449,
+
+ 449, 448, 448, 448, 448, 448, 448, 448,
+ 448, 449, 449, 449, 449, 456, 457, 454,
+ 451, 164, 166, 458, 458, 447, 453, 453,
+ 459, 459, 459, 459, 459, 459, 459, 459,
+
+ 451, 451, 448, 448, 460, 460, 461, 462,
+ 463, 464, 465, 466, 467, 468, 469, 470,
+ 471, 472, 473, 474, 474, 474, 474, 474,
+ 193, 475, 475, 476, 476, 477, 476, 476,
+
+ 193, 478, 479, 479, 193, 480, 480, 480,
+ 480, 480, 480, 480, 480, 193, 193, 480,
+ 480, 193, 193, 480, 480, 480, 480, 480,
+ 480, 480, 480, 480, 480, 480, 480, 480,
+
+ 480, 480, 480, 480, 480, 480, 480, 480,
+ 480, 193, 480, 480, 480, 480, 480, 480,
+ 480, 193, 480, 193, 193, 193, 480, 480,
+ 480, 480, 193, 193, 481, 482, 483, 479,
+
+ 479, 478, 478, 478, 478, 193, 193, 479,
+ 479, 193, 193, 484, 484, 485, 486, 193,
+ 193, 193, 193, 193, 193, 193, 193, 483,
+ 193, 193, 193, 193, 487, 487, 193, 487,
+
+ 480, 480, 478, 478, 193, 193, 488, 489,
+ 490, 491, 492, 493, 494, 495, 496, 497,
+ 480, 480, 498, 498, 499, 499, 499, 499,
+ 499, 500, 501, 502, 193, 193, 193, 193,
+
+ 193, 503, 504, 505, 193, 506, 506, 506,
+ 506, 506, 506, 193, 193, 193, 193, 506,
+ 506, 193, 193, 506, 506, 506, 506, 506,
+ 506, 506, 506, 506, 506, 506, 506, 506,
+
+ 506, 506, 506, 506, 506, 506, 506, 506,
+ 506, 193, 506, 506, 506, 506, 506, 506,
+ 506, 193, 506, 507, 193, 506, 507, 193,
+ 506, 506, 193, 193, 508, 193, 509, 509,
+
+ 509, 504, 504, 193, 193, 193, 193, 504,
+ 504, 193, 193, 504, 504, 510, 193, 193,
+ 193, 511, 193, 193, 193, 193, 193, 193,
+ 193, 507, 507, 507, 506, 193, 507, 193,
+
+ 193, 193, 193, 193, 193, 193, 512, 513,
+ 514, 515, 516, 517, 518, 519, 520, 521,
+ 504, 504, 506, 506, 506, 511, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 522, 522, 523, 193, 524, 524, 524,
+ 524, 524, 524, 524, 525, 524, 193, 524,
+ 524, 524, 193, 524, 524, 524, 524, 524,
+ 524, 524, 524, 524, 524, 524, 524, 524,
+
+ 524, 524, 524, 524, 524, 524, 524, 524,
+ 524, 193, 524, 524, 524, 524, 524, 524,
+ 524, 193, 524, 524, 193, 524, 524, 524,
+ 524, 524, 193, 193, 526, 524, 523, 523,
+
+ 523, 522, 522, 522, 522, 522, 193, 522,
+ 522, 523, 193, 523, 523, 527, 193, 193,
+ 524, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 524, 525, 528, 528, 193, 193, 529, 530,
+ 531, 532, 533, 534, 535, 536, 537, 538,
+ 539, 540, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 541, 542, 542, 193, 543, 543, 543,
+ 543, 543, 543, 543, 543, 193, 193, 543,
+ 543, 193, 193, 543, 543, 543, 543, 543,
+ 543, 543, 543, 543, 543, 543, 543, 543,
+
+ 543, 543, 543, 543, 543, 543, 543, 543,
+ 543, 193, 543, 543, 543, 543, 543, 543,
+ 543, 193, 543, 543, 193, 544, 543, 543,
+ 543, 543, 193, 193, 545, 543, 546, 541,
+
+ 542, 541, 541, 541, 547, 193, 193, 542,
+ 548, 193, 193, 548, 548, 549, 193, 193,
+ 193, 193, 193, 193, 193, 193, 550, 546,
+ 193, 193, 193, 193, 551, 551, 193, 543,
+
+ 543, 543, 547, 547, 193, 193, 552, 553,
+ 554, 555, 556, 557, 558, 559, 560, 561,
+ 562, 544, 563, 563, 563, 563, 563, 563,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 564, 565, 193, 565, 565, 565,
+ 565, 565, 565, 193, 193, 193, 565, 565,
+ 565, 193, 565, 565, 566, 565, 193, 193,
+ 193, 565, 565, 193, 565, 193, 565, 565,
+
+ 193, 193, 193, 565, 565, 193, 193, 193,
+ 565, 565, 565, 193, 193, 193, 565, 565,
+ 565, 565, 565, 565, 565, 565, 567, 565,
+ 565, 565, 193, 193, 193, 193, 568, 569,
+
+ 564, 569, 569, 193, 193, 193, 569, 569,
+ 569, 193, 570, 570, 570, 571, 193, 193,
+ 572, 193, 193, 193, 193, 193, 193, 568,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 573, 574,
+ 575, 576, 577, 578, 579, 580, 581, 582,
+ 583, 583, 583, 584, 584, 584, 584, 584,
+ 584, 585, 584, 193, 193, 193, 193, 193,
+
+ 193, 586, 586, 586, 193, 587, 587, 587,
+ 587, 587, 587, 587, 587, 193, 587, 587,
+ 587, 193, 587, 587, 587, 587, 587, 587,
+ 587, 587, 587, 587, 587, 587, 587, 587,
+
+ 587, 587, 587, 587, 587, 587, 587, 587,
+ 587, 193, 587, 587, 587, 587, 587, 587,
+ 587, 587, 587, 587, 193, 587, 587, 587,
+ 587, 587, 193, 193, 193, 588, 589, 589,
+
+ 589, 586, 586, 586, 586, 193, 589, 589,
+ 590, 193, 589, 589, 589, 591, 193, 193,
+ 193, 193, 193, 193, 193, 592, 593, 193,
+ 588, 588, 193, 193, 193, 193, 193, 193,
+
+ 587, 587, 594, 594, 193, 193, 595, 596,
+ 597, 598, 599, 600, 601, 602, 603, 604,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 605, 605, 605, 605, 605, 605, 605, 606,
+
+ 193, 193, 607, 607, 193, 608, 608, 608,
+ 608, 608, 608, 608, 608, 193, 608, 608,
+ 608, 193, 608, 608, 608, 608, 608, 608,
+ 608, 608, 608, 608, 608, 608, 608, 608,
+
+ 608, 608, 608, 608, 608, 608, 608, 608,
+ 608, 193, 608, 608, 608, 608, 608, 608,
+ 608, 608, 608, 608, 193, 608, 608, 608,
+ 608, 608, 193, 193, 609, 610, 607, 611,
+
+ 612, 607, 613, 607, 607, 193, 611, 612,
+ 612, 193, 612, 612, 614, 615, 193, 193,
+ 193, 193, 193, 193, 193, 613, 613, 193,
+ 193, 193, 193, 193, 193, 193, 608, 193,
+
+ 608, 608, 616, 616, 193, 193, 617, 618,
+ 619, 620, 621, 622, 623, 624, 625, 626,
+ 193, 627, 627, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 628, 628, 193, 629, 629, 629,
+ 629, 629, 629, 629, 629, 193, 629, 629,
+ 629, 193, 629, 629, 629, 629, 629, 629,
+ 629, 629, 629, 629, 629, 629, 629, 629,
+
+ 629, 629, 629, 629, 629, 629, 629, 629,
+ 629, 630, 629, 629, 629, 629, 629, 629,
+ 629, 629, 629, 629, 629, 629, 629, 629,
+ 629, 629, 630, 193, 193, 631, 632, 628,
+
+ 628, 633, 633, 633, 634, 193, 628, 628,
+ 628, 193, 635, 635, 635, 636, 630, 193,
+ 193, 193, 193, 193, 193, 193, 193, 632,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 629, 629, 634, 634, 193, 193, 637, 638,
+ 639, 640, 641, 642, 643, 644, 645, 646,
+ 647, 647, 647, 647, 647, 647, 193, 193,
+ 193, 648, 631, 631, 631, 631, 631, 631,
+
+ 193, 193, 649, 649, 193, 650, 650, 650,
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 650, 650, 650, 193,
+ 193, 193, 650, 650, 650, 650, 650, 650,
+
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 650, 650, 650, 650,
+ 650, 650, 193, 650, 650, 650, 650, 650,
+ 650, 650, 650, 650, 193, 650, 193, 193,
+
+ 650, 650, 650, 650, 650, 650, 650, 193,
+ 193, 193, 651, 193, 193, 193, 193, 652,
+ 649, 649, 653, 653, 653, 193, 653, 193,
+ 649, 649, 654, 649, 654, 654, 654, 652,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 649, 649, 655, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 656, 656, 656, 656, 656, 656, 656,
+ 656, 656, 656, 656, 656, 656, 656, 656,
+ 656, 656, 656, 656, 656, 656, 656, 656,
+ 656, 656, 656, 656, 656, 656, 656, 656,
+
+ 656, 656, 656, 656, 656, 656, 656, 656,
+ 656, 656, 656, 656, 656, 656, 656, 656,
+ 656, 657, 656, 658, 657, 657, 657, 657,
+ 659, 659, 660, 193, 193, 193, 193, 12,
+
+ 656, 656, 656, 656, 656, 656, 661, 657,
+ 662, 662, 662, 662, 657, 657, 657, 663,
+ 664, 665, 666, 667, 668, 669, 670, 671,
+ 672, 673, 674, 674, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 675, 675, 193, 675, 193, 193, 675,
+ 675, 193, 675, 193, 193, 675, 193, 193,
+ 193, 193, 193, 193, 675, 675, 675, 675,
+ 193, 675, 675, 675, 675, 675, 675, 675,
+
+ 193, 675, 675, 675, 193, 675, 193, 675,
+ 193, 193, 675, 675, 193, 675, 675, 675,
+ 675, 676, 675, 677, 676, 676, 676, 676,
+ 678, 678, 193, 676, 676, 675, 193, 193,
+
+ 675, 675, 675, 675, 675, 193, 679, 193,
+ 680, 680, 680, 680, 676, 676, 193, 193,
+ 681, 682, 683, 684, 685, 686, 687, 688,
+ 689, 690, 193, 193, 691, 691, 692, 692,
+
+ 693, 694, 694, 694, 695, 696, 695, 695,
+ 697, 695, 695, 698, 699, 700, 700, 700,
+ 700, 700, 697, 701, 700, 701, 701, 701,
+ 702, 702, 701, 701, 701, 701, 701, 701,
+
+ 703, 704, 705, 706, 707, 708, 709, 710,
+ 711, 712, 713, 713, 713, 713, 713, 713,
+ 713, 713, 713, 713, 714, 702, 701, 702,
+ 701, 715, 716, 717, 716, 717, 718, 718,
+
+ 693, 693, 693, 719, 693, 693, 693, 693,
+ 193, 693, 693, 693, 693, 719, 693, 693,
+ 693, 693, 719, 693, 693, 693, 693, 719,
+ 693, 693, 693, 693, 719, 693, 693, 693,
+
+ 693, 693, 693, 693, 693, 693, 693, 693,
+ 693, 719, 720, 721, 721, 193, 193, 193,
+ 193, 722, 723, 724, 725, 724, 724, 726,
+ 724, 726, 723, 723, 723, 723, 727, 728,
+
+ 723, 724, 729, 729, 730, 698, 729, 729,
+ 693, 693, 693, 693, 731, 732, 732, 732,
+ 727, 727, 727, 724, 727, 727, 733, 727,
+ 193, 727, 727, 727, 727, 724, 727, 727,
+
+ 727, 727, 724, 727, 727, 727, 727, 724,
+ 727, 727, 727, 727, 724, 727, 733, 733,
+ 733, 727, 727, 727, 727, 727, 727, 727,
+ 733, 724, 733, 733, 733, 193, 734, 734,
+
+ 735, 735, 735, 735, 735, 735, 736, 735,
+ 735, 735, 735, 735, 735, 193, 737, 735,
+ 738, 738, 739, 740, 741, 742, 742, 742,
+ 742, 743, 743, 193, 193, 193, 193, 193,
+
+ 744, 744, 744, 744, 744, 744, 744, 744,
+ 744, 744, 744, 744, 744, 744, 744, 744,
+ 744, 744, 744, 744, 744, 744, 744, 744,
+ 744, 744, 744, 744, 744, 744, 744, 744,
+
+ 744, 744, 745, 744, 744, 744, 746, 744,
+ 745, 744, 744, 747, 748, 749, 750, 749,
+ 749, 751, 749, 752, 752, 752, 749, 753,
+ 748, 754, 755, 756, 756, 752, 752, 745,
+
+ 757, 758, 759, 760, 761, 762, 763, 764,
+ 765, 766, 767, 767, 768, 768, 768, 768,
+ 744, 744, 744, 744, 744, 744, 751, 751,
+ 749, 749, 745, 745, 745, 745, 752, 752,
+
+ 752, 745, 747, 747, 747, 745, 745, 747,
+ 747, 747, 747, 747, 747, 747, 745, 745,
+ 745, 752, 752, 752, 752, 745, 745, 745,
+ 745, 745, 745, 745, 745, 745, 745, 745,
+
+ 745, 745, 752, 747, 756, 752, 752, 747,
+ 747, 747, 747, 747, 747, 769, 745, 747,
+ 770, 771, 772, 773, 774, 775, 776, 777,
+ 778, 779, 780, 780, 780, 781, 782, 782,
+
783, 783, 783, 783, 783, 783, 783, 783,
783, 783, 783, 783, 783, 783, 783, 783,
-
783, 783, 783, 783, 783, 783, 783, 783,
783, 783, 783, 783, 783, 783, 783, 783,
- 783, 783, 783, 783, 783, 783, 783, 784,
- 784, 785, 785, 786, 787, 788, 788, 788,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 789, 789, 789, 789, 789, 789,
+ 783, 783, 783, 783, 783, 783, 193, 784,
+ 193, 193, 193, 193, 193, 784, 193, 193,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 785,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 789, 789, 789, 789, 789, 789,
- 789, 789, 790, 790, 790, 790, 790, 789,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 785,
+ 785, 785, 785, 785, 785, 785, 785, 786,
+ 786, 787, 787, 788, 789, 790, 790, 790,
- 791, 792, 792, 792, 792, 792, 792, 792,
- 792, 792, 792, 792, 792, 792, 792, 792,
- 792, 792, 792, 792, 792, 792, 791, 791,
791, 791, 791, 791, 791, 791, 791, 791,
-
791, 791, 791, 791, 791, 791, 791, 791,
791, 791, 791, 791, 791, 791, 791, 791,
791, 791, 791, 791, 791, 791, 791, 791,
+
+ 791, 791, 791, 791, 791, 791, 791, 791,
+ 791, 791, 791, 791, 791, 791, 791, 791,
791, 791, 791, 791, 791, 791, 791, 791,
+ 791, 791, 792, 792, 792, 792, 792, 791,
- 791, 791, 791, 793, 793, 793, 793, 793,
+ 793, 794, 794, 794, 794, 794, 794, 794,
794, 794, 794, 794, 794, 794, 794, 794,
- 794, 794, 794, 794, 794, 794, 794, 794,
- 794, 794, 794, 794, 794, 794, 794, 794,
-
- 794, 794, 794, 795, 795, 795, 795, 795,
- 795, 795, 795, 795, 795, 795, 795, 795,
- 795, 795, 795, 795, 795, 795, 795, 795,
- 795, 795, 795, 795, 795, 795, 795, 795,
-
- 795, 795, 795, 795, 795, 795, 795, 795,
- 795, 795, 795, 795, 795, 795, 795, 795,
- 795, 795, 795, 795, 795, 795, 795, 795,
- 795, 795, 796, 796, 796, 796, 796, 796,
-
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
-
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
-
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 192, 797, 797, 797, 797, 192, 192,
- 797, 797, 797, 797, 797, 797, 797, 192,
- 797, 192, 797, 797, 797, 797, 192, 192,
-
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 192, 797, 797, 797, 797, 192, 192,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 797,
+ 794, 794, 794, 794, 794, 794, 793, 793,
+ 793, 793, 793, 793, 793, 793, 793, 793,
- 797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 192, 797, 797, 797, 797, 192, 192,
- 797, 797, 797, 797, 797, 797, 797, 192,
+ 793, 793, 793, 793, 793, 793, 793, 793,
+ 793, 793, 793, 793, 793, 793, 793, 793,
+ 793, 793, 793, 793, 793, 793, 793, 793,
+ 793, 793, 793, 793, 793, 793, 793, 793,
- 797, 192, 797, 797, 797, 797, 192, 192,
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 797, 797, 797, 797, 797, 797, 192,
- 797, 797, 797, 797, 797, 797, 797, 797,
+ 793, 793, 793, 795, 795, 795, 795, 795,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 796, 796, 796, 796, 796,
+ 796, 796, 796, 797, 797, 797, 797, 797,
797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 798,
797, 797, 797, 797, 797, 797, 797, 797,
797, 797, 797, 797, 797, 797, 797, 797,
797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 797, 797, 797, 797, 798,
- 797, 192, 797, 797, 797, 797, 192, 192,
- 797, 797, 797, 797, 797, 797, 797, 798,
-
- 797, 797, 797, 797, 797, 797, 797, 798,
797, 797, 797, 797, 797, 797, 797, 797,
797, 797, 797, 797, 797, 797, 797, 797,
- 797, 797, 797, 192, 192, 799, 799, 800,
-
- 801, 802, 803, 804, 804, 804, 804, 803,
- 803, 805, 806, 807, 808, 809, 810, 811,
- 812, 813, 814, 814, 814, 814, 814, 814,
- 814, 814, 814, 814, 814, 192, 192, 192,
-
- 798, 798, 798, 798, 798, 798, 798, 798,
- 798, 798, 798, 798, 798, 798, 798, 798,
- 815, 815, 815, 815, 815, 815, 815, 815,
- 815, 815, 192, 192, 192, 192, 192, 192,
-
- 816, 816, 816, 816, 816, 816, 816, 816,
- 816, 816, 816, 816, 816, 816, 816, 816,
- 816, 816, 816, 816, 816, 816, 816, 816,
- 816, 816, 816, 816, 816, 816, 816, 816,
-
- 816, 816, 816, 816, 816, 816, 816, 816,
- 816, 816, 816, 816, 816, 816, 816, 816,
- 816, 816, 816, 816, 816, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 817, 818, 818, 818, 818, 818, 818, 818,
- 818, 818, 818, 818, 818, 818, 818, 818,
- 818, 818, 818, 818, 818, 818, 818, 818,
- 818, 818, 818, 818, 818, 818, 818, 818,
+ 797, 797, 798, 798, 798, 798, 798, 798,
+
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 193, 799, 799, 799, 799, 193, 193,
+ 799, 799, 799, 799, 799, 799, 799, 193,
+ 799, 193, 799, 799, 799, 799, 193, 193,
+
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 193, 799, 799, 799, 799, 193, 193,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 193, 799, 799, 799, 799, 193, 193,
+ 799, 799, 799, 799, 799, 799, 799, 193,
+
+ 799, 193, 799, 799, 799, 799, 193, 193,
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 799, 799, 799, 799, 799, 799, 193,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 193, 799, 799, 799, 799, 193, 193,
+ 799, 799, 799, 799, 799, 799, 799, 800,
+
+ 799, 799, 799, 799, 799, 799, 799, 800,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 799, 799, 799, 799, 799,
+ 799, 799, 799, 193, 193, 801, 801, 802,
+
+ 803, 804, 805, 806, 806, 806, 806, 805,
+ 805, 807, 808, 809, 810, 811, 812, 813,
+ 814, 815, 816, 816, 816, 816, 816, 816,
+ 816, 816, 816, 816, 816, 193, 193, 193,
+
+ 800, 800, 800, 800, 800, 800, 800, 800,
+ 800, 800, 800, 800, 800, 800, 800, 800,
+ 817, 817, 817, 817, 817, 817, 817, 817,
+ 817, 817, 193, 193, 193, 193, 193, 193,
818, 818, 818, 818, 818, 818, 818, 818,
818, 818, 818, 818, 818, 818, 818, 818,
@@ -1645,279 +1630,299 @@ static const unsigned short uc_property_trie[] = {
818, 818, 818, 818, 818, 818, 818, 818,
818, 818, 818, 818, 818, 818, 818, 818,
- 818, 818, 818, 818, 818, 819, 820, 818,
- 818, 818, 818, 818, 818, 818, 818, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
-
- 822, 823, 823, 823, 823, 823, 823, 823,
- 823, 823, 823, 823, 823, 823, 823, 823,
+ 818, 818, 818, 818, 818, 818, 818, 818,
+ 818, 818, 818, 818, 818, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 819, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 820, 820, 820,
+
+ 820, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 820, 820, 820, 821, 822, 820,
+ 820, 820, 820, 820, 820, 820, 820, 823,
823, 823, 823, 823, 823, 823, 823, 823,
- 823, 823, 823, 824, 825, 192, 192, 192,
- 826, 826, 826, 826, 826, 826, 826, 826,
- 826, 826, 826, 826, 826, 826, 826, 826,
- 826, 826, 826, 826, 826, 826, 826, 826,
- 826, 826, 826, 826, 826, 826, 826, 826,
+ 824, 825, 825, 825, 825, 825, 825, 825,
+ 825, 825, 825, 825, 825, 825, 825, 825,
+ 825, 825, 825, 825, 825, 825, 825, 825,
+ 825, 825, 825, 826, 827, 193, 193, 193,
- 826, 826, 826, 826, 826, 826, 826, 826,
- 826, 826, 826, 827, 827, 827, 828, 828,
- 828, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 828, 828, 828, 828, 828, 828, 828, 828,
+ 828, 828, 828, 828, 828, 828, 828, 828,
+ 828, 828, 828, 828, 828, 828, 828, 828,
+ 828, 828, 828, 828, 828, 828, 828, 828,
- 829, 829, 829, 829, 829, 829, 829, 829,
- 829, 829, 829, 829, 829, 192, 829, 829,
- 829, 829, 830, 830, 831, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 828, 828, 828, 828, 828, 828, 828, 828,
+ 828, 828, 828, 829, 829, 829, 830, 830,
+ 830, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 832, 832, 832, 832, 832, 832, 832, 832,
- 832, 832, 832, 832, 832, 832, 832, 832,
- 832, 832, 833, 833, 834, 835, 835, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 831, 831, 831, 831, 831, 831, 831, 831,
+ 831, 831, 831, 831, 831, 193, 831, 831,
+ 831, 831, 832, 832, 833, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 836, 836, 836, 836, 836, 836, 836, 836,
- 836, 836, 836, 836, 836, 836, 836, 836,
- 836, 836, 837, 837, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 834, 834, 834, 834, 834, 834, 834, 834,
+ 834, 834, 834, 834, 834, 834, 834, 834,
+ 834, 834, 835, 835, 836, 837, 837, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
838, 838, 838, 838, 838, 838, 838, 838,
- 838, 838, 838, 838, 838, 192, 838, 838,
- 838, 192, 839, 839, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 838, 838, 838, 838, 838, 838, 838, 838,
+ 838, 838, 839, 839, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
840, 840, 840, 840, 840, 840, 840, 840,
- 840, 840, 840, 840, 840, 840, 840, 840,
- 840, 840, 840, 840, 840, 840, 840, 840,
- 840, 840, 840, 840, 840, 840, 840, 840,
+ 840, 840, 840, 840, 840, 193, 840, 840,
+ 840, 193, 841, 841, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 842, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 842, 842, 842, 842, 842,
+
+ 842, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 842, 842, 842, 842, 842,
+ 842, 842, 842, 842, 843, 843, 844, 843,
+ 843, 843, 843, 843, 843, 843, 844, 844,
+
+ 844, 844, 844, 844, 844, 844, 843, 844,
+ 844, 843, 843, 843, 843, 843, 843, 843,
+ 843, 843, 845, 843, 846, 846, 847, 848,
+ 846, 849, 846, 850, 842, 851, 193, 193,
+
+ 852, 853, 854, 855, 856, 857, 858, 859,
+ 860, 861, 193, 193, 193, 193, 193, 193,
+ 862, 862, 862, 862, 862, 862, 862, 862,
+ 862, 862, 193, 193, 193, 193, 193, 193,
+
+ 863, 863, 864, 865, 866, 867, 868, 869,
+ 870, 871, 872, 873, 873, 873, 874, 193,
+ 875, 876, 877, 878, 879, 880, 881, 882,
+ 883, 884, 193, 193, 193, 193, 193, 193,
- 840, 840, 840, 840, 840, 840, 840, 840,
- 840, 840, 840, 840, 840, 840, 840, 840,
- 840, 840, 840, 840, 841, 841, 842, 841,
- 841, 841, 841, 841, 841, 841, 842, 842,
-
- 842, 842, 842, 842, 842, 842, 841, 842,
- 842, 841, 841, 841, 841, 841, 841, 841,
- 841, 841, 843, 841, 844, 844, 845, 846,
- 844, 847, 844, 848, 840, 849, 192, 192,
-
- 850, 851, 852, 853, 854, 855, 856, 857,
- 858, 859, 192, 192, 192, 192, 192, 192,
- 860, 860, 860, 860, 860, 860, 860, 860,
- 860, 860, 192, 192, 192, 192, 192, 192,
-
- 861, 861, 862, 863, 864, 865, 866, 861,
- 867, 868, 861, 869, 869, 869, 870, 192,
- 871, 872, 873, 874, 875, 876, 877, 878,
- 879, 880, 192, 192, 192, 192, 192, 192,
-
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
-
- 881, 881, 881, 882, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
-
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 881, 881, 881, 881, 881, 881, 881,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 881, 881, 881, 881, 881, 881, 881, 881,
- 881, 883, 884, 192, 192, 192, 192, 192,
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
-
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
-
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 821, 821,
- 821, 821, 821, 821, 821, 821, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 886, 885, 885, 885, 885,
885, 885, 885, 885, 885, 885, 885, 885,
885, 885, 885, 885, 885, 885, 885, 885,
885, 885, 885, 885, 885, 885, 885, 885,
- 885, 885, 885, 885, 885, 192, 192, 192,
-
- 886, 886, 886, 887, 887, 887, 887, 886,
- 886, 887, 887, 887, 192, 192, 192, 192,
- 887, 887, 886, 887, 887, 887, 887, 887,
- 887, 888, 889, 890, 192, 192, 192, 192,
-
- 891, 192, 192, 192, 892, 892, 893, 894,
- 895, 896, 897, 898, 899, 900, 901, 902,
- 903, 903, 903, 903, 903, 903, 903, 903,
- 903, 903, 903, 903, 903, 903, 903, 903,
-
- 903, 903, 903, 903, 903, 903, 903, 903,
- 903, 903, 903, 903, 903, 903, 192, 192,
- 903, 903, 903, 903, 903, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 904, 904, 904, 904, 904, 904, 904, 904,
- 904, 904, 904, 904, 904, 904, 904, 904,
- 904, 904, 904, 904, 904, 904, 904, 904,
- 904, 904, 904, 904, 904, 904, 904, 904,
-
- 904, 904, 904, 904, 904, 904, 904, 904,
- 904, 904, 905, 905, 192, 192, 192, 192,
- 906, 906, 906, 906, 906, 907, 907, 907,
- 906, 906, 907, 906, 906, 906, 906, 906,
-
- 906, 904, 904, 904, 904, 904, 904, 904,
- 906, 906, 192, 192, 192, 192, 192, 192,
- 908, 909, 910, 911, 912, 913, 914, 915,
- 916, 917, 918, 192, 192, 192, 919, 919,
-
- 920, 920, 920, 920, 920, 920, 920, 920,
- 920, 920, 920, 920, 920, 920, 920, 920,
- 920, 920, 920, 920, 920, 920, 920, 920,
- 920, 920, 920, 920, 920, 920, 920, 920,
-
- 921, 921, 921, 921, 921, 921, 921, 921,
- 921, 921, 921, 921, 921, 921, 921, 921,
- 921, 921, 921, 921, 921, 921, 921, 922,
- 923, 924, 924, 924, 192, 192, 925, 925,
- 926, 926, 926, 926, 926, 926, 926, 926,
- 926, 926, 926, 926, 926, 926, 926, 926,
- 926, 926, 926, 926, 926, 926, 926, 926,
- 926, 926, 926, 926, 926, 926, 926, 926,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 887, 887, 887, 887, 887, 887, 887, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 885, 885, 885, 885, 885, 885, 885,
+
+ 885, 885, 885, 885, 885, 885, 885, 885,
+ 885, 888, 889, 193, 193, 193, 193, 193,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 823, 823,
+ 823, 823, 823, 823, 823, 823, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 890, 890, 890, 890, 890, 890, 890, 890,
+ 890, 890, 890, 890, 890, 890, 890, 890,
+ 890, 890, 890, 890, 890, 890, 890, 890,
+ 890, 890, 890, 890, 890, 193, 193, 193,
+
+ 891, 891, 891, 892, 892, 892, 892, 891,
+ 891, 892, 892, 892, 193, 193, 193, 193,
+ 892, 892, 891, 892, 892, 892, 892, 892,
+ 892, 893, 894, 895, 193, 193, 193, 193,
+
+ 896, 193, 193, 193, 897, 897, 898, 899,
+ 900, 901, 902, 903, 904, 905, 906, 907,
+ 908, 908, 908, 908, 908, 908, 908, 908,
+ 908, 908, 908, 908, 908, 908, 908, 908,
+
+ 908, 908, 908, 908, 908, 908, 908, 908,
+ 908, 908, 908, 908, 908, 908, 193, 193,
+ 908, 908, 908, 908, 908, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 909, 909, 909, 909, 909, 909, 909, 909,
+ 909, 909, 909, 909, 909, 909, 909, 909,
+ 909, 909, 909, 909, 909, 909, 909, 909,
+ 909, 909, 909, 909, 909, 909, 909, 909,
+
+ 909, 909, 909, 909, 909, 909, 909, 909,
+ 909, 909, 910, 910, 193, 193, 193, 193,
+ 911, 911, 911, 911, 911, 912, 912, 912,
+ 911, 911, 912, 911, 911, 911, 911, 911,
+
+ 911, 909, 909, 909, 909, 909, 909, 909,
+ 911, 911, 193, 193, 193, 193, 193, 193,
+ 913, 914, 915, 916, 917, 918, 919, 920,
+ 921, 922, 923, 193, 193, 193, 924, 924,
+
+ 925, 925, 925, 925, 925, 925, 925, 925,
+ 925, 925, 925, 925, 925, 925, 925, 925,
+ 925, 925, 925, 925, 925, 925, 925, 925,
+ 925, 925, 925, 925, 925, 925, 925, 925,
926, 926, 926, 926, 926, 926, 926, 926,
926, 926, 926, 926, 926, 926, 926, 926,
- 926, 926, 926, 926, 926, 927, 928, 927,
- 928, 928, 928, 928, 928, 928, 928, 192,
-
- 929, 930, 928, 930, 930, 928, 928, 928,
- 928, 928, 928, 928, 928, 927, 927, 927,
- 927, 927, 927, 928, 928, 931, 931, 931,
- 931, 931, 931, 931, 931, 192, 192, 932,
-
- 933, 934, 935, 936, 937, 938, 939, 940,
- 941, 942, 192, 192, 192, 192, 192, 192,
- 933, 934, 935, 936, 937, 938, 939, 940,
- 941, 942, 192, 192, 192, 192, 192, 192,
-
- 943, 943, 943, 943, 943, 943, 943, 944,
- 945, 945, 945, 945, 943, 943, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 946, 946, 946, 946, 947, 948, 949, 948,
- 949, 948, 949, 948, 949, 948, 949, 948,
- 948, 948, 949, 948, 948, 948, 948, 948,
- 948, 948, 948, 948, 948, 948, 948, 948,
-
- 948, 948, 948, 948, 948, 948, 948, 948,
- 948, 948, 948, 948, 948, 948, 948, 948,
- 948, 948, 948, 948, 950, 951, 946, 946,
- 946, 946, 946, 952, 946, 952, 947, 947,
-
- 952, 952, 946, 952, 953, 948, 948, 948,
- 948, 948, 948, 948, 192, 192, 192, 192,
- 954, 955, 956, 957, 958, 959, 960, 961,
- 962, 963, 964, 964, 965, 966, 964, 964,
-
- 966, 967, 967, 967, 967, 967, 967, 967,
- 967, 967, 967, 968, 969, 968, 968, 968,
- 968, 968, 968, 968, 967, 967, 967, 967,
- 967, 967, 967, 967, 967, 192, 192, 192,
-
- 970, 970, 971, 972, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 972, 972, 972,
- 972, 972, 972, 972, 972, 972, 972, 972,
-
- 972, 971, 970, 970, 970, 970, 971, 971,
- 970, 970, 973, 974, 975, 975, 972, 972,
- 976, 977, 978, 979, 980, 981, 982, 983,
- 984, 985, 986, 986, 986, 986, 986, 986,
-
- 987, 987, 987, 987, 987, 987, 987, 987,
- 987, 987, 987, 987, 987, 987, 987, 987,
- 987, 987, 987, 987, 987, 987, 987, 987,
- 987, 987, 987, 987, 987, 987, 987, 987,
-
- 987, 987, 987, 987, 987, 987, 988, 989,
- 990, 990, 989, 989, 989, 990, 989, 990,
- 990, 990, 991, 991, 192, 192, 192, 192,
- 192, 192, 192, 192, 992, 992, 992, 992,
+ 926, 926, 926, 926, 926, 926, 926, 927,
+ 928, 929, 929, 930, 193, 193, 931, 931,
+
+ 932, 932, 932, 932, 932, 932, 932, 932,
+ 932, 932, 932, 932, 932, 932, 932, 932,
+ 932, 932, 932, 932, 932, 932, 932, 932,
+ 932, 932, 932, 932, 932, 932, 932, 932,
+
+ 932, 932, 932, 932, 932, 932, 932, 932,
+ 932, 932, 932, 932, 932, 932, 932, 932,
+ 932, 932, 932, 932, 932, 933, 934, 933,
+ 934, 934, 934, 934, 934, 934, 934, 193,
+
+ 935, 936, 934, 936, 936, 934, 934, 934,
+ 934, 934, 934, 934, 934, 933, 933, 933,
+ 933, 933, 933, 934, 934, 937, 937, 937,
+ 937, 937, 937, 937, 937, 193, 193, 938,
+
+ 939, 940, 941, 942, 943, 944, 945, 946,
+ 947, 948, 193, 193, 193, 193, 193, 193,
+ 939, 940, 941, 942, 943, 944, 945, 946,
+ 947, 948, 193, 193, 193, 193, 193, 193,
+
+ 949, 949, 949, 949, 949, 949, 949, 950,
+ 951, 951, 951, 951, 949, 949, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 952, 952, 952, 952, 953, 954, 955, 954,
+ 955, 954, 955, 954, 955, 954, 955, 954,
+ 954, 954, 955, 954, 954, 954, 954, 954,
+ 954, 954, 954, 954, 954, 954, 954, 954,
+
+ 954, 954, 954, 954, 954, 954, 954, 954,
+ 954, 954, 954, 954, 954, 954, 954, 954,
+ 954, 954, 954, 954, 956, 957, 952, 952,
+ 952, 952, 952, 958, 952, 958, 953, 953,
+
+ 958, 958, 952, 958, 959, 954, 954, 954,
+ 954, 954, 954, 954, 193, 193, 193, 193,
+ 960, 961, 962, 963, 964, 965, 966, 967,
+ 968, 969, 970, 970, 971, 972, 970, 970,
+
+ 972, 973, 973, 973, 973, 973, 973, 973,
+ 973, 973, 973, 974, 975, 974, 974, 974,
+ 974, 974, 974, 974, 973, 973, 973, 973,
+ 973, 973, 973, 973, 973, 193, 193, 193,
+
+ 976, 976, 977, 978, 978, 978, 978, 978,
+ 978, 978, 978, 978, 978, 978, 978, 978,
+ 978, 978, 978, 978, 978, 978, 978, 978,
+ 978, 978, 978, 978, 978, 978, 978, 978,
+
+ 978, 977, 976, 976, 976, 976, 977, 977,
+ 976, 976, 979, 980, 981, 981, 978, 978,
+ 982, 983, 984, 985, 986, 987, 988, 989,
+ 990, 991, 992, 992, 992, 992, 992, 992,
993, 993, 993, 993, 993, 993, 993, 993,
993, 993, 993, 993, 993, 993, 993, 993,
993, 993, 993, 993, 993, 993, 993, 993,
993, 993, 993, 993, 993, 993, 993, 993,
- 993, 993, 993, 993, 994, 994, 994, 994,
- 994, 994, 994, 994, 995, 995, 995, 995,
- 995, 995, 995, 995, 994, 994, 995, 996,
- 192, 192, 192, 997, 997, 998, 998, 998,
-
- 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006,
- 1007, 1008, 192, 192, 192, 993, 993, 993,
- 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,
- 1017, 1018, 1019, 1019, 1019, 1019, 1019, 1019,
-
- 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
- 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
- 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019,
- 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1021,
-
- 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1023, 1023, 1023, 1024, 1025, 1026, 1026, 1026,
- 1026, 1026, 1023, 1023, 1026, 1026, 1026, 1026,
-
- 1023, 1027, 1025, 1025, 1025, 1025, 1025, 1025,
- 1025, 1028, 1028, 1028, 1028, 1026, 1028, 1028,
- 1028, 1028, 1027, 1029, 1030, 1031, 1031, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 993, 993, 993, 993, 993, 993, 994, 995,
+ 996, 996, 995, 995, 995, 996, 995, 996,
+ 996, 996, 997, 997, 193, 193, 193, 193,
+ 193, 193, 193, 193, 998, 998, 998, 998,
+
+ 999, 999, 999, 999, 999, 999, 999, 999,
+ 999, 999, 999, 999, 999, 999, 999, 999,
+ 999, 999, 999, 999, 999, 999, 999, 999,
+ 999, 999, 999, 999, 999, 999, 999, 999,
+
+ 999, 999, 999, 999, 1000, 1000, 1000, 1000,
+ 1000, 1000, 1000, 1000, 1001, 1001, 1001, 1001,
+ 1001, 1001, 1001, 1001, 1000, 1000, 1001, 1002,
+ 193, 193, 193, 1003, 1003, 1004, 1004, 1004,
+
+ 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012,
+ 1013, 1014, 193, 193, 193, 999, 999, 999,
+ 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022,
+ 1023, 1024, 1025, 1025, 1025, 1025, 1025, 1025,
+
+ 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025,
+ 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025,
+ 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025,
+ 1026, 1026, 1026, 1026, 1026, 1026, 1027, 1027,
+
+ 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1029, 1029, 1029, 1030, 1031, 1032, 1032, 1032,
+ 1032, 1032, 1029, 1029, 1032, 1032, 1032, 1032,
+
+ 1029, 1033, 1031, 1031, 1031, 1031, 1031, 1031,
+ 1031, 1034, 1034, 1034, 1034, 1032, 1034, 1034,
+ 1034, 1034, 1033, 1035, 1036, 1037, 1037, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 114, 114, 114, 114, 114,
114, 114, 114, 114, 114, 114, 114, 114,
- 114, 114, 114, 114, 114, 114, 1032, 1032,
- 1032, 1032, 1032, 1033, 1034, 1034, 1034, 1035,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
- 1034, 1034, 1034, 1035, 1034, 1034, 1034, 1034,
+ 114, 114, 114, 114, 114, 114, 1038, 1038,
+ 1038, 1038, 1038, 1039, 1040, 1040, 1040, 1041,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1041, 1040, 1040, 1040, 1040,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
- 1034, 1034, 1034, 1034, 1034, 1034, 1035, 1034,
- 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034,
- 1034, 1034, 1034, 1034, 1034, 1036, 1036, 1036,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1042, 1042, 1042,
- 1036, 1036, 1034, 1034, 1034, 1034, 1036, 1036,
- 1036, 1036, 1036, 114, 115, 115, 115, 115,
+ 1042, 1042, 1040, 1040, 1040, 1040, 1042, 1042,
+ 1042, 1042, 1042, 114, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
- 1037, 1038, 115, 115, 115, 1039, 115, 115,
+ 1043, 1044, 115, 115, 115, 1045, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
- 115, 115, 115, 1040, 1040, 1040, 1040, 1040,
+ 115, 115, 115, 1046, 1046, 1046, 1046, 1046,
- 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
- 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
- 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
- 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1041,
+ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046,
+ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046,
+ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046,
+ 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1047,
- 181, 181, 180, 181, 1042, 1042, 1042, 1042,
- 1042, 1042, 1043, 1044, 1044, 1045, 1046, 1047,
- 1048, 1044, 1044, 1044, 1044, 1044, 1044, 1044,
- 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044,
+ 182, 182, 181, 182, 1048, 1048, 1048, 1048,
+ 1048, 1048, 1049, 1050, 1050, 1051, 1052, 1053,
+ 1054, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050,
- 1044, 1044, 1044, 1044, 1044, 1044, 1044, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 1049, 1026, 1042, 1043,
+ 1050, 1050, 1050, 1050, 1050, 1050, 1050, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 1055, 1032, 1048, 1049,
70, 71, 70, 71, 70, 71, 70, 71,
70, 71, 70, 71, 70, 71, 70, 71,
@@ -1926,258 +1931,258 @@ static const unsigned short uc_property_trie[] = {
70, 71, 70, 71, 70, 71, 70, 71,
70, 71, 70, 71, 70, 71, 70, 71,
- 70, 71, 70, 71, 70, 71, 1050, 1051,
- 1052, 1053, 1054, 1055, 1056, 1056, 1057, 1056,
+ 70, 71, 70, 71, 70, 71, 1056, 1057,
+ 1058, 1059, 1060, 1061, 1062, 1062, 1063, 1062,
70, 71, 70, 71, 70, 71, 70, 71,
70, 71, 70, 71, 70, 71, 70, 71,
70, 71, 70, 71, 70, 71, 70, 71,
- 70, 71, 1058, 1059, 1058, 1059, 1058, 1059,
-
- 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
- 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
- 1060, 1060, 1060, 1060, 1060, 1060, 192, 192,
- 1061, 1061, 1061, 1061, 1061, 1061, 192, 192,
-
- 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
- 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
- 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
- 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
-
- 1060, 1060, 1060, 1060, 1060, 1060, 192, 192,
- 1061, 1061, 1061, 1061, 1061, 1061, 192, 192,
- 1062, 1060, 1063, 1060, 1064, 1060, 1065, 1060,
- 192, 1061, 192, 1061, 192, 1061, 192, 1061,
-
- 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060,
- 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061,
- 1066, 1067, 1068, 1069, 1068, 1069, 1070, 1071,
- 1072, 1073, 1074, 1075, 1076, 1077, 192, 192,
-
- 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085,
- 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093,
- 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101,
- 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109,
-
- 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117,
- 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125,
- 1060, 1060, 1126, 1127, 1128, 192, 1129, 1130,
- 1061, 1061, 1131, 1132, 1133, 196, 1134, 196,
-
- 196, 1135, 1136, 1137, 1138, 192, 1139, 1140,
- 1141, 1142, 1141, 1142, 1143, 1135, 1135, 1135,
- 1060, 1060, 1144, 1145, 192, 192, 1146, 1147,
- 1061, 1061, 1148, 1149, 192, 1135, 1135, 1135,
-
- 1060, 1060, 1150, 1151, 1152, 1153, 1154, 1155,
- 1061, 1061, 1156, 1157, 1158, 1135, 1159, 1159,
- 192, 192, 1160, 1161, 1162, 192, 1163, 1164,
- 1165, 1166, 1167, 1168, 1169, 1170, 196, 192,
-
- 1171, 1171, 1172, 1172, 1172, 1172, 1172, 1173,
- 1172, 1172, 1172, 1174, 1175, 1176, 1177, 1178,
- 1179, 1180, 1179, 1181, 1182, 1183, 14, 1184,
- 1185, 1186, 1187, 1188, 1188, 1189, 1187, 1188,
-
- 14, 14, 14, 14, 1190, 1191, 1191, 1192,
- 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200,
- 13, 13, 13, 1201, 1201, 1202, 1203, 1203,
- 14, 1204, 1205, 14, 1206, 1207, 1184, 43,
-
- 43, 14, 14, 14, 1208, 16, 1209, 1210,
- 1211, 1211, 1212, 1212, 1212, 1212, 1213, 1213,
- 1213, 1213, 1214, 1215, 1216, 1217, 1218, 1219,
- 1218, 1218, 1218, 1218, 1217, 1218, 1218, 1220,
-
- 1221, 1222, 1222, 1222, 1223, 1224, 1224, 1224,
- 1224, 1224, 1225, 1225, 1225, 1225, 1225, 1225,
- 1226, 1227, 192, 192, 1228, 1229, 1230, 1231,
- 1232, 1233, 1234, 1234, 1235, 1236, 1237, 151,
-
- 1226, 63, 58, 59, 1228, 1229, 1230, 1231,
- 1232, 1233, 1234, 1234, 1235, 1236, 1237, 192,
- 1040, 1040, 1040, 1040, 1040, 1238, 1238, 1238,
- 1238, 1238, 1238, 1238, 1238, 192, 192, 192,
+ 70, 71, 1064, 1065, 1064, 1065, 1064, 1065,
+
+ 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066,
+ 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
+ 1066, 1066, 1066, 1066, 1066, 1066, 193, 193,
+ 1067, 1067, 1067, 1067, 1067, 1067, 193, 193,
+
+ 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066,
+ 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
+ 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066,
+ 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
+
+ 1066, 1066, 1066, 1066, 1066, 1066, 193, 193,
+ 1067, 1067, 1067, 1067, 1067, 1067, 193, 193,
+ 1068, 1066, 1069, 1066, 1070, 1066, 1071, 1066,
+ 193, 1067, 193, 1067, 193, 1067, 193, 1067,
+
+ 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066,
+ 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
+ 1072, 1073, 1074, 1075, 1074, 1075, 1076, 1077,
+ 1078, 1079, 1080, 1081, 1082, 1083, 193, 193,
+
+ 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091,
+ 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099,
+ 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107,
+ 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115,
+
+ 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123,
+ 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131,
+ 1066, 1066, 1132, 1133, 1134, 193, 1135, 1136,
+ 1067, 1067, 1137, 1138, 1139, 197, 1140, 197,
+
+ 197, 1141, 1142, 1143, 1144, 193, 1145, 1146,
+ 1147, 1148, 1147, 1148, 1149, 1141, 1141, 1141,
+ 1066, 1066, 1150, 1151, 193, 193, 1152, 1153,
+ 1067, 1067, 1154, 1155, 193, 1141, 1141, 1141,
+
+ 1066, 1066, 1156, 1157, 1158, 1159, 1160, 1161,
+ 1067, 1067, 1162, 1163, 1164, 1141, 1165, 1165,
+ 193, 193, 1166, 1167, 1168, 193, 1169, 1170,
+ 1171, 1172, 1173, 1174, 1175, 1176, 197, 193,
+
+ 1177, 1177, 1178, 1178, 1178, 1178, 1178, 1179,
+ 1178, 1178, 1178, 1180, 1181, 1182, 1183, 1184,
+ 1185, 1186, 1185, 1187, 1188, 1189, 14, 1190,
+ 1191, 1192, 1193, 1194, 1194, 1195, 1193, 1194,
+
+ 14, 14, 14, 14, 1196, 1197, 1197, 1198,
+ 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206,
+ 13, 13, 13, 1207, 1207, 1208, 1209, 1209,
+ 14, 1210, 1211, 14, 1212, 1213, 1190, 43,
+
+ 43, 14, 14, 14, 1214, 16, 1215, 1216,
+ 1217, 1217, 1218, 1218, 1218, 1218, 1219, 1219,
+ 1219, 1219, 1220, 1221, 1222, 1223, 1224, 1225,
+ 1224, 1224, 1224, 1224, 1223, 1224, 1224, 1226,
+
+ 1227, 1228, 1228, 1228, 1229, 1230, 1231, 1232,
+ 1233, 1234, 1235, 1235, 1235, 1235, 1235, 1235,
+ 1236, 1237, 193, 193, 1238, 1239, 1240, 1241,
+ 1242, 1243, 1244, 1244, 1245, 1246, 1247, 151,
+
+ 1236, 63, 58, 59, 1238, 1239, 1240, 1241,
+ 1242, 1243, 1244, 1244, 1245, 1246, 1247, 193,
+ 1046, 1046, 1046, 1046, 1046, 1248, 1248, 1248,
+ 1248, 1248, 1248, 1248, 1248, 193, 193, 193,
12, 12, 12, 12, 12, 12, 12, 50,
- 1239, 12, 12, 1240, 1241, 1242, 1242, 1242,
- 1243, 1243, 1244, 1244, 1244, 1244, 1245, 1246,
- 1246, 1247, 1248, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 163, 163, 170, 170, 163, 163, 163, 163,
- 170, 170, 170, 163, 163, 1249, 1249, 1249,
-
- 1249, 163, 1250, 1250, 1251, 1252, 1252, 187,
- 1253, 187, 1252, 1254, 1043, 1043, 1043, 1043,
- 1044, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1255, 1255, 1256, 1257, 51, 1255, 1255, 1256,
- 51, 1257, 1258, 1256, 1256, 1256, 1258, 1258,
- 1256, 1256, 1256, 1258, 51, 1256, 1259, 51,
- 36, 1256, 1256, 1256, 1256, 1256, 51, 51,
-
- 1255, 1255, 1255, 51, 1256, 51, 1260, 51,
- 1256, 51, 1261, 1262, 1256, 1256, 1263, 1258,
- 1256, 1256, 1264, 1256, 1258, 1265, 1265, 1265,
- 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1271,
-
- 1272, 1214, 1214, 1214, 1214, 1271, 1270, 1270,
- 1270, 1270, 1273, 1214, 1274, 1275, 1276, 1277,
- 1278, 1278, 1278, 65, 65, 65, 65, 65,
+ 1249, 12, 12, 1250, 1251, 1252, 1252, 1252,
+ 1253, 1253, 1254, 1254, 1254, 1254, 1255, 1256,
+ 1256, 1257, 1258, 1259, 1259, 1259, 1259, 1259,
+
+ 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259,
+ 1259, 1259, 1259, 1259, 1259, 1259, 1259, 1259,
+ 164, 164, 171, 171, 164, 164, 164, 164,
+ 171, 171, 171, 164, 164, 1260, 1260, 1260,
+
+ 1260, 164, 1261, 1261, 1262, 1263, 1263, 188,
+ 1264, 188, 1263, 1265, 1049, 1049, 1049, 1049,
+ 1050, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1266, 1266, 1267, 1268, 51, 1266, 1266, 1267,
+ 51, 1268, 1269, 1267, 1267, 1267, 1269, 1269,
+ 1267, 1267, 1267, 1269, 51, 1267, 1270, 51,
+ 36, 1267, 1267, 1267, 1267, 1267, 51, 51,
+
+ 1266, 1266, 1266, 51, 1267, 51, 1271, 51,
+ 1267, 51, 1272, 1273, 1267, 1267, 1274, 1269,
+ 1267, 1267, 1275, 1267, 1269, 1276, 1276, 1276,
+ 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1282,
+
+ 1283, 1220, 1220, 1220, 1220, 1282, 1281, 1281,
+ 1281, 1281, 1284, 1220, 1285, 1286, 1287, 1288,
+ 1289, 1289, 1289, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65,
- 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279,
- 1279, 1279, 1279, 1279, 1279, 1279, 1279, 1279,
- 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280,
- 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280,
+ 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290,
+ 1290, 1290, 1290, 1290, 1290, 1290, 1290, 1290,
+ 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
+ 1291, 1291, 1291, 1291, 1291, 1291, 1291, 1291,
- 1281, 1281, 1281, 111, 122, 1282, 1282, 1282,
- 1282, 1278, 192, 192, 192, 192, 192, 192,
+ 1292, 1292, 1292, 111, 122, 1293, 1293, 1293,
+ 1293, 1289, 193, 193, 193, 193, 193, 193,
36, 36, 36, 36, 36, 51, 51, 51,
- 51, 51, 1283, 1283, 51, 51, 51, 51,
+ 51, 51, 1294, 1294, 51, 51, 51, 51,
36, 51, 51, 36, 51, 51, 36, 51,
- 51, 51, 51, 51, 51, 51, 1283, 51,
+ 51, 51, 51, 51, 51, 51, 1294, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 1284, 1283, 1283,
+ 51, 51, 51, 51, 51, 1295, 1294, 1294,
51, 51, 36, 51, 36, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 1267, 1267, 1267, 1267, 1267,
- 1267, 1267, 1267, 1267, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 51, 51, 51, 1278, 1278, 1278, 1278, 1278,
+ 1278, 1278, 1278, 1278, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
- 36, 36, 36, 36, 1283, 36, 36, 36,
- 1285, 1286, 1285, 1287, 1288, 1287, 36, 36,
- 36, 36, 18, 57, 36, 1289, 36, 36,
+ 36, 36, 36, 36, 1294, 36, 36, 36,
+ 1296, 1297, 1296, 1298, 1299, 1298, 36, 36,
+ 36, 36, 18, 57, 36, 1300, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 1283, 36, 1283, 36,
- 36, 36, 36, 36, 1235, 1235, 36, 1235,
- 1235, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 36, 36, 1290, 1291, 36, 36,
+ 36, 36, 36, 36, 1294, 36, 1294, 36,
+ 36, 36, 36, 36, 1245, 1245, 36, 1245,
+ 1245, 36, 36, 36, 36, 36, 36, 36,
+ 36, 36, 36, 36, 1301, 1302, 36, 36,
- 36, 1283, 36, 1292, 1283, 36, 36, 1283,
- 36, 1283, 36, 36, 36, 36, 36, 36,
- 36, 36, 1290, 1291, 1290, 1291, 36, 36,
+ 36, 1294, 36, 1303, 1294, 36, 36, 1294,
+ 36, 1294, 36, 36, 36, 36, 36, 36,
+ 36, 36, 1301, 1302, 1301, 1302, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
- 1283, 36, 1283, 36, 1290, 1291, 1290, 1291,
- 1290, 1291, 1290, 1291, 36, 1283, 1293, 1294,
- 1293, 1294, 1290, 1291, 1293, 1294, 1290, 1291,
- 1293, 1294, 1290, 1291, 1290, 1291, 1290, 1291,
+ 1294, 36, 1294, 36, 1301, 1302, 1301, 1302,
+ 1301, 1302, 1301, 1302, 36, 1294, 1304, 1305,
+ 1304, 1305, 1301, 1302, 1304, 1305, 1301, 1302,
+ 1304, 1305, 1301, 1302, 1301, 1302, 1301, 1302,
- 1293, 1294, 1290, 1291, 1293, 1294, 1290, 1291,
- 1293, 1294, 1290, 1291, 36, 36, 36, 1290,
- 1291, 1290, 1291, 36, 36, 36, 36, 36,
- 1295, 36, 36, 36, 36, 36, 36, 36,
+ 1304, 1305, 1301, 1302, 1304, 1305, 1301, 1302,
+ 1304, 1305, 1301, 1302, 36, 36, 36, 1301,
+ 1302, 1301, 1302, 36, 36, 36, 36, 36,
+ 1306, 36, 36, 36, 36, 36, 36, 36,
- 36, 36, 1290, 1291, 36, 36, 1296, 36,
- 1297, 1298, 36, 1298, 1283, 1283, 1283, 1283,
- 1290, 1291, 1290, 1291, 1290, 1291, 1290, 1291,
+ 36, 36, 1301, 1302, 36, 36, 1307, 36,
+ 1308, 1309, 36, 1309, 1294, 1294, 1294, 1294,
+ 1301, 1302, 1301, 1302, 1301, 1302, 1301, 1302,
36, 36, 36, 36, 36, 36, 36, 36,
36, 36, 36, 36, 36, 36, 36, 36,
- 36, 1290, 1291, 1290, 1291, 1299, 36, 36,
- 1290, 1291, 36, 36, 36, 36, 1290, 1291,
- 1290, 1291, 1290, 1291, 1290, 1291, 1290, 1291,
+ 36, 1301, 1302, 1301, 1302, 1310, 36, 36,
+ 1301, 1302, 36, 36, 36, 36, 1301, 1302,
+ 1301, 1302, 1301, 1302, 1301, 1302, 1301, 1302,
- 1293, 1294, 1293, 1294, 1290, 1291, 1290, 1291,
- 1290, 1291, 1293, 1294, 1293, 1294, 36, 36,
- 1290, 1291, 1300, 1300, 1300, 1214, 1301, 1301,
- 1214, 1214, 1302, 1302, 1302, 1303, 1303, 1214,
+ 1304, 1305, 1304, 1305, 1301, 1302, 1301, 1302,
+ 1301, 1302, 1304, 1305, 1304, 1305, 36, 36,
+ 1301, 1302, 1311, 1311, 1311, 1220, 1312, 1312,
+ 1220, 1220, 1313, 1313, 1313, 1314, 1314, 1220,
- 51, 1267, 51, 51, 51, 51, 51, 51,
- 1290, 1291, 1290, 1291, 51, 51, 51, 51,
+ 51, 1278, 51, 51, 51, 51, 51, 51,
+ 1315, 1316, 1315, 1316, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 1304, 1304, 51, 51, 51, 51,
+ 51, 51, 1317, 1317, 51, 51, 51, 51,
36, 36, 51, 51, 51, 51, 51, 51,
- 51, 1305, 1306, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
-
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
-
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1307, 1307, 1307, 1307, 1307,
- 1307, 1307, 1307, 1267, 1214, 1267, 1267, 1267,
-
- 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
- 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
- 1267, 1267, 1267, 1267, 1267, 1308, 1267, 1267,
- 1267, 1267, 1267, 1214, 1214, 1214, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
-
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1309,
- 1309, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- 1274, 1274, 1274, 1274, 1310, 1310, 1310, 1310,
-
- 1310, 1310, 1275, 1275, 1275, 1275, 1275, 1275,
- 1311, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1313, 1313, 1313, 1313, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 51, 1318, 1319, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1320, 1320, 1320, 1320, 1320,
+ 1320, 1320, 1320, 1278, 1220, 1278, 1278, 1278,
+
+ 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278,
+ 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278,
+ 1278, 1278, 1278, 1278, 1278, 1321, 1278, 1278,
+ 1278, 1278, 1278, 1220, 1220, 1220, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1284, 1284, 1284, 1284,
+ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
+
+ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
+ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1322,
+ 1322, 1285, 1285, 1285, 1285, 1285, 1285, 1285,
+ 1285, 1285, 1285, 1285, 1323, 1323, 1323, 1323,
+
+ 1323, 1323, 1286, 1286, 1286, 1286, 1286, 1286,
+ 1324, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1326, 1326, 1326, 1326, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 1267, 1267, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 51, 51, 51, 51, 51, 1278, 1278, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 51, 51, 51, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321,
- 1322, 65, 65, 65, 65, 65, 65, 65,
- 65, 65, 65, 65, 1314, 1315, 1316, 1317,
- 1318, 1319, 1320, 1321, 1322, 65, 65, 65,
+ 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334,
+ 1335, 65, 65, 65, 65, 65, 65, 65,
+ 65, 65, 65, 65, 1327, 1328, 1329, 1330,
+ 1331, 1332, 1333, 1334, 1335, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65,
- 63, 58, 59, 1228, 1229, 1230, 1231, 1232,
- 1233, 1323, 1323, 1323, 1323, 1323, 1323, 1323,
- 1323, 1323, 1323, 1323, 1324, 1324, 1324, 1324,
+ 63, 58, 59, 1238, 1239, 1240, 1241, 1242,
+ 1243, 1336, 1336, 1336, 1336, 1336, 1336, 1336,
+ 1336, 1336, 1336, 1336, 1337, 1337, 1337, 1337,
- 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324,
- 1324, 1324, 1324, 1324, 1324, 1324, 1324, 1324,
- 1324, 1324, 1324, 1324, 1324, 1324, 1325, 1325,
- 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1337, 1337, 1337, 1337, 1337, 1337, 1337, 1337,
+ 1337, 1337, 1337, 1337, 1337, 1337, 1337, 1337,
+ 1337, 1337, 1337, 1337, 1337, 1337, 1338, 1338,
+ 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
- 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
- 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
- 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
+ 1338, 1338, 1338, 1338, 1338, 1338, 1338, 1338,
+ 1339, 1339, 1339, 1339, 1339, 1339, 1339, 1339,
+ 1339, 1339, 1339, 1339, 1339, 1339, 1339, 1339,
- 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
- 1326, 1326, 1327, 1328, 1328, 1328, 1328, 1328,
- 1328, 1328, 1328, 1328, 1328, 1329, 1330, 1331,
- 1332, 1333, 1334, 1335, 1336, 1337, 1328, 1338,
+ 1339, 1339, 1339, 1339, 1339, 1339, 1339, 1339,
+ 1339, 1339, 1340, 1341, 1341, 1341, 1341, 1341,
+ 1341, 1341, 1341, 1341, 1341, 1342, 1343, 1344,
+ 1345, 1346, 1347, 1348, 1349, 1350, 1341, 1351,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
+ 51, 51, 51, 51, 51, 51, 1284, 1284,
+ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
@@ -2191,2707 +2196,2707 @@ static const unsigned short uc_property_trie[] = {
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1267, 1267, 1267, 1267, 1267, 1267, 1267, 1267,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
+ 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
- 1304, 1304, 1304, 1304, 51, 51, 51, 51,
+ 1317, 1317, 1317, 1317, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 1339, 1339, 1273, 1273,
- 1340, 1267, 1304, 1304, 1304, 1304, 1304, 1304,
+ 51, 51, 51, 51, 1352, 1352, 1284, 1284,
+ 1353, 1278, 1317, 1317, 1317, 1317, 1317, 1317,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 1304, 1304, 1304, 51, 51, 51, 51,
+ 51, 1317, 1317, 1317, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1304, 51, 51, 51, 51, 51, 51, 36,
- 1267, 1267, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1273, 1273, 1273, 1273, 1274, 1340,
-
- 1273, 1273, 1273, 1273, 1273, 1273, 1273, 1273,
- 1273, 1273, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1274, 1274, 1274, 1274, 1274, 1274,
- 1274, 1274, 1274, 1274, 1274, 1341, 1311, 1311,
-
- 1309, 1309, 1274, 1274, 1274, 1274, 1274, 1274,
- 1274, 1274, 1274, 1274, 1342, 1274, 1274, 1274,
- 1274, 1274, 1275, 1341, 1341, 1341, 1341, 1341,
- 1341, 1341, 1341, 1341, 1341, 1343, 1343, 1343,
-
- 1344, 1344, 1344, 1344, 1343, 1343, 1343, 1343,
- 1343, 1311, 1311, 1311, 1311, 1343, 1312, 1343,
- 1343, 1343, 1311, 1343, 1343, 1311, 1311, 1311,
- 1343, 1343, 1311, 1311, 1343, 1311, 1311, 1343,
-
- 1343, 1343, 1312, 1311, 1312, 1312, 1312, 1312,
- 1311, 1311, 1343, 1311, 1311, 1311, 1311, 1311,
- 1311, 1343, 1343, 1343, 1343, 1343, 1311, 1343,
- 1343, 1343, 1343, 1311, 1311, 1343, 1343, 1343,
-
- 192, 1304, 1304, 1304, 1304, 1312, 51, 51,
- 1304, 1304, 1313, 1313, 1304, 1304, 51, 51,
+ 1317, 51, 51, 51, 51, 51, 51, 36,
+ 1278, 1278, 1284, 1284, 1284, 1284, 1284, 1284,
+ 1284, 1284, 1284, 1284, 1284, 1284, 1285, 1353,
+
+ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
+ 1284, 1284, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1285, 1285, 1285, 1285, 1285, 1285,
+ 1285, 1285, 1285, 1285, 1285, 1354, 1324, 1324,
+
+ 1322, 1322, 1285, 1285, 1285, 1285, 1285, 1285,
+ 1285, 1285, 1285, 1285, 1355, 1285, 1285, 1285,
+ 1285, 1285, 1286, 1354, 1354, 1354, 1354, 1354,
+ 1354, 1354, 1354, 1354, 1354, 1356, 1356, 1356,
+
+ 1357, 1357, 1357, 1357, 1356, 1356, 1356, 1356,
+ 1356, 1324, 1324, 1324, 1324, 1356, 1325, 1356,
+ 1356, 1356, 1324, 1356, 1356, 1324, 1324, 1324,
+ 1356, 1356, 1324, 1324, 1356, 1324, 1324, 1356,
+
+ 1356, 1356, 1325, 1324, 1325, 1325, 1325, 1325,
+ 1324, 1324, 1356, 1324, 1324, 1324, 1324, 1324,
+ 1324, 1356, 1356, 1356, 1356, 1356, 1324, 1356,
+ 1356, 1356, 1356, 1324, 1324, 1356, 1356, 1356,
+
+ 193, 1317, 1317, 1317, 1317, 1325, 51, 51,
+ 1317, 1317, 1326, 1326, 1317, 1317, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1312, 51, 51, 51, 51, 51, 51, 51,
+ 1325, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 1312, 51, 1312, 51,
- 51, 51, 51, 1312, 1312, 1312, 51, 1311,
- 51, 51, 51, 1345, 1345, 1345, 1345, 1312,
-
- 1312, 51, 1346, 1346, 51, 51, 51, 51,
- 1347, 1348, 1347, 1348, 1347, 1348, 1347, 1348,
- 1347, 1348, 1347, 1348, 1347, 1348, 1349, 1350,
- 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358,
-
- 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356,
- 1357, 1358, 1349, 1350, 1351, 1352, 1353, 1354,
- 1355, 1356, 1357, 1358, 51, 1312, 1312, 1312,
+ 51, 51, 51, 51, 1325, 51, 1325, 51,
+ 51, 51, 51, 1325, 1325, 1325, 51, 1324,
+ 51, 51, 51, 1358, 1358, 1358, 1358, 1325,
+
+ 1325, 51, 1359, 1359, 51, 51, 51, 51,
+ 1360, 1361, 1360, 1361, 1360, 1361, 1360, 1361,
+ 1360, 1361, 1360, 1361, 1360, 1361, 1362, 1363,
+ 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371,
+
+ 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369,
+ 1370, 1371, 1362, 1363, 1364, 1365, 1366, 1367,
+ 1368, 1369, 1370, 1371, 51, 1325, 1325, 1325,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
51, 51, 51, 51, 51, 51, 51, 51,
- 1312, 51, 51, 51, 51, 51, 51, 51,
- 51, 51, 51, 51, 51, 51, 51, 1312,
-
- 1359, 1359, 1359, 1360, 1361, 1362, 1363, 1310,
- 1364, 1365, 1310, 1366, 1367, 1368, 1369, 1369,
- 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1214,
- 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1214,
-
- 1214, 1214, 1370, 1371, 1370, 1371, 1347, 1348,
- 1347, 1348, 1347, 1348, 1372, 1373, 1372, 1373,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
-
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
- 1374, 1374, 1374, 1374, 1374, 1374, 1374, 1374,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
-
- 1214, 1214, 1214, 1347, 1348, 1347, 1348, 1347,
- 1348, 1347, 1348, 1347, 1348, 1375, 1376, 1377,
- 1378, 1347, 1348, 1347, 1348, 1347, 1348, 1347,
- 1348, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1379, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
-
- 1370, 1371, 1214, 1214, 1370, 1371, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1370,
- 1371, 1370, 1371, 1214, 1370, 1371, 1214, 1214,
- 1347, 1348, 1347, 1348, 1214, 1214, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1380, 1214, 1214,
- 1370, 1371, 1214, 1214, 1347, 1348, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1272, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1370, 1371, 1370, 1371, 1214,
- 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
- 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
-
- 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1214,
- 1214, 1214, 1214, 1214, 1272, 1272, 1272, 1214,
- 1214, 1370, 1371, 1214, 1214, 1370, 1371, 1370,
-
- 1371, 1370, 1371, 1370, 1371, 1214, 1214, 1214,
- 1214, 1214, 1214, 1370, 1371, 1214, 1214, 1214,
- 1214, 1370, 1371, 1370, 1371, 1370, 1371, 1370,
- 1371, 1370, 1371, 1370, 1371, 1214, 1214, 1214,
-
- 1214, 1370, 1371, 1214, 1214, 1214, 1370, 1371,
- 1370, 1371, 1370, 1371, 1370, 1371, 1214, 1370,
- 1371, 1214, 1214, 1370, 1371, 1214, 1214, 1214,
- 1214, 1214, 1214, 1370, 1371, 1370, 1371, 1370,
-
- 1371, 1370, 1371, 1370, 1371, 1370, 1371, 1214,
- 1214, 1214, 1214, 1214, 1214, 1370, 1371, 1370,
- 1371, 1370, 1371, 1370, 1371, 1370, 1371, 1214,
- 1214, 1214, 1214, 1214, 1381, 1214, 1382, 1214,
-
- 1214, 1214, 1214, 1383, 1384, 1383, 1214, 1214,
- 1214, 1214, 1214, 1214, 1370, 1371, 1214, 1214,
- 1214, 1214, 1214, 1214, 1214, 1214, 1214, 1370,
- 1371, 1370, 1371, 1214, 1214, 1214, 1214, 1214,
-
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1274, 1274,
- 1274, 1274, 1274, 1274, 1275, 1275, 1275, 1275,
- 1275, 1275, 1275, 1341, 1341, 1341, 1341, 1341,
-
- 1275, 1275, 1275, 1275, 1341, 1341, 1341, 1341,
- 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
- 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367,
- 1367, 1367, 1367, 1367, 1367, 1367, 1367, 1367,
-
- 1367, 1367, 1367, 1367, 1367, 1341, 1341, 1367,
- 1367, 1367, 1367, 1367, 1367, 192, 192, 192,
- 1341, 1341, 1341, 1341, 1341, 1311, 1311, 1311,
- 1311, 1311, 192, 192, 192, 192, 192, 192,
-
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
-
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385,
- 1385, 1385, 1385, 1385, 1385, 1385, 1385, 192,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
-
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 1386,
- 1386, 1386, 1386, 1386, 1386, 1386, 1386, 192,
-
- 126, 122, 1387, 1388, 1389, 1390, 1391, 126,
- 122, 126, 122, 126, 122, 1392, 1393, 1394,
- 1395, 1056, 1058, 1059, 1396, 126, 122, 1396,
- 1056, 1056, 1056, 1056, 1397, 1397, 1398, 1398,
-
- 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
- 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
- 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
- 1399, 1400, 1399, 1400, 1399, 1400, 1399, 1400,
-
- 1399, 1400, 1399, 1400, 1401, 1402, 1402, 1402,
- 1402, 1402, 1402, 1403, 1404, 1403, 1404, 1405,
- 1405, 1405, 1406, 1407, 192, 192, 192, 192,
- 192, 1408, 1409, 1409, 1409, 1410, 1408, 1409,
-
- 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
- 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
- 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
- 1411, 1411, 1411, 1411, 1411, 1411, 1411, 1411,
-
- 1411, 1411, 1411, 1411, 1411, 1411, 192, 1412,
- 192, 192, 192, 192, 192, 1412, 192, 192,
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
-
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
- 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413,
-
- 1413, 1413, 1413, 1413, 1413, 1413, 1414, 1414,
- 192, 192, 192, 192, 192, 192, 192, 1415,
- 1416, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 1417,
+ 1325, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 1325,
+
+ 1372, 1372, 1372, 1373, 1374, 1375, 1376, 1323,
+ 1377, 1378, 1323, 1379, 1380, 1381, 1382, 1382,
+ 1220, 1220, 1220, 1220, 1220, 1383, 1384, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1383, 1384, 1220,
+
+ 1220, 1220, 1383, 1384, 1383, 1384, 1360, 1361,
+ 1360, 1361, 1360, 1361, 1385, 1386, 1385, 1386,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+
+ 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387,
+ 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387,
+ 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387,
+ 1387, 1387, 1387, 1387, 1387, 1387, 1387, 1387,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+
+ 1220, 1220, 1220, 1360, 1361, 1360, 1361, 1360,
+ 1361, 1360, 1361, 1360, 1361, 1388, 1389, 1390,
+ 1391, 1360, 1361, 1360, 1361, 1360, 1361, 1360,
+ 1361, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1392, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+
+ 1383, 1384, 1220, 1220, 1383, 1384, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1383,
+ 1384, 1383, 1384, 1220, 1383, 1384, 1220, 1220,
+ 1360, 1361, 1360, 1361, 1220, 1220, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1393, 1220, 1220,
+ 1383, 1384, 1220, 1220, 1360, 1361, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1283, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1383, 1384, 1383, 1384, 1220,
+ 1220, 1220, 1220, 1220, 1383, 1384, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1383, 1384, 1220, 1220,
+
+ 1220, 1220, 1220, 1220, 1383, 1384, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1283, 1283, 1283, 1220,
+ 1220, 1383, 1384, 1220, 1220, 1383, 1384, 1383,
+
+ 1384, 1383, 1384, 1383, 1384, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1383, 1384, 1220, 1220, 1220,
+ 1220, 1383, 1384, 1383, 1384, 1383, 1384, 1383,
+ 1384, 1383, 1384, 1383, 1384, 1220, 1220, 1220,
+
+ 1220, 1383, 1384, 1220, 1220, 1220, 1383, 1384,
+ 1383, 1384, 1383, 1384, 1383, 1384, 1220, 1383,
+ 1384, 1220, 1220, 1383, 1384, 1220, 1220, 1220,
+ 1220, 1220, 1220, 1383, 1384, 1383, 1384, 1383,
+
+ 1384, 1383, 1384, 1383, 1384, 1383, 1384, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1383, 1384, 1383,
+ 1384, 1383, 1384, 1383, 1384, 1383, 1384, 1220,
+ 1220, 1220, 1220, 1220, 1394, 1220, 1395, 1220,
+
+ 1220, 1220, 1220, 1396, 1397, 1396, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1383, 1384, 1220, 1220,
+ 1220, 1220, 1220, 1220, 1220, 1220, 1220, 1383,
+ 1384, 1383, 1384, 1220, 1220, 1220, 1220, 1220,
+
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1285, 1285,
+ 1285, 1285, 1285, 1285, 1286, 1286, 1286, 1286,
+ 1286, 1286, 1286, 1354, 1354, 1354, 1354, 1354,
+
+ 1286, 1286, 1286, 1286, 1354, 1354, 1354, 1354,
+ 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354,
+ 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
+ 1380, 1380, 1380, 1380, 1380, 1380, 1380, 1380,
+
+ 1380, 1380, 1380, 1380, 1380, 1354, 1354, 1380,
+ 1380, 1380, 1380, 1380, 1380, 193, 193, 193,
+ 1354, 1354, 1354, 1354, 1354, 1324, 1324, 1324,
+ 1324, 1324, 193, 193, 193, 193, 193, 193,
+
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398,
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398,
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398,
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398,
+
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 1398,
+ 1398, 1398, 1398, 1398, 1398, 1398, 1398, 193,
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
+
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 1399,
+ 1399, 1399, 1399, 1399, 1399, 1399, 1399, 193,
+
+ 126, 122, 1400, 1401, 1402, 1403, 1404, 126,
+ 122, 126, 122, 126, 122, 1405, 1406, 1407,
+ 1408, 1062, 1064, 1065, 1409, 126, 122, 1409,
+ 1062, 1062, 1062, 1062, 1410, 1410, 1411, 1411,
+
+ 1412, 1413, 1412, 1413, 1412, 1413, 1412, 1413,
+ 1412, 1413, 1412, 1413, 1412, 1413, 1412, 1413,
+ 1412, 1413, 1412, 1413, 1412, 1413, 1412, 1413,
+ 1412, 1413, 1412, 1413, 1412, 1413, 1412, 1413,
+
+ 1412, 1413, 1412, 1413, 1414, 1415, 1415, 1415,
+ 1415, 1415, 1415, 1416, 1417, 1416, 1417, 1418,
+ 1418, 1418, 1419, 1420, 193, 193, 193, 193,
+ 193, 1421, 1422, 1422, 1422, 1423, 1421, 1422,
+
+ 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424,
+ 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424,
+ 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424,
+ 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424,
+
+ 1424, 1424, 1424, 1424, 1424, 1424, 193, 1425,
+ 193, 193, 193, 193, 193, 1425, 193, 193,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1426, 1426,
+
+ 1426, 1426, 1426, 1426, 1426, 1426, 1427, 1427,
+ 193, 193, 193, 193, 193, 193, 193, 1428,
+ 1429, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 1430,
+
+ 800, 800, 800, 800, 800, 800, 800, 800,
+ 800, 800, 800, 800, 800, 800, 800, 800,
+ 800, 800, 800, 800, 800, 800, 800, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 800, 800, 800, 800, 800, 800, 800, 193,
+ 800, 800, 800, 800, 800, 800, 800, 193,
+ 800, 800, 800, 800, 800, 800, 800, 193,
+ 800, 800, 800, 800, 800, 800, 800, 193,
+
+ 257, 257, 257, 257, 257, 257, 257, 257,
+ 257, 257, 257, 257, 257, 257, 257, 257,
+ 257, 257, 257, 257, 257, 257, 257, 257,
+ 257, 257, 257, 257, 257, 257, 257, 257,
+
+ 1431, 1431, 1432, 1433, 1432, 1433, 1431, 1431,
+ 1431, 1432, 1433, 1431, 1432, 1433, 1224, 1224,
+ 1224, 1224, 1224, 1224, 1224, 1224, 1223, 1434,
+ 1435, 1436, 1437, 1438, 1432, 1433, 1438, 1438,
+
+ 1439, 1440, 1385, 1386, 1385, 1386, 1385, 1386,
+ 1385, 1386, 1436, 1436, 1436, 1436, 1441, 1442,
+ 1436, 1443, 1444, 1445, 1445, 1444, 1444, 1444,
+ 1444, 1444, 1446, 1446, 193, 193, 193, 193,
+
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 193, 1447, 1447, 1447, 1447, 1448,
+
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447,
+ 1447, 1447, 1447, 1448, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+ 1448, 1448, 1448, 1448, 1448, 1448, 1448, 1448,
+ 1448, 1448, 1448, 1448, 1448, 1448, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449,
+ 1449, 1449, 1449, 1449, 193, 193, 193, 193,
+
+ 1178, 1450, 1451, 1452, 1317, 1453, 1454, 1455,
+ 16, 1215, 16, 1215, 16, 1215, 16, 1215,
+ 16, 1215, 1317, 1317, 16, 1215, 16, 1215,
+ 16, 1215, 16, 1215, 1456, 1193, 1457, 1457,
+
+ 1317, 1455, 1455, 1455, 1455, 1455, 1455, 1455,
+ 1455, 1455, 1458, 1459, 165, 1460, 1461, 1461,
+ 1462, 1463, 1463, 1463, 1463, 1464, 1465, 1317,
+ 1466, 1466, 1466, 1467, 1468, 1469, 1449, 1317,
+
+ 193, 1470, 1471, 1470, 1471, 1470, 1471, 1470,
+ 1471, 1470, 1471, 1471, 1472, 1471, 1472, 1471,
+ 1472, 1471, 1472, 1471, 1472, 1471, 1472, 1471,
+ 1472, 1471, 1472, 1471, 1472, 1471, 1472, 1471,
+
+ 1472, 1471, 1472, 1470, 1471, 1472, 1471, 1472,
+ 1471, 1472, 1471, 1471, 1471, 1471, 1471, 1471,
+ 1472, 1472, 1471, 1472, 1472, 1471, 1472, 1472,
+ 1471, 1472, 1472, 1471, 1472, 1472, 1471, 1471,
+
+ 1471, 1471, 1471, 1470, 1471, 1470, 1471, 1470,
+ 1471, 1471, 1471, 1471, 1471, 1471, 1470, 1471,
+ 1471, 1471, 1471, 1471, 1472, 1473, 1473, 193,
+ 193, 1474, 1474, 1475, 1475, 1476, 1477, 1478,
+
+ 1479, 1480, 1481, 1480, 1481, 1480, 1481, 1480,
+ 1481, 1480, 1481, 1481, 1482, 1481, 1482, 1481,
+ 1482, 1481, 1482, 1481, 1482, 1481, 1482, 1481,
+ 1482, 1481, 1482, 1481, 1482, 1481, 1482, 1481,
+
+ 1482, 1481, 1482, 1480, 1481, 1482, 1481, 1482,
+ 1481, 1482, 1481, 1481, 1481, 1481, 1481, 1481,
+ 1482, 1482, 1481, 1482, 1482, 1481, 1482, 1482,
+ 1481, 1482, 1482, 1481, 1482, 1482, 1481, 1481,
+
+ 1481, 1481, 1481, 1480, 1481, 1480, 1481, 1480,
+ 1481, 1481, 1481, 1481, 1481, 1481, 1480, 1481,
+ 1481, 1481, 1481, 1481, 1482, 1480, 1480, 1482,
+ 1482, 1482, 1482, 1483, 1484, 1485, 1486, 1487,
+
+ 193, 193, 193, 193, 193, 1488, 1488, 1488,
+ 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488,
+ 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488,
+ 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488,
+
+ 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488,
+ 1488, 1488, 1488, 1488, 1488, 1489, 193, 193,
+ 193, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490,
+ 1490, 1490, 1490, 1490, 1490, 1490, 1490, 193,
+ 1491, 1491, 1492, 1492, 1492, 1492, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 798, 798, 798, 798, 798, 798, 798, 798,
- 798, 798, 798, 798, 798, 798, 798, 798,
- 798, 798, 798, 798, 798, 798, 798, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 798, 798, 798, 798, 798, 798, 798, 192,
- 798, 798, 798, 798, 798, 798, 798, 192,
- 798, 798, 798, 798, 798, 798, 798, 192,
- 798, 798, 798, 798, 798, 798, 798, 192,
-
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256,
-
- 1418, 1418, 1419, 1420, 1419, 1420, 1418, 1418,
- 1418, 1419, 1420, 1418, 1419, 1420, 1218, 1218,
- 1218, 1218, 1218, 1218, 1218, 1218, 1217, 1421,
- 1422, 1423, 1424, 1425, 1419, 1420, 1425, 1425,
-
- 1426, 1427, 1372, 1373, 1372, 1373, 1372, 1373,
- 1372, 1373, 1423, 1423, 1423, 1423, 1428, 1429,
- 1423, 1430, 1431, 1432, 1432, 1431, 1431, 1431,
- 1431, 1431, 1433, 1433, 192, 192, 192, 192,
-
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 192, 1434, 1434, 1434, 1434, 1435,
-
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
-
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1434, 1434, 1434, 1434, 1434,
- 1434, 1434, 1434, 1435, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
-
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 1435, 1435,
- 1435, 1435, 1435, 1435, 1435, 1435, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1436,
- 1436, 1436, 1436, 1436, 192, 192, 192, 192,
-
- 1437, 1438, 1439, 1440, 1304, 1441, 1442, 1443,
- 16, 1209, 16, 1209, 16, 1209, 16, 1209,
- 16, 1209, 1304, 1304, 16, 1209, 16, 1209,
- 16, 1209, 16, 1209, 1444, 1187, 1445, 1445,
-
- 1304, 1443, 1443, 1443, 1443, 1443, 1443, 1443,
- 1443, 1443, 1446, 1447, 164, 1448, 1449, 1449,
- 1450, 1451, 1451, 1451, 1451, 1451, 1452, 1304,
- 1453, 1453, 1453, 1454, 1455, 1456, 1436, 1304,
-
- 192, 1457, 1458, 1457, 1458, 1457, 1458, 1457,
- 1458, 1457, 1458, 1458, 1459, 1458, 1459, 1458,
- 1459, 1458, 1459, 1458, 1459, 1458, 1459, 1458,
- 1459, 1458, 1459, 1458, 1459, 1458, 1459, 1458,
-
- 1459, 1458, 1459, 1457, 1458, 1459, 1458, 1459,
- 1458, 1459, 1458, 1458, 1458, 1458, 1458, 1458,
- 1459, 1459, 1458, 1459, 1459, 1458, 1459, 1459,
- 1458, 1459, 1459, 1458, 1459, 1459, 1458, 1458,
-
- 1458, 1458, 1458, 1457, 1458, 1457, 1458, 1457,
- 1458, 1458, 1458, 1458, 1458, 1458, 1457, 1458,
- 1458, 1458, 1458, 1458, 1459, 1460, 1460, 192,
- 192, 1461, 1461, 1462, 1462, 1463, 1464, 1465,
-
- 1466, 1467, 1468, 1467, 1468, 1467, 1468, 1467,
- 1468, 1467, 1468, 1468, 1469, 1468, 1469, 1468,
- 1469, 1468, 1469, 1468, 1469, 1468, 1469, 1468,
- 1469, 1468, 1469, 1468, 1469, 1468, 1469, 1468,
-
- 1469, 1468, 1469, 1467, 1468, 1469, 1468, 1469,
- 1468, 1469, 1468, 1468, 1468, 1468, 1468, 1468,
- 1469, 1469, 1468, 1469, 1469, 1468, 1469, 1469,
- 1468, 1469, 1469, 1468, 1469, 1469, 1468, 1468,
-
- 1468, 1468, 1468, 1467, 1468, 1467, 1468, 1467,
- 1468, 1468, 1468, 1468, 1468, 1468, 1467, 1468,
- 1468, 1468, 1468, 1468, 1469, 1467, 1467, 1469,
- 1469, 1469, 1469, 1470, 1471, 1472, 1473, 1474,
-
- 192, 192, 192, 192, 192, 1475, 1475, 1475,
- 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
- 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
- 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
-
- 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
- 1475, 1475, 1475, 1475, 1475, 1476, 192, 192,
- 192, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
-
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
-
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 1477,
- 1477, 1477, 1477, 1477, 1477, 1477, 1477, 192,
- 1478, 1478, 1479, 1479, 1479, 1479, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
-
- 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
- 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
- 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481,
- 1482, 1482, 1482, 192, 192, 192, 192, 192,
-
- 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340,
- 1340, 1340, 1340, 1340, 1340, 1340, 1340, 1340,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
-
- 1344, 1344, 1344, 1344, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483,
- 1483, 1483, 1483, 1483, 1483, 1483, 1483, 1483,
-
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1484, 1485, 1485, 192,
-
- 1479, 1479, 1479, 1479, 1479, 1479, 1479, 1479,
- 1479, 1479, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
-
- 1480, 1480, 1480, 1480, 1486, 1486, 1486, 1486,
- 1487, 1487, 1487, 1487, 1487, 1487, 1487, 1487,
- 1488, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
- 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
-
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1484, 1484, 1484, 1484,
- 1484, 1484, 1484, 1484, 1485, 1485, 1490, 1478,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
- 1489, 1489, 1489, 1489, 1489, 1489, 1489, 1489,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1488, 1488, 1488, 1488,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
-
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 192,
-
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
-
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1491, 1491, 1491, 1491, 1491, 1491, 1491, 1491,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1488,
- 1488, 1488, 1488, 1480, 1480, 1480, 1480, 1480,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1488, 1488,
-
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1480,
- 1480, 1480, 1480, 1480, 1480, 1480, 1480, 1488,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1495, 1495, 1495, 193, 193, 193, 193, 193,
- 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
- 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
- 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
- 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
+ 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353,
+ 1353, 1353, 1353, 1353, 1353, 1353, 1353, 1353,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+
+ 1357, 1357, 1357, 1357, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,
+ 1496, 1496, 1496, 1496, 1496, 1496, 1496, 1496,
+
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1498, 1498, 193,
1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
- 1492, 1492, 1492, 1492, 1492, 1492, 1492, 1492,
- 1492, 1492, 1492, 1492, 1492, 1492, 1493, 1493,
+ 1492, 1492, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
-
- 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
- 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
- 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
- 1494, 1494, 1494, 1494, 1494, 1494, 1494, 1494,
+ 1493, 1493, 1493, 1493, 1499, 1499, 1499, 1499,
+ 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500,
+ 1501, 1502, 1502, 1502, 1502, 1502, 1502, 1502,
+ 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502,
- 1494, 1494, 1494, 1494, 1494, 1494, 1495, 1495,
- 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495,
- 1495, 1495, 1495, 1495, 1495, 1495, 1495, 1495,
- 1495, 1495, 1495, 1495, 1496, 1496, 1496, 1496,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 1497, 1497, 1497, 1497, 1498, 1498, 1503, 1491,
- 1496, 1496, 1496, 1496, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1498, 1493, 1493, 1493,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1502, 1502, 1502, 1502, 1502, 1502, 1502,
+ 1502, 1502, 1502, 1502, 1502, 1502, 1502, 1502,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1501, 1501, 1501, 1501,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 193,
+
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
+ 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1501,
+ 1501, 1501, 1501, 1493, 1493, 1493, 1493, 1493,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1500, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1501, 1501,
- 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
- 1499, 1499, 1499, 1499, 1499, 192, 192, 192,
- 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
- 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1501,
- 1501, 1501, 1502, 1502, 1501, 1501, 1501, 1501,
- 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
- 1501, 1501, 1501, 1501, 1502, 1501, 1501, 1501,
- 1501, 1501, 1501, 1501, 1501, 1501, 1501, 1501,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
- 1501, 1502, 1501, 1501, 1501, 1502, 1501, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
- 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1505, 1505,
+ 1505, 1505, 1505, 1505, 1505, 1505, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
- 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
- 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
- 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503,
- 1504, 1504, 1504, 1504, 1504, 1504, 1505, 1506,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
- 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
- 1507, 1507, 1507, 1507, 1508, 1509, 1510, 1511,
- 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
- 1507, 1507, 1507, 1507, 1507, 1507, 1507, 1507,
+ 1507, 1507, 1507, 1507, 1507, 1507, 1508, 1508,
+ 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
+ 1508, 1508, 1508, 1508, 1508, 1508, 1508, 1508,
+ 1508, 1508, 1508, 1508, 1509, 1509, 1509, 1509,
+
+ 1509, 1509, 1509, 1509, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1511, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1513, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+
+ 1512, 1512, 1512, 1512, 1512, 1512, 1512, 1512,
+ 1512, 1512, 1512, 1512, 1512, 193, 193, 193,
+ 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514,
+ 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514,
+
+ 1514, 1514, 1515, 1515, 1514, 1514, 1514, 1514,
+ 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514,
+ 1514, 1514, 1514, 1514, 1515, 1514, 1514, 1514,
+ 1514, 1514, 1514, 1514, 1514, 1514, 1514, 1514,
+
+ 1514, 1515, 1514, 1514, 1514, 1515, 1514, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516,
+ 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516,
+
+ 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516,
+ 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516,
+ 1516, 1516, 1516, 1516, 1516, 1516, 1516, 1516,
+ 1517, 1517, 1517, 1517, 1517, 1517, 1518, 1519,
+
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+ 1520, 1520, 1520, 1520, 1521, 1522, 1523, 1524,
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+ 1520, 1520, 1520, 1520, 1520, 1520, 1520, 1520,
+
+ 1525, 1526, 1527, 1528, 1529, 1530, 1531, 1532,
+ 1533, 1534, 1520, 1520, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+
+ 275, 276, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 1535, 257,
+ 1536, 1536, 1536, 1537, 1538, 1538, 1538, 1538,
+ 1538, 1538, 1538, 1538, 257, 257, 1537, 1539,
+
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 271, 272, 271, 272, 271, 272, 271, 272,
+ 193, 193, 193, 193, 193, 193, 193, 1538,
+
+ 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540,
+ 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540,
+ 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540,
+ 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540,
+
+ 1540, 1540, 1540, 1540, 1540, 1540, 1541, 1541,
+ 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541,
+ 1542, 1542, 1543, 1544, 1545, 1545, 1545, 1544,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546,
+ 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1546,
+ 1546, 1546, 1546, 1546, 1546, 1546, 1546, 1547,
+ 1547, 1547, 1547, 1442, 1442, 1442, 1442, 1442,
+
+ 1548, 1548, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1062, 1062, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1410, 1062, 1062, 1062, 1062, 1062, 1062, 1062,
+ 1062, 1064, 1065, 1064, 1065, 1549, 1064, 1065,
+
+ 1064, 1065, 1064, 1065, 1064, 1065, 1064, 1065,
+ 1442, 1550, 1550, 1064, 1065, 1551, 1552, 193,
+ 1553, 1554, 1555, 1556, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1553, 1554, 1553, 1554, 1553, 1554, 1553, 1554,
+ 1553, 1554, 1557, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1558, 1558, 1552, 1559, 1559, 1559, 1559, 1559,
+
+ 1560, 1560, 1561, 1560, 1560, 1560, 1562, 1560,
+ 1560, 1560, 1560, 1561, 1560, 1560, 1560, 1560,
+ 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560,
+ 1560, 1560, 1560, 1560, 1560, 1560, 1560, 1560,
+
+ 1560, 1560, 1560, 1563, 1563, 1561, 1561, 1563,
+ 1564, 1564, 1564, 1564, 193, 193, 193, 193,
+ 1500, 1500, 1500, 1500, 1500, 1500, 742, 742,
+ 1255, 1565, 193, 193, 193, 193, 193, 193,
+
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+ 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566,
+ 1566, 1566, 1567, 1568, 1569, 1569, 1570, 1570,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1571, 1571, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 1572, 1572, 1572, 1571, 1571, 1571, 1571,
+ 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571,
+
+ 1571, 1571, 1571, 1571, 1573, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 1574, 1574,
+ 1575, 1576, 1577, 1578, 1579, 1580, 1581, 1582,
+ 1583, 1584, 193, 193, 193, 193, 193, 193,
+
+ 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585,
+ 1585, 1585, 1585, 1585, 1585, 1585, 1585, 1585,
+ 1585, 1585, 475, 475, 475, 475, 475, 475,
+ 1586, 1586, 1586, 475, 193, 193, 193, 193,
+
+ 1587, 1588, 1589, 1590, 1591, 1592, 1593, 1594,
+ 1595, 1596, 1597, 1597, 1597, 1597, 1597, 1597,
+ 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597,
+ 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597,
+
+ 1597, 1597, 1597, 1597, 1597, 1597, 1598, 1598,
+ 1598, 1598, 1598, 1599, 1599, 1599, 1600, 1601,
+ 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602,
+ 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602,
+
+ 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1603,
+ 1603, 1603, 1603, 1603, 1603, 1603, 1603, 1603,
+ 1603, 1603, 1604, 1605, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 1606,
- 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519,
- 1520, 1521, 1507, 1507, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 270, 271, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
-
- 274, 275, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 1522, 256,
- 1523, 1523, 1523, 1524, 1525, 1525, 1525, 1525,
- 1525, 1525, 1525, 1525, 256, 256, 1524, 1526,
-
- 270, 271, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
- 270, 271, 270, 271, 270, 271, 270, 271,
- 192, 192, 192, 192, 192, 192, 192, 1525,
-
- 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
- 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
- 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
- 1527, 1527, 1527, 1527, 1527, 1527, 1527, 1527,
-
- 1527, 1527, 1527, 1527, 1527, 1527, 1528, 1528,
- 1528, 1528, 1528, 1528, 1528, 1528, 1528, 1528,
- 1529, 1529, 1530, 1531, 1532, 1532, 1532, 1531,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533,
- 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1533,
- 1533, 1533, 1533, 1533, 1533, 1533, 1533, 1534,
- 1534, 1534, 1534, 1429, 1429, 1429, 1429, 1429,
-
- 1535, 1535, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1056, 1056, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
-
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
-
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1397, 1056, 1056, 1056, 1056, 1056, 1056, 1056,
- 1056, 1058, 1059, 1058, 1059, 1536, 1058, 1059,
-
- 1058, 1059, 1058, 1059, 1058, 1059, 1058, 1059,
- 1429, 1537, 1537, 1058, 1059, 1538, 1539, 192,
- 1540, 1541, 1542, 1543, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1540, 1541, 1540, 1541, 1540, 1541, 1540, 1541,
- 1540, 1541, 1544, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1545, 1545, 1539, 1546, 1546, 1546, 1546, 1546,
-
- 1547, 1547, 1548, 1547, 1547, 1547, 1549, 1547,
- 1547, 1547, 1547, 1548, 1547, 1547, 1547, 1547,
- 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547,
- 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547,
-
- 1547, 1547, 1547, 1550, 1550, 1548, 1548, 1550,
- 1551, 1551, 1551, 1551, 192, 192, 192, 192,
- 1487, 1487, 1487, 1487, 1487, 1487, 740, 740,
- 1245, 1552, 192, 192, 192, 192, 192, 192,
-
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
-
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
- 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553,
- 1553, 1553, 1553, 1553, 1554, 1554, 1555, 1555,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1556, 1556, 1557, 1557, 1557, 1557, 1557, 1557,
- 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
- 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
- 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
-
- 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
- 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557,
- 1557, 1557, 1557, 1557, 1556, 1556, 1556, 1556,
- 1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556,
-
- 1556, 1556, 1556, 1556, 1558, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 1559, 1559,
- 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567,
- 1568, 1569, 192, 192, 192, 192, 192, 192,
-
- 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570,
- 1570, 1570, 1570, 1570, 1570, 1570, 1570, 1570,
- 1570, 1570, 473, 473, 473, 473, 473, 473,
- 1571, 1571, 1571, 473, 192, 192, 192, 192,
-
- 1572, 1573, 1574, 1575, 1576, 1577, 1578, 1579,
- 1580, 1581, 1582, 1582, 1582, 1582, 1582, 1582,
- 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582,
- 1582, 1582, 1582, 1582, 1582, 1582, 1582, 1582,
-
- 1582, 1582, 1582, 1582, 1582, 1582, 1583, 1583,
- 1583, 1583, 1583, 1584, 1584, 1584, 1585, 1586,
- 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
- 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
-
- 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1588,
- 1588, 1588, 1588, 1588, 1588, 1588, 1588, 1588,
- 1588, 1588, 1589, 1590, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 1591,
-
- 790, 790, 790, 790, 790, 790, 790, 790,
- 790, 790, 790, 790, 790, 790, 790, 790,
- 790, 790, 790, 790, 790, 790, 790, 790,
- 790, 790, 790, 790, 790, 192, 192, 192,
-
- 1592, 1592, 1592, 1593, 1594, 1594, 1594, 1594,
- 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
- 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
- 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
-
- 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
- 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1594,
- 1594, 1594, 1594, 1595, 1593, 1593, 1592, 1592,
- 1592, 1592, 1593, 1593, 1592, 1593, 1593, 1593,
-
- 1596, 1597, 1597, 1597, 1597, 1597, 1597, 1598,
- 1599, 1599, 1597, 1597, 1597, 1597, 192, 1600,
- 1601, 1602, 1603, 1604, 1605, 1606, 1607, 1608,
- 1609, 1610, 192, 192, 192, 192, 1597, 1597,
-
- 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
- 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
- 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
- 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
-
- 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611,
- 1611, 1612, 1612, 1612, 1612, 1612, 1612, 1613,
- 1613, 1612, 1612, 1613, 1613, 1612, 1612, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 792, 792, 792, 792, 792, 792, 792, 792,
+ 792, 792, 792, 792, 792, 792, 792, 792,
+ 792, 792, 792, 792, 792, 792, 792, 792,
+ 792, 792, 792, 792, 792, 193, 193, 193,
+
+ 1607, 1607, 1607, 1608, 1609, 1609, 1609, 1609,
+ 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609,
+ 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609,
+ 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609,
- 1611, 1611, 1611, 1612, 1611, 1611, 1611, 1611,
- 1611, 1611, 1611, 1611, 1612, 1613, 192, 192,
- 1614, 1615, 1616, 1617, 1618, 1619, 1620, 1621,
- 1622, 1623, 192, 192, 1624, 1625, 1625, 1625,
+ 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609,
+ 1609, 1609, 1609, 1609, 1609, 1609, 1609, 1609,
+ 1609, 1609, 1609, 1610, 1608, 1608, 1607, 1607,
+ 1607, 1607, 1608, 1608, 1607, 1608, 1608, 1608,
+
+ 1611, 1612, 1612, 1612, 1612, 1612, 1612, 1613,
+ 1614, 1614, 1612, 1612, 1612, 1612, 193, 1615,
+ 1616, 1617, 1618, 1619, 1620, 1621, 1622, 1623,
+ 1624, 1625, 193, 193, 193, 193, 1612, 1612,
1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
- 1627, 1626, 1626, 1626, 1626, 1626, 1626, 1628,
- 1628, 1628, 1626, 778, 192, 192, 192, 192,
-
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
-
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
- 1629, 1629, 1629, 1629, 1629, 1629, 1629, 1629,
- 1630, 1629, 1630, 1630, 1631, 1629, 1629, 1630,
- 1630, 1629, 1629, 1629, 1629, 1629, 1630, 1630,
-
- 1629, 1630, 1629, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 1629, 1629, 1632, 1633, 1633,
-
- 1634, 1634, 1634, 1634, 1634, 1634, 1634, 1634,
- 1634, 1634, 1634, 1635, 1636, 1636, 1635, 1635,
- 1637, 1637, 1634, 1638, 1638, 1635, 1639, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
- 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
- 192, 1640, 1640, 1640, 1640, 1640, 1640, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1640, 1640, 1640, 1640, 1640, 1640, 1640, 192,
- 1640, 1640, 1640, 1640, 1640, 1640, 1640, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
+ 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
- 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
- 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
- 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
- 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1626, 1626, 1626, 1626, 1626, 1626, 1626, 1626,
+ 1626, 1627, 1627, 1627, 1627, 1627, 1627, 1628,
+ 1628, 1627, 1627, 1628, 1628, 1627, 1627, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 1641, 1641, 1641, 1642, 1642, 1643, 1642, 1642,
- 1643, 1642, 1642, 1644, 1642, 1645, 192, 192,
- 1646, 1647, 1648, 1649, 1650, 1651, 1652, 1653,
- 1654, 1655, 192, 192, 192, 192, 192, 192,
-
- 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1656, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 1656, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
- 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657,
-
- 1657, 1657, 1657, 1657, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 793, 793, 793, 793, 793, 793, 793, 793,
- 793, 793, 793, 793, 793, 793, 793, 793,
+ 1626, 1626, 1626, 1627, 1626, 1626, 1626, 1626,
+ 1626, 1626, 1626, 1626, 1627, 1628, 193, 193,
+ 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636,
+ 1637, 1638, 193, 193, 1639, 1640, 1640, 1640,
- 793, 793, 793, 793, 793, 793, 793, 192,
- 192, 192, 192, 796, 796, 796, 796, 796,
- 796, 796, 796, 796, 796, 796, 796, 796,
- 796, 796, 796, 796, 796, 796, 796, 796,
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1641, 1641, 1641, 1641, 1641, 1641, 1641, 1641,
+ 1642, 1641, 1641, 1641, 1641, 1641, 1641, 1643,
+ 1643, 1643, 1641, 780, 193, 193, 193, 193,
+
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+ 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644,
+ 1645, 1644, 1645, 1645, 1646, 1644, 1644, 1645,
+ 1645, 1644, 1644, 1644, 1644, 1644, 1645, 1645,
+
+ 1644, 1645, 1644, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 1644, 1644, 1647, 1648, 1648,
+
+ 1649, 1649, 1649, 1649, 1649, 1649, 1649, 1649,
+ 1649, 1649, 1649, 1650, 1651, 1651, 1650, 1650,
+ 1652, 1652, 1649, 1653, 1653, 1650, 1654, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 1655, 1655, 1655, 1655, 1655, 1655, 193,
+ 193, 1655, 1655, 1655, 1655, 1655, 1655, 193,
+ 193, 1655, 1655, 1655, 1655, 1655, 1655, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1655, 1655, 1655, 1655, 1655, 1655, 1655, 193,
+ 1655, 1655, 1655, 1655, 1655, 1655, 1655, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656,
+ 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656,
+ 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656,
+ 1656, 1656, 1656, 1656, 1656, 1656, 1656, 1656,
+
+ 1656, 1656, 1656, 1657, 1657, 1658, 1657, 1657,
+ 1658, 1657, 1657, 1659, 1657, 1660, 193, 193,
+ 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1668,
+ 1669, 1670, 193, 193, 193, 193, 193, 193,
+
+ 1671, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1671, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1671, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1671, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1671, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1671, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1671, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 1671, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+ 1672, 1672, 1672, 1672, 1672, 1672, 1672, 1672,
+
+ 1672, 1672, 1672, 1672, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 795, 795, 795, 795, 795, 795, 795, 795,
+ 795, 795, 795, 795, 795, 795, 795, 795,
- 796, 796, 796, 796, 796, 796, 796, 796,
- 796, 796, 796, 796, 796, 796, 796, 796,
- 796, 796, 796, 796, 796, 796, 796, 796,
- 796, 796, 796, 796, 192, 192, 192, 192,
-
- 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
- 1658, 1658, 1658, 1658, 1658, 1658, 1658, 1658,
-
- 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
- 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
- 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
- 1659, 1659, 1659, 1659, 1659, 1659, 1659, 1659,
-
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
-
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1660,
- 1660, 1660, 1660, 1660, 1660, 1660, 1494, 1494,
- 1660, 1494, 1660, 1494, 1494, 1660, 1660, 1660,
- 1660, 1660, 1660, 1660, 1660, 1660, 1660, 1494,
-
- 1660, 1494, 1660, 1494, 1494, 1660, 1660, 1494,
- 1494, 1494, 1660, 1660, 1660, 1660, 1661, 1661,
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
- 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
- 1662, 1662, 1662, 1663, 1663, 1663, 1493, 1493,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
-
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
-
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664,
- 1664, 1664, 1493, 1493, 1493, 1493, 1493, 1493,
-
- 1665, 1666, 1667, 1668, 1669, 1670, 1670, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 1671, 1672, 1673, 1674, 1675,
- 192, 192, 192, 192, 192, 1676, 1677, 1678,
+ 795, 795, 795, 795, 795, 795, 795, 193,
+ 193, 193, 193, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 798, 798, 798, 798,
+ 798, 798, 798, 798, 193, 193, 193, 193,
+
+ 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
+ 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
+ 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
+ 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673,
+
+ 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674,
+ 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674,
+ 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674,
+ 1674, 1674, 1674, 1674, 1674, 1674, 1674, 1674,
+
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
+
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675,
+ 1675, 1675, 1675, 1675, 1675, 1675, 1507, 1507,
+ 1675, 1507, 1675, 1507, 1507, 1675, 1675, 1675,
+ 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1507,
+
+ 1675, 1507, 1675, 1507, 1507, 1675, 1675, 1507,
+ 1507, 1507, 1675, 1675, 1675, 1675, 1676, 1676,
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+
+ 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677,
+ 1677, 1677, 1677, 1678, 1678, 1678, 1506, 1506,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
- 1679, 1680, 1678, 1678, 1678, 1678, 1678, 1678,
- 1678, 1678, 1678, 1678, 1678, 1678, 1678, 286,
- 1678, 1678, 1678, 1678, 1678, 286, 1678, 286,
-
- 1678, 1678, 286, 1678, 1678, 286, 1678, 1678,
- 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1679,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1682, 1682, 1682, 1682, 1682, 1682,
- 1682, 1682, 1682, 1682, 1682, 1682, 1682, 1682,
-
- 1682, 1682, 318, 318, 318, 318, 318, 318,
- 318, 318, 318, 318, 318, 318, 318, 318,
- 318, 318, 318, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1187, 1445,
-
- 318, 318, 318, 318, 318, 318, 318, 318,
- 318, 318, 318, 318, 318, 318, 318, 318,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 318, 318, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 318, 318, 318, 318, 318, 318, 318, 318,
- 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
- 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
-
- 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
- 1683, 1683, 1683, 1683, 1683, 1683, 1683, 1683,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1684, 1309, 318, 318,
-
- 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685,
- 1685, 1685, 1685, 1685, 1685, 1685, 1685, 1685,
- 1686, 1687, 1688, 1689, 1690, 1691, 1691, 1692,
- 1693, 1694, 192, 192, 192, 192, 192, 192,
-
- 163, 163, 163, 163, 1044, 1044, 1044, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1695, 1696, 1696, 1697, 1697, 1698, 1699, 1698,
- 1699, 1698, 1699, 1698, 1699, 1698, 1699, 1698,
-
- 1699, 1698, 1699, 1698, 1699, 1456, 1456, 1700,
- 1701, 1695, 1695, 1695, 1695, 1697, 1697, 1697,
- 1702, 1703, 1704, 192, 1705, 1706, 1707, 1707,
- 1696, 1236, 1237, 1236, 1237, 1236, 1237, 1708,
-
- 1695, 1695, 1709, 1710, 1711, 1712, 1713, 192,
- 1695, 1239, 1201, 1695, 192, 192, 192, 192,
- 1681, 1681, 1681, 1714, 1681, 318, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
-
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 1681, 1681, 1681,
- 1681, 1681, 1681, 1681, 1681, 318, 318, 1715,
-
- 192, 1707, 1695, 1708, 1239, 1201, 1695, 1716,
- 1236, 1237, 1695, 1709, 1702, 1710, 1704, 1717,
- 1718, 1719, 1720, 1721, 1722, 1723, 1724, 1725,
- 1726, 1727, 1706, 1705, 1728, 1713, 1729, 1707,
-
- 1695, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
- 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
- 1730, 1730, 1730, 1730, 1730, 1730, 1730, 1730,
- 1730, 1730, 1730, 1731, 1695, 1732, 1733, 1697,
-
- 1733, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
- 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
- 1734, 1734, 1734, 1734, 1734, 1734, 1734, 1734,
- 1734, 1734, 1734, 1731, 1713, 1732, 1713, 1735,
-
- 1736, 1737, 1236, 1237, 1738, 1739, 1740, 1741,
- 1741, 1741, 1741, 1741, 1741, 1741, 1741, 1741,
- 1742, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
- 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
-
- 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
- 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
- 1740, 1740, 1740, 1740, 1740, 1740, 1740, 1740,
- 1740, 1740, 1740, 1740, 1740, 1740, 1743, 1743,
-
- 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
- 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
- 1744, 1744, 1744, 1744, 1744, 1744, 1744, 1744,
- 1744, 1744, 1744, 1744, 1744, 1744, 1744, 192,
-
- 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
- 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
- 192, 192, 1744, 1744, 1744, 1744, 1744, 1744,
- 192, 192, 1744, 1744, 1744, 192, 192, 192,
-
- 1745, 1239, 1713, 1733, 1452, 1239, 1239, 192,
- 1255, 1235, 1235, 1235, 1235, 1255, 1255, 192,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1746, 1746, 1746, 1747, 51, 1748, 1748,
-
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 192, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
-
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 192,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 192, 1749, 1749, 192, 1749,
-
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 192, 192,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 192, 192,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679,
+ 1679, 1679, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1680, 1681, 1682, 1683, 1684, 1685, 1685, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 1686, 1687, 1688, 1689, 1690,
+ 193, 193, 193, 193, 193, 1691, 1692, 1693,
+
+ 1694, 1694, 1694, 1694, 1694, 1694, 1694, 1694,
+ 1694, 1695, 1693, 1693, 1693, 1693, 1693, 1693,
+ 1693, 1693, 1693, 1693, 1693, 1693, 1693, 287,
+ 1693, 1693, 1693, 1693, 1693, 287, 1693, 287,
+
+ 1693, 1693, 287, 1693, 1693, 287, 1693, 1693,
+ 1693, 1693, 1693, 1693, 1693, 1693, 1693, 1694,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1697, 1697, 1697, 1697, 1697, 1697,
+ 1697, 1697, 1697, 1697, 1697, 1697, 1697, 1697,
+
+ 1697, 1697, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1193, 1457,
+
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 319, 319, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+ 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+
+ 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+ 1698, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1699, 1322, 319, 319,
+
+ 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700,
+ 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700,
+ 1701, 1702, 1703, 1704, 1705, 1706, 1706, 1707,
+ 1708, 1709, 193, 193, 193, 193, 193, 193,
+
+ 164, 164, 164, 164, 1050, 1050, 1050, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1710, 1711, 1711, 1712, 1712, 1713, 1714, 1713,
+ 1714, 1713, 1714, 1713, 1714, 1713, 1714, 1713,
+
+ 1714, 1713, 1714, 1713, 1714, 1469, 1469, 1715,
+ 1716, 1710, 1710, 1710, 1710, 1712, 1712, 1712,
+ 1717, 1718, 1719, 193, 1720, 1721, 1722, 1722,
+ 1711, 1246, 1247, 1246, 1247, 1246, 1247, 1723,
+
+ 1710, 1710, 1724, 1725, 1726, 1727, 1728, 193,
+ 1710, 1249, 1207, 1710, 193, 193, 193, 193,
+ 1696, 1696, 1696, 1729, 1696, 319, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 1696, 1696, 1696,
+ 1696, 1696, 1696, 1696, 1696, 319, 319, 1730,
+
+ 193, 1722, 1710, 1723, 1249, 1207, 1710, 1731,
+ 1246, 1247, 1710, 1724, 1717, 1725, 1719, 1732,
+ 1733, 1734, 1735, 1736, 1737, 1738, 1739, 1740,
+ 1741, 1742, 1721, 1720, 1743, 1728, 1744, 1722,
+
+ 1710, 1745, 1745, 1745, 1745, 1745, 1745, 1745,
+ 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745,
+ 1745, 1745, 1745, 1745, 1745, 1745, 1745, 1745,
+ 1745, 1745, 1745, 1746, 1710, 1747, 1748, 1712,
+
+ 1748, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749,
- 1749, 1749, 1749, 192, 192, 192, 192, 192,
-
- 1750, 1751, 1750, 192, 192, 192, 192, 1752,
- 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
- 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
- 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
-
- 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
- 1752, 1752, 1752, 1752, 1752, 1752, 1752, 1752,
- 1752, 1752, 1752, 1752, 192, 192, 192, 1753,
- 1753, 1753, 1753, 1753, 1753, 1753, 1753, 1753,
-
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
-
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
- 1754, 1754, 1754, 1754, 1754, 1754, 1754, 1754,
- 1754, 1754, 1754, 1754, 1754, 1755, 1755, 1755,
- 1755, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
+ 1749, 1749, 1749, 1746, 1728, 1747, 1728, 1750,
+ 1751, 1752, 1246, 1247, 1753, 1754, 1755, 1756,
1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1755, 192, 192, 192, 192, 192,
- 1341, 1341, 1341, 1341, 1341, 1341, 1341, 1341,
- 1341, 1341, 1341, 1341, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
- 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
-
- 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
- 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
- 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277,
- 1277, 1277, 1277, 1277, 1277, 1047, 192, 192,
-
- 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
- 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
- 1757, 1757, 1757, 1757, 1757, 1757, 1757, 1757,
- 1757, 1757, 1757, 1757, 1757, 192, 192, 192,
-
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
-
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
- 1758, 1758, 1758, 1758, 1758, 1758, 1758, 1758,
- 1758, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1757, 1755, 1755, 1755, 1755, 1755, 1755, 1755,
+ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755,
+
+ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755,
+ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755,
+ 1755, 1755, 1755, 1755, 1755, 1755, 1755, 1755,
+ 1755, 1755, 1755, 1755, 1755, 1755, 1758, 1758,
1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
1759, 1759, 1759, 1759, 1759, 1759, 1759, 1759,
- 1759, 1759, 1759, 1759, 1759, 1759, 1759, 192,
-
- 1760, 1760, 1760, 1760, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,
- 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,
-
- 1761, 1762, 1761, 1761, 1761, 1761, 1761, 1761,
- 1761, 1761, 1762, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
- 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
- 1763, 1763, 1763, 1763, 1763, 1763, 1763, 1763,
- 1763, 1763, 1763, 1763, 1763, 1763, 192, 1764,
+ 1759, 1759, 1759, 1759, 1759, 1759, 1759, 193,
+
+ 193, 193, 1759, 1759, 1759, 1759, 1759, 1759,
+ 193, 193, 1759, 1759, 1759, 1759, 1759, 1759,
+ 193, 193, 1759, 1759, 1759, 1759, 1759, 1759,
+ 193, 193, 1759, 1759, 1759, 193, 193, 193,
+
+ 1760, 1249, 1728, 1748, 1465, 1249, 1249, 193,
+ 1266, 1245, 1245, 1245, 1245, 1266, 1266, 193,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1761, 1761, 1761, 1762, 51, 1763, 1763,
+
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 193, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 193,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 193, 1764, 1764, 193, 1764,
+
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 193, 193,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 193, 193,
+
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764,
+ 1764, 1764, 1764, 193, 193, 193, 193, 193,
+
+ 1765, 1766, 1765, 193, 193, 193, 193, 1767,
+ 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
+ 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
+ 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
+
+ 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
+ 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767,
+ 1767, 1767, 1767, 1767, 193, 193, 193, 1768,
+ 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
- 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
- 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
- 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
- 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
- 1765, 1765, 1765, 1765, 192, 192, 192, 192,
- 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765,
- 1766, 1767, 1767, 1767, 1767, 1767, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
+ 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769,
+ 1769, 1769, 1769, 1769, 1769, 1770, 1770, 1770,
+ 1770, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
- 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
- 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
- 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
- 1768, 1768, 1768, 1768, 1768, 1768, 1768, 1768,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1770, 193, 193, 193, 193, 193,
+ 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1354,
+ 1354, 1354, 1354, 1354, 193, 193, 193, 193,
- 1768, 1768, 1768, 1768, 1768, 1768, 1769, 1769,
- 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
- 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
- 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
- 1770, 1770, 1770, 1770, 1770, 1770, 1770, 1770,
- 1770, 1770, 1770, 1770, 1770, 1770, 1771, 1771,
- 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
- 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1288, 1288, 1288, 1288, 1288, 1053, 193, 193,
1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
- 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772,
+ 1772, 1772, 1772, 1772, 1772, 193, 193, 193,
1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
- 1773, 1773, 1773, 1773, 1773, 1773, 192, 192,
-
- 1774, 1775, 1776, 1777, 1778, 1779, 1780, 1781,
- 1782, 1783, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1784, 1784, 1784, 1784, 1784, 1784, 286, 286,
- 1784, 286, 1784, 1784, 1784, 1784, 1784, 1784,
- 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
- 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
-
- 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
- 1784, 1784, 1784, 1784, 1784, 1784, 1784, 1784,
- 1784, 1784, 1784, 1784, 1784, 1784, 286, 1784,
- 1784, 286, 286, 286, 1784, 286, 286, 1784,
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 1773, 1773, 1773, 1773, 1773, 1773, 1773,
+ 1773, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774,
+ 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774,
+ 1774, 1774, 1774, 1774, 1774, 1774, 1774, 1774,
+ 1774, 1774, 1774, 1774, 1774, 1774, 1774, 193,
+
+ 1775, 1775, 1775, 1775, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776,
+ 1776, 1776, 1776, 1776, 1776, 1776, 1776, 1776,
+
+ 1776, 1777, 1776, 1776, 1776, 1776, 1776, 1776,
+ 1776, 1776, 1777, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778,
+ 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778,
+ 1778, 1778, 1778, 1778, 1778, 1778, 1778, 1778,
+ 1778, 1778, 1778, 1778, 1778, 1778, 193, 1779,
+
+ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780,
+ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780,
+ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780,
+ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780,
+
+ 1780, 1780, 1780, 1780, 193, 193, 193, 193,
+ 1780, 1780, 1780, 1780, 1780, 1780, 1780, 1780,
+ 1781, 1782, 1782, 1782, 1782, 1782, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
+ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
+ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
+ 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783,
+
+ 1783, 1783, 1783, 1783, 1783, 1783, 1784, 1784,
+ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
- 1785, 1785, 1785, 1785, 1785, 1785, 286, 1786,
+
+ 1785, 1785, 1785, 1785, 1785, 1785, 1785, 1785,
+ 1785, 1785, 1785, 1785, 1785, 1785, 1786, 1786,
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
+
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
+ 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,
1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
- 1788, 1788, 1788, 1788, 1788, 1788, 1789, 1789,
- 1789, 1789, 1790, 1790, 286, 286, 286, 1791,
-
- 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
- 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
- 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
- 1792, 1792, 286, 286, 286, 286, 286, 1793,
-
- 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
- 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
- 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
- 1794, 1794, 1794, 1794, 1794, 1794, 1794, 1794,
-
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 1795, 1795, 1795, 1795, 1795, 1795, 1795, 1795,
- 286, 286, 286, 286, 286, 286, 1795, 1795,
-
- 1796, 1797, 1797, 1797, 286, 1797, 1797, 286,
- 286, 286, 286, 286, 1797, 1798, 1797, 1799,
- 1796, 1796, 1796, 1796, 286, 1796, 1796, 1796,
- 286, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
-
- 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
- 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796,
- 1796, 1796, 1796, 1796, 286, 286, 286, 286,
- 1799, 1800, 1798, 286, 286, 286, 286, 1801,
-
- 1802, 1803, 1804, 1805, 1806, 1806, 1806, 1806,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 1807, 1807, 1807, 1807, 1807, 1807, 1808, 1808,
- 1809, 286, 286, 286, 286, 286, 286, 286,
+ 1788, 1788, 1788, 1788, 1788, 1788, 1788, 1788,
+ 1788, 1788, 1788, 1788, 1788, 1788, 193, 193,
+
+ 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796,
+ 1797, 1798, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1799, 1799, 1799, 1799, 1799, 1799, 287, 287,
+ 1799, 287, 1799, 1799, 1799, 1799, 1799, 1799,
+ 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799,
+ 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799,
+
+ 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799,
+ 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799,
+ 1799, 1799, 1799, 1799, 1799, 1799, 287, 1799,
+ 1799, 287, 287, 287, 1799, 287, 287, 1799,
+
+ 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
+ 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800,
+ 1800, 1800, 1800, 1800, 1800, 1800, 287, 1801,
+ 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802,
+
+ 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803,
+ 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803,
+ 1803, 1803, 1803, 1803, 1803, 1803, 1804, 1804,
+ 1804, 1804, 1805, 1805, 287, 287, 287, 1806,
+
+ 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807,
+ 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807,
+ 1807, 1807, 1807, 1807, 1807, 1807, 1807, 1807,
+ 1807, 1807, 287, 287, 287, 287, 287, 1808,
+
+ 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809,
+ 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809,
+ 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809,
+ 1809, 1809, 1809, 1809, 1809, 1809, 1809, 1809,
1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
1810, 1810, 1810, 1810, 1810, 1810, 1810, 1810,
- 1810, 1810, 1810, 1810, 1810, 1811, 1811, 1812,
-
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
-
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
- 1813, 1813, 1813, 1813, 1813, 1813, 1813, 1813,
- 1813, 1813, 1813, 1813, 1813, 1813, 286, 286,
- 286, 1814, 1814, 1814, 1814, 1814, 1814, 1814,
-
- 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815,
- 1815, 1815, 1815, 1815, 1815, 1815, 1815, 1815,
- 1815, 1815, 1815, 1815, 1815, 1815, 286, 286,
- 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816,
-
- 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817,
- 1817, 1817, 1817, 1817, 1817, 1817, 1817, 1817,
- 1817, 1817, 1817, 286, 286, 286, 286, 286,
- 1818, 1818, 1818, 1818, 1818, 1818, 1818, 1818,
-
- 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
- 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
- 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
- 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
-
- 1819, 1819, 1819, 1819, 1819, 1819, 1819, 1819,
- 1819, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
-
- 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827,
- 1828, 1829, 1829, 1829, 1829, 1829, 1829, 1829,
- 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829,
- 1829, 1829, 1829, 1829, 1829, 1829, 1829, 286,
-
- 1830, 1831, 1830, 1832, 1832, 1832, 1832, 1832,
- 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
- 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
- 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
- 1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
+ 287, 287, 287, 287, 287, 287, 1810, 1810,
+
+ 1811, 1812, 1812, 1812, 287, 1812, 1812, 287,
+ 287, 287, 287, 287, 1812, 1813, 1812, 1814,
+ 1811, 1811, 1811, 1811, 287, 1811, 1811, 1811,
+ 287, 1811, 1811, 1811, 1811, 1811, 1811, 1811,
+
+ 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811,
+ 1811, 1811, 1811, 1811, 1811, 1811, 1811, 1811,
+ 1811, 1811, 1811, 1811, 287, 287, 287, 287,
+ 1814, 1815, 1813, 287, 287, 287, 287, 1816,
+
+ 1817, 1818, 1819, 1820, 1821, 1821, 1821, 1821,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 1822, 1822, 1822, 1822, 1822, 1822, 1823, 1823,
+ 1824, 287, 287, 287, 287, 287, 287, 287,
+
+ 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825,
+ 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825,
+ 1825, 1825, 1825, 1825, 1825, 1825, 1825, 1825,
+ 1825, 1825, 1825, 1825, 1825, 1826, 1826, 1827,
+
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 1828, 1828,
+ 1828, 1828, 1828, 1828, 1828, 1828, 287, 287,
+ 287, 1829, 1829, 1829, 1829, 1829, 1829, 1829,
+
+ 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830,
+ 1830, 1830, 1830, 1830, 1830, 1830, 1830, 1830,
+ 1830, 1830, 1830, 1830, 1830, 1830, 287, 287,
+ 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831,
+
1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
1832, 1832, 1832, 1832, 1832, 1832, 1832, 1832,
- 1831, 1831, 1831, 1831, 1831, 1831, 1831, 1831,
- 1831, 1831, 1831, 1831, 1831, 1831, 1833, 1834,
- 1834, 1835, 1835, 1835, 1835, 1835, 192, 192,
- 192, 192, 1836, 1837, 1838, 1839, 1840, 1841,
- 1842, 1843, 1844, 1845, 1845, 1845, 1845, 1845,
- 1845, 1845, 1845, 1845, 1845, 1845, 1846, 1847,
- 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1856, 1856, 1857, 1858, 1858, 1858, 1858, 1858,
- 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
- 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
- 1858, 1858, 1859, 1858, 1859, 1858, 1858, 1858,
- 1858, 1858, 1858, 1858, 1858, 1858, 1858, 1858,
- 1858, 1858, 1858, 1859, 1858, 1858, 1858, 1858,
- 1857, 1857, 1857, 1856, 1856, 1856, 1856, 1857,
- 1857, 1860, 1861, 1862, 1862, 1863, 1864, 1864,
- 1864, 1864, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
- 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
- 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865,
- 1865, 192, 192, 192, 192, 192, 192, 192,
- 1866, 1867, 1868, 1869, 1870, 1871, 1872, 1873,
- 1874, 1875, 192, 192, 192, 192, 192, 192,
-
- 1876, 1876, 1876, 1877, 1877, 1877, 1877, 1877,
- 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
- 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
- 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1877,
- 1877, 1877, 1877, 1877, 1877, 1877, 1877, 1878,
- 1879, 1879, 1879, 1879, 1880, 1879, 1881, 1881,
- 1879, 1879, 1879, 1882, 1882, 192, 1883, 1884,
- 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892,
- 1893, 1894, 1894, 1894, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1895, 1895, 1896, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1897, 1897, 1897, 1897, 1897,
- 1897, 1897, 1897, 1896, 1896, 1896, 1895, 1895,
- 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1896,
- 1898, 1897, 1897, 1897, 1897, 1899, 1899, 1900,
- 1901, 192, 192, 192, 192, 192, 192, 192,
- 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909,
- 1910, 1911, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1832, 1832, 1832, 287, 287, 287, 287, 287,
+ 1833, 1833, 1833, 1833, 1833, 1833, 1833, 1833,
+
+ 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
+ 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
+ 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
+ 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
+
+ 1834, 1834, 1834, 1834, 1834, 1834, 1834, 1834,
+ 1834, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+
+ 1835, 1836, 1837, 1838, 1839, 1840, 1841, 1842,
+ 1843, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
+ 1844, 1844, 1844, 1844, 1844, 1844, 1844, 1844,
+ 1844, 1844, 1844, 1844, 1844, 1844, 1844, 287,
+
+ 1845, 1846, 1845, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1847, 1847, 1847, 1847, 1847, 1847, 1847, 1847,
+ 1846, 1846, 1846, 1846, 1846, 1846, 1846, 1846,
+ 1846, 1846, 1846, 1846, 1846, 1846, 1848, 1849,
+ 1849, 1850, 1850, 1850, 1850, 1850, 193, 193,
+ 193, 193, 1851, 1852, 1853, 1854, 1855, 1856,
+ 1857, 1858, 1859, 1860, 1860, 1860, 1860, 1860,
+ 1860, 1860, 1860, 1860, 1860, 1860, 1861, 1862,
+ 1863, 1864, 1865, 1866, 1867, 1868, 1869, 1870,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1871, 1871, 1872, 1873, 1873, 1873, 1873, 1873,
+ 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873,
+ 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873,
+ 1873, 1873, 1874, 1873, 1874, 1873, 1873, 1873,
+ 1873, 1873, 1873, 1873, 1873, 1873, 1873, 1873,
+ 1873, 1873, 1873, 1874, 1873, 1873, 1873, 1873,
+ 1872, 1872, 1872, 1871, 1871, 1871, 1871, 1872,
+ 1872, 1875, 1876, 1877, 1877, 1878, 1879, 1879,
+ 1879, 1879, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880,
+ 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880,
+ 1880, 1880, 1880, 1880, 1880, 1880, 1880, 1880,
+ 1880, 193, 193, 193, 193, 193, 193, 193,
+ 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888,
+ 1889, 1890, 193, 193, 193, 193, 193, 193,
+
+ 1891, 1891, 1891, 1892, 1892, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1892,
+ 1892, 1892, 1892, 1892, 1892, 1892, 1892, 1893,
+ 1894, 1894, 1894, 1894, 1895, 1894, 1896, 1896,
+ 1894, 1894, 1894, 1897, 1897, 193, 1898, 1899,
+ 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907,
+ 1908, 1909, 1909, 1909, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1910, 1910, 1911, 1912, 1912, 1912, 1912, 1912,
1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
1912, 1912, 1912, 1912, 1912, 1912, 1912, 1912,
- 1912, 1912, 1912, 1913, 1914, 1913, 1914, 1914,
- 1913, 1913, 1913, 1913, 1913, 1913, 1915, 1916,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1912, 1912, 1912, 1911, 1911, 1911, 1910, 1910,
+ 1910, 1910, 1910, 1910, 1910, 1910, 1910, 1911,
+ 1913, 1912, 1912, 1912, 1912, 1914, 1914, 1915,
+ 1916, 193, 193, 193, 193, 193, 193, 193,
1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924,
- 1925, 1926, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
+ 1925, 1926, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
-
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 1927,
- 1927, 1927, 1927, 1927, 1927, 1927, 1927, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 1928, 1928, 1928, 1928, 1928,
- 1928, 1928, 1928, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1929, 1929, 1929, 1929, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
-
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1931, 1931, 1931, 1932, 1932, 1932, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1932, 1930, 1930, 1930, 1931, 1932,
- 1931, 1932, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
-
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1931, 1932, 1932, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
-
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 1930,
- 1930, 1930, 1930, 1930, 1930, 1930, 1930, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
-
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 1933, 1933, 1933, 1933, 1933, 1933, 1933,
- 1933, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 1934, 1934, 1934,
- 1934, 1934, 1934, 1934, 1934, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1934, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
- 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
- 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
- 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
- 1935, 1935, 1935, 1935, 1935, 1935, 1935, 1935,
- 1935, 1935, 1935, 1935, 1935, 1935, 1935, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 1936,
- 1936, 1936, 1936, 1937, 1937, 1937, 1937, 1937,
- 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1938, 1939, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 192,
- 192, 1277, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1941, 1941,
- 1941, 1941, 1941, 1941, 1941, 1942, 1943, 1944,
- 1944, 1944, 1940, 1940, 1940, 1945, 1942, 1942,
- 1942, 1942, 1942, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1947, 1947, 1947, 1947, 1947,
- 1947, 1947, 1947, 1940, 1940, 1948, 1948, 1948,
- 1948, 1948, 1947, 1947, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1948, 1948, 1948, 1948, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1941, 1941, 1941, 1941, 1941,
- 1941, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 1940, 1940,
- 1940, 1940, 1940, 1940, 1940, 1940, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1756, 1756, 1756, 1756, 1756, 1756,
- 1756, 1756, 1949, 1949, 1949, 1756, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- 1309, 1309, 1309, 1309, 1309, 1309, 1309, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
+ 1927, 1927, 1927, 1928, 1929, 1928, 1929, 1929,
+ 1928, 1928, 1928, 1928, 1928, 1928, 1930, 1931,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939,
+ 1940, 1941, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 1942,
+ 1942, 1942, 1942, 1942, 1942, 1942, 1942, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 1943, 1943, 1943, 1943, 1943,
+ 1943, 1943, 1943, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1944, 1944, 1944, 1944, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1946, 1946, 1946, 1947, 1947, 1947, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1947, 1945, 1945, 1945, 1946, 1947,
+ 1946, 1947, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1946, 1947, 1947, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 1945,
+ 1945, 1945, 1945, 1945, 1945, 1945, 1945, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 1948, 1948, 1948, 1948, 1948, 1948, 1948,
+ 1948, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949,
+ 1949, 1949, 1949, 1949, 1949, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1949, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
- 1950, 1950, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 192, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 192, 1951, 1951,
- 192, 192, 1951, 192, 192, 1951, 1951, 192,
- 192, 1951, 1951, 1951, 1951, 192, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
- 1952, 1952, 192, 1952, 192, 1952, 1952, 1952,
- 1952, 1953, 1952, 1952, 192, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
-
- 1952, 1952, 1952, 1952, 1951, 1951, 192, 1951,
- 1951, 1951, 1951, 192, 192, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 192, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 192, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 192, 1951, 1951, 1951, 1951, 192,
- 1951, 1951, 1951, 1951, 1951, 192, 1951, 192,
- 192, 192, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 192, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
-
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1269, 1269, 192, 192,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1954, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1955, 1952, 1952, 1952, 1952,
- 1952, 1952, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1954, 1952, 1952, 1952, 1952,
-
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1955, 1952, 1952,
- 1952, 1952, 1952, 1952, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1954, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1955,
- 1952, 1952, 1952, 1952, 1952, 1952, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1954,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1955, 1952, 1952, 1952, 1952, 1952, 1952,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1951, 1951, 1951, 1951, 1951, 1951, 1951,
- 1951, 1954, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
+ 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
+ 1950, 1950, 1950, 1950, 1950, 1950, 1950, 1950,
+ 1950, 1950, 1950, 1950, 1950, 1950, 1950, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 1951,
+ 1951, 1951, 1951, 1952, 1952, 1952, 1952, 1952,
1952, 1952, 1952, 1952, 1952, 1952, 1952, 1952,
- 1952, 1952, 1952, 1955, 1952, 1952, 1952, 1952,
- 1952, 1952, 1956, 1957, 192, 192, 1958, 1959,
- 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967,
- 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965,
- 1966, 1967, 1958, 1959, 1960, 1961, 1962, 1963,
- 1964, 1965, 1966, 1967, 1958, 1959, 1960, 1961,
- 1962, 1963, 1964, 1965, 1966, 1967, 1958, 1959,
- 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967,
-
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
- 286, 286, 286, 286, 286, 286, 286, 286,
-
- 1968, 1968, 1968, 1968, 318, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 318, 1968, 1968, 318, 1968, 318, 318, 1968,
- 318, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
- 318, 1968, 318, 1968, 318, 318, 318, 318,
- 318, 318, 1968, 318, 318, 318, 318, 1968,
- 318, 1968, 318, 1968, 318, 1968, 1968, 1968,
- 318, 1968, 1968, 318, 1968, 318, 318, 1968,
- 318, 1968, 318, 1968, 318, 1968, 318, 1968,
- 318, 1968, 1968, 318, 1968, 318, 318, 1968,
- 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 318, 1968, 1968, 1968, 1968,
- 318, 1968, 1968, 1968, 1968, 318, 1968, 318,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 318, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 318, 318, 318, 318,
- 318, 1968, 1968, 1968, 318, 1968, 1968, 1968,
- 1968, 1968, 318, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 1968, 1968, 1968, 1968,
- 1968, 1968, 1968, 1968, 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, 318, 318, 318, 318, 318,
- 1969, 1969, 318, 318, 318, 318, 318, 318,
- 318, 318, 318, 318, 318, 318, 318, 318,
-
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 192, 192, 192, 192,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
- 1344, 1344, 1344, 1344, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
- 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
- 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 192, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1970, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
- 1977, 1978, 1979, 192, 192, 192, 192, 192,
- 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
- 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
- 1980, 1980, 1980, 1980, 1980, 1980, 1980, 1980,
- 1980, 1980, 1980, 1980, 1980, 1980, 1980, 192,
- 1981, 1980, 1981, 1981, 1981, 1981, 1981, 1981,
- 1981, 1981, 1981, 1981, 1981, 1980, 1981, 1980,
- 1981, 1981, 1980, 1981, 1981, 1981, 1980, 1981,
- 1981, 1981, 1980, 1980, 1980, 1980, 1980, 1981,
- 1982, 1982, 1982, 1982, 1982, 1982, 1982, 740,
- 1982, 1982, 1982, 1982, 1982, 1982, 1982, 740,
- 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
- 1982, 1982, 1983, 1983, 192, 192, 192, 192,
- 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
- 1982, 740, 1982, 740, 740, 1982, 1982, 740,
- 1982, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
- 1982, 1982, 740, 740, 740, 740, 1982, 1982,
- 1980, 1982, 1982, 1982, 1982, 1982, 1982, 1982,
- 1982, 1982, 1982, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 1984, 1984,
- 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
- 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
- 1984, 1984, 1984, 1984, 1984, 1984, 1984, 1984,
-
- 1985, 1986, 1986, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
- 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
- 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
- 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
- 1486, 1486, 1986, 1986, 1986, 1986, 1986, 1986,
- 1986, 1986, 1986, 192, 192, 192, 192, 192,
- 1486, 1486, 1486, 1486, 1486, 1486, 1486, 1486,
- 1486, 192, 192, 192, 192, 192, 192, 192,
- 1986, 1986, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 192, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1312, 1312, 1313,
- 1313, 1313, 1313, 1313, 1312, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 192, 1313, 1313,
- 1313, 1313, 1313, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 192,
- 1313, 192, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1312, 1313, 1312, 1313, 1312, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1312,
- 1313, 1312, 1312, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 192, 1313, 1313, 1313, 1313, 192, 192, 192,
-
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 192, 192,
- 1987, 1987, 1987, 1987, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 1313, 1313, 1313, 1313, 1313,
-
- 1988, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1988, 1313, 1313, 1313, 1988, 1313, 1988,
- 1313, 1988, 1313, 1988, 1313, 1313, 1313, 1988,
- 1313, 1313, 1313, 1313, 1313, 1313, 1988, 1988,
- 1313, 1313, 1313, 1313, 1988, 1313, 1988, 1988,
- 1313, 1313, 1313, 1313, 1988, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 192, 192, 192, 192, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313,
- 1313, 1313, 1313, 1313, 1313, 1313, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312,
- 1312, 1312, 1312, 1312, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
-
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 192, 192,
- 192, 192, 192, 192, 192, 192, 1989, 1989,
-
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
-
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1990,
- 1990, 1990, 1990, 1990, 1990, 1990, 1990, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
-
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1953, 1954, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 193,
+ 193, 1288, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1956, 1956,
+ 1956, 1956, 1956, 1956, 1956, 1957, 1958, 1959,
+ 1959, 1959, 1955, 1955, 1955, 1960, 1957, 1957,
+ 1957, 1957, 1957, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1962, 1962, 1962, 1962, 1962,
+ 1962, 1962, 1962, 1955, 1955, 1963, 1963, 1963,
+ 1963, 1963, 1962, 1962, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1963, 1963, 1963, 1963, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1956, 1956, 1956, 1956, 1956,
+ 1956, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 1955, 1955,
+ 1955, 1955, 1955, 1955, 1955, 1955, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1771, 1771, 1771, 1771, 1771, 1771,
+ 1771, 1771, 1964, 1964, 1964, 1771, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
+ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965,
+ 1965, 1965, 1965, 1965, 1965, 1965, 1965, 1965,
+ 1965, 1965, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 193, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 193, 1966, 1966,
+ 193, 193, 1966, 193, 193, 1966, 1966, 193,
+ 193, 1966, 1966, 1966, 1966, 193, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1967, 1967,
+ 1967, 1967, 193, 1967, 193, 1967, 1967, 1967,
+ 1967, 1968, 1967, 1967, 193, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+
+ 1967, 1967, 1967, 1967, 1966, 1966, 193, 1966,
+ 1966, 1966, 1966, 193, 193, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 193, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 193, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 193, 1966, 1966, 1966, 1966, 193,
+ 1966, 1966, 1966, 1966, 1966, 193, 1966, 193,
+ 193, 193, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 193, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1280, 1280, 193, 193,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1969, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1970, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1969, 1967, 1967, 1967, 1967,
+
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1970, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1969, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1970,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1969,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1970, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1966, 1966, 1966, 1966, 1966, 1966, 1966,
+ 1966, 1969, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1967, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1967, 1970, 1967, 1967, 1967, 1967,
+ 1967, 1967, 1971, 1972, 193, 193, 1973, 1974,
+ 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982,
+ 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980,
+ 1981, 1982, 1973, 1974, 1975, 1976, 1977, 1978,
+ 1979, 1980, 1981, 1982, 1973, 1974, 1975, 1976,
+ 1977, 1978, 1979, 1980, 1981, 1982, 1973, 1974,
+ 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982,
+
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 287,
+
+ 1983, 1983, 1983, 1983, 319, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 319, 1983, 1983, 319, 1983, 319, 319, 1983,
+ 319, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 319, 1983, 1983, 1983, 1983,
+ 319, 1983, 319, 1983, 319, 319, 319, 319,
+ 319, 319, 1983, 319, 319, 319, 319, 1983,
+ 319, 1983, 319, 1983, 319, 1983, 1983, 1983,
+ 319, 1983, 1983, 319, 1983, 319, 319, 1983,
+ 319, 1983, 319, 1983, 319, 1983, 319, 1983,
+ 319, 1983, 1983, 319, 1983, 319, 319, 1983,
+ 1983, 1983, 1983, 319, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 319, 1983, 1983, 1983, 1983,
+ 319, 1983, 1983, 1983, 1983, 319, 1983, 319,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 319, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 319, 319, 319, 319,
+ 319, 1983, 1983, 1983, 319, 1983, 1983, 1983,
+ 1983, 1983, 319, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 1983, 1983, 1983, 1983,
+ 1983, 1983, 1983, 1983, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+ 1984, 1984, 319, 319, 319, 319, 319, 319,
+ 319, 319, 319, 319, 319, 319, 319, 319,
+
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 193, 193, 193, 193,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 1357, 1357, 1357, 1357,
+ 1357, 1357, 1357, 1357, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 193,
+ 193, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 193,
+ 193, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 193, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 1985, 1985, 1986, 1987, 1988, 1989, 1990, 1991,
+ 1992, 1993, 1994, 193, 193, 193, 193, 193,
+ 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995,
+ 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995,
+ 1995, 1995, 1995, 1995, 1995, 1995, 1995, 1995,
+ 1995, 1995, 1995, 1995, 1995, 1995, 1995, 193,
+ 1996, 1995, 1996, 1996, 1996, 1996, 1996, 1996,
+ 1996, 1996, 1996, 1996, 1996, 1995, 1996, 1995,
+ 1996, 1996, 1995, 1996, 1996, 1996, 1995, 1996,
+ 1996, 1996, 1995, 1995, 1995, 1995, 1995, 1996,
+ 1997, 1997, 1997, 1997, 1997, 1997, 1997, 742,
+ 1997, 1997, 1997, 1997, 1997, 1997, 1997, 742,
+ 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997,
+ 1997, 1997, 1998, 1998, 193, 193, 193, 193,
+ 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997,
+ 1997, 742, 1997, 742, 742, 1997, 1997, 742,
+ 1997, 1997, 1997, 1997, 1997, 1997, 1997, 1997,
+ 1997, 1997, 742, 742, 742, 742, 1997, 1997,
+ 1995, 1997, 1997, 1997, 1997, 1997, 1997, 1997,
+ 1997, 1997, 1997, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 1999, 1999,
+ 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999,
+ 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999,
+ 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999,
+
+ 2000, 2001, 2001, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 1499, 2001, 2001, 2001, 2001, 2001, 2001,
+ 2001, 2001, 2001, 193, 193, 193, 193, 193,
+ 1499, 1499, 1499, 1499, 1499, 1499, 1499, 1499,
+ 1499, 193, 193, 193, 193, 193, 193, 193,
+ 2001, 2001, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1497, 1497, 1497,
- 1497, 1497, 1497, 1497, 1497, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
-
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991,
- 1991, 1991, 1991, 1991, 1991, 1991, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 193, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1325, 1325, 1326,
+ 1326, 1326, 1326, 1326, 1325, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 193, 1326, 1326,
+ 1326, 1326, 1326, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 193,
+ 1326, 193, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1325, 1326, 1325, 1326, 1325, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1325,
+ 1326, 1325, 1325, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 193, 1326, 1326, 1326, 1326, 193, 193, 193,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
-
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1992, 1992,
- 1992, 1992, 1992, 1992, 1992, 1992, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 193, 193,
+ 2002, 2002, 2002, 2002, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 1326, 1326, 1326, 1326, 1326,
+
+ 2003, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 2003, 1326, 1326, 1326, 2003, 1326, 2003,
+ 1326, 2003, 1326, 2003, 1326, 1326, 1326, 2003,
+ 1326, 1326, 1326, 1326, 1326, 1326, 2003, 2003,
+ 1326, 1326, 1326, 1326, 2003, 1326, 2003, 2003,
+ 1326, 1326, 1326, 1326, 2003, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 193, 193, 193, 193, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 1326, 1326,
+ 1326, 1326, 1326, 1326, 1326, 1326, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493,
- 1493, 1493, 1493, 1493, 1493, 1493, 1989, 1989,
-
- 1224, 1946, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1946, 1946, 1946, 1946, 1946, 1946, 1946, 1946,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
-
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1993, 1993, 1993, 1993, 1993, 1993, 1993, 1993,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
-
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
- 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224,
-
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
-
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1994, 1994,
- 1994, 1994, 1994, 1994, 1994, 1994, 1989, 1989,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1325, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 2004, 2004,
+
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 2005,
+ 2005, 2005, 2005, 2005, 2005, 2005, 2005, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1510, 1510, 1510,
+ 1510, 1510, 1510, 1510, 1510, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 2006, 2006,
+ 2006, 2006, 2006, 2006, 2006, 2006, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007,
+ 2007, 2007, 2007, 2007, 2007, 2007, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506,
+ 1506, 1506, 1506, 1506, 1506, 1506, 2004, 2004,
+
+ 1230, 1961, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1961, 1961, 1961, 1961, 1961, 1961, 1961, 1961,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230,
+
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009,
+ 2009, 2009, 2009, 2009, 2009, 2009, 2004, 2004,
};
#define GET_PROP_INDEX(ucs4) \
@@ -4913,41 +4918,41 @@ static const Properties uc_properties[] = {
{ 9, 8, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 21, 2 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 5, 32, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 13, 3, 2 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 13, 3, 2 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
{ 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 11, 8, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 11, 8, 2 },
{ 20, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 16, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 10, 8, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 10, 8, 2 },
{ 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 7, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
{ 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 0, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 0, 8, 2 },
{ 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
{ 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
{ 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 2, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 15, 0, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
{ 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
{ 9, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
@@ -4956,645 +4961,647 @@ static const Properties uc_properties[] = {
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
{ 23, 10, 0, 0, -1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 17, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 17, 2 },
{ 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
{ 26, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 9, 2 },
{ 5, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 5, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 18, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 743, 743, 775, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 743, 743, 775, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 2 },
{ 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 24, 10, 0, 0, -1, -16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 16, 13, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 19, 0, 0, 0, 1, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -232, -232, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 98, 98, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -121, 0, 0, -121, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -300, -300, -268, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 195, 195, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 210, 0, 0, 210, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 206, 0, 0, 206, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 205, 0, 0, 205, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 79, 0, 0, 79, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 202, 0, 0, 202, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 203, 0, 0, 203, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 207, 0, 0, 207, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 97, 97, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 211, 0, 0, 211, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 209, 0, 0, 209, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 213, 0, 0, 213, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 214, 0, 0, 214, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 218, 0, 0, 218, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 217, 0, 0, 217, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 219, 0, 0, 219, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 56, 56, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 2, 0, 1, 2, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
- { 16, 0, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -2, -1, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -79, -79, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 109, 109, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -97, 0, 0, -97, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -56, 0, 0, -56, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 10795, 0, 0, 10795, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -163, 0, 0, -163, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 10792, 0, 0, 10792, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10815, 10815, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -195, 0, 0, -195, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 69, 0, 0, 69, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 71, 0, 0, 71, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10783, 10783, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10780, 10780, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10782, 10782, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -210, -210, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -206, -206, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -205, -205, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -202, -202, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -203, -203, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -207, -207, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 3, 3, 0, 0, 1, 1, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -209, -209, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -211, -211, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10743, 10743, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10749, 10749, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -213, -213, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -214, -214, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 10727, 10727, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -218, -218, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -69, -69, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -217, -217, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -71, -71, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -219, -219, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 18, 2 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 16, 13, 0, 0, 1, 1, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 19, 0, 0, 0, 1, 0, 0, 0, 1, 17, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -232, -232, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 98, 98, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -121, 0, 0, -121, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -300, -300, -268, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 195, 195, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 210, 0, 0, 210, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 206, 0, 0, 206, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 205, 0, 0, 205, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 79, 0, 0, 79, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 202, 0, 0, 202, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 203, 0, 0, 203, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 207, 0, 0, 207, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 97, 97, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 211, 0, 0, 211, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 209, 0, 0, 209, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 213, 0, 0, 213, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 214, 0, 0, 214, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 218, 0, 0, 218, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 217, 0, 0, 217, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 219, 0, 0, 219, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 56, 56, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 2, 0, 1, 2, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 3 },
+ { 16, 0, 0, 0, -1, 0, 1, -1, 0, 1, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -2, -1, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -79, -79, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 109, 109, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -97, 0, 0, -97, 0, 0, 0, 0, 4, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -56, 0, 0, -56, 0, 0, 0, 0, 4, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 6, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 10795, 0, 0, 10795, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -163, 0, 0, -163, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 10792, 0, 0, 10792, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10815, 10815, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -195, 0, 0, -195, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 69, 0, 0, 69, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 71, 0, 0, 71, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10783, 10783, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10780, 10780, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10782, 10782, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -210, -210, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -206, -206, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -205, -205, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -202, -202, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -203, -203, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -207, -207, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 3, 3, 0, 0, 1, 1, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -209, -209, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -211, -211, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10743, 10743, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10749, 10749, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -213, -213, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -214, -214, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 10727, 10727, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -218, -218, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -69, -69, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -217, -217, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -71, -71, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -219, -219, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 18, 2 },
+ { 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 36 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 4, 4, 4, 21, 1 },
- { 0, 17, 240, 0, -1, 0, 0, 84, 84, 116, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 232, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 4 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 2 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 232, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 216, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 4, 4, 4, 21, 1 },
+ { 0, 17, 240, 5, -1, 0, 0, 84, 84, 116, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 232, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 8, 6, 12, 4 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 4 },
{ 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 4 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 10, 0, 8, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 4 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 13, 0, 8, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 4 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 38, 0, 0, 38, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 9, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 37, 0, 0, 37, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 64, 0, 0, 64, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 63, 0, 0, 63, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -38, -38, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -37, -37, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -31, -31, 1, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -64, -64, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -63, -63, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 8, 0, 0, 8, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -62, -62, -30, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -57, -57, -25, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -47, -47, -15, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -54, -54, -22, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -8, -8, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -86, -86, -54, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, -48, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -60, 0, 0, -60, 0, 0, 0, 0, 5, 80, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -96, -96, -64, 0, 0, 0, 0, 5, 80, 0, 7, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 38, 0, 0, 38, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 12, 0, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 37, 0, 0, 37, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 64, 0, 0, 64, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 63, 0, 0, 63, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -38, -38, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -37, -37, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -31, -31, 1, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -64, -64, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -63, -63, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 8, 0, 0, 8, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -62, -62, -30, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -57, -57, -25, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -47, -47, -15, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -54, -54, -22, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -8, -8, 0, 0, 0, 0, 0, 4, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -86, -86, -54, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, -48, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -60, 0, 0, -60, 0, 0, 0, 0, 5, 80, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -96, -96, -64, 0, 0, 0, 0, 5, 80, 0, 8, 6, 12, 4 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 7, 0, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 7, 80, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 7, 0, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 7, 80, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -130, 0, 0, -130, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 4, 17, 0, 8, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 80, 0, 0, 80, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 4, 17, 0, 8, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -80, -80, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 5 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 15, 0, 0, 15, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -15, -15, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 7, 7, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 5 },
- { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 6 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 6 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 5 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
+ { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 6, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 15, 0, 0, 15, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -15, -15, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 17, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 4, 17, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 8, 7, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 8, 6, 12, 5 },
+ { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 6 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 6 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 6 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 12, 6 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 1, 0, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 65, 62, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
- { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 12, 8, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 1, 0, 0, 8, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 65, 62, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
+ { 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 12, 8, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 6 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 9, 6 },
{ 13, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 10, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 11, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 12, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 13, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 14, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 15, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 16, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 17, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 19, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 20, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 21, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 22, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 10, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 11, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 12, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 13, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 14, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 15, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 16, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 17, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 18, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 19, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 19, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 20, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 21, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 22, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
{ 20, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 7 },
- { 0, 17, 23, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 23, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 7 },
- { 0, 17, 24, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
- { 0, 17, 25, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 24, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 25, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 7 },
- { 0, 17, 18, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 18, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 7 },
{ 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 13, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 7 },
- { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 12, 7 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 7 },
+ { 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 12, 7 },
+ { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 3, 4, 4, 12, 8 },
+ { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 3, 4, 4, 12, 8 },
{ 13, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
{ 26, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 8 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 8 },
{ 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10, 8 },
- { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 10, 11, 8, 8 },
+ { 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 13, 11, 8, 8 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 30, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 31, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 32, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 2 },
+ { 10, 13, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 2 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 8 },
- { 17, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 2 },
- { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 30, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 31, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 32, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 33, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 34, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 8 },
- { 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
- { 3, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 2 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 8 },
+ { 17, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 2 },
+ { 0, 17, 27, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 28, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 29, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 30, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 31, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 32, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 33, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 34, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 8 },
+ { 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
+ { 3, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 2 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 9, 11, 8 },
+ { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 25, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 9, 11, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 8 },
- { 0, 17, 35, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 8 },
+ { 0, 17, 35, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 6, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
- { 10, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
+ { 10, 5, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
- { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 8 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 8 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 8 },
+ { 17, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 8 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 8 },
{ 29, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 8 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 8 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 9 },
{ 25, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 9 },
- { 10, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 9 },
- { 0, 17, 36, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 9 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 9 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 10 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 10 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 10 },
- { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 66 },
- { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
+ { 10, 13, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 12, 9 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 9 },
+ { 0, 17, 36, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 9 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 9 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 9 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 9 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 10 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 10 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 10 },
+ { 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 3, 1, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 66 },
+ { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 66 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 66 },
+ { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 66 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 66 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 10, 11, 8, 66 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 13, 11, 8, 66 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 66 },
- { 17, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 66 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 82 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 82 },
- { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 82 },
+ { 17, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 66 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 82 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 82 },
+ { 17, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 82 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 82 },
- { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
- { 18, 1, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 95 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 95 },
+ { 18, 1, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 95 },
+ { 18, 1, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 95 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 95 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 95 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 95 },
- { 18, 13, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 8 },
- { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 8 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 28, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 29, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 18, 13, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 8 },
+ { 18, 13, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 8 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 27, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 28, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 29, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 8 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 12, 11 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 11 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 11 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 11 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 11 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 11 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 11 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 11 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 17, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 11 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 11 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 11 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 11 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 11 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 11 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 11 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 12 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 12 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 12 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 12 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 12 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 12 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 12 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 12 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 12 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 12 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 12 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 12 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 12 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 12 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 13 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 4, 4, 21, 13 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 13 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 13 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 13 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 13 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 13 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 13 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 13 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 13 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 13 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 13 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 14 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 14 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 14 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 14 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 14 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 14 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 14 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 14 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 14 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 14 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 14 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 15 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 15 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 15 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 15 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 15 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 12, 15 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 15 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 15 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 15 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 8, 8, 12, 15 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 15 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 15 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 15 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 7, 8, 12, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 16 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 8, 8, 12, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 16 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 16 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 16 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 16 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 16 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 16 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 16 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 16 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 16 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 16 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 16 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 9, 16 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 17 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 17 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 4, 4, 21, 17 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 84, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
- { 0, 17, 91, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 17 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 17 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 17 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 17 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 17 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 4, 4, 21, 17 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 84, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 17 },
+ { 0, 17, 91, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 17 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 17 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 17 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 17 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 18 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 18 },
- { 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 18 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 18 },
+ { 0, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 18 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 18 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 18 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 18 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 18 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 18 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 18 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 18 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 4, 4, 21, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 19 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 19 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 19 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 19 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 19 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 7, 4, 4, 21, 19 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 19 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 19 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 19 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 19 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 19 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 21, 20 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 20 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 20 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 21, 20 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 20 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 20 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 7, 4, 4, 21, 20 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 20 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 21 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 7, 0, 8, 30, 21 },
- { 0, 17, 103, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 0, 17, 103, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 21 },
- { 0, 17, 107, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
+ { 0, 17, 107, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 21 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 21 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 21 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 21 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 21 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 22 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 7, 0, 8, 30, 22 },
- { 0, 17, 118, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 0, 17, 118, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 30, 22 },
- { 0, 17, 122, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 9, 11, 22 },
+ { 0, 17, 122, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 30, 22 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 14, 9, 11, 22 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 8, 30, 22 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 30, 22 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 7, 8, 12, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 8, 8, 12, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 23 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
@@ -5603,41 +5610,41 @@ static const Properties uc_properties[] = {
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 0, 0, 0, 4, 23 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 6, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 11, 9, 11, 23 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 14, 9, 11, 23 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 23 },
- { 0, 17, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 216, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 0, 23 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 13, 1, 23 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 0, 7, 8, 12, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 23 },
- { 0, 17, 129, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 130, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 4, 4, 4, 21, 23 },
- { 0, 17, 132, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 0, 8, 8, 12, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 23 },
+ { 0, 17, 129, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 130, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 85, 4, 4, 4, 21, 23 },
+ { 0, 17, 132, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 80, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 7, 4, 4, 17, 23 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 23 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 4, 4, 21, 23 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 23 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 23 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 23 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 23 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 18, 23 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 23 },
@@ -5650,60 +5657,60 @@ static const Properties uc_properties[] = {
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 17, 0, 0, 8, 30, 24 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 4, 4, 30, 24 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 30, 24 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 204, 4, 4, 4, 30, 24 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 30, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 24 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 24 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 17, 24 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 24 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 24 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 30, 24 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 24 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 30, 24 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 24 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 24 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 30, 24 },
- { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 25 },
- { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 25 },
+ { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 25 },
+ { 14, 0, 0, 0, -1, 0, 7264, 0, 0, 7264, 0, 0, 0, 0, 13, 0, 0, 8, 7, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 25 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 7, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 7, 8, 25, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 7, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 9, 7, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 9, 7, 8, 26, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 10, 7, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 7, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 10, 7, 8, 27, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 27 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 27 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 27 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 8, 8, 8, 25, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 8, 8, 8, 25, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 9, 8, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 9, 8, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 9, 8, 8, 26, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 10, 8, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 10, 8, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 10, 8, 8, 27, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 27 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 27 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 27 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 27 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 27 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 27 },
@@ -5719,50 +5726,50 @@ static const Properties uc_properties[] = {
{ 5, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 27 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 28 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 28 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 29 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 29 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 29 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 12, 29 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 29 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 29 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 17, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 30 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 30 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 0, 30 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 13, 1, 30 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 31 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 31 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 31 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 42 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 43 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 31 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 42 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 42 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 43 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 43 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 12, 17, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 44 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 44 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 45 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 45 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 44 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 44 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 45 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 45 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 32 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 7, 4, 4, 30, 32 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 30, 32 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 32 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5, 32 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 30, 32 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 32 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 9, 32 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 30, 32 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 32 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 30, 32 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 32 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 2 },
@@ -5770,339 +5777,343 @@ static const Properties uc_properties[] = {
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 33 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 33 },
+ { 25, 10, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 11, 6, 33 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 12, 6, 33 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 4, 33 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 11, 9, 11, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 33 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 12, 33 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 33 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 47 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 25, 10, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 33 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 4, 33 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 14, 9, 11, 33 },
+ { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 33 },
+ { 17, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 33 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 12, 33 },
+ { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 33 },
+ { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 33 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 47 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 4, 4, 21, 47 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 47 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 47 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 12, 6, 47 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 47 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 47 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 8, 30, 48 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 30, 56 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 56 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 4, 4, 30, 56 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 30, 56 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 9, 11, 56 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 14, 9, 11, 56 },
{ 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 56 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 30, 56 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 32 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 55 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 55 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 21, 55 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 55 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 55 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 78 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 30, 78 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 4, 4, 30, 78 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 78 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 78 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 78 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 78 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 78 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 78 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 78 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 30, 78 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 4, 4, 21, 62 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 62 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 0, 7, 8, 12, 62 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 62 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 0, 8, 8, 12, 62 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 204, 7, 4, 4, 21, 62 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 17, 7, 4, 4, 21, 62 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 7, 4, 4, 21, 62 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 11, 9, 11, 62 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 14, 9, 11, 62 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 17, 62 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 62 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 62 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 67 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 62 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 67 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 67 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 67 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 67 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 67 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 67 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 67 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 93 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 67 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 93 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 93 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 93 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 93 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 93 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 68 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 68 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 68 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 68 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 68 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 69 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 69 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 69 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 68 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 69 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 69 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 69 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 69 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 67 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 1 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 2 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 2 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 2 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 1 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 5 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 4 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 5 },
- { 15, 0, 0, 0, -1, 0, 0, 5, 5, 0, 0, 1, 1, 0, 8, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 3814, 3814, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 4 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 234, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 214, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 202, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 233, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 1 },
- { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 115, 115, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 118, 118, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 124, 124, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -59, -59, -58, 0, 0, 0, 0, 2, 81, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -7615, 0, 0, -7615, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 8, 8, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -8, 0, 0, -8, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 127, 127, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 134, 134, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 138, 138, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 176, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 179, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 182, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 185, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 188, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 191, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 194, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 197, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 176, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 179, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 182, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 185, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 188, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 191, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 194, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 197, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 200, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 203, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 206, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 209, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 212, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 215, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 218, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 221, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 200, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 203, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 206, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 209, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 212, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 215, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 218, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 221, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 224, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 227, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 230, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 233, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 236, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 239, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 242, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 245, 8, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 224, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 227, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 230, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 233, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 236, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 239, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 242, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -8, 245, 0, -8, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 260, 257, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 248, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 266, 263, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 142, 142, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 297, 293, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 248, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, -7205, -7205, -7173, 0, 0, 0, 0, 1, 85, 0, 7, 6, 12, 4 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 1 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 5 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 8, 6, 12, 4 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 6, 12, 5 },
+ { 15, 0, 0, 0, -1, 0, 0, 5, 5, 0, 0, 1, 1, 0, 8, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 3814, 3814, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 6, 12, 4 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 234, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 214, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 202, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 233, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 1 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 115, 115, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 118, 118, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 121, 121, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 124, 124, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -59, -59, -58, 0, 0, 0, 0, 2, 81, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -7615, 0, 0, -7615, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 10, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 8, 8, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -8, 0, 0, -8, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 127, 127, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 130, 130, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 134, 134, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 138, 138, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 74, 74, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 86, 86, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 100, 100, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 128, 128, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 112, 112, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 126, 126, 0, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 176, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 179, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 182, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 185, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 188, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 191, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 194, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 197, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 176, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 179, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 182, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 185, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 188, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 191, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 194, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 197, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 200, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 203, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 206, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 209, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 212, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 215, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 218, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 221, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 200, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 203, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 206, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 209, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 212, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 215, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 218, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 221, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 224, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 227, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 230, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 233, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 236, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 239, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 242, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 245, 8, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 224, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 227, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 230, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 233, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 236, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 239, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 242, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -8, 245, 0, -8, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 260, 257, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 248, 9, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 266, 263, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 142, 142, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 297, 293, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -74, 0, 0, -74, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 248, 0, -9, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, -7205, -7205, -7173, 0, 0, 0, 0, 1, 85, 0, 8, 6, 12, 4 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 81, 0, 0, 0, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 272, 269, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 251, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 278, 275, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 145, 145, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 305, 301, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 251, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 148, 148, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 152, 152, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 155, 155, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 159, 159, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 85, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 166, 166, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 169, 169, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 272, 269, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 251, 9, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 278, 275, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 145, 145, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 305, 301, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -86, 0, 0, -86, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 251, 0, -9, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 148, 148, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 101, 101, 0, 0, 1, 1, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 152, 152, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 155, 155, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -100, 0, 0, -100, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 159, 159, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 105, 105, 0, 0, 1, 1, 0, 1, 85, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 163, 163, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 166, 166, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 169, 169, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -112, 0, 0, -112, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -7, 0, 0, -7, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 284, 281, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 254, 9, 0, 0, 1, 0, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 290, 287, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 173, 173, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 15, 0, 0, 0, -1, 0, 0, 313, 309, 0, 0, 1, 1, 0, 1, 17, 0, 7, 6, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 16, 0, 0, 0, -1, 0, -9, 254, 0, -9, 0, 1, 0, 0, 1, 17, 0, 7, 7, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 284, 281, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 254, 9, 0, 0, 1, 0, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 290, 287, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 173, 173, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 15, 0, 0, 0, -1, 0, 0, 313, 309, 0, 0, 1, 1, 0, 1, 17, 0, 8, 6, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -128, 0, 0, -128, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -126, 0, 0, -126, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 16, 0, 0, 0, -1, 0, -9, 254, 0, -9, 0, 1, 0, 0, 1, 17, 0, 8, 7, 12, 4 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 0, 18, 4 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 5, 17, 2 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 17, 2 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 4, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 10, 18, 0, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
- { 10, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 4, 20, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 10, 18, 0, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 1, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 17, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 4, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 17, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 19, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
- { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 13, 3, 2 },
+ { 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 13, 3, 2 },
+ { 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 11, 13, 3, 2 },
{ 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 2 },
{ 23, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
{ 24, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 10, 15, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 11, 10, 15, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 15, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 9, 0, 17, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 12, 0, 17, 2 },
{ 7, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
{ 8, 7, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 35, 2 },
- { 10, 11, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
- { 10, 14, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
- { 10, 16, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
- { 10, 12, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
- { 10, 15, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 11, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 14, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 16, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 12, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 15, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
{ 6, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 5, 4, 2 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 2 },
@@ -6111,7 +6122,7 @@ static const Properties uc_properties[] = {
{ 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 3, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 5, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 5, 2 },
- { 26, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 10, 0, 8, 2 },
+ { 26, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 13, 0, 8, 2 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 12, 5, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 12, 5, 2 },
@@ -6119,18 +6130,22 @@ static const Properties uc_properties[] = {
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 12, 0, 12, 2 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 15, 0, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
{ 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 5, 17, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 22, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 12, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 4, 4, 12, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 22, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 4, 4, 12, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 3, 4, 4, 12, 2 },
+ { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 12, 0 },
+ { 10, 19, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 20, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 21, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 22, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 3, 4, 4, 21, 2 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 21, 2 },
{ 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 6, 12, 3 },
{ 5, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 5, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 5, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
@@ -6141,7 +6156,7 @@ static const Properties uc_properties[] = {
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 7, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 8, 6, 12, 3 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 9, 2 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 9, 2 },
@@ -6152,40 +6167,41 @@ static const Properties uc_properties[] = {
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 9, 2 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 9, 2 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 9, 2 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
+ { 13, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0 },
+ { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 4, 21, 1 },
+ { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 1 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 9, 2 },
- { 14, 0, 0, 0, -1, 0, -7517, 0, 0, -7517, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 4 },
- { 14, 0, 0, 0, -1, 0, -8383, 0, 0, -8383, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -8262, 0, 0, -8262, 0, 0, 0, 0, 1, 85, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -7517, 0, 0, -7517, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 4 },
+ { 14, 0, 0, 0, -1, 0, -8383, 0, 0, -8383, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -8262, 0, 0, -8262, 0, 0, 0, 0, 1, 85, 0, 8, 7, 12, 3 },
{ 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 28, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 7, 7, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 7, 6, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 28, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 8, 7, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 8, 6, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 6, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 7, 7, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 6, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 6, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 8, 7, 12, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -28, -28, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -28, -28, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 3 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
- { 4, 0, 0, 0, -1, 0, 16, 0, 0, 16, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, -16, -16, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 12, 3 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 16, 0, 0, 16, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, -16, -16, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 12, 3 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 3 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 2 },
@@ -6207,6 +6223,8 @@ static const Properties uc_properties[] = {
{ 26, 10, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
+ { 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 12, 2 },
+ { 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 13, 1, 2 },
@@ -6228,8 +6246,8 @@ static const Properties uc_properties[] = {
{ 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 5, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 26, 0, 0, 26, 0, 0, 0, 0, 1, 80, 0, 7, 7, 12, 2 },
- { 29, 0, 0, 0, -1, 0, 0, -26, -26, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 26, 0, 0, 26, 0, 0, 0, 0, 1, 80, 0, 8, 7, 12, 2 },
+ { 29, 0, 0, 0, -1, 0, 0, -26, -26, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 12, 2 },
{ 5, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 2 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
@@ -6288,39 +6306,39 @@ static const Properties uc_properties[] = {
{ 26, 10, 0, 0, -1, -2104, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, -2106, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, -2108, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 57 },
- { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 57 },
- { 14, 0, 0, 0, -1, 0, -10743, 0, 0, -10743, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -3814, 0, 0, -3814, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10727, 0, 0, -10727, 0, 0, 0, 0, 9, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -10795, -10795, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -10792, -10792, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10780, 0, 0, -10780, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10749, 0, 0, -10749, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10783, 0, 0, -10783, 0, 0, 0, 0, 10, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10782, 0, 0, -10782, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 6, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 80, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, -10815, 0, 0, -10815, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 46 },
+ { 14, 0, 0, 0, -1, 0, 48, 0, 0, 48, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 57 },
+ { 15, 0, 0, 0, -1, 0, 0, -48, -48, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 57 },
+ { 14, 0, 0, 0, -1, 0, -10743, 0, 0, -10743, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -3814, 0, 0, -3814, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10727, 0, 0, -10727, 0, 0, 0, 0, 9, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -10795, -10795, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -10792, -10792, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10780, 0, 0, -10780, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10749, 0, 0, -10749, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10783, 0, 0, -10783, 0, 0, 0, 0, 10, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10782, 0, 0, -10782, 0, 0, 0, 0, 11, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 6, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 80, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, -10815, 0, 0, -10815, 0, 0, 0, 0, 11, 0, 0, 8, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 8, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 46 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 7, 6, 12, 46 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 46 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 46 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 8, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 11, 0, 0, 8, 6, 12, 46 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 46 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 8, 7, 12, 46 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 8, 6, 12, 46 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 6, 46 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 46 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 46 },
- { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 8, 0, 0, 7, 6, 12, 25 },
- { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 25 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 58 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 58 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 7, 8, 12, 58 },
+ { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 8, 0, 0, 8, 6, 12, 25 },
+ { 15, 0, 0, 0, -1, 0, 0, -7264, -7264, 0, 0, 0, 0, 0, 13, 0, 0, 8, 6, 12, 25 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 58 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 58 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 8, 8, 12, 58 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 17, 58 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 58 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 58 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
{ 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
{ 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 13, 3, 2 },
@@ -6332,7 +6350,7 @@ static const Properties uc_properties[] = {
{ 23, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
{ 24, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 13, 3, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 2 },
@@ -6340,31 +6358,31 @@ static const Properties uc_properties[] = {
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 37 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 0, 14, 37 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 2 },
- { 6, 9, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 5, 14, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 11, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 5, 37 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 5, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 2 },
{ 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 37 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 5, 2 },
{ 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 13, 1, 2 },
- { 0, 17, 218, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 228, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 222, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 218, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 228, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 222, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 1 },
{ 1, 0, 224, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 26 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 14, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 21, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 80, 0, 0, 8, 14, 37 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 5, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 5, 2 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 5, 37 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 5, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 2 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 14, 34 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 14, 34 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 8, 5, 34 },
- { 0, 17, 8, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
+ { 0, 17, 8, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 204, 4, 4, 4, 21, 1 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 0, 5, 2 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 5, 34 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 0, 8, 5, 34 },
@@ -6378,14 +6396,14 @@ static const Properties uc_properties[] = {
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 6, 8, 5, 35 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 0, 6, 8, 5, 35 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 6, 8, 14, 35 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 14, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 14, 26 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 14, 2 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 14, 36 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 14, 36 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 14, 36 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 6, 8, 5, 35 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 26 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 0, 14, 26 },
@@ -6402,165 +6420,167 @@ static const Properties uc_properties[] = {
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 8, 14, 37 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 14, 38 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 7, 8, 5, 38 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 14, 38 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 8, 5, 38 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 14, 38 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 14, 38 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 83 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 83 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 83 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 83 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 83 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 83 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 70 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 70 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 70 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 70 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 70 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 6, 70 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 70 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 70 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 5 },
- { 2, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 70 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 5 },
+ { 2, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 5 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 5 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 5 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 5 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 84 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 84 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 84 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 5 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 5 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 84 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 84 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 84 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 84 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 84 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 84 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 2 },
- { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 2 },
+ { 17, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 7, 0, 0, 7, 1, 0, 0, 1, 10, 0, 0, 7, 7, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 7, 0, 0, 7, 1, 0, 0, 1, 10, 0, 0, 8, 7, 12, 3 },
{ 28, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 9, 0, 0, 9, 1, 0, 0, 1, 12, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 7, 7, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 7, 6, 12, 3 },
- { 14, 0, 0, 0, -1, 0, 11, 0, 0, 11, 1, 0, 0, 1, 13, 0, 0, 7, 7, 12, 3 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 7, 6, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 3 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 59 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
+ { 14, 0, 0, 0, -1, 0, 9, 0, 0, 9, 1, 0, 0, 1, 12, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 12, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 12, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 13, 0, 0, 8, 7, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0, 0, 0, 13, 0, 0, 8, 6, 12, 3 },
+ { 14, 0, 0, 0, -1, 0, 11, 0, 0, 11, 1, 0, 0, 1, 13, 0, 0, 8, 7, 12, 3 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 8, 6, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 3 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 59 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 59 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 7, 4, 4, 21, 59 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 59 },
{ 29, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 65 },
+ { 18, 0, 0, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 65 },
+ { 18, 0, 0, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 65 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 65 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 18, 65 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 12, 6, 65 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 71 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 71 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 71 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 71 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 71 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 71 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 71 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 71 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 11 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 11 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 72 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 72 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 72 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 72 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 17, 72 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 72 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 73 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 73 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 73 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 73 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 73 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 73 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 73 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 85 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 85 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 85 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 85 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 85 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 85 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 85 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 85 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 85 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 77 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 77 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 2 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 85 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 77 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 4, 4, 4, 21, 77 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 7, 4, 4, 21, 77 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 11, 9, 11, 77 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 14, 9, 11, 77 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 77 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 12, 17, 77 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 24 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 24 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 24 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 79 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 30, 79 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 8, 30, 79 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 30, 79 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 86 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 86 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 86 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 86 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 86 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 27 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 86 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 86 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 86 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 27 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 86 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 86 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 86 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 11, 9, 11, 86 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 11, 7, 8, 23, 26 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 12, 7, 8, 24, 26 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 86 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 9, 11, 86 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 11, 8, 8, 23, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17, 12, 8, 8, 24, 26 },
{ 11, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 0, 31, 0 },
{ 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 0, 8, 14, 37 },
@@ -6568,48 +6588,48 @@ static const Properties uc_properties[] = {
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 85, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 85, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 85, 0, 0, 8, 14, 37 },
- { 15, 0, 0, 0, -1, 0, 0, 25, 22, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 31, 28, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 37, 34, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 44, 40, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 52, 48, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 59, 56, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 3 },
- { 15, 0, 0, 0, -1, 0, 0, 71, 68, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 77, 74, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 83, 80, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 89, 86, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
- { 15, 0, 0, 0, -1, 0, 0, 95, 92, 0, 0, 1, 1, 0, 1, 80, 0, 7, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 25, 22, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 31, 28, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 37, 34, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 44, 40, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 52, 48, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 59, 56, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, 71, 68, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 77, 74, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 83, 80, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 89, 86, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
+ { 15, 0, 0, 0, -1, 0, 0, 95, 92, 0, 0, 1, 1, 0, 1, 80, 0, 8, 6, 12, 6 },
{ 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 85, 0, 7, 8, 13, 7 },
- { 0, 17, 26, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
+ { 0, 17, 26, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 4, 4, 21, 7 },
{ 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 85, 0, 7, 8, 13, 7 },
{ 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 13, 7 },
{ 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 12, 7 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 8 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 12, 8 },
{ 28, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 8 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 0 },
+ { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 0 },
{ 27, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 0, 10, 8 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 11, 8, 2 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 4, 4, 4, 21, 1 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 13, 11, 8, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 11, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 9, 11, 8, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 10, 0, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 12, 11, 8, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 13, 0, 8, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 6, 2 },
{ 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 13, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 0, 0, 0, 15, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 20, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
- { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 12, 0, 14, 2 },
+ { 19, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 15, 0, 14, 2 },
{ 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
{ 21, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 0, 13, 1, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 11, 1, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 13, 11, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 11, 14, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 10, 1, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 10, 0, 5, 2 },
- { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 9, 11, 5, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 11, 10, 1, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 13, 0, 5, 2 },
+ { 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 12, 11, 5, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 6, 2 },
{ 25, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 26, 3, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
@@ -6617,9 +6637,9 @@ static const Properties uc_properties[] = {
{ 26, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 26, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 7, 8, 12, 8 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 22, 2 },
- { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 0, 14, 2 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 8, 12, 8 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 4, 4, 22, 2 },
+ { 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 11, 0, 14, 2 },
{ 25, 6, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
@@ -6633,11 +6653,11 @@ static const Properties uc_properties[] = {
{ 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 26, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
{ 26, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 80, 0, 7, 7, 14, 3 },
+ { 14, 0, 0, 0, -1, 0, 32, 0, 0, 32, 0, 0, 0, 0, 1, 80, 0, 8, 7, 14, 3 },
{ 21, 10, 0, 0, -1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 13, 1, 2 },
{ 28, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 14, 2 },
- { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 80, 0, 7, 6, 14, 3 },
+ { 15, 0, 0, 0, -1, 0, 0, -32, -32, 0, 0, 0, 0, 0, 1, 80, 0, 8, 6, 14, 3 },
{ 21, 10, 0, 0, -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 0, 2 },
{ 22, 10, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 80, 0, 0, 13, 1, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 12, 1, 2 },
@@ -6647,64 +6667,64 @@ static const Properties uc_properties[] = {
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 8, 5, 35 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 6, 8, 5, 2 },
{ 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 4, 4, 4, 5, 2 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 7, 8, 12, 26 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 8, 8, 12, 26 },
{ 27, 4, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 80, 0, 0, 0, 10, 2 },
- { 10, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 21, 2 },
+ { 10, 10, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 4, 4, 21, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 29, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 49 },
+ { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 12, 0 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 49 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 2 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 12, 2 },
- { 4, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 4 },
+ { 4, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 4 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 4 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 74 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 75 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 39 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 74 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 75 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 8, 8, 12, 39 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 39 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 40 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 7, 8, 12, 40 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 50 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 8, 8, 12, 40 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 8, 8, 12, 40 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 50 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 17, 50 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 60 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 60 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 60 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 60 },
- { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 5, 0, 0, 7, 7, 12, 41 },
- { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 7, 0, 0, 7, 7, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 5, 0, 0, 7, 6, 12, 41 },
- { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 7, 0, 0, 7, 6, 12, 41 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 51 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 52 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 11, 9, 11, 52 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 7, 8, 12, 53 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 87 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 60 },
+ { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 5, 0, 0, 8, 7, 12, 41 },
+ { 14, 0, 0, 0, -1, 0, 40, 0, 0, 40, 0, 0, 0, 0, 7, 0, 0, 8, 7, 12, 41 },
+ { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 5, 0, 0, 8, 6, 12, 41 },
+ { 15, 0, 0, 0, -1, 0, 0, -40, -40, 0, 0, 0, 0, 0, 7, 0, 0, 8, 6, 12, 41 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 51 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 52 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 14, 9, 11, 52 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 8, 8, 12, 53 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 87 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 87 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 87 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 64 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 64 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 64 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 64 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 64 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 7, 8, 12, 76 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 8, 8, 12, 76 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 12, 76 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 98 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 97 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 7, 8, 12, 61 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 98 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 97 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 8, 8, 12, 61 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 61 },
{ 5, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
{ 5, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
{ 5, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
@@ -6713,16 +6733,16 @@ static const Properties uc_properties[] = {
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 17, 61 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 12, 17, 61 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 12, 61 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 88 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 88 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
{ 25, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 88 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 80 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 80 },
{ 25, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 17, 80 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 89 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 89 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 89 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 90 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 90 },
{ 5, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 90 },
- { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 91 },
+ { 18, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 91 },
{ 5, 5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
{ 5, 5, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
{ 5, 5, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
@@ -6734,9 +6754,9 @@ static const Properties uc_properties[] = {
{ 5, 5, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
{ 5, 5, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 8 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 7, 4, 4, 21, 94 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 94 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 94 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 4, 4, 4, 21, 94 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 17, 94 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
{ 5, 10, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
@@ -6749,129 +6769,129 @@ static const Properties uc_properties[] = {
{ 5, 10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
{ 5, 10, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
{ 5, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 12, 94 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 11, 9, 11, 94 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 14, 9, 11, 94 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 7, 4, 4, 21, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 17, 0, 7, 8, 12, 92 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 204, 4, 4, 4, 21, 92 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 92 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 17, 0, 8, 8, 12, 92 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 4, 4, 4, 21, 92 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 204, 4, 4, 4, 21, 92 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 12, 92 },
- { 10, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 3, 4, 4, 12, 92 },
+ { 10, 0, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 3, 4, 4, 12, 92 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 12, 17, 92 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 101 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 101 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 204, 4, 4, 4, 21, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 101 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 101 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 96 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 204, 4, 4, 4, 21, 96 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 17, 4, 4, 4, 21, 96 },
- { 0, 17, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 96 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 17, 4, 4, 4, 21, 96 },
+ { 0, 17, 9, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 96 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 96 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 96 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 96 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 100 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 100 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 100 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 100 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 100 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 12, 17, 100 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 100 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 17, 100 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 100 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 102 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 100 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 102 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 102 },
{ 1, 0, 9, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 102 },
- { 0, 17, 7, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
- { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 11, 9, 11, 102 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 63 },
- { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 7, 8, 12, 63 },
+ { 0, 17, 7, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 102 },
+ { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 3, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 14, 9, 11, 102 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 63 },
+ { 4, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 8, 8, 12, 63 },
{ 25, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 17, 63 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 12, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 0, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 7, 8, 1, 81 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 7, 8, 12, 84 },
- { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 99 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 12, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 0, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 8, 8, 1, 81 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 8, 8, 12, 84 },
+ { 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 99 },
{ 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 7, 4, 4, 21, 99 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 99 },
- { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 7, 8, 12, 99 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 4, 4, 4, 21, 99 },
+ { 17, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 8, 8, 12, 99 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 6, 8, 14, 35 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 34 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 12, 2 },
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 0, 12, 2 },
{ 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 2 },
{ 1, 0, 216, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 4, 4, 21, 2 },
- { 0, 17, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 1, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
{ 1, 0, 226, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 7, 4, 4, 21, 2 },
- { 10, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 3, 4, 4, 21, 2 },
- { 0, 17, 220, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
- { 0, 17, 230, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 4 },
+ { 10, 18, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 3, 4, 4, 21, 2 },
+ { 0, 17, 220, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 230, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 4, 4, 4, 21, 4 },
{ 5, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 7, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 7, 6, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 7, 6, 12, 2 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 8, 7, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 8, 6, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 80, 0, 8, 6, 12, 2 },
{ 26, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 0, 0, 12, 2 },
- { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 7, 7, 12, 2 },
- { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 7, 6, 12, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 11, 9, 11, 2 },
- { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 7, 8, 12, 8 },
+ { 14, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 8, 7, 12, 2 },
+ { 15, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 80, 0, 8, 6, 12, 2 },
+ { 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 3, 2, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 80, 0, 14, 9, 11, 2 },
+ { 18, 13, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 80, 0, 8, 8, 12, 8 },
{ 26, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 8 },
{ 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
{ 5, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 80, 0, 0, 0, 12, 2 },
@@ -6892,11 +6912,11 @@ static const Properties uc_properties[] = {
{ 29, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 80, 0, 0, 0, 14, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 12, 2 },
{ 29, 10, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 14, 2 },
- { 13, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 },
+ { 13, 18, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 8, 14, 37 },
{ 18, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 85, 0, 0, 8, 14, 37 },
- { 0, 17, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
+ { 0, 17, 0, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 4, 4, 4, 21, 1 },
{ 12, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 12, 0 }
};
diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/tools/qunicodetables_p.h
index 08b8d58e70..ec9607b817 100644
--- a/src/corelib/tools/qunicodetables_p.h
+++ b/src/corelib/tools/qunicodetables_p.h
@@ -67,8 +67,8 @@ struct Properties {
ushort category : 8; /* 5 used */
ushort direction : 8; /* 5 used */
ushort combiningClass : 8;
- ushort joining : 2;
- signed short digitValue : 6; /* 5 used */
+ ushort joining : 3;
+ signed short digitValue : 5; /* 5 used */
signed short mirrorDiff : 16;
signed short lowerCaseDiff : 16;
signed short upperCaseDiff : 16;
@@ -114,7 +114,10 @@ enum WordBreakClass {
WordBreak_Extend,
WordBreak_RegionalIndicator,
WordBreak_Katakana,
+ WordBreak_HebrewLetter,
WordBreak_ALetter,
+ WordBreak_SingleQuote,
+ WordBreak_DoubleQuote,
WordBreak_MidNumLet,
WordBreak_MidLetter,
WordBreak_MidNum,
diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/tools/qunicodetools.cpp
index b3e55a5abc..fac795051a 100644
--- a/src/corelib/tools/qunicodetools.cpp
+++ b/src/corelib/tools/qunicodetools.cpp
@@ -57,7 +57,7 @@ namespace QUnicodeTools {
// -----------------------------------------------------------------------------------------------------
//
// The text boundaries determination algorithm.
-// See http://www.unicode.org/reports/tr29/tr29-21.html
+// See http://www.unicode.org/reports/tr29/tr29-23.html
//
// -----------------------------------------------------------------------------------------------------
@@ -112,26 +112,30 @@ static void getGraphemeBreaks(const ushort *string, quint32 len, QCharAttributes
namespace WB {
enum Action {
- NoBreak = 0,
- Break = 1,
- Lookup = 2
+ NoBreak,
+ Break,
+ Lookup,
+ LookupW
};
static const uchar breakTable[QUnicodeTables::WordBreak_ExtendNumLet + 1][QUnicodeTables::WordBreak_ExtendNumLet + 1] = {
-// Other CR LF Newline Extend RI Katakana ALetter MidNumLet MidLetter MidNum Numeric ExtendNumLet
- { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break }, // Other
- { Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // CR
- { Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // LF
- { Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // Newline
- { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break }, // Extend
- { Break , Break , Break , Break , NoBreak, NoBreak, Break , Break , Break , Break , Break , Break , Break }, // RegionalIndicator
- { Break , Break , Break , Break , NoBreak, Break , NoBreak, Break , Break , Break , Break , Break , NoBreak }, // Katakana
- { Break , Break , Break , Break , NoBreak, Break , Break , NoBreak, Lookup , Lookup , Break , NoBreak, NoBreak }, // ALetter
- { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break }, // MidNumLet
- { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break }, // MidLetter
- { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break }, // MidNum
- { Break , Break , Break , Break , NoBreak, Break , Break , NoBreak, Lookup , Break , Lookup , NoBreak, NoBreak }, // Numeric
- { Break , Break , Break , Break , NoBreak, Break , NoBreak, NoBreak, Break , Break , Break , NoBreak, NoBreak }, // ExtendNumLet
+// Other CR LF Newline Extend RI Katakana HLetter ALetter SQuote DQuote MidNumLet MidLetter MidNum Numeric ExtendNumLet
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // Other
+ { Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // CR
+ { Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // LF
+ { Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // Newline
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // Extend
+ { Break , Break , Break , Break , NoBreak, NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // RegionalIndicator
+ { Break , Break , Break , Break , NoBreak, Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , NoBreak }, // Katakana
+ { Break , Break , Break , Break , NoBreak, Break , Break , NoBreak, NoBreak, LookupW, Lookup , LookupW, LookupW, Break , NoBreak, NoBreak }, // HebrewLetter
+ { Break , Break , Break , Break , NoBreak, Break , Break , NoBreak, NoBreak, LookupW, Break , LookupW, LookupW, Break , NoBreak, NoBreak }, // ALetter
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // SingleQuote
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // DoubleQuote
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // MidNumLet
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // MidLetter
+ { Break , Break , Break , Break , NoBreak, Break , Break , Break , Break , Break , Break , Break , Break , Break , Break , Break }, // MidNum
+ { Break , Break , Break , Break , NoBreak, Break , Break , NoBreak, NoBreak, Lookup , Break , Lookup , Break , Lookup , NoBreak, NoBreak }, // Numeric
+ { Break , Break , Break , Break , NoBreak, Break , NoBreak, NoBreak, NoBreak, Break , Break , Break , Break , Break , NoBreak, NoBreak }, // ExtendNumLet
};
} // namespace WB
@@ -160,8 +164,8 @@ static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *at
if (qt_initcharattributes_default_algorithm_only) {
// as of Unicode 5.1, some punctuation marks were mapped to MidLetter and MidNumLet
// which caused "hi.there" to be treated like if it were just a single word;
- // by remapping those characters in the Unicode tables generator.
- // this code is needed to pass the coverage tests; remove once the issue is fixed.
+ // we keep the pre-5.1 behavior by remapping these characters in the Unicode tables generator
+ // and this code is needed to pass the coverage tests; remove once the issue is fixed.
if (ucs4 == 0x002E) // FULL STOP
ncls = QUnicodeTables::WordBreak_MidNumLet;
else if (ucs4 == 0x003A) // COLON
@@ -170,8 +174,17 @@ static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *at
#endif
uchar action = WB::breakTable[cls][ncls];
- if (Q_UNLIKELY(action == WB::Lookup)) {
- action = WB::Break;
+ switch (action) {
+ case WB::Break:
+ break;
+ case WB::NoBreak:
+ if (Q_UNLIKELY(ncls == QUnicodeTables::WordBreak_Extend)) {
+ // WB4: X(Extend|Format)* -> X
+ continue;
+ }
+ break;
+ case WB::Lookup:
+ case WB::LookupW:
for (quint32 lookahead = i + 1; lookahead < len; ++lookahead) {
ucs4 = string[lookahead];
if (QChar::isHighSurrogate(ucs4) && lookahead + 1 != len) {
@@ -184,20 +197,28 @@ static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *at
prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::WordBreakClass tcls = (QUnicodeTables::WordBreakClass) prop->wordBreakClass;
- if (Q_UNLIKELY(tcls == QUnicodeTables::WordBreak_Extend))
+
+ if (Q_UNLIKELY(tcls == QUnicodeTables::WordBreak_Extend)) {
+ // WB4: X(Extend|Format)* -> X
continue;
- if (Q_LIKELY(tcls == cls)) {
+ }
+
+ if (Q_LIKELY(tcls == cls || (action == WB::LookupW && (tcls == QUnicodeTables::WordBreak_HebrewLetter
+ || tcls == QUnicodeTables::WordBreak_ALetter)))) {
i = lookahead;
ncls = tcls;
action = WB::NoBreak;
}
break;
}
- } else if (Q_UNLIKELY(ncls == QUnicodeTables::WordBreak_Extend)) {
- // WB4: X(Extend|Format)* -> X
- if (Q_LIKELY(action != WB::Break))
- continue;
+ if (action != WB::NoBreak) {
+ action = WB::Break;
+ if (Q_UNLIKELY(ncls == QUnicodeTables::WordBreak_SingleQuote && cls == QUnicodeTables::WordBreak_HebrewLetter))
+ action = WB::NoBreak; // WB7a
+ }
+ break;
}
+
cls = ncls;
if (action == WB::Break) {
attributes[pos].wordBreak = true;
@@ -208,6 +229,7 @@ static void getWordBreaks(const ushort *string, quint32 len, QCharAttributes *at
currentWordType = WordTypeHiraganaKatakana;
attributes[pos].wordStart = true;
break;
+ case QUnicodeTables::WordBreak_HebrewLetter:
case QUnicodeTables::WordBreak_ALetter:
case QUnicodeTables::WordBreak_Numeric:
currentWordType = WordTypeAlphaNumeric;
@@ -327,7 +349,7 @@ static void getSentenceBreaks(const ushort *string, quint32 len, QCharAttributes
// -----------------------------------------------------------------------------------------------------
//
// The line breaking algorithm.
-// See http://www.unicode.org/reports/tr14/tr14-30.html
+// See http://www.unicode.org/reports/tr14/tr14-32.html
//
// -----------------------------------------------------------------------------------------------------
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index 309d2a2dca..bfa0bbbbb1 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -107,6 +107,10 @@ public:
inline int capacity() const { return a; }
inline void reserve(int size);
+ inline int indexOf(const T &t, int from = 0) const;
+ inline int lastIndexOf(const T &t, int from = -1) const;
+ inline bool contains(const T &t) const;
+
inline T &operator[](int idx) {
Q_ASSERT(idx >= 0 && idx < s);
return ptr[idx];
@@ -229,6 +233,51 @@ Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize)
{ if (asize > a) realloc(s, asize); }
template <class T, int Prealloc>
+Q_INLINE_TEMPLATE int QVarLengthArray<T, Prealloc>::indexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from = qMax(from + s, 0);
+ if (from < s) {
+ T *n = ptr + from - 1;
+ T *e = ptr + s;
+ while (++n != e)
+ if (*n == t)
+ return n - ptr;
+ }
+ return -1;
+}
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE int QVarLengthArray<T, Prealloc>::lastIndexOf(const T &t, int from) const
+{
+ if (from < 0)
+ from += s;
+ else if (from >= s)
+ from = s - 1;
+ if (from >= 0) {
+ T *b = ptr;
+ T *n = ptr + from + 1;
+ while (n != b) {
+ if (*--n == t)
+ return n - b;
+ }
+ }
+ return -1;
+}
+
+template <class T, int Prealloc>
+Q_INLINE_TEMPLATE bool QVarLengthArray<T, Prealloc>::contains(const T &t) const
+{
+ T *b = ptr;
+ T *i = ptr + s;
+ while (i != b) {
+ if (*--i == t)
+ return true;
+ }
+ return false;
+}
+
+template <class T, int Prealloc>
Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int increment)
{
Q_ASSERT(abuf);
diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc
index db435739fc..05d9258c86 100644
--- a/src/corelib/tools/qvarlengtharray.qdoc
+++ b/src/corelib/tools/qvarlengtharray.qdoc
@@ -671,3 +671,42 @@
\sa append(), operator<<()
*/
+/*! \fn int QVarLengthArray::indexOf(const T &value, int from = 0) const
+
+ \since 5.3
+ Returns the index position of the first occurrence of \a value in
+ the array, searching forward from index position \a from.
+ Returns -1 if no item matched.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa lastIndexOf(), contains()
+*/
+
+/*! \fn int QVarLengthArray::lastIndexOf(const T &value, int from = -1) const
+
+ \since 5.3
+ Returns the index position of the last occurrence of the value \a
+ value in the array, searching backward from index position \a
+ from. If \a from is -1 (the default), the search starts at the
+ last item. Returns -1 if no item matched.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf(), contains()
+*/
+
+/*! \fn bool QVarLengthArray::contains(const T &value) const
+
+ \since 5.3
+ Returns \c true if the array contains an occurrence of \a value;
+ otherwise returns \c false.
+
+ This function requires the value type to have an implementation of
+ \c operator==().
+
+ \sa indexOf(), lastIndexOf()
+*/
+
diff --git a/src/corelib/tools/qvector_msvc.cpp b/src/corelib/tools/qvector_msvc.cpp
new file mode 100644
index 0000000000..8570fcf5fe
--- /dev/null
+++ b/src/corelib/tools/qvector_msvc.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// ### Qt6: verify if we can remove this, somehow.
+// First, try to see if the extern template from qvector.h is necessary.
+// If it still is, check if removing the copy constructors in qarraydata.h
+// make the calling convention of both sets of begin() and end() functions
+// match, as it does for the IA-64 C++ ABI.
+
+#ifdef QVECTOR_H
+# error "This file must be compiled with no precompiled headers"
+#endif
+
+// invert the setting of QT_STRICT_ITERATORS, whichever it was
+#ifdef QT_STRICT_ITERATORS
+# undef QT_STRICT_ITERATORS
+#else
+# define QT_STRICT_ITERATORS
+#endif
+
+// the Q_TEMPLATE_EXTERN at the bottom of qvector.h will do the trick
+#include <QtCore/qvector.h>
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 52bb987506..1e4a503778 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -9,6 +9,7 @@ HEADERS += \
tools/qarraydatapointer.h \
tools/qbitarray.h \
tools/qbytearray.h \
+ tools/qbytearraylist.h \
tools/qbytearraymatcher.h \
tools/qbytedata_p.h \
tools/qcache.h \
@@ -58,6 +59,7 @@ HEADERS += \
tools/qstack.h \
tools/qstring.h \
tools/qstringbuilder.h \
+ tools/qstringiterator_p.h \
tools/qstringlist.h \
tools/qstringmatcher.h \
tools/qtextboundaryfinder.h \
@@ -76,6 +78,7 @@ SOURCES += \
tools/qarraydata.cpp \
tools/qbitarray.cpp \
tools/qbytearray.cpp \
+ tools/qbytearraylist.cpp \
tools/qbytearraymatcher.cpp \
tools/qcollator.cpp \
tools/qcommandlineoption.cpp \
@@ -116,6 +119,10 @@ SOURCES += \
tools/qvector.cpp \
tools/qvsnprintf.cpp
+NO_PCH_SOURCES = tools/qstring_compat.cpp
+msvc: NO_PCH_SOURCES += tools/qvector_msvc.cpp
+false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
+
!nacl:mac: {
SOURCES += tools/qelapsedtimer_mac.cpp
OBJECTIVE_SOURCES += tools/qlocale_mac.mm \
@@ -127,8 +134,11 @@ else:blackberry {
HEADERS += tools/qlocale_blackberry.h
}
else:unix:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp
-else:win32:SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp tools/qtimezoneprivate_win.cpp
-else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
+else:win32 {
+ SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp
+ !winrt: SOURCES += tools/qtimezoneprivate_win.cpp
+ winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil
+} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:SOURCES += tools/qelapsedtimer_generic.cpp
contains(QT_CONFIG, zlib) {
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 2a26c2ede4..5461139582 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -3170,7 +3170,7 @@ QXmlStreamPrivateTagStack::NamespaceDeclaration &QXmlStreamWriterPrivate::findNa
--j;
if (j < 0)
break;
- }
+ }
namespaceDeclaration.prefix = addToStringStorage(s);
}
namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index 9e81bac30e..96f28ac821 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -183,6 +183,9 @@ DEFINEFUNC(unsigned int , dbus_watch_get_flags, (DBusWatch *watch),
DEFINEFUNC(dbus_bool_t , dbus_watch_handle, (DBusWatch *watch,
unsigned int flags),
(watch, flags), return)
+DEFINEFUNC(void , dbus_connection_set_allow_anonymous, (DBusConnection *connection,
+ dbus_bool_t value),
+ (connection, value), return)
/* dbus-errors.h */
DEFINEFUNC(void , dbus_error_free, (DBusError *error),
diff --git a/src/dbus/qdbusabstractinterface.cpp b/src/dbus/qdbusabstractinterface.cpp
index bf92ccb30f..bbcd52294f 100644
--- a/src/dbus/qdbusabstractinterface.cpp
+++ b/src/dbus/qdbusabstractinterface.cpp
@@ -116,17 +116,16 @@ bool QDBusAbstractInterfacePrivate::canMakeCalls() const
return true;
}
-void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const
+bool QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, void *returnValuePtr) const
{
- if (!isValid || !canMakeCalls()) { // can't make calls
- where.clear();
- return;
- }
+ if (!isValid || !canMakeCalls()) // can't make calls
+ return false;
+ const int type = mp.userType();
// is this metatype registered?
const char *expectedSignature = "";
if (int(mp.type()) != QMetaType::QVariant) {
- expectedSignature = QDBusMetaType::typeToSignature(where.userType());
+ expectedSignature = QDBusMetaType::typeToSignature(type);
if (expectedSignature == 0) {
qWarning("QDBusAbstractInterface: type %s must be registered with Qt D-Bus before it can be "
"used to read property %s.%s",
@@ -134,8 +133,7 @@ void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &
lastError = QDBusError(QDBusError::Failed,
QString::fromLatin1("Unregistered type %1 cannot be handled")
.arg(QLatin1String(mp.typeName())));
- where.clear();
- return;
+ return false;
}
}
@@ -149,26 +147,29 @@ void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &
if (reply.type() != QDBusMessage::ReplyMessage) {
lastError = QDBusError(reply);
- where.clear();
- return;
+ return false;
}
if (reply.signature() != QLatin1String("v")) {
QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
DBUS_INTERFACE_PROPERTIES);
lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
- where.clear();
- return;
+ return false;
}
QByteArray foundSignature;
const char *foundType = 0;
QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
- if (value.userType() == where.userType() || mp.userType() == QMetaType::QVariant
+ if (value.userType() == type || type == QMetaType::QVariant
|| (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
// simple match
- where = value;
- return;
+ if (type == QMetaType::QVariant) {
+ *reinterpret_cast<QVariant*>(returnValuePtr) = value;
+ } else {
+ QMetaType::destruct(type, returnValuePtr);
+ QMetaType::construct(type, returnValuePtr, value.constData());
+ }
+ return true;
}
if (value.userType() == qMetaTypeId<QDBusArgument>()) {
@@ -178,8 +179,7 @@ void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &
foundSignature = arg.currentSignature().toLatin1();
if (foundSignature == expectedSignature) {
// signatures match, we can demarshall
- QDBusMetaType::demarshall(arg, where.userType(), where.data());
- return;
+ return QDBusMetaType::demarshall(arg, type, returnValuePtr);
}
} else {
foundType = value.typeName();
@@ -196,8 +196,7 @@ void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &
QString::fromUtf8(mp.name()),
QString::fromLatin1(mp.typeName()),
QString::fromLatin1(expectedSignature)));
- where.clear();
- return;
+ return false;
}
bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value)
@@ -246,13 +245,22 @@ int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void
if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) {
QMetaProperty mp = metaObject()->property(saved_id);
int &status = *reinterpret_cast<int *>(_a[2]);
- QVariant &variant = *reinterpret_cast<QVariant *>(_a[1]);
if (_c == QMetaObject::WriteProperty) {
- status = d_func()->setProperty(mp, variant) ? 1 : 0;
+ QVariant value;
+ if (mp.userType() == qMetaTypeId<QDBusVariant>())
+ value = reinterpret_cast<const QDBusVariant*>(_a[0])->variant();
+ else
+ value = QVariant(mp.userType(), _a[0]);
+ status = d_func()->setProperty(mp, value) ? 1 : 0;
} else {
- d_func()->property(mp, variant);
- status = variant.isValid() ? 1 : 0;
+ bool readStatus = d_func()->property(mp, _a[0]);
+ // Caller supports QVariant returns? Then we can also report errors
+ // by storing an invalid variant.
+ if (!readStatus && _a[1]) {
+ status = 0;
+ reinterpret_cast<QVariant*>(_a[1])->clear();
+ }
}
_id = -1;
}
diff --git a/src/dbus/qdbusabstractinterface_p.h b/src/dbus/qdbusabstractinterface_p.h
index 05ca04e3ef..e696781cdc 100644
--- a/src/dbus/qdbusabstractinterface_p.h
+++ b/src/dbus/qdbusabstractinterface_p.h
@@ -89,7 +89,7 @@ public:
bool canMakeCalls() const;
// these functions do not check if the property is valid
- void property(const QMetaProperty &mp, QVariant &where) const;
+ bool property(const QMetaProperty &mp, void *returnValuePtr) const;
bool setProperty(const QMetaProperty &mp, const QVariant &value);
// return conn's d pointer
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index 350e49a50d..f2590f9c54 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -322,6 +322,8 @@ public:
QMutex callDeliveryMutex;
QDBusCallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
+ bool anonymousAuthenticationAllowed;
+
public:
// static methods
static int findSlot(QObject *obj, const QByteArray &normalizedName, QVector<int> &params);
diff --git a/src/dbus/qdbusdemarshaller.cpp b/src/dbus/qdbusdemarshaller.cpp
index 953b0f3d03..0728192748 100644
--- a/src/dbus/qdbusdemarshaller.cpp
+++ b/src/dbus/qdbusdemarshaller.cpp
@@ -244,9 +244,9 @@ QVariant QDBusDemarshaller::toVariantInternal()
case DBUS_TYPE_BYTE:
return QVariant::fromValue(toByte());
case DBUS_TYPE_INT16:
- return QVariant::fromValue(toShort());
+ return QVariant::fromValue(toShort());
case DBUS_TYPE_UINT16:
- return QVariant::fromValue(toUShort());
+ return QVariant::fromValue(toUShort());
case DBUS_TYPE_INT32:
return toInt();
case DBUS_TYPE_UINT32:
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 77de09d197..1fef6d4d49 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -391,6 +391,10 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
q_dbus_connection_ref(connection);
QDBusConnectionPrivate *serverConnection = static_cast<QDBusConnectionPrivate *>(data);
+ // allow anonymous authentication
+ if (serverConnection->anonymousAuthenticationAllowed)
+ q_dbus_connection_set_allow_anonymous(connection, true);
+
QDBusConnectionPrivate *newConnection = new QDBusConnectionPrivate(serverConnection->parent());
QMutexLocker locker(&QDBusConnectionManager::instance()->mutex);
QDBusConnectionManager::instance()->setConnection(QLatin1String("QDBusServer-") + QString::number(reinterpret_cast<qulonglong>(newConnection)), newConnection);
@@ -986,9 +990,9 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q
fail = object->qt_metacall(QMetaObject::InvokeMetaMethod,
slotIdx, params.data()) >= 0;
QDBusConnectionPrivate::setSender(0);
- // the object might be deleted in the slot
- if (!ptr.isNull())
- QDBusContextPrivate::set(object, old);
+ // the object might be deleted in the slot
+ if (!ptr.isNull())
+ QDBusContextPrivate::set(object, old);
}
// do we create a reply? Only if the caller is waiting for a reply and one hasn't been sent
@@ -1014,7 +1018,8 @@ extern bool qDBusInitThreads();
QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
: QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0),
watchAndTimeoutLock(QMutex::Recursive),
- rootNode(QString(QLatin1Char('/')))
+ rootNode(QString(QLatin1Char('/'))),
+ anonymousAuthenticationAllowed(false)
{
static const bool threads = q_dbus_threads_init_default();
static const int debugging = qgetenv("QDBUS_DEBUG").toInt();
diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp
index e9bfd19060..17e12f1bba 100644
--- a/src/dbus/qdbusinternalfilters.cpp
+++ b/src/dbus/qdbusinternalfilters.cpp
@@ -92,6 +92,12 @@ static const char propertiesInterfaceXml[] =
" <arg name=\"values\" type=\"a{sv}\" direction=\"out\"/>\n"
" <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out0\" value=\"QVariantMap\"/>\n"
" </method>\n"
+ " <signal name=\"PropertiesChanged\">\n"
+ " <arg name=\"interface_name\" type=\"s\" direction=\"out\"/>\n"
+ " <arg name=\"changed_properties\" type=\"a{sv}\" direction=\"out\"/>\n"
+ " <annotation name=\"org.qtproject.QtDBus.QtTypeName.Out1\" value=\"QVariantMap\"/>\n"
+ " <arg name=\"invalidated_properties\" type=\"as\" direction=\"out\"/>\n"
+ " </signal>\n"
" </interface>\n";
static const char peerInterfaceXml[] =
diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp
index 170e6ff5cf..a9dd72036c 100644
--- a/src/dbus/qdbusserver.cpp
+++ b/src/dbus/qdbusserver.cpp
@@ -150,6 +150,33 @@ QString QDBusServer::address() const
}
/*!
+ \since 5.3
+
+ If \a value is set to true, an incoming connection can proceed even if the
+ connecting client is not authenticated as a user.
+
+ By default, this value is false.
+
+ \sa isAnonymousAuthenticationAllowed()
+*/
+void QDBusServer::setAnonymousAuthenticationAllowed(bool value)
+{
+ d->anonymousAuthenticationAllowed = value;
+}
+
+/*!
+ \since 5.3
+
+ Returns true if anonymous authentication is allowed.
+
+ \sa setAnonymousAuthenticationAllowed()
+*/
+bool QDBusServer::isAnonymousAuthenticationAllowed() const
+{
+ return d->anonymousAuthenticationAllowed;
+}
+
+/*!
\fn void QDBusServer::newConnection(const QDBusConnection &connection)
This signal is emitted when a new client connection \a connection is
diff --git a/src/dbus/qdbusserver.h b/src/dbus/qdbusserver.h
index d455f8e0ec..7a7f54b6c1 100644
--- a/src/dbus/qdbusserver.h
+++ b/src/dbus/qdbusserver.h
@@ -66,6 +66,9 @@ public:
QDBusError lastError() const;
QString address() const;
+ void setAnonymousAuthenticationAllowed(bool value);
+ bool isAnonymousAuthenticationAllowed() const;
+
Q_SIGNALS:
void newConnection(const QDBusConnection &connection);
diff --git a/src/dbus/qdbusxmlgenerator.cpp b/src/dbus/qdbusxmlgenerator.cpp
index c724ac573a..240c374cc5 100644
--- a/src/dbus/qdbusxmlgenerator.cpp
+++ b/src/dbus/qdbusxmlgenerator.cpp
@@ -77,6 +77,14 @@ static inline QString typeNameToXml(const char *typeName)
return rich;
}
+static inline QLatin1String accessAsString(bool read, bool write)
+{
+ if (read)
+ return write ? QLatin1String("readwrite") : QLatin1String("read") ;
+ else
+ return write ? QLatin1String("write") : QLatin1String("") ;
+}
+
// implement the D-Bus org.freedesktop.DBus.Introspectable interface
// we do that by analysing the metaObject of all the adaptor interfaces
@@ -88,7 +96,6 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
if (flags & (QDBusConnection::ExportScriptableProperties |
QDBusConnection::ExportNonScriptableProperties)) {
for (int i = propOffset; i < mo->propertyCount(); ++i) {
- static const char *accessvalues[] = {0, "read", "write", "readwrite"};
QMetaProperty mp = mo->property(i);
@@ -96,12 +103,6 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
(!mp.isScriptable() && (flags & QDBusConnection::ExportNonScriptableProperties))))
continue;
- int access = 0;
- if (mp.isReadable())
- access |= 1;
- if (mp.isWritable())
- access |= 2;
-
int typeId = mp.userType();
if (!typeId)
continue;
@@ -110,9 +111,9 @@ static QString generateInterfaceXml(const QMetaObject *mo, int flags, int method
continue;
retval += QString::fromLatin1(" <property name=\"%1\" type=\"%2\" access=\"%3\"")
- .arg(QLatin1String(mp.name()))
- .arg(QLatin1String(signature))
- .arg(QLatin1String(accessvalues[access]));
+ .arg(QLatin1String(mp.name()),
+ QLatin1String(signature),
+ accessAsString(mp.isReadable(), mp.isWritable()));
if (QDBusMetaType::signatureToType(signature) == QVariant::Invalid) {
const char *typeName = QMetaType::typeName(typeId);
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index a9a880e71f..fe66c6e19d 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -90,7 +90,7 @@ QAccessible::Id QAccessibleCache::insert(QObject *object, QAccessibleInterface *
Q_ASSERT(object == obj);
if (obj) {
objectToId.insert(obj, id);
- connect(obj, SIGNAL(destroyed(QObject *)), this, SLOT(objectDestroyed(QObject *)));
+ connect(obj, &QObject::destroyed, this, &QAccessibleCache::objectDestroyed);
}
idToInterface.insert(id, iface);
return id;
diff --git a/src/gui/doc/snippets/image/supportedformat.cpp b/src/gui/doc/snippets/image/supportedformat.cpp
index f4d2606728..0b52156b80 100644
--- a/src/gui/doc/snippets/image/supportedformat.cpp
+++ b/src/gui/doc/snippets/image/supportedformat.cpp
@@ -43,10 +43,10 @@
int main(int argv, char **args)
{
//! [0]
- QImageWriter writer;
- writer.setFormat("png");
- if (writer.supportsOption(QImageIOHandler::Description))
- qDebug() << "Png supports embedded text";
+ QImageWriter writer;
+ writer.setFormat("png");
+ if (writer.supportsOption(QImageIOHandler::Description))
+ qDebug() << "Png supports embedded text";
//! [0]
return 0;
}
diff --git a/src/gui/doc/src/coordsys.qdoc b/src/gui/doc/src/coordsys.qdoc
index e66afcfe55..d9c7c7e3c1 100644
--- a/src/gui/doc/src/coordsys.qdoc
+++ b/src/gui/doc/src/coordsys.qdoc
@@ -29,7 +29,7 @@
\page coordsys.html
\title Coordinate System
\ingroup qt-graphics
- \ingroup best-practices
+ \ingroup best-practices
\brief Information about the coordinate system used by the paint
system.
diff --git a/src/gui/doc/src/paintsystem.qdoc b/src/gui/doc/src/paintsystem.qdoc
index cd208e9e18..1006d2ef65 100644
--- a/src/gui/doc/src/paintsystem.qdoc
+++ b/src/gui/doc/src/paintsystem.qdoc
@@ -93,8 +93,8 @@
\page paintsystem-devices.html
\title Paint Devices and Backends
- \contentspage The Paint System
- \nextpage Drawing and Filling
+ \contentspage The Paint System
+ \nextpage Drawing and Filling
\section1 Creating a Paint Device
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index f4c35a36c5..9bd33d1f57 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -13,11 +13,13 @@ MODULE_PLUGIN_TYPES = \
imageformats
# This is here only because the platform plugin is no module, obviously.
-win32:contains(QT_CONFIG, angle) {
+win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
MODULE_AUX_INCLUDES = \
\$\$QT_MODULE_INCLUDE_BASE/QtANGLE
}
+contains(QT_CONFIG, dynamicgl): DEFINES += QT_OPENGL_DYNAMIC_IN_GUI
+
load(qt_module)
# Code coverage with TestCocoon
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index bf4b5ddf01..bbdd0f3da7 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -32,6 +32,7 @@ HEADERS += \
SOURCES += \
image/qbitmap.cpp \
image/qimage.cpp \
+ image/qimage_conversions.cpp \
image/qimageiohandler.cpp \
image/qimagereader.cpp \
image/qimagewriter.cpp \
@@ -54,6 +55,9 @@ SOURCES += \
win32:!winrt: SOURCES += image/qpixmap_win.cpp
+NO_PCH_SOURCES += image/qimage_compat.cpp
+false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
+
# Built-in image format support
HEADERS += \
image/qbmphandler_p.h \
@@ -74,9 +78,12 @@ contains(QT_CONFIG, jpeg):include($$PWD/qjpeghandler.pri)
contains(QT_CONFIG, gif):include($$PWD/qgifhandler.pri)
# SIMD
-NEON_SOURCES += image/qimage_neon.cpp
-SSE2_SOURCES += image/qimage_sse2.cpp
-SSSE3_SOURCES += image/qimage_ssse3.cpp
-AVX_SOURCES += image/qimage_avx.cpp
+contains(QT_CPU_FEATURES.$$QT_ARCH, neon) {
+ SOURCES += image/qimage_neon.cpp
+}
+contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
+ SOURCES += image/qimage_sse2.cpp
+ SSSE3_SOURCES += image/qimage_ssse3.cpp
+}
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index c03d9b8e5d..bb79a139b3 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -210,54 +210,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
uint red_mask = 0;
uint green_mask = 0;
uint blue_mask = 0;
+ uint alpha_mask = 0;
int red_shift = 0;
int green_shift = 0;
int blue_shift = 0;
+ int alpha_shift = 0;
int red_scale = 0;
int green_scale = 0;
int blue_scale = 0;
-
- int ncols = 0;
- int depth = 0;
- QImage::Format format;
- switch (nbits) {
- case 32:
- case 24:
- case 16:
- depth = 32;
- format = QImage::Format_RGB32;
- break;
- case 8:
- case 4:
- depth = 8;
- format = QImage::Format_Indexed8;
- break;
- default:
- depth = 1;
- format = QImage::Format_Mono;
- }
-
- if (bi.biHeight < 0)
- h = -h; // support images with negative height
-
- if (image.size() != QSize(w, h) || image.format() != format) {
- image = QImage(w, h, format);
- if (image.isNull()) // could not create image
- return false;
- }
-
- if (depth != 32) {
- ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
- if (ncols > 256) // sanity check - don't run out of mem if color table is broken
- return false;
- image.setColorCount(ncols);
- }
-
- image.setDotsPerMeterX(bi.biXPelsPerMeter);
- image.setDotsPerMeterY(bi.biYPelsPerMeter);
-
- if (!d->isSequential())
- d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+ int alpha_scale = 0;
if (bi.biSize >= BMP_WIN4 || (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32))) {
if (d->read((char *)&red_mask, sizeof(red_mask)) != sizeof(red_mask))
@@ -269,7 +230,6 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
// Read BMP v4+ header
if (bi.biSize >= BMP_WIN4) {
- int alpha_mask = 0;
int CSType = 0;
int gamma_red = 0;
int gamma_green = 0;
@@ -307,6 +267,49 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
}
}
+ bool transp = (comp == BMP_BITFIELDS) && alpha_mask;
+ int ncols = 0;
+ int depth = 0;
+ QImage::Format format;
+ switch (nbits) {
+ case 32:
+ case 24:
+ case 16:
+ depth = 32;
+ format = transp ? QImage::Format_ARGB32 : QImage::Format_RGB32;
+ break;
+ case 8:
+ case 4:
+ depth = 8;
+ format = QImage::Format_Indexed8;
+ break;
+ default:
+ depth = 1;
+ format = QImage::Format_Mono;
+ }
+
+ if (bi.biHeight < 0)
+ h = -h; // support images with negative height
+
+ if (image.size() != QSize(w, h) || image.format() != format) {
+ image = QImage(w, h, format);
+ if (image.isNull()) // could not create image
+ return false;
+ }
+
+ if (depth != 32) {
+ ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
+ if (ncols > 256) // sanity check - don't run out of mem if color table is broken
+ return false;
+ image.setColorCount(ncols);
+ }
+
+ image.setDotsPerMeterX(bi.biXPelsPerMeter);
+ image.setDotsPerMeterY(bi.biYPelsPerMeter);
+
+ if (!d->isSequential())
+ d->seek(startpos + BMP_FILEHDR_SIZE + (bi.biSize >= BMP_WIN4? BMP_WIN : bi.biSize)); // goto start of colormap
+
if (ncols > 0) { // read color table
uchar rgb[4];
int rgb_len = t == BMP_OLD ? 3 : 4;
@@ -324,6 +327,8 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
green_scale = 256 / ((green_mask >> green_shift) + 1);
blue_shift = calc_shift(blue_mask);
blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
+ alpha_shift = calc_shift(alpha_mask);
+ alpha_scale = 256 / ((alpha_mask >> alpha_shift) + 1);
} else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
blue_mask = 0x000000ff;
green_mask = 0x0000ff00;
@@ -344,6 +349,13 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
blue_scale = 8;
}
+#if 0
+ qDebug("Rmask: %08x Rshift: %08x Rscale:%08x", red_mask, red_shift, red_scale);
+ qDebug("Gmask: %08x Gshift: %08x Gscale:%08x", green_mask, green_shift, green_scale);
+ qDebug("Bmask: %08x Bshift: %08x Bscale:%08x", blue_mask, blue_shift, blue_scale);
+ qDebug("Amask: %08x Ashift: %08x Ascale:%08x", alpha_mask, alpha_shift, alpha_scale);
+#endif
+
// offset can be bogus, be careful
if (offset>=0 && startpos + offset > d->pos()) {
if (!d->isSequential())
@@ -535,11 +547,14 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
b = buf24;
while (p < end) {
c = *(uchar*)b | (*(uchar*)(b+1)<<8);
- if (nbits != 16)
+ if (nbits > 16)
c |= *(uchar*)(b+2)<<16;
- *p++ = qRgb(((c & red_mask) >> red_shift) * red_scale,
+ if (nbits > 24)
+ c |= *(uchar*)(b+3)<<24;
+ *p++ = qRgba(((c & red_mask) >> red_shift) * red_scale,
((c & green_mask) >> green_shift) * green_scale,
- ((c & blue_mask) >> blue_shift) * blue_scale);
+ ((c & blue_mask) >> blue_shift) * blue_scale,
+ transp ? ((c & alpha_mask) >> alpha_shift) * alpha_scale : 0xff);
b += nbits/8;
}
}
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 0b2211defc..48c262ae7a 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -715,42 +715,6 @@ bool QImageData::checkForAlphaPixels() const
QImage member functions
*****************************************************************************/
-// table to flip bits
-static const uchar bitflip[256] = {
- /*
- open OUT, "| fmt";
- for $i (0..255) {
- print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
- (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
- (($i << 7) & 0x80) | (($i << 5) & 0x40) |
- (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
- }
- close OUT;
- */
- 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
- 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
- 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
- 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
- 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
- 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
- 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
- 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
- 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
- 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
- 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
- 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
- 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
- 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
- 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
- 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
-};
-
-const uchar *qt_get_bitflip_array() // called from QPixmap code
-{
- return bitflip;
-}
-
-
/*!
Constructs a null image.
@@ -1105,8 +1069,7 @@ void QImage::detach()
if (d->ref.load() != 1 || d->ro_data)
*this = copy();
- if (d)
- ++d->detach_no;
+ ++d->detach_no;
}
}
@@ -1756,7 +1719,7 @@ void QImage::fill(const QColor &color)
if (d->depth == 32) {
uint pixel = color.rgba();
if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
- pixel = PREMUL(pixel);
+ pixel = qPremultiply(pixel);
fill((uint) pixel);
} else if (d->format == QImage::Format_RGB16) {
@@ -1898,2101 +1861,9 @@ QImage::Format QImage::format() const
return d ? d->format : Format_Invalid;
}
-
-
-/*****************************************************************************
- Internal routines for converting image depth.
- *****************************************************************************/
-
-typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
-
-typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
-
-static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = PREMUL(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- data->format = QImage::Format_ARGB32_Premultiplied;
- return true;
-}
-
-static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(0xff000000 | *src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- quint32 *rgb_data = (quint32 *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const quint32 *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = ARGB2RGBA(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- if (data->format == QImage::Format_ARGB32)
- data->format = QImage::Format_RGBA8888;
- else
- data->format = QImage::Format_RGBA8888_Premultiplied;
- return true;
-}
-
-static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = RGBA2ARGB(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = RGBA2ARGB(*rgb_data);
- ++rgb_data;
- }
- rgb_data += pad;
- }
- if (data->format == QImage::Format_RGBA8888_Premultiplied)
- data->format = QImage::Format_ARGB32_Premultiplied;
- else if (data->format == QImage::Format_RGBX8888)
- data->format = QImage::Format_RGB32;
- else
- data->format = QImage::Format_ARGB32;
- return true;
-}
-
-static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888);
- Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const quint32 *src_data = (quint32 *) src->data;
- quint32 *dest_data = (quint32 *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const quint32 *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGBA8888);
-
- const int pad = (data->bytes_per_line >> 2) - data->width;
- QRgb *rgb_data = (QRgb *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- const QRgb *end = rgb_data + data->width;
- while (rgb_data < end) {
- *rgb_data = PREMUL(RGBA2ARGB(*rgb_data));
- ++rgb_data;
- }
- rgb_data += pad;
- }
- data->format = QImage::Format_ARGB32_Premultiplied;
- return true;
-}
-
-static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 32;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes; // end of src
- quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 2) - width;
- if (data->colortable.size() == 0) {
- data->colortable.resize(256);
- for (int i = 0; i < 256; ++i)
- data->colortable[i] = qRgb(i, i, i);
- } else {
- for (int i = 0; i < data->colortable.size(); ++i)
- data->colortable[i] = PREMUL(data->colortable.at(i));
-
- // Fill the rest of the table in case src_data > colortable.size()
- const int oldSize = data->colortable.size();
- const QRgb lastColor = data->colortable.at(oldSize - 1);
- data->colortable.insert(oldSize, 256 - oldSize, lastColor);
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = data->colortable.at(*src_data);
- }
- }
-
- data->colortable = QVector<QRgb>();
- data->format = QImage::Format_ARGB32_Premultiplied;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 32;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes;
- quint32 *dest_data = (quint32 *) (newData + nbytes);
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 2) - width;
- if (data->colortable.size() == 0) {
- data->colortable.resize(256);
- for (int i = 0; i < 256; ++i)
- data->colortable[i] = qRgb(i, i, i);
- } else {
- // Fill the rest of the table in case src_data > colortable.size()
- const int oldSize = data->colortable.size();
- const QRgb lastColor = data->colortable.at(oldSize - 1);
- data->colortable.insert(oldSize, 256 - oldSize, lastColor);
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = (quint32) data->colortable.at(*src_data);
- }
- }
-
- data->colortable = QVector<QRgb>();
- data->format = QImage::Format_RGB32;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_Indexed8);
- const int depth = 16;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, nbytes);
- if (!newData)
- return false;
-
- data->data = newData;
-
- // start converting from the end because the end image is bigger than the source
- uchar *src_data = newData + data->nbytes;
- quint16 *dest_data = (quint16 *) (newData + nbytes);
- const int width = data->width;
- const int src_pad = data->bytes_per_line - width;
- const int dest_pad = (dst_bytes_per_line >> 1) - width;
-
- quint16 colorTableRGB16[256];
- if (data->colortable.isEmpty()) {
- for (int i = 0; i < 256; ++i)
- colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i));
- } else {
- // 1) convert the existing colors to RGB16
- const int tableSize = data->colortable.size();
- for (int i = 0; i < tableSize; ++i)
- colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i));
- data->colortable = QVector<QRgb>();
-
- // 2) fill the rest of the table in case src_data > colortable.size()
- const quint16 lastColor = colorTableRGB16[tableSize - 1];
- for (int i = tableSize; i < 256; ++i)
- colorTableRGB16[i] = lastColor;
- }
-
- for (int i = 0; i < data->height; ++i) {
- src_data -= src_pad;
- dest_data -= dest_pad;
- for (int pixI = 0; pixI < width; ++pixI) {
- --src_data;
- --dest_data;
- *dest_data = colorTableRGB16[*src_data];
- }
- }
-
- data->format = QImage::Format_RGB16;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = nbytes;
-
- return true;
-}
-
-static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
-{
- Q_ASSERT(data->format == QImage::Format_RGB32);
- const int depth = 16;
-
- const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
- const int src_bytes_per_line = data->bytes_per_line;
- quint32 *src_data = (quint32 *) data->data;
- quint16 *dst_data = (quint16 *) data->data;
-
- for (int i = 0; i < data->height; ++i) {
- for (int j = 0; j < data->width; ++j)
- dst_data[j] = qConvertRgb32To16(src_data[j]);
- src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
- dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
- }
- data->format = QImage::Format_RGB16;
- data->bytes_per_line = dst_bytes_per_line;
- data->depth = depth;
- data->nbytes = dst_bytes_per_line * data->height;
- uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
- if (newData) {
- data->data = newData;
- return true;
- } else {
- return false;
- }
-}
-
-static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_RGBA8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = INV_PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(*src_data);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(0xff000000 | INV_PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGBA8888);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(INV_PREMUL(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
- Q_ASSERT(dest->format == QImage::Format_RGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB32);
- Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = ARGB2RGBA(*src_data | 0xff000000);
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_ARGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = INV_PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
- Q_ASSERT(dest->format == QImage::Format_RGB32);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const QRgb *src_data = (QRgb *) src->data;
- QRgb *dest_data = (QRgb *) dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const QRgb *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = 0xff000000 | INV_PREMUL(RGBA2ARGB(*src_data));
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
- Q_ASSERT(src->nbytes == dest->nbytes);
- Q_ASSERT(src->bytes_per_line == dest->bytes_per_line);
-
- dest->colortable = src->colortable;
-
- const uchar *src_data = src->data;
- const uchar *end = src->data + src->nbytes;
- uchar *dest_data = dest->data;
- while (src_data < end) {
- *dest_data = bitflip[*src_data];
- ++src_data;
- ++dest_data;
- }
-}
-
-static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = *src_data | 0xff000000;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-}
-
-static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
-{
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- return mask_alpha_converter(dest, src, flags);
-#else
- Q_UNUSED(flags);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- const int src_pad = (src->bytes_per_line >> 2) - src->width;
- const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
- const uint *src_data = (const uint *)src->data;
- uint *dest_data = (uint *)dest->data;
-
- for (int i = 0; i < src->height; ++i) {
- const uint *end = src_data + src->width;
- while (src_data < end) {
- *dest_data = *src_data | 0x000000ff;
- ++src_data;
- ++dest_data;
- }
- src_data += src_pad;
- dest_data += dest_pad;
- }
-#endif
-}
-
-static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
-{
- QVector<QRgb> colorTable = ctbl;
- if (format == QImage::Format_RGB32) {
- // check if the color table has alpha
- for (int i = 0; i < colorTable.size(); ++i)
- if (qAlpha(colorTable.at(i) != 0xff))
- colorTable[i] = colorTable.at(i) | 0xff000000;
- } else if (format == QImage::Format_ARGB32_Premultiplied) {
- // check if the color table has alpha
- for (int i = 0; i < colorTable.size(); ++i)
- colorTable[i] = PREMUL(colorTable.at(i));
- }
- return colorTable;
-}
-
-//
-// dither_to_1: Uses selected dithering algorithm.
-//
-
-static void dither_to_Mono(QImageData *dst, const QImageData *src,
- Qt::ImageConversionFlags flags, bool fromalpha)
-{
- Q_ASSERT(src->width == dst->width);
- Q_ASSERT(src->height == dst->height);
- Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
-
- dst->colortable.clear();
- dst->colortable.append(0xffffffff);
- dst->colortable.append(0xff000000);
-
- enum { Threshold, Ordered, Diffuse } dithermode;
-
- if (fromalpha) {
- if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither)
- dithermode = Diffuse;
- else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither)
- dithermode = Ordered;
- else
- dithermode = Threshold;
- } else {
- if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither)
- dithermode = Threshold;
- else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither)
- dithermode = Ordered;
- else
- dithermode = Diffuse;
- }
-
- int w = src->width;
- int h = src->height;
- int d = src->depth;
- uchar gray[256]; // gray map for 8 bit images
- bool use_gray = (d == 8);
- if (use_gray) { // make gray map
- if (fromalpha) {
- // Alpha 0x00 -> 0 pixels (white)
- // Alpha 0xFF -> 1 pixels (black)
- for (int i = 0; i < src->colortable.size(); i++)
- gray[i] = (255 - (src->colortable.at(i) >> 24));
- } else {
- // Pixel 0x00 -> 1 pixels (black)
- // Pixel 0xFF -> 0 pixels (white)
- for (int i = 0; i < src->colortable.size(); i++)
- gray[i] = qGray(src->colortable.at(i));
- }
- }
-
- uchar *dst_data = dst->data;
- int dst_bpl = dst->bytes_per_line;
- const uchar *src_data = src->data;
- int src_bpl = src->bytes_per_line;
-
- switch (dithermode) {
- case Diffuse: {
- QScopedArrayPointer<int> lineBuffer(new int[w * 2]);
- int *line1 = lineBuffer.data();
- int *line2 = lineBuffer.data() + w;
- int bmwidth = (w+7)/8;
-
- int *b1, *b2;
- int wbytes = w * (d/8);
- const uchar *p = src->data;
- const uchar *end = p + wbytes;
- b2 = line2;
- if (use_gray) { // 8 bit image
- while (p < end)
- *b2++ = gray[*p++];
- } else { // 32 bit image
- if (fromalpha) {
- while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
- p += 4;
- }
- } else {
- while (p < end) {
- *b2++ = qGray(*(uint*)p);
- p += 4;
- }
- }
- }
- for (int y=0; y<h; y++) { // for each scan line...
- int *tmp = line1; line1 = line2; line2 = tmp;
- bool not_last_line = y < h - 1;
- if (not_last_line) { // calc. grayvals for next line
- p = src->data + (y+1)*src->bytes_per_line;
- end = p + wbytes;
- b2 = line2;
- if (use_gray) { // 8 bit image
- while (p < end)
- *b2++ = gray[*p++];
- } else { // 24 bit image
- if (fromalpha) {
- while (p < end) {
- *b2++ = 255 - (*(uint*)p >> 24);
- p += 4;
- }
- } else {
- while (p < end) {
- *b2++ = qGray(*(uint*)p);
- p += 4;
- }
- }
- }
- }
-
- int err;
- uchar *p = dst->data + y*dst->bytes_per_line;
- memset(p, 0, bmwidth);
- b1 = line1;
- b2 = line2;
- int bit = 7;
- for (int x=1; x<=w; x++) {
- if (*b1 < 128) { // black pixel
- err = *b1++;
- *p |= 1 << bit;
- } else { // white pixel
- err = *b1++ - 255;
- }
- if (bit == 0) {
- p++;
- bit = 7;
- } else {
- bit--;
- }
- if (x < w)
- *b1 += (err*7)>>4; // spread error to right pixel
- if (not_last_line) {
- b2[0] += (err*5)>>4; // pixel below
- if (x > 1)
- b2[-1] += (err*3)>>4; // pixel below left
- if (x < w)
- b2[1] += err>>4; // pixel below right
- }
- b2++;
- }
- }
- } break;
- case Ordered: {
-
- memset(dst->data, 0, dst->nbytes);
- if (d == 32) {
- for (int i=0; i<h; i++) {
- const uint *p = (const uint *)src_data;
- const uint *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- int j = 0;
- if (fromalpha) {
- while (p < end) {
- if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- } else {
- while (p < end) {
- if ((uint)qGray(*p++) < qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- } else
- /* (d == 8) */ {
- for (int i=0; i<h; i++) {
- const uchar *p = src_data;
- const uchar *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- int j = 0;
- while (p < end) {
- if ((uint)gray[*p++] < qt_bayer_matrix[j++&15][i&15])
- *m |= 1 << bit;
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- }
- } break;
- default: { // Threshold:
- memset(dst->data, 0, dst->nbytes);
- if (d == 32) {
- for (int i=0; i<h; i++) {
- const uint *p = (const uint *)src_data;
- const uint *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- if (fromalpha) {
- while (p < end) {
- if ((*p++ >> 24) >= 128)
- *m |= 1 << bit; // Set mask "on"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- } else {
- while (p < end) {
- if (qGray(*p++) < 128)
- *m |= 1 << bit; // Set pixel "black"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- } else
- if (d == 8) {
- for (int i=0; i<h; i++) {
- const uchar *p = src_data;
- const uchar *end = p + w;
- uchar *m = dst_data;
- int bit = 7;
- while (p < end) {
- if (gray[*p++] < 128)
- *m |= 1 << bit; // Set mask "on"/ pixel "black"
- if (bit == 0) {
- m++;
- bit = 7;
- } else {
- bit--;
- }
- }
- dst_data += dst_bpl;
- src_data += src_bpl;
- }
- }
- }
- }
-
- if (dst->format == QImage::Format_MonoLSB) {
- // need to swap bit order
- uchar *sl = dst->data;
- int bpl = (dst->width + 7) * dst->depth / 8;
- int pad = dst->bytes_per_line - bpl;
- for (int y=0; y<dst->height; ++y) {
- for (int x=0; x<bpl; ++x) {
- *sl = bitflip[*sl];
- ++sl;
- }
- sl += pad;
- }
- }
-}
-
-static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- dither_to_Mono(dst, src, flags, false);
-}
-
-static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
- convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
- dither_to_Mono(dst, tmp.data(), flags, false);
-}
-
-//
-// convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
-// image with a colormap. If the 32 bit image has more than 256 colors,
-// we convert the red,green and blue bytes into a single byte encoded
-// as 6 shades of each of red, green and blue.
-//
-// if dithering is needed, only 1 color at most is available for alpha.
-//
-struct QRgbMap {
- inline QRgbMap() : used(0) { }
- uchar pix;
- uchar used;
- QRgb rgb;
-};
-
-static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
- Q_ASSERT(dst->format == QImage::Format_Indexed8);
- Q_ASSERT(src->width == dst->width);
- Q_ASSERT(src->height == dst->height);
-
- bool do_quant = (flags & Qt::DitherMode_Mask) == Qt::PreferDither
- || src->format == QImage::Format_ARGB32;
- uint alpha_mask = src->format == QImage::Format_RGB32 ? 0xff000000 : 0;
-
- const int tablesize = 997; // prime
- QRgbMap table[tablesize];
- int pix=0;
-
- if (!dst->colortable.isEmpty()) {
- QVector<QRgb> ctbl = dst->colortable;
- dst->colortable.resize(256);
- // Preload palette into table.
- // Almost same code as pixel insertion below
- for (int i = 0; i < dst->colortable.size(); ++i) {
- // Find in table...
- QRgb p = ctbl.at(i) | alpha_mask;
- int hash = p % tablesize;
- for (;;) {
- if (table[hash].used) {
- if (table[hash].rgb == p) {
- // Found previous insertion - use it
- break;
- } else {
- // Keep searching...
- if (++hash == tablesize) hash = 0;
- }
- } else {
- // Cannot be in table
- Q_ASSERT (pix != 256); // too many colors
- // Insert into table at this unused position
- dst->colortable[pix] = p;
- table[hash].pix = pix++;
- table[hash].rgb = p;
- table[hash].used = 1;
- break;
- }
- }
- }
- }
-
- if ((flags & Qt::DitherMode_Mask) != Qt::PreferDither) {
- dst->colortable.resize(256);
- const uchar *src_data = src->data;
- uchar *dest_data = dst->data;
- for (int y = 0; y < src->height; y++) { // check if <= 256 colors
- const QRgb *s = (const QRgb *)src_data;
- uchar *b = dest_data;
- for (int x = 0; x < src->width; ++x) {
- QRgb p = s[x] | alpha_mask;
- int hash = p % tablesize;
- for (;;) {
- if (table[hash].used) {
- if (table[hash].rgb == (p)) {
- // Found previous insertion - use it
- break;
- } else {
- // Keep searching...
- if (++hash == tablesize) hash = 0;
- }
- } else {
- // Cannot be in table
- if (pix == 256) { // too many colors
- do_quant = true;
- // Break right out
- x = src->width;
- y = src->height;
- } else {
- // Insert into table at this unused position
- dst->colortable[pix] = p;
- table[hash].pix = pix++;
- table[hash].rgb = p;
- table[hash].used = 1;
- }
- break;
- }
- }
- *b++ = table[hash].pix; // May occur once incorrectly
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- }
- int numColors = do_quant ? 256 : pix;
-
- dst->colortable.resize(numColors);
-
- if (do_quant) { // quantization needed
-
-#define MAX_R 5
-#define MAX_G 5
-#define MAX_B 5
-#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
-
- for (int rc=0; rc<=MAX_R; rc++) // build 6x6x6 color cube
- for (int gc=0; gc<=MAX_G; gc++)
- for (int bc=0; bc<=MAX_B; bc++)
- dst->colortable[INDEXOF(rc,gc,bc)] = 0xff000000 | qRgb(rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B);
-
- const uchar *src_data = src->data;
- uchar *dest_data = dst->data;
- if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) {
- for (int y = 0; y < src->height; y++) {
- const QRgb *p = (const QRgb *)src_data;
- const QRgb *end = p + src->width;
- uchar *b = dest_data;
-
- while (p < end) {
-#define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
- *b++ =
- INDEXOF(
- DITHER(qRed(*p), MAX_R),
- DITHER(qGreen(*p), MAX_G),
- DITHER(qBlue(*p), MAX_B)
- );
-#undef DITHER
- p++;
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- } else if ((flags & Qt::Dither_Mask) == Qt::DiffuseDither) {
- int* line1[3];
- int* line2[3];
- int* pv[3];
- QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]);
- line1[0] = lineBuffer.data();
- line2[0] = lineBuffer.data() + src->width;
- line1[1] = lineBuffer.data() + src->width * 2;
- line2[1] = lineBuffer.data() + src->width * 3;
- line1[2] = lineBuffer.data() + src->width * 4;
- line2[2] = lineBuffer.data() + src->width * 5;
- pv[0] = lineBuffer.data() + src->width * 6;
- pv[1] = lineBuffer.data() + src->width * 7;
- pv[2] = lineBuffer.data() + src->width * 8;
-
- int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian);
- for (int y = 0; y < src->height; y++) {
- const uchar* q = src_data;
- const uchar* q2 = y < src->height - 1 ? q + src->bytes_per_line : src->data;
- uchar *b = dest_data;
- for (int chan = 0; chan < 3; chan++) {
- int *l1 = (y&1) ? line2[chan] : line1[chan];
- int *l2 = (y&1) ? line1[chan] : line2[chan];
- if (y == 0) {
- for (int i = 0; i < src->width; i++)
- l1[i] = q[i*4+chan+endian];
- }
- if (y+1 < src->height) {
- for (int i = 0; i < src->width; i++)
- l2[i] = q2[i*4+chan+endian];
- }
- // Bi-directional error diffusion
- if (y&1) {
- for (int x = 0; x < src->width; x++) {
- int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
- int err = l1[x] - pix * 255 / 5;
- pv[chan][x] = pix;
-
- // Spread the error around...
- if (x + 1< src->width) {
- l1[x+1] += (err*7)>>4;
- l2[x+1] += err>>4;
- }
- l2[x]+=(err*5)>>4;
- if (x>1)
- l2[x-1]+=(err*3)>>4;
- }
- } else {
- for (int x = src->width; x-- > 0;) {
- int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
- int err = l1[x] - pix * 255 / 5;
- pv[chan][x] = pix;
-
- // Spread the error around...
- if (x > 0) {
- l1[x-1] += (err*7)>>4;
- l2[x-1] += err>>4;
- }
- l2[x]+=(err*5)>>4;
- if (x + 1 < src->width)
- l2[x+1]+=(err*3)>>4;
- }
- }
- }
- if (endian) {
- for (int x = 0; x < src->width; x++) {
- *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
- }
- } else {
- for (int x = 0; x < src->width; x++) {
- *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
- }
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- } else { // OrderedDither
- for (int y = 0; y < src->height; y++) {
- const QRgb *p = (const QRgb *)src_data;
- const QRgb *end = p + src->width;
- uchar *b = dest_data;
-
- int x = 0;
- while (p < end) {
- uint d = qt_bayer_matrix[y & 15][x & 15] << 8;
-
-#define DITHER(p, d, m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) >> 16))
- *b++ =
- INDEXOF(
- DITHER(qRed(*p), d, MAX_R),
- DITHER(qGreen(*p), d, MAX_G),
- DITHER(qBlue(*p), d, MAX_B)
- );
-#undef DITHER
-
- p++;
- x++;
- }
- src_data += src->bytes_per_line;
- dest_data += dst->bytes_per_line;
- }
- }
-
- if (src->format != QImage::Format_RGB32
- && src->format != QImage::Format_RGB16) {
- const int trans = 216;
- Q_ASSERT(dst->colortable.size() > trans);
- dst->colortable[trans] = 0;
- QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono));
- dither_to_Mono(mask.data(), src, flags, true);
- uchar *dst_data = dst->data;
- const uchar *mask_data = mask->data;
- for (int y = 0; y < src->height; y++) {
- for (int x = 0; x < src->width ; x++) {
- if (!(mask_data[x>>3] & (0x80 >> (x & 7))))
- dst_data[x] = trans;
- }
- mask_data += mask->bytes_per_line;
- dst_data += dst->bytes_per_line;
- }
- dst->has_alpha_clut = true;
- }
-
-#undef MAX_R
-#undef MAX_G
-#undef MAX_B
-#undef INDEXOF
-
- }
-}
-
-static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
- convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
- convert_RGB_to_Indexed8(dst, tmp.data(), flags);
-}
-
-static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
-{
- convert_RGB_to_Indexed8(dst, src, flags);
-}
-
-static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Indexed8);
- Q_ASSERT(dest->format == QImage::Format_RGB32
- || dest->format == QImage::Format_ARGB32
- || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
- if (colorTable.size() == 0) {
- colorTable.resize(256);
- for (int i=0; i<256; ++i)
- colorTable[i] = qRgb(i, i, i);
- }
-
- int w = src->width;
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- int tableSize = colorTable.size() - 1;
- for (int y = 0; y < src->height; y++) {
- uint *p = (uint *)dest_data;
- const uchar *b = src_data;
- uint *end = p + w;
-
- while (p < end)
- *p++ = colorTable.at(qMin<int>(tableSize, *b++));
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
-}
-
-static void convert_Mono_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_RGB32
- || dest->format == QImage::Format_ARGB32
- || dest->format == QImage::Format_ARGB32_Premultiplied);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
-
- // Default to black / white colors
- if (colorTable.size() < 2) {
- if (colorTable.size() == 0)
- colorTable << 0xff000000;
- colorTable << 0xffffffff;
- }
-
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- if (src->format == QImage::Format_Mono) {
- for (int y = 0; y < dest->height; y++) {
- uint *p = (uint *)dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = colorTable.at((src_data[x>>3] >> (7 - (x & 7))) & 1);
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- } else {
- for (int y = 0; y < dest->height; y++) {
- uint *p = (uint *)dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = colorTable.at((src_data[x>>3] >> (x & 7)) & 1);
-
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- }
-}
-
-
-static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
- Q_ASSERT(dest->format == QImage::Format_Indexed8);
- Q_ASSERT(src->width == dest->width);
- Q_ASSERT(src->height == dest->height);
-
- QVector<QRgb> ctbl = src->colortable;
- if (ctbl.size() > 2) {
- ctbl.resize(2);
- } else if (ctbl.size() < 2) {
- if (ctbl.size() == 0)
- ctbl << 0xff000000;
- ctbl << 0xffffffff;
- }
- dest->colortable = ctbl;
- dest->has_alpha_clut = src->has_alpha_clut;
-
-
- const uchar *src_data = src->data;
- uchar *dest_data = dest->data;
- if (src->format == QImage::Format_Mono) {
- for (int y = 0; y < dest->height; y++) {
- uchar *p = dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = (src_data[x>>3] >> (7 - (x & 7))) & 1;
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- } else {
- for (int y = 0; y < dest->height; y++) {
- uchar *p = dest_data;
- for (int x = 0; x < dest->width; x++)
- *p++ = (src_data[x>>3] >> (x & 7)) & 1;
- src_data += src->bytes_per_line;
- dest_data += dest->bytes_per_line;
- }
- }
-}
-
-// Cannot be used with indexed formats.
-static void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
-{
- const int buffer_size = 2048;
- uint buffer[buffer_size];
- const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
- const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
- const uchar *srcData = src->data;
- uchar *destData = dest->data;
-
- FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
- StorePixelsFunc store = qStorePixels[destLayout->bpp];
-
- for (int y = 0; y < src->height; ++y) {
- int x = 0;
- while (x < src->width) {
- int l = qMin(src->width - x, buffer_size);
- const uint *ptr = fetch(buffer, srcData, x, l);
- ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
- ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
- store(destData, ptr, x, l);
- x += l;
- }
- srcData += src->bytes_per_line;
- destData += dest->bytes_per_line;
- }
-}
-
-
-// first index source, second dest
-static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =
-{
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- },
- {
- 0,
- 0,
- swap_bit_order,
- convert_Mono_to_Indexed8,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_Mono
-
- {
- 0,
- swap_bit_order,
- 0,
- convert_Mono_to_Indexed8,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- convert_Mono_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_MonoLSB
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- 0,
- convert_Indexed8_to_X32,
- convert_Indexed8_to_X32,
- convert_Indexed8_to_X32,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_Indexed8
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- convert_RGB_to_Indexed8,
- 0,
- mask_alpha_converter,
- mask_alpha_converter,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_RGB_to_RGBA,
- convert_RGB_to_RGBA,
- convert_RGB_to_RGBA
- }, // Format_RGB32
-
- {
- 0,
- convert_X_to_Mono,
- convert_X_to_Mono,
- convert_ARGB_to_Indexed8,
- mask_alpha_converter,
- 0,
- convert_ARGB_to_ARGB_PM,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_generic,
- convert_ARGB_to_RGBx,
- convert_ARGB_to_RGBA,
- convert_ARGB_to_RGBA_PM,
- }, // Format_ARGB32
-
- {
- 0,
- convert_ARGB_PM_to_Mono,
- convert_ARGB_PM_to_Mono,
- convert_ARGB_PM_to_Indexed8,
- convert_ARGB_PM_to_RGB,
- convert_ARGB_PM_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_PM_to_RGBx,
- convert_ARGB_PM_to_RGBA,
- convert_ARGB_to_RGBA,
- }, // Format_ARGB32_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
-#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- convert_generic,
-#else
- 0,
-#endif
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB16
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB8565_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB666
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB6666_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
-#if defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16)
- convert_generic,
-#else
- 0,
-#endif
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB555
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB8555_Premultiplied
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB888
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_RGB444
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_generic,
- convert_generic,
- convert_generic,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0
- }, // Format_ARGB4444_Premultiplied
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_RGB,
- convert_RGBA_to_ARGB,
- convert_RGBA_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- mask_alpha_converter_RGBx,
- mask_alpha_converter_RGBx,
- }, // Format_RGBX8888
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_RGB,
- convert_RGBA_to_ARGB,
- convert_RGBA_to_ARGB_PM,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- mask_alpha_converter_RGBx,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- 0,
- convert_ARGB_to_ARGB_PM,
-#else
- 0,
- 0
-#endif
- }, // Format_RGBA8888
-
- {
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_PM_to_RGB,
- convert_RGBA_PM_to_ARGB,
- convert_RGBA_to_ARGB,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- convert_ARGB_PM_to_RGB,
- convert_ARGB_PM_to_ARGB,
- 0,
-#else
- 0,
- 0,
- 0
-#endif
- } // Format_RGBA8888_Premultiplied
-};
-
-static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
-{
- {
- 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, 0, 0, 0, 0, 0
- }, // Format_Mono
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_MonoLSB
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_indexed8_to_RGB_inplace,
- convert_indexed8_to_ARGB_PM_inplace,
- convert_indexed8_to_RGB16_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_Indexed8
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGB_to_RGB16_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGB32
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_ARGB_PM_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_RGBA_inplace,
- 0,
- }, // Format_ARGB32
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_ARGB_to_RGBA_inplace
- }, // Format_ARGB32_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB16
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB8565_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB666
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB6666_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB555
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB8555_Premultiplied
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB888
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_RGB444
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }, // Format_ARGB4444_Premultiplied
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- convert_RGBA_to_ARGB_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGBX8888
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- convert_RGBA_to_ARGB_PM_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- }, // Format_RGBA8888
- {
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- convert_RGBA_to_ARGB_inplace,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- } // Format_RGBA8888_Premultiplied
-};
-
-void qInitImageConversions()
-{
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (qCpuHasFeature(AVX)) {
- extern bool convert_ARGB_to_ARGB_PM_inplace_avx(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_avx;
-
- extern void convert_RGB888_to_RGB32_avx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_avx;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_avx;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_avx;
- return;
- }
-#endif
-
-#if defined(QT_COMPILER_SUPPORTS_SSE2) && !defined(__AVX__)
- if (qCpuHasFeature(SSE2)) {
- extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
-#ifdef QT_COMPILER_SUPPORTS_SSSE3
- if (qCpuHasFeature(SSSE3)) {
- extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
- }
-#endif
- return;
- }
-#endif // SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_NEON
- if (qCpuHasFeature(NEON)) {
- extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
- converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
- converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
- return;
- }
-#endif
-
-#ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2
- extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags);
- inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2;
- return;
-#endif
-}
-
-extern const uchar *qt_pow_rgb_gamma();
-
-void qGamma_correct_back_to_linear_cs(QImage *image)
-{
- const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
- if (!tables)
- return;
- const uchar *gamma = tables->qt_pow_rgb_gamma;
- // gamma correct the pixels back to linear color space...
- int h = image->height();
- int w = image->width();
-
- for (int y=0; y<h; ++y) {
- uint *pixels = (uint *) image->scanLine(y);
- for (int x=0; x<w; ++x) {
- uint p = pixels[x];
- uint r = gamma[qRed(p)];
- uint g = gamma[qGreen(p)];
- uint b = gamma[qBlue(p)];
- pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
- }
- }
-}
-
/*!
+ \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const
+
Returns a copy of the image in the given \a format.
The specified image conversion \a flags control how the image data
@@ -4000,7 +1871,11 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
\sa {Image Formats}
*/
-QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const
+
+/*!
+ \internal
+*/
+QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const
{
if (!d || d->format == format)
return *this;
@@ -4008,8 +1883,9 @@ QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) co
if (format == Format_Invalid || d->format == Format_Invalid)
return QImage();
- const Image_Converter *converterPtr = &converter_map[d->format][format];
- Image_Converter converter = *converterPtr;
+ Image_Converter converter = qimage_converter_map[d->format][format];
+ if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8)
+ converter = convert_generic;
if (converter) {
QImage image(d->width, d->height, format);
@@ -4025,14 +1901,20 @@ QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) co
return image;
}
+ // Convert indexed formats over ARGB32 to the final format.
Q_ASSERT(format != QImage::Format_ARGB32);
Q_ASSERT(d->format != QImage::Format_ARGB32);
- QImage image = convertToFormat(Format_ARGB32, flags);
- return image.convertToFormat(format, flags);
+ return convertToFormat(Format_ARGB32, flags).convertToFormat(format, flags);
}
-
+/*!
+ \internal
+*/
+bool QImage::convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags)
+{
+ return d && d->convertInPlace(format, flags);
+}
static inline int pixel_distance(QRgb p1, QRgb p2) {
int r1 = qRed(p1);
@@ -4131,7 +2013,7 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q
return convertWithPalette(*this, format, colorTable);
}
- const Image_Converter *converterPtr = &converter_map[d->format][format];
+ const Image_Converter *converterPtr = &qimage_converter_map[d->format][format];
Image_Converter converter = *converterPtr;
if (!converter)
return QImage();
@@ -4240,6 +2122,7 @@ QRgb QImage::pixel(int x, int y) const
case Format_Indexed8:
return d->colortable.at((int)s[x]);
case Format_RGB32:
+ return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
case Format_ARGB32: // Keep old behaviour.
case Format_ARGB32_Premultiplied:
return reinterpret_cast<const QRgb *>(s)[x];
@@ -4321,17 +2204,17 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
case Format_RGB32:
//make sure alpha is 255, we depend on it in qdrawhelper for cases
// when image is set as a texture pattern on a qbrush
- ((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
+ ((uint *)s)[x] = 0xff000000 | index_or_rgb;
return;
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
((uint *)s)[x] = index_or_rgb;
return;
case Format_RGB16:
- ((quint16 *)s)[x] = qConvertRgb32To16(INV_PREMUL(index_or_rgb));
+ ((quint16 *)s)[x] = qConvertRgb32To16(qUnpremultiply(index_or_rgb));
return;
case Format_RGBX8888:
- ((uint *)s)[x] = ARGB2RGBA(index_or_rgb | 0xff000000);
+ ((uint *)s)[x] = ARGB2RGBA(0xff000000 | index_or_rgb);
return;
case Format_RGBA8888:
case Format_RGBA8888_Premultiplied:
@@ -4810,6 +2693,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
*/
/*!
+ \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const
Returns a mirror of the image, mirrored in the horizontal and/or
the vertical direction depending on whether \a horizontal and \a
vertical are set to true or false.
@@ -4818,7 +2702,70 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
\sa {QImage#Image Transformations}{Image Transformations}
*/
-QImage QImage::mirrored(bool horizontal, bool vertical) const
+
+template<typename T>
+inline void mirrored_helper_loop(int w, int h, int dxi, int dxs, int dyi, int dy, const uchar* sdata, uchar* ddata, int sbpl, int dbpl)
+{
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ const T* ssl = (T*)(sdata + sy*sbpl);
+ T* dsl = (T*)(ddata + dy*dbpl);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ dsl[dx] = ssl[sx];
+ }
+}
+
+template<typename T>
+inline void mirrored_helper_loop_inplace(int w, int h, int dxi, int dxs, int dyi, int dy, uchar* sdata, int sbpl)
+{
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ T* ssl = (T*)(sdata + sy*sbpl);
+ T* dsl = (T*)(sdata + dy*sbpl);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ std::swap(dsl[dx], ssl[sx]);
+ }
+}
+
+inline void mirror_horizonal_bitmap(int w, int h, int dxs, uchar* data, int bpl, bool monolsb)
+{
+ int shift = w % 8;
+ const uchar* bitflip = qt_get_bitflip_array();
+ for (int y = h-1; y >= 0; y--) {
+ quint8* a0 = (quint8*)(data + y*bpl);
+ // Swap bytes
+ quint8* a = a0+dxs;
+ while (a >= a0) {
+ *a = bitflip[*a];
+ a--;
+ }
+ // Shift bits if unaligned
+ if (shift != 0) {
+ a = a0+dxs;
+ quint8 c = 0;
+ if (monolsb) {
+ while (a >= a0) {
+ quint8 nc = *a << shift;
+ *a = (*a >> (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ } else {
+ while (a >= a0) {
+ quint8 nc = *a >> shift;
+ *a = (*a << (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
{
if (!d)
return QImage();
@@ -4840,92 +2787,80 @@ QImage QImage::mirrored(bool horizontal, bool vertical) const
result.d->has_alpha_clut = d->has_alpha_clut;
result.d->devicePixelRatio = d->devicePixelRatio;
- if (depth() == 1)
+ if (d->depth == 1)
w = (w+7)/8;
int dxi = horizontal ? -1 : 1;
int dxs = horizontal ? w-1 : 0;
int dyi = vertical ? -1 : 1;
- int dy = vertical ? h-1: 0;
+ int dys = vertical ? h-1 : 0;
// 1 bit, 8 bit
- if (d->depth == 1 || d->depth == 8) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint8* ssl = (quint8*)(d->data + sy*d->bytes_per_line);
- quint8* dsl = (quint8*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ if (d->depth == 1 || d->depth == 8)
+ mirrored_helper_loop<quint8>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 16 bit
- else if (d->depth == 16) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint16* ssl = (quint16*)(d->data + sy*d->bytes_per_line);
- quint16* dsl = (quint16*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 16)
+ mirrored_helper_loop<quint16>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 24 bit
- else if (d->depth == 24) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint24* ssl = (quint24*)(d->data + sy*d->bytes_per_line);
- quint24* dsl = (quint24*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 24)
+ mirrored_helper_loop<quint24>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// 32 bit
- else if (d->depth == 32) {
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- quint32* ssl = (quint32*)(d->data + sy*d->bytes_per_line);
- quint32* dsl = (quint32*)(result.d->data + dy*result.d->bytes_per_line);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
- }
- }
+ else if (d->depth == 32)
+ mirrored_helper_loop<quint32>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
// special handling of 1 bit images for horizontal mirroring
- if (horizontal && d->depth == 1) {
- int shift = width() % 8;
- for (int y = h-1; y >= 0; y--) {
- quint8* a0 = (quint8*)(result.d->data + y*d->bytes_per_line);
- // Swap bytes
- quint8* a = a0+dxs;
- while (a >= a0) {
- *a = bitflip[*a];
- a--;
- }
- // Shift bits if unaligned
- if (shift != 0) {
- a = a0+dxs;
- quint8 c = 0;
- if (format() == Format_MonoLSB) {
- while (a >= a0) {
- quint8 nc = *a << shift;
- *a = (*a >> (8-shift)) | c;
- --a;
- c = nc;
- }
- } else {
- while (a >= a0) {
- quint8 nc = *a >> shift;
- *a = (*a << (8-shift)) | c;
- --a;
- c = nc;
- }
- }
- }
- }
- }
-
+ if (horizontal && d->depth == 1)
+ mirror_horizonal_bitmap(d->width, d->height, dxs, result.d->data, result.d->bytes_per_line, d->format == Format_MonoLSB);
return result;
}
/*!
+ \internal
+*/
+void QImage::mirrored_inplace(bool horizontal, bool vertical)
+{
+ if (!d)
+ return;
+
+ if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
+ return;
+
+ detach();
+
+ int w = d->width;
+ int h = d->height;
+
+ if (d->depth == 1)
+ w = (w+7)/8;
+ int dxi = horizontal ? -1 : 1;
+ int dxs = horizontal ? w-1 : 0;
+ int dyi = vertical ? -1 : 1;
+ int dys = vertical ? h-1 : 0;
+
+ if (vertical)
+ h = h/2;
+ else if (horizontal)
+ w = w/2;
+
+ // 1 bit, 8 bit
+ if (d->depth == 1 || d->depth == 8)
+ mirrored_helper_loop_inplace<quint8>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 16 bit
+ else if (d->depth == 16)
+ mirrored_helper_loop_inplace<quint16>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 24 bit
+ else if (d->depth == 24)
+ mirrored_helper_loop_inplace<quint24>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+ // 32 bit
+ else if (d->depth == 32)
+ mirrored_helper_loop_inplace<quint32>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
+
+ // special handling of 1 bit images for horizontal mirroring
+ if (horizontal && d->depth == 1)
+ mirror_horizonal_bitmap(d->width, d->height, dxs, d->data, d->bytes_per_line, d->format == Format_MonoLSB);
+}
+
+/*!
+ \fn QImage QImage::rgbSwapped() const
Returns a QImage in which the values of the red and blue
components of all pixels have been swapped, effectively converting
an RGB image to an BGR image.
@@ -4934,16 +2869,54 @@ QImage QImage::mirrored(bool horizontal, bool vertical) const
\sa {QImage#Image Transformations}{Image Transformations}
*/
-QImage QImage::rgbSwapped() const
+
+inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
+{
+ Q_ASSERT(layout->redWidth == layout->blueWidth);
+ FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
+ StorePixelsFunc store = qStorePixels[layout->bpp];
+
+ const uint redBlueMask = (1 << layout->redWidth) - 1;
+ const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
+ | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ for (int i = 0; i < height; ++i) {
+ uchar *q = dst->scanLine(i);
+ const uchar *p = src->constScanLine(i);
+ int x = 0;
+ while (x < width) {
+ int l = qMin(width - x, buffer_size);
+ const uint *ptr = fetch(buffer, p, x, l);
+ for (int j = 0; j < l; ++j) {
+ uint red = (ptr[j] >> layout->redShift) & redBlueMask;
+ uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
+ buffer[j] = (ptr[j] & alphaGreenMask)
+ | (red << layout->blueShift)
+ | (blue << layout->redShift);
+ }
+ store(q, buffer, x, l);
+ x += l;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+QImage QImage::rgbSwapped_helper() const
{
if (isNull())
return *this;
+
QImage res;
+
switch (d->format) {
case Format_Invalid:
case NImageFormats:
Q_ASSERT(false);
- return res;
+ break;
case Format_Mono:
case Format_MonoLSB:
case Format_Indexed8:
@@ -4952,7 +2925,7 @@ QImage QImage::rgbSwapped() const
QRgb c = res.d->colortable.at(i);
res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
}
- return res;
+ break;
case Format_RGB32:
case Format_ARGB32:
case Format_ARGB32_Premultiplied:
@@ -4965,15 +2938,16 @@ QImage QImage::rgbSwapped() const
QIMAGE_SANITYCHECK_MEMORY(res);
for (int i = 0; i < d->height; i++) {
uint *q = (uint*)res.scanLine(i);
- uint *p = (uint*)constScanLine(i);
- uint *end = p + d->width;
+ const uint *p = (const uint*)constScanLine(i);
+ const uint *end = p + d->width;
while (p < end) {
- *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
+ uint c = *p;
+ *q = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
p++;
q++;
}
}
- return res;
+ break;
case Format_RGB16:
res = QImage(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(res);
@@ -4982,48 +2956,77 @@ QImage QImage::rgbSwapped() const
const ushort *p = (const ushort*)constScanLine(i);
const ushort *end = p + d->width;
while (p < end) {
- *q = ((*p << 11) & 0xf800) | ((*p >> 11) & 0x1f) | (*p & 0x07e0);
+ ushort c = *p;
+ *q = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
p++;
q++;
}
}
- return res;
+ break;
default:
+ res = QImage(d->width, d->height, d->format);
+ rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]);
break;
}
+ return res;
+}
- res = QImage(d->width, d->height, d->format);
- QIMAGE_SANITYCHECK_MEMORY(res);
- const QPixelLayout *layout = &qPixelLayouts[d->format];
- Q_ASSERT(layout->redWidth == layout->blueWidth);
- FetchPixelsFunc fetch = qFetchPixels[layout->bpp];
- StorePixelsFunc store = qStorePixels[layout->bpp];
+/*!
+ \internal
+*/
+void QImage::rgbSwapped_inplace()
+{
+ if (isNull())
+ return;
- const uint redBlueMask = (1 << layout->redWidth) - 1;
- const uint alphaGreenMask = (((1 << layout->alphaWidth) - 1) << layout->alphaShift)
- | (((1 << layout->greenWidth) - 1) << layout->greenShift);
+ detach();
- const int buffer_size = 2048;
- uint buffer[buffer_size];
- for (int i = 0; i < d->height; ++i) {
- uchar *q = res.scanLine(i);
- const uchar *p = constScanLine(i);
- int x = 0;
- while (x < d->width) {
- int l = qMin(d->width - x, buffer_size);
- const uint *ptr = fetch(buffer, p, x, l);
- for (int j = 0; j < l; ++j) {
- uint red = (ptr[j] >> layout->redShift) & redBlueMask;
- uint blue = (ptr[j] >> layout->blueShift) & redBlueMask;
- buffer[j] = (ptr[j] & alphaGreenMask)
- | (red << layout->blueShift)
- | (blue << layout->redShift);
+ switch (d->format) {
+ case Format_Invalid:
+ case NImageFormats:
+ Q_ASSERT(false);
+ break;
+ case Format_Mono:
+ case Format_MonoLSB:
+ case Format_Indexed8:
+ for (int i = 0; i < d->colortable.size(); i++) {
+ QRgb c = d->colortable.at(i);
+ d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
+ }
+ break;
+ case Format_RGB32:
+ case Format_ARGB32:
+ case Format_ARGB32_Premultiplied:
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ case Format_RGBX8888:
+ case Format_RGBA8888:
+ case Format_RGBA8888_Premultiplied:
+#endif
+ for (int i = 0; i < d->height; i++) {
+ uint *p = (uint*)scanLine(i);
+ uint *end = p + d->width;
+ while (p < end) {
+ uint c = *p;
+ *p = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
+ p++;
}
- store(q, buffer, x, l);
- x += l;
}
+ break;
+ case Format_RGB16:
+ for (int i = 0; i < d->height; i++) {
+ ushort *p = (ushort*)scanLine(i);
+ ushort *end = p + d->width;
+ while (p < end) {
+ ushort c = *p;
+ *p = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
+ p++;
+ }
+ }
+ break;
+ default:
+ rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]);
+ break;
}
- return res;
}
/*!
@@ -6433,10 +4436,12 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla
if (ref.load() > 1)
return false;
- const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat];
+ const InPlace_Image_Converter *const converterPtr = &qimage_inplace_converter_map[format][newFormat];
InPlace_Image_Converter converter = *converterPtr;
if (converter)
return converter(this, flags);
+ else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8)
+ return convert_generic_inplace(this, newFormat, flags);
else
return false;
}
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index bc7f3729ad..4326d5dbbc 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -172,7 +172,19 @@ public:
Format format() const;
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QIMAGE_COMPAT_CPP)
+ QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const & Q_REQUIRED_RESULT
+ { return convertToFormat_helper(f, flags); }
+ QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) && Q_REQUIRED_RESULT
+ {
+ if (convertToFormat_inplace(f, flags))
+ return std::move(*this);
+ else
+ return convertToFormat_helper(f, flags);
+ }
+#else
QImage convertToFormat(Format f, Qt::ImageConversionFlags flags = Qt::AutoColor) const Q_REQUIRED_RESULT;
+#endif
QImage convertToFormat(Format f, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags = Qt::AutoColor) const Q_REQUIRED_RESULT;
int width() const;
@@ -245,8 +257,19 @@ public:
static QMatrix trueMatrix(const QMatrix &, int w, int h);
QImage transformed(const QTransform &matrix, Qt::TransformationMode mode = Qt::FastTransformation) const;
static QTransform trueMatrix(const QTransform &, int w, int h);
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QIMAGE_COMPAT_CPP)
+ QImage mirrored(bool horizontally = false, bool vertically = true) const &
+ { return mirrored_helper(horizontally, vertically); }
+ QImage &&mirrored(bool horizontally = false, bool vertically = true) &&
+ { mirrored_inplace(horizontally, vertically); return qMove(*this); }
+ QImage rgbSwapped() const &
+ { return rgbSwapped_helper(); }
+ QImage &&rgbSwapped() &&
+ { rgbSwapped_inplace(); return qMove(*this); }
+#else
QImage mirrored(bool horizontally = false, bool vertically = true) const;
QImage rgbSwapped() const;
+#endif
void invertPixels(InvertMode = InvertRgb);
@@ -298,6 +321,12 @@ public:
protected:
virtual int metric(PaintDeviceMetric metric) const;
+ QImage mirrored_helper(bool horizontal, bool vertical) const;
+ QImage rgbSwapped_helper() const;
+ void mirrored_inplace(bool horizontal, bool vertical);
+ void rgbSwapped_inplace();
+ QImage convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const;
+ bool convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags);
private:
friend class QWSOnScreenSurface;
diff --git a/src/gui/image/qimage_avx.cpp b/src/gui/image/qimage_compat.cpp
index d04ec5b3de..9acf5c18fa 100644
--- a/src/gui/image/qimage_avx.cpp
+++ b/src/gui/image/qimage_compat.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Intel Corporation
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -39,19 +39,30 @@
**
****************************************************************************/
-#include <private/qsimd_p.h>
+#ifdef QIMAGE_H
+# error "This file cannot be used with precompiled headers"
+#endif
+#define QT_COMPILING_QIMAGE_COMPAT_CPP
-#ifdef QT_COMPILER_SUPPORTS_AVX
+#include "qimage.h"
-#ifndef __AVX__
-#error "AVX not enabled in this file, cannot proceed"
-#endif
+QT_BEGIN_NAMESPACE
-#define convert_ARGB_to_ARGB_PM_inplace_sse2 convert_ARGB_to_ARGB_PM_inplace_avx
-#include "qimage_sse2.cpp"
+// These implementations must be the same as the inline versions in qimage.h
-#define qt_convert_rgb888_to_rgb32_ssse3 qt_convert_rgb888_to_rgb32_avx
-#define convert_RGB888_to_RGB32_ssse3 convert_RGB888_to_RGB32_avx
-#include "qimage_ssse3.cpp"
+QImage QImage::convertToFormat(Format f, Qt::ImageConversionFlags flags) const
+{
+ return convertToFormat_helper(f, flags);
+}
-#endif
+QImage QImage::mirrored(bool horizontally, bool vertically) const
+{
+ return mirrored_helper(horizontally, vertically);
+}
+
+QImage QImage::rgbSwapped() const
+{
+ return rgbSwapped_helper();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
new file mode 100644
index 0000000000..629a7c9b69
--- /dev/null
+++ b/src/gui/image/qimage_conversions.cpp
@@ -0,0 +1,2183 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qdrawhelper_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qsimd_p.h>
+
+#include <private/qimage_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// table to flip bits
+static const uchar bitflip[256] = {
+ /*
+ open OUT, "| fmt";
+ for $i (0..255) {
+ print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
+ (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
+ (($i << 7) & 0x80) | (($i << 5) & 0x40) |
+ (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
+ }
+ close OUT;
+ */
+ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
+};
+
+const uchar *qt_get_bitflip_array()
+{
+ return bitflip;
+}
+
+void qGamma_correct_back_to_linear_cs(QImage *image)
+{
+ const QDrawHelperGammaTables *tables = QGuiApplicationPrivate::instance()->gammaTables();
+ if (!tables)
+ return;
+ const uchar *gamma = tables->qt_pow_rgb_gamma;
+ // gamma correct the pixels back to linear color space...
+ int h = image->height();
+ int w = image->width();
+
+ for (int y=0; y<h; ++y) {
+ uint *pixels = (uint *) image->scanLine(y);
+ for (int x=0; x<w; ++x) {
+ uint p = pixels[x];
+ uint r = gamma[qRed(p)];
+ uint g = gamma[qGreen(p)];
+ uint b = gamma[qBlue(p)];
+ pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
+ }
+ }
+}
+
+/*****************************************************************************
+ Internal routines for converting image depth.
+ *****************************************************************************/
+
+// Cannot be used with indexed formats.
+void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dest->format > QImage::Format_Indexed8);
+ Q_ASSERT(src->format > QImage::Format_Indexed8);
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[src->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dest->format];
+ const uchar *srcData = src->data;
+ uchar *destData = dest->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < src->height; ++y) {
+ int x = 0;
+ while (x < src->width) {
+ int l = qMin(src->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(destData, ptr, x, l);
+ x += l;
+ }
+ srcData += src->bytes_per_line;
+ destData += dest->bytes_per_line;
+ }
+}
+
+// Cannot be used with indexed formats or between formats with different pixel depths.
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dst_format > QImage::Format_Indexed8);
+ Q_ASSERT(data->format > QImage::Format_Indexed8);
+ if (data->depth != qt_depthForFormat(dst_format))
+ return false;
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
+
+ uchar *srcData = data->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < data->height; ++y) {
+ int x = 0;
+ while (x < data->width) {
+ int l = qMin(data->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(srcData, ptr, x, l);
+ x += l;
+ }
+ srcData += data->bytes_per_line;
+ }
+ data->format = dst_format;
+ return true;
+}
+
+static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qPremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
+
+#ifndef __SSE2__
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = PREMUL(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+#endif
+
+static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | *src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ quint32 *rgb_data = (quint32 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const quint32 *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = ARGB2RGBA(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_ARGB32)
+ data->format = QImage::Format_RGBA8888;
+ else
+ data->format = QImage::Format_RGBA8888_Premultiplied;
+ return true;
+}
+
+static void convert_ARGB_to_RGBA_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(qPremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBX8888 || src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBX8888 || data->format == QImage::Format_RGBA8888 || data->format == QImage::Format_RGBA8888_Premultiplied);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = RGBA2ARGB(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ if (data->format == QImage::Format_RGBA8888_Premultiplied)
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ else if (data->format == QImage::Format_RGBX8888)
+ data->format = QImage::Format_RGB32;
+ else
+ data->format = QImage::Format_ARGB32;
+ return true;
+}
+
+static void convert_RGBA_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const quint32 *src_data = (quint32 *) src->data;
+ quint32 *dest_data = (quint32 *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const quint32 *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qPremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGBA8888);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = qPremultiply(RGBA2ARGB(*rgb_data));
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+
+static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes; // end of src
+ quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+ if (data->colortable.size() == 0) {
+ data->colortable.resize(256);
+ for (int i = 0; i < 256; ++i)
+ data->colortable[i] = qRgb(i, i, i);
+ } else {
+ for (int i = 0; i < data->colortable.size(); ++i)
+ data->colortable[i] = qPremultiply(data->colortable.at(i));
+
+ // Fill the rest of the table in case src_data > colortable.size()
+ const int oldSize = data->colortable.size();
+ const QRgb lastColor = data->colortable.at(oldSize - 1);
+ data->colortable.insert(oldSize, 256 - oldSize, lastColor);
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = data->colortable.at(*src_data);
+ }
+ }
+
+ data->colortable = QVector<QRgb>();
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint32 *dest_data = (quint32 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+ if (data->colortable.size() == 0) {
+ data->colortable.resize(256);
+ for (int i = 0; i < 256; ++i)
+ data->colortable[i] = qRgb(i, i, i);
+ } else {
+ // Fill the rest of the table in case src_data > colortable.size()
+ const int oldSize = data->colortable.size();
+ const QRgb lastColor = data->colortable.at(oldSize - 1);
+ data->colortable.insert(oldSize, 256 - oldSize, lastColor);
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = (quint32) data->colortable.at(*src_data);
+ }
+ }
+
+ data->colortable = QVector<QRgb>();
+ data->format = QImage::Format_RGB32;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint16 *dest_data = (quint16 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 1) - width;
+
+ quint16 colorTableRGB16[256];
+ if (data->colortable.isEmpty()) {
+ for (int i = 0; i < 256; ++i)
+ colorTableRGB16[i] = qConvertRgb32To16(qRgb(i, i, i));
+ } else {
+ // 1) convert the existing colors to RGB16
+ const int tableSize = data->colortable.size();
+ for (int i = 0; i < tableSize; ++i)
+ colorTableRGB16[i] = qConvertRgb32To16(data->colortable.at(i));
+ data->colortable = QVector<QRgb>();
+
+ // 2) fill the rest of the table in case src_data > colortable.size()
+ const quint16 lastColor = colorTableRGB16[tableSize - 1];
+ for (int i = tableSize; i < 256; ++i)
+ colorTableRGB16[i] = lastColor;
+ }
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = colorTableRGB16[*src_data];
+ }
+ }
+
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGB32);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int src_bytes_per_line = data->bytes_per_line;
+ quint32 *src_data = (quint32 *) data->data;
+ quint16 *dst_data = (quint16 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ for (int j = 0; j < data->width; ++j)
+ dst_data[j] = qConvertRgb32To16(src_data[j]);
+ src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
+ dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
+ }
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
+ if (newData) {
+ data->data = newData;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qUnpremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied || src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | qUnpremultiply(*src_data);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(0xff000000 | qUnpremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_ARGB_PM_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGBA8888);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(qUnpremultiply(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888 || src->format == QImage::Format_RGBX8888);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = RGBA2ARGB(*src_data) | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32);
+ Q_ASSERT(dest->format == QImage::Format_RGBX8888 || dest->format == QImage::Format_RGBA8888 || dest->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = ARGB2RGBA(*src_data | 0xff000000);
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_ARGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = qUnpremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void convert_RGBA_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGBA8888_Premultiplied);
+ Q_ASSERT(dest->format == QImage::Format_RGB32);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const QRgb *src_data = (QRgb *) src->data;
+ QRgb *dest_data = (QRgb *) dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const QRgb *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = 0xff000000 | qUnpremultiply(RGBA2ARGB(*src_data));
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+ Q_ASSERT(src->nbytes == dest->nbytes);
+ Q_ASSERT(src->bytes_per_line == dest->bytes_per_line);
+
+ dest->colortable = src->colortable;
+
+ const uchar *src_data = src->data;
+ const uchar *end = src->data + src->nbytes;
+ uchar *dest_data = dest->data;
+ while (src_data < end) {
+ *dest_data = bitflip[*src_data];
+ ++src_data;
+ ++dest_data;
+ }
+}
+
+static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0xff000000;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+}
+
+static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return mask_alpha_converter(dest, src, flags);
+#else
+ Q_UNUSED(flags);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ const int src_pad = (src->bytes_per_line >> 2) - src->width;
+ const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
+ const uint *src_data = (const uint *)src->data;
+ uint *dest_data = (uint *)dest->data;
+
+ for (int i = 0; i < src->height; ++i) {
+ const uint *end = src_data + src->width;
+ while (src_data < end) {
+ *dest_data = *src_data | 0x000000ff;
+ ++src_data;
+ ++dest_data;
+ }
+ src_data += src_pad;
+ dest_data += dest_pad;
+ }
+#endif
+}
+
+static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
+{
+ QVector<QRgb> colorTable = ctbl;
+ if (format == QImage::Format_RGB32) {
+ // check if the color table has alpha
+ for (int i = 0; i < colorTable.size(); ++i)
+ if (qAlpha(colorTable.at(i) != 0xff))
+ colorTable[i] = colorTable.at(i) | 0xff000000;
+ } else if (format == QImage::Format_ARGB32_Premultiplied) {
+ // check if the color table has alpha
+ for (int i = 0; i < colorTable.size(); ++i)
+ colorTable[i] = qPremultiply(colorTable.at(i));
+ }
+ return colorTable;
+}
+
+//
+// dither_to_1: Uses selected dithering algorithm.
+//
+
+void dither_to_Mono(QImageData *dst, const QImageData *src,
+ Qt::ImageConversionFlags flags, bool fromalpha)
+{
+ Q_ASSERT(src->width == dst->width);
+ Q_ASSERT(src->height == dst->height);
+ Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
+
+ dst->colortable.clear();
+ dst->colortable.append(0xffffffff);
+ dst->colortable.append(0xff000000);
+
+ enum { Threshold, Ordered, Diffuse } dithermode;
+
+ if (fromalpha) {
+ if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither)
+ dithermode = Diffuse;
+ else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither)
+ dithermode = Ordered;
+ else
+ dithermode = Threshold;
+ } else {
+ if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither)
+ dithermode = Threshold;
+ else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither)
+ dithermode = Ordered;
+ else
+ dithermode = Diffuse;
+ }
+
+ int w = src->width;
+ int h = src->height;
+ int d = src->depth;
+ uchar gray[256]; // gray map for 8 bit images
+ bool use_gray = (d == 8);
+ if (use_gray) { // make gray map
+ if (fromalpha) {
+ // Alpha 0x00 -> 0 pixels (white)
+ // Alpha 0xFF -> 1 pixels (black)
+ for (int i = 0; i < src->colortable.size(); i++)
+ gray[i] = (255 - (src->colortable.at(i) >> 24));
+ } else {
+ // Pixel 0x00 -> 1 pixels (black)
+ // Pixel 0xFF -> 0 pixels (white)
+ for (int i = 0; i < src->colortable.size(); i++)
+ gray[i] = qGray(src->colortable.at(i));
+ }
+ }
+
+ uchar *dst_data = dst->data;
+ int dst_bpl = dst->bytes_per_line;
+ const uchar *src_data = src->data;
+ int src_bpl = src->bytes_per_line;
+
+ switch (dithermode) {
+ case Diffuse: {
+ QScopedArrayPointer<int> lineBuffer(new int[w * 2]);
+ int *line1 = lineBuffer.data();
+ int *line2 = lineBuffer.data() + w;
+ int bmwidth = (w+7)/8;
+
+ int *b1, *b2;
+ int wbytes = w * (d/8);
+ const uchar *p = src->data;
+ const uchar *end = p + wbytes;
+ b2 = line2;
+ if (use_gray) { // 8 bit image
+ while (p < end)
+ *b2++ = gray[*p++];
+ } else { // 32 bit image
+ if (fromalpha) {
+ while (p < end) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while (p < end) {
+ *b2++ = qGray(*(uint*)p);
+ p += 4;
+ }
+ }
+ }
+ for (int y=0; y<h; y++) { // for each scan line...
+ int *tmp = line1; line1 = line2; line2 = tmp;
+ bool not_last_line = y < h - 1;
+ if (not_last_line) { // calc. grayvals for next line
+ p = src->data + (y+1)*src->bytes_per_line;
+ end = p + wbytes;
+ b2 = line2;
+ if (use_gray) { // 8 bit image
+ while (p < end)
+ *b2++ = gray[*p++];
+ } else { // 24 bit image
+ if (fromalpha) {
+ while (p < end) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while (p < end) {
+ *b2++ = qGray(*(uint*)p);
+ p += 4;
+ }
+ }
+ }
+ }
+
+ int err;
+ uchar *p = dst->data + y*dst->bytes_per_line;
+ memset(p, 0, bmwidth);
+ b1 = line1;
+ b2 = line2;
+ int bit = 7;
+ for (int x=1; x<=w; x++) {
+ if (*b1 < 128) { // black pixel
+ err = *b1++;
+ *p |= 1 << bit;
+ } else { // white pixel
+ err = *b1++ - 255;
+ }
+ if (bit == 0) {
+ p++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ if (x < w)
+ *b1 += (err*7)>>4; // spread error to right pixel
+ if (not_last_line) {
+ b2[0] += (err*5)>>4; // pixel below
+ if (x > 1)
+ b2[-1] += (err*3)>>4; // pixel below left
+ if (x < w)
+ b2[1] += err>>4; // pixel below right
+ }
+ b2++;
+ }
+ }
+ } break;
+ case Ordered: {
+
+ memset(dst->data, 0, dst->nbytes);
+ if (d == 32) {
+ for (int i=0; i<h; i++) {
+ const uint *p = (const uint *)src_data;
+ const uint *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ int j = 0;
+ if (fromalpha) {
+ while (p < end) {
+ if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while (p < end) {
+ if ((uint)qGray(*p++) < qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ } else
+ /* (d == 8) */ {
+ for (int i=0; i<h; i++) {
+ const uchar *p = src_data;
+ const uchar *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ int j = 0;
+ while (p < end) {
+ if ((uint)gray[*p++] < qt_bayer_matrix[j++&15][i&15])
+ *m |= 1 << bit;
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ }
+ } break;
+ default: { // Threshold:
+ memset(dst->data, 0, dst->nbytes);
+ if (d == 32) {
+ for (int i=0; i<h; i++) {
+ const uint *p = (const uint *)src_data;
+ const uint *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ if (fromalpha) {
+ while (p < end) {
+ if ((*p++ >> 24) >= 128)
+ *m |= 1 << bit; // Set mask "on"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while (p < end) {
+ if (qGray(*p++) < 128)
+ *m |= 1 << bit; // Set pixel "black"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ } else
+ if (d == 8) {
+ for (int i=0; i<h; i++) {
+ const uchar *p = src_data;
+ const uchar *end = p + w;
+ uchar *m = dst_data;
+ int bit = 7;
+ while (p < end) {
+ if (gray[*p++] < 128)
+ *m |= 1 << bit; // Set mask "on"/ pixel "black"
+ if (bit == 0) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ dst_data += dst_bpl;
+ src_data += src_bpl;
+ }
+ }
+ }
+ }
+
+ if (dst->format == QImage::Format_MonoLSB) {
+ // need to swap bit order
+ uchar *sl = dst->data;
+ int bpl = (dst->width + 7) * dst->depth / 8;
+ int pad = dst->bytes_per_line - bpl;
+ for (int y=0; y<dst->height; ++y) {
+ for (int x=0; x<bpl; ++x) {
+ *sl = bitflip[*sl];
+ ++sl;
+ }
+ sl += pad;
+ }
+ }
+}
+
+static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ dither_to_Mono(dst, src, flags, false);
+}
+
+static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
+ convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
+ dither_to_Mono(dst, tmp.data(), flags, false);
+}
+
+//
+// convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
+// image with a colormap. If the 32 bit image has more than 256 colors,
+// we convert the red,green and blue bytes into a single byte encoded
+// as 6 shades of each of red, green and blue.
+//
+// if dithering is needed, only 1 color at most is available for alpha.
+//
+struct QRgbMap {
+ inline QRgbMap() : used(0) { }
+ uchar pix;
+ uchar used;
+ QRgb rgb;
+};
+
+static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
+ Q_ASSERT(dst->format == QImage::Format_Indexed8);
+ Q_ASSERT(src->width == dst->width);
+ Q_ASSERT(src->height == dst->height);
+
+ bool do_quant = (flags & Qt::DitherMode_Mask) == Qt::PreferDither
+ || src->format == QImage::Format_ARGB32;
+ uint alpha_mask = src->format == QImage::Format_RGB32 ? 0xff000000 : 0;
+
+ const int tablesize = 997; // prime
+ QRgbMap table[tablesize];
+ int pix=0;
+
+ if (!dst->colortable.isEmpty()) {
+ QVector<QRgb> ctbl = dst->colortable;
+ dst->colortable.resize(256);
+ // Preload palette into table.
+ // Almost same code as pixel insertion below
+ for (int i = 0; i < dst->colortable.size(); ++i) {
+ // Find in table...
+ QRgb p = ctbl.at(i) | alpha_mask;
+ int hash = p % tablesize;
+ for (;;) {
+ if (table[hash].used) {
+ if (table[hash].rgb == p) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ Q_ASSERT (pix != 256); // too many colors
+ // Insert into table at this unused position
+ dst->colortable[pix] = p;
+ table[hash].pix = pix++;
+ table[hash].rgb = p;
+ table[hash].used = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ if ((flags & Qt::DitherMode_Mask) != Qt::PreferDither) {
+ dst->colortable.resize(256);
+ const uchar *src_data = src->data;
+ uchar *dest_data = dst->data;
+ for (int y = 0; y < src->height; y++) { // check if <= 256 colors
+ const QRgb *s = (const QRgb *)src_data;
+ uchar *b = dest_data;
+ for (int x = 0; x < src->width; ++x) {
+ QRgb p = s[x] | alpha_mask;
+ int hash = p % tablesize;
+ for (;;) {
+ if (table[hash].used) {
+ if (table[hash].rgb == (p)) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ if (pix == 256) { // too many colors
+ do_quant = true;
+ // Break right out
+ x = src->width;
+ y = src->height;
+ } else {
+ // Insert into table at this unused position
+ dst->colortable[pix] = p;
+ table[hash].pix = pix++;
+ table[hash].rgb = p;
+ table[hash].used = 1;
+ }
+ break;
+ }
+ }
+ *b++ = table[hash].pix; // May occur once incorrectly
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ }
+ int numColors = do_quant ? 256 : pix;
+
+ dst->colortable.resize(numColors);
+
+ if (do_quant) { // quantization needed
+
+#define MAX_R 5
+#define MAX_G 5
+#define MAX_B 5
+#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
+
+ for (int rc=0; rc<=MAX_R; rc++) // build 6x6x6 color cube
+ for (int gc=0; gc<=MAX_G; gc++)
+ for (int bc=0; bc<=MAX_B; bc++)
+ dst->colortable[INDEXOF(rc,gc,bc)] = 0xff000000 | qRgb(rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B);
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dst->data;
+ if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) {
+ for (int y = 0; y < src->height; y++) {
+ const QRgb *p = (const QRgb *)src_data;
+ const QRgb *end = p + src->width;
+ uchar *b = dest_data;
+
+ while (p < end) {
+#define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
+ *b++ =
+ INDEXOF(
+ DITHER(qRed(*p), MAX_R),
+ DITHER(qGreen(*p), MAX_G),
+ DITHER(qBlue(*p), MAX_B)
+ );
+#undef DITHER
+ p++;
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ } else if ((flags & Qt::Dither_Mask) == Qt::DiffuseDither) {
+ int* line1[3];
+ int* line2[3];
+ int* pv[3];
+ QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]);
+ line1[0] = lineBuffer.data();
+ line2[0] = lineBuffer.data() + src->width;
+ line1[1] = lineBuffer.data() + src->width * 2;
+ line2[1] = lineBuffer.data() + src->width * 3;
+ line1[2] = lineBuffer.data() + src->width * 4;
+ line2[2] = lineBuffer.data() + src->width * 5;
+ pv[0] = lineBuffer.data() + src->width * 6;
+ pv[1] = lineBuffer.data() + src->width * 7;
+ pv[2] = lineBuffer.data() + src->width * 8;
+
+ int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian);
+ for (int y = 0; y < src->height; y++) {
+ const uchar* q = src_data;
+ const uchar* q2 = y < src->height - 1 ? q + src->bytes_per_line : src->data;
+ uchar *b = dest_data;
+ for (int chan = 0; chan < 3; chan++) {
+ int *l1 = (y&1) ? line2[chan] : line1[chan];
+ int *l2 = (y&1) ? line1[chan] : line2[chan];
+ if (y == 0) {
+ for (int i = 0; i < src->width; i++)
+ l1[i] = q[i*4+chan+endian];
+ }
+ if (y+1 < src->height) {
+ for (int i = 0; i < src->width; i++)
+ l2[i] = q2[i*4+chan+endian];
+ }
+ // Bi-directional error diffusion
+ if (y&1) {
+ for (int x = 0; x < src->width; x++) {
+ int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if (x + 1< src->width) {
+ l1[x+1] += (err*7)>>4;
+ l2[x+1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x>1)
+ l2[x-1]+=(err*3)>>4;
+ }
+ } else {
+ for (int x = src->width; x-- > 0;) {
+ int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if (x > 0) {
+ l1[x-1] += (err*7)>>4;
+ l2[x-1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x + 1 < src->width)
+ l2[x+1]+=(err*3)>>4;
+ }
+ }
+ }
+ if (endian) {
+ for (int x = 0; x < src->width; x++) {
+ *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
+ }
+ } else {
+ for (int x = 0; x < src->width; x++) {
+ *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
+ }
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ } else { // OrderedDither
+ for (int y = 0; y < src->height; y++) {
+ const QRgb *p = (const QRgb *)src_data;
+ const QRgb *end = p + src->width;
+ uchar *b = dest_data;
+
+ int x = 0;
+ while (p < end) {
+ uint d = qt_bayer_matrix[y & 15][x & 15] << 8;
+
+#define DITHER(p, d, m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) >> 16))
+ *b++ =
+ INDEXOF(
+ DITHER(qRed(*p), d, MAX_R),
+ DITHER(qGreen(*p), d, MAX_G),
+ DITHER(qBlue(*p), d, MAX_B)
+ );
+#undef DITHER
+
+ p++;
+ x++;
+ }
+ src_data += src->bytes_per_line;
+ dest_data += dst->bytes_per_line;
+ }
+ }
+
+ if (src->format != QImage::Format_RGB32
+ && src->format != QImage::Format_RGB16) {
+ const int trans = 216;
+ Q_ASSERT(dst->colortable.size() > trans);
+ dst->colortable[trans] = 0;
+ QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono));
+ dither_to_Mono(mask.data(), src, flags, true);
+ uchar *dst_data = dst->data;
+ const uchar *mask_data = mask->data;
+ for (int y = 0; y < src->height; y++) {
+ for (int x = 0; x < src->width ; x++) {
+ if (!(mask_data[x>>3] & (0x80 >> (x & 7))))
+ dst_data[x] = trans;
+ }
+ mask_data += mask->bytes_per_line;
+ dst_data += dst->bytes_per_line;
+ }
+ dst->has_alpha_clut = true;
+ }
+
+#undef MAX_R
+#undef MAX_G
+#undef MAX_B
+#undef INDEXOF
+
+ }
+}
+
+static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
+ convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
+ convert_RGB_to_Indexed8(dst, tmp.data(), flags);
+}
+
+static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
+{
+ convert_RGB_to_Indexed8(dst, src, flags);
+}
+
+static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Indexed8);
+ Q_ASSERT(dest->format == QImage::Format_RGB32
+ || dest->format == QImage::Format_ARGB32
+ || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
+ if (colorTable.size() == 0) {
+ colorTable.resize(256);
+ for (int i=0; i<256; ++i)
+ colorTable[i] = qRgb(i, i, i);
+ }
+
+ int w = src->width;
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ int tableSize = colorTable.size() - 1;
+ for (int y = 0; y < src->height; y++) {
+ uint *p = (uint *)dest_data;
+ const uchar *b = src_data;
+ uint *end = p + w;
+
+ while (p < end)
+ *p++ = colorTable.at(qMin<int>(tableSize, *b++));
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+}
+
+static void convert_Mono_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_RGB32
+ || dest->format == QImage::Format_ARGB32
+ || dest->format == QImage::Format_ARGB32_Premultiplied);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
+
+ // Default to black / white colors
+ if (colorTable.size() < 2) {
+ if (colorTable.size() == 0)
+ colorTable << 0xff000000;
+ colorTable << 0xffffffff;
+ }
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ if (src->format == QImage::Format_Mono) {
+ for (int y = 0; y < dest->height; y++) {
+ uint *p = (uint *)dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = colorTable.at((src_data[x>>3] >> (7 - (x & 7))) & 1);
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ } else {
+ for (int y = 0; y < dest->height; y++) {
+ uint *p = (uint *)dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = colorTable.at((src_data[x>>3] >> (x & 7)) & 1);
+
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ }
+}
+
+
+static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
+ Q_ASSERT(dest->format == QImage::Format_Indexed8);
+ Q_ASSERT(src->width == dest->width);
+ Q_ASSERT(src->height == dest->height);
+
+ QVector<QRgb> ctbl = src->colortable;
+ if (ctbl.size() > 2) {
+ ctbl.resize(2);
+ } else if (ctbl.size() < 2) {
+ if (ctbl.size() == 0)
+ ctbl << 0xff000000;
+ ctbl << 0xffffffff;
+ }
+ dest->colortable = ctbl;
+ dest->has_alpha_clut = src->has_alpha_clut;
+
+
+ const uchar *src_data = src->data;
+ uchar *dest_data = dest->data;
+ if (src->format == QImage::Format_Mono) {
+ for (int y = 0; y < dest->height; y++) {
+ uchar *p = dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = (src_data[x>>3] >> (7 - (x & 7))) & 1;
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ } else {
+ for (int y = 0; y < dest->height; y++) {
+ uchar *p = dest_data;
+ for (int x = 0; x < dest->width; x++)
+ *p++ = (src_data[x>>3] >> (x & 7)) & 1;
+ src_data += src->bytes_per_line;
+ dest_data += dest->bytes_per_line;
+ }
+ }
+}
+
+// first index source, second dest
+Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+{
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 0,
+ 0,
+ swap_bit_order,
+ convert_Mono_to_Indexed8,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_Mono
+
+ {
+ 0,
+ swap_bit_order,
+ 0,
+ convert_Mono_to_Indexed8,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ convert_Mono_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_MonoLSB
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ 0,
+ convert_Indexed8_to_X32,
+ convert_Indexed8_to_X32,
+ convert_Indexed8_to_X32,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_Indexed8
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ convert_RGB_to_Indexed8,
+ 0,
+ mask_alpha_converter,
+ mask_alpha_converter,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA,
+ convert_RGB_to_RGBA
+ }, // Format_RGB32
+
+ {
+ 0,
+ convert_X_to_Mono,
+ convert_X_to_Mono,
+ convert_ARGB_to_Indexed8,
+ mask_alpha_converter,
+ 0,
+ convert_ARGB_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBx,
+ convert_ARGB_to_RGBA,
+ convert_ARGB_to_RGBA_PM,
+ }, // Format_ARGB32
+
+ {
+ 0,
+ convert_ARGB_PM_to_Mono,
+ convert_ARGB_PM_to_Mono,
+ convert_ARGB_PM_to_Indexed8,
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_PM_to_RGBx,
+ convert_ARGB_PM_to_RGBA,
+ convert_ARGB_to_RGBA,
+ }, // Format_ARGB32_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB16
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB8565_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB666
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB6666_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB555
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB8555_Premultiplied
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_RGB444
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+ mask_alpha_converter_RGBx,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_RGB,
+ convert_RGBA_to_ARGB,
+ convert_RGBA_to_ARGB_PM,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ mask_alpha_converter_RGBx,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ 0,
+ convert_ARGB_to_ARGB_PM,
+#else
+ 0,
+ 0
+#endif
+ }, // Format_RGBA8888
+
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_PM_to_RGB,
+ convert_RGBA_PM_to_ARGB,
+ convert_RGBA_to_ARGB,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ convert_ARGB_PM_to_RGB,
+ convert_ARGB_PM_to_ARGB,
+ 0,
+#else
+ 0,
+ 0,
+ 0
+#endif
+ } // Format_RGBA8888_Premultiplied
+};
+
+InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+{
+ {
+ 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, 0, 0, 0, 0, 0
+ }, // Format_Mono
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_MonoLSB
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_indexed8_to_RGB_inplace,
+ convert_indexed8_to_ARGB_PM_inplace,
+ convert_indexed8_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_Indexed8
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGB32
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+#ifdef __SSE2__
+ convert_ARGB_to_ARGB_PM_inplace_sse2,
+#else
+ convert_ARGB_to_ARGB_PM_inplace,
+#endif
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace,
+ 0,
+ }, // Format_ARGB32
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_RGBA_inplace
+ }, // Format_ARGB32_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB16
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8565_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB666
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB6666_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB555
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8555_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB888
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB444
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB4444_Premultiplied
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBX8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ convert_RGBA_to_ARGB_PM_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_RGBA8888
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGBA_to_ARGB_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ } // Format_RGBA8888_Premultiplied
+};
+
+void qInitImageConversions()
+{
+#if defined(__SSE2__) && defined(QT_COMPILER_SUPPORTS_SSSE3)
+ if (qCpuHasFeature(SSSE3)) {
+ extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
+ }
+#endif
+
+#ifdef __ARM_NEON__
+ extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
+ qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
+#endif
+
+#ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2
+ extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags);
+ inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2;
+ return;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp
index 1ac0a87272..60c2da6a58 100644
--- a/src/gui/image/qimage_neon.cpp
+++ b/src/gui/image/qimage_neon.cpp
@@ -43,7 +43,7 @@
#include <private/qimage_p.h>
#include <private/qsimd_p.h>
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
QT_BEGIN_NAMESPACE
@@ -111,4 +111,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 36f117df60..81730b92f2 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -108,7 +108,20 @@ struct Q_GUI_EXPORT QImageData { // internal image data
QPaintEngine *paintEngine;
};
+typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
+
+extern Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats];
+extern InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats];
+
+void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags);
+
+void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);
+
void qInitImageConversions();
+
+const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
inline int qt_depthForFormat(QImage::Format format)
diff --git a/src/gui/image/qimage_sse2.cpp b/src/gui/image/qimage_sse2.cpp
index 0d6eac4ea2..037846c9aa 100644
--- a/src/gui/image/qimage_sse2.cpp
+++ b/src/gui/image/qimage_sse2.cpp
@@ -94,7 +94,7 @@ bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionF
if (*p < 0x00ffffff)
*p = 0;
else if (*p < 0xff000000)
- *p = PREMUL(*p);
+ *p = qPremultiply(*p);
}
d = reinterpret_cast<__m128i*>(p+pad);
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 636d86991b..091837b8b4 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -190,37 +190,36 @@ enum _qt_BuiltInFormatType {
struct _qt_BuiltInFormatStruct
{
- _qt_BuiltInFormatType type;
const char *extension;
const char *mimeType;
};
static const _qt_BuiltInFormatStruct _qt_BuiltInFormats[] = {
#ifndef QT_NO_IMAGEFORMAT_PNG
- {_qt_PngFormat, "png", "image/png"},
+ {"png", "image/png"},
#endif
#ifndef QT_NO_IMAGEFORMAT_JPEG
- {_qt_JpgFormat, "jpg", "image/jpeg"},
- {_qt_JpegFormat, "jpeg", "image/jpeg"},
+ {"jpg", "image/jpeg"},
+ {"jpeg", "image/jpeg"},
#endif
#ifdef QT_BUILTIN_GIF_READER
- {_qt_GifFormat, "gif", "image/gif"},
+ {"gif", "image/gif"},
#endif
#ifndef QT_NO_IMAGEFORMAT_BMP
- {_qt_BmpFormat, "bmp", "image/bmp"},
+ {"bmp", "image/bmp"},
#endif
#ifndef QT_NO_IMAGEFORMAT_PPM
- {_qt_PpmFormat, "ppm", "image/x-portable-pixmap"},
- {_qt_PgmFormat, "pgm", "image/x-portable-graymap"},
- {_qt_PbmFormat, "pbm", "image/x-portable-bitmap"},
+ {"ppm", "image/x-portable-pixmap"},
+ {"pgm", "image/x-portable-graymap"},
+ {"pbm", "image/x-portable-bitmap"},
#endif
#ifndef QT_NO_IMAGEFORMAT_XBM
- {_qt_XbmFormat, "xbm", "image/x-xbitmap"},
+ {"xbm", "image/x-xbitmap"},
#endif
#ifndef QT_NO_IMAGEFORMAT_XPM
- {_qt_XpmFormat, "xpm", "image/x-xpixmap"},
+ {"xpm", "image/x-xpixmap"},
#endif
- {_qt_NoFormat, "", ""}
+ {"", ""}
};
static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
@@ -423,10 +422,8 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray subType;
int numFormats = _qt_NumFormats;
while (device && numFormats >= 0) {
- const _qt_BuiltInFormatStruct *formatStruct = &_qt_BuiltInFormats[currentFormat];
-
const qint64 pos = device->pos();
- switch (formatStruct->type) {
+ switch (currentFormat) {
#ifndef QT_NO_IMAGEFORMAT_PNG
case _qt_PngFormat:
if (QPngHandler::canRead(device))
@@ -482,7 +479,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (handler) {
#ifdef QIMAGEREADER_DEBUG
- qDebug() << "QImageReader::createReadHandler: the" << formatStruct->extension
+ qDebug() << "QImageReader::createReadHandler: the" << _qt_BuiltInFormats[currentFormat].extension
<< "built-in handler can read this data";
#endif
break;
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 3f90bb42f0..bd358b7228 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -861,24 +861,18 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_avx(quint32 *dst, const
QJpegHandler::QJpegHandler()
: d(new QJpegHandlerPrivate(this))
{
-#if defined(QT_COMPILER_SUPPORTS_NEON)
+#if defined(__ARM_NEON__)
// from qimage_neon.cpp
if (qCpuHasFeature(NEON))
rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
#if defined(QT_COMPILER_SUPPORTS_SSSE3)
// from qimage_ssse3.cpp
if (false) {
-# if defined(QT_COMPILER_SUPPORTS_AVX)
- } else if (qCpuHasFeature(AVX)) {
- rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_avx;
-# endif
-# ifndef __AVX__
} else if (qCpuHasFeature(SSSE3)) {
rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3;
-# endif
}
#endif // QT_COMPILER_SUPPORTS_SSSE3
}
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 6dced54d20..86c4dfbdca 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1617,6 +1617,28 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
}
/*!
+ \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
+ \since 5.3
+ \overload
+
+ Converts the given \a image to a pixmap without copying if possible.
+*/
+
+
+/*!
+ \internal
+*/
+QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
+{
+ if (image.isNull())
+ return QPixmap();
+
+ QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
+ data->fromImageInPlace(image, flags);
+ return QPixmap(data.take());
+}
+
+/*!
\fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
Create a QPixmap from an image read directly from an \a imageReader.
diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h
index f1fce03c80..0efd606283 100644
--- a/src/gui/image/qpixmap.h
+++ b/src/gui/image/qpixmap.h
@@ -131,6 +131,12 @@ public:
QImage toImage() const;
static QPixmap fromImage(const QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
static QPixmap fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags = Qt::AutoColor);
+#ifdef Q_COMPILER_RVALUE_REFS
+ static QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags = Qt::AutoColor)
+ {
+ return fromImageInPlace(image, flags);
+ }
+#endif
bool load(const QString& fileName, const char *format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
bool loadFromData(const uchar *buf, uint len, const char* format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor);
@@ -167,6 +173,7 @@ public:
protected:
int metric(PaintDeviceMetric) const;
+ static QPixmap fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags = Qt::AutoColor);
private:
QExplicitlySharedDataPointer<QPlatformPixmap> data;
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp
index 4c1b30a6d8..839a7a709f 100644
--- a/src/gui/image/qpixmap_blitter.cpp
+++ b/src/gui/image/qpixmap_blitter.cpp
@@ -148,7 +148,7 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
m_alpha = true;
}
- uint pixel = PREMUL(color.rgba());
+ uint pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[blittable()->lock()->format()];
Q_ASSERT(layout->convertFromARGB32PM);
layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index f9a017c281..1465fea8b9 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -135,11 +135,16 @@ bool QRasterPlatformPixmap::fromData(const uchar *buffer, uint len, const char *
void QRasterPlatformPixmap::fromImage(const QImage &sourceImage,
Qt::ImageConversionFlags flags)
{
- Q_UNUSED(flags);
QImage image = sourceImage;
createPixmapForImage(image, flags, /* inplace = */false);
}
+void QRasterPlatformPixmap::fromImageInPlace(QImage &sourceImage,
+ Qt::ImageConversionFlags flags)
+{
+ createPixmapForImage(sourceImage, flags, /* inplace = */true);
+}
+
void QRasterPlatformPixmap::fromImageReader(QImageReader *imageReader,
Qt::ImageConversionFlags flags)
{
@@ -182,7 +187,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
QImage::Format toFormat;
-#if !(defined(QT_COMPILER_SUPPORTS_NEON) || defined(__SSE2__))
+#if !(defined(__ARM_NEON__) || defined(__SSE2__))
if (image.format() == QImage::Format_RGB16)
toFormat = QImage::Format_ARGB8565_Premultiplied;
else if (image.format() == QImage::Format_RGB666)
@@ -203,7 +208,7 @@ void QRasterPlatformPixmap::fill(const QColor &color)
}
}
}
- pixel = PREMUL(color.rgba());
+ pixel = qPremultiply(color.rgba());
const QPixelLayout *layout = &qPixelLayouts[image.format()];
layout->convertFromARGB32PM(&pixel, &pixel, 1, layout, 0);
} else {
@@ -311,7 +316,7 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
QImage::Format opaqueFormat = QNativeImage::systemFormat();
QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-#if !defined(QT_COMPILER_SUPPORTS_NEON) && !defined(__SSE2__)
+#if !defined(__ARM_NEON__) && !defined(__SSE2__)
switch (opaqueFormat) {
case QImage::Format_RGB16:
alphaFormat = QImage::Format_ARGB8565_Premultiplied;
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index cef8821888..b273d65c9f 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -69,6 +69,7 @@ public:
void resize(int width, int height);
bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
+ void fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags);
void fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags);
void copy(const QPlatformPixmap *data, const QRect &rect);
diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h
index 08e03f10bd..435811eb84 100644
--- a/src/gui/image/qplatformpixmap.h
+++ b/src/gui/image/qplatformpixmap.h
@@ -69,7 +69,8 @@ public:
};
enum ClassId { RasterClass, DirectFBClass,
- BlitterClass, CustomClass = 1024 };
+ BlitterClass, Direct2DClass,
+ CustomClass = 1024 };
QPlatformPixmap(PixelType pixelType, int classId);
virtual ~QPlatformPixmap();
@@ -79,6 +80,12 @@ public:
virtual void resize(int width, int height) = 0;
virtual void fromImage(const QImage &image,
Qt::ImageConversionFlags flags) = 0;
+ virtual void fromImageInPlace(QImage &image,
+ Qt::ImageConversionFlags flags)
+ {
+ fromImage(image, flags);
+ }
+
virtual void fromImageReader(QImageReader *imageReader,
Qt::ImageConversionFlags flags);
diff --git a/src/gui/image/qpnghandler.pri b/src/gui/image/qpnghandler.pri
index bedf23ff12..aca7e2c568 100644
--- a/src/gui/image/qpnghandler.pri
+++ b/src/gui/image/qpnghandler.pri
@@ -2,7 +2,7 @@ INCLUDEPATH *= $$PWD
HEADERS += $$PWD/qpnghandler_p.h
SOURCES += $$PWD/qpnghandler.cpp
contains(QT_CONFIG, system-png) {
- if(unix|win32-g++*): LIBS_PRIVATE += -lpng
+ if(unix|mingw): LIBS_PRIVATE += -lpng
else:win32: LIBS += libpng.lib
} else {
diff --git a/src/gui/image/qxbmhandler.cpp b/src/gui/image/qxbmhandler.cpp
index aceb6623ea..5311afd745 100644
--- a/src/gui/image/qxbmhandler.cpp
+++ b/src/gui/image/qxbmhandler.cpp
@@ -103,7 +103,7 @@ static bool read_xbm_header(QIODevice *device, int& w, int& h)
// "#define .._height <num>"
readBytes = device->readLine(buf, buflen);
if (readBytes <= 0)
- return false;
+ return false;
buf[readBytes - 1] = '\0';
sbuf = QString::fromLatin1(buf);
@@ -183,9 +183,9 @@ static bool read_xbm_image(QIODevice *device, QImage *outImage)
static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const QString &fileName)
{
QImage image = sourceImage;
- int w = image.width();
- int h = image.height();
- int i;
+ int w = image.width();
+ int h = image.height();
+ int i;
QString s = fileName; // get file base name
int msize = s.length() + 100;
char *buf = new char[msize];
@@ -203,16 +203,16 @@ static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const
bool invert = qGray(image.color(0)) < qGray(image.color(1));
char hexrep[16];
for (i=0; i<10; i++)
- hexrep[i] = '0' + i;
+ hexrep[i] = '0' + i;
for (i=10; i<16; i++)
- hexrep[i] = 'a' -10 + i;
+ hexrep[i] = 'a' -10 + i;
if (invert) {
- char t;
- for (i=0; i<8; i++) {
- t = hexrep[15-i];
- hexrep[15-i] = hexrep[i];
- hexrep[i] = t;
- }
+ char t;
+ for (i=0; i<8; i++) {
+ t = hexrep[15-i];
+ hexrep[15-i] = hexrep[i];
+ hexrep[i] = t;
+ }
}
int bcnt = 0;
char *p = buf;
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index d9bcbf316f..e9e4a1d818 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -121,7 +121,8 @@ SOURCES += \
kernel/qplatformservices.cpp \
kernel/qplatformscreenpageflipper.cpp \
kernel/qplatformsystemtrayicon_qpa.cpp \
- kernel/qplatformsessionmanager.cpp
+ kernel/qplatformsessionmanager.cpp \
+ kernel/qplatformmenu.cpp
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 91aae94730..465c04cdc8 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -103,7 +103,7 @@ QT_BEGIN_NAMESPACE
\sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime,
{Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example},
- {Fridge Magnets Example}
+ {Fridge Magnets Example}
*/
/*!
@@ -253,8 +253,8 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
loop. Other events are still delivered to the application while
the operation is performed. On Windows, the Qt event loop is
blocked during the operation. However, QDrag::exec() on
- Windows causes processEvents() to be called frequently to keep the GUI responsive.
- If any loops or operations are called while a drag operation is active, it will block the drag operation.
+ Windows causes processEvents() to be called frequently to keep the GUI responsive.
+ If any loops or operations are called while a drag operation is active, it will block the drag operation.
*/
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defaultDropAction)
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 131f1863a5..7759e812cb 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -274,6 +274,38 @@ QMouseEvent::~QMouseEvent()
{
}
+/*!
+ \since 5.3
+
+ Returns information about the mouse event source.
+
+ The mouse event source can be used to distinguish between genuine
+ and artificial mouse events. The latter are events that are
+ synthesized from touch events by the operating system or Qt itself.
+
+ \note Many platforms provide no such information. On such platforms
+ \l Qt::MouseEventNotSynthesized is returned always.
+
+ \sa Qt::MouseEventSource
+ */
+Qt::MouseEventSource QMouseEvent::source() const
+{
+ return QGuiApplicationPrivate::mouseEventSource(this);
+}
+
+/*!
+ \since 5.3
+
+ Returns the mouse event flags.
+
+ The mouse event flags provide additional information about a mouse event.
+
+ \sa Qt::MouseEventFlag
+ */
+Qt::MouseEventFlags QMouseEvent::flags() const
+{
+ return QGuiApplicationPrivate::mouseEventFlags(this);
+}
/*!
\fn QPointF QMouseEvent::localPos() const
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index d22e423248..0a826284c9 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -135,6 +135,9 @@ public:
QT_DEPRECATED inline QPointF posF() const { return l; }
#endif
+ Qt::MouseEventSource source() const;
+ Qt::MouseEventFlags flags() const;
+
protected:
QPointF l, w, s;
Qt::MouseButton b;
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c935a45085..c587e51299 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -59,6 +59,7 @@
#include <QtCore/qmutex.h>
#include <QtCore/private/qthread_p.h>
#include <QtCore/qdir.h>
+#include <QtCore/qlibraryinfo.h>
#include <QtCore/qnumeric.h>
#include <QtDebug>
#ifndef QT_NO_ACCESSIBILITY
@@ -132,6 +133,8 @@ enum ApplicationResourceFlags
static unsigned applicationResourceFlags = 0;
+QIcon *QGuiApplicationPrivate::app_icon = 0;
+
QString *QGuiApplicationPrivate::platform_name = 0;
QString *QGuiApplicationPrivate::displayName = 0;
@@ -490,6 +493,8 @@ static QWindowGeometrySpecification windowGeometrySpecification;
Qt::RightToLeft
\li \c{-session} \e session, restores the application from an earlier
\l{Session Management}{session}.
+ \li -qwindowgeometry, sets the geometry of the first window
+ \li -qwindowtitle, sets the title of the first window
\endlist
The following standard command line options are available for X11:
@@ -565,6 +570,8 @@ QGuiApplication::~QGuiApplication()
d->cursor_list.clear();
#endif
+ delete QGuiApplicationPrivate::app_icon;
+ QGuiApplicationPrivate::app_icon = 0;
delete QGuiApplicationPrivate::platform_name;
QGuiApplicationPrivate::platform_name = 0;
delete QGuiApplicationPrivate::displayName;
@@ -960,11 +967,14 @@ QString QGuiApplication::platformName()
*QGuiApplicationPrivate::platform_name : QString();
}
-static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, int &argc, char **argv)
+static void init_platform(const QString &pluginArgument, const QString &platformPluginPath, const QString &platformThemeName, int &argc, char **argv)
{
// Split into platform name and arguments
QStringList arguments = pluginArgument.split(QLatin1Char(':'));
const QString name = arguments.takeFirst().toLower();
+ QString argumentsKey = name;
+ argumentsKey[0] = argumentsKey.at(0).toUpper();
+ arguments.append(QLibraryInfo::platformPluginArguments(argumentsKey));
// Create the platform integration.
QGuiApplicationPrivate::platform_integration = QPlatformIntegrationFactory::create(name, arguments, argc, argv, platformPluginPath);
@@ -991,15 +1001,21 @@ static void init_platform(const QString &pluginArgument, const QString &platform
}
// Create the platform theme:
- // 1) Ask the platform integration for a list of names.
- const QStringList themeNames = QGuiApplicationPrivate::platform_integration->themeNames();
+
+ // 1) Fetch the platform name from the environment if present.
+ QStringList themeNames;
+ if (!platformThemeName.isEmpty())
+ themeNames.append(platformThemeName);
+
+ // 2) Ask the platform integration for a list of names and try loading them.
+ themeNames += QGuiApplicationPrivate::platform_integration->themeNames();
foreach (const QString &themeName, themeNames) {
QGuiApplicationPrivate::platform_theme = QPlatformThemeFactory::create(themeName, platformPluginPath);
if (QGuiApplicationPrivate::platform_theme)
break;
}
- // 2) If none found, look for a theme plugin. Theme plugins are located in the
+ // 3) If none found, look for a theme plugin. Theme plugins are located in the
// same directory as platform plugins.
if (!QGuiApplicationPrivate::platform_theme) {
foreach (const QString &themeName, themeNames) {
@@ -1010,7 +1026,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform
// No error message; not having a theme plugin is allowed.
}
- // 3) Fall back on the built-in "null" platform theme.
+ // 4) Fall back on the built-in "null" platform theme.
if (!QGuiApplicationPrivate::platform_theme)
QGuiApplicationPrivate::platform_theme = new QPlatformTheme;
@@ -1070,6 +1086,8 @@ void QGuiApplicationPrivate::createPlatformIntegration()
platformName = platformNameEnv;
}
+ QString platformThemeName = QString::fromLocal8Bit(qgetenv("QT_QPA_PLATFORMTHEME"));
+
// Get command line params
int j = argc ? 1 : 0;
@@ -1079,15 +1097,23 @@ void QGuiApplicationPrivate::createPlatformIntegration()
continue;
}
QByteArray arg = argv[i];
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
if (arg == "-platformpluginpath") {
if (++i < argc)
platformPluginPath = QLatin1String(argv[i]);
} else if (arg == "-platform") {
if (++i < argc)
platformName = argv[i];
+ } else if (arg == "-platformtheme") {
+ if (++i < argc)
+ platformThemeName = QString::fromLocal8Bit(argv[i]);
} else if (arg == "-qwindowgeometry" || (platformName == "xcb" && arg == "-geometry")) {
if (++i < argc)
windowGeometrySpecification = QWindowGeometrySpecification::fromArgument(argv[i]);
+ } else if (arg == "-qwindowtitle" || (platformName == "xcb" && arg == "-title")) {
+ if (++i < argc)
+ firstWindowTitle = QString::fromLocal8Bit(argv[i]);
} else {
argv[j++] = argv[i];
}
@@ -1098,7 +1124,7 @@ void QGuiApplicationPrivate::createPlatformIntegration()
argc = j;
}
- init_platform(QLatin1String(platformName), platformPluginPath, argc, argv);
+ init_platform(QLatin1String(platformName), platformPluginPath, platformThemeName, argc, argv);
}
@@ -1156,6 +1182,8 @@ void QGuiApplicationPrivate::init()
continue;
}
QByteArray arg = argv[i];
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
if (arg == "-plugin") {
if (++i < argc)
pluginList << argv[i];
@@ -1644,6 +1672,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers);
ev.setTimestamp(e->timestamp);
+ setMouseEventSource(&ev, e->source);
#ifndef QT_NO_CURSOR
if (!e->synthetic) {
if (const QScreen *screen = window->screen())
@@ -1657,6 +1686,11 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
return;
}
+ if (doubleClick && (ev.type() == QEvent::MouseButtonPress)) {
+ // QtBUG-25831, used to suppress delivery in qwidgetwindow.cpp
+ setMouseEventFlags(&ev, ev.flags() | Qt::MouseEventCreatedDoubleClick);
+ }
+
QGuiApplication::sendSpontaneousEvent(window, &ev);
if (!e->synthetic && !ev.isAccepted()
&& !frameStrut
@@ -1694,11 +1728,14 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
}
if (doubleClick) {
mousePressButton = Qt::NoButton;
- const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
- QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
- button, buttons, e->modifiers);
- dblClickEvent.setTimestamp(e->timestamp);
- QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
+ if (!e->window.isNull()) { // QTBUG-36364, check if window closed in response to press
+ const QEvent::Type doubleClickType = frameStrut ? QEvent::NonClientAreaMouseButtonDblClick : QEvent::MouseButtonDblClick;
+ QMouseEvent dblClickEvent(doubleClickType, localPoint, localPoint, globalPoint,
+ button, buttons, e->modifiers);
+ dblClickEvent.setTimestamp(e->timestamp);
+ setMouseEventSource(&dblClickEvent, e->source);
+ QGuiApplication::sendSpontaneousEvent(window, &dblClickEvent);
+ }
}
}
@@ -2114,7 +2151,8 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
synthIt->pos,
synthIt->screenPos,
Qt::NoButton,
- e->modifiers);
+ e->modifiers,
+ Qt::MouseEventSynthesizedByQt);
fake.synthetic = true;
processMouseEvent(&fake);
}
@@ -2634,6 +2672,35 @@ void QGuiApplicationPrivate::notifyActiveWindowChange(QWindow *)
{
}
+/*!
+ \property QGuiApplication::windowIcon
+ \brief the default window icon
+
+ \sa QWindow::setIcon(), {Setting the Application Icon}
+*/
+QIcon QGuiApplication::windowIcon()
+{
+ return QGuiApplicationPrivate::app_icon ? *QGuiApplicationPrivate::app_icon : QIcon();
+}
+
+void QGuiApplication::setWindowIcon(const QIcon &icon)
+{
+ if (!QGuiApplicationPrivate::app_icon)
+ QGuiApplicationPrivate::app_icon = new QIcon();
+ *QGuiApplicationPrivate::app_icon = icon;
+ if (QGuiApplicationPrivate::is_app_running && !QGuiApplicationPrivate::is_app_closing)
+ QGuiApplicationPrivate::self->notifyWindowIconChanged();
+}
+
+void QGuiApplicationPrivate::notifyWindowIconChanged()
+{
+ QEvent ev(QEvent::ApplicationWindowIconChange);
+ const QWindowList list = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < list.size(); ++i)
+ QCoreApplication::sendEvent(list.at(i), &ev);
+}
+
+
/*!
\property QGuiApplication::quitOnLastWindowClosed
@@ -2701,6 +2768,27 @@ bool QGuiApplicationPrivate::shouldQuitInternal(const QWindowList &processedWind
return true;
}
+bool QGuiApplicationPrivate::tryCloseAllWindows()
+{
+ return tryCloseRemainingWindows(QWindowList());
+}
+
+bool QGuiApplicationPrivate::tryCloseRemainingWindows(QWindowList processedWindows)
+{
+ QWindowList list = QGuiApplication::topLevelWindows();
+ for (int i = 0; i < list.size(); ++i) {
+ QWindow *w = list.at(i);
+ if (w->isVisible() && !processedWindows.contains(w)) {
+ if (!w->close())
+ return false;
+ processedWindows.append(w);
+ list = QGuiApplication::topLevelWindows();
+ i = -1;
+ }
+ }
+ return true;
+}
+
/*!
\since 5.2
\fn Qt::ApplicationState QGuiApplication::applicationState()
@@ -2907,23 +2995,8 @@ void QGuiApplicationPrivate::commitData()
Q_Q(QGuiApplication);
is_saving_session = true;
emit q->commitDataRequest(*session_manager);
- if (session_manager->allowsInteraction()) {
- QWindowList done;
- QWindowList list = QGuiApplication::topLevelWindows();
- bool cancelled = false;
- for (int i = 0; !cancelled && i < list.size(); ++i) {
- QWindow* w = list.at(i);
- if (w->isVisible() && !done.contains(w)) {
- cancelled = !w->close();
- if (!cancelled)
- done.append(w);
- list = QGuiApplication::topLevelWindows();
- i = -1;
- }
- }
- if (cancelled)
- session_manager->cancel();
- }
+ if (session_manager->allowsInteraction() && !tryCloseAllWindows())
+ session_manager->cancel();
is_saving_session = false;
}
@@ -3219,9 +3292,18 @@ void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object)
emit q->focusObjectChanged(object);
}
+enum {
+ MouseCapsMask = 0xFF,
+ MouseSourceMaskDst = 0xFF00,
+ MouseSourceMaskSrc = MouseCapsMask,
+ MouseSourceShift = 8,
+ MouseFlagsCapsMask = 0xFF0000,
+ MouseFlagsShift = 16
+};
+
int QGuiApplicationPrivate::mouseEventCaps(QMouseEvent *event)
{
- return event->caps;
+ return event->caps & MouseCapsMask;
}
QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
@@ -3231,16 +3313,40 @@ QVector2D QGuiApplicationPrivate::mouseEventVelocity(QMouseEvent *event)
void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity)
{
- event->caps = caps;
+ Q_ASSERT(caps <= MouseCapsMask);
+ event->caps &= ~MouseCapsMask;
+ event->caps |= caps & MouseCapsMask;
event->velocity = velocity;
}
-void QGuiApplicationPrivate::setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other)
+Qt::MouseEventSource QGuiApplicationPrivate::mouseEventSource(const QMouseEvent *event)
+{
+ return Qt::MouseEventSource((event->caps & MouseSourceMaskDst) >> MouseSourceShift);
+}
+
+void QGuiApplicationPrivate::setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source)
+{
+ // Mouse event synthesization status is encoded in the caps field because
+ // QTouchDevice::CapabilityFlag uses only 6 bits from it.
+ int value = source;
+ Q_ASSERT(value <= MouseSourceMaskSrc);
+ event->caps &= ~MouseSourceMaskDst;
+ event->caps |= (value & MouseSourceMaskSrc) << MouseSourceShift;
+}
+
+Qt::MouseEventFlags QGuiApplicationPrivate::mouseEventFlags(const QMouseEvent *event)
{
- event->caps = other->caps;
- event->velocity = other->velocity;
+ return Qt::MouseEventFlags((event->caps & MouseFlagsCapsMask) >> MouseFlagsShift);
}
+void QGuiApplicationPrivate::setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags)
+{
+ // use the 0x00FF0000 byte from caps (containing up to 7 mouse event flags)
+ unsigned int value = flags;
+ Q_ASSERT(value <= Qt::MouseEventFlagMask);
+ event->caps &= ~MouseFlagsCapsMask;
+ event->caps |= (value & Qt::MouseEventFlagMask) << MouseFlagsShift;
+}
#include "moc_qguiapplication.cpp"
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 0089d48fa6..6d9a4b2376 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -73,6 +73,7 @@ class QStyleHints;
class Q_GUI_EXPORT QGuiApplication : public QCoreApplication
{
Q_OBJECT
+ Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
Q_PROPERTY(QString applicationDisplayName READ applicationDisplayName WRITE setApplicationDisplayName)
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection)
Q_PROPERTY(QString platformName READ platformName STORED false)
@@ -93,6 +94,9 @@ public:
static QWindowList topLevelWindows();
static QWindow *topLevelAt(const QPoint &pos);
+ static void setWindowIcon(const QIcon &icon);
+ static QIcon windowIcon();
+
static QString platformName();
static QWindow *modalWindow();
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 218036033e..1ec808ec27 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -92,6 +92,7 @@ public:
virtual bool shouldQuit();
bool shouldQuitInternal(const QWindowList &processedWindows);
+ virtual bool tryCloseAllWindows();
static Qt::KeyboardModifiers modifier_buttons;
static Qt::MouseButtons mouse_buttons;
@@ -171,7 +172,7 @@ public:
{
if (!(alignment & Qt::AlignHorizontal_Mask))
alignment |= Qt::AlignLeft;
- if ((alignment & Qt::AlignAbsolute) == 0 && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
+ if (!(alignment & Qt::AlignAbsolute) && (alignment & (Qt::AlignLeft | Qt::AlignRight))) {
if (direction == Qt::RightToLeft)
alignment ^= (Qt::AlignLeft | Qt::AlignRight);
alignment |= Qt::AlignAbsolute;
@@ -187,6 +188,7 @@ public:
static QGuiApplicationPrivate *instance() { return self; }
+ static QIcon *app_icon;
static QString *platform_name;
static QString *displayName;
@@ -231,6 +233,8 @@ public:
static bool noGrab;
QInputMethod *inputMethod;
+ QString firstWindowTitle;
+
static QList<QObject *> generic_plugin_list;
#ifndef QT_NO_SHORTCUT
QShortcutMap shortcutMap;
@@ -268,19 +272,27 @@ public:
static int mouseEventCaps(QMouseEvent *event);
static QVector2D mouseEventVelocity(QMouseEvent *event);
static void setMouseEventCapsAndVelocity(QMouseEvent *event, int caps, const QVector2D &velocity);
- static void setMouseEventCapsAndVelocity(QMouseEvent *event, QMouseEvent *other);
+
+ static Qt::MouseEventSource mouseEventSource(const QMouseEvent *event);
+ static void setMouseEventSource(QMouseEvent *event, Qt::MouseEventSource source);
+
+ static Qt::MouseEventFlags mouseEventFlags(const QMouseEvent *event);
+ static void setMouseEventFlags(QMouseEvent *event, Qt::MouseEventFlags flags);
const QDrawHelperGammaTables *gammaTables();
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
+ virtual void notifyWindowIconChanged();
+
static QRect applyWindowGeometrySpecification(const QRect &windowGeometry, const QWindow *window);
static void setApplicationState(Qt::ApplicationState state);
protected:
virtual void notifyThemeChanged();
+ bool tryCloseRemainingWindows(QWindowList processedWindows);
#ifndef QT_NO_DRAGANDDROP
virtual void notifyDragStarted(const QDrag *);
#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index b4e936f818..1739e8c6fd 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -165,7 +165,7 @@ public:
#ifndef QT_NO_ICON
bool delegate(const QIcon *)
{
- return false;
+ return v_cast<QIcon>(Base::m_a)->cacheKey() == v_cast<QIcon>(Base::m_b)->cacheKey();
}
#endif
bool delegate(const void *p) { return Base::delegate(p); }
diff --git a/src/gui/kernel/qinputmethod.cpp b/src/gui/kernel/qinputmethod.cpp
index 438c169f71..495ea8f6e7 100644
--- a/src/gui/kernel/qinputmethod.cpp
+++ b/src/gui/kernel/qinputmethod.cpp
@@ -45,6 +45,8 @@
#include <qtimer.h>
#include <qpa/qplatforminputcontext_p.h>
+#include <QDebug>
+
QT_BEGIN_NAMESPACE
/*!
@@ -365,6 +367,29 @@ bool QInputMethodPrivate::objectAcceptsInputMethod(QObject *object)
return enabled;
}
+/*!
+ Send \a query to the current focus object with parameters \a argument and return the result.
+ */
+QVariant QInputMethod::queryFocusObject(Qt::InputMethodQuery query, QVariant argument)
+{
+ QVariant retval;
+ QObject *focusObject = qGuiApp->focusObject();
+ if (!focusObject)
+ return retval;
+
+ bool newMethodWorks = QMetaObject::invokeMethod(focusObject, "inputMethodQuery",
+ Qt::DirectConnection,
+ Q_RETURN_ARG(QVariant, retval),
+ Q_ARG(Qt::InputMethodQuery, query),
+ Q_ARG(QVariant, argument));
+ if (newMethodWorks)
+ return retval;
+
+ QInputMethodQueryEvent queryEvent(query);
+ QCoreApplication::sendEvent(focusObject, &queryEvent);
+ return queryEvent.value(query);
+}
+
QT_END_NAMESPACE
#include "moc_qinputmethod.cpp"
diff --git a/src/gui/kernel/qinputmethod.h b/src/gui/kernel/qinputmethod.h
index fe6cc3f331..b155b5c0ca 100644
--- a/src/gui/kernel/qinputmethod.h
+++ b/src/gui/kernel/qinputmethod.h
@@ -50,6 +50,7 @@ class QInputMethodPrivate;
class QWindow;
class QRectF;
class QTransform;
+class QInputMethodQueryEvent;
class Q_GUI_EXPORT QInputMethod : public QObject
{
@@ -89,6 +90,8 @@ public:
QLocale locale() const;
Qt::LayoutDirection inputDirection() const;
+ static QVariant queryFocusObject(Qt::InputMethodQuery query, QVariant argument);
+
public Q_SLOTS:
void show();
void hide();
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 5770b76f1f..4569457a20 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -1567,7 +1567,7 @@ QDataStream &operator<<(QDataStream &s, const QKeySequence &keysequence)
*/
QDataStream &operator>>(QDataStream &s, QKeySequence &keysequence)
{
- qAtomicDetach(keysequence.d);
+ qAtomicDetach(keysequence.d);
QList<quint32> list;
s >> list;
for (int i = 0; i < 4; ++i)
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 39dd2a2dfa..7257663799 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -337,31 +337,32 @@ int QOpenGLContextPrivate::maxTextureSize()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-#if defined(QT_OPENGL_ES)
- return max_texture_size;
-#else
- GLenum proxy = GL_PROXY_TEXTURE_2D;
-
- GLint size;
- GLint next = 64;
- glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
- if (size == 0) {
- return max_texture_size;
- }
- do {
- size = next;
- next = size * 2;
+#ifndef QT_OPENGL_ES
+ if (!QOpenGLFunctions::isES()) {
+ GLenum proxy = GL_PROXY_TEXTURE_2D;
- if (next > max_texture_size)
- break;
+ GLint size;
+ GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
- } while (next > size);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+ if (size == 0) {
+ return max_texture_size;
+ }
+ do {
+ size = next;
+ next = size * 2;
+
+ if (next > max_texture_size)
+ break;
+ glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+ } while (next > size);
+
+ max_texture_size = size;
+ }
+#endif // QT_OPENGL_ES
- max_texture_size = size;
return max_texture_size;
-#endif
}
/*!
@@ -641,6 +642,13 @@ QOpenGLFunctions *QOpenGLContext::functions() const
*/
QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
{
+#ifndef QT_OPENGL_ES_2
+ if (QOpenGLFunctions::isES()) {
+ qWarning("versionFunctions: Not supported on dynamic GL ES");
+ return 0;
+ }
+#endif // QT_OPENGL_ES_2
+
Q_D(const QOpenGLContext);
const QSurfaceFormat f = format();
@@ -761,8 +769,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!surface->surfaceHandle())
return false;
-
- if (surface->surfaceType() != QSurface::OpenGLSurface) {
+ if (!surface->supportsOpenGL()) {
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface;
return false;
}
@@ -837,9 +844,9 @@ void QOpenGLContext::swapBuffers(QSurface *surface)
return;
}
- if (surface->surfaceType() != QSurface::OpenGLSurface) {
- qWarning() << "QOpenGLContext::swapBuffers() called with non-opengl surface";
- return;
+ if (!surface->supportsOpenGL()) {
+ qWarning() << "QOpenGLContext::swapBuffers() called with non-opengl surface";
+ return;
}
if (surface->surfaceClass() == QSurface::Window
diff --git a/src/gui/kernel/qplatformdialoghelper.cpp b/src/gui/kernel/qplatformdialoghelper.cpp
index 5ddd718e69..66a2fdff96 100644
--- a/src/gui/kernel/qplatformdialoghelper.cpp
+++ b/src/gui/kernel/qplatformdialoghelper.cpp
@@ -62,6 +62,70 @@ QT_BEGIN_NAMESPACE
*/
+static const int buttonRoleLayouts[2][5][14] =
+{
+ // Qt::Horizontal
+ {
+ // WinLayout
+ { QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole,
+ QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::Stretch, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // KdeLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::YesRole,
+ QPlatformDialogHelper::NoRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
+ QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::EOL },
+
+ // GnomeLayout
+ { QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::ApplyRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::DestructiveRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AlternateRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::RejectRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::AcceptRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::NoRole | QPlatformDialogHelper::Reverse,
+ QPlatformDialogHelper::YesRole | QPlatformDialogHelper::Reverse, QPlatformDialogHelper::EOL },
+
+ // MacModelessLayout
+ { QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ },
+
+ // Qt::Vertical
+ {
+ // WinLayout
+ { QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole,
+ QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacLayout
+ { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole,
+ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // KdeLayout
+ { QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole,
+ QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::Stretch, QPlatformDialogHelper::ResetRole,
+ QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::RejectRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL },
+
+ // GnomeLayout
+ { QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole, QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
+ QPlatformDialogHelper::AlternateRole, QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL },
+
+ // MacModelessLayout
+ { QPlatformDialogHelper::ActionRole, QPlatformDialogHelper::ApplyRole, QPlatformDialogHelper::ResetRole, QPlatformDialogHelper::Stretch,
+ QPlatformDialogHelper::HelpRole, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL,
+ QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL, QPlatformDialogHelper::EOL }
+ }
+};
+
QPlatformDialogHelper::QPlatformDialogHelper()
{
}
@@ -603,7 +667,7 @@ class QMessageDialogOptionsPrivate : public QSharedData
public:
QMessageDialogOptionsPrivate() :
icon(QMessageDialogOptions::NoIcon),
- buttons(QMessageDialogOptions::Ok)
+ buttons(QPlatformDialogHelper::Ok)
{}
QString windowTitle;
@@ -611,7 +675,7 @@ public:
QString text;
QString informativeText;
QString detailedText;
- QMessageDialogOptions::StandardButtons buttons;
+ QPlatformDialogHelper::StandardButtons buttons;
};
QMessageDialogOptions::QMessageDialogOptions() : d(new QMessageDialogOptionsPrivate)
@@ -683,17 +747,17 @@ void QMessageDialogOptions::setDetailedText(const QString &detailedText)
d->detailedText = detailedText;
}
-void QMessageDialogOptions::setStandardButtons(StandardButtons buttons)
+void QMessageDialogOptions::setStandardButtons(QPlatformDialogHelper::StandardButtons buttons)
{
d->buttons = buttons;
}
-QMessageDialogOptions::StandardButtons QMessageDialogOptions::standardButtons() const
+QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons() const
{
return d->buttons;
}
-QMessageDialogOptions::ButtonRole QMessageDialogOptions::buttonRole(QMessageDialogOptions::StandardButton button)
+QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
{
switch (button) {
case Ok:
@@ -736,6 +800,20 @@ QMessageDialogOptions::ButtonRole QMessageDialogOptions::buttonRole(QMessageDial
return InvalidRole;
}
+const int *QPlatformDialogHelper::buttonLayout(Qt::Orientation orientation, ButtonLayout policy)
+{
+ if (policy == UnknownLayout) {
+#if defined (Q_OS_OSX)
+ policy = MacLayout;
+#elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX)
+ policy = KdeLayout;
+#else
+ policy = WinLayout;
+#endif
+ }
+ return buttonRoleLayouts[orientation == Qt::Vertical][policy];
+}
+
/*!
\class QPlatformMessageDialogHelper
\since 5.0
diff --git a/src/gui/kernel/qplatformdialoghelper.h b/src/gui/kernel/qplatformdialoghelper.h
index 9eeb0a6da4..731440723b 100644
--- a/src/gui/kernel/qplatformdialoghelper.h
+++ b/src/gui/kernel/qplatformdialoghelper.h
@@ -82,6 +82,71 @@ public:
};
enum DialogCode { Rejected, Accepted };
+ enum StandardButton {
+ // keep this in sync with QDialogButtonBox::StandardButton and QMessageBox::StandardButton
+ NoButton = 0x00000000,
+ Ok = 0x00000400,
+ Save = 0x00000800,
+ SaveAll = 0x00001000,
+ Open = 0x00002000,
+ Yes = 0x00004000,
+ YesToAll = 0x00008000,
+ No = 0x00010000,
+ NoToAll = 0x00020000,
+ Abort = 0x00040000,
+ Retry = 0x00080000,
+ Ignore = 0x00100000,
+ Close = 0x00200000,
+ Cancel = 0x00400000,
+ Discard = 0x00800000,
+ Help = 0x01000000,
+ Apply = 0x02000000,
+ Reset = 0x04000000,
+ RestoreDefaults = 0x08000000,
+
+
+ FirstButton = Ok, // internal
+ LastButton = RestoreDefaults, // internal
+ LowestBit = 10, // internal: log2(FirstButton)
+ HighestBit = 27 // internal: log2(LastButton)
+ };
+
+ Q_DECLARE_FLAGS(StandardButtons, StandardButton)
+
+ enum ButtonRole {
+ // keep this in sync with QDialogButtonBox::ButtonRole and QMessageBox::ButtonRole
+ // TODO Qt 6: make the enum copies explicit, and make InvalidRole == 0 so that
+ // AcceptRole can be or'ed with flags, and EOL can be the same as InvalidRole (null-termination)
+ InvalidRole = -1,
+ AcceptRole,
+ RejectRole,
+ DestructiveRole,
+ ActionRole,
+ HelpRole,
+ YesRole,
+ NoRole,
+ ResetRole,
+ ApplyRole,
+
+ NRoles,
+
+ RoleMask = 0x0FFFFFFF,
+ AlternateRole = 0x10000000,
+ Stretch = 0x20000000,
+ Reverse = 0x40000000,
+ EOL = InvalidRole
+ };
+
+ enum ButtonLayout {
+ // keep this in sync with QDialogButtonBox::ButtonLayout and QMessageBox::ButtonLayout
+ UnknownLayout = -1,
+ WinLayout,
+ MacLayout,
+ KdeLayout,
+ GnomeLayout,
+ MacModelessLayout
+ };
+
QPlatformDialogHelper();
virtual ~QPlatformDialogHelper();
@@ -95,6 +160,9 @@ public:
static QVariant defaultStyleHint(QPlatformDialogHelper::StyleHint hint);
+ static const int *buttonLayout(Qt::Orientation orientation = Qt::Horizontal, ButtonLayout policy = UnknownLayout);
+ static ButtonRole buttonRole(StandardButton button);
+
Q_SIGNALS:
void accept();
void reject();
@@ -332,50 +400,6 @@ public:
// Keep in sync with QMessageBox::Icon
enum Icon { NoIcon, Information, Warning, Critical, Question };
- enum StandardButton {
- // keep this in sync with QDialogButtonBox::StandardButton and QMessageBox::StandardButton
- NoButton = 0x00000000,
- Ok = 0x00000400,
- Save = 0x00000800,
- SaveAll = 0x00001000,
- Open = 0x00002000,
- Yes = 0x00004000,
- YesToAll = 0x00008000,
- No = 0x00010000,
- NoToAll = 0x00020000,
- Abort = 0x00040000,
- Retry = 0x00080000,
- Ignore = 0x00100000,
- Close = 0x00200000,
- Cancel = 0x00400000,
- Discard = 0x00800000,
- Help = 0x01000000,
- Apply = 0x02000000,
- Reset = 0x04000000,
- RestoreDefaults = 0x08000000,
-
-
- FirstButton = Ok, // internal
- LastButton = RestoreDefaults // internal
- };
-
- Q_DECLARE_FLAGS(StandardButtons, StandardButton)
-
- enum ButtonRole {
- InvalidRole = -1,
- AcceptRole,
- RejectRole,
- DestructiveRole,
- ActionRole,
- HelpRole,
- YesRole,
- NoRole,
- ResetRole,
- ApplyRole,
-
- NRoles
- };
-
QMessageDialogOptions();
QMessageDialogOptions(const QMessageDialogOptions &rhs);
QMessageDialogOptions &operator=(const QMessageDialogOptions &rhs);
@@ -398,10 +422,8 @@ public:
void setDetailedText(const QString &text);
QString detailedText() const;
- void setStandardButtons(StandardButtons buttons);
- StandardButtons standardButtons() const;
-
- static ButtonRole buttonRole(StandardButton button);
+ void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
+ QPlatformDialogHelper::StandardButtons standardButtons() const;
private:
QSharedDataPointer<QMessageDialogOptionsPrivate> d;
@@ -417,7 +439,7 @@ public:
void setOptions(const QSharedPointer<QMessageDialogOptions> &options);
Q_SIGNALS:
- void clicked(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole role);
+ void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
private:
QSharedPointer<QMessageDialogOptions> m_options;
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 26aaf931b3..bec201f3f7 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -359,6 +359,8 @@ QVariant QPlatformIntegration::styleHint(StyleHint hint) const
return true;
case SetFocusOnTouchRelease:
return QVariant(false);
+ case MousePressAndHoldInterval:
+ return QPlatformTheme::defaultThemeHint(QPlatformTheme::MousePressAndHoldInterval);
}
return 0;
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index 580fc15233..35ef88949f 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -95,7 +95,8 @@ public:
NonFullScreenWindows,
NativeWidgets,
WindowManagement,
- SyncState
+ SyncState,
+ RasterGLSurface
};
virtual ~QPlatformIntegration() { }
@@ -148,7 +149,8 @@ public:
SynthesizeMouseFromTouchEvents,
PasswordMaskCharacter,
SetFocusOnTouchRelease,
- ShowIsMaximized
+ ShowIsMaximized,
+ MousePressAndHoldInterval
};
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/gui/kernel/qplatformmenu.cpp b/src/gui/kernel/qplatformmenu.cpp
new file mode 100644
index 0000000000..54c340abf9
--- /dev/null
+++ b/src/gui/kernel/qplatformmenu.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Martin Graesslin <mgraesslin@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformmenu.h"
+
+#include <qpa/qplatformtheme.h>
+#include <private/qguiapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QPlatformMenuItem *QPlatformMenu::createMenuItem() const
+{
+ return QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 3485cc58dd..9326a2b3a1 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -116,6 +116,8 @@ public:
virtual QPlatformMenuItem *menuItemAt(int position) const = 0;
virtual QPlatformMenuItem *menuItemForTag(quintptr tag) const = 0;
+
+ virtual QPlatformMenuItem *createMenuItem() const;
Q_SIGNALS:
void aboutToShow();
void aboutToHide();
diff --git a/src/gui/kernel/qplatformsessionmanager.h b/src/gui/kernel/qplatformsessionmanager.h
index 23b7a62436..80f1bcbaa0 100644
--- a/src/gui/kernel/qplatformsessionmanager.h
+++ b/src/gui/kernel/qplatformsessionmanager.h
@@ -91,10 +91,10 @@ public:
virtual bool isPhase2() const;
virtual void requestPhase2();
-protected:
- virtual void appCommitData();
- virtual void appSaveState();
+ void appCommitData();
+ void appSaveState();
+protected:
QString m_sessionId;
QString m_sessionKey;
diff --git a/src/gui/kernel/qplatformsystemtrayicon.h b/src/gui/kernel/qplatformsystemtrayicon.h
index 2c05b1a7fa..6bad643c7c 100644
--- a/src/gui/kernel/qplatformsystemtrayicon.h
+++ b/src/gui/kernel/qplatformsystemtrayicon.h
@@ -83,6 +83,8 @@ public:
virtual bool isSystemTrayAvailable() const = 0;
virtual bool supportsMessages() const = 0;
+ virtual QPlatformMenu *createMenu() const;
+
Q_SIGNALS:
void activated(QPlatformSystemTrayIcon::ActivationReason reason);
void messageClicked();
diff --git a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp b/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
index c4cec40a10..bc37f99210 100644
--- a/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
+++ b/src/gui/kernel/qplatformsystemtrayicon_qpa.cpp
@@ -159,6 +159,22 @@ QPlatformSystemTrayIcon::~QPlatformSystemTrayIcon()
\sa activated()
*/
+/*!
+ This method is called in case there is no QPlatformMenu available when
+ updating the menu. This allows the abstraction to provide a menu for the
+ system tray icon even if normally a non-native menu is used.
+
+ The default implementation returns a null pointer.
+
+ \sa updateMenu()
+ \since 5.3
+ */
+
+QPlatformMenu *QPlatformSystemTrayIcon::createMenu() const
+{
+ return Q_NULLPTR;
+}
+
QT_END_NAMESPACE
#include "moc_qplatformsystemtrayicon.cpp"
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 3548ec0199..e12eb318dc 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -51,6 +51,7 @@
#include <private/qiconloader_p.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,9 @@ QT_BEGIN_NAMESPACE
\value MouseDoubleClickInterval (int) Mouse double click interval in ms,
overriding QPlatformIntegration::styleHint.
+ \value MousePressAndHoldInterval (int) Mouse press and hold interval in ms,
+ overriding QPlatformIntegration::styleHint.
+
\value StartDragDistance (int) Start drag distance,
overriding QPlatformIntegration::styleHint.
@@ -425,6 +429,8 @@ QVariant QPlatformTheme::themeHint(ThemeHint hint) const
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskDelay);
case QPlatformTheme::PasswordMaskCharacter:
return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::PasswordMaskCharacter);
+ case QPlatformTheme::MousePressAndHoldInterval:
+ return QGuiApplicationPrivate::platformIntegration()->styleHint(QPlatformIntegration::MousePressAndHoldInterval);
default:
return QPlatformTheme::defaultThemeHint(hint);
}
@@ -491,6 +497,8 @@ QVariant QPlatformTheme::defaultThemeHint(ThemeHint hint)
case DialogSnapToDefaultButton:
case ContextMenuOnMouseRelease:
return QVariant(false);
+ case MousePressAndHoldInterval:
+ return QVariant(800);
}
return QVariant();
}
@@ -620,6 +628,63 @@ QList<QKeySequence> QPlatformTheme::keyBindings(QKeySequence::StandardKey key) c
return list;
}
+/*!
+ Returns the text of a standard \a button.
+
+ \since 5.3
+ \sa QPlatformDialogHelper::StandardButton
+ */
+
+QString QPlatformTheme::standardButtonText(int button) const
+{
+ return QPlatformTheme::defaultStandardButtonText(button);
+}
+
+QString QPlatformTheme::defaultStandardButtonText(int button)
+{
+ switch (button) {
+ case QPlatformDialogHelper::Ok:
+ return QCoreApplication::translate("QPlatformTheme", "OK");
+ case QPlatformDialogHelper::Save:
+ return QCoreApplication::translate("QPlatformTheme", "Save");
+ case QPlatformDialogHelper::SaveAll:
+ return QCoreApplication::translate("QPlatformTheme", "Save All");
+ case QPlatformDialogHelper::Open:
+ return QCoreApplication::translate("QPlatformTheme", "Open");
+ case QPlatformDialogHelper::Yes:
+ return QCoreApplication::translate("QPlatformTheme", "&Yes");
+ case QPlatformDialogHelper::YesToAll:
+ return QCoreApplication::translate("QPlatformTheme", "Yes to &All");
+ case QPlatformDialogHelper::No:
+ return QCoreApplication::translate("QPlatformTheme", "&No");
+ case QPlatformDialogHelper::NoToAll:
+ return QCoreApplication::translate("QPlatformTheme", "N&o to All");
+ case QPlatformDialogHelper::Abort:
+ return QCoreApplication::translate("QPlatformTheme", "Abort");
+ case QPlatformDialogHelper::Retry:
+ return QCoreApplication::translate("QPlatformTheme", "Retry");
+ case QPlatformDialogHelper::Ignore:
+ return QCoreApplication::translate("QPlatformTheme", "Ignore");
+ case QPlatformDialogHelper::Close:
+ return QCoreApplication::translate("QPlatformTheme", "Close");
+ case QPlatformDialogHelper::Cancel:
+ return QCoreApplication::translate("QPlatformTheme", "Cancel");
+ case QPlatformDialogHelper::Discard:
+ return QCoreApplication::translate("QPlatformTheme", "Discard");
+ case QPlatformDialogHelper::Help:
+ return QCoreApplication::translate("QPlatformTheme", "Help");
+ case QPlatformDialogHelper::Apply:
+ return QCoreApplication::translate("QPlatformTheme", "Apply");
+ case QPlatformDialogHelper::Reset:
+ return QCoreApplication::translate("QPlatformTheme", "Reset");
+ case QPlatformDialogHelper::RestoreDefaults:
+ return QCoreApplication::translate("QPlatformTheme", "Restore Defaults");
+ default:
+ break;
+ }
+ return QString();
+}
+
unsigned QPlatformThemePrivate::currentKeyPlatforms()
{
const uint keyboardScheme = QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::KeyboardScheme).toInt();
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 5cdec48ca3..205a5bab69 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -107,7 +107,8 @@ public:
IconPixmapSizes,
PasswordMaskCharacter,
DialogSnapToDefaultButton,
- ContextMenuOnMouseRelease
+ ContextMenuOnMouseRelease,
+ MousePressAndHoldInterval
};
enum DialogType {
@@ -295,7 +296,10 @@ public:
virtual QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const;
+ virtual QString standardButtonText(int button) const;
+
static QVariant defaultThemeHint(ThemeHint hint);
+ static QString defaultStandardButtonText(int button);
protected:
explicit QPlatformTheme(QPlatformThemePrivate *priv);
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 954d47f18c..faaf418522 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -127,6 +127,18 @@ QRect QPlatformWindow::geometry() const
return d->rect;
}
+/*!
+ Returns the geometry of a window in 'normal' state
+ (neither maximized, fullscreen nor minimized) for saving geometries to
+ application settings.
+
+ \since 5.3
+*/
+QRect QPlatformWindow::normalGeometry() const
+{
+ return QRect();
+}
+
QMargins QPlatformWindow::frameMargins() const
{
return QMargins();
@@ -509,6 +521,20 @@ static inline const QScreen *effectiveScreen(const QWindow *window)
}
/*!
+ Invalidates the window's surface by releasing its surface buffers.
+
+ Many platforms do not support releasing the surface memory,
+ and the default implementation does nothing.
+
+ The platform window is expected to recreate the surface again if
+ it is needed. For instance, if an OpenGL context is made current
+ on this window.
+ */
+void QPlatformWindow::invalidateSurface()
+{
+}
+
+/*!
Helper function to get initial geometry on windowing systems which do not
do smart positioning and also do not provide a means of centering a
transient window w.r.t. its parent. For example this is useful on Windows
@@ -521,14 +547,13 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight)
{
QRect rect(initialGeometry);
- if (rect.isNull()) {
- QSize minimumSize = w->minimumSize();
- if (minimumSize.width() > 0 || minimumSize.height() > 0) {
- rect.setSize(minimumSize);
- } else {
- rect.setWidth(defaultWidth);
- rect.setHeight(defaultHeight);
- }
+ if (rect.width() == 0) {
+ const int minWidth = w->minimumWidth();
+ rect.setWidth(minWidth > 0 ? minWidth : defaultWidth);
+ }
+ if (rect.height() == 0) {
+ const int minHeight = w->minimumHeight();
+ rect.setHeight(minHeight > 0 ? minHeight : defaultHeight);
}
if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic
&& w->type() != Qt::Popup) {
diff --git a/src/gui/kernel/qplatformwindow.h b/src/gui/kernel/qplatformwindow.h
index 7dfbae036f..39bd8324a0 100644
--- a/src/gui/kernel/qplatformwindow.h
+++ b/src/gui/kernel/qplatformwindow.h
@@ -84,6 +84,7 @@ public:
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const;
+ virtual QRect normalGeometry() const;
virtual QMargins frameMargins() const;
@@ -131,6 +132,8 @@ public:
virtual void setAlertState(bool enabled);
virtual bool isAlertState() const;
+ virtual void invalidateSurface();
+
static QRect initialGeometry(const QWindow *w,
const QRect &initialGeometry, int defaultWidth, int defaultHeight);
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 2573f76374..70ee631fc8 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -401,8 +401,8 @@ Qt::ScreenOrientations QScreen::orientationUpdateMask() const
The screen orientation represents the physical orientation
of the display. For example, the screen orientation of a mobile device
- will change based on the device is being held, and a desktop display
- might be rotated so that it's in portrait mode.
+ will change based on how it is being held. A change to the orientation
+ might or might not trigger a change to the primary orientation of the screen.
Changes to this property will be filtered by orientationUpdateMask(),
so in order to receive orientation updates the application must first
@@ -435,7 +435,12 @@ qreal QScreen::refreshRate() const
The primary screen orientation is Qt::LandscapeOrientation
if the screen geometry's width is greater than or equal to its
- height, or Qt::PortraitOrientation otherwise.
+ height, or Qt::PortraitOrientation otherwise. This property might
+ change when the screen orientation was changed (i.e. when the
+ display is rotated).
+ The behavior is however platform dependent and can often be specified in
+ an application manifest file.
+
*/
Qt::ScreenOrientation QScreen::primaryOrientation() const
{
diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp
index 513e21937e..c915ed3928 100644
--- a/src/gui/kernel/qshortcutmap.cpp
+++ b/src/gui/kernel/qshortcutmap.cpp
@@ -359,7 +359,7 @@ bool QShortcutMap::tryShortcutEvent(QObject *o, QKeyEvent *e)
resetState();
dispatchEvent(e);
default:
- break;
+ break;
}
// If nextState is QKeySequence::ExactMatch && identicals.count == 0
// we've only found disabled shortcuts
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index 68eb724454..e1468942af 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -62,6 +62,25 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th,
return QGuiApplicationPrivate::platformIntegration()->styleHint(ih);
}
+class QStyleHintsPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QStyleHints)
+public:
+ inline QStyleHintsPrivate()
+ : m_mouseDoubleClickInterval(-1)
+ , m_startDragDistance(-1)
+ , m_startDragTime(-1)
+ , m_keyboardInputInterval(-1)
+ , m_cursorFlashTime(-1)
+ {}
+
+ int m_mouseDoubleClickInterval;
+ int m_startDragDistance;
+ int m_startDragTime;
+ int m_keyboardInputInterval;
+ int m_cursorFlashTime;
+};
+
/*!
\class QStyleHints
\since 5.0
@@ -80,17 +99,55 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th,
\sa QGuiApplication::styleHints(), QPlatformTheme
*/
QStyleHints::QStyleHints()
- : QObject()
+ : QObject(*new QStyleHintsPrivate(), 0)
{
}
/*!
+ Sets the \a mouseDoubleClickInterval.
+ \internal
+ \sa mouseDoubleClickInterval()
+ \since 5.3
+*/
+void QStyleHints::setMouseDoubleClickInterval(int mouseDoubleClickInterval)
+{
+ Q_D(QStyleHints);
+ d->m_mouseDoubleClickInterval = mouseDoubleClickInterval;
+}
+
+/*!
Returns the time limit in milliseconds that distinguishes a double click
from two consecutive mouse clicks.
*/
int QStyleHints::mouseDoubleClickInterval() const
{
- return themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt();
+ Q_D(const QStyleHints);
+ return d->m_mouseDoubleClickInterval >= 0 ?
+ d->m_mouseDoubleClickInterval :
+ themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt();
+}
+
+/*!
+ Returns the time limit in milliseconds that activates
+ a press and hold.
+
+ \since 5.3
+*/
+int QStyleHints::mousePressAndHoldInterval() const
+{
+ return themeableHint(QPlatformTheme::MousePressAndHoldInterval, QPlatformIntegration::MousePressAndHoldInterval).toInt();
+}
+
+/*!
+ Sets the \a startDragDistance.
+ \internal
+ \sa startDragDistance()
+ \since 5.3
+*/
+void QStyleHints::setStartDragDistance(int startDragDistance)
+{
+ Q_D(QStyleHints);
+ d->m_startDragDistance = startDragDistance;
}
/*!
@@ -112,7 +169,22 @@ int QStyleHints::mouseDoubleClickInterval() const
*/
int QStyleHints::startDragDistance() const
{
- return themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt();
+ Q_D(const QStyleHints);
+ return d->m_startDragDistance >= 0 ?
+ d->m_startDragDistance :
+ themeableHint(QPlatformTheme::StartDragDistance, QPlatformIntegration::StartDragDistance).toInt();
+}
+
+/*!
+ Sets the \a startDragDragTime.
+ \internal
+ \sa startDragTime()
+ \since 5.3
+*/
+void QStyleHints::setStartDragTime(int startDragTime)
+{
+ Q_D(QStyleHints);
+ d->m_startDragTime = startDragTime;
}
/*!
@@ -127,7 +199,10 @@ int QStyleHints::startDragDistance() const
*/
int QStyleHints::startDragTime() const
{
- return themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt();
+ Q_D(const QStyleHints);
+ return d->m_startDragTime >= 0 ?
+ d->m_startDragTime :
+ themeableHint(QPlatformTheme::StartDragTime, QPlatformIntegration::StartDragTime).toInt();
}
/*!
@@ -143,12 +218,27 @@ int QStyleHints::startDragVelocity() const
}
/*!
+ Sets the \a keyboardInputInterval.
+ \internal
+ \sa keyboardInputInterval()
+ \since 5.3
+*/
+void QStyleHints::setKeyboardInputInterval(int keyboardInputInterval)
+{
+ Q_D(QStyleHints);
+ d->m_keyboardInputInterval = keyboardInputInterval;
+}
+
+/*!
Returns the time limit, in milliseconds, that distinguishes a key press
from two consecutive key presses.
*/
int QStyleHints::keyboardInputInterval() const
{
- return themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt();
+ Q_D(const QStyleHints);
+ return d->m_keyboardInputInterval >= 0 ?
+ d->m_keyboardInputInterval :
+ themeableHint(QPlatformTheme::KeyboardInputInterval, QPlatformIntegration::KeyboardInputInterval).toInt();
}
/*!
@@ -161,6 +251,18 @@ int QStyleHints::keyboardAutoRepeatRate() const
}
/*!
+ Sets the \a cursorFlashTime.
+ \internal
+ \sa cursorFlashTime()
+ \since 5.3
+*/
+void QStyleHints::setCursorFlashTime(int cursorFlashTime)
+{
+ Q_D(QStyleHints);
+ d->m_cursorFlashTime = cursorFlashTime;
+}
+
+/*!
Returns the text cursor's flash (blink) time in milliseconds.
The flash time is the time used to display, invert and restore the
@@ -169,7 +271,10 @@ int QStyleHints::keyboardAutoRepeatRate() const
*/
int QStyleHints::cursorFlashTime() const
{
- return themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt();
+ Q_D(const QStyleHints);
+ return d->m_cursorFlashTime >= 0 ?
+ d->m_cursorFlashTime :
+ themeableHint(QPlatformTheme::CursorFlashTime, QPlatformIntegration::CursorFlashTime).toInt();
}
/*!
diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h
index a0facd5f94..33fbe2965e 100644
--- a/src/gui/kernel/qstylehints.h
+++ b/src/gui/kernel/qstylehints.h
@@ -48,17 +48,25 @@ QT_BEGIN_NAMESPACE
class QPlatformIntegration;
+class QStyleHintsPrivate;
class Q_GUI_EXPORT QStyleHints : public QObject
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QStyleHints)
public:
+ void setMouseDoubleClickInterval(int mouseDoubleClickInterval);
int mouseDoubleClickInterval() const;
+ int mousePressAndHoldInterval() const;
+ void setStartDragDistance(int startDragDistance);
int startDragDistance() const;
+ void setStartDragTime(int startDragTime);
int startDragTime() const;
int startDragVelocity() const;
+ void setKeyboardInputInterval(int keyboardInputInterval);
int keyboardInputInterval() const;
int keyboardAutoRepeatRate() const;
+ void setCursorFlashTime(int cursorFlashTime);
int cursorFlashTime() const;
bool showIsFullScreen() const;
int passwordMaskDelay() const;
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index a943639d5f..a27bdaccde 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -74,6 +74,9 @@ QT_BEGIN_NAMESPACE
a software rasterizer like Qt's raster paint engine.
\value OpenGLSurface The surface is an OpenGL compatible surface and can be used
in conjunction with QOpenGLContext.
+ \value RasterGLSurface The surface can be rendered to using a software rasterizer,
+ and also supports OpenGL. This surface type is intended for internal Qt use, and
+ requires the use of private API.
*/
@@ -84,6 +87,19 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ Returns true if the surface is OpenGL compatible and can be used in
+ conjunction with QOpenGLContext; otherwise returns false.
+
+ \since 5.3
+*/
+
+bool QSurface::supportsOpenGL() const
+{
+ SurfaceType type = surfaceType();
+ return type == OpenGLSurface || type == RasterGLSurface;
+}
+
+/*!
\fn QPlatformSurface *QSurface::surfaceHandle() const
Returns a handle to the platform-specific implementation of the surface.
diff --git a/src/gui/kernel/qsurface.h b/src/gui/kernel/qsurface.h
index 8dbc230c10..c4a3276372 100644
--- a/src/gui/kernel/qsurface.h
+++ b/src/gui/kernel/qsurface.h
@@ -64,7 +64,8 @@ public:
enum SurfaceType {
RasterSurface,
- OpenGLSurface
+ OpenGLSurface,
+ RasterGLSurface
};
virtual ~QSurface();
@@ -75,6 +76,7 @@ public:
virtual QPlatformSurface *surfaceHandle() const = 0;
virtual SurfaceType surfaceType() const = 0;
+ bool supportsOpenGL() const;
virtual QSize size() const = 0;
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index fe5615d394..2b6cb2d949 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -72,6 +72,7 @@ public:
, profile(QSurfaceFormat::NoProfile)
, major(2)
, minor(0)
+ , swapInterval(1) // default to vsync
{
}
@@ -89,7 +90,8 @@ public:
renderableType(other->renderableType),
profile(other->profile),
major(other->major),
- minor(other->minor)
+ minor(other->minor),
+ swapInterval(other->swapInterval)
{
}
@@ -107,6 +109,7 @@ public:
QSurfaceFormat::OpenGLContextProfile profile;
int major;
int minor;
+ int swapInterval;
};
/*!
@@ -311,9 +314,15 @@ void QSurfaceFormat::setSamples(int numSamples)
}
/*!
- Sets the format option to \a opt.
+ \obsolete
+ \overload
- \sa testOption()
+ Use setOption(QSurfaceFormat::FormatOption, bool) or setOptions() instead.
+
+ Sets the format options to the OR combination of \a opt and the
+ current format options.
+
+ \sa options(), testOption()
*/
void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
{
@@ -325,7 +334,13 @@ void QSurfaceFormat::setOption(QSurfaceFormat::FormatOptions opt)
}
/*!
- Returns \c true if format option \a opt is set; otherwise returns \c false.
+ \obsolete
+ \overload
+
+ Use testOption(QSurfaceFormat::FormatOption) instead.
+
+ Returns \c true if any of the options in \a opt is currently set
+ on this object; otherwise returns false.
\sa setOption()
*/
@@ -335,6 +350,63 @@ bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOptions opt) const
}
/*!
+ \since 5.3
+
+ Sets the format options to \a options.
+
+ \sa options(), testOption()
+*/
+void QSurfaceFormat::setOptions(QSurfaceFormat::FormatOptions options)
+{
+ if (int(d->opts) != int(options)) {
+ detach();
+ d->opts = options;
+ }
+}
+
+/*!
+ \since 5.3
+
+ Sets the format option \a option if \a on is true; otherwise, clears the option.
+
+ \sa setOptions(), options(), testOption()
+*/
+void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
+{
+ if (testOption(option) == on)
+ return;
+ detach();
+ if (on)
+ d->opts |= option;
+ else
+ d->opts &= ~option;
+}
+
+/*!
+ \since 5.3
+
+ Returns true if the format option \a option is set; otherwise returns false.
+
+ \sa options(), testOption()
+*/
+bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
+{
+ return d->opts & option;
+}
+
+/*!
+ \since 5.3
+
+ Returns the currently set format options.
+
+ \sa setOption(), setOptions(), testOption()
+*/
+QSurfaceFormat::FormatOptions QSurfaceFormat::options() const
+{
+ return d->opts;
+}
+
+/*!
Set the minimum depth buffer size to \a size.
\sa depthBufferSize()
@@ -607,6 +679,46 @@ void QSurfaceFormat::setVersion(int major, int minor)
}
/*!
+ Sets the preferred swap interval. The swap interval specifies the
+ minimum number of video frames that are displayed before a buffer
+ swap occurs. This can be used to sync the GL drawing into a window
+ to the vertical refresh of the screen.
+
+ Setting an \a interval value of 0 will turn the vertical refresh
+ syncing off, any value higher than 0 will turn the vertical
+ syncing on. Setting \a interval to a higher value, for example 10,
+ results in having 10 vertical retraces between every buffer swap.
+
+ The default interval is 1.
+
+ Changing the swap interval may not be supported by the underlying
+ platform. In this case, the request will be silently ignored.
+
+ \since 5.3
+
+ \sa swapInterval()
+ */
+void QSurfaceFormat::setSwapInterval(int interval)
+{
+ if (d->swapInterval != interval) {
+ detach();
+ d->swapInterval = interval;
+ }
+}
+
+/*!
+ Returns the swap interval.
+
+ \since 5.3
+
+ \sa setSwapInterval()
+*/
+int QSurfaceFormat::swapInterval() const
+{
+ return d->swapInterval;
+}
+
+/*!
Returns \c true if all the options of the two QSurfaceFormat objects
\a a and \a b are equal.
@@ -625,7 +737,8 @@ bool operator==(const QSurfaceFormat& a, const QSurfaceFormat& b)
&& a.d->swapBehavior == b.d->swapBehavior
&& a.d->profile == b.d->profile
&& a.d->major == b.d->major
- && a.d->minor == b.d->minor);
+ && a.d->minor == b.d->minor
+ && a.d->swapInterval == b.d->swapInterval);
}
/*!
@@ -655,6 +768,7 @@ QDebug operator<<(QDebug dbg, const QSurfaceFormat &f)
<< ", stencilBufferSize " << d->stencilSize
<< ", samples " << d->numSamples
<< ", swapBehavior " << d->swapBehavior
+ << ", swapInterval " << d->swapInterval
<< ", profile " << d->profile
<< ')';
diff --git a/src/gui/kernel/qsurfaceformat.h b/src/gui/kernel/qsurfaceformat.h
index 7c3c846df3..453beac5cd 100644
--- a/src/gui/kernel/qsurfaceformat.h
+++ b/src/gui/kernel/qsurfaceformat.h
@@ -127,8 +127,16 @@ public:
bool stereo() const;
void setStereo(bool enable);
- void setOption(QSurfaceFormat::FormatOptions opt);
- bool testOption(QSurfaceFormat::FormatOptions opt) const;
+ QT_DEPRECATED void setOption(QSurfaceFormat::FormatOptions opt);
+ QT_DEPRECATED bool testOption(QSurfaceFormat::FormatOptions opt) const;
+
+ void setOptions(QSurfaceFormat::FormatOptions options);
+ void setOption(FormatOption option, bool on = true);
+ bool testOption(FormatOption option) const;
+ QSurfaceFormat::FormatOptions options() const;
+
+ int swapInterval() const;
+ void setSwapInterval(int interval);
private:
QSurfaceFormatPrivate *d;
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 19bd947c2c..51548aa371 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -163,9 +163,7 @@ QWindow::QWindow(QScreen *targetScreen)
//if your applications aborts here, then chances are your creating a QWindow before the
//screen list is populated.
Q_ASSERT(d->screen);
-
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -188,8 +186,7 @@ QWindow::QWindow(QWindow *parent)
d->screen = parent->screen();
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -214,8 +211,7 @@ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent)
d->screen = parent->screen();
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
- connect(d->screen, SIGNAL(destroyed(QObject*)), this, SLOT(screenDestroyed(QObject*)));
- QGuiApplicationPrivate::window_list.prepend(this);
+ d->init();
}
/*!
@@ -233,6 +229,13 @@ QWindow::~QWindow()
destroy();
}
+void QWindowPrivate::init()
+{
+ Q_Q(QWindow);
+ QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
+ QGuiApplicationPrivate::window_list.prepend(q);
+}
+
/*!
\enum QWindow::Visibility
\since 5.1
@@ -429,6 +432,14 @@ void QWindow::setVisible(bool visible)
// remove posted quit events when showing a new window
QCoreApplication::removePostedEvents(qApp, QEvent::Quit);
+ if (type() == Qt::Window) {
+ QString &firstWindowTitle = QGuiApplicationPrivate::instance()->firstWindowTitle;
+ if (!firstWindowTitle.isEmpty()) {
+ setTitle(firstWindowTitle);
+ firstWindowTitle = QString();
+ }
+ }
+
QShowEvent showEvent;
QGuiApplication::sendEvent(this, &showEvent);
}
@@ -765,6 +776,8 @@ void QWindow::setIcon(const QIcon &icon)
d->windowIcon = icon;
if (d->platformWindow)
d->platformWindow->setWindowIcon(icon);
+ QEvent e(QEvent::WindowIconChange);
+ QCoreApplication::sendEvent(this, &e);
}
/*!
@@ -775,6 +788,8 @@ void QWindow::setIcon(const QIcon &icon)
QIcon QWindow::icon() const
{
Q_D(const QWindow);
+ if (d->windowIcon.isNull())
+ return QGuiApplication::windowIcon();
return d->windowIcon;
}
@@ -1929,6 +1944,10 @@ bool QWindow::event(QEvent *ev)
hideEvent(static_cast<QHideEvent *>(ev));
break;
+ case QEvent::ApplicationWindowIconChange:
+ setIcon(icon());
+ break;
+
case QEvent::WindowStateChange: {
Q_D(QWindow);
emit windowStateChanged(d->windowState);
@@ -2147,6 +2166,26 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed()
}
+QWindow *QWindowPrivate::topLevelWindow() const
+{
+ Q_Q(const QWindow);
+
+ QWindow *window = const_cast<QWindow *>(q);
+
+ while (window) {
+ QWindow *parent = window->parent();
+ if (!parent)
+ parent = window->transientParent();
+
+ if (!parent)
+ break;
+
+ window = parent;
+ }
+
+ return window;
+}
+
/*!
Creates a local representation of a window created by another process or by
using native libraries below Qt.
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 8d8fca3ce6..4305edea51 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -108,6 +108,8 @@ public:
{
}
+ void init();
+
void maybeQuitOnLastWindowClosed();
#ifndef QT_NO_CURSOR
void setCursor(const QCursor *c = 0);
@@ -122,6 +124,8 @@ public:
return offset;
}
+ QWindow *topLevelWindow() const;
+
virtual QWindow *eventReceiver() { Q_Q(QWindow); return q; }
void updateVisibility();
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 8ef275a27c..49ff8bcb0d 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -164,31 +164,35 @@ void QWindowSystemInterface::handleCloseEvent(QWindow *tlw, bool *accepted)
\a w == 0 means that the event is in global coords only, \a local will be ignored in this case
*/
-void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleMouseEvent(w, time, local, global, b, mods);
+ handleMouseEvent(w, time, local, global, b, mods, source);
}
-void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, local, global, b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
-void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
const unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed();
- handleFrameStrutMouseEvent(w, time, local, global, b, mods);
+ handleFrameStrutMouseEvent(w, time, local, global, b, mods, source);
}
-void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
+void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods);
+ local, global, b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h
index d1c3c8e249..71feb1bcb7 100644
--- a/src/gui/kernel/qwindowsysteminterface.h
+++ b/src/gui/kernel/qwindowsysteminterface.h
@@ -73,10 +73,18 @@ class QPlatformDropQtResponse;
class Q_GUI_EXPORT QWindowSystemInterface
{
public:
- static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
- static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier);
+ static void handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleFrameStrutMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
+ static void handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b,
+ Qt::KeyboardModifiers mods = Qt::NoModifier,
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized);
static bool tryHandleShortcutEvent(QWindow *w, int k, Qt::KeyboardModifiers mods,
const QString & text = QString(), bool autorep = false, ushort count = 1);
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 42dbe7509e..8e503bbf3d 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -209,14 +209,17 @@ public:
class MouseEvent : public InputEvent {
public:
MouseEvent(QWindow * w, ulong time, const QPointF & local, const QPointF & global,
- Qt::MouseButtons b, Qt::KeyboardModifiers mods)
- : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b) { }
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods,
+ Qt::MouseEventSource src = Qt::MouseEventNotSynthesized)
+ : InputEvent(w, time, Mouse, mods), localPos(local), globalPos(global), buttons(b), source(src) { }
MouseEvent(QWindow * w, ulong time, EventType t, const QPointF & local, const QPointF & global,
- Qt::MouseButtons b, Qt::KeyboardModifiers mods)
- : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b) { }
+ Qt::MouseButtons b, Qt::KeyboardModifiers mods,
+ Qt::MouseEventSource src = Qt::MouseEventNotSynthesized)
+ : InputEvent(w, time, t, mods), localPos(local), globalPos(global), buttons(b), source(src) { }
QPointF localPos;
QPointF globalPos;
Qt::MouseButtons buttons;
+ Qt::MouseEventSource source;
};
class WheelEvent : public InputEvent {
diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h
index 55e606ec35..649d45d477 100644
--- a/src/gui/math3d/qvector2d.h
+++ b/src/gui/math3d/qvector2d.h
@@ -57,10 +57,10 @@ class QVariant;
class Q_GUI_EXPORT QVector2D
{
public:
- QVector2D();
- QVector2D(float xpos, float ypos);
- explicit QVector2D(const QPoint& point);
- explicit QVector2D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector2D();
+ Q_DECL_CONSTEXPR QVector2D(float xpos, float ypos);
+ Q_DECL_CONSTEXPR explicit QVector2D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector2D(const QPointF& point);
#ifndef QT_NO_VECTOR3D
explicit QVector2D(const QVector3D& vector);
#endif
@@ -70,8 +70,8 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
void setX(float x);
void setY(float y);
@@ -80,7 +80,12 @@ public:
float operator[](int i) const;
float length() const;
+#ifdef QT_BUILD_GUI_LIB
float lengthSquared() const;
+#else
+ Q_DECL_CONSTEXPR inline float lengthSquared() const
+ { return xp * xp + yp * yp; }
+#endif
QVector2D normalized() const;
void normalize();
@@ -94,19 +99,24 @@ public:
QVector2D &operator*=(const QVector2D &vector);
QVector2D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector2D& v1, const QVector2D& v2);
+#else
+ Q_DECL_CONSTEXPR inline static float dotProduct(const QVector2D& v1, const QVector2D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp; }
+#endif
- friend inline bool operator==(const QVector2D &v1, const QVector2D &v2);
- friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator*(float factor, const QVector2D &vector);
- friend inline const QVector2D operator*(const QVector2D &vector, float factor);
- friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2);
- friend inline const QVector2D operator-(const QVector2D &vector);
- friend inline const QVector2D operator/(const QVector2D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(float factor, const QVector2D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(const QVector2D &vector, float factor);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator-(const QVector2D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector2D operator/(const QVector2D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2);
#ifndef QT_NO_VECTOR3D
QVector3D toVector3D() const;
@@ -115,8 +125,8 @@ public:
QVector4D toVector4D() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -129,21 +139,21 @@ private:
Q_DECLARE_TYPEINFO(QVector2D, Q_MOVABLE_TYPE);
-inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {}
-inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(float xpos, float ypos) : xp(xpos), yp(ypos) {}
-inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {}
-inline QVector2D::QVector2D(const QPointF& point) : xp(point.x()), yp(point.y()) {}
+Q_DECL_CONSTEXPR inline QVector2D::QVector2D(const QPointF& point) : xp(point.x()), yp(point.y()) {}
inline bool QVector2D::isNull() const
{
return qIsNull(xp) && qIsNull(yp);
}
-inline float QVector2D::x() const { return xp; }
-inline float QVector2D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector2D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector2D::y() const { return yp; }
inline void QVector2D::setX(float aX) { xp = aX; }
inline void QVector2D::setY(float aY) { yp = aY; }
@@ -195,62 +205,62 @@ inline QVector2D &QVector2D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector2D &v1, const QVector2D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp;
}
-inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector2D &v1, const QVector2D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp;
}
-inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator+(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp + v2.xp, v1.yp + v2.yp);
}
-inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp - v2.xp, v1.yp - v2.yp);
}
-inline const QVector2D operator*(float factor, const QVector2D &vector)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(float factor, const QVector2D &vector)
{
return QVector2D(vector.xp * factor, vector.yp * factor);
}
-inline const QVector2D operator*(const QVector2D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &vector, float factor)
{
return QVector2D(vector.xp * factor, vector.yp * factor);
}
-inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
+Q_DECL_CONSTEXPR inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2)
{
return QVector2D(v1.xp * v2.xp, v1.yp * v2.yp);
}
-inline const QVector2D operator-(const QVector2D &vector)
+Q_DECL_CONSTEXPR inline const QVector2D operator-(const QVector2D &vector)
{
return QVector2D(-vector.xp, -vector.yp);
}
-inline const QVector2D operator/(const QVector2D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector2D operator/(const QVector2D &vector, float divisor)
{
return QVector2D(vector.xp / divisor, vector.yp / divisor);
}
-inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp);
}
-inline QPoint QVector2D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector2D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector2D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector2D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h
index c880930935..c5506bf1ac 100644
--- a/src/gui/math3d/qvector3d.h
+++ b/src/gui/math3d/qvector3d.h
@@ -57,10 +57,11 @@ class QVector4D;
class Q_GUI_EXPORT QVector3D
{
public:
- QVector3D();
- QVector3D(float xpos, float ypos, float zpos);
- explicit QVector3D(const QPoint& point);
- explicit QVector3D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector3D();
+ Q_DECL_CONSTEXPR QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
+
+ Q_DECL_CONSTEXPR explicit QVector3D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector3D(const QPointF& point);
#ifndef QT_NO_VECTOR2D
QVector3D(const QVector2D& vector);
QVector3D(const QVector2D& vector, float zpos);
@@ -71,9 +72,9 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
- float z() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
+ Q_DECL_CONSTEXPR float z() const;
void setX(float x);
void setY(float y);
@@ -94,8 +95,17 @@ public:
QVector3D &operator*=(const QVector3D& vector);
QVector3D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector3D& v1, const QVector3D& v2);
static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2);
+#else
+ Q_DECL_CONSTEXPR inline static float dotProduct(const QVector3D& v1, const QVector3D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; }
+ Q_DECL_CONSTEXPR inline static QVector3D crossProduct(const QVector3D& v1, const QVector3D& v2)
+ { return QVector3D(v1.yp * v2.zp - v1.zp * v2.yp,
+ v1.zp * v2.xp - v1.xp * v2.zp,
+ v1.xp * v2.yp - v1.yp * v2.xp); }
+#endif
static QVector3D normal(const QVector3D& v1, const QVector3D& v2);
static QVector3D normal
(const QVector3D& v1, const QVector3D& v2, const QVector3D& v3);
@@ -105,17 +115,17 @@ public:
float distanceToPlane(const QVector3D& plane1, const QVector3D& plane2, const QVector3D& plane3) const;
float distanceToLine(const QVector3D& point, const QVector3D& direction) const;
- friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
- friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
- friend inline const QVector3D operator*(float factor, const QVector3D &vector);
- friend inline const QVector3D operator*(const QVector3D &vector, float factor);
- friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
- friend inline const QVector3D operator-(const QVector3D &vector);
- friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator*(float factor, const QVector3D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator*(const QVector3D &vector, float factor);
+ Q_DECL_CONSTEXPR friend const QVector3D operator*(const QVector3D &v1, const QVector3D& v2);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator-(const QVector3D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector3D operator/(const QVector3D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2);
#ifndef QT_NO_VECTOR2D
QVector2D toVector2D() const;
@@ -124,8 +134,8 @@ public:
QVector4D toVector4D() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -142,22 +152,20 @@ private:
Q_DECLARE_TYPEINFO(QVector3D, Q_MOVABLE_TYPE);
-inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
-
-inline QVector3D::QVector3D(float xpos, float ypos, float zpos) : xp(xpos), yp(ypos), zp(zpos) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {}
-inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
-inline QVector3D::QVector3D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector3D::QVector3D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f) {}
inline bool QVector3D::isNull() const
{
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
}
-inline float QVector3D::x() const { return xp; }
-inline float QVector3D::y() const { return yp; }
-inline float QVector3D::z() const { return zp; }
+Q_DECL_CONSTEXPR inline float QVector3D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector3D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector3D::z() const { return zp; }
inline void QVector3D::setX(float aX) { xp = aX; }
inline void QVector3D::setY(float aY) { yp = aY; }
@@ -215,64 +223,64 @@ inline QVector3D &QVector3D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector3D &v1, const QVector3D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp;
}
-inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector3D &v1, const QVector3D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp;
}
-inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator+(const QVector3D &v1, const QVector3D &v2)
{
return QVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp);
}
-inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2)
{
return QVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp);
}
-inline const QVector3D operator*(float factor, const QVector3D &vector)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(float factor, const QVector3D &vector)
{
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
}
-inline const QVector3D operator*(const QVector3D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &vector, float factor)
{
return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor);
}
-inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
+Q_DECL_CONSTEXPR inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2)
{
return QVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp);
}
-inline const QVector3D operator-(const QVector3D &vector)
+Q_DECL_CONSTEXPR inline const QVector3D operator-(const QVector3D &vector)
{
return QVector3D(-vector.xp, -vector.yp, -vector.zp);
}
-inline const QVector3D operator/(const QVector3D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector3D operator/(const QVector3D &vector, float divisor)
{
return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor);
}
-inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) &&
qFuzzyCompare(v1.yp, v2.yp) &&
qFuzzyCompare(v1.zp, v2.zp);
}
-inline QPoint QVector3D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector3D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector3D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector3D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h
index 810380b805..1256f384a0 100644
--- a/src/gui/math3d/qvector4d.h
+++ b/src/gui/math3d/qvector4d.h
@@ -57,10 +57,10 @@ class QVector3D;
class Q_GUI_EXPORT QVector4D
{
public:
- QVector4D();
- QVector4D(float xpos, float ypos, float zpos, float wpos);
- explicit QVector4D(const QPoint& point);
- explicit QVector4D(const QPointF& point);
+ Q_DECL_CONSTEXPR QVector4D();
+ Q_DECL_CONSTEXPR QVector4D(float xpos, float ypos, float zpos, float wpos);
+ Q_DECL_CONSTEXPR explicit QVector4D(const QPoint& point);
+ Q_DECL_CONSTEXPR explicit QVector4D(const QPointF& point);
#ifndef QT_NO_VECTOR2D
QVector4D(const QVector2D& vector);
QVector4D(const QVector2D& vector, float zpos, float wpos);
@@ -72,10 +72,10 @@ public:
bool isNull() const;
- float x() const;
- float y() const;
- float z() const;
- float w() const;
+ Q_DECL_CONSTEXPR float x() const;
+ Q_DECL_CONSTEXPR float y() const;
+ Q_DECL_CONSTEXPR float z() const;
+ Q_DECL_CONSTEXPR float w() const;
void setX(float x);
void setY(float y);
@@ -86,7 +86,12 @@ public:
float operator[](int i) const;
float length() const;
+#ifdef QT_BUILD_GUI_LIB
float lengthSquared() const;
+#else
+ Q_DECL_CONSTEXPR inline float lengthSquared() const
+ { return xp * xp + yp * yp + zp * zp + wp * wp; }
+#endif
QVector4D normalized() const;
void normalize();
@@ -97,19 +102,24 @@ public:
QVector4D &operator*=(const QVector4D &vector);
QVector4D &operator/=(float divisor);
+#ifdef QT_BUILD_GUI_LIB
static float dotProduct(const QVector4D& v1, const QVector4D& v2);
+#else
+ static float dotProduct(const QVector4D& v1, const QVector4D& v2)
+ { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp; }
+#endif
- friend inline bool operator==(const QVector4D &v1, const QVector4D &v2);
- friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2);
- friend inline const QVector4D operator*(float factor, const QVector4D &vector);
- friend inline const QVector4D operator*(const QVector4D &vector, float factor);
- friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2);
- friend inline const QVector4D operator-(const QVector4D &vector);
- friend inline const QVector4D operator/(const QVector4D &vector, float divisor);
+ Q_DECL_CONSTEXPR friend inline bool operator==(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline bool operator!=(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(float factor, const QVector4D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(const QVector4D &vector, float factor);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator-(const QVector4D &vector);
+ Q_DECL_CONSTEXPR friend inline const QVector4D operator/(const QVector4D &vector, float divisor);
- friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2);
+ Q_DECL_CONSTEXPR friend inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2);
#ifndef QT_NO_VECTOR2D
QVector2D toVector2D() const;
@@ -120,8 +130,8 @@ public:
QVector3D toVector3DAffine() const;
#endif
- QPoint toPoint() const;
- QPointF toPointF() const;
+ Q_DECL_CONSTEXPR QPoint toPoint() const;
+ Q_DECL_CONSTEXPR QPointF toPointF() const;
operator QVariant() const;
@@ -138,23 +148,23 @@ private:
Q_DECLARE_TYPEINFO(QVector4D, Q_MOVABLE_TYPE);
-inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {}
-inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {}
-inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
-inline QVector4D::QVector4D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
+Q_DECL_CONSTEXPR inline QVector4D::QVector4D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {}
inline bool QVector4D::isNull() const
{
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp);
}
-inline float QVector4D::x() const { return xp; }
-inline float QVector4D::y() const { return yp; }
-inline float QVector4D::z() const { return zp; }
-inline float QVector4D::w() const { return wp; }
+Q_DECL_CONSTEXPR inline float QVector4D::x() const { return xp; }
+Q_DECL_CONSTEXPR inline float QVector4D::y() const { return yp; }
+Q_DECL_CONSTEXPR inline float QVector4D::z() const { return zp; }
+Q_DECL_CONSTEXPR inline float QVector4D::w() const { return wp; }
inline void QVector4D::setX(float aX) { xp = aX; }
inline void QVector4D::setY(float aY) { yp = aY; }
@@ -218,52 +228,52 @@ inline QVector4D &QVector4D::operator/=(float divisor)
return *this;
}
-inline bool operator==(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline bool operator==(const QVector4D &v1, const QVector4D &v2)
{
return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp && v1.wp == v2.wp;
}
-inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline bool operator!=(const QVector4D &v1, const QVector4D &v2)
{
return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp || v1.wp != v2.wp;
}
-inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator+(const QVector4D &v1, const QVector4D &v2)
{
return QVector4D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp, v1.wp + v2.wp);
}
-inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2)
{
return QVector4D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp, v1.wp - v2.wp);
}
-inline const QVector4D operator*(float factor, const QVector4D &vector)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(float factor, const QVector4D &vector)
{
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
}
-inline const QVector4D operator*(const QVector4D &vector, float factor)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &vector, float factor)
{
return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor);
}
-inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
+Q_DECL_CONSTEXPR inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2)
{
return QVector4D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp, v1.wp * v2.wp);
}
-inline const QVector4D operator-(const QVector4D &vector)
+Q_DECL_CONSTEXPR inline const QVector4D operator-(const QVector4D &vector)
{
return QVector4D(-vector.xp, -vector.yp, -vector.zp, -vector.wp);
}
-inline const QVector4D operator/(const QVector4D &vector, float divisor)
+Q_DECL_CONSTEXPR inline const QVector4D operator/(const QVector4D &vector, float divisor)
{
return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor);
}
-inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
+Q_DECL_CONSTEXPR inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
{
return qFuzzyCompare(v1.xp, v2.xp) &&
qFuzzyCompare(v1.yp, v2.yp) &&
@@ -271,12 +281,12 @@ inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2)
qFuzzyCompare(v1.wp, v2.wp);
}
-inline QPoint QVector4D::toPoint() const
+Q_DECL_CONSTEXPR inline QPoint QVector4D::toPoint() const
{
return QPoint(qRound(xp), qRound(yp));
}
-inline QPointF QVector4D::toPointF() const
+Q_DECL_CONSTEXPR inline QPointF QVector4D::toPointF() const
{
return QPointF(qreal(xp), qreal(yp));
}
diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri
index d249b855f5..56aecd49e2 100644
--- a/src/gui/opengl/opengl.pri
+++ b/src/gui/opengl/opengl.pri
@@ -31,7 +31,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopenglversionfunctions.h \
opengl/qopenglversionfunctionsfactory_p.h \
opengl/qopenglvertexarrayobject.h \
- opengl/qopengldebug.h
+ opengl/qopengldebug.h \
+ opengl/qopengltextureblitter_p.h
SOURCES += opengl/qopengl.cpp \
opengl/qopenglfunctions.cpp \
@@ -51,7 +52,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
opengl/qopenglversionfunctions.cpp \
opengl/qopenglversionfunctionsfactory.cpp \
opengl/qopenglvertexarrayobject.cpp \
- opengl/qopengldebug.cpp
+ opengl/qopengldebug.cpp \
+ opengl/qopengltextureblitter.cpp
!wince* {
HEADERS += opengl/qopengltexture.h \
@@ -120,4 +122,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
SOURCES += opengl/qopenglfunctions_es2.cpp
}
+
+ contains(QT_CONFIG, dynamicgl) {
+ win32: SOURCES += opengl/qopenglproxy_win.cpp
+ }
}
diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h
index 6eb656cd09..025f8b823c 100644
--- a/src/gui/opengl/qopengl.h
+++ b/src/gui/opengl/qopengl.h
@@ -107,7 +107,17 @@ typedef GLfloat GLdouble;
# include <OpenGL/glext.h>
# else
# define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h
+ // In dynamic GL builds qopenglproxy will export the GL functions that are
+ // called also in QtGui itself. To prevent linker warnings (msvc) or errors (mingw)
+ // we need to make sure the prototypes do not have dllimport.
+# ifdef QT_OPENGL_DYNAMIC_IN_GUI
+# undef WINGDIAPI
+# define WINGDIAPI
+# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <GL/gl.h>
+# ifdef QT_OPENGL_DYNAMIC_IN_GUI
+# undef WINGDIAPI
+# endif // QT_OPENGL_DYNAMIC_IN_GUI
# include <QtGui/qopenglext.h>
# endif // Q_OS_MAC
#endif
diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
index b832cefd70..a4c1e538ee 100644
--- a/src/gui/opengl/qopenglbuffer.cpp
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -333,18 +333,20 @@ void QOpenGLBuffer::destroy()
bool QOpenGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
- Q_D(QOpenGLBuffer);
- if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
- return false;
- while (glGetError() != GL_NO_ERROR) ; // Clear error state.
- d->funcs->glGetBufferSubData(d->type, offset, count, data);
- return glGetError() == GL_NO_ERROR;
+ if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
+ Q_D(QOpenGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return glGetError() == GL_NO_ERROR;
+ }
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
- return false;
#endif
+ return false;
}
/*!
diff --git a/src/gui/opengl/qopenglengineshadermanager.cpp b/src/gui/opengl/qopenglengineshadermanager.cpp
index 7c3c309ea5..95bafb07d9 100644
--- a/src/gui/opengl/qopenglengineshadermanager.cpp
+++ b/src/gui/opengl/qopenglengineshadermanager.cpp
@@ -164,7 +164,10 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
- code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
+ if (QOpenGLFunctions::isES())
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES;
+ else
+ code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop;
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;
diff --git a/src/gui/opengl/qopenglengineshadersource_p.h b/src/gui/opengl/qopenglengineshadersource_p.h
index ba72de3fb0..5bb0bc4704 100644
--- a/src/gui/opengl/qopenglengineshadersource_p.h
+++ b/src/gui/opengl/qopenglengineshadersource_p.h
@@ -305,25 +305,23 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
= qopenglslPositionWithTextureBrushVertexShader;
-#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
-static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+static const char* const qopenglslTextureBrushSrcFragmentShader_ES = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
-#else
-static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
+
+static const char* const qopenglslTextureBrushSrcFragmentShader_desktop = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
-#endif
static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 14d7fac9f7..9953b4e889 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -72,8 +72,6 @@ QT_BEGIN_NAMESPACE
#define QT_CHECK_GLERROR() {}
#endif
-// ####TODO Properly #ifdef this class to use #define symbols actually defined
-// by OpenGL/ES includes
#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES 0x8D57
#endif
@@ -448,42 +446,12 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glGenFramebuffers(1, &fbo);
funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- GLuint texture = 0;
GLuint color_buffer = 0;
QT_CHECK_GLERROR();
// init texture
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) {
- int width = size.width();
- int height = size.height();
- int level = 0;
- while (width > 1 || height > 1) {
- width = qMax(1, width >> 1);
- height = qMax(1, height >> 1);
- ++level;
- glTexImage2D(target, level, internal_format, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
- }
- funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- target, texture, 0);
-
- QT_CHECK_GLERROR();
- valid = checkFramebufferStatus(ctx);
- glBindTexture(target, 0);
-
- color_buffer = 0;
+ initTexture(texture_target, internal_format, size, mipmap);
} else {
mipmap = false;
funcs.glGenRenderbuffers(1, &color_buffer);
@@ -494,8 +462,10 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
QT_CHECK_GLERROR();
valid = checkFramebufferStatus(ctx);
- if (valid)
+ if (valid) {
funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
+ color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
+ }
}
format.setTextureTarget(target);
@@ -508,20 +478,59 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_func()->current_fbo);
if (valid) {
fbo_guard = new QOpenGLSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
- if (color_buffer)
- color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
- else
- texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
} else {
- if (color_buffer)
- funcs.glDeleteRenderbuffers(1, &color_buffer);
- else
- glDeleteTextures(1, &texture);
+ if (color_buffer_guard) {
+ color_buffer_guard->free();
+ color_buffer_guard = 0;
+ } else if (texture_guard) {
+ texture_guard->free();
+ texture_guard = 0;
+ }
funcs.glDeleteFramebuffers(1, &fbo);
}
QT_CHECK_GLERROR();
}
+void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal_format,
+ const QSize &size, bool mipmap)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ GLuint texture = 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) {
+ int width = size.width();
+ int height = size.height();
+ int level = 0;
+ while (width > 1 || height > 1) {
+ width = qMax(1, width >> 1);
+ height = qMax(1, height >> 1);
+ ++level;
+ glTexImage2D(target, level, internal_format, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ }
+ funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ target, texture, 0);
+
+ QT_CHECK_GLERROR();
+ glBindTexture(target, 0);
+ valid = checkFramebufferStatus(ctx);
+ if (valid)
+ texture_guard = new QOpenGLSharedResourceGuard(ctx, texture, freeTextureFunc);
+ else
+ glDeleteTextures(1, &texture);
+}
+
void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
{
int samples = format.samples();
@@ -581,30 +590,29 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#ifdef QT_OPENGL_ES
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT24, size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT24, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT16, size.width(), size.height());
} else {
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT16, size.width(), size.height());
+ GL_DEPTH_COMPONENT, size.width(), size.height());
}
-#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT, size.width(), size.height());
-#endif
} else {
-#ifdef QT_OPENGL_ES
- if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
- size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
+ size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size.width(), size.height());
+ }
} else {
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
- size.width(), size.height());
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
}
-#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
-#endif
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_buffer);
@@ -619,23 +627,18 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
funcs.glGenRenderbuffers(1, &stencil_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
- if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX8, size.width(), size.height());
-#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX, size.width(), size.height());
-#endif
- } else {
+
#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
- size.width(), size.height());
+ GLenum storage = GL_STENCIL_INDEX8;
#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
- size.width(), size.height());
+ GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
- }
+
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
+
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus(ctx);
@@ -768,7 +771,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, size, NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -782,7 +791,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, QSize(width, height), NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -831,6 +846,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, QSize(width, height), attachment, target, internal_format);
}
@@ -852,6 +873,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment
: d_ptr(new QOpenGLFramebufferObjectPrivate)
{
Q_D(QOpenGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, size, attachment, target, internal_format);
}
@@ -907,12 +934,16 @@ bool QOpenGLFramebufferObject::isValid() const
framebuffer to this framebuffer object.
Returns \c true upon success, false otherwise.
+ \note If takeTexture() was called, a new texture is created and associated
+ with the framebuffer object. This is potentially expensive and changes the
+ context state (the currently bound texture).
+
\sa release()
*/
bool QOpenGLFramebufferObject::bind()
{
if (!isValid())
- return false;
+ return false;
Q_D(QOpenGLFramebufferObject);
QOpenGLContext *current = QOpenGLContext::currentContext();
if (!current)
@@ -922,7 +953,10 @@ bool QOpenGLFramebufferObject::bind()
qWarning("QOpenGLFramebufferObject::bind() called from incompatible context");
#endif
d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
- d->valid = d->checkFramebufferStatus(current);
+ if (d->texture_guard || d->format.samples() != 0)
+ d->valid = d->checkFramebufferStatus(current);
+ else
+ d->initTexture(d->format.textureTarget(), d->format.internalTextureFormat(), d->size, d->format.mipmap());
if (d->valid && current)
current->d_func()->current_fbo = d->fbo();
return d->valid;
@@ -940,7 +974,7 @@ bool QOpenGLFramebufferObject::bind()
bool QOpenGLFramebufferObject::release()
{
if (!isValid())
- return false;
+ return false;
QOpenGLContext *current = QOpenGLContext::currentContext();
if (!current)
@@ -969,6 +1003,8 @@ bool QOpenGLFramebufferObject::release()
If a multisample framebuffer object is used then the value returned
from this function will be invalid.
+
+ \sa takeTexture()
*/
GLuint QOpenGLFramebufferObject::texture() const
{
@@ -977,6 +1013,40 @@ GLuint QOpenGLFramebufferObject::texture() const
}
/*!
+ \fn GLuint QOpenGLFramebufferObject::takeTexture()
+
+ Returns the texture id for the texture attached to this framebuffer
+ object. The ownership of the texture is transferred to the caller.
+
+ If the framebuffer object is currently bound, an implicit release()
+ will be done. During the next call to bind() a new texture will be
+ created.
+
+ If a multisample framebuffer object is used, then there is no
+ texture and the return value from this function will be invalid.
+ Similarly, incomplete framebuffer objects will also return 0.
+
+ \since 5.3
+
+ \sa texture(), bind(), release()
+ */
+GLuint QOpenGLFramebufferObject::takeTexture()
+{
+ Q_D(QOpenGLFramebufferObject);
+ GLuint id = 0;
+ if (isValid() && d->texture_guard) {
+ QOpenGLContext *current = QOpenGLContext::currentContext();
+ if (current && current->shareGroup() == d->fbo_guard->group() && current->d_func()->current_fbo == d->fbo())
+ release();
+ id = d->texture_guard->id();
+ // Do not call free() on texture_guard, just null it out.
+ // This way the texture will not be deleted when the guard is destroyed.
+ d->texture_guard = 0;
+ }
+ return id;
+}
+
+/*!
\fn QSize QOpenGLFramebufferObject::size() const
Returns the size of the texture attached to this framebuffer
diff --git a/src/gui/opengl/qopenglframebufferobject.h b/src/gui/opengl/qopenglframebufferobject.h
index 215d3701ca..3df929c210 100644
--- a/src/gui/opengl/qopenglframebufferobject.h
+++ b/src/gui/opengl/qopenglframebufferobject.h
@@ -69,17 +69,11 @@ public:
explicit QOpenGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
-#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
- QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
- QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
-#else
+
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
-#endif
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);
@@ -97,6 +91,7 @@ public:
int height() const { return size().height(); }
GLuint texture() const;
+ GLuint takeTexture();
QSize size() const;
QImage toImage() const;
Attachment attachment() const;
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index c8c69c4b3e..f0e07f2119 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -59,12 +59,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
class QOpenGLFramebufferObjectFormatPrivate
{
public:
@@ -73,9 +67,13 @@ public:
samples(0),
attachment(QOpenGLFramebufferObject::NoAttachment),
target(GL_TEXTURE_2D),
- internal_format(DEFAULT_FORMAT),
mipmap(false)
{
+#ifndef QT_OPENGL_ES_2
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#else
+ internal_format = GL_RGBA;
+#endif
}
QOpenGLFramebufferObjectFormatPrivate
(const QOpenGLFramebufferObjectFormatPrivate *other)
@@ -116,6 +114,7 @@ public:
QOpenGLFramebufferObject::Attachment attachment,
GLenum internal_format, GLenum texture_target,
GLint samples = 0, bool mipmap = false);
+ void initTexture(GLenum target, GLenum internal_format, const QSize &size, bool mipmap);
void initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment);
bool checkFramebufferStatus(QOpenGLContext *ctx) const;
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 0e5a1327b0..150e7dcb32 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -249,98 +249,98 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
-#if defined(QT_OPENGL_ES_2)
- int features = QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::Shaders |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::Framebuffers |
- QOpenGLFunctions::BlendColor |
- QOpenGLFunctions::BlendEquation |
- QOpenGLFunctions::BlendEquationSeparate |
- QOpenGLFunctions::BlendFuncSeparate |
- QOpenGLFunctions::BlendSubtract |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample |
- QOpenGLFunctions::StencilSeparate;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures |
- QOpenGLFunctions::NPOTTextureRepeat;
- return features;
-#elif defined(QT_OPENGL_ES)
- int features = QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_OES_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_OES_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_OES_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- return features;
-#else
- int features = 0;
- QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- QOpenGLExtensionMatcher extensions;
-
- // Recognize features by extension name.
- if (extensions.match("GL_ARB_multitexture"))
- features |= QOpenGLFunctions::Multitexture;
- if (extensions.match("GL_ARB_shader_objects"))
- features |= QOpenGLFunctions::Shaders;
- if (extensions.match("GL_EXT_framebuffer_object") ||
+ if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Framebuffers |
+ QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::BlendSubtract |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::StencilSeparate;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures |
+ QOpenGLFunctions::NPOTTextureRepeat;
+ return features;
+ } else if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
+ int features = QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_OES_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_OES_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_OES_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QOpenGLFunctions::NPOTTextures;
+ return features;
+ } else {
+ int features = 0;
+ QSurfaceFormat format = QOpenGLContext::currentContext()->format();
+ QOpenGLExtensionMatcher extensions;
+
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QOpenGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QOpenGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_framebuffer_object") ||
extensions.match("GL_ARB_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_EXT_blend_color"))
- features |= QOpenGLFunctions::BlendColor;
- if (extensions.match("GL_EXT_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_EXT_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_EXT_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_ARB_texture_compression"))
- features |= QOpenGLFunctions::CompressedTextures;
- if (extensions.match("GL_ARB_multisample"))
- features |= QOpenGLFunctions::Multisample;
- if (extensions.match("GL_ARB_texture_non_power_of_two"))
- features |= QOpenGLFunctions::NPOTTextures;
-
- // assume version 2.0 or higher
- features |= QOpenGLFunctions::BlendColor |
- QOpenGLFunctions::BlendEquation |
- QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample |
- QOpenGLFunctions::BlendFuncSeparate |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::Shaders |
- QOpenGLFunctions::StencilSeparate |
- QOpenGLFunctions::BlendEquationSeparate |
- QOpenGLFunctions::NPOTTextures;
-
- if (format.majorVersion() >= 3)
- features |= QOpenGLFunctions::Framebuffers;
-
- const QPair<int, int> version = format.version();
- if (version < qMakePair(3, 0)
+ features |= QOpenGLFunctions::Framebuffers;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QOpenGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QOpenGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QOpenGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QOpenGLFunctions::NPOTTextures;
+
+ // assume version 2.0 or higher
+ features |= QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::StencilSeparate |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::NPOTTextures;
+
+ if (format.majorVersion() >= 3)
+ features |= QOpenGLFunctions::Framebuffers;
+
+ const QPair<int, int> version = format.version();
+ if (version < qMakePair(3, 0)
|| (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
|| (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
|| (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
- features |= QOpenGLFunctions::FixedFunctionPipeline;
+ features |= QOpenGLFunctions::FixedFunctionPipeline;
+ }
+ return features;
}
- return features;
-#endif
}
static int qt_gl_resolve_extensions()
@@ -350,38 +350,38 @@ static int qt_gl_resolve_extensions()
if (extensionMatcher.match("GL_EXT_bgra"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
-#if defined(QT_OPENGL_ES)
- if (extensionMatcher.match("GL_OES_mapbuffer"))
- extensions |= QOpenGLExtensions::MapBuffer;
- if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
- extensions |= QOpenGLExtensions::PackedDepthStencil;
- if (extensionMatcher.match("GL_OES_element_index_uint"))
- extensions |= QOpenGLExtensions::ElementIndexUint;
- if (extensionMatcher.match("GL_OES_depth24"))
- extensions |= QOpenGLExtensions::Depth24;
- // TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
- if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
- extensions |= QOpenGLExtensions::BGRATextureFormat;
-#else
- QSurfaceFormat format = QOpenGLContext::currentContext()->format();
- extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
-
- // Recognize features by extension name.
- if (format.majorVersion() >= 3
- || extensionMatcher.match("GL_ARB_framebuffer_object"))
- {
- extensions |= QOpenGLExtensions::FramebufferMultisample |
- QOpenGLExtensions::FramebufferBlit |
- QOpenGLExtensions::PackedDepthStencil;
- } else {
- if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
- extensions |= QOpenGLExtensions::FramebufferMultisample;
- if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
- extensions |= QOpenGLExtensions::FramebufferBlit;
- if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
+ if (QOpenGLFunctions::isES()) {
+ if (extensionMatcher.match("GL_OES_mapbuffer"))
+ extensions |= QOpenGLExtensions::MapBuffer;
+ if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
extensions |= QOpenGLExtensions::PackedDepthStencil;
+ if (extensionMatcher.match("GL_OES_element_index_uint"))
+ extensions |= QOpenGLExtensions::ElementIndexUint;
+ if (extensionMatcher.match("GL_OES_depth24"))
+ extensions |= QOpenGLExtensions::Depth24;
+ // TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
+ if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
+ extensions |= QOpenGLExtensions::BGRATextureFormat;
+ } else {
+ QSurfaceFormat format = QOpenGLContext::currentContext()->format();
+ extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
+
+ // Recognize features by extension name.
+ if (format.majorVersion() >= 3
+ || extensionMatcher.match("GL_ARB_framebuffer_object"))
+ {
+ extensions |= QOpenGLExtensions::FramebufferMultisample |
+ QOpenGLExtensions::FramebufferBlit |
+ QOpenGLExtensions::PackedDepthStencil;
+ } else {
+ if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
+ extensions |= QOpenGLExtensions::FramebufferMultisample;
+ if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
+ extensions |= QOpenGLExtensions::FramebufferBlit;
+ if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
+ extensions |= QOpenGLExtensions::PackedDepthStencil;
+ }
}
-#endif
return extensions;
}
@@ -2509,4 +2509,88 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
GetBufferSubData = qopenglfResolveGetBufferSubData;
}
+#if defined(QT_OPENGL_DYNAMIC)
+extern int qgl_proxyLibraryType(void);
+extern HMODULE qgl_glHandle(void);
+#endif
+
+/*!
+ \enum QOpenGLFunctions::PlatformGLType
+ This enum defines the type of the underlying GL implementation.
+
+ \value DesktopGL Desktop OpenGL
+ \value GLES2 OpenGL ES 2.0 or higher
+ \value GLES1 OpenGL ES 1.x
+
+ \since 5.3
+ */
+
+/*!
+ \fn QOpenGLFunctions::isES()
+
+ On platforms where the OpenGL implementation is dynamically loaded
+ this function returns true if the underlying GL implementation is
+ Open GL ES.
+
+ On platforms that do not use runtime loading of the GL the return
+ value is based on Qt's compile-time configuration and will never
+ change during runtime.
+
+ \sa platformGLType()
+
+ \since 5.3
+ */
+
+/*!
+ Returns the underlying GL implementation type.
+
+ On platforms where the OpenGL implementation is not dynamically
+ loaded, the return value is determined during compile time and never
+ changes.
+
+ Platforms that use dynamic GL loading (e.g. Windows) cannot rely on
+ compile-time defines for differentiating between desktop and ES
+ OpenGL code. Instead, they rely on this function to query, during
+ runtime, the type of the loaded graphics library.
+
+ \since 5.3
+ */
+QOpenGLFunctions::PlatformGLType QOpenGLFunctions::platformGLType()
+{
+#if defined(QT_OPENGL_DYNAMIC)
+ return PlatformGLType(qgl_proxyLibraryType());
+#elif defined(QT_OPENGL_ES_2)
+ return GLES2;
+#elif defined(QT_OPENGL_ES)
+ return GLES1;
+#else
+ return DesktopGL;
+#endif
+}
+
+/*!
+ Returns the platform-specific handle for the OpenGL implementation that
+ is currently in use. (for example, a HMODULE on Windows)
+
+ On platforms that do not use dynamic GL switch the return value is null.
+
+ The library might be GL-only, meaning that windowing system interface
+ functions (for example EGL) may live in another, separate library.
+
+ Always use platformGLType() before resolving any functions to check if the
+ library implements desktop OpenGL or OpenGL ES.
+
+ \sa platformGLType()
+
+ \since 5.3
+ */
+void *QOpenGLFunctions::platformGLHandle()
+{
+#if defined(QT_OPENGL_DYNAMIC)
+ return qgl_glHandle();
+#else
+ return 0;
+#endif
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglfunctions.h b/src/gui/opengl/qopenglfunctions.h
index 9d8da209ad..6d3f038004 100644
--- a/src/gui/opengl/qopenglfunctions.h
+++ b/src/gui/opengl/qopenglfunctions.h
@@ -311,6 +311,15 @@ public:
void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+ enum PlatformGLType {
+ DesktopGL = 0,
+ GLES2,
+ GLES1
+ };
+ static PlatformGLType platformGLType();
+ static void *platformGLHandle();
+ static bool isES() { return platformGLType() != DesktopGL; }
+
protected:
QOpenGLFunctionsPrivate *d_ptr;
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
@@ -322,7 +331,6 @@ struct QOpenGLFunctionsPrivate
{
QOpenGLFunctionsPrivate(QOpenGLContext *ctx);
-#ifndef QT_OPENGL_ES_2
void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader);
void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const char* name);
@@ -418,7 +426,6 @@ struct QOpenGLFunctionsPrivate
void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values);
void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
-#endif
};
inline void QOpenGLFunctions::glActiveTexture(GLenum texture)
diff --git a/src/gui/opengl/qopenglgradientcache.cpp b/src/gui/opengl/qopenglgradientcache.cpp
index 9c4fbbe013..9c312808a2 100644
--- a/src/gui/opengl/qopenglgradientcache.cpp
+++ b/src/gui/opengl/qopenglgradientcache.cpp
@@ -168,7 +168,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
qreal incr = 1.0 / qreal(size);
qreal fpos = 1.5 * incr;
- colorTable[pos++] = ARGB2RGBA(PREMUL(current_color));
+ colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));
while (fpos <= s.first().first) {
colorTable[pos] = colorTable[pos - 1];
@@ -177,13 +177,13 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
}
if (colorInterpolation)
- current_color = PREMUL(current_color);
+ current_color = qPremultiply(current_color);
for (int i = 0; i < s.size() - 1; ++i) {
qreal delta = 1/(s[i+1].first - s[i].first);
uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
if (colorInterpolation)
- next_color = PREMUL(next_color);
+ next_color = qPremultiply(next_color);
while (fpos < s[i+1].first && pos < size) {
int dist = int(256 * ((fpos - s[i].first) * delta));
@@ -191,7 +191,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
if (colorInterpolation)
colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
else
- colorTable[pos] = ARGB2RGBA(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
+ colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
++pos;
fpos += incr;
}
@@ -200,7 +200,7 @@ void QOpenGL2GradientCache::generateGradientColorTable(const QGradient& gradient
Q_ASSERT(s.size() > 0);
- uint last_color = ARGB2RGBA(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
+ uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
for (;pos < size; ++pos)
colorTable[pos] = last_color;
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 05135519f8..e91ada7b3a 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -220,14 +220,14 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
-#if defined(QT_OPENGL_ES_2)
- // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
- // we emulate GL_REPEAT by only taking the fractional part of the texture coords
- // in the qopenglslTextureBrushSrcFragmentShader program.
- GLuint wrapMode = GL_CLAMP_TO_EDGE;
-#else
GLuint wrapMode = GL_REPEAT;
-#endif
+ if (QOpenGLFunctions::isES()) {
+ // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
+ // we emulate GL_REPEAT by only taking the fractional part of the texture coords
+ // in the qopenglslTextureBrushSrcFragmentShader program.
+ wrapMode = GL_CLAMP_TO_EDGE;
+ }
+
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap);
updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
@@ -542,36 +542,38 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
- Q_ASSERT(QOpenGLContext::currentContext());
- const QOpenGLContext *ctx = d->ctx;
- const QSurfaceFormat &fmt = d->device->context()->format();
- if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
- || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
- || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
- {
- // be nice to people who mix OpenGL 1.x code with QPainter commands
- // by setting modelview and projection matrices to mirror the GL 1
- // paint engine
- const QTransform& mtx = state()->matrix;
-
- float mv_matrix[4][4] =
+ if (!QOpenGLFunctions::isES()) {
+ Q_ASSERT(QOpenGLContext::currentContext());
+ const QOpenGLContext *ctx = d->ctx;
+ const QSurfaceFormat &fmt = d->device->context()->format();
+ if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
+ || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
+ || fmt.profile() == QSurfaceFormat::CompatibilityProfile)
{
- { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
- { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
- { 0, 0, 1, 0 },
- { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
- };
-
- const QSize sz = d->device->size();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(&mv_matrix[0][0]);
+ // be nice to people who mix OpenGL 1.x code with QPainter commands
+ // by setting modelview and projection matrices to mirror the GL 1
+ // paint engine
+ const QTransform& mtx = state()->matrix;
+
+ float mv_matrix[4][4] =
+ {
+ { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
+ { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
+ { 0, 0, 1, 0 },
+ { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
+ };
+
+ const QSize sz = d->device->size();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&mv_matrix[0][0]);
+ }
}
-#endif
+#endif // QT_OPENGL_ES_2
d->lastTextureUsed = GLuint(-1);
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
@@ -598,11 +600,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
-#ifndef QT_OPENGL_ES_2
- // gl_Color, corresponding to vertex attribute 3, may have been changed
- float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- funcs.glVertexAttrib4fv(3, color);
-#endif
+ if (!QOpenGLFunctions::isES()) {
+ // gl_Color, corresponding to vertex attribute 3, may have been changed
+ float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ funcs.glVertexAttrib4fv(3, color);
+ }
}
void QOpenGL2PaintEngineEx::endNativePainting()
@@ -1332,13 +1334,15 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
{
state()->renderHintsChanged = true;
-#if !defined(QT_OPENGL_ES_2)
- if ((state()->renderHints & QPainter::Antialiasing)
- || (state()->renderHints & QPainter::HighQualityAntialiasing))
- glEnable(GL_MULTISAMPLE);
- else
- glDisable(GL_MULTISAMPLE);
-#endif
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ if ((state()->renderHints & QPainter::Antialiasing)
+ || (state()->renderHints & QPainter::HighQualityAntialiasing))
+ glEnable(GL_MULTISAMPLE);
+ else
+ glDisable(GL_MULTISAMPLE);
+ }
+#endif // QT_OPENGL_ES_2
Q_D(QOpenGL2PaintEngineEx);
d->lastTextureUsed = GLuint(-1);
@@ -2008,23 +2012,20 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
-#if !defined(QT_OPENGL_ES_2)
- glDisable(GL_MULTISAMPLE);
-#endif
-
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
-#if !defined(QT_OPENGL_ES_2)
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ glDisable(GL_MULTISAMPLE);
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
-#endif
-
-#if defined(QT_OPENGL_ES_2)
- // OpenGL ES can't switch MSAA off, so if the gl paint device is
- // multisampled, it's always multisampled.
- d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
-#else
- d->multisamplingAlwaysEnabled = false;
-#endif
+ d->multisamplingAlwaysEnabled = false;
+ } else
+#endif // QT_OPENGL_ES_2
+ {
+ // OpenGL ES can't switch MSAA off, so if the gl paint device is
+ // multisampled, it's always multisampled.
+ d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
+ }
return true;
}
diff --git a/src/gui/opengl/qopenglproxy_win.cpp b/src/gui/opengl/qopenglproxy_win.cpp
new file mode 100644
index 0000000000..83c3073f63
--- /dev/null
+++ b/src/gui/opengl/qopenglproxy_win.cpp
@@ -0,0 +1,4600 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QByteArray>
+#include <QVector>
+#include <QCoreApplication>
+#include <QLoggingCategory>
+#include <qt_windows.h>
+// Must not include QOpenGLFunctions or anything that pulls in qopengl.h.
+// Otherwise we end up with errors about inconsistent linkage.
+#include <GL/gl.h>
+#include <EGL/egl.h>
+
+#if defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
+# error "Proxy GL is not compatible with static ES builds"
+#endif
+
+// This should not be an issue with the compilers used on Windows, but just in case:
+#ifndef Q_COMPILER_VARIADIC_MACROS
+# error "Proxy GL requires variadic macro support"
+#endif
+
+// Disable inconsistent dll linkage warnings. gl.h and egl.h are included and these mark
+// the egl and (w)gl functions as imported. We will mark them as exported.
+#if defined(Q_CC_MSVC)
+# pragma warning(disable : 4273)
+#elif defined(Q_CC_MINGW)
+# pragma GCC diagnostic ignored "-Wattributes"
+#endif
+
+#ifdef Q_OS_WIN64
+typedef signed long long int khronos_intptr_t;
+typedef signed long long int khronos_ssize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef signed long int khronos_ssize_t;
+#endif
+
+typedef char GLchar;
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t GLsizeiptr;
+
+Q_LOGGING_CATEGORY(qglLc, "qt.gui.openglproxy")
+
+class QAbstractWindowsOpenGL
+{
+public:
+ QAbstractWindowsOpenGL();
+ virtual ~QAbstractWindowsOpenGL() { }
+
+ enum LibType { // must match QOpenGLFunctions::PlatformGLType
+ DesktopGL = 0,
+ GLES2
+ };
+
+ LibType libraryType() const { return m_libraryType; }
+ HMODULE libraryHandle() const { return m_lib; }
+ bool functionsReady() const { return m_loaded; }
+
+ // WGL
+ BOOL (WINAPI * CopyContext)(HGLRC src, HGLRC dst, UINT mask);
+ HGLRC (WINAPI * CreateContext)(HDC dc);
+ HGLRC (WINAPI * CreateLayerContext)(HDC dc, int plane);
+ BOOL (WINAPI * DeleteContext)(HGLRC context);
+ HGLRC (WINAPI * GetCurrentContext)();
+ HDC (WINAPI * GetCurrentDC)();
+ PROC (WINAPI * GetProcAddress)(LPCSTR name);
+ BOOL (WINAPI * MakeCurrent)(HDC dc, HGLRC context);
+ BOOL (WINAPI * ShareLists)(HGLRC context1, HGLRC context2);
+ BOOL (WINAPI * UseFontBitmapsW)(HDC dc, DWORD first, DWORD count, DWORD base);
+ BOOL (WINAPI * UseFontOutlinesW)(HDC dc, DWORD first, DWORD count, DWORD base, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT gmf);
+ BOOL (WINAPI * DescribeLayerPlane)(HDC dc, int pixelFormat, int plane, UINT n,
+ LPLAYERPLANEDESCRIPTOR planeDescriptor);
+ int (WINAPI * SetLayerPaletteEntries)(HDC dc, int plane, int start, int entries,
+ CONST COLORREF *colors);
+ int (WINAPI * GetLayerPaletteEntries)(HDC dc, int plane, int start, int entries,
+ COLORREF *color);
+ BOOL (WINAPI * RealizeLayerPalette)(HDC dc, int plane, BOOL realize);
+ BOOL (WINAPI * SwapLayerBuffers)(HDC dc, UINT planes);
+ DWORD (WINAPI * SwapMultipleBuffers)(UINT n, CONST WGLSWAP *buffers);
+
+ // EGL
+ EGLint (EGLAPIENTRY * EGL_GetError)(void);
+ EGLDisplay (EGLAPIENTRY * EGL_GetDisplay)(EGLNativeDisplayType display_id);
+ EGLBoolean (EGLAPIENTRY * EGL_Initialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ EGLBoolean (EGLAPIENTRY * EGL_Terminate)(EGLDisplay dpy);
+ const char * (EGLAPIENTRY * EGL_QueryString)(EGLDisplay dpy, EGLint name);
+ EGLBoolean (EGLAPIENTRY * EGL_GetConfigs)(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config);
+ EGLBoolean (EGLAPIENTRY * EGL_ChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config);
+ EGLBoolean (EGLAPIENTRY * EGL_GetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value);
+ EGLSurface (EGLAPIENTRY * EGL_CreateWindowSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePbufferSurface)(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePixmapSurface)(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_DestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean (EGLAPIENTRY * EGL_QuerySurface)(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value);
+ EGLBoolean (EGLAPIENTRY * EGL_BindAPI)(EGLenum api);
+ EGLenum (EGLAPIENTRY * EGL_QueryAPI)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitClient)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_ReleaseThread)(void);
+ EGLSurface (EGLAPIENTRY * EGL_CreatePbufferFromClientBuffer)(EGLDisplay dpy, EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_SurfaceAttrib)(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value);
+ EGLBoolean (EGLAPIENTRY * EGL_BindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ EGLBoolean (EGLAPIENTRY * EGL_ReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+ EGLBoolean (EGLAPIENTRY * EGL_SwapInterval)(EGLDisplay dpy, EGLint interval);
+ EGLContext (EGLAPIENTRY * EGL_CreateContext)(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+ EGLBoolean (EGLAPIENTRY * EGL_DestroyContext)(EGLDisplay dpy, EGLContext ctx);
+ EGLBoolean (EGLAPIENTRY * EGL_MakeCurrent)(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx);
+ EGLContext (EGLAPIENTRY * EGL_GetCurrentContext)(void);
+ EGLSurface (EGLAPIENTRY * EGL_GetCurrentSurface)(EGLint readdraw);
+ EGLDisplay (EGLAPIENTRY * EGL_GetCurrentDisplay)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_QueryContext)(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitGL)(void);
+ EGLBoolean (EGLAPIENTRY * EGL_WaitNative)(EGLint engine);
+ EGLBoolean (EGLAPIENTRY * EGL_SwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+ EGLBoolean (EGLAPIENTRY * EGL_CopyBuffers)(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target);
+ __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * EGL_GetProcAddress)(const char *procname);
+
+ // OpenGL 1.0
+ void (APIENTRY * Viewport)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * DepthRange)(GLdouble nearVal, GLdouble farVal);
+ GLboolean (APIENTRY * IsEnabled)(GLenum cap);
+ void (APIENTRY * GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexParameteriv)(GLenum target, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
+ const GLubyte * (APIENTRY * GetString)(GLenum name);
+ void (APIENTRY * GetIntegerv)(GLenum pname, GLint *params);
+ void (APIENTRY * GetFloatv)(GLenum pname, GLfloat *params);
+ GLenum (APIENTRY * GetError)();
+ void (APIENTRY * GetDoublev)(GLenum pname, GLdouble *params);
+ void (APIENTRY * GetBooleanv)(GLenum pname, GLboolean *params);
+ void (APIENTRY * ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+ void (APIENTRY * ReadBuffer)(GLenum mode);
+ void (APIENTRY * PixelStorei)(GLenum pname, GLint param);
+ void (APIENTRY * PixelStoref)(GLenum pname, GLfloat param);
+ void (APIENTRY * DepthFunc)(GLenum func);
+ void (APIENTRY * StencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * StencilFunc)(GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * LogicOp)(GLenum opcode);
+ void (APIENTRY * BlendFunc)(GLenum sfactor, GLenum dfactor);
+ void (APIENTRY * Flush)();
+ void (APIENTRY * Finish)();
+ void (APIENTRY * Enable)(GLenum cap);
+ void (APIENTRY * Disable)(GLenum cap);
+ void (APIENTRY * DepthMask)(GLboolean flag);
+ void (APIENTRY * ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void (APIENTRY * StencilMask)(GLuint mask);
+ void (APIENTRY * ClearDepth)(GLdouble depth);
+ void (APIENTRY * ClearStencil)(GLint s);
+ void (APIENTRY * ClearColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * Clear)(GLbitfield mask);
+ void (APIENTRY * DrawBuffer)(GLenum mode);
+ void (APIENTRY * TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexParameteriv)(GLenum target, GLenum pname, const GLint *params);
+ void (APIENTRY * TexParameteri)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexParameterf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * Scissor)(GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * PolygonMode)(GLenum face, GLenum mode);
+ void (APIENTRY * PointSize)(GLfloat size);
+ void (APIENTRY * LineWidth)(GLfloat width);
+ void (APIENTRY * Hint)(GLenum target, GLenum mode);
+ void (APIENTRY * FrontFace)(GLenum mode);
+ void (APIENTRY * CullFace)(GLenum mode);
+
+ void (APIENTRY * Translatef)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Translated)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Scalef)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Scaled)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * PushMatrix)();
+ void (APIENTRY * PopMatrix)();
+ void (APIENTRY * Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+ void (APIENTRY * MultMatrixd)(const GLdouble *m);
+ void (APIENTRY * MultMatrixf)(const GLfloat *m);
+ void (APIENTRY * MatrixMode)(GLenum mode);
+ void (APIENTRY * LoadMatrixd)(const GLdouble *m);
+ void (APIENTRY * LoadMatrixf)(const GLfloat *m);
+ void (APIENTRY * LoadIdentity)();
+ void (APIENTRY * Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+ GLboolean (APIENTRY * IsList)(GLuint list);
+ void (APIENTRY * GetTexGeniv)(GLenum coord, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexGenfv)(GLenum coord, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetTexGendv)(GLenum coord, GLenum pname, GLdouble *params);
+ void (APIENTRY * GetTexEnviv)(GLenum target, GLenum pname, GLint *params);
+ void (APIENTRY * GetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetPolygonStipple)(GLubyte *mask);
+ void (APIENTRY * GetPixelMapusv)(GLenum map, GLushort *values);
+ void (APIENTRY * GetPixelMapuiv)(GLenum map, GLuint *values);
+ void (APIENTRY * GetPixelMapfv)(GLenum map, GLfloat *values);
+ void (APIENTRY * GetMaterialiv)(GLenum face, GLenum pname, GLint *params);
+ void (APIENTRY * GetMaterialfv)(GLenum face, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetMapiv)(GLenum target, GLenum query, GLint *v);
+ void (APIENTRY * GetMapfv)(GLenum target, GLenum query, GLfloat *v);
+ void (APIENTRY * GetMapdv)(GLenum target, GLenum query, GLdouble *v);
+ void (APIENTRY * GetLightiv)(GLenum light, GLenum pname, GLint *params);
+ void (APIENTRY * GetLightfv)(GLenum light, GLenum pname, GLfloat *params);
+ void (APIENTRY * GetClipPlane)(GLenum plane, GLdouble *equation);
+ void (APIENTRY * DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
+ void (APIENTRY * PixelMapusv)(GLenum map, GLint mapsize, const GLushort *values);
+ void (APIENTRY * PixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values);
+ void (APIENTRY * PixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values);
+ void (APIENTRY * PixelTransferi)(GLenum pname, GLint param);
+ void (APIENTRY * PixelTransferf)(GLenum pname, GLfloat param);
+ void (APIENTRY * PixelZoom)(GLfloat xfactor, GLfloat yfactor);
+ void (APIENTRY * AlphaFunc)(GLenum func, GLfloat ref);
+ void (APIENTRY * EvalPoint2)(GLint i, GLint j);
+ void (APIENTRY * EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
+ void (APIENTRY * EvalPoint1)(GLint i);
+ void (APIENTRY * EvalMesh1)(GLenum mode, GLint i1, GLint i2);
+ void (APIENTRY * EvalCoord2fv)(const GLfloat *u);
+ void (APIENTRY * EvalCoord2f)(GLfloat u, GLfloat v);
+ void (APIENTRY * EvalCoord2dv)(const GLdouble *u);
+ void (APIENTRY * EvalCoord2d)(GLdouble u, GLdouble v);
+ void (APIENTRY * EvalCoord1fv)(const GLfloat *u);
+ void (APIENTRY * EvalCoord1f)(GLfloat u);
+ void (APIENTRY * EvalCoord1dv)(const GLdouble *u);
+ void (APIENTRY * EvalCoord1d)(GLdouble u);
+ void (APIENTRY * MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
+ void (APIENTRY * MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
+ void (APIENTRY * MapGrid1f)(GLint un, GLfloat u1, GLfloat u2);
+ void (APIENTRY * MapGrid1d)(GLint un, GLdouble u1, GLdouble u2);
+ void (APIENTRY * Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+ void (APIENTRY * Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+ void (APIENTRY * Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+ void (APIENTRY * Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+ void (APIENTRY * PushAttrib)(GLbitfield mask);
+ void (APIENTRY * PopAttrib)();
+ void (APIENTRY * Accum)(GLenum op, GLfloat value);
+ void (APIENTRY * IndexMask)(GLuint mask);
+ void (APIENTRY * ClearIndex)(GLfloat c);
+ void (APIENTRY * ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * PushName)(GLuint name);
+ void (APIENTRY * PopName)();
+ void (APIENTRY * PassThrough)(GLfloat token);
+ void (APIENTRY * LoadName)(GLuint name);
+ void (APIENTRY * InitNames)();
+ GLint (APIENTRY * RenderMode)(GLenum mode);
+ void (APIENTRY * SelectBuffer)(GLsizei size, GLuint *buffer);
+ void (APIENTRY * FeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer);
+ void (APIENTRY * TexGeniv)(GLenum coord, GLenum pname, const GLint *params);
+ void (APIENTRY * TexGeni)(GLenum coord, GLenum pname, GLint param);
+ void (APIENTRY * TexGenfv)(GLenum coord, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexGenf)(GLenum coord, GLenum pname, GLfloat param);
+ void (APIENTRY * TexGendv)(GLenum coord, GLenum pname, const GLdouble *params);
+ void (APIENTRY * TexGend)(GLenum coord, GLenum pname, GLdouble param);
+ void (APIENTRY * TexEnviv)(GLenum target, GLenum pname, const GLint *params);
+ void (APIENTRY * TexEnvi)(GLenum target, GLenum pname, GLint param);
+ void (APIENTRY * TexEnvfv)(GLenum target, GLenum pname, const GLfloat *params);
+ void (APIENTRY * TexEnvf)(GLenum target, GLenum pname, GLfloat param);
+ void (APIENTRY * ShadeModel)(GLenum mode);
+ void (APIENTRY * PolygonStipple)(const GLubyte *mask);
+ void (APIENTRY * Materialiv)(GLenum face, GLenum pname, const GLint *params);
+ void (APIENTRY * Materiali)(GLenum face, GLenum pname, GLint param);
+ void (APIENTRY * Materialfv)(GLenum face, GLenum pname, const GLfloat *params);
+ void (APIENTRY * Materialf)(GLenum face, GLenum pname, GLfloat param);
+ void (APIENTRY * LineStipple)(GLint factor, GLushort pattern);
+ void (APIENTRY * LightModeliv)(GLenum pname, const GLint *params);
+ void (APIENTRY * LightModeli)(GLenum pname, GLint param);
+ void (APIENTRY * LightModelfv)(GLenum pname, const GLfloat *params);
+ void (APIENTRY * LightModelf)(GLenum pname, GLfloat param);
+ void (APIENTRY * Lightiv)(GLenum light, GLenum pname, const GLint *params);
+ void (APIENTRY * Lighti)(GLenum light, GLenum pname, GLint param);
+ void (APIENTRY * Lightfv)(GLenum light, GLenum pname, const GLfloat *params);
+ void (APIENTRY * Lightf)(GLenum light, GLenum pname, GLfloat param);
+ void (APIENTRY * Fogiv)(GLenum pname, const GLint *params);
+ void (APIENTRY * Fogi)(GLenum pname, GLint param);
+ void (APIENTRY * Fogfv)(GLenum pname, const GLfloat *params);
+ void (APIENTRY * Fogf)(GLenum pname, GLfloat param);
+ void (APIENTRY * ColorMaterial)(GLenum face, GLenum mode);
+ void (APIENTRY * ClipPlane)(GLenum plane, const GLdouble *equation);
+ void (APIENTRY * Vertex4sv)(const GLshort *v);
+ void (APIENTRY * Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w);
+ void (APIENTRY * Vertex4iv)(const GLint *v);
+ void (APIENTRY * Vertex4i)(GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * Vertex4fv)(const GLfloat *v);
+ void (APIENTRY * Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * Vertex4dv)(const GLdouble *v);
+ void (APIENTRY * Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+ void (APIENTRY * Vertex3sv)(const GLshort *v);
+ void (APIENTRY * Vertex3s)(GLshort x, GLshort y, GLshort z);
+ void (APIENTRY * Vertex3iv)(const GLint *v);
+ void (APIENTRY * Vertex3i)(GLint x, GLint y, GLint z);
+ void (APIENTRY * Vertex3fv)(const GLfloat *v);
+ void (APIENTRY * Vertex3f)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Vertex3dv)(const GLdouble *v);
+ void (APIENTRY * Vertex3d)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * Vertex2sv)(const GLshort *v);
+ void (APIENTRY * Vertex2s)(GLshort x, GLshort y);
+ void (APIENTRY * Vertex2iv)(const GLint *v);
+ void (APIENTRY * Vertex2i)(GLint x, GLint y);
+ void (APIENTRY * Vertex2fv)(const GLfloat *v);
+ void (APIENTRY * Vertex2f)(GLfloat x, GLfloat y);
+ void (APIENTRY * Vertex2dv)(const GLdouble *v);
+ void (APIENTRY * Vertex2d)(GLdouble x, GLdouble y);
+ void (APIENTRY * TexCoord4sv)(const GLshort *v);
+ void (APIENTRY * TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q);
+ void (APIENTRY * TexCoord4iv)(const GLint *v);
+ void (APIENTRY * TexCoord4i)(GLint s, GLint t, GLint r, GLint q);
+ void (APIENTRY * TexCoord4fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+ void (APIENTRY * TexCoord4dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+ void (APIENTRY * TexCoord3sv)(const GLshort *v);
+ void (APIENTRY * TexCoord3s)(GLshort s, GLshort t, GLshort r);
+ void (APIENTRY * TexCoord3iv)(const GLint *v);
+ void (APIENTRY * TexCoord3i)(GLint s, GLint t, GLint r);
+ void (APIENTRY * TexCoord3fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord3f)(GLfloat s, GLfloat t, GLfloat r);
+ void (APIENTRY * TexCoord3dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord3d)(GLdouble s, GLdouble t, GLdouble r);
+ void (APIENTRY * TexCoord2sv)(const GLshort *v);
+ void (APIENTRY * TexCoord2s)(GLshort s, GLshort t);
+ void (APIENTRY * TexCoord2iv)(const GLint *v);
+ void (APIENTRY * TexCoord2i)(GLint s, GLint t);
+ void (APIENTRY * TexCoord2fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord2f)(GLfloat s, GLfloat t);
+ void (APIENTRY * TexCoord2dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord2d)(GLdouble s, GLdouble t);
+ void (APIENTRY * TexCoord1sv)(const GLshort *v);
+ void (APIENTRY * TexCoord1s)(GLshort s);
+ void (APIENTRY * TexCoord1iv)(const GLint *v);
+ void (APIENTRY * TexCoord1i)(GLint s);
+ void (APIENTRY * TexCoord1fv)(const GLfloat *v);
+ void (APIENTRY * TexCoord1f)(GLfloat s);
+ void (APIENTRY * TexCoord1dv)(const GLdouble *v);
+ void (APIENTRY * TexCoord1d)(GLdouble s);
+ void (APIENTRY * Rectsv)(const GLshort *v1, const GLshort *v2);
+ void (APIENTRY * Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
+ void (APIENTRY * Rectiv)(const GLint *v1, const GLint *v2);
+ void (APIENTRY * Recti)(GLint x1, GLint y1, GLint x2, GLint y2);
+ void (APIENTRY * Rectfv)(const GLfloat *v1, const GLfloat *v2);
+ void (APIENTRY * Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
+ void (APIENTRY * Rectdv)(const GLdouble *v1, const GLdouble *v2);
+ void (APIENTRY * Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
+ void (APIENTRY * RasterPos4sv)(const GLshort *v);
+ void (APIENTRY * RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w);
+ void (APIENTRY * RasterPos4iv)(const GLint *v);
+ void (APIENTRY * RasterPos4i)(GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * RasterPos4fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * RasterPos4dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+ void (APIENTRY * RasterPos3sv)(const GLshort *v);
+ void (APIENTRY * RasterPos3s)(GLshort x, GLshort y, GLshort z);
+ void (APIENTRY * RasterPos3iv)(const GLint *v);
+ void (APIENTRY * RasterPos3i)(GLint x, GLint y, GLint z);
+ void (APIENTRY * RasterPos3fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos3f)(GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * RasterPos3dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos3d)(GLdouble x, GLdouble y, GLdouble z);
+ void (APIENTRY * RasterPos2sv)(const GLshort *v);
+ void (APIENTRY * RasterPos2s)(GLshort x, GLshort y);
+ void (APIENTRY * RasterPos2iv)(const GLint *v);
+ void (APIENTRY * RasterPos2i)(GLint x, GLint y);
+ void (APIENTRY * RasterPos2fv)(const GLfloat *v);
+ void (APIENTRY * RasterPos2f)(GLfloat x, GLfloat y);
+ void (APIENTRY * RasterPos2dv)(const GLdouble *v);
+ void (APIENTRY * RasterPos2d)(GLdouble x, GLdouble y);
+ void (APIENTRY * Normal3sv)(const GLshort *v);
+ void (APIENTRY * Normal3s)(GLshort nx, GLshort ny, GLshort nz);
+ void (APIENTRY * Normal3iv)(const GLint *v);
+ void (APIENTRY * Normal3i)(GLint nx, GLint ny, GLint nz);
+ void (APIENTRY * Normal3fv)(const GLfloat *v);
+ void (APIENTRY * Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz);
+ void (APIENTRY * Normal3dv)(const GLdouble *v);
+ void (APIENTRY * Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz);
+ void (APIENTRY * Normal3bv)(const GLbyte *v);
+ void (APIENTRY * Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz);
+ void (APIENTRY * Indexsv)(const GLshort *c);
+ void (APIENTRY * Indexs)(GLshort c);
+ void (APIENTRY * Indexiv)(const GLint *c);
+ void (APIENTRY * Indexi)(GLint c);
+ void (APIENTRY * Indexfv)(const GLfloat *c);
+ void (APIENTRY * Indexf)(GLfloat c);
+ void (APIENTRY * Indexdv)(const GLdouble *c);
+ void (APIENTRY * Indexd)(GLdouble c);
+ void (APIENTRY * End)();
+ void (APIENTRY * EdgeFlagv)(const GLboolean *flag);
+ void (APIENTRY * EdgeFlag)(GLboolean flag);
+ void (APIENTRY * Color4usv)(const GLushort *v);
+ void (APIENTRY * Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha);
+ void (APIENTRY * Color4uiv)(const GLuint *v);
+ void (APIENTRY * Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha);
+ void (APIENTRY * Color4ubv)(const GLubyte *v);
+ void (APIENTRY * Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+ void (APIENTRY * Color4sv)(const GLshort *v);
+ void (APIENTRY * Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha);
+ void (APIENTRY * Color4iv)(const GLint *v);
+ void (APIENTRY * Color4i)(GLint red, GLint green, GLint blue, GLint alpha);
+ void (APIENTRY * Color4fv)(const GLfloat *v);
+ void (APIENTRY * Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void (APIENTRY * Color4dv)(const GLdouble *v);
+ void (APIENTRY * Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
+ void (APIENTRY * Color4bv)(const GLbyte *v);
+ void (APIENTRY * Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
+ void (APIENTRY * Color3usv)(const GLushort *v);
+ void (APIENTRY * Color3us)(GLushort red, GLushort green, GLushort blue);
+ void (APIENTRY * Color3uiv)(const GLuint *v);
+ void (APIENTRY * Color3ui)(GLuint red, GLuint green, GLuint blue);
+ void (APIENTRY * Color3ubv)(const GLubyte *v);
+ void (APIENTRY * Color3ub)(GLubyte red, GLubyte green, GLubyte blue);
+ void (APIENTRY * Color3sv)(const GLshort *v);
+ void (APIENTRY * Color3s)(GLshort red, GLshort green, GLshort blue);
+ void (APIENTRY * Color3iv)(const GLint *v);
+ void (APIENTRY * Color3i)(GLint red, GLint green, GLint blue);
+ void (APIENTRY * Color3fv)(const GLfloat *v);
+ void (APIENTRY * Color3f)(GLfloat red, GLfloat green, GLfloat blue);
+ void (APIENTRY * Color3dv)(const GLdouble *v);
+ void (APIENTRY * Color3d)(GLdouble red, GLdouble green, GLdouble blue);
+ void (APIENTRY * Color3bv)(const GLbyte *v);
+ void (APIENTRY * Color3b)(GLbyte red, GLbyte green, GLbyte blue);
+ void (APIENTRY * Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
+ void (APIENTRY * Begin)(GLenum mode);
+ void (APIENTRY * ListBase)(GLuint base);
+ GLuint (APIENTRY * GenLists)(GLsizei range);
+ void (APIENTRY * DeleteLists)(GLuint list, GLsizei range);
+ void (APIENTRY * CallLists)(GLsizei n, GLenum type, const GLvoid *lists);
+ void (APIENTRY * CallList)(GLuint list);
+ void (APIENTRY * EndList)();
+ void (APIENTRY * NewList)(GLuint list, GLenum mode);
+
+ // OpenGL 1.1
+ void (APIENTRY * Indexubv)(const GLubyte *c);
+ void (APIENTRY * Indexub)(GLubyte c);
+ GLboolean (APIENTRY * IsTexture)(GLuint texture);
+ void (APIENTRY * GenTextures)(GLsizei n, GLuint *textures);
+ void (APIENTRY * DeleteTextures)(GLsizei n, const GLuint *textures);
+ void (APIENTRY * BindTexture)(GLenum target, GLuint texture);
+ void (APIENTRY * TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+ void (APIENTRY * CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+ void (APIENTRY * CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+ void (APIENTRY * CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void (APIENTRY * CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+ void (APIENTRY * PolygonOffset)(GLfloat factor, GLfloat units);
+ void (APIENTRY * GetPointerv)(GLenum pname, GLvoid* *params);
+ void (APIENTRY * DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+ void (APIENTRY * DrawArrays)(GLenum mode, GLint first, GLsizei count);
+
+ void (APIENTRY * PushClientAttrib)(GLbitfield mask);
+ void (APIENTRY * PopClientAttrib)();
+ void (APIENTRY * PrioritizeTextures)(GLsizei n, const GLuint *textures, const GLfloat *priorities);
+ GLboolean (APIENTRY * AreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences);
+ void (APIENTRY * VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * NormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * InterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * IndexPointer)(GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * EnableClientState)(GLenum array);
+ void (APIENTRY * EdgeFlagPointer)(GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * DisableClientState)(GLenum array);
+ void (APIENTRY * ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+ void (APIENTRY * ArrayElement)(GLint i);
+
+ // OpenGL ES 2.0
+ void (APIENTRY * ActiveTexture)(GLenum texture);
+ void (APIENTRY * AttachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * BindAttribLocation)(GLuint program, GLuint index, const GLchar* name);
+ void (APIENTRY * BindBuffer)(GLenum target, GLuint buffer);
+ void (APIENTRY * BindFramebuffer)(GLenum target, GLuint framebuffer);
+ void (APIENTRY * BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+ void (APIENTRY * BlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void (APIENTRY * BlendEquation)(GLenum mode);
+ void (APIENTRY * BlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha);
+ void (APIENTRY * BlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ void (APIENTRY * BufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+ void (APIENTRY * BufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
+ GLenum (APIENTRY * CheckFramebufferStatus)(GLenum target);
+ void (APIENTRY * ClearDepthf)(GLclampf depth);
+ void (APIENTRY * CompileShader)(GLuint shader);
+ void (APIENTRY * CompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+ void (APIENTRY * CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
+ GLuint (APIENTRY * CreateProgram)(void);
+ GLuint (APIENTRY * CreateShader)(GLenum type);
+ void (APIENTRY * DeleteBuffers)(GLsizei n, const GLuint* buffers);
+ void (APIENTRY * DeleteFramebuffers)(GLsizei n, const GLuint* framebuffers);
+ void (APIENTRY * DeleteProgram)(GLuint program);
+ void (APIENTRY * DeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers);
+ void (APIENTRY * DeleteShader)(GLuint shader);
+ void (APIENTRY * DepthRangef)(GLclampf zNear, GLclampf zFar);
+ void (APIENTRY * DetachShader)(GLuint program, GLuint shader);
+ void (APIENTRY * DisableVertexAttribArray)(GLuint index);
+ void (APIENTRY * EnableVertexAttribArray)(GLuint index);
+ void (APIENTRY * FramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+ void (APIENTRY * FramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+ void (APIENTRY * GenBuffers)(GLsizei n, GLuint* buffers);
+ void (APIENTRY * GenerateMipmap)(GLenum target);
+ void (APIENTRY * GenFramebuffers)(GLsizei n, GLuint* framebuffers);
+ void (APIENTRY * GenRenderbuffers)(GLsizei n, GLuint* renderbuffers);
+ void (APIENTRY * GetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ void (APIENTRY * GetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+ void (APIENTRY * GetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+ int (APIENTRY * GetAttribLocation)(GLuint program, const GLchar* name);
+ void (APIENTRY * GetBufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * GetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params);
+ void (APIENTRY * GetProgramiv)(GLuint program, GLenum pname, GLint* params);
+ void (APIENTRY * GetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ void (APIENTRY * GetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params);
+ void (APIENTRY * GetShaderiv)(GLuint shader, GLenum pname, GLint* params);
+ void (APIENTRY * GetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
+ void (APIENTRY * GetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+ void (APIENTRY * GetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
+ void (APIENTRY * GetUniformfv)(GLuint program, GLint location, GLfloat* params);
+ void (APIENTRY * GetUniformiv)(GLuint program, GLint location, GLint* params);
+ int (APIENTRY * GetUniformLocation)(GLuint program, const GLchar* name);
+ void (APIENTRY * GetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params);
+ void (APIENTRY * GetVertexAttribiv)(GLuint index, GLenum pname, GLint* params);
+ void (APIENTRY * GetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer);
+ GLboolean (APIENTRY * IsBuffer)(GLuint buffer);
+ GLboolean (APIENTRY * IsFramebuffer)(GLuint framebuffer);
+ GLboolean (APIENTRY * IsProgram)(GLuint program);
+ GLboolean (APIENTRY * IsRenderbuffer)(GLuint renderbuffer);
+ GLboolean (APIENTRY * IsShader)(GLuint shader);
+ void (APIENTRY * LinkProgram)(GLuint program);
+ void (APIENTRY * ReleaseShaderCompiler)(void);
+ void (APIENTRY * RenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void (APIENTRY * SampleCoverage)(GLclampf value, GLboolean invert);
+ void (APIENTRY * ShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+ void (APIENTRY * ShaderSource)(GLuint shader, GLsizei count, const GLchar* *string, const GLint* length);
+ void (APIENTRY * StencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void (APIENTRY * StencilMaskSeparate)(GLenum face, GLuint mask);
+ void (APIENTRY * StencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+ void (APIENTRY * Uniform1f)(GLint location, GLfloat x);
+ void (APIENTRY * Uniform1fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform1i)(GLint location, GLint x);
+ void (APIENTRY * Uniform1iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform2f)(GLint location, GLfloat x, GLfloat y);
+ void (APIENTRY * Uniform2fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform2i)(GLint location, GLint x, GLint y);
+ void (APIENTRY * Uniform2iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * Uniform3fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform3i)(GLint location, GLint x, GLint y, GLint z);
+ void (APIENTRY * Uniform3iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * Uniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * Uniform4fv)(GLint location, GLsizei count, const GLfloat* v);
+ void (APIENTRY * Uniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w);
+ void (APIENTRY * Uniform4iv)(GLint location, GLsizei count, const GLint* v);
+ void (APIENTRY * UniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+ void (APIENTRY * UseProgram)(GLuint program);
+ void (APIENTRY * ValidateProgram)(GLuint program);
+ void (APIENTRY * VertexAttrib1f)(GLuint indx, GLfloat x);
+ void (APIENTRY * VertexAttrib1fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y);
+ void (APIENTRY * VertexAttrib2fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ void (APIENTRY * VertexAttrib3fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void (APIENTRY * VertexAttrib4fv)(GLuint indx, const GLfloat* values);
+ void (APIENTRY * VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
+
+protected:
+ HMODULE m_lib;
+ LibType m_libraryType;
+ bool m_loaded;
+};
+
+class QWindowsOpenGL : public QAbstractWindowsOpenGL
+{
+public:
+ QWindowsOpenGL();
+ ~QWindowsOpenGL();
+
+private:
+ bool load(const char *glName, const char *eglName);
+ void unload();
+
+ void resolve();
+
+ void resolveWGL();
+ void resolveEGL();
+ void resolveGLCommon();
+ void resolveGL11();
+ void resolveGLES2();
+
+ FARPROC resolveFunc(const char *name);
+ FARPROC resolveEglFunc(const char *name);
+
+ bool testDesktopGL();
+
+ HMODULE m_eglLib;
+};
+
+static QString qgl_windowsErrorMessage(unsigned long errorCode)
+{
+ QString rc = QString::fromLatin1("#%1: ").arg(errorCode);
+ ushort *lpMsgBuf;
+
+ const int len = FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
+ if (len) {
+ rc += QString::fromUtf16(lpMsgBuf, len);
+ LocalFree(lpMsgBuf);
+ } else {
+ rc += QString::fromLatin1("<unknown error>");
+ }
+ return rc;
+}
+
+static HMODULE qgl_loadLib(const char *name, bool warnOnFail = true)
+{
+ HMODULE lib = LoadLibraryA(name);
+
+ if (lib)
+ return lib;
+
+ if (warnOnFail) {
+ QString msg = qgl_windowsErrorMessage(GetLastError());
+ qCWarning(qglLc, "Failed to load %s: %s", name, qPrintable(msg));
+ }
+
+ return 0;
+}
+
+QWindowsOpenGL::QWindowsOpenGL()
+ : m_eglLib(0)
+{
+ if (qEnvironmentVariableIsSet("QT_OPENGLPROXY_DEBUG"))
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.gui.openglproxy=true"));
+
+ enum RequestedLib {
+ Unknown,
+ Desktop,
+ GLES
+ } req = Unknown;
+
+ // Check if the application has requested a certain implementation.
+ if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
+ req = Desktop;
+ else if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES))
+ req = GLES;
+
+ // Check if an implementation is forced through the environment variable.
+ QByteArray requested = qgetenv("QT_OPENGL");
+ if (requested == QByteArrayLiteral("desktop"))
+ req = Desktop;
+ else if (requested == QByteArrayLiteral("angle"))
+ req = GLES;
+
+ bool desktopTested = false;
+ if (req == Unknown) {
+ // No explicit request. Start testing. opengl32.dll is preferred. Angle is the fallback.
+ desktopTested = true;
+ if (testDesktopGL())
+ req = Desktop;
+ else
+ req = GLES;
+ }
+
+ Q_ASSERT(req != Unknown);
+
+ if (req == GLES) {
+ qCDebug(qglLc, "Using Angle");
+#ifdef QT_DEBUG
+ m_loaded = load("libglesv2d.dll", "libegld.dll");
+#else
+ m_loaded = load("libglesv2.dll", "libegl.dll");
+#endif
+ if (m_loaded) {
+ m_libraryType = QWindowsOpenGL::GLES2;
+ } else {
+ // Could not load Angle. Try opengl32.dll.
+ if (!desktopTested && testDesktopGL())
+ req = Desktop;
+ }
+ }
+
+ if (req == Desktop) {
+ qCDebug(qglLc, "Using desktop OpenGL");
+ m_loaded = load("opengl32.dll", 0);
+ if (m_loaded)
+ m_libraryType = QWindowsOpenGL::DesktopGL;
+ }
+
+ if (m_loaded)
+ resolve();
+
+ // When no library is loaded, keep on running. All EGL/WGL/GL functions will
+ // return 0 in this case without further errors. It is up to the clients
+ // (application code, Qt Quick, etc.) to act when eglInitialize() and
+ // friends fail, i.e. when QOpenGLContext::create() returns false due to the
+ // platform plugin's failure to create a platform context.
+}
+
+QWindowsOpenGL::~QWindowsOpenGL()
+{
+ unload();
+}
+
+bool QWindowsOpenGL::load(const char *glName, const char *eglName)
+{
+ qCDebug(qglLc, "Loading %s %s", glName, eglName ? eglName : "");
+
+ bool result = true;
+
+ if (glName) {
+ m_lib = qgl_loadLib(glName);
+ result &= m_lib != 0;
+ }
+
+ if (eglName) {
+ m_eglLib = qgl_loadLib(eglName);
+ result &= m_eglLib != 0;
+ }
+
+ if (!result)
+ unload();
+
+ return result;
+}
+
+void QWindowsOpenGL::unload()
+{
+ if (m_lib) {
+ FreeLibrary(m_lib);
+ m_lib = 0;
+ }
+ if (m_eglLib) {
+ FreeLibrary(m_eglLib);
+ m_eglLib = 0;
+ }
+ m_loaded = false;
+}
+
+FARPROC QWindowsOpenGL::resolveFunc(const char *name)
+{
+ FARPROC proc = m_lib ? ::GetProcAddress(m_lib, name) : 0;
+ if (!proc)
+ qCDebug(qglLc, "Failed to resolve GL function %s", name);
+ return proc;
+}
+
+FARPROC QWindowsOpenGL::resolveEglFunc(const char *name)
+{
+ FARPROC proc = m_eglLib ? ::GetProcAddress(m_eglLib, name) : 0;
+ if (!proc)
+ qCDebug(qglLc, "Failed to resolve EGL function %s", name);
+ return proc;
+}
+
+void QWindowsOpenGL::resolveWGL()
+{
+ CopyContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC, UINT)>(resolveFunc("wglCopyContext"));
+ CreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(resolveFunc("wglCreateContext"));
+ CreateLayerContext = reinterpret_cast<HGLRC (WINAPI *)(HDC, int)>(resolveFunc("wglCreateLayerContext"));
+ DeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(resolveFunc("wglDeleteContext"));
+ GetCurrentContext = reinterpret_cast<HGLRC (WINAPI *)()>(resolveFunc("wglGetCurrentContext"));
+ GetCurrentDC = reinterpret_cast<HDC (WINAPI *)()>(resolveFunc("wglGetCurrentDC"));
+ GetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(resolveFunc("wglGetProcAddress"));
+ MakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(resolveFunc("wglMakeCurrent"));
+ ShareLists = reinterpret_cast<BOOL (WINAPI *)(HGLRC, HGLRC)>(resolveFunc("wglShareLists"));
+ UseFontBitmapsW = reinterpret_cast<BOOL (WINAPI *)(HDC, DWORD, DWORD, DWORD)>(resolveFunc("wglUseFontBitmapsW"));
+ UseFontOutlinesW = reinterpret_cast<BOOL (WINAPI *)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT)>(resolveFunc("wglUseFontOutlinesW"));
+ DescribeLayerPlane = reinterpret_cast<BOOL (WINAPI *)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR)>(resolveFunc("wglDescribeLayerPlane"));
+ SetLayerPaletteEntries = reinterpret_cast<int (WINAPI *)(HDC, int, int, int, CONST COLORREF *)>(resolveFunc("wglSetLayerPaletteEntries"));
+ GetLayerPaletteEntries = reinterpret_cast<int (WINAPI *)(HDC, int, int, int, COLORREF *)>(resolveFunc("wglGetLayerPaletteEntries"));
+ RealizeLayerPalette = reinterpret_cast<BOOL (WINAPI *)(HDC, int, BOOL)>(resolveFunc("wglRealizeLayerPalette"));
+ SwapLayerBuffers = reinterpret_cast<BOOL (WINAPI *)(HDC, UINT)>(resolveFunc("wglSwapLayerBuffers"));
+ SwapMultipleBuffers = reinterpret_cast<DWORD (WINAPI *)(UINT, CONST WGLSWAP *)>(resolveFunc("wglSwapMultipleBuffers"));
+}
+
+void QWindowsOpenGL::resolveEGL()
+{
+ EGL_GetError = reinterpret_cast<EGLint (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetError"));
+ EGL_GetDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)>(resolveEglFunc("eglGetDisplay"));
+ EGL_Initialize = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)>(resolveEglFunc("eglInitialize"));
+ EGL_Terminate = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay)>(resolveEglFunc("eglTerminate"));
+ EGL_QueryString = reinterpret_cast<const char * (EGLAPIENTRY *)(EGLDisplay, EGLint)>(resolveEglFunc("eglQueryString"));
+ EGL_GetConfigs = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay, EGLConfig *, EGLint, EGLint *)>(resolveEglFunc("eglGetConfigs"));
+ EGL_ChooseConfig = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)>(resolveEglFunc("eglChooseConfig"));
+ EGL_GetConfigAttrib = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLint, EGLint *)>(resolveEglFunc("eglGetConfigAttrib"));
+ EGL_CreateWindowSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint *)>(resolveEglFunc("eglCreateWindowSurface"));
+ EGL_CreatePbufferSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLDisplay , EGLConfig, const EGLint *)>(resolveEglFunc("eglCreatePbufferSurface"));
+ EGL_CreatePixmapSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY * )(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType , const EGLint *)>(resolveEglFunc("eglCreatePixmapSurface"));
+ EGL_DestroySurface = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface )>(resolveEglFunc("eglDestroySurface"));
+ EGL_QuerySurface = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay , EGLSurface , EGLint , EGLint *)>(resolveEglFunc("eglQuerySurface"));
+ EGL_BindAPI = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLenum )>(resolveEglFunc("eglBindAPI"));
+ EGL_QueryAPI = reinterpret_cast<EGLenum (EGLAPIENTRY *)(void)>(resolveEglFunc("eglQueryAPI"));
+ EGL_WaitClient = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglWaitClient"));
+ EGL_ReleaseThread = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglReleaseThread"));
+ EGL_CreatePbufferFromClientBuffer = reinterpret_cast<EGLSurface (EGLAPIENTRY * )(EGLDisplay , EGLenum , EGLClientBuffer , EGLConfig , const EGLint *)>(resolveEglFunc("eglCreatePbufferFromClientBuffer"));
+ EGL_SurfaceAttrib = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLint , EGLint )>(resolveEglFunc("eglSurfaceAttrib"));
+ EGL_BindTexImage = reinterpret_cast<EGLBoolean (EGLAPIENTRY * )(EGLDisplay, EGLSurface , EGLint )>(resolveEglFunc("eglBindTexImage"));
+ EGL_ReleaseTexImage = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLSurface , EGLint)>(resolveEglFunc("eglReleaseTexImage"));
+ EGL_SwapInterval = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLint )>(resolveEglFunc("eglSwapInterval"));
+ EGL_CreateContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(EGLDisplay , EGLConfig , EGLContext , const EGLint *)>(resolveEglFunc("eglCreateContext"));
+ EGL_DestroyContext = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLContext)>(resolveEglFunc("eglDestroyContext"));
+ EGL_MakeCurrent = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLSurface , EGLContext )>(resolveEglFunc("eglMakeCurrent"));
+ EGL_GetCurrentContext = reinterpret_cast<EGLContext (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetCurrentContext"));
+ EGL_GetCurrentSurface = reinterpret_cast<EGLSurface (EGLAPIENTRY *)(EGLint )>(resolveEglFunc("eglGetCurrentSurface"));
+ EGL_GetCurrentDisplay = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(void)>(resolveEglFunc("eglGetCurrentDisplay"));
+ EGL_QueryContext = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLContext , EGLint , EGLint *)>(resolveEglFunc("eglQueryContext"));
+ EGL_WaitGL = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(void)>(resolveEglFunc("eglWaitGL"));
+ EGL_WaitNative = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLint )>(resolveEglFunc("eglWaitNative"));
+ EGL_SwapBuffers = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)>(resolveEglFunc("eglSwapBuffers"));
+ EGL_CopyBuffers = reinterpret_cast<EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLNativePixmapType )>(resolveEglFunc("eglCopyBuffers"));
+ EGL_GetProcAddress = reinterpret_cast<__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)>(resolveEglFunc("eglGetProcAddress"));
+}
+
+void QWindowsOpenGL::resolveGLCommon()
+{
+ Viewport = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glViewport"));
+ IsEnabled = reinterpret_cast<GLboolean (APIENTRY *)(GLenum )>(resolveFunc("glIsEnabled"));
+ GetTexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexParameteriv"));
+ GetTexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexParameterfv"));
+ GetString = reinterpret_cast<const GLubyte * (APIENTRY *)(GLenum )>(resolveFunc("glGetString"));
+ GetIntegerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint *)>(resolveFunc("glGetIntegerv"));
+ GetFloatv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolveFunc("glGetFloatv"));
+ GetError = reinterpret_cast<GLenum (APIENTRY *)()>(resolveFunc("glGetError"));
+ GetBooleanv = reinterpret_cast<void (APIENTRY *)(GLenum , GLboolean *)>(resolveFunc("glGetBooleanv"));
+ ReadPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , GLvoid *)>(resolveFunc("glReadPixels"));
+ PixelStorei = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glPixelStorei"));
+ DepthFunc = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDepthFunc"));
+ StencilOp = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum )>(resolveFunc("glStencilOp"));
+ StencilFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLuint )>(resolveFunc("glStencilFunc"));
+ BlendFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glBlendFunc"));
+ Flush = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glFlush"));
+ Finish = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glFinish"));
+ Enable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glEnable"));
+ Disable = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDisable"));
+ DepthMask = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolveFunc("glDepthMask"));
+ ColorMask = reinterpret_cast<void (APIENTRY *)(GLboolean , GLboolean , GLboolean , GLboolean )>(resolveFunc("glColorMask"));
+ StencilMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glStencilMask"));
+ ClearStencil = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glClearStencil"));
+ ClearColor = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glClearColor"));
+ Clear = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glClear"));
+ TexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexImage2D"));
+ TexParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexParameteriv"));
+ TexParameteri = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexParameteri"));
+ TexParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexParameterfv"));
+ TexParameterf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexParameterf"));
+ Scissor = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glScissor"));
+ LineWidth = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glLineWidth"));
+ Hint = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glHint"));
+ FrontFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glFrontFace"));
+ CullFace = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glCullFace"));
+
+ IsTexture = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsTexture"));
+ GenTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolveFunc("glGenTextures"));
+ DeleteTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *)>(resolveFunc("glDeleteTextures"));
+ BindTexture = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindTexture"));
+ TexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexSubImage2D"));
+ CopyTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei )>(resolveFunc("glCopyTexSubImage2D"));
+ CopyTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLsizei , GLint )>(resolveFunc("glCopyTexImage2D"));
+ PolygonOffset = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glPolygonOffset"));
+ DrawElements = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , GLenum , const GLvoid *)>(resolveFunc("glDrawElements"));
+ DrawArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLsizei )>(resolveFunc("glDrawArrays"));
+}
+
+void QWindowsOpenGL::resolveGL11()
+{
+ DepthRange = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glDepthRange"));
+ GetTexImage = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLenum , GLvoid *)>(resolveFunc("glGetTexImage"));
+ LogicOp = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glLogicOp"));
+ ClearDepth = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glClearDepth"));
+ PolygonMode = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glPolygonMode"));
+ PointSize = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glPointSize"));
+ GetTexLevelParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint *)>(resolveFunc("glGetTexLevelParameteriv"));
+ GetTexLevelParameterfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLfloat *)>(resolveFunc("glGetTexLevelParameterfv"));
+ GetDoublev = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble *)>(resolveFunc("glGetDoublev"));
+ PixelStoref = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glPixelStoref"));
+ ReadBuffer = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glReadBuffer"));
+ DrawBuffer = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDrawBuffer"));
+ TexImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexImage1D"));
+
+ Translatef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glTranslatef"));
+ Translated = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glTranslated"));
+ Scalef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glScalef"));
+ Scaled = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glScaled"));
+ Rotatef = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRotatef"));
+ Rotated = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRotated"));
+ PushMatrix = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPushMatrix"));
+ PopMatrix = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopMatrix"));
+ Ortho = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glOrtho"));
+ MultMatrixd = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glMultMatrixd"));
+ MultMatrixf = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glMultMatrixf"));
+ MatrixMode = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glMatrixMode"));
+ LoadMatrixd = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glLoadMatrixd"));
+ LoadMatrixf = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glLoadMatrixf"));
+ LoadIdentity = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glLoadIdentity"));
+ Frustum = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glFrustum"));
+ IsList = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsList"));
+ GetTexGeniv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexGeniv"));
+ GetTexGenfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexGenfv"));
+ GetTexGendv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble *)>(resolveFunc("glGetTexGendv"));
+ GetTexEnviv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetTexEnviv"));
+ GetTexEnvfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetTexEnvfv"));
+ GetPolygonStipple = reinterpret_cast<void (APIENTRY *)(GLubyte *)>(resolveFunc("glGetPolygonStipple"));
+ GetPixelMapusv = reinterpret_cast<void (APIENTRY *)(GLenum , GLushort *)>(resolveFunc("glGetPixelMapusv"));
+ GetPixelMapuiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint *)>(resolveFunc("glGetPixelMapuiv"));
+ GetPixelMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat *)>(resolveFunc("glGetPixelMapfv"));
+ GetMaterialiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetMaterialiv"));
+ GetMaterialfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetMaterialfv"));
+ GetMapiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetMapiv"));
+ GetMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetMapfv"));
+ GetMapdv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble *)>(resolveFunc("glGetMapdv"));
+ GetLightiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint *)>(resolveFunc("glGetLightiv"));
+ GetLightfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat *)>(resolveFunc("glGetLightfv"));
+ GetClipPlane = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble *)>(resolveFunc("glGetClipPlane"));
+ DrawPixels = reinterpret_cast<void (APIENTRY *)(GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glDrawPixels"));
+ CopyPixels = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLsizei , GLsizei , GLenum )>(resolveFunc("glCopyPixels"));
+ PixelMapusv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLushort *)>(resolveFunc("glPixelMapusv"));
+ PixelMapuiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLuint *)>(resolveFunc("glPixelMapuiv"));
+ PixelMapfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , const GLfloat *)>(resolveFunc("glPixelMapfv"));
+ PixelTransferi = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glPixelTransferi"));
+ PixelTransferf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glPixelTransferf"));
+ PixelZoom = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glPixelZoom"));
+ AlphaFunc = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glAlphaFunc"));
+ EvalPoint2 = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glEvalPoint2"));
+ EvalMesh2 = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint )>(resolveFunc("glEvalMesh2"));
+ EvalPoint1 = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glEvalPoint1"));
+ EvalMesh1 = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint )>(resolveFunc("glEvalMesh1"));
+ EvalCoord2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glEvalCoord2fv"));
+ EvalCoord2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glEvalCoord2f"));
+ EvalCoord2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glEvalCoord2dv"));
+ EvalCoord2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glEvalCoord2d"));
+ EvalCoord1fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glEvalCoord1fv"));
+ EvalCoord1f = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glEvalCoord1f"));
+ EvalCoord1dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glEvalCoord1dv"));
+ EvalCoord1d = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glEvalCoord1d"));
+ MapGrid2f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLint , GLfloat , GLfloat )>(resolveFunc("glMapGrid2f"));
+ MapGrid2d = reinterpret_cast<void (APIENTRY *)(GLint , GLdouble , GLdouble , GLint , GLdouble , GLdouble )>(resolveFunc("glMapGrid2d"));
+ MapGrid1f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat )>(resolveFunc("glMapGrid1f"));
+ MapGrid1d = reinterpret_cast<void (APIENTRY *)(GLint , GLdouble , GLdouble )>(resolveFunc("glMapGrid1d"));
+ Map2f = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat , GLfloat , GLint , GLint , GLfloat , GLfloat , GLint , GLint , const GLfloat *)>(resolveFunc("glMap2f"));
+ Map2d = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble , GLdouble , GLint , GLint , GLdouble , GLdouble , GLint , GLint , const GLdouble *)>(resolveFunc("glMap2d"));
+ Map1f = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat , GLfloat , GLint , GLint , const GLfloat *)>(resolveFunc("glMap1f"));
+ Map1d = reinterpret_cast<void (APIENTRY *)(GLenum , GLdouble , GLdouble , GLint , GLint , const GLdouble *)>(resolveFunc("glMap1d"));
+ PushAttrib = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glPushAttrib"));
+ PopAttrib = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopAttrib"));
+ Accum = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glAccum"));
+ IndexMask = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glIndexMask"));
+ ClearIndex = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glClearIndex"));
+ ClearAccum = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glClearAccum"));
+ PushName = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glPushName"));
+ PopName = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopName"));
+ PassThrough = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glPassThrough"));
+ LoadName = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glLoadName"));
+ InitNames = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glInitNames"));
+ RenderMode = reinterpret_cast<GLint (APIENTRY *)(GLenum )>(resolveFunc("glRenderMode"));
+ SelectBuffer = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint *)>(resolveFunc("glSelectBuffer"));
+ FeedbackBuffer = reinterpret_cast<void (APIENTRY *)(GLsizei , GLenum , GLfloat *)>(resolveFunc("glFeedbackBuffer"));
+ TexGeniv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexGeniv"));
+ TexGeni = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexGeni"));
+ TexGenfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexGenfv"));
+ TexGenf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexGenf"));
+ TexGendv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLdouble *)>(resolveFunc("glTexGendv"));
+ TexGend = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLdouble )>(resolveFunc("glTexGend"));
+ TexEnviv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glTexEnviv"));
+ TexEnvi = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glTexEnvi"));
+ TexEnvfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glTexEnvfv"));
+ TexEnvf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glTexEnvf"));
+ ShadeModel = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glShadeModel"));
+ PolygonStipple = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glPolygonStipple"));
+ Materialiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glMaterialiv"));
+ Materiali = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glMateriali"));
+ Materialfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glMaterialfv"));
+ Materialf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glMaterialf"));
+ LineStipple = reinterpret_cast<void (APIENTRY *)(GLint , GLushort )>(resolveFunc("glLineStipple"));
+ LightModeliv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLint *)>(resolveFunc("glLightModeliv"));
+ LightModeli = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glLightModeli"));
+ LightModelfv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLfloat *)>(resolveFunc("glLightModelfv"));
+ LightModelf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glLightModelf"));
+ Lightiv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLint *)>(resolveFunc("glLightiv"));
+ Lighti = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint )>(resolveFunc("glLighti"));
+ Lightfv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , const GLfloat *)>(resolveFunc("glLightfv"));
+ Lightf = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLfloat )>(resolveFunc("glLightf"));
+ Fogiv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLint *)>(resolveFunc("glFogiv"));
+ Fogi = reinterpret_cast<void (APIENTRY *)(GLenum , GLint )>(resolveFunc("glFogi"));
+ Fogfv = reinterpret_cast<void (APIENTRY *)(GLenum , const GLfloat *)>(resolveFunc("glFogfv"));
+ Fogf = reinterpret_cast<void (APIENTRY *)(GLenum , GLfloat )>(resolveFunc("glFogf"));
+ ColorMaterial = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glColorMaterial"));
+ ClipPlane = reinterpret_cast<void (APIENTRY *)(GLenum , const GLdouble *)>(resolveFunc("glClipPlane"));
+ Vertex4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex4sv"));
+ Vertex4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glVertex4s"));
+ Vertex4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex4iv"));
+ Vertex4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glVertex4i"));
+ Vertex4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex4fv"));
+ Vertex4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertex4f"));
+ Vertex4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex4dv"));
+ Vertex4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glVertex4d"));
+ Vertex3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex3sv"));
+ Vertex3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glVertex3s"));
+ Vertex3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex3iv"));
+ Vertex3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glVertex3i"));
+ Vertex3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex3fv"));
+ Vertex3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertex3f"));
+ Vertex3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex3dv"));
+ Vertex3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glVertex3d"));
+ Vertex2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glVertex2sv"));
+ Vertex2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glVertex2s"));
+ Vertex2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glVertex2iv"));
+ Vertex2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glVertex2i"));
+ Vertex2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glVertex2fv"));
+ Vertex2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glVertex2f"));
+ Vertex2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glVertex2dv"));
+ Vertex2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glVertex2d"));
+ TexCoord4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord4sv"));
+ TexCoord4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glTexCoord4s"));
+ TexCoord4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord4iv"));
+ TexCoord4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glTexCoord4i"));
+ TexCoord4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord4fv"));
+ TexCoord4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glTexCoord4f"));
+ TexCoord4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord4dv"));
+ TexCoord4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glTexCoord4d"));
+ TexCoord3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord3sv"));
+ TexCoord3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glTexCoord3s"));
+ TexCoord3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord3iv"));
+ TexCoord3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glTexCoord3i"));
+ TexCoord3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord3fv"));
+ TexCoord3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glTexCoord3f"));
+ TexCoord3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord3dv"));
+ TexCoord3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glTexCoord3d"));
+ TexCoord2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord2sv"));
+ TexCoord2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glTexCoord2s"));
+ TexCoord2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord2iv"));
+ TexCoord2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glTexCoord2i"));
+ TexCoord2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord2fv"));
+ TexCoord2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glTexCoord2f"));
+ TexCoord2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord2dv"));
+ TexCoord2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glTexCoord2d"));
+ TexCoord1sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glTexCoord1sv"));
+ TexCoord1s = reinterpret_cast<void (APIENTRY *)(GLshort )>(resolveFunc("glTexCoord1s"));
+ TexCoord1iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glTexCoord1iv"));
+ TexCoord1i = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glTexCoord1i"));
+ TexCoord1fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glTexCoord1fv"));
+ TexCoord1f = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glTexCoord1f"));
+ TexCoord1dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glTexCoord1dv"));
+ TexCoord1d = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glTexCoord1d"));
+ Rectsv = reinterpret_cast<void (APIENTRY *)(const GLshort *, const GLshort *)>(resolveFunc("glRectsv"));
+ Rects = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glRects"));
+ Rectiv = reinterpret_cast<void (APIENTRY *)(const GLint *, const GLint *)>(resolveFunc("glRectiv"));
+ Recti = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glRecti"));
+ Rectfv = reinterpret_cast<void (APIENTRY *)(const GLfloat *, const GLfloat *)>(resolveFunc("glRectfv"));
+ Rectf = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRectf"));
+ Rectdv = reinterpret_cast<void (APIENTRY *)(const GLdouble *, const GLdouble *)>(resolveFunc("glRectdv"));
+ Rectd = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRectd"));
+ RasterPos4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos4sv"));
+ RasterPos4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glRasterPos4s"));
+ RasterPos4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos4iv"));
+ RasterPos4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glRasterPos4i"));
+ RasterPos4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos4fv"));
+ RasterPos4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glRasterPos4f"));
+ RasterPos4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos4dv"));
+ RasterPos4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glRasterPos4d"));
+ RasterPos3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos3sv"));
+ RasterPos3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glRasterPos3s"));
+ RasterPos3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos3iv"));
+ RasterPos3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glRasterPos3i"));
+ RasterPos3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos3fv"));
+ RasterPos3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glRasterPos3f"));
+ RasterPos3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos3dv"));
+ RasterPos3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glRasterPos3d"));
+ RasterPos2sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glRasterPos2sv"));
+ RasterPos2s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort )>(resolveFunc("glRasterPos2s"));
+ RasterPos2iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glRasterPos2iv"));
+ RasterPos2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glRasterPos2i"));
+ RasterPos2fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glRasterPos2fv"));
+ RasterPos2f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat )>(resolveFunc("glRasterPos2f"));
+ RasterPos2dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glRasterPos2dv"));
+ RasterPos2d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble )>(resolveFunc("glRasterPos2d"));
+ Normal3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glNormal3sv"));
+ Normal3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glNormal3s"));
+ Normal3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glNormal3iv"));
+ Normal3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glNormal3i"));
+ Normal3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glNormal3fv"));
+ Normal3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glNormal3f"));
+ Normal3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glNormal3dv"));
+ Normal3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glNormal3d"));
+ Normal3bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glNormal3bv"));
+ Normal3b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte )>(resolveFunc("glNormal3b"));
+ Indexsv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glIndexsv"));
+ Indexs = reinterpret_cast<void (APIENTRY *)(GLshort )>(resolveFunc("glIndexs"));
+ Indexiv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glIndexiv"));
+ Indexi = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glIndexi"));
+ Indexfv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glIndexfv"));
+ Indexf = reinterpret_cast<void (APIENTRY *)(GLfloat )>(resolveFunc("glIndexf"));
+ Indexdv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glIndexdv"));
+ Indexd = reinterpret_cast<void (APIENTRY *)(GLdouble )>(resolveFunc("glIndexd"));
+ End = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glEnd"));
+ EdgeFlagv = reinterpret_cast<void (APIENTRY *)(const GLboolean *)>(resolveFunc("glEdgeFlagv"));
+ EdgeFlag = reinterpret_cast<void (APIENTRY *)(GLboolean )>(resolveFunc("glEdgeFlag"));
+ Color4usv = reinterpret_cast<void (APIENTRY *)(const GLushort *)>(resolveFunc("glColor4usv"));
+ Color4us = reinterpret_cast<void (APIENTRY *)(GLushort , GLushort , GLushort , GLushort )>(resolveFunc("glColor4us"));
+ Color4uiv = reinterpret_cast<void (APIENTRY *)(const GLuint *)>(resolveFunc("glColor4uiv"));
+ Color4ui = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLuint , GLuint )>(resolveFunc("glColor4ui"));
+ Color4ubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glColor4ubv"));
+ Color4ub = reinterpret_cast<void (APIENTRY *)(GLubyte , GLubyte , GLubyte , GLubyte )>(resolveFunc("glColor4ub"));
+ Color4sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glColor4sv"));
+ Color4s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort , GLshort )>(resolveFunc("glColor4s"));
+ Color4iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glColor4iv"));
+ Color4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glColor4i"));
+ Color4fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glColor4fv"));
+ Color4f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glColor4f"));
+ Color4dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glColor4dv"));
+ Color4d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble , GLdouble )>(resolveFunc("glColor4d"));
+ Color4bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glColor4bv"));
+ Color4b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte , GLbyte )>(resolveFunc("glColor4b"));
+ Color3usv = reinterpret_cast<void (APIENTRY *)(const GLushort *)>(resolveFunc("glColor3usv"));
+ Color3us = reinterpret_cast<void (APIENTRY *)(GLushort , GLushort , GLushort )>(resolveFunc("glColor3us"));
+ Color3uiv = reinterpret_cast<void (APIENTRY *)(const GLuint *)>(resolveFunc("glColor3uiv"));
+ Color3ui = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLuint )>(resolveFunc("glColor3ui"));
+ Color3ubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glColor3ubv"));
+ Color3ub = reinterpret_cast<void (APIENTRY *)(GLubyte , GLubyte , GLubyte )>(resolveFunc("glColor3ub"));
+ Color3sv = reinterpret_cast<void (APIENTRY *)(const GLshort *)>(resolveFunc("glColor3sv"));
+ Color3s = reinterpret_cast<void (APIENTRY *)(GLshort , GLshort , GLshort )>(resolveFunc("glColor3s"));
+ Color3iv = reinterpret_cast<void (APIENTRY *)(const GLint *)>(resolveFunc("glColor3iv"));
+ Color3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glColor3i"));
+ Color3fv = reinterpret_cast<void (APIENTRY *)(const GLfloat *)>(resolveFunc("glColor3fv"));
+ Color3f = reinterpret_cast<void (APIENTRY *)(GLfloat , GLfloat , GLfloat )>(resolveFunc("glColor3f"));
+ Color3dv = reinterpret_cast<void (APIENTRY *)(const GLdouble *)>(resolveFunc("glColor3dv"));
+ Color3d = reinterpret_cast<void (APIENTRY *)(GLdouble , GLdouble , GLdouble )>(resolveFunc("glColor3d"));
+ Color3bv = reinterpret_cast<void (APIENTRY *)(const GLbyte *)>(resolveFunc("glColor3bv"));
+ Color3b = reinterpret_cast<void (APIENTRY *)(GLbyte , GLbyte , GLbyte )>(resolveFunc("glColor3b"));
+ Bitmap = reinterpret_cast<void (APIENTRY *)(GLsizei , GLsizei , GLfloat , GLfloat , GLfloat , GLfloat , const GLubyte *)>(resolveFunc("glBitmap"));
+ Begin = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glBegin"));
+ ListBase = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glListBase"));
+ GenLists = reinterpret_cast<GLuint (APIENTRY *)(GLsizei )>(resolveFunc("glGenLists"));
+ DeleteLists = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei )>(resolveFunc("glDeleteLists"));
+ CallLists = reinterpret_cast<void (APIENTRY *)(GLsizei , GLenum , const GLvoid *)>(resolveFunc("glCallLists"));
+ CallList = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glCallList"));
+ EndList = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glEndList"));
+ NewList = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum )>(resolveFunc("glNewList"));
+
+ Indexubv = reinterpret_cast<void (APIENTRY *)(const GLubyte *)>(resolveFunc("glIndexubv"));
+ Indexub = reinterpret_cast<void (APIENTRY *)(GLubyte )>(resolveFunc("glIndexub"));
+ TexSubImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(resolveFunc("glTexSubImage1D"));
+ CopyTexSubImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint , GLint , GLsizei )>(resolveFunc("glCopyTexSubImage1D"));
+ CopyTexImage1D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLint , GLint , GLsizei , GLint )>(resolveFunc("glCopyTexImage1D"));
+ GetPointerv = reinterpret_cast<void (APIENTRY *)(GLenum , GLvoid* *)>(resolveFunc("glGetPointerv"));
+
+ PushClientAttrib = reinterpret_cast<void (APIENTRY *)(GLbitfield )>(resolveFunc("glPushClientAttrib"));
+ PopClientAttrib = reinterpret_cast<void (APIENTRY *)()>(resolveFunc("glPopClientAttrib"));
+ PrioritizeTextures = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint *, const GLfloat *)>(resolveFunc("glPrioritizeTextures"));
+ AreTexturesResident = reinterpret_cast<GLboolean (APIENTRY *)(GLsizei , const GLuint *, GLboolean *)>(resolveFunc("glAreTexturesResident"));
+ VertexPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glVertexPointer"));
+ TexCoordPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glTexCoordPointer"));
+ NormalPointer = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glNormalPointer"));
+ InterleavedArrays = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glInterleavedArrays"));
+ IndexPointer = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizei , const GLvoid *)>(resolveFunc("glIndexPointer"));
+ EnableClientState = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glEnableClientState"));
+ EdgeFlagPointer = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLvoid *)>(resolveFunc("glEdgeFlagPointer"));
+ DisableClientState = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glDisableClientState"));
+ ColorPointer = reinterpret_cast<void (APIENTRY *)(GLint , GLenum , GLsizei , const GLvoid *)>(resolveFunc("glColorPointer"));
+ ArrayElement = reinterpret_cast<void (APIENTRY *)(GLint )>(resolveFunc("glArrayElement"));
+}
+
+void QWindowsOpenGL::resolveGLES2()
+{
+ ActiveTexture = reinterpret_cast<void (APIENTRY *)(GLenum)>(resolveFunc("glActiveTexture"));
+ AttachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolveFunc("glAttachShader"));
+ BindAttribLocation = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , const GLchar* )>(resolveFunc("glBindAttribLocation"));
+ BindBuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindBuffer"));
+ BindFramebuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindFramebuffer"));
+ BindRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glBindRenderbuffer"));
+ BlendColor = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf , GLclampf , GLclampf )>(resolveFunc("glBlendColor"));
+ BlendEquation = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glBlendEquation"));
+ BlendEquationSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum )>(resolveFunc("glBlendEquationSeparate"));
+ BlendFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolveFunc("glBlendFuncSeparate"));
+ BufferData = reinterpret_cast<void (APIENTRY *)(GLenum , GLsizeiptr , const GLvoid* , GLenum )>(resolveFunc("glBufferData"));
+ BufferSubData = reinterpret_cast<void (APIENTRY *)(GLenum , GLintptr , GLsizeiptr , const GLvoid* )>(resolveFunc("glBufferSubData"));
+ CheckFramebufferStatus = reinterpret_cast<GLenum (APIENTRY *)(GLenum )>(resolveFunc("glCheckFramebufferStatus"));
+ ClearDepthf = reinterpret_cast<void (APIENTRY *)(GLclampf )>(resolveFunc("glClearDepthf"));
+ CompileShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glCompileShader"));
+ CompressedTexImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLenum , GLsizei , GLsizei, GLint, GLsizei, const GLvoid* )>(resolveFunc("glCompressedTexImage2D"));
+ CompressedTexSubImage2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLint , GLint , GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid* )>(resolveFunc("glCompressedTexSubImage2D"));
+ CreateProgram = reinterpret_cast<GLuint (APIENTRY *)(void)>(resolveFunc("glCreateProgram"));
+ CreateShader = reinterpret_cast<GLuint (APIENTRY *)(GLenum )>(resolveFunc("glCreateShader"));
+ DeleteBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*)>(resolveFunc("glDeleteBuffers"));
+ DeleteFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolveFunc("glDeleteFramebuffers"));
+ DeleteProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDeleteProgram"));
+ DeleteRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint* )>(resolveFunc("glDeleteRenderbuffers"));
+ DeleteShader = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDeleteShader"));
+ DepthRangef = reinterpret_cast<void (APIENTRY *)(GLclampf , GLclampf )>(resolveFunc("glDepthRangef"));
+ DetachShader = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint )>(resolveFunc("glDetachShader"));
+ DisableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glDisableVertexAttribArray"));
+ EnableVertexAttribArray = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glEnableVertexAttribArray"));
+ FramebufferRenderbuffer = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint )>(resolveFunc("glFramebufferRenderbuffer"));
+ FramebufferTexture2D = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLuint , GLint )>(resolveFunc("glFramebufferTexture2D"));
+ GenBuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenBuffers"));
+ GenerateMipmap = reinterpret_cast<void (APIENTRY *)(GLenum )>(resolveFunc("glGenerateMipmap"));
+ GenFramebuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenFramebuffers"));
+ GenRenderbuffers = reinterpret_cast<void (APIENTRY *)(GLsizei , GLuint* )>(resolveFunc("glGenRenderbuffers"));
+ GetActiveAttrib = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolveFunc("glGetActiveAttrib"));
+ GetActiveUniform = reinterpret_cast<void (APIENTRY *)(GLuint , GLuint , GLsizei , GLsizei* , GLint* , GLenum* , GLchar* )>(resolveFunc("glGetActiveUniform"));
+ GetAttachedShaders = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLuint* )>(resolveFunc("glGetAttachedShaders"));
+ GetAttribLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolveFunc("glGetAttribLocation"));
+ GetBufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolveFunc("glGetBufferParameteriv"));
+ GetFramebufferAttachmentParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum, GLenum , GLint* )>(resolveFunc("glGetFramebufferAttachmentParameteriv"));
+ GetProgramiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetProgramiv"));
+ GetProgramInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolveFunc("glGetProgramInfoLog"));
+ GetRenderbufferParameteriv = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* )>(resolveFunc("glGetRenderbufferParameteriv"));
+ GetShaderiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetShaderiv"));
+ GetShaderInfoLog = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei*, GLchar*)>(resolveFunc("glGetShaderInfoLog"));
+ GetShaderPrecisionFormat = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint* , GLint* )>(resolveFunc("glGetShaderPrecisionFormat"));
+ GetShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , GLsizei* , GLchar* )>(resolveFunc("glGetShaderSource"));
+ GetUniformfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLfloat*)>(resolveFunc("glGetUniformfv"));
+ GetUniformiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLint , GLint*)>(resolveFunc("glGetUniformiv"));
+ GetUniformLocation = reinterpret_cast<int (APIENTRY *)(GLuint , const GLchar* )>(resolveFunc("glGetUniformLocation"));
+ GetVertexAttribfv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLfloat* )>(resolveFunc("glGetVertexAttribfv"));
+ GetVertexAttribiv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLint* )>(resolveFunc("glGetVertexAttribiv"));
+ GetVertexAttribPointerv = reinterpret_cast<void (APIENTRY *)(GLuint , GLenum , GLvoid** pointer)>(resolveFunc("glGetVertexAttribPointerv"));
+ IsBuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsBuffer"));
+ IsFramebuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsFramebuffer"));
+ IsProgram = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsProgram"));
+ IsRenderbuffer = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsRenderbuffer"));
+ IsShader = reinterpret_cast<GLboolean (APIENTRY *)(GLuint )>(resolveFunc("glIsShader"));
+ LinkProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glLinkProgram"));
+ ReleaseShaderCompiler = reinterpret_cast<void (APIENTRY *)(void)>(resolveFunc("glReleaseShaderCompiler"));
+ RenderbufferStorage = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLsizei , GLsizei )>(resolveFunc("glRenderbufferStorage"));
+ SampleCoverage = reinterpret_cast<void (APIENTRY *)(GLclampf , GLboolean )>(resolveFunc("glSampleCoverage"));
+ ShaderBinary = reinterpret_cast<void (APIENTRY *)(GLsizei , const GLuint*, GLenum , const GLvoid* , GLsizei )>(resolveFunc("glShaderBinary"));
+ ShaderSource = reinterpret_cast<void (APIENTRY *)(GLuint , GLsizei , const GLchar* *, const GLint* )>(resolveFunc("glShaderSource"));
+ StencilFuncSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLint , GLuint )>(resolveFunc("glStencilFuncSeparate"));
+ StencilMaskSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLuint )>(resolveFunc("glStencilMaskSeparate"));
+ StencilOpSeparate = reinterpret_cast<void (APIENTRY *)(GLenum , GLenum , GLenum , GLenum )>(resolveFunc("glStencilOpSeparate"));
+ Uniform1f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat )>(resolveFunc("glUniform1f"));
+ Uniform1fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform1fv"));
+ Uniform1i = reinterpret_cast<void (APIENTRY *)(GLint , GLint )>(resolveFunc("glUniform1i"));
+ Uniform1iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform1iv"));
+ Uniform2f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat )>(resolveFunc("glUniform2f"));
+ Uniform2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform2fv"));
+ Uniform2i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint )>(resolveFunc("glUniform2i"));
+ Uniform2iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform2iv"));
+ Uniform3f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat )>(resolveFunc("glUniform3f"));
+ Uniform3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform3fv"));
+ Uniform3i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint )>(resolveFunc("glUniform3i"));
+ Uniform3iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform3iv"));
+ Uniform4f = reinterpret_cast<void (APIENTRY *)(GLint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glUniform4f"));
+ Uniform4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLfloat* )>(resolveFunc("glUniform4fv"));
+ Uniform4i = reinterpret_cast<void (APIENTRY *)(GLint , GLint , GLint , GLint , GLint )>(resolveFunc("glUniform4i"));
+ Uniform4iv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , const GLint* )>(resolveFunc("glUniform4iv"));
+ UniformMatrix2fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix2fv"));
+ UniformMatrix3fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix3fv"));
+ UniformMatrix4fv = reinterpret_cast<void (APIENTRY *)(GLint , GLsizei , GLboolean , const GLfloat* )>(resolveFunc("glUniformMatrix4fv"));
+ UseProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glUseProgram"));
+ ValidateProgram = reinterpret_cast<void (APIENTRY *)(GLuint )>(resolveFunc("glValidateProgram"));
+ VertexAttrib1f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat )>(resolveFunc("glVertexAttrib1f"));
+ VertexAttrib1fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib1fv"));
+ VertexAttrib2f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib2f"));
+ VertexAttrib2fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib2fv"));
+ VertexAttrib3f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib3f"));
+ VertexAttrib3fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib3fv"));
+ VertexAttrib4f = reinterpret_cast<void (APIENTRY *)(GLuint , GLfloat , GLfloat , GLfloat , GLfloat )>(resolveFunc("glVertexAttrib4f"));
+ VertexAttrib4fv = reinterpret_cast<void (APIENTRY *)(GLuint , const GLfloat* )>(resolveFunc("glVertexAttrib4fv"));
+ VertexAttribPointer = reinterpret_cast<void (APIENTRY *)(GLuint , GLint, GLenum, GLboolean, GLsizei, const GLvoid* )>(resolveFunc("glVertexAttribPointer"));
+}
+
+void QWindowsOpenGL::resolve()
+{
+ switch (libraryType()) {
+ case DesktopGL:
+ resolveWGL();
+ resolveGLCommon();
+ resolveGL11();
+ break;
+
+ case GLES2:
+ resolveEGL();
+ resolveGLCommon();
+ resolveGLES2();
+ break;
+
+ default:
+ Q_ASSERT_X(0, "QWindowsOpenGL", "Nothing to resolve");
+ break;
+ }
+}
+
+bool QWindowsOpenGL::testDesktopGL()
+{
+ HMODULE lib = 0;
+ HWND wnd = 0;
+ HDC dc = 0;
+ HGLRC context = 0;
+ LPCTSTR className = L"qtopenglproxytest";
+
+ HGLRC (WINAPI * CreateContext)(HDC dc) = 0;
+ BOOL (WINAPI * DeleteContext)(HGLRC context) = 0;
+ BOOL (WINAPI * MakeCurrent)(HDC dc, HGLRC context) = 0;
+ PROC (WINAPI * WGL_GetProcAddress)(LPCSTR name) = 0;
+
+ bool result = false;
+
+ // Test #1: Load opengl32.dll and try to resolve an OpenGL 2 function.
+ // This will typically fail on systems that do not have a real OpenGL driver.
+ lib = qgl_loadLib("opengl32.dll", false);
+ if (lib) {
+ CreateContext = reinterpret_cast<HGLRC (WINAPI *)(HDC)>(::GetProcAddress(lib, "wglCreateContext"));
+ if (!CreateContext)
+ goto cleanup;
+ DeleteContext = reinterpret_cast<BOOL (WINAPI *)(HGLRC)>(::GetProcAddress(lib, "wglDeleteContext"));
+ if (!DeleteContext)
+ goto cleanup;
+ MakeCurrent = reinterpret_cast<BOOL (WINAPI *)(HDC, HGLRC)>(::GetProcAddress(lib, "wglMakeCurrent"));
+ if (!MakeCurrent)
+ goto cleanup;
+ WGL_GetProcAddress = reinterpret_cast<PROC (WINAPI *)(LPCSTR)>(::GetProcAddress(lib, "wglGetProcAddress"));
+ if (!WGL_GetProcAddress)
+ goto cleanup;
+
+ WNDCLASS wclass;
+ wclass.cbClsExtra = 0;
+ wclass.cbWndExtra = 0;
+ wclass.hInstance = (HINSTANCE) GetModuleHandle(0);
+ wclass.hIcon = 0;
+ wclass.hCursor = 0;
+ wclass.hbrBackground = (HBRUSH) (COLOR_BACKGROUND);
+ wclass.lpszMenuName = 0;
+ wclass.lpfnWndProc = DefWindowProc;
+ wclass.lpszClassName = className;
+ wclass.style = CS_OWNDC;
+ if (!RegisterClass(&wclass))
+ goto cleanup;
+ wnd = CreateWindow(className, L"qtopenglproxytest", WS_OVERLAPPED,
+ 0, 0, 640, 480, 0, 0, wclass.hInstance, 0);
+ if (!wnd)
+ goto cleanup;
+ dc = GetDC(wnd);
+ if (!dc)
+ goto cleanup;
+
+ PIXELFORMATDESCRIPTOR pfd;
+ memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ // Use the GDI functions. Under the hood this will call the wgl variants in opengl32.dll.
+ int pixelFormat = ChoosePixelFormat(dc, &pfd);
+ if (!pixelFormat)
+ goto cleanup;
+ if (!SetPixelFormat(dc, pixelFormat, &pfd))
+ goto cleanup;
+ context = CreateContext(dc);
+ if (!context)
+ goto cleanup;
+ if (!MakeCurrent(dc, context))
+ goto cleanup;
+
+ // Now that there is finally a context current, try doing something useful.
+ if (WGL_GetProcAddress("glCreateShader")) {
+ result = true;
+ qCDebug(qglLc, "OpenGL 2 entry points available");
+ } else {
+ qCDebug(qglLc, "OpenGL 2 entry points not found");
+ }
+ } else {
+ qCDebug(qglLc, "Failed to load opengl32.dll");
+ }
+
+cleanup:
+ if (MakeCurrent)
+ MakeCurrent(0, 0);
+ if (context)
+ DeleteContext(context);
+ if (dc && wnd)
+ ReleaseDC(wnd, dc);
+ if (wnd)
+ DestroyWindow(wnd);
+ UnregisterClass(className, GetModuleHandle(0));
+ if (lib)
+ FreeLibrary(lib);
+
+ return result;
+}
+
+class QWindowsOpenGLList
+{
+public:
+ QWindowsOpenGLList();
+ ~QWindowsOpenGLList();
+ QVector<QAbstractWindowsOpenGL *> list;
+};
+
+QWindowsOpenGLList::QWindowsOpenGLList()
+{
+ // For now there is always one OpenGL ( + winsys interface) loaded.
+ // This may change in the future.
+ list.append(new QWindowsOpenGL);
+}
+
+QWindowsOpenGLList::~QWindowsOpenGLList()
+{
+ qDeleteAll(list);
+}
+
+// Use Q_GLOBAL_STATIC and perform initialization in the constructor to be
+// thread safe.
+Q_GLOBAL_STATIC(QWindowsOpenGLList, gl)
+
+static inline QAbstractWindowsOpenGL *qgl_choose()
+{
+ return gl()->list[0];
+}
+
+// functionsReady() -> the DLL is there but some functions were not resolved. This is fatal.
+// !functionsReady() -> could not load a GL implementation. No error message in this case.
+#define GLWARN(g, func, prefix) \
+ { \
+ if (g->functionsReady()) \
+ qFatal("Qt OpenGL: Attempted to call unresolved function %s%s. " \
+ "This is likely caused by making OpenGL-only calls with an OpenGL ES implementation (Angle).", \
+ prefix, #func); \
+ }
+
+#define GLCALLV(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ g->func(__VA_ARGS__); \
+ else \
+ GLWARN(g, func, "gl") \
+ }
+
+#define GLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ return g->func(__VA_ARGS__); \
+ GLWARN(g, func, "gl") \
+ return 0; \
+ }
+
+#define WGLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->func) \
+ return g->func(__VA_ARGS__); \
+ GLWARN(g, func, "wgl") \
+ return 0; \
+ }
+
+#define EGLCALL(func, ...) \
+ { \
+ QAbstractWindowsOpenGL *g = qgl_choose(); \
+ if (g->EGL_##func) \
+ return g->EGL_##func(__VA_ARGS__); \
+ GLWARN(g, func, "egl") \
+ return 0; \
+ }
+
+
+extern "C" {
+
+// WGL
+
+Q_DECL_EXPORT BOOL WINAPI wglCopyContext(HGLRC src, HGLRC dst, UINT mask)
+{
+ WGLCALL(CopyContext, src, dst, mask);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglCreateContext(HDC dc)
+{
+ WGLCALL(CreateContext, dc);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglCreateLayerContext(HDC dc, int plane)
+{
+ WGLCALL(CreateLayerContext, dc, plane);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglDeleteContext(HGLRC context)
+{
+ WGLCALL(DeleteContext, context);
+}
+
+Q_DECL_EXPORT HGLRC WINAPI wglGetCurrentContext(VOID)
+{
+ WGLCALL(GetCurrentContext);
+}
+
+Q_DECL_EXPORT HDC WINAPI wglGetCurrentDC(VOID)
+{
+ WGLCALL(GetCurrentDC);
+}
+
+Q_DECL_EXPORT PROC WINAPI wglGetProcAddress(LPCSTR name)
+{
+ WGLCALL(GetProcAddress, name);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglMakeCurrent(HDC dc, HGLRC context)
+{
+ WGLCALL(MakeCurrent, dc, context);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglShareLists(HGLRC context1, HGLRC context2)
+{
+ WGLCALL(ShareLists, context1, context2);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglUseFontBitmapsW(HDC dc, DWORD first, DWORD count, DWORD base)
+{
+ WGLCALL(UseFontBitmapsW, dc, first, count, base);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglUseFontOutlinesW(HDC dc, DWORD first, DWORD count, DWORD base, FLOAT deviation,
+ FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT gmf)
+{
+ WGLCALL(UseFontOutlinesW, dc, first, count, base, deviation, extrusion, format, gmf);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglDescribeLayerPlane(HDC dc, int pixelFormat, int plane, UINT n,
+ LPLAYERPLANEDESCRIPTOR planeDescriptor)
+{
+ WGLCALL(DescribeLayerPlane, dc, pixelFormat, plane, n, planeDescriptor);
+}
+
+Q_DECL_EXPORT int WINAPI wglSetLayerPaletteEntries(HDC dc, int plane, int start, int entries,
+ CONST COLORREF *colors)
+{
+ WGLCALL(SetLayerPaletteEntries, dc, plane, start, entries, colors);
+}
+
+Q_DECL_EXPORT int WINAPI wglGetLayerPaletteEntries(HDC dc, int plane, int start, int entries,
+ COLORREF *color)
+{
+ WGLCALL(GetLayerPaletteEntries, dc, plane, start, entries, color);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglRealizeLayerPalette(HDC dc, int plane, BOOL realize)
+{
+ WGLCALL(RealizeLayerPalette, dc, plane, realize);
+}
+
+Q_DECL_EXPORT BOOL WINAPI wglSwapLayerBuffers(HDC dc, UINT planes)
+{
+ WGLCALL(SwapLayerBuffers, dc, planes);
+}
+
+Q_DECL_EXPORT DWORD WINAPI wglSwapMultipleBuffers(UINT n, CONST WGLSWAP *buffers)
+{
+ WGLCALL(SwapMultipleBuffers, n, buffers);
+}
+
+// EGL
+
+Q_DECL_EXPORT EGLint EGLAPIENTRY eglGetError(void)
+{
+ EGLCALL(GetError);
+}
+
+Q_DECL_EXPORT EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+ EGLCALL(GetDisplay, display_id);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ EGLCALL(Initialize, dpy, major, minor);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+ EGLCALL(Terminate, dpy);
+}
+
+Q_DECL_EXPORT const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ EGLCALL(QueryString, dpy, name);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
+{
+ EGLCALL(GetConfigs, dpy, configs, config_size, num_config);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+ EGLConfig *configs, EGLint config_size,
+ EGLint *num_config)
+{
+ EGLCALL(ChooseConfig, dpy, attrib_list, configs, config_size, num_config);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(GetConfigAttrib, dpy, config, attribute, value);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreateWindowSurface, dpy, config, win, attrib_list);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreatePbufferSurface, dpy, config, attrib_list);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreatePixmapSurface, dpy, config, pixmap, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLCALL(DestroySurface, dpy, surface);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(QuerySurface, dpy, surface, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+ EGLCALL(BindAPI, api);
+}
+
+Q_DECL_EXPORT EGLenum EGLAPIENTRY eglQueryAPI(void)
+{
+ EGLCALL(QueryAPI);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitClient(void)
+{
+ EGLCALL(WaitClient);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglReleaseThread(void)
+{
+ EGLCALL(ReleaseThread);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
+ EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+ EGLConfig config, const EGLint *attrib_list)
+{
+ EGLCALL(CreatePbufferFromClientBuffer, dpy, buftype, buffer, config, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value)
+{
+ EGLCALL(SurfaceAttrib, dpy, surface, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EGLCALL(BindTexImage, dpy, surface, buffer);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EGLCALL(ReleaseTexImage, dpy, surface, buffer);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ EGLCALL(SwapInterval, dpy, interval);
+}
+
+Q_DECL_EXPORT EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list)
+{
+ EGLCALL(CreateContext, dpy, config, share_context, attrib_list);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EGLCALL(DestroyContext, dpy, ctx);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
+ EGLSurface read, EGLContext ctx)
+{
+ EGLCALL(MakeCurrent, dpy, draw, read, ctx);
+}
+
+Q_DECL_EXPORT EGLContext EGLAPIENTRY eglGetCurrentContext(void)
+{
+ EGLCALL(GetCurrentContext);
+}
+
+Q_DECL_EXPORT EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+ EGLCALL(GetCurrentSurface, readdraw);
+}
+
+Q_DECL_EXPORT EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
+{
+ EGLCALL(GetCurrentDisplay);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value)
+{
+ EGLCALL(QueryContext, dpy, ctx, attribute, value);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitGL(void)
+{
+ EGLCALL(WaitGL);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+ EGLCALL(WaitNative, engine);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ EGLCALL(SwapBuffers, dpy, surface);
+}
+
+Q_DECL_EXPORT EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
+ EGLNativePixmapType target)
+{
+ EGLCALL(CopyBuffers, dpy, surface, target);
+}
+
+// OpenGL
+
+Q_DECL_EXPORT void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(Viewport, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthRange(GLdouble nearVal, GLdouble farVal)
+{
+ if (qgl_choose()->libraryType() == QAbstractWindowsOpenGL::DesktopGL) {
+ GLCALLV(DepthRange, nearVal, farVal);
+ } else {
+ GLCALLV(DepthRangef, nearVal, farVal);
+ }
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsEnabled(GLenum cap)
+{
+ GLCALL(IsEnabled, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexLevelParameteriv, target, level, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexLevelParameterfv, target, level, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexParameteriv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexParameterfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GLCALLV(GetTexImage, target, level, format, type, pixels);
+}
+
+Q_DECL_EXPORT const GLubyte * APIENTRY glGetString(GLenum name)
+{
+ GLCALL(GetString, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetIntegerv(GLenum pname, GLint *params)
+{
+ GLCALLV(GetIntegerv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetFloatv(GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetFloatv, pname, params);
+}
+
+Q_DECL_EXPORT GLenum APIENTRY glGetError()
+{
+ GLCALL(GetError);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetDoublev(GLenum pname, GLdouble *params)
+{
+ GLCALLV(GetDoublev, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetBooleanv(GLenum pname, GLboolean *params)
+{
+ GLCALLV(GetBooleanv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GLCALLV(ReadPixels, x, y, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glReadBuffer(GLenum mode)
+{
+ GLCALLV(ReadBuffer, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+ GLCALLV(PixelStorei, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelStoref(GLenum pname, GLfloat param)
+{
+ GLCALLV(PixelStoref, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthFunc(GLenum func)
+{
+ GLCALLV(DepthFunc, func);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GLCALLV(StencilOp, fail, zfail, zpass);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ GLCALLV(StencilFunc, func, ref, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glLogicOp(GLenum opcode)
+{
+ GLCALLV(LogicOp, opcode);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ GLCALLV(BlendFunc, sfactor, dfactor);
+}
+
+Q_DECL_EXPORT void APIENTRY glFlush()
+{
+ GLCALLV(Flush);
+}
+
+Q_DECL_EXPORT void APIENTRY glFinish()
+{
+ GLCALLV(Finish);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnable(GLenum cap)
+{
+ GLCALLV(Enable, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisable(GLenum cap)
+{
+ GLCALLV(Disable, cap);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthMask(GLboolean flag)
+{
+ GLCALLV(DepthMask, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ GLCALLV(ColorMask, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilMask(GLuint mask)
+{
+ GLCALLV(StencilMask, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearDepth(GLdouble depth)
+{
+ if (qgl_choose()->libraryType() == QAbstractWindowsOpenGL::DesktopGL) {
+ GLCALLV(ClearDepth, depth);
+ } else {
+ GLCALLV(ClearDepthf, depth);
+ }
+}
+
+Q_DECL_EXPORT void APIENTRY glClearStencil(GLint s)
+{
+ GLCALLV(ClearStencil, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(ClearColor, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glClear(GLbitfield mask)
+{
+ GLCALLV(Clear, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawBuffer(GLenum mode)
+{
+ GLCALLV(DrawBuffer, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexImage1D, target, level, internalformat, width, border, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexParameteriv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ GLCALLV(TexParameteri, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexParameterfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexParameterf, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(Scissor, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonMode(GLenum face, GLenum mode)
+{
+ GLCALLV(PolygonMode, face, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPointSize(GLfloat size)
+{
+ GLCALLV(PointSize, size);
+}
+
+Q_DECL_EXPORT void APIENTRY glLineWidth(GLfloat width)
+{
+ GLCALLV(LineWidth, width);
+}
+
+Q_DECL_EXPORT void APIENTRY glHint(GLenum target, GLenum mode)
+{
+ GLCALLV(Hint, target, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glFrontFace(GLenum mode)
+{
+ GLCALLV(FrontFace, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glCullFace(GLenum mode)
+{
+ GLCALLV(CullFace, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Translatef, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Translated, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Scalef, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Scaled, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Rotatef, angle, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Rotated, angle, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushMatrix()
+{
+ GLCALLV(PushMatrix);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopMatrix()
+{
+ GLCALLV(PopMatrix);
+}
+
+Q_DECL_EXPORT void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ GLCALLV(Ortho, left, right, bottom, top, zNear, zFar);
+}
+
+Q_DECL_EXPORT void APIENTRY glMultMatrixd(const GLdouble *m)
+{
+ GLCALLV(MultMatrixd, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glMultMatrixf(const GLfloat *m)
+{
+ GLCALLV(MultMatrixf, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glMatrixMode(GLenum mode)
+{
+ GLCALLV(MatrixMode, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadMatrixd(const GLdouble *m)
+{
+ GLCALLV(LoadMatrixd, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+ GLCALLV(LoadMatrixf, m);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadIdentity()
+{
+ GLCALLV(LoadIdentity);
+}
+
+Q_DECL_EXPORT void APIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ GLCALLV(Frustum, left, right, bottom, top, zNear, zFar);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsList(GLuint list)
+{
+ GLCALL(IsList, list);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexGeniv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexGenfv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ GLCALLV(GetTexGendv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ GLCALLV(GetTexEnviv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetTexEnvfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPolygonStipple(GLubyte *mask)
+{
+ GLCALLV(GetPolygonStipple, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
+{
+ GLCALLV(GetPixelMapusv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
+{
+ GLCALLV(GetPixelMapuiv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
+{
+ GLCALLV(GetPixelMapfv, map, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ GLCALLV(GetMaterialiv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetMaterialfv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
+{
+ GLCALLV(GetMapiv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+ GLCALLV(GetMapfv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+ GLCALLV(GetMapdv, target, query, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ GLCALLV(GetLightiv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ GLCALLV(GetLightfv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
+{
+ GLCALLV(GetClipPlane, plane, equation);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(DrawPixels, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ GLCALLV(CopyPixels, x, y, width, height, type);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapusv(GLenum map, GLint mapsize, const GLushort *values)
+{
+ GLCALLV(PixelMapusv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapuiv(GLenum map, GLint mapsize, const GLuint *values)
+{
+ GLCALLV(PixelMapuiv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
+{
+ GLCALLV(PixelMapfv, map, mapsize, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelTransferi(GLenum pname, GLint param)
+{
+ GLCALLV(PixelTransferi, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
+{
+ GLCALLV(PixelTransferf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ GLCALLV(PixelZoom, xfactor, yfactor);
+}
+
+Q_DECL_EXPORT void APIENTRY glAlphaFunc(GLenum func, GLfloat ref)
+{
+ GLCALLV(AlphaFunc, func, ref);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalPoint2(GLint i, GLint j)
+{
+ GLCALLV(EvalPoint2, i, j);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ GLCALLV(EvalMesh2, mode, i1, i2, j1, j2);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalPoint1(GLint i)
+{
+ GLCALLV(EvalPoint1, i);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ GLCALLV(EvalMesh1, mode, i1, i2);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2fv(const GLfloat *u)
+{
+ GLCALLV(EvalCoord2fv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
+{
+ GLCALLV(EvalCoord2f, u, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2dv(const GLdouble *u)
+{
+ GLCALLV(EvalCoord2dv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
+{
+ GLCALLV(EvalCoord2d, u, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1fv(const GLfloat *u)
+{
+ GLCALLV(EvalCoord1fv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1f(GLfloat u)
+{
+ GLCALLV(EvalCoord1f, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1dv(const GLdouble *u)
+{
+ GLCALLV(EvalCoord1dv, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glEvalCoord1d(GLdouble u)
+{
+ GLCALLV(EvalCoord1d, u);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+ GLCALLV(MapGrid2f, un, u1, u2, vn, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+ GLCALLV(MapGrid2d, un, u1, u2, vn, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ GLCALLV(MapGrid1f, un, u1, u2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ GLCALLV(MapGrid1d, un, u1, u2);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
+{
+ GLCALLV(Map2f, target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
+{
+ GLCALLV(Map2d, target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
+{
+ GLCALLV(Map1f, target, u1, u2, stride, order, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
+{
+ GLCALLV(Map1d, target, u1, u2, stride, order, points);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushAttrib(GLbitfield mask)
+{
+ GLCALLV(PushAttrib, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopAttrib()
+{
+ GLCALLV(PopAttrib);
+}
+
+Q_DECL_EXPORT void APIENTRY glAccum(GLenum op, GLfloat value)
+{
+ GLCALLV(Accum, op, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexMask(GLuint mask)
+{
+ GLCALLV(IndexMask, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearIndex(GLfloat c)
+{
+ GLCALLV(ClearIndex, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(ClearAccum, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushName(GLuint name)
+{
+ GLCALLV(PushName, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopName()
+{
+ GLCALLV(PopName);
+}
+
+Q_DECL_EXPORT void APIENTRY glPassThrough(GLfloat token)
+{
+ GLCALLV(PassThrough, token);
+}
+
+Q_DECL_EXPORT void APIENTRY glLoadName(GLuint name)
+{
+ GLCALLV(LoadName, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glInitNames()
+{
+ GLCALLV(InitNames);
+}
+
+Q_DECL_EXPORT GLint APIENTRY glRenderMode(GLenum mode)
+{
+ GLCALL(RenderMode, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
+{
+ GLCALLV(SelectBuffer, size, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+ GLCALLV(FeedbackBuffer, size, type, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexGeniv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ GLCALLV(TexGeni, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexGenfv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexGenf, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ GLCALLV(TexGendv, coord, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ GLCALLV(TexGend, coord, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ GLCALLV(TexEnviv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ GLCALLV(TexEnvi, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(TexEnvfv, target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ GLCALLV(TexEnvf, target, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glShadeModel(GLenum mode)
+{
+ GLCALLV(ShadeModel, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonStipple(const GLubyte *mask)
+{
+ GLCALLV(PolygonStipple, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
+{
+ GLCALLV(Materialiv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
+{
+ GLCALLV(Materiali, face, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Materialfv, face, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+ GLCALLV(Materialf, face, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLineStipple(GLint factor, GLushort pattern)
+{
+ GLCALLV(LineStipple, factor, pattern);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModeliv(GLenum pname, const GLint *params)
+{
+ GLCALLV(LightModeliv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModeli(GLenum pname, GLint param)
+{
+ GLCALLV(LightModeli, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+ GLCALLV(LightModelfv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+ GLCALLV(LightModelf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ GLCALLV(Lightiv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
+{
+ GLCALLV(Lighti, light, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Lightfv, light, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+ GLCALLV(Lightf, light, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogiv(GLenum pname, const GLint *params)
+{
+ GLCALLV(Fogiv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogi(GLenum pname, GLint param)
+{
+ GLCALLV(Fogi, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+ GLCALLV(Fogfv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+ GLCALLV(Fogf, pname, param);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorMaterial(GLenum face, GLenum mode)
+{
+ GLCALLV(ColorMaterial, face, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
+{
+ GLCALLV(ClipPlane, plane, equation);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4sv(const GLshort *v)
+{
+ GLCALLV(Vertex4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ GLCALLV(Vertex4s, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4iv(const GLint *v)
+{
+ GLCALLV(Vertex4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(Vertex4i, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4fv(const GLfloat *v)
+{
+ GLCALLV(Vertex4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(Vertex4f, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4dv(const GLdouble *v)
+{
+ GLCALLV(Vertex4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ GLCALLV(Vertex4d, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3sv(const GLshort *v)
+{
+ GLCALLV(Vertex3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
+{
+ GLCALLV(Vertex3s, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3iv(const GLint *v)
+{
+ GLCALLV(Vertex3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3i(GLint x, GLint y, GLint z)
+{
+ GLCALLV(Vertex3i, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3fv(const GLfloat *v)
+{
+ GLCALLV(Vertex3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Vertex3f, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3dv(const GLdouble *v)
+{
+ GLCALLV(Vertex3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(Vertex3d, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2sv(const GLshort *v)
+{
+ GLCALLV(Vertex2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2s(GLshort x, GLshort y)
+{
+ GLCALLV(Vertex2s, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2iv(const GLint *v)
+{
+ GLCALLV(Vertex2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2i(GLint x, GLint y)
+{
+ GLCALLV(Vertex2i, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2fv(const GLfloat *v)
+{
+ GLCALLV(Vertex2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2f(GLfloat x, GLfloat y)
+{
+ GLCALLV(Vertex2f, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2dv(const GLdouble *v)
+{
+ GLCALLV(Vertex2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertex2d(GLdouble x, GLdouble y)
+{
+ GLCALLV(Vertex2d, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4sv(const GLshort *v)
+{
+ GLCALLV(TexCoord4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ GLCALLV(TexCoord4s, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4iv(const GLint *v)
+{
+ GLCALLV(TexCoord4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+ GLCALLV(TexCoord4i, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ GLCALLV(TexCoord4f, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ GLCALLV(TexCoord4d, s, t, r, q);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3sv(const GLshort *v)
+{
+ GLCALLV(TexCoord3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
+{
+ GLCALLV(TexCoord3s, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3iv(const GLint *v)
+{
+ GLCALLV(TexCoord3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
+{
+ GLCALLV(TexCoord3i, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+ GLCALLV(TexCoord3f, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+ GLCALLV(TexCoord3d, s, t, r);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2sv(const GLshort *v)
+{
+ GLCALLV(TexCoord2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2s(GLshort s, GLshort t)
+{
+ GLCALLV(TexCoord2s, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2iv(const GLint *v)
+{
+ GLCALLV(TexCoord2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2i(GLint s, GLint t)
+{
+ GLCALLV(TexCoord2i, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
+{
+ GLCALLV(TexCoord2f, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
+{
+ GLCALLV(TexCoord2d, s, t);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1sv(const GLshort *v)
+{
+ GLCALLV(TexCoord1sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1s(GLshort s)
+{
+ GLCALLV(TexCoord1s, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1iv(const GLint *v)
+{
+ GLCALLV(TexCoord1iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1i(GLint s)
+{
+ GLCALLV(TexCoord1i, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1fv(const GLfloat *v)
+{
+ GLCALLV(TexCoord1fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1f(GLfloat s)
+{
+ GLCALLV(TexCoord1f, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1dv(const GLdouble *v)
+{
+ GLCALLV(TexCoord1dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoord1d(GLdouble s)
+{
+ GLCALLV(TexCoord1d, s);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
+{
+ GLCALLV(Rectsv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ GLCALLV(Rects, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectiv(const GLint *v1, const GLint *v2)
+{
+ GLCALLV(Rectiv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ GLCALLV(Recti, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ GLCALLV(Rectfv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ GLCALLV(Rectf, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ GLCALLV(Rectdv, v1, v2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ GLCALLV(Rectd, x1, y1, x2, y2);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4sv(const GLshort *v)
+{
+ GLCALLV(RasterPos4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ GLCALLV(RasterPos4s, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4iv(const GLint *v)
+{
+ GLCALLV(RasterPos4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(RasterPos4i, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(RasterPos4f, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ GLCALLV(RasterPos4d, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3sv(const GLshort *v)
+{
+ GLCALLV(RasterPos3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ GLCALLV(RasterPos3s, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3iv(const GLint *v)
+{
+ GLCALLV(RasterPos3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
+{
+ GLCALLV(RasterPos3i, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(RasterPos3f, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ GLCALLV(RasterPos3d, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2sv(const GLshort *v)
+{
+ GLCALLV(RasterPos2sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2s(GLshort x, GLshort y)
+{
+ GLCALLV(RasterPos2s, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2iv(const GLint *v)
+{
+ GLCALLV(RasterPos2iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2i(GLint x, GLint y)
+{
+ GLCALLV(RasterPos2i, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2fv(const GLfloat *v)
+{
+ GLCALLV(RasterPos2fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
+{
+ GLCALLV(RasterPos2f, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2dv(const GLdouble *v)
+{
+ GLCALLV(RasterPos2dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
+{
+ GLCALLV(RasterPos2d, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3sv(const GLshort *v)
+{
+ GLCALLV(Normal3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+ GLCALLV(Normal3s, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3iv(const GLint *v)
+{
+ GLCALLV(Normal3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
+{
+ GLCALLV(Normal3i, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3fv(const GLfloat *v)
+{
+ GLCALLV(Normal3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ GLCALLV(Normal3f, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3dv(const GLdouble *v)
+{
+ GLCALLV(Normal3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+ GLCALLV(Normal3d, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3bv(const GLbyte *v)
+{
+ GLCALLV(Normal3bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+ GLCALLV(Normal3b, nx, ny, nz);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexsv(const GLshort *c)
+{
+ GLCALLV(Indexsv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexs(GLshort c)
+{
+ GLCALLV(Indexs, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexiv(const GLint *c)
+{
+ GLCALLV(Indexiv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexi(GLint c)
+{
+ GLCALLV(Indexi, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexfv(const GLfloat *c)
+{
+ GLCALLV(Indexfv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexf(GLfloat c)
+{
+ GLCALLV(Indexf, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexdv(const GLdouble *c)
+{
+ GLCALLV(Indexdv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexd(GLdouble c)
+{
+ GLCALLV(Indexd, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnd()
+{
+ GLCALLV(End);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlagv(const GLboolean *flag)
+{
+ GLCALLV(EdgeFlagv, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlag(GLboolean flag)
+{
+ GLCALLV(EdgeFlag, flag);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4usv(const GLushort *v)
+{
+ GLCALLV(Color4usv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+ GLCALLV(Color4us, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4uiv(const GLuint *v)
+{
+ GLCALLV(Color4uiv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+ GLCALLV(Color4ui, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ubv(const GLubyte *v)
+{
+ GLCALLV(Color4ubv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ GLCALLV(Color4ub, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4sv(const GLshort *v)
+{
+ GLCALLV(Color4sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+ GLCALLV(Color4s, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4iv(const GLint *v)
+{
+ GLCALLV(Color4iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+ GLCALLV(Color4i, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4fv(const GLfloat *v)
+{
+ GLCALLV(Color4fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ GLCALLV(Color4f, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4dv(const GLdouble *v)
+{
+ GLCALLV(Color4dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+ GLCALLV(Color4d, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4bv(const GLbyte *v)
+{
+ GLCALLV(Color4bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+ GLCALLV(Color4b, red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3usv(const GLushort *v)
+{
+ GLCALLV(Color3usv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ GLCALLV(Color3us, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3uiv(const GLuint *v)
+{
+ GLCALLV(Color3uiv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ GLCALLV(Color3ui, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ubv(const GLubyte *v)
+{
+ GLCALLV(Color3ubv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ GLCALLV(Color3ub, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3sv(const GLshort *v)
+{
+ GLCALLV(Color3sv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ GLCALLV(Color3s, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3iv(const GLint *v)
+{
+ GLCALLV(Color3iv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3i(GLint red, GLint green, GLint blue)
+{
+ GLCALLV(Color3i, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3fv(const GLfloat *v)
+{
+ GLCALLV(Color3fv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ GLCALLV(Color3f, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3dv(const GLdouble *v)
+{
+ GLCALLV(Color3dv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ GLCALLV(Color3d, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3bv(const GLbyte *v)
+{
+ GLCALLV(Color3bv, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ GLCALLV(Color3b, red, green, blue);
+}
+
+Q_DECL_EXPORT void APIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
+{
+ GLCALLV(Bitmap, width, height, xorig, yorig, xmove, ymove, bitmap);
+}
+
+Q_DECL_EXPORT void APIENTRY glBegin(GLenum mode)
+{
+ GLCALLV(Begin, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glListBase(GLuint base)
+{
+ GLCALLV(ListBase, base);
+}
+
+Q_DECL_EXPORT GLuint APIENTRY glGenLists(GLsizei range)
+{
+ GLCALL(GenLists, range);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteLists(GLuint list, GLsizei range)
+{
+ GLCALLV(DeleteLists, list, range);
+}
+
+Q_DECL_EXPORT void APIENTRY glCallLists(GLsizei n, GLenum type, const GLvoid *lists)
+{
+ GLCALLV(CallLists, n, type, lists);
+}
+
+Q_DECL_EXPORT void APIENTRY glCallList(GLuint list)
+{
+ GLCALLV(CallList, list);
+}
+
+Q_DECL_EXPORT void APIENTRY glEndList()
+{
+ GLCALLV(EndList);
+}
+
+Q_DECL_EXPORT void APIENTRY glNewList(GLuint list, GLenum mode)
+{
+ GLCALLV(NewList, list, mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexubv(const GLubyte *c)
+{
+ GLCALLV(Indexubv, c);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexub(GLubyte c)
+{
+ GLCALLV(Indexub, c);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsTexture(GLuint texture)
+{
+ GLCALL(IsTexture, texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenTextures(GLsizei n, GLuint *textures)
+{
+ GLCALLV(GenTextures, n, textures);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ GLCALLV(DeleteTextures, n, textures);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+ GLCALLV(BindTexture, target, texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLCALLV(TexSubImage1D, target, level, xoffset, width, format, type, pixels);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ GLCALLV(CopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ GLCALLV(CopyTexSubImage1D, target, level, xoffset, x, y, width);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ GLCALLV(CopyTexImage2D, target, level, internalformat, x, y, width, height, border);
+}
+
+Q_DECL_EXPORT void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border)
+{
+ GLCALLV(CopyTexImage1D, target, level, internalformat, x, y, width, border);
+}
+
+Q_DECL_EXPORT void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ GLCALLV(PolygonOffset, factor, units);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetPointerv(GLenum pname, GLvoid* *params)
+{
+ GLCALLV(GetPointerv, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+{
+ GLCALLV(DrawElements, mode, count, type, indices);
+}
+
+Q_DECL_EXPORT void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ GLCALLV(DrawArrays, mode, first, count);
+}
+
+Q_DECL_EXPORT void APIENTRY glPushClientAttrib(GLbitfield mask)
+{
+ GLCALLV(PushClientAttrib, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glPopClientAttrib()
+{
+ GLCALLV(PopClientAttrib);
+}
+
+Q_DECL_EXPORT void APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities)
+{
+ GLCALLV(PrioritizeTextures, n, textures, priorities);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
+{
+ GLCALL(AreTexturesResident, n, textures, residences);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(VertexPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(TexCoordPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(NormalPointer, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(InterleavedArrays, format, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(IndexPointer, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnableClientState(GLenum array)
+{
+ GLCALLV(EnableClientState, array);
+}
+
+Q_DECL_EXPORT void APIENTRY glEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(EdgeFlagPointer, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisableClientState(GLenum array)
+{
+ GLCALLV(DisableClientState, array);
+}
+
+Q_DECL_EXPORT void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+{
+ GLCALLV(ColorPointer, size, type, stride, pointer);
+}
+
+Q_DECL_EXPORT void APIENTRY glArrayElement(GLint i)
+{
+ GLCALLV(ArrayElement, i);
+}
+
+// OpenGL ES 2.0
+
+Q_DECL_EXPORT void APIENTRY glActiveTexture(GLenum texture)
+{
+ GLCALLV(ActiveTexture,texture);
+}
+
+Q_DECL_EXPORT void APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+ GLCALLV(AttachShader,program, shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
+{
+ GLCALLV(BindAttribLocation,program, index, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+ GLCALLV(BindBuffer,target, buffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ GLCALLV(BindFramebuffer,target, framebuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ GLCALLV(BindRenderbuffer,target, renderbuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+ GLCALLV(BlendColor,red, green, blue, alpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendEquation(GLenum mode)
+{
+ GLCALLV(BlendEquation,mode);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ GLCALLV(BlendEquationSeparate,modeRGB, modeAlpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ GLCALLV(BlendFuncSeparate,srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+Q_DECL_EXPORT void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
+{
+ GLCALLV(BufferData,target, size, data, usage);
+}
+
+Q_DECL_EXPORT void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
+{
+ GLCALLV(BufferSubData,target, offset, size, data);
+}
+
+Q_DECL_EXPORT GLenum APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+ GLCALL(CheckFramebufferStatus,target);
+}
+
+Q_DECL_EXPORT void APIENTRY glClearDepthf(GLclampf depth)
+{
+ glClearDepth(depth);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompileShader(GLuint shader)
+{
+ GLCALLV(CompileShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
+{
+ GLCALLV(CompressedTexImage2D,target, level, internalformat, width, height, border, imageSize, data);
+}
+
+Q_DECL_EXPORT void APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
+{
+ GLCALLV(CompressedTexSubImage2D,target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+
+Q_DECL_EXPORT GLuint APIENTRY glCreateProgram(void)
+{
+ GLCALL(CreateProgram);
+}
+
+Q_DECL_EXPORT GLuint glCreateShader(GLenum type)
+{
+ GLCALL(CreateShader,type);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteBuffers(GLsizei n, const GLuint* buffers)
+{
+ GLCALLV(DeleteBuffers,n, buffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
+{
+ GLCALLV(DeleteFramebuffers,n, framebuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteProgram(GLuint program)
+{
+ GLCALLV(DeleteProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
+{
+ GLCALLV(DeleteRenderbuffers,n, renderbuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glDeleteShader(GLuint shader)
+{
+ GLCALLV(DeleteShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glDepthRangef(GLclampf zNear, GLclampf zFar)
+{
+ glDepthRange(zNear, zFar);
+}
+
+Q_DECL_EXPORT void APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+ GLCALLV(DetachShader,program, shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+ GLCALLV(DisableVertexAttribArray,index);
+}
+
+Q_DECL_EXPORT void APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+ GLCALLV(EnableVertexAttribArray,index);
+}
+
+Q_DECL_EXPORT void APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ GLCALLV(FramebufferRenderbuffer,target, attachment, renderbuffertarget, renderbuffer);
+}
+
+Q_DECL_EXPORT void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ GLCALLV(FramebufferTexture2D,target, attachment, textarget, texture, level);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenBuffers(GLsizei n, GLuint* buffers)
+{
+ GLCALLV(GenBuffers,n, buffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenerateMipmap(GLenum target)
+{
+ GLCALLV(GenerateMipmap,target);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
+{
+ GLCALLV(GenFramebuffers,n, framebuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
+{
+ GLCALLV(GenRenderbuffers,n, renderbuffers);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ GLCALLV(GetActiveAttrib,program, index, bufsize, length, size, type, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+{
+ GLCALLV(GetActiveUniform,program, index, bufsize, length, size, type, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+{
+ GLCALLV(GetAttachedShaders,program, maxcount, count, shaders);
+}
+
+Q_DECL_EXPORT int APIENTRY glGetAttribLocation(GLuint program, const GLchar* name)
+{
+ GLCALL(GetAttribLocation,program, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ GLCALLV(GetBufferParameteriv,target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
+{
+ GLCALLV(GetFramebufferAttachmentParameteriv,target, attachment, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* params)
+{
+ GLCALLV(GetProgramiv,program, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLCALLV(GetProgramInfoLog,program, bufsize, length, infolog);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
+{
+ GLCALLV(GetRenderbufferParameteriv,target, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
+{
+ GLCALLV(GetShaderiv,shader, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
+{
+ GLCALLV(GetShaderInfoLog,shader, bufsize, length, infolog);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+{
+ GLCALLV(GetShaderPrecisionFormat,shadertype, precisiontype, range, precision);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
+{
+ GLCALLV(GetShaderSource,shader, bufsize, length, source);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat* params)
+{
+ GLCALLV(GetUniformfv, program, location, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetUniformiv(GLuint program, GLint location, GLint* params)
+{
+ GLCALLV(GetUniformiv, program, location, params);
+}
+
+Q_DECL_EXPORT int APIENTRY glGetUniformLocation(GLuint program, const GLchar* name)
+{
+ GLCALL(GetUniformLocation,program, name);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
+{
+ GLCALLV(GetVertexAttribfv,index, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
+{
+ GLCALLV(GetVertexAttribiv,index, pname, params);
+}
+
+Q_DECL_EXPORT void APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
+{
+ GLCALLV(GetVertexAttribPointerv,index, pname, pointer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsBuffer(GLuint buffer)
+{
+ GLCALL(IsBuffer,buffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+ GLCALL(IsFramebuffer,framebuffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsProgram(GLuint program)
+{
+ GLCALL(IsProgram,program);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+ GLCALL(IsRenderbuffer,renderbuffer);
+}
+
+Q_DECL_EXPORT GLboolean APIENTRY glIsShader(GLuint shader)
+{
+ GLCALL(IsShader,shader);
+}
+
+Q_DECL_EXPORT void APIENTRY glLinkProgram(GLuint program)
+{
+ GLCALLV(LinkProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glReleaseShaderCompiler(void)
+{
+ GLCALLV(ReleaseShaderCompiler,);
+}
+
+Q_DECL_EXPORT void APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ GLCALLV(RenderbufferStorage,target, internalformat, width, height);
+}
+
+Q_DECL_EXPORT void APIENTRY glSampleCoverage(GLclampf value, GLboolean invert)
+{
+ GLCALLV(SampleCoverage,value, invert);
+}
+
+Q_DECL_EXPORT void APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+{
+ GLCALLV(ShaderBinary,n, shaders, binaryformat, binary, length);
+}
+
+Q_DECL_EXPORT void APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar* *string, const GLint* length)
+{
+ GLCALLV(ShaderSource,shader, count, string, length);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GLCALLV(StencilFuncSeparate,face, func, ref, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ GLCALLV(StencilMaskSeparate,face, mask);
+}
+
+Q_DECL_EXPORT void APIENTRY glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ GLCALLV(StencilOpSeparate,face, fail, zfail, zpass);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1f(GLint location, GLfloat x)
+{
+ GLCALLV(Uniform1f,location, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform1fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1i(GLint location, GLint x)
+{
+ GLCALLV(Uniform1i,location, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform1iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2f(GLint location, GLfloat x, GLfloat y)
+{
+ GLCALLV(Uniform2f,location, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform2fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2i(GLint location, GLint x, GLint y)
+{
+ GLCALLV(Uniform2i,location, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform2iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(Uniform3f,location, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform3fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3i(GLint location, GLint x, GLint y, GLint z)
+{
+ GLCALLV(Uniform3i,location, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform3iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(Uniform4f,location, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
+{
+ GLCALLV(Uniform4fv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ GLCALLV(Uniform4i,location, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint* v)
+{
+ GLCALLV(Uniform4iv,location, count, v);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix2fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix3fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+{
+ GLCALLV(UniformMatrix4fv,location, count, transpose, value);
+}
+
+Q_DECL_EXPORT void APIENTRY glUseProgram(GLuint program)
+{
+ GLCALLV(UseProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glValidateProgram(GLuint program)
+{
+ GLCALLV(ValidateProgram,program);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib1f(GLuint indx, GLfloat x)
+{
+ GLCALLV(VertexAttrib1f,indx, x);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib1fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib1fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
+{
+ GLCALLV(VertexAttrib2f,indx, x, y);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib2fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib2fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLCALLV(VertexAttrib3f,indx, x, y, z);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib3fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib3fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLCALLV(VertexAttrib4f,indx, x, y, z, w);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttrib4fv(GLuint indx, const GLfloat* values)
+{
+ GLCALLV(VertexAttrib4fv,indx, values);
+}
+
+Q_DECL_EXPORT void APIENTRY glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
+{
+ GLCALLV(VertexAttribPointer,indx, size, type, normalized, stride, ptr);
+}
+
+// EGL
+
+Q_DECL_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+ // This is a bit more complicated since the GLES2 functions (that are not in OpenGL 1)
+ // must be made queriable in order to allow classes like QOpenGLFunctions to operate
+ // on the same code path for desktop GL and proxied ES.
+ typedef __eglMustCastToProperFunctionPointerType FuncType;
+ FuncType f = 0;
+ f = qgl_choose()->EGL_GetProcAddress(procname);
+ if (!f) {
+ static struct Tab {
+ const char *name;
+ FuncType func;
+ } tab[] = {
+ { "glActiveTexture", (FuncType) glActiveTexture },
+ { "glAttachShader", (FuncType) glAttachShader },
+ { "glBindAttribLocation", (FuncType) glBindAttribLocation },
+ { "glBindBuffer", (FuncType) glBindBuffer },
+ { "glBindFramebuffer", (FuncType) glBindFramebuffer },
+ { "glBindRenderbuffer", (FuncType) glBindRenderbuffer },
+ { "glBlendColor", (FuncType) glBlendColor },
+ { "glBlendEquation", (FuncType) glBlendEquation },
+ { "glBlendEquationSeparate", (FuncType) glBlendEquationSeparate },
+ { "glBlendFuncSeparate", (FuncType) glBlendFuncSeparate },
+ { "glBufferData", (FuncType) glBufferData },
+ { "glBufferSubData", (FuncType) glBufferSubData },
+ { "glCheckFramebufferStatus", (FuncType) glCheckFramebufferStatus },
+ { "glCompileShader", (FuncType) glCompileShader },
+ { "glCompressedTexImage2D", (FuncType) glCompressedTexImage2D },
+ { "glCompressedTexSubImage2D", (FuncType) glCompressedTexSubImage2D },
+ { "glCreateProgram", (FuncType) glCreateProgram },
+ { "glCreateShader", (FuncType) glCreateShader },
+ { "glDeleteBuffers", (FuncType) glDeleteBuffers },
+ { "glDeleteFramebuffers", (FuncType) glDeleteFramebuffers },
+ { "glDeleteProgram", (FuncType) glDeleteProgram },
+ { "glDeleteRenderbuffers", (FuncType) glDeleteRenderbuffers },
+ { "glDeleteShader", (FuncType) glDeleteShader },
+ { "glDetachShader", (FuncType) glDetachShader },
+ { "glDisableVertexAttribArray", (FuncType) glDisableVertexAttribArray },
+ { "glEnableVertexAttribArray", (FuncType) glEnableVertexAttribArray },
+ { "glFramebufferRenderbuffer", (FuncType) glFramebufferRenderbuffer },
+ { "glFramebufferTexture2D", (FuncType) glFramebufferTexture2D },
+ { "glGenBuffers", (FuncType) glGenBuffers },
+ { "glGenerateMipmap", (FuncType) glGenerateMipmap },
+ { "glGenFramebuffers", (FuncType) glGenFramebuffers },
+ { "glGenRenderbuffers", (FuncType) glGenRenderbuffers },
+ { "glGetActiveAttrib", (FuncType) glGetActiveAttrib },
+ { "glGetActiveUniform", (FuncType) glGetActiveUniform },
+ { "glGetAttachedShaders", (FuncType) glGetAttachedShaders },
+ { "glGetAttribLocation", (FuncType) glGetAttribLocation },
+ { "glGetBufferParameteriv", (FuncType) glGetBufferParameteriv },
+ { "glGetFramebufferAttachmentParameteriv", (FuncType) glGetFramebufferAttachmentParameteriv },
+ { "glGetProgramiv", (FuncType) glGetProgramiv },
+ { "glGetProgramInfoLog", (FuncType) glGetProgramInfoLog },
+ { "glGetRenderbufferParameteriv", (FuncType) glGetRenderbufferParameteriv },
+ { "glGetShaderiv", (FuncType) glGetShaderiv },
+ { "glGetShaderInfoLog", (FuncType) glGetShaderInfoLog },
+ { "glGetShaderPrecisionFormat", (FuncType) glGetShaderPrecisionFormat },
+ { "glGetShaderSource", (FuncType) glGetShaderSource },
+ { "glGetUniformfv", (FuncType) glGetUniformfv },
+ { "glGetUniformiv", (FuncType) glGetUniformiv },
+ { "glGetUniformLocation", (FuncType) glGetUniformLocation },
+ { "glGetVertexAttribfv", (FuncType) glGetVertexAttribfv },
+ { "glGetVertexAttribiv", (FuncType) glGetVertexAttribiv },
+ { "glGetVertexAttribPointerv", (FuncType) glGetVertexAttribPointerv },
+ { "glIsBuffer", (FuncType) glIsBuffer },
+ { "glIsFramebuffer", (FuncType) glIsFramebuffer },
+ { "glIsProgram", (FuncType) glIsProgram },
+ { "glIsRenderbuffer", (FuncType) glIsRenderbuffer },
+ { "glIsShader", (FuncType) glIsShader },
+ { "glLinkProgram", (FuncType) glLinkProgram },
+ { "glReleaseShaderCompiler", (FuncType) glReleaseShaderCompiler },
+ { "glRenderbufferStorage", (FuncType) glRenderbufferStorage },
+ { "glSampleCoverage", (FuncType) glSampleCoverage },
+ { "glShaderBinary", (FuncType) glShaderBinary },
+ { "glShaderSource", (FuncType) glShaderSource },
+ { "glStencilFuncSeparate", (FuncType) glStencilFuncSeparate },
+ { "glStencilMaskSeparate", (FuncType) glStencilMaskSeparate },
+ { "glStencilOpSeparate", (FuncType) glStencilOpSeparate },
+ { "glUniform1f", (FuncType) glUniform1f },
+ { "glUniform1fv", (FuncType) glUniform1fv },
+ { "glUniform1i", (FuncType) glUniform1i },
+ { "glUniform1iv", (FuncType) glUniform1iv },
+ { "glUniform2f", (FuncType) glUniform2f },
+ { "glUniform2fv", (FuncType) glUniform2fv },
+ { "glUniform2i", (FuncType) glUniform2i },
+ { "glUniform2iv", (FuncType) glUniform2iv },
+ { "glUniform3f", (FuncType) glUniform3f },
+ { "glUniform3fv", (FuncType) glUniform3fv },
+ { "glUniform3i", (FuncType) glUniform3i },
+ { "glUniform3iv", (FuncType) glUniform3iv },
+ { "glUniform4f", (FuncType) glUniform4f },
+ { "glUniform4fv", (FuncType) glUniform4fv },
+ { "glUniform4i", (FuncType) glUniform4i },
+ { "glUniform4iv", (FuncType) glUniform4iv },
+ { "glUniformMatrix2fv", (FuncType) glUniformMatrix2fv },
+ { "glUniformMatrix3fv", (FuncType) glUniformMatrix3fv },
+ { "glUniformMatrix4fv", (FuncType) glUniformMatrix4fv },
+ { "glUseProgram", (FuncType) glUseProgram },
+ { "glValidateProgram", (FuncType) glValidateProgram },
+ { "glVertexAttrib1f", (FuncType) glVertexAttrib1f },
+ { "glVertexAttrib1fv", (FuncType) glVertexAttrib1fv },
+ { "glVertexAttrib2f", (FuncType) glVertexAttrib2f },
+ { "glVertexAttrib2fv", (FuncType) glVertexAttrib2fv },
+ { "glVertexAttrib3f", (FuncType) glVertexAttrib3f },
+ { "glVertexAttrib3fv", (FuncType) glVertexAttrib3fv },
+ { "glVertexAttrib4f", (FuncType) glVertexAttrib4f },
+ { "glVertexAttrib4fv", (FuncType) glVertexAttrib4fv },
+ { "glVertexAttribPointer", (FuncType) glVertexAttribPointer }
+ };
+ for (size_t i = 0; i < sizeof(tab) / sizeof(Tab); ++i) {
+ uint len = qstrlen(tab[i].name);
+ if (!qstrncmp(tab[i].name, procname, len)
+ && procname[len] == '\0') {
+ f = tab[i].func;
+ break;
+ }
+ }
+ if (!f)
+ qCDebug(qglLc, "eglGetProcAddress failed for %s", procname);
+ }
+
+ return f;
+}
+
+} // extern "C"
+
+// For QOpenGLFunctions
+int qgl_proxyLibraryType(void)
+{
+ return qgl_choose()->libraryType();
+}
+
+HMODULE qgl_glHandle(void)
+{
+ return qgl_choose()->libraryHandle();
+}
+
+QAbstractWindowsOpenGL::QAbstractWindowsOpenGL()
+ :
+ CopyContext(0),
+ CreateContext(0),
+ CreateLayerContext(0),
+ DeleteContext(0),
+ GetCurrentContext(0),
+ GetCurrentDC(0),
+ GetProcAddress(0),
+ MakeCurrent(0),
+ ShareLists(0),
+ UseFontBitmapsW(0),
+ UseFontOutlinesW(0),
+ DescribeLayerPlane(0),
+ SetLayerPaletteEntries(0),
+ GetLayerPaletteEntries(0),
+ RealizeLayerPalette(0),
+ SwapLayerBuffers(0),
+ SwapMultipleBuffers(0),
+
+ EGL_GetError(0),
+ EGL_GetDisplay(0),
+ EGL_Initialize(0),
+ EGL_Terminate(0),
+ EGL_QueryString(0),
+ EGL_GetConfigs(0),
+ EGL_ChooseConfig(0),
+ EGL_GetConfigAttrib(0),
+ EGL_CreateWindowSurface(0),
+ EGL_CreatePbufferSurface(0),
+ EGL_CreatePixmapSurface(0),
+ EGL_DestroySurface(0),
+ EGL_QuerySurface(0),
+ EGL_BindAPI(0),
+ EGL_QueryAPI(0),
+ EGL_WaitClient(0),
+ EGL_ReleaseThread(0),
+ EGL_CreatePbufferFromClientBuffer(0),
+ EGL_SurfaceAttrib(0),
+ EGL_BindTexImage(0),
+ EGL_ReleaseTexImage(0),
+ EGL_SwapInterval(0),
+ EGL_CreateContext(0),
+ EGL_DestroyContext(0),
+ EGL_MakeCurrent (0),
+ EGL_GetCurrentContext(0),
+ EGL_GetCurrentSurface(0),
+ EGL_GetCurrentDisplay(0),
+ EGL_QueryContext(0),
+ EGL_WaitGL(0),
+ EGL_WaitNative(0),
+ EGL_SwapBuffers(0),
+ EGL_CopyBuffers(0),
+ EGL_GetProcAddress(0),
+
+ Viewport(0),
+ DepthRange(0),
+ IsEnabled(0),
+ GetTexLevelParameteriv(0),
+ GetTexLevelParameterfv(0),
+ GetTexParameteriv(0),
+ GetTexParameterfv(0),
+ GetTexImage(0),
+ GetString(0),
+ GetIntegerv(0),
+ GetFloatv(0),
+ GetError(0),
+ GetDoublev(0),
+ GetBooleanv(0),
+ ReadPixels(0),
+ ReadBuffer(0),
+ PixelStorei(0),
+ PixelStoref(0),
+ DepthFunc(0),
+ StencilOp(0),
+ StencilFunc(0),
+ LogicOp(0),
+ BlendFunc(0),
+ Flush(0),
+ Finish(0),
+ Enable(0),
+ Disable(0),
+ DepthMask(0),
+ ColorMask(0),
+ StencilMask(0),
+ ClearDepth(0),
+ ClearStencil(0),
+ ClearColor(0),
+ Clear(0),
+ DrawBuffer(0),
+ TexImage2D(0),
+ TexImage1D(0),
+ TexParameteriv(0),
+ TexParameteri(0),
+ TexParameterfv(0),
+ TexParameterf(0),
+ Scissor(0),
+ PolygonMode(0),
+ PointSize(0),
+ LineWidth(0),
+ Hint(0),
+ FrontFace(0),
+ CullFace(0),
+
+ Translatef(0),
+ Translated(0),
+ Scalef(0),
+ Scaled(0),
+ Rotatef(0),
+ Rotated(0),
+ PushMatrix(0),
+ PopMatrix(0),
+ Ortho(0),
+ MultMatrixd(0),
+ MultMatrixf(0),
+ MatrixMode(0),
+ LoadMatrixd(0),
+ LoadMatrixf(0),
+ LoadIdentity(0),
+ Frustum(0),
+ IsList(0),
+ GetTexGeniv(0),
+ GetTexGenfv(0),
+ GetTexGendv(0),
+ GetTexEnviv(0),
+ GetTexEnvfv(0),
+ GetPolygonStipple(0),
+ GetPixelMapusv(0),
+ GetPixelMapuiv(0),
+ GetPixelMapfv(0),
+ GetMaterialiv(0),
+ GetMaterialfv(0),
+ GetMapiv(0),
+ GetMapfv(0),
+ GetMapdv(0),
+ GetLightiv(0),
+ GetLightfv(0),
+ GetClipPlane(0),
+ DrawPixels(0),
+ CopyPixels(0),
+ PixelMapusv(0),
+ PixelMapuiv(0),
+ PixelMapfv(0),
+ PixelTransferi(0),
+ PixelTransferf(0),
+ PixelZoom(0),
+ AlphaFunc(0),
+ EvalPoint2(0),
+ EvalMesh2(0),
+ EvalPoint1(0),
+ EvalMesh1(0),
+ EvalCoord2fv(0),
+ EvalCoord2f(0),
+ EvalCoord2dv(0),
+ EvalCoord2d(0),
+ EvalCoord1fv(0),
+ EvalCoord1f(0),
+ EvalCoord1dv(0),
+ EvalCoord1d(0),
+ MapGrid2f(0),
+ MapGrid2d(0),
+ MapGrid1f(0),
+ MapGrid1d(0),
+ Map2f(0),
+ Map2d(0),
+ Map1f(0),
+ Map1d(0),
+ PushAttrib(0),
+ PopAttrib(0),
+ Accum(0),
+ IndexMask(0),
+ ClearIndex(0),
+ ClearAccum(0),
+ PushName(0),
+ PopName(0),
+ PassThrough(0),
+ LoadName(0),
+ InitNames(0),
+ RenderMode(0),
+ SelectBuffer(0),
+ FeedbackBuffer(0),
+ TexGeniv(0),
+ TexGeni(0),
+ TexGenfv(0),
+ TexGenf(0),
+ TexGendv(0),
+ TexGend(0),
+ TexEnviv(0),
+ TexEnvi(0),
+ TexEnvfv(0),
+ TexEnvf(0),
+ ShadeModel(0),
+ PolygonStipple(0),
+ Materialiv(0),
+ Materiali(0),
+ Materialfv(0),
+ Materialf(0),
+ LineStipple(0),
+ LightModeliv(0),
+ LightModeli(0),
+ LightModelfv(0),
+ LightModelf(0),
+ Lightiv(0),
+ Lighti(0),
+ Lightfv(0),
+ Lightf(0),
+ Fogiv(0),
+ Fogi(0),
+ Fogfv(0),
+ Fogf(0),
+ ColorMaterial(0),
+ ClipPlane(0),
+ Vertex4sv(0),
+ Vertex4s(0),
+ Vertex4iv(0),
+ Vertex4i(0),
+ Vertex4fv(0),
+ Vertex4f(0),
+ Vertex4dv(0),
+ Vertex4d(0),
+ Vertex3sv(0),
+ Vertex3s(0),
+ Vertex3iv(0),
+ Vertex3i(0),
+ Vertex3fv(0),
+ Vertex3f(0),
+ Vertex3dv(0),
+ Vertex3d(0),
+ Vertex2sv(0),
+ Vertex2s(0),
+ Vertex2iv(0),
+ Vertex2i(0),
+ Vertex2fv(0),
+ Vertex2f(0),
+ Vertex2dv(0),
+ Vertex2d(0),
+ TexCoord4sv(0),
+ TexCoord4s(0),
+ TexCoord4iv(0),
+ TexCoord4i(0),
+ TexCoord4fv(0),
+ TexCoord4f(0),
+ TexCoord4dv(0),
+ TexCoord4d(0),
+ TexCoord3sv(0),
+ TexCoord3s(0),
+ TexCoord3iv(0),
+ TexCoord3i(0),
+ TexCoord3fv(0),
+ TexCoord3f(0),
+ TexCoord3dv(0),
+ TexCoord3d(0),
+ TexCoord2sv(0),
+ TexCoord2s(0),
+ TexCoord2iv(0),
+ TexCoord2i(0),
+ TexCoord2fv(0),
+ TexCoord2f(0),
+ TexCoord2dv(0),
+ TexCoord2d(0),
+ TexCoord1sv(0),
+ TexCoord1s(0),
+ TexCoord1iv(0),
+ TexCoord1i(0),
+ TexCoord1fv(0),
+ TexCoord1f(0),
+ TexCoord1dv(0),
+ TexCoord1d(0),
+ Rectsv(0),
+ Rects(0),
+ Rectiv(0),
+ Recti(0),
+ Rectfv(0),
+ Rectf(0),
+ Rectdv(0),
+ Rectd(0),
+ RasterPos4sv(0),
+ RasterPos4s(0),
+ RasterPos4iv(0),
+ RasterPos4i(0),
+ RasterPos4fv(0),
+ RasterPos4f(0),
+ RasterPos4dv(0),
+ RasterPos4d(0),
+ RasterPos3sv(0),
+ RasterPos3s(0),
+ RasterPos3iv(0),
+ RasterPos3i(0),
+ RasterPos3fv(0),
+ RasterPos3f(0),
+ RasterPos3dv(0),
+ RasterPos3d(0),
+ RasterPos2sv(0),
+ RasterPos2s(0),
+ RasterPos2iv(0),
+ RasterPos2i(0),
+ RasterPos2fv(0),
+ RasterPos2f(0),
+ RasterPos2dv(0),
+ RasterPos2d(0),
+ Normal3sv(0),
+ Normal3s(0),
+ Normal3iv(0),
+ Normal3i(0),
+ Normal3fv(0),
+ Normal3f(0),
+ Normal3dv(0),
+ Normal3d(0),
+ Normal3bv(0),
+ Normal3b(0),
+ Indexsv(0),
+ Indexs(0),
+ Indexiv(0),
+ Indexi(0),
+ Indexfv(0),
+ Indexf(0),
+ Indexdv(0),
+ Indexd(0),
+ End(0),
+ EdgeFlagv(0),
+ EdgeFlag(0),
+ Color4usv(0),
+ Color4us(0),
+ Color4uiv(0),
+ Color4ui(0),
+ Color4ubv(0),
+ Color4ub(0),
+ Color4sv(0),
+ Color4s(0),
+ Color4iv(0),
+ Color4i(0),
+ Color4fv(0),
+ Color4f(0),
+ Color4dv(0),
+ Color4d(0),
+ Color4bv(0),
+ Color4b(0),
+ Color3usv(0),
+ Color3us(0),
+ Color3uiv(0),
+ Color3ui(0),
+ Color3ubv(0),
+ Color3ub(0),
+ Color3sv(0),
+ Color3s(0),
+ Color3iv(0),
+ Color3i(0),
+ Color3fv(0),
+ Color3f(0),
+ Color3dv(0),
+ Color3d(0),
+ Color3bv(0),
+ Color3b(0),
+ Bitmap(0),
+ Begin(0),
+ ListBase(0),
+ GenLists(0),
+ DeleteLists(0),
+ CallLists(0),
+ CallList(0),
+ EndList(0),
+ NewList(0),
+
+ Indexubv(0),
+ Indexub(0),
+ IsTexture(0),
+ GenTextures(0),
+ DeleteTextures(0),
+ BindTexture(0),
+ TexSubImage2D(0),
+ TexSubImage1D(0),
+ CopyTexSubImage2D(0),
+ CopyTexSubImage1D(0),
+ CopyTexImage2D(0),
+ CopyTexImage1D(0),
+ PolygonOffset(0),
+ GetPointerv(0),
+ DrawElements(0),
+ DrawArrays(0),
+
+ PushClientAttrib(0),
+ PopClientAttrib(0),
+ PrioritizeTextures(0),
+ AreTexturesResident(0),
+ VertexPointer(0),
+ TexCoordPointer(0),
+ NormalPointer(0),
+ InterleavedArrays(0),
+ IndexPointer(0),
+ EnableClientState(0),
+ EdgeFlagPointer(0),
+ DisableClientState(0),
+ ColorPointer(0),
+ ArrayElement(0),
+
+ ActiveTexture(0),
+ AttachShader(0),
+ BindAttribLocation(0),
+ BindBuffer(0),
+ BindFramebuffer(0),
+ BindRenderbuffer(0),
+ BlendColor(0),
+ BlendEquation(0),
+ BlendEquationSeparate(0),
+ BlendFuncSeparate(0),
+ BufferData(0),
+ BufferSubData(0),
+ CheckFramebufferStatus(0),
+ ClearDepthf(0),
+ CompileShader(0),
+ CompressedTexImage2D(0),
+ CompressedTexSubImage2D(0),
+ CreateProgram(0),
+ CreateShader(0),
+ DeleteBuffers(0),
+ DeleteFramebuffers(0),
+ DeleteProgram(0),
+ DeleteRenderbuffers(0),
+ DeleteShader(0),
+ DepthRangef(0),
+ DetachShader(0),
+ DisableVertexAttribArray(0),
+ EnableVertexAttribArray(0),
+ FramebufferRenderbuffer(0),
+ FramebufferTexture2D(0),
+ GenBuffers(0),
+ GenerateMipmap(0),
+ GenFramebuffers(0),
+ GenRenderbuffers(0),
+ GetActiveAttrib(0),
+ GetActiveUniform(0),
+ GetAttachedShaders(0),
+ GetAttribLocation(0),
+ GetBufferParameteriv(0),
+ GetFramebufferAttachmentParameteriv(0),
+ GetProgramiv(0),
+ GetProgramInfoLog(0),
+ GetRenderbufferParameteriv(0),
+ GetShaderiv(0),
+ GetShaderInfoLog(0),
+ GetShaderPrecisionFormat(0),
+ GetShaderSource(0),
+ GetUniformfv(0),
+ GetUniformiv(0),
+ GetUniformLocation(0),
+ GetVertexAttribfv(0),
+ GetVertexAttribiv(0),
+ GetVertexAttribPointerv(0),
+ IsBuffer(0),
+ IsFramebuffer(0),
+ IsProgram(0),
+ IsRenderbuffer(0),
+ IsShader(0),
+ LinkProgram(0),
+ ReleaseShaderCompiler(0),
+ RenderbufferStorage(0),
+ SampleCoverage(0),
+ ShaderBinary(0),
+ ShaderSource(0),
+ StencilFuncSeparate(0),
+ StencilMaskSeparate(0),
+ StencilOpSeparate(0),
+ Uniform1f(0),
+ Uniform1fv(0),
+ Uniform1i(0),
+ Uniform1iv(0),
+ Uniform2f(0),
+ Uniform2fv(0),
+ Uniform2i(0),
+ Uniform2iv(0),
+ Uniform3f(0),
+ Uniform3fv(0),
+ Uniform3i(0),
+ Uniform3iv(0),
+ Uniform4f(0),
+ Uniform4fv(0),
+ Uniform4i(0),
+ Uniform4iv(0),
+ UniformMatrix2fv(0),
+ UniformMatrix3fv(0),
+ UniformMatrix4fv(0),
+ UseProgram(0),
+ ValidateProgram(0),
+ VertexAttrib1f(0),
+ VertexAttrib1fv(0),
+ VertexAttrib2f(0),
+ VertexAttrib2fv(0),
+ VertexAttrib3f(0),
+ VertexAttrib3fv(0),
+ VertexAttrib4f(0),
+ VertexAttrib4fv(0),
+ VertexAttribPointer(0),
+
+ m_lib(0),
+ m_libraryType(DesktopGL),
+ m_loaded(false)
+{
+}
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index ecc38b902c..06f40eafd0 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -175,13 +175,15 @@ public:
#endif
{
#ifndef QT_OPENGL_ES_2
- QSurfaceFormat f = ctx->format();
-
- // Geometry shaders require OpenGL >= 3.2
- if (shaderType & QOpenGLShader::Geometry)
- supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
- else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
- supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
+ if (!QOpenGLFunctions::isES()) {
+ QSurfaceFormat f = ctx->format();
+
+ // Geometry shaders require OpenGL >= 3.2
+ if (shaderType & QOpenGLShader::Geometry)
+ supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
+ else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
+ supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
+ }
#endif
}
~QOpenGLShaderPrivate();
@@ -441,7 +443,8 @@ bool QOpenGLShader::compileSourceCode(const char *source)
}
#ifdef QOpenGL_REDEFINE_HIGHP
- if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers) {
+ if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
+ && QOpenGLFunctions::isES()) {
src.append(redefineHighp);
srclen.append(GLint(sizeof(redefineHighp) - 1));
}
@@ -650,7 +653,8 @@ bool QOpenGLShaderProgram::init()
#ifndef QT_OPENGL_ES_2
// Resolve OpenGL 4 functions for tessellation shader support
QSurfaceFormat format = context->format();
- if (format.version() >= qMakePair<int, int>(4, 0)) {
+ if (!QOpenGLFunctions::isES()
+ && format.version() >= qMakePair<int, int>(4, 0)) {
d->tessellationFuncs = context->versionFunctions<QOpenGLFunctions_4_0_Core>();
d->tessellationFuncs->initializeOpenGLFunctions();
}
@@ -3248,14 +3252,16 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
#ifndef QT_OPENGL_ES_2
// Geometry shaders require OpenGL 3.2 or newer
QSurfaceFormat format = context->format();
- return (format.version() >= qMakePair<int, int>(3, 2));
+ return (!QOpenGLFunctions::isES())
+ && (format.version() >= qMakePair<int, int>(3, 2));
#else
// No geometry shader support in OpenGL ES2
return false;
#endif
} else if (type == TessellationControl || type == TessellationEvaluation) {
#if !defined(QT_OPENGL_ES_2)
- return (format.version() >= qMakePair<int, int>(4, 0));
+ return (!QOpenGLFunctions::isES())
+ && (format.version() >= qMakePair<int, int>(4, 0));
#else
// No tessellation shader support in OpenGL ES2
return false;
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index d9b2e82d0b..8bdbdba6f7 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -319,42 +319,70 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
return;
case QOpenGLTexture::Target1D:
- for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage1D(textureId, target, level, format,
- mipLevelSize(level, dimensions[0]),
- 0,
- QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ if (features.testFlag(QOpenGLTexture::Texture1D)) {
+ for (int level = 0; level < mipLevels; ++level)
+ texFuncs->glTextureImage1D(textureId, target, bindingTarget, level, format,
+ mipLevelSize(level, dimensions[0]),
+ 0,
+ QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ } else {
+ qWarning("1D textures are not supported");
+ return;
+ }
break;
case QOpenGLTexture::Target1DArray:
- if (features.testFlag(QOpenGLTexture::TextureArrays)) {
+ if (features.testFlag(QOpenGLTexture::Texture1D)
+ && features.testFlag(QOpenGLTexture::TextureArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage2D(textureId, target, level, format,
+ texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
layers,
0,
QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
} else {
- qWarning("Array textures are not supported");
+ qWarning("1D array textures are not supported");
return;
}
break;
case QOpenGLTexture::Target2D:
- case QOpenGLTexture::TargetCubeMap:
case QOpenGLTexture::TargetRectangle:
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage2D(textureId, target, level, format,
+ texFuncs->glTextureImage2D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
0,
QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
break;
+ case QOpenGLTexture::TargetCubeMap: {
+ // Cubemaps are the odd one out. We have to allocate storage for each
+ // face and miplevel using the special cubemap face targets rather than
+ // GL_TARGET_CUBEMAP.
+ const QOpenGLTexture::CubeMapFace faceTargets[] = {
+ QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::CubeMapNegativeX,
+ QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::CubeMapNegativeY,
+ QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::CubeMapNegativeZ
+ };
+
+ for (int faceTarget = 0; faceTarget < 6; ++faceTarget) {
+ for (int level = 0; level < mipLevels; ++level) {
+ texFuncs->glTextureImage2D(textureId, faceTargets[faceTarget], bindingTarget,
+ level, format,
+ mipLevelSize(level, dimensions[0]),
+ mipLevelSize(level, dimensions[1]),
+ 0,
+ QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, 0);
+ }
+ }
+ break;
+ }
+
case QOpenGLTexture::Target2DArray:
if (features.testFlag(QOpenGLTexture::TextureArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
layers,
@@ -370,7 +398,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
// Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
6 * layers,
@@ -385,7 +413,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target3D:
if (features.testFlag(QOpenGLTexture::Texture3D)) {
for (int level = 0; level < mipLevels; ++level)
- texFuncs->glTextureImage3D(textureId, target, level, format,
+ texFuncs->glTextureImage3D(textureId, target, bindingTarget, level, format,
mipLevelSize(level, dimensions[0]),
mipLevelSize(level, dimensions[1]),
mipLevelSize(level, dimensions[2]),
@@ -399,7 +427,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target2DMultisample:
if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
- texFuncs->glTextureImage2DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureImage2DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1],
fixedSamplePositions);
} else {
@@ -411,7 +439,7 @@ void QOpenGLTexturePrivate::allocateMutableStorage()
case QOpenGLTexture::Target2DMultisampleArray:
if (features.testFlag(QOpenGLTexture::TextureMultisample)
&& features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureImage3DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureImage3DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1], layers,
fixedSamplePositions);
} else {
@@ -433,16 +461,22 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
return;
case QOpenGLTexture::Target1D:
- texFuncs->glTextureStorage1D(textureId, target, mipLevels, format,
- dimensions[0]);
+ if (features.testFlag(QOpenGLTexture::Texture1D)) {
+ texFuncs->glTextureStorage1D(textureId, target, bindingTarget, mipLevels, format,
+ dimensions[0]);
+ } else {
+ qWarning("1D textures are not supported");
+ return;
+ }
break;
case QOpenGLTexture::Target1DArray:
- if (features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage2D(textureId, target, mipLevels, format,
+ if (features.testFlag(QOpenGLTexture::Texture1D)
+ && features.testFlag(QOpenGLTexture::TextureArrays)) {
+ texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], layers);
} else {
- qWarning("Array textures are not supported");
+ qWarning("1D array textures are not supported");
return;
}
break;
@@ -450,13 +484,13 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2D:
case QOpenGLTexture::TargetCubeMap:
case QOpenGLTexture::TargetRectangle:
- texFuncs->glTextureStorage2D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage2D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1]);
break;
case QOpenGLTexture::Target2DArray:
if (features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], layers);
} else {
qWarning("Array textures are not supported");
@@ -467,7 +501,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::TargetCubeMapArray:
// Cubemap arrays must specify number of layer-faces (6 * layers) as depth parameter
if (features.testFlag(QOpenGLTexture::TextureCubeMapArrays)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], 6 * layers);
} else {
qWarning("Cubemap Array textures are not supported");
@@ -477,7 +511,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target3D:
if (features.testFlag(QOpenGLTexture::Texture3D)) {
- texFuncs->glTextureStorage3D(textureId, target, mipLevels, format,
+ texFuncs->glTextureStorage3D(textureId, target, bindingTarget, mipLevels, format,
dimensions[0], dimensions[1], dimensions[2]);
} else {
qWarning("3D textures are not supported");
@@ -487,7 +521,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2DMultisample:
if (features.testFlag(QOpenGLTexture::TextureMultisample)) {
- texFuncs->glTextureStorage2DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureStorage2DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1],
fixedSamplePositions);
} else {
@@ -499,7 +533,7 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
case QOpenGLTexture::Target2DMultisampleArray:
if (features.testFlag(QOpenGLTexture::TextureMultisample)
&& features.testFlag(QOpenGLTexture::TextureArrays)) {
- texFuncs->glTextureStorage3DMultisample(textureId, target, samples, format,
+ texFuncs->glTextureStorage3DMultisample(textureId, target, bindingTarget, samples, format,
dimensions[0], dimensions[1], layers,
fixedSamplePositions);
} else {
@@ -514,20 +548,20 @@ void QOpenGLTexturePrivate::allocateImmutableStorage()
void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options)
+ const void *data, const QOpenGLPixelTransferOptions * const options)
{
switch (target) {
case QOpenGLTexture::Target1D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage1D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
0, mipLevelSize( mipLevel, dimensions[0] ),
sourceFormat, sourceType, data, options);
break;
case QOpenGLTexture::Target1DArray:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, layer,
mipLevelSize(mipLevel, dimensions[0]),
1,
@@ -536,7 +570,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target2D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -545,7 +579,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target2DArray:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -555,7 +589,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::Target3D:
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -565,7 +599,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::TargetCubeMap:
Q_UNUSED(layer);
- texFuncs->glTextureSubImage2D(textureId, cubeFace, mipLevel,
+ texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -575,7 +609,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
case QOpenGLTexture::TargetCubeMapArray: {
int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
int layerFace = 6 * layer + faceIndex;
- texFuncs->glTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layerFace,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -588,7 +622,7 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
Q_UNUSED(mipLevel);
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glTextureSubImage2D(textureId, target, 0,
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0,
0, 0,
dimensions[0],
dimensions[1],
@@ -611,21 +645,21 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, QOpenGLTexture::Cub
}
void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options)
{
switch (target) {
case QOpenGLTexture::Target1D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage1D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
0, mipLevelSize( mipLevel, dimensions[0] ),
format, dataSize, data, options);
break;
case QOpenGLTexture::Target1DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, layer,
mipLevelSize(mipLevel, dimensions[0]),
1,
@@ -634,7 +668,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target2D:
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -643,7 +677,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target2DArray:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -653,7 +687,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::Target3D:
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layer,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -663,7 +697,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::TargetCubeMap:
Q_UNUSED(layer);
- texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, mipLevel,
+ texFuncs->glCompressedTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
0, 0,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -673,7 +707,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
case QOpenGLTexture::TargetCubeMapArray: {
int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
int layerFace = 6 * layer + faceIndex;
- texFuncs->glCompressedTextureSubImage3D(textureId, target, mipLevel,
+ texFuncs->glCompressedTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
0, 0, layerFace,
mipLevelSize(mipLevel, dimensions[0]),
mipLevelSize(mipLevel, dimensions[1]),
@@ -686,7 +720,7 @@ void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, QOpenGLTe
Q_UNUSED(mipLevel);
Q_UNUSED(layer);
Q_UNUSED(cubeFace);
- texFuncs->glCompressedTextureSubImage2D(textureId, target, 0,
+ texFuncs->glCompressedTextureSubImage2D(textureId, target, bindingTarget, 0,
0, 0,
dimensions[0],
dimensions[1],
@@ -715,7 +749,7 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode)
case QOpenGLTexture::Target1DArray:
case QOpenGLTexture::TargetBuffer:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::Target2D:
@@ -726,15 +760,15 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::WrapMode mode)
case QOpenGLTexture::Target2DMultisampleArray:
case QOpenGLTexture::TargetRectangle:
wrapModes[0] = wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
break;
case QOpenGLTexture::Target3D:
wrapModes[0] = wrapModes[1] = wrapModes[2] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_R, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_R, mode);
break;
}
}
@@ -748,7 +782,7 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::DirectionT:
@@ -768,12 +802,12 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_S, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_S, mode);
break;
case QOpenGLTexture::DirectionT:
wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, GL_TEXTURE_WRAP_T, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, GL_TEXTURE_WRAP_T, mode);
break;
case QOpenGLTexture::DirectionR:
@@ -786,17 +820,17 @@ void QOpenGLTexturePrivate::setWrapMode(QOpenGLTexture::CoordinateDirection dire
switch (direction) {
case QOpenGLTexture::DirectionS:
wrapModes[0] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
case QOpenGLTexture::DirectionT:
wrapModes[1] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
case QOpenGLTexture::DirectionR:
wrapModes[2] = mode;
- texFuncs->glTextureParameteri(textureId, target, direction, mode);
+ texFuncs->glTextureParameteri(textureId, target, bindingTarget, direction, mode);
break;
}
break;
@@ -1367,6 +1401,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
\value NPOTTextures Basic support for non-power-of-two textures
\value NPOTTextureRepeat Full support for non-power-of-two textures including texture
repeat modes
+ \value Texture1D Support for the 1 dimensional texture target
*/
/*!
@@ -2135,6 +2170,65 @@ bool QOpenGLTexture::isTextureView() const
If using a compressed format() then you should use setCompressedData() instead of this
function.
+ \since 5.3
+ \sa setCompressedData()
+*/
+void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ if (!isStorageAllocated()) {
+ qWarning("Cannot set data on a texture that does not have storage allocated.\n"
+ "To do so call allocate() before this function");
+ return;
+ }
+ d->setData(mipLevel, layer, cubeFace, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(mipLevel, layer, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(int mipLevel,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(mipLevel, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \since 5.3
+ \overload
+*/
+void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
+}
+
+/*!
+ \obsolete
+ \overload
+
\sa setCompressedData()
*/
void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
@@ -2152,6 +2246,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer, CubeMapFace cubeFace,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(int mipLevel, int layer,
@@ -2164,6 +2259,7 @@ void QOpenGLTexture::setData(int mipLevel, int layer,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(int mipLevel,
@@ -2176,6 +2272,7 @@ void QOpenGLTexture::setData(int mipLevel,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
@@ -2202,7 +2299,7 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
QOpenGLPixelTransferOptions uploadOptions;
uploadOptions.setAlignment(1);
- setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.bits(), &uploadOptions);
+ setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions);
}
/*!
@@ -2212,6 +2309,59 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps)
If not using a compressed format() then you should use setData() instead of this
function.
+
+ \since 5.3
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
+ int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ if (!isStorageAllocated()) {
+ qWarning("Cannot set data on a texture that does not have storage allocated.\n"
+ "To do so call allocate() before this function");
+ return;
+ }
+ d->setCompressedData(mipLevel, layer, cubeFace, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(mipLevel, layer, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(mipLevel, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \overload
+*/
+void QOpenGLTexture::setCompressedData(int dataSize, const void *data,
+ const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setCompressedData(0, 0, QOpenGLTexture::CubeMapPositiveX, dataSize, data, options);
+}
+
+/*!
+ \obsolete
+ \overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
int dataSize, void *data,
@@ -2228,6 +2378,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, CubeMapFace cube
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, void *data,
@@ -2239,6 +2390,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int layer, int dataSize, vo
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, void *data,
@@ -2250,6 +2402,7 @@ void QOpenGLTexture::setCompressedData(int mipLevel, int dataSize, void *data,
}
/*!
+ \obsolete
\overload
*/
void QOpenGLTexture::setCompressedData(int dataSize, void *data,
@@ -2275,74 +2428,87 @@ bool QOpenGLTexture::hasFeature(Feature feature)
QSurfaceFormat f = ctx->format();
bool supported = false;
- switch (feature) {
+
#if !defined(QT_OPENGL_ES_2)
- case ImmutableMultisampleStorage:
- case TextureBuffer:
- case StencilTexturing:
- supported = f.version() >= qMakePair(4, 3);
- break;
+ if (!QOpenGLFunctions::isES()) {
+ switch (feature) {
+ case ImmutableMultisampleStorage:
+ case TextureBuffer:
+ case StencilTexturing:
+ supported = f.version() >= qMakePair(4, 3);
+ break;
- case ImmutableStorage:
- supported = f.version() >= qMakePair(4, 2);
- break;
+ case ImmutableStorage:
+ supported = f.version() >= qMakePair(4, 2);
+ break;
- case TextureCubeMapArrays:
- supported = f.version() >= qMakePair(4, 0);
- break;
+ case TextureCubeMapArrays:
+ supported = f.version() >= qMakePair(4, 0);
+ break;
- case Swizzle:
- supported = f.version() >= qMakePair(3, 3);
- break;
+ case Swizzle:
+ supported = f.version() >= qMakePair(3, 3);
+ break;
- case TextureMultisample:
- supported = f.version() >= qMakePair(3, 2);
- break;
+ case TextureMultisample:
+ supported = f.version() >= qMakePair(3, 2);
+ break;
- case TextureArrays:
- supported = f.version() >= qMakePair(3, 0);
- break;
+ case TextureArrays:
+ supported = f.version() >= qMakePair(3, 0);
+ break;
- case TextureRectangle:
- supported = f.version() >= qMakePair(2, 1);
- break;
+ case TextureRectangle:
+ supported = f.version() >= qMakePair(2, 1);
+ break;
- case Texture3D:
- supported = f.version() >= qMakePair(1, 3);
- break;
+ case Texture3D:
+ supported = f.version() >= qMakePair(1, 3);
+ break;
- case AnisotropicFiltering:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
- break;
+ case AnisotropicFiltering:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
+ break;
- case NPOTTextures:
- case NPOTTextureRepeat:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
- break;
+ case NPOTTextures:
+ case NPOTTextureRepeat:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ break;
- case MaxFeatureFlag:
- break;
- }
+ case Texture1D:
+ supported = f.version() >= qMakePair(1, 1);
+ break;
-#else
- case Texture3D:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
- break;
- case AnisotropicFiltering:
- supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
- break;
- case NPOTTextures:
- case NPOTTextureRepeat:
- supported = f.version() >= qMakePair(3,0);
- if (!supported) {
- supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
- if (!supported)
- supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ case MaxFeatureFlag:
+ break;
+
+ default:
+ break;
}
- default:
- break;
}
+
+ if (QOpenGLFunctions::isES())
#endif
+ {
+ switch (feature) {
+ case Texture3D:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
+ break;
+ case AnisotropicFiltering:
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
+ break;
+ case NPOTTextures:
+ case NPOTTextureRepeat:
+ supported = f.version() >= qMakePair(3,0);
+ if (!supported) {
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
+ if (!supported)
+ supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
+ }
+ default:
+ break;
+ }
+ }
return supported;
}
@@ -2356,17 +2522,20 @@ bool QOpenGLTexture::hasFeature(Feature feature)
void QOpenGLTexture::setMipBaseLevel(int baseLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(baseLevel <= d->maxLevel);
- d->baseLevel = baseLevel;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(baseLevel <= d->maxLevel);
+ d->baseLevel = baseLevel;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ return;
+ }
#else
Q_UNUSED(baseLevel);
- qWarning("QOpenGLTexture: Mipmap base level is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap base level is not supported");
}
/*!
@@ -2390,17 +2559,20 @@ int QOpenGLTexture::mipBaseLevel() const
void QOpenGLTexture::setMipMaxLevel(int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->baseLevel <= maxLevel);
- d->maxLevel = maxLevel;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->baseLevel <= maxLevel);
+ d->maxLevel = maxLevel;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ return;
+ }
#else
Q_UNUSED(maxLevel);
- qWarning("QOpenGLTexture: Mipmap max level is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap max level is not supported");
}
/*!
@@ -2424,18 +2596,21 @@ int QOpenGLTexture::mipMaxLevel() const
void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->textureId);
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(baseLevel <= maxLevel);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_BASE_LEVEL, baseLevel);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(baseLevel <= maxLevel);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
+ return;
+ }
#else
Q_UNUSED(baseLevel);
Q_UNUSED(maxLevel);
- qWarning("QOpenGLTexture: Mipmap level range is not supported");
#endif
+ qWarning("QOpenGLTexture: Mipmap level range is not supported");
}
/*!
@@ -2487,7 +2662,7 @@ void QOpenGLTexture::generateMipMaps()
Q_D(QOpenGLTexture);
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
- d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target);
+ d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
}
/*!
@@ -2511,7 +2686,7 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
if (resetBaseLevel)
oldBaseLevel = mipBaseLevel();
setMipBaseLevel(baseLevel);
- d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target);
+ d->texFuncs->glGenerateTextureMipmap(d->textureId, d->target, d->bindingTarget);
if (resetBaseLevel)
setMipBaseLevel(oldBaseLevel);
}
@@ -2531,21 +2706,24 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(Swizzle)) {
- qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(Swizzle)) {
+ qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ return;
+ }
+ d->swizzleMask[component - SwizzleRed] = value;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
return;
}
- d->swizzleMask[component - SwizzleRed] = value;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, component, value);
#else
Q_UNUSED(component);
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
+ qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@@ -2555,27 +2733,30 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
SwizzleValue b, SwizzleValue a)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(Swizzle)) {
- qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(Swizzle)) {
+ qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
+ return;
+ }
+ GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
+ d->swizzleMask[0] = r;
+ d->swizzleMask[1] = g;
+ d->swizzleMask[2] = b;
+ d->swizzleMask[3] = a;
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
return;
}
- GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
- d->swizzleMask[0] = r;
- d->swizzleMask[1] = g;
- d->swizzleMask[2] = b;
- d->swizzleMask[3] = a;
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Texture swizzling is not supported");
#endif
+ qWarning("QOpenGLTexture: Texture swizzling is not supported");
}
/*!
@@ -2591,9 +2772,9 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
If using a texture that has a combined depth/stencil format this function sets
which component of the texture is accessed to \a mode.
- When the parameter is set to ?DepthMode, then accessing it from the
+ When the parameter is set to DepthMode, then accessing it from the
shader will access the depth component as a single float, as normal. But when
- the parameter is set to StencilMode?, the shader will access the stencil component.
+ the parameter is set to StencilMode, the shader will access the stencil component.
\note This function has no effect on Mac and Qt built for OpenGL ES 2.
\sa depthStencilMode()
@@ -2601,20 +2782,23 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
{
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- if (!d->features.testFlag(StencilTexturing)) {
- qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ if (!d->features.testFlag(StencilTexturing)) {
+ qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
+ return;
+ }
+ d->depthStencilMode = mode;
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
return;
}
- d->depthStencilMode = mode;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
#else
Q_UNUSED(mode);
- qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
#endif
+ qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
}
/*!
@@ -2640,7 +2824,7 @@ void QOpenGLTexture::setMinificationFilter(QOpenGLTexture::Filter filter)
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->minFilter = filter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MIN_FILTER, filter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, filter);
}
/*!
@@ -2666,7 +2850,7 @@ void QOpenGLTexture::setMagnificationFilter(QOpenGLTexture::Filter filter)
Q_ASSERT(d->texFuncs);
Q_ASSERT(d->textureId);
d->magFilter = filter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAG_FILTER, filter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, filter);
}
/*!
@@ -2695,8 +2879,8 @@ void QOpenGLTexture::setMinMagFilters(QOpenGLTexture::Filter minificationFilter,
Q_ASSERT(d->textureId);
d->minFilter = minificationFilter;
d->magFilter = magnificationFilter;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MIN_FILTER, minificationFilter);
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAG_FILTER, magnificationFilter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_FILTER, minificationFilter);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAG_FILTER, magnificationFilter);
}
/*!
@@ -2727,7 +2911,7 @@ void QOpenGLTexture::setMaximumAnisotropy(float anisotropy)
return;
}
d->maxAnisotropy = anisotropy;
- d->texFuncs->glTextureParameteri(d->textureId, d->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
+ d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
}
/*!
@@ -2788,23 +2972,26 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire
void QOpenGLTexture::setBorderColor(QColor color)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- float values[4];
- values[0] = color.redF();
- values[1] = color.greenF();
- values[2] = color.blueF();
- values[3] = color.alphaF();
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameterfv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ float values[4];
+ values[0] = color.redF();
+ values[1] = color.greenF();
+ values[2] = color.blueF();
+ values[3] = color.alphaF();
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(color);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@@ -2813,26 +3000,29 @@ void QOpenGLTexture::setBorderColor(QColor color)
void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- float values[4];
- values[0] = r;
- values[1] = g;
- values[2] = b;
- values[3] = a;
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameterfv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ float values[4];
+ values[0] = r;
+ values[1] = g;
+ values[2] = b;
+ values[3] = a;
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
}
/*!
@@ -2841,26 +3031,29 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- int values[4];
- values[0] = r;
- values[1] = g;
- values[2] = b;
- values[3] = a;
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ int values[4];
+ values[0] = r;
+ values[1] = g;
+ values[2] = b;
+ values[3] = a;
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIiv() based on format
}
@@ -2871,26 +3064,29 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- int values[4];
- values[0] = int(r);
- values[1] = int(g);
- values[2] = int(b);
- values[3] = int(a);
- d->borderColor.clear();
- for (int i = 0; i < 4; ++i)
- d->borderColor.append(QVariant(values[i]));
- d->texFuncs->glTextureParameteriv(d->textureId, d->target, GL_TEXTURE_BORDER_COLOR, values);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ int values[4];
+ values[0] = int(r);
+ values[1] = int(g);
+ values[2] = int(b);
+ values[3] = int(a);
+ d->borderColor.clear();
+ for (int i = 0; i < 4; ++i)
+ d->borderColor.append(QVariant(values[i]));
+ d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
+ return;
+ }
#else
Q_UNUSED(r);
Q_UNUSED(g);
Q_UNUSED(b);
Q_UNUSED(a);
- qWarning("QOpenGLTexture: Border color is not supported");
#endif
+ qWarning("QOpenGLTexture: Border color is not supported");
// TODO Handle case of using glTextureParameterIuiv() based on format
}
@@ -2974,17 +3170,20 @@ void QOpenGLTexture::borderColor(unsigned int *border) const
void QOpenGLTexture::setMinimumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(value < d->maxLevelOfDetail);
- d->minLevelOfDetail = value;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MIN_LOD, value);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(value < d->maxLevelOfDetail);
+ d->minLevelOfDetail = value;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
+ return;
+ }
#else
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3008,17 +3207,20 @@ float QOpenGLTexture::minimumLevelOfDetail() const
void QOpenGLTexture::setMaximumLevelOfDetail(float value)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(value > d->minLevelOfDetail);
- d->maxLevelOfDetail = value;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MAX_LOD, value);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(value > d->minLevelOfDetail);
+ d->maxLevelOfDetail = value;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
+ return;
+ }
#else
Q_UNUSED(value);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3041,20 +3243,23 @@ float QOpenGLTexture::maximumLevelOfDetail() const
void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- Q_ASSERT(min < max);
- d->minLevelOfDetail = min;
- d->maxLevelOfDetail = max;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MIN_LOD, min);
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_MAX_LOD, max);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ Q_ASSERT(min < max);
+ d->minLevelOfDetail = min;
+ d->maxLevelOfDetail = max;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
+ return;
+ }
#else
Q_UNUSED(min);
Q_UNUSED(max);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
@@ -3077,16 +3282,19 @@ QPair<float, float> QOpenGLTexture::levelOfDetailRange() const
void QOpenGLTexture::setLevelofDetailBias(float bias)
{
#if !defined(QT_OPENGL_ES_2)
- Q_D(QOpenGLTexture);
- d->create();
- Q_ASSERT(d->texFuncs);
- Q_ASSERT(d->textureId);
- d->levelOfDetailBias = bias;
- d->texFuncs->glTextureParameterf(d->textureId, d->target, GL_TEXTURE_LOD_BIAS, bias);
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QOpenGLTexture);
+ d->create();
+ Q_ASSERT(d->texFuncs);
+ Q_ASSERT(d->textureId);
+ d->levelOfDetailBias = bias;
+ d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
+ return;
+ }
#else
Q_UNUSED(bias);
- qWarning("QOpenGLTexture: Detail level is not supported");
#endif
+ qWarning("QOpenGLTexture: Detail level is not supported");
}
/*!
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index 5c0f8101a6..0c272456f6 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -337,28 +337,53 @@ public:
};
// Pixel transfer
+ // ### Qt 6: remove the non-const void * overloads
+ QT_DEPRECATED void setData(int mipLevel, int layer, CubeMapFace cubeFace,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(int mipLevel,
+ PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setData(PixelFormat sourceFormat, PixelType sourceType,
+ void *data, const QOpenGLPixelTransferOptions * const options = 0);
+
void setData(int mipLevel, int layer, CubeMapFace cubeFace,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(int mipLevel, int layer,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(int mipLevel,
PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
void setData(PixelFormat sourceFormat, PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options = 0);
+ const void *data, const QOpenGLPixelTransferOptions * const options = 0);
// Compressed data upload
+ // ### Qt 6: remove the non-const void * overloads
+ QT_DEPRECATED void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
+ int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int mipLevel, int layer,
+ int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int mipLevel, int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+ QT_DEPRECATED void setCompressedData(int dataSize, void *data,
+ const QOpenGLPixelTransferOptions * const options = 0);
+
void setCompressedData(int mipLevel, int layer, CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
void setCompressedData(int mipLevel, int layer,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
- void setCompressedData(int mipLevel, int dataSize, void *data,
+ void setCompressedData(int mipLevel, int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
- void setCompressedData(int dataSize, void *data,
+ void setCompressedData(int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options = 0);
// Helpful overloads for setData
@@ -379,8 +404,9 @@ public:
AnisotropicFiltering = 0x00000400,
NPOTTextures = 0x00000800,
NPOTTextureRepeat = 0x00001000,
+ Texture1D = 0x00002000,
#ifndef Q_QDOC
- MaxFeatureFlag = 0x00002000
+ MaxFeatureFlag = 0x00004000
#endif
};
Q_DECLARE_FLAGS(Features, Feature)
diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h
index 009561533b..a732805f55 100644
--- a/src/gui/opengl/qopengltexture_p.h
+++ b/src/gui/opengl/qopengltexture_p.h
@@ -89,9 +89,9 @@ public:
void allocateImmutableStorage();
void setData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
- void *data, const QOpenGLPixelTransferOptions * const options);
+ const void *data, const QOpenGLPixelTransferOptions * const options);
void setCompressedData(int mipLevel, int layer, QOpenGLTexture::CubeMapFace cubeFace,
- int dataSize, void *data,
+ int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options);
void setWrapMode(QOpenGLTexture::WrapMode mode);
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
new file mode 100644
index 0000000000..b776444347
--- /dev/null
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureblitter_p.h"
+
+#include <QtGui/QOpenGLBuffer>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLVertexArrayObject>
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+static const char vertex_shader150[] =
+ "#version 150 core\n"
+ "in vec3 vertexCoord;"
+ "in vec2 textureCoord;"
+ "out vec2 uv;"
+ "uniform mat4 vertexTransform;"
+ "uniform mat3 textureTransform;"
+ "void main() {"
+ " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"
+ " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"
+ "}";
+
+static const char fragment_shader150[] =
+ "#version 150 core\n"
+ "in vec2 uv;"
+ "out vec4 fragcolor;"
+ "uniform sampler2D textureSampler;"
+ "uniform bool swizzle;"
+ "void main() {"
+ " if (swizzle) {"
+ " fragcolor = texture(textureSampler, uv).bgra;"
+ " } else {"
+ " fragcolor = texture(textureSampler,uv);"
+ " }"
+ "}";
+
+static const char vertex_shader[] =
+ "attribute highp vec3 vertexCoord;"
+ "attribute highp vec2 textureCoord;"
+ "varying highp vec2 uv;"
+ "uniform highp mat4 vertexTransform;"
+ "uniform highp mat3 textureTransform;"
+ "void main() {"
+ " uv = (textureTransform * vec3(textureCoord,1.0)).xy;"
+ " gl_Position = vertexTransform * vec4(vertexCoord,1.0);"
+ "}";
+
+static const char fragment_shader[] =
+ "varying highp vec2 uv;"
+ "uniform sampler2D textureSampler;"
+ "uniform bool swizzle;"
+ "void main() {"
+ " if (swizzle) {"
+ " gl_FragColor = texture2D(textureSampler, uv).bgra;"
+ " } else {"
+ " gl_FragColor = texture2D(textureSampler,uv);"
+ " }"
+ "}";
+
+static const GLfloat vertex_buffer_data[] = {
+ -1,-1, 0,
+ -1, 1, 0,
+ 1,-1, 0,
+ -1, 1, 0,
+ 1,-1, 0,
+ 1, 1, 0
+};
+
+static const GLfloat texture_buffer_data[] = {
+ 0, 0,
+ 0, 1,
+ 1, 0,
+ 0, 1,
+ 1, 0,
+ 1, 1
+};
+
+class TextureBinder
+{
+public:
+ TextureBinder(GLuint textureId)
+ {
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ }
+ ~TextureBinder()
+ {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+};
+
+class QOpenGLTextureBlitterPrivate
+{
+public:
+ enum TextureMatrixUniform {
+ User,
+ Identity,
+ IdentityFlipped
+ };
+
+ QOpenGLTextureBlitterPrivate()
+ : program(0)
+ , vertexCoordAttribPos(0)
+ , vertexTransformUniformPos(0)
+ , textureCoordAttribPos(0)
+ , textureTransformUniformPos(0)
+ , swizzle(false)
+ , swizzleOld(false)
+ , textureMatrixUniformState(User)
+ , vao(new QOpenGLVertexArrayObject())
+ { }
+
+ void blit(GLuint texture, const QMatrix4x4 &vertexTransform, const QMatrix3x3 &textureTransform);
+ void blit(GLuint texture, const QMatrix4x4 &vertexTransform, QOpenGLTextureBlitter::Origin origin);
+
+ void prepareProgram(const QMatrix4x4 &vertexTransform)
+ {
+ vertexBuffer.bind();
+ program->setAttributeBuffer(vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ program->enableAttributeArray(vertexCoordAttribPos);
+ vertexBuffer.release();
+
+ program->setUniformValue(vertexTransformUniformPos, vertexTransform);
+
+ textureBuffer.bind();
+ program->setAttributeBuffer(textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ program->enableAttributeArray(textureCoordAttribPos);
+ textureBuffer.release();
+
+ if (swizzle != swizzleOld) {
+ program->setUniformValue(swizzleUniformPos, swizzle);
+ swizzleOld = swizzle;
+ }
+ }
+
+ QOpenGLBuffer vertexBuffer;
+ QOpenGLBuffer textureBuffer;
+ QScopedPointer<QOpenGLShaderProgram> program;
+ GLuint vertexCoordAttribPos;
+ GLuint vertexTransformUniformPos;
+ GLuint textureCoordAttribPos;
+ GLuint textureTransformUniformPos;
+ GLuint swizzleUniformPos;
+ bool swizzle;
+ bool swizzleOld;
+ TextureMatrixUniform textureMatrixUniformState;
+ QScopedPointer<QOpenGLVertexArrayObject> vao;
+};
+
+void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
+ const QMatrix4x4 &vertexTransform,
+ const QMatrix3x3 &textureTransform)
+{
+ TextureBinder binder(texture);
+ prepareProgram(vertexTransform);
+
+ program->setUniformValue(textureTransformUniformPos, textureTransform);
+ textureMatrixUniformState = User;
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+void QOpenGLTextureBlitterPrivate::blit(GLuint texture,
+ const QMatrix4x4 &vertexTransform,
+ QOpenGLTextureBlitter::Origin origin)
+{
+ TextureBinder binder(texture);
+ prepareProgram(vertexTransform);
+
+ if (origin == QOpenGLTextureBlitter::OriginTopLeft) {
+ if (textureMatrixUniformState != IdentityFlipped) {
+ QMatrix3x3 flipped;
+ flipped(1,1) = -1;
+ flipped(1,2) = 1;
+ program->setUniformValue(textureTransformUniformPos, flipped);
+ textureMatrixUniformState = IdentityFlipped;
+ }
+ } else if (textureMatrixUniformState != Identity) {
+ program->setUniformValue(textureTransformUniformPos, QMatrix3x3());
+ textureMatrixUniformState = Identity;
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+}
+
+QOpenGLTextureBlitter::QOpenGLTextureBlitter()
+ : d_ptr(new QOpenGLTextureBlitterPrivate)
+{
+}
+
+QOpenGLTextureBlitter::~QOpenGLTextureBlitter()
+{
+}
+
+bool QOpenGLTextureBlitter::create()
+{
+ QOpenGLContext *currentContext = QOpenGLContext::currentContext();
+ if (!currentContext)
+ return false;
+
+ Q_D(QOpenGLTextureBlitter);
+
+ d->vao->create();
+ d->vao->bind();
+
+ if (d->program)
+ return true;
+
+ d->program.reset(new QOpenGLShaderProgram());
+
+ QSurfaceFormat format = currentContext->format();
+
+ if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) {
+ d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader150);
+ d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader150);
+ } else {
+ d->program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertex_shader);
+ d->program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragment_shader);
+ }
+ d->program->link();
+ if (!d->program->isLinked()) {
+ qWarning() << Q_FUNC_INFO << "Could not link shader program:\n" << d->program->log();
+ return false;
+ }
+
+ d->program->bind();
+
+ d->vertexBuffer.create();
+ d->vertexBuffer.bind();
+ d->vertexBuffer.allocate(vertex_buffer_data, sizeof(vertex_buffer_data) * sizeof(vertex_buffer_data[0]));
+ d->vertexBuffer.release();
+
+ d->textureBuffer.create();
+ d->textureBuffer.bind();
+ d->textureBuffer.allocate(texture_buffer_data, sizeof(texture_buffer_data) * sizeof(texture_buffer_data[0]));
+ d->textureBuffer.release();
+
+ d->vertexCoordAttribPos = d->program->attributeLocation("vertexCoord");
+ d->vertexTransformUniformPos = d->program->uniformLocation("vertexTransform");
+ d->textureCoordAttribPos = d->program->attributeLocation("textureCoord");
+ d->textureTransformUniformPos = d->program->uniformLocation("textureTransform");
+ d->swizzleUniformPos = d->program->uniformLocation("swizzle");
+
+ d->program->setUniformValue(d->swizzleUniformPos,false);
+
+ d->vao->release();
+
+ return true;
+}
+
+void QOpenGLTextureBlitter::destroy()
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->program.reset();
+ d->vertexBuffer.destroy();
+ d->textureBuffer.destroy();
+ d->vao.reset();
+}
+
+void QOpenGLTextureBlitter::bind()
+{
+ Q_D(QOpenGLTextureBlitter);
+
+ d->vao->bind();
+
+ d->program->bind();
+
+ d->vertexBuffer.bind();
+ d->program->setAttributeBuffer(d->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0);
+ d->program->enableAttributeArray(d->vertexCoordAttribPos);
+ d->vertexBuffer.release();
+
+ d->textureBuffer.bind();
+ d->program->setAttributeBuffer(d->textureCoordAttribPos, GL_FLOAT, 0, 2, 0);
+ d->program->enableAttributeArray(d->textureCoordAttribPos);
+ d->textureBuffer.release();
+}
+
+void QOpenGLTextureBlitter::release()
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->program->release();
+ d->vao->release();
+}
+
+void QOpenGLTextureBlitter::setSwizzleRB(bool swizzle)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->swizzle = swizzle;
+}
+
+void QOpenGLTextureBlitter::blit(GLuint texture,
+ const QMatrix4x4 &targetTransform,
+ Origin sourceOrigin)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->blit(texture,targetTransform, sourceOrigin);
+}
+
+void QOpenGLTextureBlitter::blit(GLuint texture,
+ const QMatrix4x4 &targetTransform,
+ const QMatrix3x3 &sourceTransform)
+{
+ Q_D(QOpenGLTextureBlitter);
+ d->blit(texture, targetTransform, sourceTransform);
+}
+
+QMatrix4x4 QOpenGLTextureBlitter::targetTransform(const QRectF &target,
+ const QRect &viewport)
+{
+ qreal x_scale = target.width() / viewport.width();
+ qreal y_scale = target.height() / viewport.height();
+
+ const QPointF relative_to_viewport = target.topLeft() - viewport.topLeft();
+ qreal x_translate = x_scale - 1 + ((relative_to_viewport.x() / viewport.width()) * 2);
+ qreal y_translate = -y_scale + 1 - ((relative_to_viewport.y() / viewport.height()) * 2);
+
+ QMatrix4x4 matrix;
+ matrix(0,3) = x_translate;
+ matrix(1,3) = y_translate;
+
+ matrix(0,0) = x_scale;
+ matrix(1,1) = y_scale;
+
+ return matrix;
+}
+
+QMatrix3x3 QOpenGLTextureBlitter::sourceTransform(const QRectF &subTexture,
+ const QSize &textureSize,
+ Origin origin)
+{
+ qreal x_scale = subTexture.width() / textureSize.width();
+ qreal y_scale = subTexture.height() / textureSize.height();
+
+ const QPointF topLeft = subTexture.topLeft();
+ qreal x_translate = topLeft.x() / textureSize.width();
+ qreal y_translate = topLeft.y() / textureSize.height();
+
+ if (origin == OriginTopLeft) {
+ y_scale = -y_scale;
+ y_translate = 1 - y_translate;
+ }
+
+ QMatrix3x3 matrix;
+ matrix(0,2) = x_translate;
+ matrix(1,2) = y_translate;
+
+ matrix(0,0) = x_scale;
+ matrix(1,1) = y_scale;
+
+ return matrix;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
new file mode 100644
index 0000000000..b2ccc13391
--- /dev/null
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLTEXTUREBLITTER_P_H
+#define QOPENGLTEXTUREBLITTER_P_H
+
+#include <QtGui/qopengl.h>
+#include <QtGui/QMatrix3x3>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLTextureBlitterPrivate;
+
+
+class Q_GUI_EXPORT QOpenGLTextureBlitter
+{
+public:
+ QOpenGLTextureBlitter();
+ ~QOpenGLTextureBlitter();
+
+ enum Origin {
+ OriginBottomLeft,
+ OriginTopLeft
+ };
+
+ bool create();
+ void destroy();
+
+ void bind();
+ void release();
+
+ void setSwizzleRB(bool swizzle);
+
+ void blit(GLuint texture, const QMatrix4x4 &targetTransform, Origin sourceOrigin);
+ void blit(GLuint texture, const QMatrix4x4 &targetTransform, const QMatrix3x3 &sourceTransform);
+
+ static QMatrix4x4 targetTransform(const QRectF &target, const QRect &viewport);
+ static QMatrix3x3 sourceTransform(const QRectF &subTexture, const QSize &textureSize, Origin origin);
+
+private:
+ Q_DISABLE_COPY(QOpenGLTextureBlitter);
+ Q_DECLARE_PRIVATE(QOpenGLTextureBlitter);
+ QScopedPointer<QOpenGLTextureBlitterPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif //QOPENGLTEXTUREBLITTER_P_H
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index 3b62d1d63a..0d9a2359bd 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -328,8 +328,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
if (mask.format() == QImage::Format_RGB32
// We need to make the alpha component equal to the average of the RGB values.
// This is needed when drawing sub-pixel antialiased text on translucent targets.
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|| mask.format() == QImage::Format_ARGB32_Premultiplied
+#else
+ || (mask.format() == QImage::Format_ARGB32_Premultiplied
+ && QOpenGLFunctions::isES())
#endif
) {
for (int y = 0; y < maskHeight; ++y) {
@@ -345,10 +348,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
avg = qAlpha(src[x]);
src[x] = qRgba(r, g, b, avg);
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
// swizzle the bits to accommodate for the GL_RGBA upload.
- src[x] = ARGB2RGBA(src[x]);
+#if Q_BYTE_ORDER != Q_BIG_ENDIAN
+ if (QOpenGLFunctions::isES())
#endif
+ src[x] = ARGB2RGBA(src[x]);
}
}
}
@@ -356,11 +360,16 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.depth() == 32) {
-#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
+#ifdef QT_OPENGL_ES_2
+ GLenum fmt = GL_RGBA;
#else
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
+ GLenum fmt = QOpenGLFunctions::isES() ? GL_RGBA : GL_BGRA;
+#endif // QT_OPENGL_ES_2
+
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ fmt = GL_RGBA;
#endif
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits());
} else {
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp
index 676c0802de..1f44a81276 100644
--- a/src/gui/opengl/qopengltexturehelper.cpp
+++ b/src/gui/opengl/qopengltexturehelper.cpp
@@ -42,14 +42,15 @@
#include "qopengltexturehelper_p.h"
#include <QOpenGLContext>
+#include <QOpenGLFunctions>
QT_BEGIN_NAMESPACE
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
{
// Resolve EXT_direct_state_access entry points if present
-#if !defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
+ if (!QOpenGLFunctions::isES()
+ && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT")));
TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));
TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress(QByteArrayLiteral("glTextureParameterfEXT")));
@@ -97,7 +98,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D;
} else {
-#endif
// Use our own DSA emulation
TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri;
TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv;
@@ -119,37 +119,28 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D;
CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D;
CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D;
-#if defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
- TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
- TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
- CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
- CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
- }
-#endif
-
-#if !defined(QT_OPENGL_ES_2)
}
-#endif
// Some DSA functions are part of NV_texture_multisample instead
-#if !defined(QT_OPENGL_ES_2)
- if (context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
+ if (!QOpenGLFunctions::isES()
+ && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV")));
TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV")));
TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample;
} else {
-#endif
TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample;
TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample;
-#if !defined(QT_OPENGL_ES_2)
}
-#endif
+
+ // wglGetProcAddress should not be used to (and indeed will not) load OpenGL <= 1.1 functions.
+ // Hence, we resolve them "the hard way"
#if defined(Q_OS_WIN) && !defined(QT_OPENGL_ES_2)
- HMODULE handle = GetModuleHandleA("opengl32.dll");
+ HMODULE handle = static_cast<HMODULE>(QOpenGLFunctions::platformGLHandle());
+ if (!handle)
+ handle = GetModuleHandleA("opengl32.dll");
// OpenGL 1.0
GetIntegerv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint *)>(GetProcAddress(handle, QByteArrayLiteral("glGetIntegerv")));
@@ -200,18 +191,27 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D")));
#endif
- // OpenGL 1.2
- TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
- TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
+ if (QOpenGLFunctions::isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
+ TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
+ TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
+ CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
+ CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
+ } else {
+ // OpenGL 1.2
+ TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
+ TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
+
+ // OpenGL 1.3
+ CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D")));
+ CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D")));
+ }
// OpenGL 1.3
GetCompressedTexImage = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glGetCompressedTexImage")));
CompressedTexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage1D")));
CompressedTexSubImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage2D")));
- CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D")));
CompressedTexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage1D")));
CompressedTexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage2D")));
- CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D")));
ActiveTexture = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress(QByteArrayLiteral("glActiveTexture")));
// OpenGL 3.0
@@ -233,4 +233,404 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress(QByteArrayLiteral("glTextureView")));
}
+void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameteriEXT(texture, target, pname, param);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterivEXT(texture, target, pname, params);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterfEXT(texture, target, pname, param);
+}
+
+void QOpenGLTextureHelper::dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
+{
+ Q_UNUSED(bindingTarget);
+ TextureParameterfvEXT(texture, target, pname, params);
+}
+
+void QOpenGLTextureHelper::dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
+{
+ Q_UNUSED(bindingTarget);
+ GenerateTextureMipmapEXT(texture, target);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage2DEXT(texture, target, levels, internalFormat, width, height);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage1DEXT(texture, target, levels, internalFormat, width);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ Q_UNUSED(bindingTarget);
+ TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ Q_UNUSED(bindingTarget);
+ TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ Q_UNUSED(bindingTarget);
+ CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameteri(target, pname, param);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameteriv(target, pname, params);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameterf(target, pname, param);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexParameterfv(target, pname, params);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glGenerateMipmap(target);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage3D(target, levels, internalFormat, width, height, depth);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage2D(target, levels, internalFormat, width, height);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage1D(target, levels, internalFormat, width);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
+ GLint oldTexture;
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
+}
+
+void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ // For cubemaps we can't use the standard DSA emulation as it is illegal to
+ // try to bind a texture to one of the cubemap face targets. So we force the
+ // target and binding target to the cubemap values in this case.
+ GLint oldTexture;
+
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
+ break;
+
+ default:
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+ glBindTexture(target, oldTexture);
+ break;
+ }
+}
+
+void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
+void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
+{
+ GLint oldTexture;
+ glGetIntegerv(bindingTarget, &oldTexture);
+ glBindTexture(target, texture);
+ glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
+ glBindTexture(target, oldTexture);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h
index fa4bd8120a..782486b90d 100644
--- a/src/gui/opengl/qopengltexturehelper_p.h
+++ b/src/gui/opengl/qopengltexturehelper_p.h
@@ -59,135 +59,135 @@ class QOpenGLTextureHelper
public:
QOpenGLTextureHelper(QOpenGLContext *context);
- // DSA API
- inline void glTextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
+ // DSA-like API. Will either use real DSA or our emulation
+ inline void glTextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
{
- (this->*TextureParameteri)(texture, target, pname, param);
+ (this->*TextureParameteri)(texture, target, bindingTarget, pname, param);
}
- inline void glTextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
+ inline void glTextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
{
- (this->*TextureParameteriv)(texture, target, pname, params);
+ (this->*TextureParameteriv)(texture, target, bindingTarget, pname, params);
}
- inline void glTextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
+ inline void glTextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
{
- (this->*TextureParameterf)(texture, target, pname, param);
+ (this->*TextureParameterf)(texture, target, bindingTarget, pname, param);
}
- inline void glTextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
+ inline void glTextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
{
- (this->*TextureParameterfv)(texture, target, pname, params);
+ (this->*TextureParameterfv)(texture, target, bindingTarget, pname, params);
}
- inline void glGenerateTextureMipmap(GLuint texture, GLenum target)
+ inline void glGenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
{
- (this->*GenerateTextureMipmap)(texture, target);
+ (this->*GenerateTextureMipmap)(texture, target, bindingTarget);
}
- inline void glTextureStorage3D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth)
{
- (this->*TextureStorage3D)(texture, target, levels, internalFormat, width, height, depth);
+ (this->*TextureStorage3D)(texture, target, bindingTarget, levels, internalFormat, width, height, depth);
}
- inline void glTextureStorage2D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width, GLsizei height)
{
- (this->*TextureStorage2D)(texture, target, levels, internalFormat, width, height);
+ (this->*TextureStorage2D)(texture, target, bindingTarget, levels, internalFormat, width, height);
}
- inline void glTextureStorage1D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
+ inline void glTextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
GLsizei width)
{
- (this->*TextureStorage1D)(texture, target, levels, internalFormat, width);
+ (this->*TextureStorage1D)(texture, target, bindingTarget, levels, internalFormat, width);
}
- inline void glTextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
+ inline void glTextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- (this->*TextureStorage3DMultisample)(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ (this->*TextureStorage3DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, depth, fixedSampleLocations);
}
- inline void glTextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
+ inline void glTextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- (this->*TextureStorage2DMultisample)(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+ (this->*TextureStorage2DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, fixedSampleLocations);
}
- inline void glTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage3D)(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
+ (this->*TextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, format, type, pixels);
}
- inline void glTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage2D)(texture, target, level, internalFormat, width, height, border, format, type, pixels);
+ (this->*TextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, format, type, pixels);
}
- inline void glTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
+ inline void glTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
- (this->*TextureImage1D)(texture, target, level, internalFormat, width, border, format, type, pixels);
+ (this->*TextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, format, type, pixels);
}
- inline void glTextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ inline void glTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ (this->*TextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+ (this->*TextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
}
- inline void glTextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ inline void glTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+ (this->*TextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
+ (this->*TextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, type, pixels);
}
}
- inline void glTextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset,
+ inline void glTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset,
GLsizei width, GLenum format, GLenum type,
const GLvoid *pixels, const QOpenGLPixelTransferOptions * const options = 0)
{
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*TextureSubImage1D)(texture, target, level, xoffset, width, format, type, pixels);
+ (this->*TextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, type, pixels);
setPixelUploadOptions(oldOptions);
} else {
- (this->*TextureSubImage1D)(texture, target, level, xoffset, width, format, type, pixels);
+ (this->*TextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, type, pixels);
}
}
- inline void glTextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
+ inline void glTextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
{
- (this->*TextureImage3DMultisample)(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
+ (this->*TextureImage3DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, depth, fixedSampleLocations);
}
- inline void glTextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
+ inline void glTextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
{
- (this->*TextureImage2DMultisample)(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
+ (this->*TextureImage2DMultisample)(texture, target, bindingTarget, samples, internalFormat, width, height, fixedSampleLocations);
}
- inline void glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLsizei width,
GLenum format, GLsizei imageSize, const GLvoid *bits,
const QOpenGLPixelTransferOptions * const options = 0)
@@ -195,14 +195,14 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage1D)(texture, target, level, xoffset, width, format, imageSize, bits);
+ (this->*CompressedTextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage1D)(texture, target, level, xoffset, width, format, imageSize, bits);
+ (this->*CompressedTextureSubImage1D)(texture, target, bindingTarget, level, xoffset, width, format, imageSize, bits);
}
}
- inline void glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei imageSize, const GLvoid *bits,
@@ -211,14 +211,14 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ (this->*CompressedTextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage2D)(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
+ (this->*CompressedTextureSubImage2D)(texture, target, bindingTarget, level, xoffset, yoffset, width, height, format, imageSize, bits);
}
}
- inline void glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei imageSize, const GLvoid *bits,
@@ -227,443 +227,200 @@ public:
if (options) {
QOpenGLPixelTransferOptions oldOptions = savePixelUploadOptions();
setPixelUploadOptions(*options);
- (this->*CompressedTextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ (this->*CompressedTextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
setPixelUploadOptions(oldOptions);
} else {
- (this->*CompressedTextureSubImage3D)(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
+ (this->*CompressedTextureSubImage3D)(texture, target, bindingTarget, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
}
}
- inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage1D)(texture, target, level, internalFormat, width, border, imageSize, bits);
+ (this->*CompressedTextureImage1D)(texture, target, bindingTarget, level, internalFormat, width, border, imageSize, bits);
}
- inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage2D)(texture, target, level, internalFormat, width, height, border, imageSize, bits);
+ (this->*CompressedTextureImage2D)(texture, target, bindingTarget, level, internalFormat, width, height, border, imageSize, bits);
}
- inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLint level,
+ inline void glCompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei imageSize, const GLvoid *bits)
{
- (this->*CompressedTextureImage3D)(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
+ (this->*CompressedTextureImage3D)(texture, target, bindingTarget, level, internalFormat, width, height, depth, border, imageSize, bits);
}
private:
-#if !defined(QT_OPENGL_ES_2)
// DSA wrapper (so we can use pointer to member function as switch)
- inline void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
- {
- TextureParameteriEXT(texture, target, pname, param);
- }
+ void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
- inline void dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
- {
- TextureParameterivEXT(texture, target, pname, params);
- }
+ void dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
- inline void dsa_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
- {
- TextureParameterfEXT(texture, target, pname, param);
- }
+ void dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
- inline void dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
- {
- TextureParameterfvEXT(texture, target, pname, params);
- }
+ void dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
- inline void dsa_GenerateTextureMipmap(GLuint texture, GLenum target)
- {
- GenerateTextureMipmapEXT(texture, target);
- }
+ void dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget);
- inline void dsa_TextureStorage3D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth)
- {
- TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth);
- }
+ void dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth);
- inline void dsa_TextureStorage2D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width, GLsizei height)
- {
- TextureStorage2DEXT(texture, target, levels, internalFormat, width, height);
- }
+ void dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width, GLsizei height);
- inline void dsa_TextureStorage1D(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat,
- GLsizei width)
- {
- TextureStorage1DEXT(texture, target, levels, internalFormat, width);
- }
+ void dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat,
+ GLsizei width);
- inline void dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
- {
- TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- }
+ void dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- inline void dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat,
- GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
- {
- TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
- }
+ void dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- inline void dsa_TextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
- }
+ void dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels);
- }
+ void dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels);
- }
+ void dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage3D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- }
+ void dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
- }
+ void dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureSubImage1D(GLuint texture, GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
- {
- TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);
- }
+ void dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset,
+ GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
- inline void dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
- {
- TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- }
+ void dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- inline void dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat,
- GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
- {
- TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
- }
+ void dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat,
+ GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- inline void dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
- }
+ void dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits);
- }
+ void dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits);
- }
+ void dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
- inline void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLint level,
- GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLsizei imageSize, const GLvoid *bits)
- {
- CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
- }
-#endif
+ void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLsizei imageSize, const GLvoid *bits);
+ // DSA emulation API
+ void qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
- // DSA-like API
- inline void qt_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameteri(target, pname, param);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
- inline void qt_TextureParameteriv(GLuint texture, GLenum target, GLenum pname, const GLint *params)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameteriv(target, pname, params);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
- inline void qt_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameterf(target, pname, param);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
- inline void qt_TextureParameterfv(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexParameterfv(target, pname, params);
- glBindTexture(target, oldTexture);
- }
+ void qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget);
- inline void qt_GenerateTextureMipmap(GLuint texture, GLenum target)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glGenerateMipmap(target);
- glBindTexture(target, oldTexture);
- }
-
- inline void qt_TextureStorage3D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage3D(target, levels, internalFormat, width, height, depth);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
- inline void qt_TextureStorage2D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width, GLsizei height)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage2D(target, levels, internalFormat, width, height);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height);
- inline void qt_TextureStorage1D(GLuint texture, GLenum target, GLsizei levels,
- GLenum internalFormat, GLsizei width)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage1D(target, levels, internalFormat, width);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels,
+ GLenum internalFormat, GLsizei width);
- inline void qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLsizei depth, GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations);
- inline void qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLenum internalFormat, GLsizei width, GLsizei height,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLboolean fixedSampleLocations);
- inline void qt_TextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border, GLenum format, GLenum type,
- const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels);
- inline void qt_TextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width,
- GLenum format, GLenum type, const GLvoid *pixels)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type, const GLvoid *pixels);
- inline void qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth,
+ GLboolean fixedSampleLocations);
- inline void qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLsizei samples,
- GLint internalFormat, GLsizei width, GLsizei height,
- GLboolean fixedSampleLocations)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
- glBindTexture(target, oldTexture);
- }
+ void qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples,
+ GLint internalFormat, GLsizei width, GLsizei height,
+ GLboolean fixedSampleLocations);
- inline void qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
- inline void qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLint level, GLenum internalFormat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *bits)
- {
- GLint oldTexture;
- glGetIntegerv(target, &oldTexture);
- glBindTexture(target, texture);
- glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
- glBindTexture(target, oldTexture);
- }
+ void qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *bits);
public:
// Raw OpenGL functions, resolved and used by our DSA-like static functions if no EXT_direct_state_access is available
@@ -936,31 +693,33 @@ public:
}
private:
- // Typedefs and pointers to member functions used to switch between EXT_direct_state_access and our own emulated DSA
- typedef void (QOpenGLTextureHelper::*TextureParameteriMemberFunc)(GLuint texture, GLenum target, GLenum pname, GLint param);
- typedef void (QOpenGLTextureHelper::*TextureParameterivMemberFunc)(GLuint texture, GLenum target, GLenum pname, const GLint *params);
- typedef void (QOpenGLTextureHelper::*TextureParameterfMemberFunc)(GLuint texture, GLenum target, GLenum pname, GLfloat param);
- typedef void (QOpenGLTextureHelper::*TextureParameterfvMemberFunc)(GLuint texture, GLenum target, GLenum pname, const GLfloat *params);
- typedef void (QOpenGLTextureHelper::*GenerateTextureMipmapMemberFunc)(GLuint texture, GLenum target);
- typedef void (QOpenGLTextureHelper::*TextureStorage3DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
- typedef void (QOpenGLTextureHelper::*TextureStorage2DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
- typedef void (QOpenGLTextureHelper::*TextureStorage1DMemberFunc)(GLuint texture, GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width);
- typedef void (QOpenGLTextureHelper::*TextureStorage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureStorage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
- typedef void (QOpenGLTextureHelper::*TextureImage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*TextureImage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage1DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage2DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
- typedef void (QOpenGLTextureHelper::*CompressedTextureImage3DMemberFunc)(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
+ // Typedefs and pointers to member functions used to switch between EXT_direct_state_access and our own emulated DSA.
+ // The argument match the corresponding GL function, but there's an extra "GLenum bindingTarget" which gets used with
+ // the DSA emulation -- it contains the right GL_BINDING_TEXTURE_X to use.
+ typedef void (QOpenGLTextureHelper::*TextureParameteriMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
+ typedef void (QOpenGLTextureHelper::*TextureParameterivMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params);
+ typedef void (QOpenGLTextureHelper::*TextureParameterfMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param);
+ typedef void (QOpenGLTextureHelper::*TextureParameterfvMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params);
+ typedef void (QOpenGLTextureHelper::*GenerateTextureMipmapMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget);
+ typedef void (QOpenGLTextureHelper::*TextureStorage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth);
+ typedef void (QOpenGLTextureHelper::*TextureStorage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height);
+ typedef void (QOpenGLTextureHelper::*TextureStorage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width);
+ typedef void (QOpenGLTextureHelper::*TextureStorage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureStorage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+ typedef void (QOpenGLTextureHelper::*TextureImage3DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*TextureImage2DMultisampleMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureSubImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage1DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage2DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits);
+ typedef void (QOpenGLTextureHelper::*CompressedTextureImage3DMemberFunc)(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits);
TextureParameteriMemberFunc TextureParameteri;
@@ -988,7 +747,6 @@ private:
CompressedTextureImage2DMemberFunc CompressedTextureImage2D;
CompressedTextureImage3DMemberFunc CompressedTextureImage3D;
-#if !defined(QT_OPENGL_ES_2)
// Raw function pointers for core and DSA functions
// EXT_direct_state_access used when DSA is available
@@ -1019,7 +777,6 @@ private:
// Plus some missing ones that are in the NV_texture_multisample extension instead
void (QOPENGLF_APIENTRYP TextureImage3DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
void (QOPENGLF_APIENTRYP TextureImage2DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
-#endif
// OpenGL 1.0
void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params);
diff --git a/src/gui/opengl/qopengltimerquery.cpp b/src/gui/opengl/qopengltimerquery.cpp
index c5c3d42e5d..deb88b7778 100644
--- a/src/gui/opengl/qopengltimerquery.cpp
+++ b/src/gui/opengl/qopengltimerquery.cpp
@@ -44,6 +44,7 @@
#include "qopenglqueryhelper_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
QT_BEGIN_NAMESPACE
@@ -123,6 +124,11 @@ public:
bool QOpenGLTimerQueryPrivate::create()
{
+ if (QOpenGLFunctions::isES()) {
+ qWarning("QOpenGLTimerQuery: Not supported on dynamic GL ES");
+ return false;
+ }
+
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (timer && context == ctx)
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index ee8abde77b..e26c6ec25a 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -43,6 +43,7 @@
#include <QtCore/private/qobject_p.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
#if !defined(QT_OPENGL_ES_2)
#include <QtGui/qopenglfunctions_3_0.h>
@@ -156,6 +157,13 @@ bool QOpenGLVertexArrayObjectPrivate::create()
return false;
}
+#if !defined(QT_OPENGL_ES_2)
+ if (QOpenGLFunctions::isES()) {
+ qWarning("QOpenGLVertexArrayObject: Not supported on dynamic GL ES");
+ return false;
+ }
+#endif
+
Q_Q(QOpenGLVertexArrayObject);
if (context)
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index aadcc0f686..6bf80eddbd 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -87,14 +87,15 @@ SOURCES += \
painting/qpaintbuffer.cpp \
painting/qpathsimplifier.cpp
-SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
-SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+contains(QT_CPU_FEATURES.$$QT_ARCH, sse2) {
+ SOURCES += painting/qdrawhelper_sse2.cpp
+ SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
+}
IWMMXT_SOURCES += painting/qdrawhelper_iwmmxt.cpp
-AVX_SOURCES += painting/qdrawhelper_avx.cpp
-!ios {
- NEON_SOURCES += painting/qdrawhelper_neon.cpp
- NEON_HEADERS += painting/qdrawhelper_neon_p.h
+!ios:contains(QT_CPU_FEATURES.$$QT_ARCH, neon) {
+ SOURCES += painting/qdrawhelper_neon.cpp
+ HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
}
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 8bbe6b6f42..b35fa38ce0 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -56,44 +56,49 @@ QT_BEGIN_NAMESPACE
const uchar *qt_patternForBrush(int brushStyle, bool invert)
{
Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
- if(invert) {
- static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
- static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar hor_pat[] = { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 };
- static const uchar ver_pat[] = { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 };
- static const uchar cross_pat[] = { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 };
- static const uchar bdiag_pat[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- static const uchar fdiag_pat[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
- static const uchar dcross_pat[] = { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
- }
- static const uchar dense1_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
- static const uchar dense2_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
- static const uchar dense3_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
- static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
- static const uchar dense5_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
- static const uchar dense6_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
- static const uchar dense7_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
- static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff };
- static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
- static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef };
- static const uchar bdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
- static const uchar fdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
- static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
- static const uchar *const pat_tbl[] = {
- dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
- dense6_pat, dense7_pat,
- hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
- return pat_tbl[brushStyle - Qt::Dense1Pattern];
+ static const uchar pat_tbl[][2][8] = {
+ {
+ /* dense1 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ /*~dense1 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ }, {
+ /* dense2 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ /*~dense2 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ }, {
+ /* dense3 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ /*~dense3 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ }, {
+ /* dense4 */ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+ /*~dense4 */ { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 },
+ }, {
+ /* dense5 */ { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee },
+ /*~dense5 */ { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 },
+ }, {
+ /* dense6 */ { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff },
+ /*~dense6 */ { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
+ }, {
+ /* dense7 */ { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff },
+ /*~dense7 */ { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 },
+ }, {
+ /* hor */ { 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff },
+ /*~hor */ { 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 },
+ }, {
+ /* ver */ { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef },
+ /*~ver */ { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* cross */ { 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef, 0xef },
+ /*~cross */ { 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0x10 },
+ }, {
+ /* bdiag */ { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe },
+ /*~bdiag */ { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 },
+ }, {
+ /* fdiag */ { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f },
+ /*~fdiag */ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
+ }, {
+ /* dcross */ { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e },
+ /*~dcross */ { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 },
+ },
+ };
+ return pat_tbl[brushStyle - Qt::Dense1Pattern][invert];
}
QPixmap qt_pixmapForBrush(int brushStyle, bool invert)
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index 706273c151..b9d3ca888e 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -2499,6 +2499,41 @@ QDataStream &operator>>(QDataStream &stream, QColor &color)
}
#endif // QT_NO_DATASTREAM
+// A table of precalculated results of 0x00ff00ff/alpha use by qUnpremultiply:
+const uint qt_inv_premul_factor[256] = {
+ 0, 16711935, 8355967, 5570645, 4177983, 3342387, 2785322, 2387419,
+ 2088991, 1856881, 1671193, 1519266, 1392661, 1285533, 1193709, 1114129,
+ 1044495, 983055, 928440, 879575, 835596, 795806, 759633, 726605,
+ 696330, 668477, 642766, 618960, 596854, 576273, 557064, 539094,
+ 522247, 506422, 491527, 477483, 464220, 451673, 439787, 428511,
+ 417798, 407608, 397903, 388649, 379816, 371376, 363302, 355573,
+ 348165, 341059, 334238, 327685, 321383, 315319, 309480, 303853,
+ 298427, 293191, 288136, 283253, 278532, 273966, 269547, 265268,
+ 261123, 257106, 253211, 249431, 245763, 242201, 238741, 235379,
+ 232110, 228930, 225836, 222825, 219893, 217038, 214255, 211543,
+ 208899, 206320, 203804, 201348, 198951, 196611, 194324, 192091,
+ 189908, 187774, 185688, 183647, 181651, 179698, 177786, 175915,
+ 174082, 172287, 170529, 168807, 167119, 165464, 163842, 162251,
+ 160691, 159161, 157659, 156186, 154740, 153320, 151926, 150557,
+ 149213, 147893, 146595, 145321, 144068, 142837, 141626, 140436,
+ 139266, 138115, 136983, 135869, 134773, 133695, 132634, 131590,
+ 130561, 129549, 128553, 127572, 126605, 125653, 124715, 123792,
+ 122881, 121984, 121100, 120229, 119370, 118524, 117689, 116866,
+ 116055, 115254, 114465, 113686, 112918, 112160, 111412, 110675,
+ 109946, 109228, 108519, 107818, 107127, 106445, 105771, 105106,
+ 104449, 103800, 103160, 102527, 101902, 101284, 100674, 100071,
+ 99475, 98887, 98305, 97730, 97162, 96600, 96045, 95496,
+ 94954, 94417, 93887, 93362, 92844, 92331, 91823, 91322,
+ 90825, 90334, 89849, 89368, 88893, 88422, 87957, 87497,
+ 87041, 86590, 86143, 85702, 85264, 84832, 84403, 83979,
+ 83559, 83143, 82732, 82324, 81921, 81521, 81125, 80733,
+ 80345, 79961, 79580, 79203, 78829, 78459, 78093, 77729,
+ 77370, 77013, 76660, 76310, 75963, 75619, 75278, 74941,
+ 74606, 74275, 73946, 73620, 73297, 72977, 72660, 72346,
+ 72034, 71725, 71418, 71114, 70813, 70514, 70218, 69924,
+ 69633, 69344, 69057, 68773, 68491, 68211, 67934, 67659,
+ 67386, 67116, 66847, 66581, 66317, 66055, 65795, 65537
+};
/*****************************************************************************
QColor global functions (documentation only)
@@ -2581,6 +2616,26 @@ QDataStream &operator>>(QDataStream &stream, QColor &color)
*/
/*!
+ \fn QRgb qPremultiply(QRgb rgb)
+ \since 5.3
+ \relates QColor
+
+ Converts an unpremultiplied ARGB quadruplet \a rgb into a premultiplied ARGB quadruplet.
+
+ \sa qUnpremultiply()
+*/
+
+/*!
+ \fn QRgb qUnpremultiply(QRgb rgb)
+ \since 5.3
+ \relates QColor
+
+ Converts a premultiplied ARGB quadruplet \a rgb into an unpremultiplied ARGB quadruplet.
+
+ \sa qPremultiply()
+*/
+
+/*!
\fn QColor QColor::convertTo(Spec colorSpec) const
Creates a copy of \e this color in the format specified by \a colorSpec.
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c71d75cf94..66481d4287 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -53,6 +53,13 @@
# endif
#endif
+#include <qglobal.h>
+#ifdef Q_OS_IOS
+// We don't build the NEON drawhelpers as they are implemented partly
+// in GAS syntax assembly, which is not supported by the iOS toolchain.
+#undef __ARM_NEON__
+#endif
+
#include <qstylehints.h>
#include <qguiapplication.h>
#include <qatomic.h>
@@ -84,74 +91,254 @@ enum {
// must be multiple of 4 for easier SIMD implementations
static const int buffer_size = 2048;
+#ifdef Q_COMPILER_CONSTEXPR
+
+template<QImage::Format> Q_DECL_CONSTEXPR uint redWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint redShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint greenWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint greenShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint blueWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint blueShift();
+template<QImage::Format> Q_DECL_CONSTEXPR uint alphaWidth();
+template<QImage::Format> Q_DECL_CONSTEXPR uint alphaShift();
+
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint redWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB16>() { return 11; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB444>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB555>() { return 10; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB666>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_RGB888>() { return 16; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB4444_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8555_Premultiplied>() { return 18; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB8565_Premultiplied>() { return 19; }
+template<> Q_DECL_CONSTEXPR uint redShift<QImage::Format_ARGB6666_Premultiplied>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB16>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB8565_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8555_Premultiplied>() { return 13; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB8565_Premultiplied>() { return 13; }
+template<> Q_DECL_CONSTEXPR uint greenShift<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB16>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB444>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB555>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB666>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_RGB888>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8555_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB8565_Premultiplied>() { return 5; }
+template<> Q_DECL_CONSTEXPR uint blueWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB16>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB444>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB555>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB666>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_RGB888>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB4444_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint blueShift<QImage::Format_ARGB6666_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB4444_Premultiplied>() { return 4; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8555_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB8565_Premultiplied>() { return 8; }
+template<> Q_DECL_CONSTEXPR uint alphaWidth<QImage::Format_ARGB6666_Premultiplied>() { return 6; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB4444_Premultiplied>() { return 12; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8555_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB8565_Premultiplied>() { return 0; }
+template<> Q_DECL_CONSTEXPR uint alphaShift<QImage::Format_ARGB6666_Premultiplied>() { return 18; }
+
+template<QImage::Format> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel();
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB16>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB444>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB555>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB666>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_RGB888>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB4444_Premultiplied>() { return QPixelLayout::BPP16; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8555_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB8565_Premultiplied>() { return QPixelLayout::BPP24; }
+template<> Q_DECL_CONSTEXPR QPixelLayout::BPP bitsPerPixel<QImage::Format_ARGB6666_Premultiplied>() { return QPixelLayout::BPP24; }
+
+
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
+ green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = 0xff000000 | red | green | blue;
+ }
-// To convert in place, let 'dest' and 'src' be the same.
-static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *clut)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = PREMUL(clut[src[i]]);
return buffer;
}
-static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
- const QPixelLayout *, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertARGBPMToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- return src;
+ Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar alphaLeftShift = 8 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar redLeftShift = 8 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenLeftShift = 8 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueLeftShift = 8 - blueWidth<Format>();
+
+ Q_CONSTEXPR uchar alphaRightShift = 2 * alphaWidth<Format>() - 8;
+ Q_CONSTEXPR uchar redRightShift = 2 * redWidth<Format>() - 8;
+ Q_CONSTEXPR uchar greenRightShift = 2 * greenWidth<Format>() - 8;
+ Q_CONSTEXPR uchar blueRightShift = 2 * blueWidth<Format>() - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint alpha = (src[i] >> alphaShift<Format>()) & alphaMask;
+ uint red = (src[i] >> redShift<Format>()) & redMask;
+ uint green = (src[i] >> greenShift<Format>()) & greenMask;
+ uint blue = (src[i] >> blueShift<Format>()) & blueMask;
+
+ alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift);
+ red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift));
+ green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift));
+ blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift));
+ buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue;
+ }
+
+ return buffer;
}
-static const uint *QT_FASTCALL convertRGB16ToARGB32PM(uint *buffer, const uint *src, int count,
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qConvertRgb16To32(src[i]);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
+
+ for (int i = 0; i < count; ++i) {
+ const uint color = qUnpremultiply(src[i]);
+ const uint red = ((color >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((color >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((color >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = red | green | blue;
+ }
return buffer;
}
-static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertRGBFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = PREMUL(src[i]);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
+
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
+
+ for (int i = 0; i < count; ++i) {
+ const uint red = ((src[i] >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((src[i] >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((src[i] >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = red | green | blue;
+ }
return buffer;
}
-static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *)
+template<QImage::Format Format>
+static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
{
- Q_ASSERT(layout->redWidth >= 4);
- Q_ASSERT(layout->greenWidth >= 4);
- Q_ASSERT(layout->blueWidth >= 4);
- Q_ASSERT(layout->alphaWidth == 0);
-
- const uint redMask = ((1 << layout->redWidth) - 1);
- const uint greenMask = ((1 << layout->greenWidth) - 1);
- const uint blueMask = ((1 << layout->blueWidth) - 1);
-
- const uchar redLeftShift = 8 - layout->redWidth;
- const uchar greenLeftShift = 8 - layout->greenWidth;
- const uchar blueLeftShift = 8 - layout->blueWidth;
+ Q_CONSTEXPR uint alphaMask = ((1 << alphaWidth<Format>()) - 1);
+ Q_CONSTEXPR uint redMask = ((1 << redWidth<Format>()) - 1);
+ Q_CONSTEXPR uint greenMask = ((1 << greenWidth<Format>()) - 1);
+ Q_CONSTEXPR uint blueMask = ((1 << blueWidth<Format>()) - 1);
- const uchar redRightShift = 2 * layout->redWidth - 8;
- const uchar greenRightShift = 2 * layout->greenWidth - 8;
- const uchar blueRightShift = 2 * layout->blueWidth - 8;
+ Q_CONSTEXPR uchar alphaRightShift = 32 - alphaWidth<Format>();
+ Q_CONSTEXPR uchar redRightShift = 24 - redWidth<Format>();
+ Q_CONSTEXPR uchar greenRightShift = 16 - greenWidth<Format>();
+ Q_CONSTEXPR uchar blueRightShift = 8 - blueWidth<Format>();
for (int i = 0; i < count; ++i) {
- uint red = (src[i] >> layout->redShift) & redMask;
- uint green = (src[i] >> layout->greenShift) & greenMask;
- uint blue = (src[i] >> layout->blueShift) & blueMask;
-
- red = ((red << redLeftShift) | (red >> redRightShift)) << 16;
- green = ((green << greenLeftShift) | (green >> greenRightShift)) << 8;
- blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = 0xff000000 | red | green | blue;
+ const uint alpha = ((src[i] >> alphaRightShift) & alphaMask) << alphaShift<Format>();
+ const uint red = ((src[i] >> redRightShift) & redMask) << redShift<Format>();
+ const uint green = ((src[i] >> greenRightShift) & greenMask) << greenShift<Format>();
+ const uint blue = ((src[i] >> blueRightShift) & blueMask) << blueShift<Format>();
+ buffer[i] = alpha | red | green | blue;
}
-
return buffer;
}
+template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB()
+{
+ return QPixelLayout{
+ redWidth<Format>(), redShift<Format>(),
+ greenWidth<Format>(), greenShift<Format>(),
+ blueWidth<Format>(), blueShift<Format>(),
+ 0, 0,
+ false, bitsPerPixel<Format>(),
+ convertToRGB32<Format>,
+ convertRGBFromARGB32PM<Format>,
+ convertRGBFromRGB32<Format>
+ };
+}
+
+template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutARGBPM()
+{
+ return QPixelLayout{
+ redWidth<Format>(), redShift<Format>(),
+ greenWidth<Format>(), greenShift<Format>(),
+ blueWidth<Format>(), blueShift<Format>(),
+ alphaWidth<Format>(), alphaShift<Format>(),
+ true, bitsPerPixel<Format>(),
+ convertARGBPMToARGB32PM<Format>,
+ convertARGBPMFromARGB32PM<Format>,
+ 0
+ };
+}
+
+#else // CONSTEXPR
+
static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, int count,
const QPixelLayout *layout, const QRgb *)
{
@@ -200,25 +387,42 @@ static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src,
red = (red << redLeftShift) | (red >> redRightShift);
green = (green << greenLeftShift) | (green >> greenRightShift);
blue = (blue << blueLeftShift) | (blue >> blueRightShift);
- buffer[i] = PREMUL((alpha << 24) | (red << 16) | (green << 8) | blue);
+ buffer[i] = qPremultiply((alpha << 24) | (red << 16) | (green << 8) | blue);
}
}
return buffer;
}
-static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
+static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
{
- for (int i = 0; i < count; ++i)
- buffer[i] = qConvertRgb32To16(INV_PREMUL(src[i]));
- return buffer;
-}
+ Q_ASSERT(layout->redWidth >= 4);
+ Q_ASSERT(layout->greenWidth >= 4);
+ Q_ASSERT(layout->blueWidth >= 4);
+ Q_ASSERT(layout->alphaWidth == 0);
-static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *, const QRgb *)
-{
- for (int i = 0; i < count; ++i)
- buffer[i] = INV_PREMUL(src[i]);
+ const uint redMask = ((1 << layout->redWidth) - 1);
+ const uint greenMask = ((1 << layout->greenWidth) - 1);
+ const uint blueMask = ((1 << layout->blueWidth) - 1);
+
+ const uchar redLeftShift = 8 - layout->redWidth;
+ const uchar greenLeftShift = 8 - layout->greenWidth;
+ const uchar blueLeftShift = 8 - layout->blueWidth;
+
+ const uchar redRightShift = 2 * layout->redWidth - 8;
+ const uchar greenRightShift = 2 * layout->greenWidth - 8;
+ const uchar blueRightShift = 2 * layout->blueWidth - 8;
+
+ for (int i = 0; i < count; ++i) {
+ uint red = (src[i] >> layout->redShift) & redMask;
+ uint green = (src[i] >> layout->greenShift) & greenMask;
+ uint blue = (src[i] >> layout->blueShift) & blueMask;
+
+ red = (red << redLeftShift) | (red >> redRightShift);
+ green = (green << greenLeftShift) | (green >> greenRightShift);
+ blue = (blue << blueLeftShift) | (blue >> blueRightShift);
+ buffer[i] = 0xff000000 | (red << 16) | (green << 8) | blue;
+ }
return buffer;
}
@@ -242,7 +446,7 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
if (!layout->premultiplied) {
for (int i = 0; i < count; ++i)
- buffer[i] = qAlpha(src[i]) == 255 ? src[i] : INV_PREMUL(src[i]);
+ buffer[i] = qUnpremultiply(src[i]);
src = buffer;
}
for (int i = 0; i < count; ++i) {
@@ -255,13 +459,14 @@ static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src
return buffer;
}
-static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *src, int count,
- const QPixelLayout *layout, const QRgb *)
+static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *layout, const QRgb *)
{
Q_ASSERT(layout->redWidth <= 8);
Q_ASSERT(layout->greenWidth <= 8);
Q_ASSERT(layout->blueWidth <= 8);
Q_ASSERT(layout->alphaWidth == 0);
+ Q_ASSERT(!layout->premultiplied);
const uint redMask = (1 << layout->redWidth) - 1;
const uint greenMask = (1 << layout->greenWidth) - 1;
@@ -272,16 +477,118 @@ static const uint *QT_FASTCALL convertRGBFromARGB32PM(uint *buffer, const uint *
const uchar blueRightShift = 8 - layout->blueWidth;
for (int i = 0; i < count; ++i) {
- uint color = INV_PREMUL(src[i]);
- uint red = ((color >> redRightShift) & redMask) << layout->redShift;
- uint green = ((color >> greenRightShift) & greenMask) << layout->greenShift;
- uint blue = ((color >> blueRightShift) & blueMask) << layout->blueShift;
- uint alpha = 0xff << layout->alphaShift;
- buffer[i] = red | green | blue | alpha;
+ uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift;
+ uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift;
+ uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift;
+ buffer[i] = red | green | blue;
}
return buffer;
}
+static const uint *QT_FASTCALL convertRGB16ToRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb16To32(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGB16FromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb32To16(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qConvertRgb32To16(qUnpremultiply(src[i]));
+ return buffer;
+}
+#endif
+
+// To convert in place, let 'dest' and 'src' be the same.
+static const uint *QT_FASTCALL convertIndexedToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *clut)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(clut[src[i]]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertPassThrough(uint *, const uint *src, int,
+ const QPixelLayout *, const QRgb *)
+{
+ return src;
+}
+
+static const uint *QT_FASTCALL convertARGB32ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888PMToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = RGBA2ARGB(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888ToARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qPremultiply(RGBA2ARGB(src[i]));
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertARGB32FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = qUnpremultiply(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888PMFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBA8888FromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(qUnpremultiply(src[i]));
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBXFromRGB32(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(0xff000000 | src[i]);
+ return buffer;
+}
+
+static const uint *QT_FASTCALL convertRGBXFromARGB32PM(uint *buffer, const uint *src, int count,
+ const QPixelLayout *, const QRgb *)
+{
+ for (int i = 0; i < count; ++i)
+ buffer[i] = ARGB2RGBA(0xff000000 | qUnpremultiply(src[i]));
+ return buffer;
+}
+
template <QPixelLayout::BPP bpp> static
uint QT_FASTCALL fetchPixel(const uchar *src, int index);
@@ -392,30 +699,44 @@ inline void QT_FASTCALL storePixels<QPixelLayout::BPP32>(uchar *dest, const uint
// convertFromArgb32() assumes that no color channel is more than 8 bits.
// QImage::rgbSwapped() assumes that the red and blue color channels have the same number of bits.
QPixelLayout qPixelLayouts[QImage::NImageFormats] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0 }, // Format_Invalid
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0 }, // Format_Mono
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0 }, // Format_MonoLSB
- { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0 }, // Format_Indexed8
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_RGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM }, // Format_ARGB32
- { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough }, // Format_ARGB32_Premultiplied
- { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToARGB32PM, convertRGB16FromARGB32PM }, // Format_RGB16
- { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8565_Premultiplied
- { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB666
- { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB6666_Premultiplied
- { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB555
- { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB8555_Premultiplied
- { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM }, // Format_RGB888
- { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM }, // Format_RGB444
- { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM }, // Format_ARGB4444_Premultiplied
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPPNone, 0, 0, 0 }, // Format_Invalid
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1MSB, convertIndexedToARGB32PM, 0, 0 }, // Format_Mono
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP1LSB, convertIndexedToARGB32PM, 0, 0 }, // Format_MonoLSB
+ { 0, 0, 0, 0, 0, 0, 0, 0, false, QPixelLayout::BPP8, convertIndexedToARGB32PM, 0, 0 }, // Format_Indexed8
+ // Technically using convertPassThrough to convert from ARGB32PM to RGB32 is wrong,
+ // but everywhere this generic conversion would be wrong is currently overloaed.
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, convertPassThrough }, // Format_RGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, false, QPixelLayout::BPP32, convertARGB32ToARGB32PM, convertARGB32FromARGB32PM, 0 }, // Format_ARGB32
+ { 8, 16, 8, 8, 8, 0, 8, 24, true, QPixelLayout::BPP32, convertPassThrough, convertPassThrough, 0 }, // Format_ARGB32_Premultiplied
+#ifdef Q_COMPILER_CONSTEXPR
+ pixelLayoutRGB<QImage::Format_RGB16>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8565_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB666>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB6666_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB555>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB8555_Premultiplied>(),
+ pixelLayoutRGB<QImage::Format_RGB888>(),
+ pixelLayoutRGB<QImage::Format_RGB444>(),
+ pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(),
+#else
+ { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToRGB32, convertRGB16FromARGB32PM, convertRGB16FromRGB32 }, // Format_RGB16
+ { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8565_Premultiplied
+ { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB666
+ { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB6666_Premultiplied
+ { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB555
+ { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB8555_Premultiplied
+ { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB888
+ { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB444
+ { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, 0 }, // Format_ARGB4444_Premultiplied
+#endif
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
- { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888
- { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888_Premultiplied
+ { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888
+ { 8, 24, 8, 16, 8, 8, 8, 0, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 }, // Format_RGBA8888_Premultiplied
#else
- { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertToRGB32, convertRGBFromARGB32PM }, // Format_RGBX8888
- { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM }, // Format_RGBA8888 (ABGR32)
- { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertToARGB32PM, convertFromARGB32PM } // Format_RGBA8888_Premultiplied
+ { 8, 0, 8, 8, 8, 16, 0, 24, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888
+ { 8, 0, 8, 8, 8, 16, 8, 24, false, QPixelLayout::BPP32, convertRGBA8888ToARGB32PM, convertRGBA8888FromARGB32PM, 0 }, // Format_RGBA8888 (ABGR32)
+ { 8, 0, 8, 8, 8, 16, 8, 24, true, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBA8888PMFromARGB32PM, 0 } // Format_RGBA8888_Premultiplied
#endif
};
@@ -532,9 +853,9 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] =
*/
static inline QRgb findNearestColor(QRgb color, QRasterBuffer *rbuf)
{
- QRgb color_0 = PREMUL(rbuf->destColor0);
- QRgb color_1 = PREMUL(rbuf->destColor1);
- color = PREMUL(color);
+ QRgb color_0 = qPremultiply(rbuf->destColor0);
+ QRgb color_1 = qPremultiply(rbuf->destColor1);
+ color = qPremultiply(color);
int r = qRed(color);
int g = qGreen(color);
@@ -630,7 +951,12 @@ static void QT_FASTCALL destStore(QRasterBuffer *rasterBuffer, int x, int y, con
uchar *dest = rasterBuffer->scanLine(y);
while (length) {
int l = qMin(length, buffer_size);
- const uint *ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0);
+ const uint *ptr = 0;
+ if (layout->convertFromRGB32) {
+ Q_ASSERT(!layout->premultiplied && !layout->alphaWidth);
+ ptr = layout->convertFromRGB32(buf, buffer, l, layout, 0);
+ } else
+ ptr = layout->convertFromARGB32PM(buf, buffer, l, layout, 0);
store(dest, ptr, x, l);
length -= l;
buffer += l;
@@ -891,7 +1217,7 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
{
uint distxy = distx * disty;
//idistx * disty = (16-distx) * disty = 16*disty - distxy
- //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*dity + distxy
+ //idistx * idisty = (16-distx) * (16-disty) = 16*16 - 16*distx -16*disty + distxy
uint tlrb = (tl & 0x00ff00ff) * (16*16 - 16*distx - 16*disty + distxy);
uint tlag = ((tl & 0xff00ff00) >> 8) * (16*16 - 16*distx - 16*disty + distxy);
uint trrb = ((tr & 0x00ff00ff) * (distx*16 - distxy));
@@ -973,6 +1299,44 @@ static inline uint interpolate_4_pixels_16(uint tl, uint tr, uint bl, uint br, i
}
#endif
+#if defined(__SSE2__)
+static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
+{
+ // First interpolate right and left pixels in parallel.
+ __m128i vl = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tl), _mm_cvtsi32_si128(bl));
+ __m128i vr = _mm_unpacklo_epi32(_mm_cvtsi32_si128(tr), _mm_cvtsi32_si128(br));
+ vl = _mm_unpacklo_epi8(vl, _mm_setzero_si128());
+ vr = _mm_unpacklo_epi8(vr, _mm_setzero_si128());
+ vl = _mm_mullo_epi16(vl, _mm_set1_epi16(256 - distx));
+ vr = _mm_mullo_epi16(vr, _mm_set1_epi16(distx));
+ __m128i vtb = _mm_add_epi16(vl, vr);
+ vtb = _mm_srli_epi16(vtb, 8);
+ // vtb now contains the result of the first two interpolate calls vtb = unpacked((xbot << 64) | xtop)
+
+ // Now the last interpolate between top and bottom interpolations.
+ const __m128i vidisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(256 - disty), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vdisty = _mm_shufflelo_epi16(_mm_cvtsi32_si128(disty), _MM_SHUFFLE(0, 0, 0, 0));
+ const __m128i vmuly = _mm_unpacklo_epi16(vidisty, vdisty);
+ vtb = _mm_unpacklo_epi16(vtb, _mm_srli_si128(vtb, 8));
+ // vtb now contains the colors of top and bottom interleaved { ta, ba, tr, br, tg, bg, tb, bb }
+ vtb = _mm_madd_epi16(vtb, vmuly); // Multiply and horizontal add.
+ vtb = _mm_srli_epi32(vtb, 8);
+ vtb = _mm_packs_epi32(vtb, _mm_setzero_si128());
+ vtb = _mm_packus_epi16(vtb, _mm_setzero_si128());
+ return _mm_cvtsi128_si32(vtb);
+}
+#else
+static inline uint interpolate_4_pixels(uint tl, uint tr, uint bl, uint br, uint distx, uint disty)
+{
+ uint idistx = 256 - distx;
+ uint idisty = 256 - disty;
+ uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
+ uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
+ return INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+}
+#endif
+
+
template<TextureBlendType blendType>
void fetchTransformedBilinear_pixelBounds(int max, int l1, int l2, int &v1, int &v2);
@@ -1177,7 +1541,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
const uint *s1 = (const uint *)data->texture.scanLine(y1);
const uint *s2 = (const uint *)data->texture.scanLine(y2);
int disty = (fy & 0x0000ffff) >> 8;
- int idisty = 256 - disty;
while (b < end) {
int x1 = (fx >> 16);
int x2;
@@ -1186,13 +1549,8 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
uint tr = s1[x2];
uint bl = s2[x1];
uint br = s2[x2];
-
int distx = (fx & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
-
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
++b;
@@ -1356,12 +1714,8 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
int distx = (fx & 0x0000ffff) >> 8;
int disty = (fy & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
fy += fdy;
@@ -1418,8 +1772,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
int distx = int((px - x1) * 256);
int disty = int((py - y1) * 256);
- int idistx = 256 - distx;
- int idisty = 256 - disty;
fetchTransformedBilinear_pixelBounds<blendType>(image_width, image_x1, image_x2, x1, x2);
fetchTransformedBilinear_pixelBounds<blendType>(image_height, image_y1, image_y2, y1, y2);
@@ -1432,9 +1784,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
uint bl = s2[x1];
uint br = s2[x2];
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- *b = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ *b = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fx += fdx;
fy += fdy;
@@ -1606,17 +1956,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
if ((fdx < 0 && fdx > -(fixed_scale / 8)) || fabs(data->m22) < (1./8.)) { // scale up more than 8x
int disty = (fy & 0x0000ffff) >> 8;
- int idisty = 256 - disty;
for (int i = 0; i < len; ++i) {
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
int distx = (fracX & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fracX += fdx;
}
} else { //scale down
@@ -1677,12 +2023,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
int distx = (fracX & 0x0000ffff) >> 8;
int disty = (fracY & 0x0000ffff) >> 8;
- int idistx = 256 - distx;
- int idisty = 256 - disty;
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
fracX += fdx;
fracY += fdy;
}
@@ -1764,17 +2106,13 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
for (int i = 0; i < len; ++i) {
int distx = distxs[i];
int disty = distys[i];
- int idistx = 256 - distx;
- int idisty = 256 - disty;
uint tl = buf1[i * 2 + 0];
uint tr = buf1[i * 2 + 1];
uint bl = buf2[i * 2 + 0];
uint br = buf2[i * 2 + 1];
- uint xtop = INTERPOLATE_PIXEL_256(tl, idistx, tr, distx);
- uint xbot = INTERPOLATE_PIXEL_256(bl, idistx, br, distx);
- b[i] = INTERPOLATE_PIXEL_256(xtop, idisty, xbot, disty);
+ b[i] = interpolate_4_pixels(tl, tr, bl, br, distx, disty);
}
length -= len;
b += len;
@@ -5071,13 +5409,15 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
int l = qMin(length, buffer_size);
const uint *end = buffer + l;
uint *b = buffer;
+ int px16 = x % (image_width << 16);
+ int py16 = y % (image_height << 16);
+ int px_delta = fdx % (image_width << 16);
+ int py_delta = fdy % (image_height << 16);
while (b < end) {
- int px = x >> 16;
- int py = y >> 16;
- px %= image_width;
- py %= image_height;
- if (px < 0) px += image_width;
- if (py < 0) py += image_height;
+ if (px16 < 0) px16 += image_width << 16;
+ if (py16 < 0) py16 += image_height << 16;
+ int px = px16 >> 16;
+ int py = py16 >> 16;
int y_offset = py * scanline_offset;
Q_ASSERT(px >= 0 && px < image_width);
@@ -5086,6 +5426,12 @@ static void blend_transformed_tiled_argb(int count, const QSpan *spans, void *us
*b = image_bits[y_offset + px];
x += fdx;
y += fdy;
+ px16 += px_delta;
+ if (px16 >= image_width << 16)
+ px16 -= image_width << 16;
+ py16 += py_delta;
+ if (py16 >= image_height << 16)
+ py16 -= image_height << 16;
++b;
}
func(target, buffer, l, coverage);
@@ -5916,7 +6262,7 @@ static void qt_rectfill_nonpremul_argb32(QRasterBuffer *rasterBuffer,
quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- INV_PREMUL(color), x, y, width, height, rasterBuffer->bytesPerLine());
+ qUnpremultiply(color), x, y, width, height, rasterBuffer->bytesPerLine());
}
static void qt_rectfill_rgba(QRasterBuffer *rasterBuffer,
@@ -5932,7 +6278,7 @@ static void qt_rectfill_nonpremul_rgba(QRasterBuffer *rasterBuffer,
quint32 color)
{
qt_rectfill<quint32>(reinterpret_cast<quint32 *>(rasterBuffer->buffer()),
- ARGB2RGBA(INV_PREMUL(color)), x, y, width, height, rasterBuffer->bytesPerLine());
+ ARGB2RGBA(qUnpremultiply(color)), x, y, width, height, rasterBuffer->bytesPerLine());
}
@@ -6140,110 +6486,73 @@ inline void qt_memfill_template(quint16 *dest, quint16 value, int count)
}
#endif
-static void qt_memfill_quint16(quint16 *dest, quint16 color, int count)
+#if !defined(__SSE2__)
+void qt_memfill16(quint16 *dest, quint16 color, int count)
{
qt_memfill_template<quint16>(dest, color, count);
}
-
-typedef void (*qt_memfill32_func)(quint32 *dest, quint32 value, int count);
-typedef void (*qt_memfill16_func)(quint16 *dest, quint16 value, int count);
-static void qt_memfill32_setup(quint32 *dest, quint32 value, int count);
-static void qt_memfill16_setup(quint16 *dest, quint16 value, int count);
-
-qt_memfill32_func qt_memfill32 = qt_memfill32_setup;
-qt_memfill16_func qt_memfill16 = qt_memfill16_setup;
+#endif
+#if !defined(__SSE2__) && !defined(__ARM_NEON__)
+void qt_memfill32(quint32 *dest, quint32 color, int count)
+{
+# ifdef QT_COMPILER_SUPPORTS_MIPS_DSP
+ extern "C" qt_memfill32_asm_mips_dsp(quint32 *, quint32, int);
+ qt_memfill32_asm_mips_dsp(dest, color, count);
+# else
+ qt_memfill_template<quint32>(dest, color, count);
+# endif
+}
+#endif
void qInitDrawhelperAsm()
{
-
- qt_memfill32 = qt_memfill_template<quint32>;
- qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16>;
-
CompositionFunction *functionForModeAsm = 0;
CompositionFunctionSolid *functionForModeSolidAsm = 0;
const uint features = qCpuFeatures();
- if (false) {
- Q_UNUSED(features);
-#ifdef QT_COMPILER_SUPPORTS_AVX
- } else if (features & AVX) {
- qt_memfill32 = qt_memfill32_avx;
- qt_memfill16 = qt_memfill16_avx;
- qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_avx;
- qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_avx;
- qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_avx;
-
- extern void qt_scale_image_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- int const_alpha);
- qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
- qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
- qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_avx;
-#endif
-#endif
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- } else if (features & SSE2) {
- qt_memfill32 = qt_memfill32_sse2;
- qt_memfill16 = qt_memfill16_sse2;
- qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
- qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
-
- extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- const QRectF &targetRect,
- const QRectF &sourceRect,
- const QRect &clip,
- int const_alpha);
- qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
- qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
- qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
-#endif
-#endif
- }
-
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- if (features & SSE2) {
- extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
- extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
-#endif
-
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
-
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
- }
+ Q_UNUSED(features);
+#ifdef __SSE2__
+ qDrawHelper[QImage::Format_RGB32].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
+
+ extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ const QRectF &targetRect,
+ const QRectF &sourceRect,
+ const QRect &clip,
+ int const_alpha);
+ qScaleFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+ qScaleFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_scale_image_argb32_on_argb32_sse2;
+
+ extern void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+ extern void qt_blend_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
+ const uchar *srcPixels, int sbpl,
+ int w, int h,
+ int const_alpha);
+
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_sse2;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_sse2;
+
+ extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length);
+
+ qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2;
#ifdef QT_COMPILER_SUPPORTS_SSSE3
if (features & SSSE3) {
@@ -6254,65 +6563,13 @@ void qInitDrawhelperAsm()
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_ssse3;
-#endif
}
#endif // SSSE3
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (features & AVX) {
- extern void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
- extern void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_avx;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_avx;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_avx;
-#endif
-
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_avx(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
-
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_avx;
- }
-#endif // AVX
-
-#endif // SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_SSE2
- if (features & SSE2) {
- functionForModeAsm = qt_functionForMode_SSE2;
- functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
- }
-#endif
-#ifdef QT_COMPILER_SUPPORTS_AVX
- if (features & AVX) {
- extern void QT_FASTCALL comp_func_SourceOver_avx(uint *destPixels,
- const uint *srcPixels,
- int length,
- uint const_alpha);
- extern void QT_FASTCALL comp_func_solid_SourceOver_avx(uint *destPixels, int length, uint color, uint const_alpha);
- extern void QT_FASTCALL comp_func_Plus_avx(uint *dst, const uint *src, int length, uint const_alpha);
- extern void QT_FASTCALL comp_func_Source_avx(uint *dst, const uint *src, int length, uint const_alpha);
-
- functionForModeAsm[0] = comp_func_SourceOver_avx;
- functionForModeAsm[QPainter::CompositionMode_Source] = comp_func_Source_avx;
- functionForModeAsm[QPainter::CompositionMode_Plus] = comp_func_Plus_avx;
- functionForModeSolidAsm[0] = comp_func_solid_SourceOver_avx;
- }
+ functionForModeAsm = qt_functionForMode_SSE2;
+ functionForModeSolidAsm = qt_functionForModeSolid_SSE2;
#endif // SSE2
#ifdef QT_COMPILER_SUPPORTS_IWMMXT
@@ -6323,45 +6580,42 @@ void qInitDrawhelperAsm()
}
#endif // IWMMXT
-#if defined(QT_COMPILER_SUPPORTS_NEON) && !defined(Q_OS_IOS)
- if (features & NEON) {
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
- qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
+#if defined(__ARM_NEON__) && !defined(Q_OS_IOS)
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_rgb16_neon;
+ qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB16] = qt_blend_rgb16_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_blend_rgb16_on_rgb16_neon;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
- qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
- qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBX8888] = qt_blend_rgb32_on_rgb32_neon;
+ qBlendFunctions[QImage::Format_RGBX8888][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
+ qBlendFunctions[QImage::Format_RGBA8888_Premultiplied][QImage::Format_RGBA8888_Premultiplied] = qt_blend_argb32_on_argb32_neon;
#endif
- qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
- qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
+ qScaleFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_scale_image_argb32_on_rgb16_neon;
+ qScaleFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_scale_image_rgb16_on_rgb16_neon;
- qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
- qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
+ qTransformFunctions[QImage::Format_RGB16][QImage::Format_ARGB32_Premultiplied] = qt_transform_image_argb32_on_rgb16_neon;
+ qTransformFunctions[QImage::Format_RGB16][QImage::Format_RGB16] = qt_transform_image_rgb16_on_rgb16_neon;
- qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
+ qDrawHelper[QImage::Format_RGB16].alphamapBlit = qt_alphamapblit_quint16_neon;
- functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
- functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
- functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
- destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
- destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
+ functionForMode_C[QPainter::CompositionMode_SourceOver] = qt_blend_argb32_on_argb32_scanline_neon;
+ functionForModeSolid_C[QPainter::CompositionMode_SourceOver] = comp_func_solid_SourceOver_neon;
+ functionForMode_C[QPainter::CompositionMode_Plus] = comp_func_Plus_neon;
+ destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon;
+ destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon;
- qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
- qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
- qt_memfill32 = qt_memfill32_neon;
+ qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon;
+ qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon;
- extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
- int y, int x, int length);
+ extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data,
+ int y, int x, int length);
- qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
- }
+ qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon;
#endif
#if defined(QT_COMPILER_SUPPORTS_MIPS_DSP)
@@ -6385,8 +6639,6 @@ void qInitDrawhelperAsm()
functionForModeSolid_C[QPainter::CompositionMode_Xor] = comp_func_solid_XOR_mips_dsp;
functionForModeSolid_C[QPainter::CompositionMode_SourceOut] = comp_func_solid_SourceOut_mips_dsp;
- qt_memfill32 = qt_memfill32_asm_mips_dsp;
-
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_mips_dsp;
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_mips_dsp;
@@ -6427,16 +6679,4 @@ void qInitDrawhelperAsm()
functionForMode = functionForModeAsm;
}
-static void qt_memfill32_setup(quint32 *dest, quint32 value, int count)
-{
- qInitDrawhelperAsm();
- qt_memfill32(dest, value, count);
-}
-
-static void qt_memfill16_setup(quint16 *dest, quint16 value, int count)
-{
- qInitDrawhelperAsm();
- qt_memfill16(dest, value, count);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_avx.cpp b/src/gui/painting/qdrawhelper_avx.cpp
deleted file mode 100644
index 7da6ce6a20..0000000000
--- a/src/gui/painting/qdrawhelper_avx.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Intel Corporation
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qsimd_p.h>
-
-#ifdef QT_COMPILER_SUPPORTS_AVX
-#define QDRAWHELPER_AVX
-
-#ifndef __AVX__
-#error "AVX not enabled in this file, cannot proceed"
-#endif
-
-#define qt_blend_argb32_on_argb32_ssse3 qt_blend_argb32_on_argb32_avx
-#include "qdrawhelper_ssse3.cpp"
-
-//#define qt_blend_argb32_on_argb32_sse2 qt_blend_argb32_on_argb32_avx
-#define qt_blend_rgb32_on_rgb32_sse2 qt_blend_rgb32_on_rgb32_avx
-#define comp_func_SourceOver_sse2 comp_func_SourceOver_avx
-#define comp_func_Plus_sse2 comp_func_Plus_avx
-#define comp_func_Source_sse2 comp_func_Source_avx
-#define comp_func_solid_SourceOver_sse2 comp_func_solid_SourceOver_avx
-#define qt_memfill32_sse2 qt_memfill32_avx
-#define qt_memfill16_sse2 qt_memfill16_avx
-#define qt_bitmapblit32_sse2 qt_bitmapblit32_avx
-#define qt_bitmapblit16_sse2 qt_bitmapblit16_avx
-#define QSimdSse2 QSimdAvx
-#define qt_fetch_radial_gradient_sse2 qt_fetch_radial_gradient_avx
-#define qt_scale_image_argb32_on_argb32_sse2 qt_scale_image_argb32_on_argb32_avx
-
-#include "qdrawhelper_sse2.cpp"
-
-#endif
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index 541b3ef619..a40166d5be 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -43,7 +43,7 @@
#include <private/qblendfunctions_p.h>
#include <private/qmath_p.h>
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
#include <private/qdrawhelper_neon_p.h>
#include <private/qpaintengine_raster_p.h>
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
-void qt_memfill32_neon(quint32 *dest, quint32 value, int count)
+void qt_memfill32(quint32 *dest, quint32 value, int count)
{
const int epilogueSize = count % 16;
if (count >= 16) {
@@ -998,5 +998,5 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Opera
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index 475df639f8..cad6fe22e9 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_COMPILER_SUPPORTS_NEON
+#ifdef __ARM_NEON__
void qt_blend_argb32_on_argb32_neon(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
@@ -139,7 +139,7 @@ void QT_FASTCALL qt_destStoreRGB16_neon(QRasterBuffer *rasterBuffer,
void QT_FASTCALL comp_func_solid_SourceOver_neon(uint *destPixels, int length, uint color, uint const_alpha);
void QT_FASTCALL comp_func_Plus_neon(uint *dst, const uint *src, int length, uint const_alpha);
-#endif // QT_COMPILER_SUPPORTS_NEON
+#endif // __ARM_NEON__
QT_END_NAMESPACE
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 418294c56d..bbeb73f0af 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -171,6 +171,8 @@ extern MemRotateFunc qMemRotateFunctions[QImage::NImageFormats][3];
extern DrawHelper qDrawHelper[QImage::NImageFormats];
void qBlendTexture(int count, const QSpan *spans, void *userData);
+extern void qt_memfill32(quint32 *dest, quint32 value, int count);
+extern void qt_memfill16(quint16 *dest, quint16 value, int count);
typedef void (QT_FASTCALL *CompositionFunction)(uint *Q_DECL_RESTRICT dest, const uint *Q_DECL_RESTRICT src, int length, uint const_alpha);
typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha);
@@ -386,8 +388,6 @@ static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c)
return (b * b) - (4 * a * c);
}
-extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count);
-
template <class RadialFetchFunc> Q_STATIC_TEMPLATE_FUNCTION
const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data,
int y, int x, int length)
@@ -599,14 +599,6 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) {
return (uint(t)) | (uint(t >> 24));
}
-static Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
- t &= 0x000000ff00ff00ff;
- return (uint(t)) | (uint(t >> 24)) | (a << 24);
-}
-
#else // 32-bit versions
static Q_ALWAYS_INLINE uint INTERPOLATE_PIXEL_256(uint x, uint a, uint y, uint b) {
@@ -639,20 +631,9 @@ static Q_ALWAYS_INLINE uint BYTE_MUL(uint x, uint a) {
# pragma pop
#endif
-static Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- uint t = (x & 0xff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff) * a;
- x = (x + ((x >> 8) & 0xff) + 0x80);
- x &= 0xff00;
- x |= t | (a << 24);
- return x;
-}
#endif
+
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
static Q_ALWAYS_INLINE quint32 RGBA2ARGB(quint32 x) {
quint32 rgb = x >> 8;
@@ -691,12 +672,9 @@ static Q_ALWAYS_INLINE uint BYTE_MUL_RGB16_32(uint x, uint a) {
return t;
}
-#define INV_PREMUL(p) \
- (qAlpha(p) == 0 ? 0 : \
- ((qAlpha(p) << 24) \
- | (((255*qRed(p))/ qAlpha(p)) << 16) \
- | (((255*qGreen(p)) / qAlpha(p)) << 8) \
- | ((255*qBlue(p)) / qAlpha(p))))
+// FIXME: Remove when all Qt modules have stopped using PREMUL and INV_PREMUL
+#define PREMUL(x) qPremultiply(x)
+#define INV_PREMUL(p) qUnpremultiply(p)
struct quint24 {
quint24(uint value);
@@ -726,7 +704,6 @@ template<> inline void qt_memfill(quint32 *dest, quint32 color, int count)
template<> inline void qt_memfill(quint16 *dest, quint16 color, int count)
{
- extern void (*qt_memfill16)(quint16 *dest, quint16 value, int count);
qt_memfill16(dest, color, count);
}
@@ -1031,6 +1008,7 @@ struct QPixelLayout
BPP bpp;
ConvertFunc convertToARGB32PM;
ConvertFunc convertFromARGB32PM;
+ ConvertFunc convertFromRGB32;
};
typedef const uint *(QT_FASTCALL *FetchPixelsFunc)(uint *buffer, const uchar *src, int index, int count);
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index a9dc5a7fb7..f5523f7113 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -238,7 +238,7 @@ void QT_FASTCALL comp_func_Source_sse2(uint *dst, const uint *src, int length, u
}
}
-void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
+void qt_memfill32(quint32 *dest, quint32 value, int count)
{
if (count < 7) {
switch (count) {
@@ -259,33 +259,39 @@ void qt_memfill32_sse2(quint32 *dest, quint32 value, int count)
case 12: *dest++ = value; --count;
}
+ const int rest = count & 0x3;
+ if (rest) {
+ switch (rest) {
+ case 3: dest[count - 3] = value;
+ case 2: dest[count - 2] = value;
+ case 1: dest[count - 1] = value;
+ }
+ }
+
int count128 = count / 4;
__m128i *dst128 = reinterpret_cast<__m128i*>(dest);
+ __m128i *end128 = dst128 + count128;
const __m128i value128 = _mm_set_epi32(value, value, value, value);
- int n = (count128 + 3) / 4;
+ while (dst128 + 3 < end128) {
+ _mm_stream_si128(dst128 + 0, value128);
+ _mm_stream_si128(dst128 + 1, value128);
+ _mm_stream_si128(dst128 + 2, value128);
+ _mm_stream_si128(dst128 + 3, value128);
+ dst128 += 4;
+ }
+
switch (count128 & 0x3) {
- case 0: do { _mm_stream_si128(dst128++, value128);
case 3: _mm_stream_si128(dst128++, value128);
case 2: _mm_stream_si128(dst128++, value128);
case 1: _mm_stream_si128(dst128++, value128);
- } while (--n > 0);
- }
-
- const int rest = count & 0x3;
- if (rest) {
- switch (rest) {
- case 3: dest[count - 3] = value;
- case 2: dest[count - 2] = value;
- case 1: dest[count - 1] = value;
- }
}
}
void QT_FASTCALL comp_func_solid_SourceOver_sse2(uint *destPixels, int length, uint color, uint const_alpha)
{
if ((const_alpha & qAlpha(color)) == 255) {
- qt_memfill32_sse2(destPixels, color, length);
+ qt_memfill32(destPixels, color, length);
} else {
if (const_alpha != 255)
color = BYTE_MUL(color, const_alpha);
@@ -397,7 +403,7 @@ CompositionFunction qt_functionForMode_SSE2[numCompositionFunctions] = {
};
#endif
-void qt_memfill16_sse2(quint16 *dest, quint16 value, int count)
+void qt_memfill16(quint16 *dest, quint16 value, int count)
{
if (count < 3) {
switch (count) {
@@ -413,7 +419,7 @@ void qt_memfill16_sse2(quint16 *dest, quint16 value, int count)
}
const quint32 value32 = (value << 16) | value;
- qt_memfill32_sse2(reinterpret_cast<quint32*>(dest), value32, count / 2);
+ qt_memfill32(reinterpret_cast<quint32*>(dest), value32, count / 2);
if (count & 0x1)
dest[count - 1] = value;
diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h
index d64b9cec39..699c586cb0 100644
--- a/src/gui/painting/qdrawhelper_x86_p.h
+++ b/src/gui/painting/qdrawhelper_x86_p.h
@@ -57,9 +57,9 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_COMPILER_SUPPORTS_SSE2
-void qt_memfill32_sse2(quint32 *dest, quint32 value, int count);
-void qt_memfill16_sse2(quint16 *dest, quint16 value, int count);
+#ifdef __SSE2__
+void qt_memfill32(quint32 *dest, quint32 value, int count);
+void qt_memfill16(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
@@ -77,26 +77,7 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl,
extern CompositionFunction qt_functionForMode_SSE2[];
extern CompositionFunctionSolid qt_functionForModeSolid_SSE2[];
-#endif // QT_COMPILER_SUPPORTS_SSE2
-
-#ifdef QT_COMPILER_SUPPORTS_AVX
-void qt_memfill32_avx(quint32 *dest, quint32 value, int count);
-void qt_memfill16_avx(quint16 *dest, quint16 value, int count);
-void qt_bitmapblit32_avx(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
- const uchar *src, int width, int height, int stride);
-void qt_bitmapblit16_avx(QRasterBuffer *rasterBuffer, int x, int y,
- quint32 color,
- const uchar *src, int width, int height, int stride);
-void qt_blend_argb32_on_argb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-void qt_blend_rgb32_on_rgb32_avx(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
- int w, int h,
- int const_alpha);
-#endif // QT_COMPILER_SUPPORTS_AVX
+#endif // __SSE2__
#ifdef QT_COMPILER_SUPPORTS_IWMMXT
void qt_blend_color_argb_iwmmxt(int count, const QSpan *spans, void *userData);
diff --git a/src/gui/painting/qdrawingprimitive_sse2_p.h b/src/gui/painting/qdrawingprimitive_sse2_p.h
index 0e0c06f56c..cdf68b932d 100644
--- a/src/gui/painting/qdrawingprimitive_sse2_p.h
+++ b/src/gui/painting/qdrawingprimitive_sse2_p.h
@@ -44,7 +44,7 @@
#include <private/qsimd_p.h>
-#ifdef QT_COMPILER_SUPPORTS_SSE2
+#ifdef __SSE2__
//
// W A R N I N G
@@ -242,6 +242,6 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
-#endif // QT_COMPILER_SUPPORTS_SSE2
+#endif // __SSE2__
#endif // QDRAWINGPRIMITIVE_SSE2_P_H
diff --git a/src/gui/painting/qemulationpaintengine.cpp b/src/gui/painting/qemulationpaintengine.cpp
index bb87b4fd6e..0fb907b6c5 100644
--- a/src/gui/painting/qemulationpaintengine.cpp
+++ b/src/gui/painting/qemulationpaintengine.cpp
@@ -169,7 +169,7 @@ void QEmulationPaintEngine::drawTextItem(const QPointF &p, const QTextItem &text
{
if (state()->bgMode == Qt::OpaqueMode) {
const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
- QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
+ QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent).toReal());
fillBGRect(rect);
}
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index f855e9e32d..421d706230 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -70,13 +70,11 @@ QTextItemIntCopy::QTextItemIntCopy(const QTextItem &item)
m_item.chars = chars;
m_item.logClusters = logClusters;
- const int size = QGlyphLayout::spaceNeededForGlyphLayout(m_item.glyphs.numGlyphs);
- char *glyphLayoutData = new char[size];
+ char *glyphLayoutData = new char[m_item.glyphs.numGlyphs * QGlyphLayout::SpaceNeeded];
QGlyphLayout glyphs(glyphLayoutData, m_item.glyphs.numGlyphs);
memcpy(glyphs.offsets, m_item.glyphs.offsets, m_item.glyphs.numGlyphs * sizeof(QFixedPoint));
memcpy(glyphs.glyphs, m_item.glyphs.glyphs, m_item.glyphs.numGlyphs * sizeof(glyph_t));
- memcpy(glyphs.advances_x, m_item.glyphs.advances_x, m_item.glyphs.numGlyphs * sizeof(QFixed));
- memcpy(glyphs.advances_y, m_item.glyphs.advances_y, m_item.glyphs.numGlyphs * sizeof(QFixed));
+ memcpy(glyphs.advances, m_item.glyphs.advances, m_item.glyphs.numGlyphs * sizeof(QFixed));
memcpy(glyphs.justifications, m_item.glyphs.justifications, m_item.glyphs.numGlyphs * sizeof(QGlyphJustification));
memcpy(glyphs.attributes, m_item.glyphs.attributes, m_item.glyphs.numGlyphs * sizeof(QGlyphAttributes));
m_item.glyphs = glyphs;
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index f1eaea0f6b..acab08e794 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -387,6 +387,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw
\value OpenGL2
\value PaintBuffer
\value Blitter
+ \value Direct2D Windows only, Direct2D based engine
*/
/*!
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index 18b6d84146..7b928ba5f6 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -207,6 +207,7 @@ public:
OpenGL2,
PaintBuffer,
Blitter,
+ Direct2D,
User = 50, // first user type id
MaxUser = 100 // last user type id
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index bdd0d9cd4c..9a2e49618c 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -1823,7 +1823,7 @@ void QRasterPaintEngine::fillRect(const QRectF &r, const QColor &color)
Q_D(QRasterPaintEngine);
QRasterPaintEngineState *s = state();
- d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
+ d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color.rgba(), s->intOpacity));
if ((d->solid_color_filler.solid.color & 0xff000000) == 0
&& s->composition_mode == QPainter::CompositionMode_SourceOver) {
return;
@@ -2272,7 +2272,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
| ((((color & 0xff00ff00) >> 8) * s->intOpacity) & 0xff00ff00);
break;
default:
- d->solid_color_filler.solid.color = PREMUL(ARGB_COMBINE_ALPHA(color, s->intOpacity));
+ d->solid_color_filler.solid.color = qPremultiply(ARGB_COMBINE_ALPHA(color, s->intOpacity));
break;
}
@@ -3662,7 +3662,7 @@ QImage QRasterBuffer::colorizeBitmap(const QImage &image, const QColor &color)
QImage sourceImage = image.convertToFormat(QImage::Format_MonoLSB);
QImage dest = QImage(sourceImage.size(), QImage::Format_ARGB32_Premultiplied);
- QRgb fg = PREMUL(color.rgba());
+ QRgb fg = qPremultiply(color.rgba());
QRgb bg = 0;
int height = sourceImage.height();
@@ -3702,8 +3702,8 @@ QImage::Format QRasterBuffer::prepare(QImage *image)
drawHelper = qDrawHelper + format;
if (image->depth() == 1 && image->colorTable().size() == 2) {
monoDestinationWithClut = true;
- destColor0 = PREMUL(image->colorTable()[0]);
- destColor1 = PREMUL(image->colorTable()[1]);
+ destColor0 = qPremultiply(image->colorTable()[0]);
+ destColor1 = qPremultiply(image->colorTable()[1]);
}
return format;
@@ -4260,8 +4260,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
}
if (colorInterpolation) {
- first_color = PREMUL(first_color);
- second_color = PREMUL(second_color);
+ first_color = qPremultiply(first_color);
+ second_color = qPremultiply(second_color);
}
int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1));
@@ -4282,7 +4282,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = first_color;
else
- colorTable[i] = PREMUL(first_color);
+ colorTable[i] = qPremultiply(first_color);
}
if (i < second_index) {
@@ -4311,7 +4311,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = color;
else
- colorTable[i] = PREMUL(color);
+ colorTable[i] = qPremultiply(color);
}
}
@@ -4319,7 +4319,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[i] = second_color;
else
- colorTable[i] = PREMUL(second_color);
+ colorTable[i] = qPremultiply(second_color);
}
return;
@@ -4327,7 +4327,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity);
if (stopCount == 1) {
- current_color = PREMUL(current_color);
+ current_color = qPremultiply(current_color);
for (int i = 0; i < size; ++i)
colorTable[i] = current_color;
return;
@@ -4344,7 +4344,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
qreal dpos = 1.5 * incr; // current position in gradient stop list (0 to 1)
// Up to first point
- colorTable[pos++] = PREMUL(current_color);
+ colorTable[pos++] = qPremultiply(current_color);
while (dpos <= begin_pos) {
colorTable[pos] = colorTable[pos - 1];
++pos;
@@ -4366,8 +4366,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
next_color = ARGB_COMBINE_ALPHA(stops[current_stop+1].second.rgba(), opacity);
if (colorInterpolation) {
- current_color = PREMUL(current_color);
- next_color = PREMUL(next_color);
+ current_color = qPremultiply(current_color);
+ next_color = qPremultiply(next_color);
}
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
@@ -4384,7 +4384,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation)
colorTable[pos] = INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist);
else
- colorTable[pos] = PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ colorTable[pos] = qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
++pos;
dpos += incr;
@@ -4408,8 +4408,8 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
if (colorInterpolation) {
if (skip != 1)
- current_color = PREMUL(current_color);
- next_color = PREMUL(next_color);
+ current_color = qPremultiply(current_color);
+ next_color = qPremultiply(next_color);
}
qreal diff = stops[current_stop+1].first - stops[current_stop].first;
@@ -4421,7 +4421,7 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint
}
// After last point
- current_color = PREMUL(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
+ current_color = qPremultiply(ARGB_COMBINE_ALPHA(stops[stopCount - 1].second.rgba(), opacity));
while (pos < size - 1) {
colorTable[pos] = current_color;
++pos;
@@ -4455,7 +4455,7 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode
type = Solid;
QColor c = qbrush_color(brush);
QRgb rgba = c.rgba();
- solid.color = PREMUL(ARGB_COMBINE_ALPHA(rgba, alpha));
+ solid.color = qPremultiply(ARGB_COMBINE_ALPHA(rgba, alpha));
if ((solid.color & 0xff000000) == 0
&& compositionMode == QPainter::CompositionMode_SourceOver) {
type = None;
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 41a2e39fc9..1fc044aa44 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5617,8 +5617,7 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
textItem.glyphs.numGlyphs = glyphCount;
textItem.glyphs.glyphs = const_cast<glyph_t *>(glyphArray);
textItem.glyphs.offsets = positions;
- textItem.glyphs.advances_x = advances.data();
- textItem.glyphs.advances_y = advances.data();
+ textItem.glyphs.advances = advances.data();
textItem.glyphs.justifications = glyphJustifications.data();
textItem.glyphs.attributes = glyphAttributes.data();
@@ -5846,11 +5845,8 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif
int numGlyphs = len;
QVarLengthGlyphLayoutArray glyphs(len);
QFontEngine *fontEngine = d->state->font.d->engineForScript(QChar::Script_Common);
- if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
- glyphs.resize(numGlyphs);
- if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
+ Q_UNREACHABLE();
QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
drawTextItem(p, gf);
@@ -6354,7 +6350,7 @@ void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QText
QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));
if (!extended && state->bgMode == Qt::OpaqueMode) {
- QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
+ QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent).toReal());
q->fillRect(rect, state->bgBrush);
}
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index 156e411154..aa2b9bea54 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1738,8 +1738,8 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QMatrix &matrix) const
//same as qt_polygon_isect_line in qpolygon.cpp
static void qt_painterpath_isect_line(const QPointF &p1,
- const QPointF &p2,
- const QPointF &pos,
+ const QPointF &p2,
+ const QPointF &pos,
int *winding)
{
qreal x1 = p1.x();
@@ -2551,6 +2551,26 @@ QPainterPathStroker::QPainterPathStroker()
}
/*!
+ Creates a new stroker based on \a pen.
+
+ \since 5.3
+ */
+QPainterPathStroker::QPainterPathStroker(const QPen &pen)
+ : d_ptr(new QPainterPathStrokerPrivate)
+{
+ setWidth(pen.widthF());
+ setCapStyle(pen.capStyle());
+ setJoinStyle(pen.joinStyle());
+ setMiterLimit(pen.miterLimit());
+ setDashOffset(pen.dashOffset());
+
+ if (pen.style() == Qt::CustomDashLine)
+ setDashPattern(pen.dashPattern());
+ else
+ setDashPattern(pen.style());
+}
+
+/*!
Destroys the stroker.
*/
QPainterPathStroker::~QPainterPathStroker()
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index e22c1729f3..c922867eb9 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -57,6 +57,7 @@ class QPainterPathPrivate;
struct QPainterPathPrivateDeleter;
class QPainterPathData;
class QPainterPathStrokerPrivate;
+class QPen;
class QPolygonF;
class QRegion;
class QVectorPath;
@@ -243,6 +244,7 @@ class Q_GUI_EXPORT QPainterPathStroker
Q_DECLARE_PRIVATE(QPainterPathStroker)
public:
QPainterPathStroker();
+ QPainterPathStroker(const QPen &pen);
~QPainterPathStroker();
void setWidth(qreal width);
diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp
index 6a3eacd67a..c0b3769c2d 100644
--- a/src/gui/painting/qpen.cpp
+++ b/src/gui/painting/qpen.cpp
@@ -455,15 +455,19 @@ QVector<qreal> QPen::dashPattern() const
switch (d->style) {
case Qt::DashLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dash << space;
break;
case Qt::DotLine:
+ dd->dashPattern.reserve(2);
dd->dashPattern << dot << space;
break;
case Qt::DashDotLine:
+ dd->dashPattern.reserve(4);
dd->dashPattern << dash << space << dot << space;
break;
case Qt::DashDotDotLine:
+ dd->dashPattern.reserve(6);
dd->dashPattern << dash << space << dot << space << dot << space;
break;
default:
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index feec0c7f3d..15459dd748 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -44,6 +44,16 @@
#include <qpixmap.h>
#include <private/qwindow_p.h>
+#include <qopengl.h>
+#include <qopenglcontext.h>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#ifndef QT_NO_OPENGL
+#include <QtGui/private/qopengltextureblitter_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QPlatformBackingStorePrivate
@@ -51,13 +61,109 @@ class QPlatformBackingStorePrivate
public:
QPlatformBackingStorePrivate(QWindow *w)
: window(w)
+#ifndef QT_NO_OPENGL
+ , blitter(0)
+#endif
{
}
+ ~QPlatformBackingStorePrivate()
+ {
+#ifndef QT_NO_OPENGL
+ if (blitter)
+ blitter->destroy();
+ delete blitter;
+#endif
+ }
QWindow *window;
QSize size;
+#ifndef QT_NO_OPENGL
+ mutable GLuint textureId;
+ mutable QSize textureSize;
+ QOpenGLTextureBlitter *blitter;
+#endif
};
+#ifndef QT_NO_OPENGL
+
+struct QBackingstoreTextureInfo
+{
+ GLuint textureId;
+ QRect rect;
+};
+
+Q_DECLARE_TYPEINFO(QBackingstoreTextureInfo, Q_MOVABLE_TYPE);
+
+class QPlatformTextureListPrivate : public QObjectPrivate
+{
+public:
+ QPlatformTextureListPrivate()
+ : locked(false)
+ {
+ }
+
+ QList<QBackingstoreTextureInfo> textures;
+ bool locked;
+};
+
+QPlatformTextureList::QPlatformTextureList(QObject *parent)
+: QObject(*new QPlatformTextureListPrivate, parent)
+{
+}
+
+QPlatformTextureList::~QPlatformTextureList()
+{
+}
+
+int QPlatformTextureList::count() const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.count();
+}
+
+GLuint QPlatformTextureList::textureId(int index) const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.at(index).textureId;
+}
+
+QRect QPlatformTextureList::geometry(int index) const
+{
+ Q_D(const QPlatformTextureList);
+ return d->textures.at(index).rect;
+}
+
+void QPlatformTextureList::lock(bool on)
+{
+ Q_D(QPlatformTextureList);
+ if (on != d->locked) {
+ d->locked = on;
+ emit locked(on);
+ }
+}
+
+bool QPlatformTextureList::isLocked() const
+{
+ Q_D(const QPlatformTextureList);
+ return d->locked;
+}
+
+void QPlatformTextureList::appendTexture(GLuint textureId, const QRect &geometry)
+{
+ Q_D(QPlatformTextureList);
+ QBackingstoreTextureInfo bi;
+ bi.textureId = textureId;
+ bi.rect = geometry;
+ d->textures.append(bi);
+}
+
+void QPlatformTextureList::clear()
+{
+ Q_D(QPlatformTextureList);
+ d->textures.clear();
+}
+#endif // QT_NO_OPENGL
+
/*!
\class QPlatformBackingStore
\since 5.0
@@ -79,6 +185,147 @@ public:
Note that the \a offset parameter is currently unused.
*/
+#ifndef QT_NO_OPENGL
+/*!
+ Flushes the given \a region from the specified \a window onto the
+ screen, and composes it with the specified \a textures.
+
+ The default implementation retrieves the contents using toTexture()
+ and composes using OpenGL. May be reimplemented in subclasses if there
+ is a more efficient native way to do it.
+
+ Note that the \a offset parameter is currently unused.
+ */
+
+void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
+ const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context)
+{
+ Q_UNUSED(offset);
+
+ context->makeCurrent(window);
+ glViewport(0, 0, window->width(), window->height());
+
+ if (!d_ptr->blitter) {
+ d_ptr->blitter = new QOpenGLTextureBlitter;
+ d_ptr->blitter->create();
+ }
+
+ d_ptr->blitter->bind();
+
+ QRect windowRect(QPoint(), window->size());
+ for (int i = 0; i < textures->count(); ++i) {
+ GLuint textureId = textures->textureId(i);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect);
+ d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+
+ GLuint textureId = toTexture(region);
+ if (!textureId)
+ return;
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
+ d_ptr->blitter->setSwizzleRB(true);
+ d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ d_ptr->blitter->setSwizzleRB(false);
+
+ glDisable(GL_BLEND);
+ d_ptr->blitter->release();
+ context->swapBuffers(window);
+}
+
+/*!
+ Implemented in subclasses to return the content of the backingstore as a QImage.
+
+ If QPlatformIntegration::RasterGLSurface is supported, either this function or
+ toTexture() must be implemented.
+
+ \sa toTexture()
+ */
+QImage QPlatformBackingStore::toImage() const
+{
+ return QImage();
+}
+
+/*!
+ May be reimplemented in subclasses to return the content of the
+ backingstore as an OpenGL texture. \a dirtyRegion is the part of the
+ backingstore which may have changed since the last call to this function. The
+ caller of this function must ensure that there is a current context.
+
+ The ownership of the texture is not transferred. The caller must not store
+ the return value between calls, but instead call this function before each use.
+
+ The default implementation returns a cached texture if \a dirtyRegion is
+ empty and the window has not been resized, otherwise it retrieves the
+ content using toImage() and performs a texture upload.
+ */
+
+GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
+{
+ QImage image = toImage();
+ QSize imageSize = image.size();
+ if (imageSize.isEmpty())
+ return 0;
+
+ bool resized = d_ptr->textureSize != imageSize;
+ if (dirtyRegion.isEmpty() && !resized)
+ return d_ptr->textureId;
+
+ if (image.format() != QImage::Format_RGB32 && image.format() != QImage::Format_RGBA8888)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+
+ if (resized) {
+ if (d_ptr->textureId)
+ glDeleteTextures(1, &d_ptr->textureId);
+ glGenTextures(1, &d_ptr->textureId);
+ glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
+#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ }
+#endif
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ const_cast<uchar*>(image.constBits()));
+ d_ptr->textureSize = imageSize;
+ } else {
+ glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
+ QRect imageRect = image.rect();
+ QRect rect = dirtyRegion.boundingRect() & imageRect;
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (rect.width() >= imageRect.width() / 2) {
+ rect.setX(0);
+ rect.setWidth(imageRect.width());
+ }
+
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.copy(rect).constBits());
+ }
+ }
+
+ return d_ptr->textureId;
+}
+#endif // QT_NO_OPENGL
+
/*!
\fn QPaintDevice* QPlatformBackingStore::paintDevice()
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 1b19b2c379..76fd3d40b4 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -52,9 +52,11 @@
//
#include <QtCore/qrect.h>
+#include <QtCore/qobject.h>
#include <QtGui/qwindow.h>
#include <QtGui/qregion.h>
+#include <QtGui/qopengl.h>
QT_BEGIN_NAMESPACE
@@ -65,6 +67,33 @@ class QPoint;
class QImage;
class QPlatformBackingStorePrivate;
class QPlatformWindow;
+class QPlatformTextureList;
+class QPlatformTextureListPrivate;
+class QOpenGLContext;
+
+#ifndef QT_NO_OPENGL
+class Q_GUI_EXPORT QPlatformTextureList : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QPlatformTextureList)
+public:
+ explicit QPlatformTextureList(QObject *parent = 0);
+ ~QPlatformTextureList();
+
+ int count() const;
+ bool isEmpty() const { return count() == 0; }
+ GLuint textureId(int index) const;
+ QRect geometry(int index) const;
+ void lock(bool on);
+ bool isLocked() const;
+
+ void appendTexture(GLuint textureId, const QRect &geometry);
+ void clear();
+
+ Q_SIGNALS:
+ void locked(bool);
+};
+#endif
class Q_GUI_EXPORT QPlatformBackingStore
{
@@ -79,6 +108,11 @@ public:
// 'window' can be a child window, in which case 'region' is in child window coordinates and
// offset is the (child) window's offset in relation to the window surface.
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) = 0;
+#ifndef QT_NO_OPENGL
+ virtual void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset, QPlatformTextureList *textures, QOpenGLContext *context);
+ virtual QImage toImage() const;
+ virtual GLuint toTexture(const QRegion &dirtyRegion) const;
+#endif
virtual void resize(const QSize &size, const QRegion &staticContents) = 0;
diff --git a/src/gui/painting/qrgb.h b/src/gui/painting/qrgb.h
index 3c2bc5b97a..d8e19302d1 100644
--- a/src/gui/painting/qrgb.h
+++ b/src/gui/painting/qrgb.h
@@ -43,6 +43,7 @@
#define QRGB_H
#include <QtCore/qglobal.h>
+#include <QtCore/qprocessordetection.h>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,48 @@ inline Q_DECL_CONSTEXPR int qGray(QRgb rgb) // convert RGB to gra
inline Q_DECL_CONSTEXPR bool qIsGray(QRgb rgb)
{ return qRed(rgb) == qGreen(rgb) && qRed(rgb) == qBlue(rgb); }
+
+#if Q_PROCESSOR_WORDSIZE == 8 // 64-bit version
+inline QRgb qPremultiply(QRgb x)
+{
+ const uint a = qAlpha(x);
+ quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
+ t &= 0x000000ff00ff00ff;
+ return (uint(t)) | (uint(t >> 24)) | (a << 24);
+}
+#else // 32-bit version
+inline QRgb qPremultiply(QRgb x)
+{
+ const uint a = qAlpha(x);
+ uint t = (x & 0xff00ff) * a;
+ t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
+ t &= 0xff00ff;
+
+ x = ((x >> 8) & 0xff) * a;
+ x = (x + ((x >> 8) & 0xff) + 0x80);
+ x &= 0xff00;
+ x |= t | (a << 24);
+ return x;
+}
+#endif
+
+Q_GUI_EXPORT extern const uint qt_inv_premul_factor[];
+
+inline QRgb qUnpremultiply(QRgb p)
+{
+ const uint alpha = qAlpha(p);
+ // Alpha 255 and 0 are the two most common values, which makes them beneficial to short-cut.
+ if (alpha == 255)
+ return p;
+ if (alpha == 0)
+ return 0;
+ // (p*(0x00ff00ff/alpha)) >> 16 == (p*255)/alpha for all p and alpha <= 256.
+ const uint invAlpha = qt_inv_premul_factor[alpha];
+ // We add 0x8000 to get even rounding. The rounding also ensures that qPremultiply(qUnpremultiply(p)) == p for all p.
+ return qRgba((qRed(p)*invAlpha + 0x8000)>>16, (qGreen(p)*invAlpha + 0x8000)>>16, (qBlue(p)*invAlpha + 0x8000)>>16, alpha);
+}
+
QT_END_NAMESPACE
#endif // QRGB_H
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index e584b66a25..f2b88c4692 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -739,13 +739,19 @@ bool qt_fontHasNarrowOutlines(QFontEngine *fontEngine)
if (!fe)
return false;
- QGlyphLayout glyphs;
+ const QChar uc(QLatin1Char('O'));
+
glyph_t glyph;
- glyphs.glyphs = &glyph;
+
+ QGlyphLayout glyphs;
glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
int numGlyphs = 1;
- QChar uc = QLatin1Char('O');
- fe->stringToCMap(&uc, 1, &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly);
+
+ if (!fe->stringToCMap(&uc, 1, &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(numGlyphs == 1);
+
QImage im = fe->alphaMapForGlyph(glyph, QFixed(), QTransform());
Q_ASSERT(fe->ref.load() == 0);
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 49b5a9ba46..83f2d7190b 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -2073,6 +2073,18 @@ QString QFont::toString() const
QString::number((int) rawMode());
}
+/*!
+ Returns the hash value for \a font. If specified, \a seed is used
+ to initialize the hash.
+
+ \relates QFont
+ \since 5.3
+*/
+uint qHash(const QFont &font, uint seed) Q_DECL_NOTHROW
+{
+ return qHash(QFontPrivate::get(font)->request, seed);
+}
+
/*!
Sets this font to match the description \a descrip. The description
@@ -2533,8 +2545,10 @@ bool QFontInfo::fixedPitch() const
QChar ch[2] = { QLatin1Char('i'), QLatin1Char('m') };
QGlyphLayoutArray<2> g;
int l = 2;
- engine->stringToCMap(ch, 2, &g, &l, 0);
- engine->fontDef.fixedPitch = g.advances_x[0] == g.advances_x[1];
+ if (!engine->stringToCMap(ch, 2, &g, &l, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(l == 2);
+ engine->fontDef.fixedPitch = g.advances[0] == g.advances[1];
engine->fontDef.fixedPitchComputed = true;
}
#endif
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index 6d36f7839b..a207a1d60e 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -315,6 +315,8 @@ private:
Q_DECLARE_SHARED(QFont)
+Q_GUI_EXPORT uint qHash(const QFont &font, uint seed = 0) Q_DECL_NOTHROW;
+
inline bool QFont::bold() const
{ return weight() > Normal; }
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index 5b7f918e21..6165554388 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -55,6 +55,7 @@
#include "QtGui/qfont.h"
#include "QtCore/qmap.h"
+#include "QtCore/qhash.h"
#include "QtCore/qobject.h"
#include "QtCore/qstringlist.h"
#include <QtGui/qfontdatabase.h>
@@ -133,6 +134,22 @@ struct QFontDef
}
};
+inline uint qHash(const QFontDef &fd, uint seed = 0) Q_DECL_NOTHROW
+{
+ return qHash(qRound64(fd.pixelSize*10000)) // use only 4 fractional digits
+ ^ qHash(fd.weight)
+ ^ qHash(fd.style)
+ ^ qHash(fd.stretch)
+ ^ qHash(fd.styleHint)
+ ^ qHash(fd.styleStrategy)
+ ^ qHash(fd.ignorePitch)
+ ^ qHash(fd.fixedPitch)
+ ^ qHash(fd.family, seed)
+ ^ qHash(fd.styleName)
+ ^ qHash(fd.hintingPreference)
+ ;
+}
+
class QFontEngineData
{
public:
diff --git a/src/gui/text/qfontdatabase.h b/src/gui/text/qfontdatabase.h
index 708b8cbd58..9986ef6c60 100644
--- a/src/gui/text/qfontdatabase.h
+++ b/src/gui/text/qfontdatabase.h
@@ -167,8 +167,6 @@ private:
friend class QFontPrivate;
friend class QFontDialog;
friend class QFontDialogPrivate;
- friend class QFontEngineMultiXLFD;
- friend class QFontEngineMultiQWS;
friend class QFontEngineMultiQPA;
QFontDatabasePrivate *d;
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index 6f4971e267..1972f5d58c 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -182,10 +182,17 @@ QFontEngine *loadSingleEngine(int script,
QFontCache::Key key(def,script);
QFontEngine *engine = QFontCache::instance()->findEngine(key);
if (!engine) {
- engine = pfdb->fontEngine(def, QChar::Script(script), size->handle);
+ engine = pfdb->fontEngine(def, size->handle);
if (engine) {
- QFontCache::Key key(def,script);
- QFontCache::instance()->instance()->insertEngine(key,engine);
+ // Also check for OpenType tables when using complex scripts
+ if (!engine->supportsScript(QChar::Script(script))) {
+ qWarning(" OpenType support missing for script %d", script);
+ if (engine->ref.load() == 0)
+ delete engine;
+ return 0;
+ }
+
+ QFontCache::instance()->insertEngine(key, engine);
}
}
return engine;
@@ -221,10 +228,10 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
pfMultiEngine->setFallbackFamiliesList(fallbacks);
engine = pfMultiEngine;
- // Cache Multi font engine as well in case we got the FT single
+ // Cache Multi font engine as well in case we got the single
// font engine when we are actually looking for a Multi one
QFontCache::Key key(request, script, 1);
- QFontCache::instance()->instance()->insertEngine(key, engine);
+ QFontCache::instance()->insertEngine(key, engine);
}
return engine;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index 9eea2e786f..14ce5d2396 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -48,6 +48,7 @@
#include "qvarlengtharray.h"
#include <qmath.h>
#include <qendian.h>
+#include <private/qstringiterator_p.h>
#ifdef QT_ENABLE_HARFBUZZ_NG
# include "qharfbuzzng_p.h"
@@ -89,18 +90,48 @@ static HB_Bool hb_stringToGlyphs(HB_Font font, const HB_UChar16 *string, hb_uint
{
QFontEngine *fe = (QFontEngine *)font->userData;
+ const QChar *str = reinterpret_cast<const QChar *>(string);
+
QGlyphLayout qglyphs;
qglyphs.numGlyphs = *numGlyphs;
qglyphs.glyphs = glyphs;
-
- QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (rightToLeft)
- shaperFlags |= QFontEngine::RightToLeft;
-
int nGlyphs = *numGlyphs;
- bool result = fe->stringToCMap(reinterpret_cast<const QChar *>(string), length, &qglyphs, &nGlyphs, shaperFlags);
+ bool result = fe->stringToCMap(str, length, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly);
*numGlyphs = nGlyphs;
+ if (rightToLeft && result && !fe->symbol) {
+ uint glyph_pos = 0;
+ for (uint i = 0; i < length; ++i, ++glyph_pos) {
+ uint ucs4 = str[i].unicode();
+ if (Q_UNLIKELY(QChar::isHighSurrogate(ucs4) && i + 1 < length)) {
+ uint low = str[i + 1].unicode();
+ if (Q_LIKELY(QChar::isLowSurrogate(low))) {
+ ucs4 = QChar::surrogateToUcs4(ucs4, low);
+ ++i;
+ }
+ }
+
+ uint mirrored = QChar::mirroredChar(ucs4);
+ if (Q_UNLIKELY(mirrored != ucs4)) {
+ QChar chars[2];
+ uint numChars = 0;
+ if (Q_UNLIKELY(QChar::requiresSurrogates(mirrored))) {
+ chars[numChars++] = QChar(QChar::highSurrogate(mirrored));
+ chars[numChars++] = QChar(QChar::lowSurrogate(mirrored));
+ } else {
+ chars[numChars++] = QChar(mirrored);
+ }
+
+ qglyphs.numGlyphs = numChars;
+ qglyphs.glyphs = glyphs + glyph_pos;
+ nGlyphs = numChars;
+ if (!fe->stringToCMap(chars, numChars, &qglyphs, &nGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 1);
+ }
+ }
+ }
+
return result;
}
@@ -108,13 +139,10 @@ static void hb_getAdvances(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGl
{
QFontEngine *fe = (QFontEngine *)font->userData;
- QVarLengthArray<QFixed> advances_y(numGlyphs);
-
QGlyphLayout qglyphs;
qglyphs.numGlyphs = numGlyphs;
qglyphs.glyphs = const_cast<glyph_t *>(glyphs);
- qglyphs.advances_x = reinterpret_cast<QFixed *>(advances);
- qglyphs.advances_y = advances_y.data(); // not used
+ qglyphs.advances = reinterpret_cast<QFixed *>(advances);
fe->recalcAdvances(&qglyphs, (flags & HB_ShaperFlag_UseDesignMetrics) ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlags(0));
}
@@ -278,6 +306,10 @@ void *QFontEngine::harfbuzzFont() const
return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
#endif
if (!font_) {
+ HB_Face hbFace = (HB_Face)harfbuzzFace();
+ if (hbFace->font_for_init != 0)
+ q_check_ptr(qHBLoadFace(hbFace));
+
HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
Q_CHECK_PTR(hbFont);
hbFont->klass = &hb_fontClass;
@@ -308,8 +340,6 @@ void *QFontEngine::harfbuzzFace() const
if (!face_) {
HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
Q_CHECK_PTR(hbFace);
- if (hbFace->font_for_init != 0)
- hbFace = qHBLoadFace(hbFace);
hbFace->isSymbolFont = symbol;
face_ = (void *)hbFace;
@@ -349,6 +379,8 @@ bool QFontEngine::supportsScript(QChar::Script script) const
}
#endif
HB_Face hbFace = (HB_Face)harfbuzzFace();
+ if (hbFace->font_for_init != 0)
+ q_check_ptr(qHBLoadFace(hbFace));
return hbFace->supported_scripts[script_to_hbscript(script)];
}
@@ -364,23 +396,39 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix
QFixed QFontEngine::xHeight() const
{
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
QChar x((ushort)'x');
- stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly);
- glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);
return bb.height;
}
QFixed QFontEngine::averageCharWidth() const
{
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
QChar x((ushort)'x');
- stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly);
- glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&x, 1, &glyphs, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph);
return bb.xoff;
}
@@ -411,8 +459,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
while(i--) {
if (glyphs.attributes[i].dontPrint)
continue;
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
totalKashidas += glyphs.justifications[i].nKashidas;
}
positions.resize(glyphs.numGlyphs+totalKashidas);
@@ -424,8 +471,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
++i;
continue;
}
- xpos -= glyphs.advances_x[i];
- ypos -= glyphs.advances_y[i];
+ xpos -= glyphs.advances[i];
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@@ -441,12 +487,22 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
++current;
if (glyphs.justifications[i].nKashidas) {
QChar ch(0x640); // Kashida character
- QGlyphLayoutArray<8> g;
- int nglyphs = 7;
- stringToCMap(&ch, 1, &g, &nglyphs, 0);
+
+ glyph_t kashidaGlyph;
+ QFixed kashidaWidth;
+
+ QGlyphLayout g;
+ g.numGlyphs = 1;
+ g.glyphs = &kashidaGlyph;
+ g.advances = &kashidaWidth;
+
+ int nglyphs = 1;
+ if (!stringToCMap(&ch, 1, &g, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
for (uint k = 0; k < glyphs.justifications[i].nKashidas; ++k) {
- xpos -= g.advances_x[0];
- ypos -= g.advances_y[0];
+ xpos -= kashidaWidth;
QFixed gpos_x = xpos + glyphs.offsets[i].x;
QFixed gpos_y = ypos + glyphs.offsets[i].y;
@@ -458,7 +514,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
}
positions[current].x = gpos_x;
positions[current].y = gpos_y;
- glyphs_out[current] = g.glyphs[0];
+ glyphs_out[current] = kashidaGlyph;
++current;
}
} else {
@@ -476,8 +532,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = xpos + glyphs.offsets[i].x;
positions[current].y = ypos + glyphs.offsets[i].y;
glyphs_out[current] = glyphs.glyphs[i];
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@@ -492,8 +547,7 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform
positions[current].x = QFixed::fromReal(gpos.x());
positions[current].y = QFixed::fromReal(gpos.y());
glyphs_out[current] = glyphs.glyphs[i];
- xpos += glyphs.advances_x[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
- ypos += glyphs.advances_y[i];
+ xpos += glyphs.advances[i] + QFixed::fromFixed(glyphs.justifications[i].space_18d6);
++current;
}
++i;
@@ -656,8 +710,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
for (int i=0; i < glyphs.numGlyphs; ++i) {
glyph_metrics_t metrics = boundingBox(glyphs.glyphs[i]);
if (metrics.width.value() == 0 || metrics.height.value() == 0) {
- advanceX += glyphs.advances_x[i];
- advanceY += glyphs.advances_y[i];
+ advanceX += glyphs.advances[i];
continue;
}
const QImage alphaMask = alphaMapForGlyph(glyphs.glyphs[i]);
@@ -692,8 +745,7 @@ void QFontEngine::addBitmapFontToPath(qreal x, qreal y, const QGlyphLayout &glyp
advanceX += offset.x;
advanceY += offset.y;
qt_addBitmapToPath((advanceX + metrics.x).toReal(), (advanceY + metrics.y).toReal(), bitmap_data, bitmap.bytesPerLine(), w, h, path);
- advanceX += glyphs.advances_x[i];
- advanceY += glyphs.advances_y[i];
+ advanceX += glyphs.advances[i];
}
}
@@ -704,16 +756,12 @@ void QFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int n
qreal y = positions[0].y.toReal();
QVarLengthGlyphLayoutArray g(nGlyphs);
- for (int i = 0; i < nGlyphs; ++i) {
+ for (int i = 0; i < nGlyphs - 1; ++i) {
g.glyphs[i] = glyphs[i];
- if (i < nGlyphs - 1) {
- g.advances_x[i] = positions[i+1].x - positions[i].x;
- g.advances_y[i] = positions[i+1].y - positions[i].y;
- } else {
- g.advances_x[i] = QFixed::fromReal(maxCharWidth());
- g.advances_y[i] = 0;
- }
+ g.advances[i] = positions[i + 1].x - positions[i].x;
}
+ g.glyphs[nGlyphs - 1] = glyphs[nGlyphs - 1];
+ g.advances[nGlyphs - 1] = QFixed::fromReal(maxCharWidth());
addBitmapFontToPath(x, y, g, path, flags);
}
@@ -973,10 +1021,10 @@ void QFontEngine::doKerning(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags
if (flags & DesignMetrics) {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
- glyphs->advances_x[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
+ glyphs->advances[i] += kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs);
} else {
for(int i = 0; i < glyphs->numGlyphs - 1; ++i)
- glyphs->advances_x[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
+ glyphs->advances[i] += qRound(kerning(glyphs->glyphs[i], glyphs->glyphs[i+1] , pairs, numPairs));
}
}
@@ -1320,17 +1368,22 @@ QFontEngineBox::~QFontEngineBox()
{
}
-bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
+bool QFontEngineBox::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QFontEngine::ShaperFlags flags) const
{
if (*nglyphs < len) {
*nglyphs = len;
return false;
}
- memset(glyphs->glyphs, 0, len * sizeof(glyph_t));
+ int ucs4Length = 0;
+ QStringIterator it(str, str + len);
+ while (it.hasNext()) {
+ it.advance();
+ glyphs->glyphs[ucs4Length++] = 0;
+ }
- *nglyphs = len;
- glyphs->numGlyphs = len;
+ *nglyphs = ucs4Length;
+ glyphs->numGlyphs = ucs4Length;
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
@@ -1340,10 +1393,8 @@ bool QFontEngineBox::stringToCMap(const QChar *, int len, QGlyphLayout *glyphs,
void QFontEngineBox::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const
{
- for (int i = 0; i < glyphs->numGlyphs; i++) {
- glyphs->advances_x[i] = _size;
- glyphs->advances_y[i] = 0;
- }
+ for (int i = 0; i < glyphs->numGlyphs; i++)
+ glyphs->advances[i] = _size;
}
void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QPainterPath *path, QTextItem::RenderFlags flags)
@@ -1503,11 +1554,9 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate());
uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode();
if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) {
- QFixedPoint tmpAdvance;
- if (!(flags & GlyphIndicesOnly)) {
- tmpAdvance.x = glyphs->advances_x[glyph_pos];
- tmpAdvance.y = glyphs->advances_y[glyph_pos];
- }
+ QFixed tmpAdvance;
+ if (!(flags & GlyphIndicesOnly))
+ tmpAdvance = glyphs->advances[glyph_pos];
for (int x = 1, n = qMin(engines.size(), 256); x < n; ++x) {
if (engines.at(x) == 0 && !shouldLoadFontEngineForCharacter(x, ucs4))
continue;
@@ -1522,11 +1571,12 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
continue;
if (!(flags & GlyphIndicesOnly))
- glyphs->advances_x[glyph_pos] = glyphs->advances_y[glyph_pos] = 0;
+ glyphs->advances[glyph_pos] = QFixed();
int num = 2;
- QGlyphLayout offs = glyphs->mid(glyph_pos, num);
- engine->stringToCMap(str + i, surrogate ? 2 : 1, &offs, &num, flags);
- Q_ASSERT(num == 1); // surrogates only give 1 glyph
+ QGlyphLayout g = glyphs->mid(glyph_pos, num);
+ if (!engine->stringToCMap(str + i, surrogate ? 2 : 1, &g, &num, flags))
+ Q_UNREACHABLE();
+ Q_ASSERT(num == 1);
if (glyphs->glyphs[glyph_pos]) {
// set the high byte to indicate which engine the glyph came from
glyphs->glyphs[glyph_pos] |= (x << 24);
@@ -1535,10 +1585,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len,
}
// ensure we use metrics from the 1st font when we use the fallback image.
- if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0) {
- glyphs->advances_x[glyph_pos] = tmpAdvance.x;
- glyphs->advances_y[glyph_pos] = tmpAdvance.y;
- }
+ if (!(flags & GlyphIndicesOnly) && glyphs->glyphs[glyph_pos] == 0)
+ glyphs->advances[glyph_pos] = tmpAdvance;
}
if (surrogate)
@@ -1639,10 +1687,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
int start = 0;
int end, i;
if (flags & QTextItem::RightToLeft) {
- for (int gl = 0; gl < glyphs.numGlyphs; gl++) {
- x += glyphs.advances_x[gl].toReal();
- y += glyphs.advances_y[gl].toReal();
- }
+ for (int gl = 0; gl < glyphs.numGlyphs; gl++)
+ x += glyphs.advances[gl].toReal();
}
for (end = 0; end < glyphs.numGlyphs; ++end) {
const int e = highByte(glyphs.glyphs[end]);
@@ -1650,10 +1696,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
continue;
if (flags & QTextItem::RightToLeft) {
- for (i = start; i < end; ++i) {
- x -= glyphs.advances_x[i].toReal();
- y -= glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x -= glyphs.advances[i].toReal();
}
// set the high byte to zero
@@ -1666,10 +1710,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
glyphs.glyphs[i] = hi | glyphs.glyphs[i];
if (!(flags & QTextItem::RightToLeft)) {
- for (i = start; i < end; ++i) {
- x += glyphs.advances_x[i].toReal();
- y += glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x += glyphs.advances[i].toReal();
}
// change engine
@@ -1678,10 +1720,8 @@ void QFontEngineMulti::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &gl
}
if (flags & QTextItem::RightToLeft) {
- for (i = start; i < end; ++i) {
- x -= glyphs.advances_x[i].toReal();
- y -= glyphs.advances_y[i].toReal();
- }
+ for (i = start; i < end; ++i)
+ x -= glyphs.advances[i].toReal();
}
// set the high byte to zero
@@ -1847,16 +1887,11 @@ bool QFontEngineMulti::canRender(const QChar *string, int len)
QGlyphLayout g;
g.numGlyphs = nglyphs;
g.glyphs = glyphs.data();
- if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly)) {
- glyphs.resize(nglyphs);
- g.numGlyphs = nglyphs;
- g.glyphs = glyphs.data();
- if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!stringToCMap(string, len, &g, &nglyphs, GlyphIndicesOnly))
+ Q_UNREACHABLE();
for (int i = 0; i < nglyphs; i++) {
- if (g.glyphs[i] == 0)
+ if (glyphs[i] == 0)
return false;
}
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 05bd014bd7..665932e4a5 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -723,7 +723,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
FT_Set_Transform(face, &matrix, 0);
freetype->matrix = matrix;
// fake bold
- if ((fontDef.weight == QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
+ if ((fontDef.weight >= QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face))
embolden = true;
// underline metrics
line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale));
@@ -1196,7 +1196,7 @@ int QFontEngineFT::synthesized() const
int s = 0;
if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC))
s = SynthesizedItalic;
- if ((fontDef.weight == QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
+ if ((fontDef.weight >= QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD))
s |= SynthesizedBold;
if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face))
s |= SynthesizedStretch;
@@ -1283,13 +1283,22 @@ qreal QFontEngineFT::minRightBearing() const
{
if (rbearing == SHRT_MIN) {
lbearing = rbearing = 0;
- const QChar *ch = (const QChar *)(const void*)char_table;
- QGlyphLayoutArray<char_table_entries> glyphs;
+
+ const QChar *ch = reinterpret_cast<const QChar *>(char_table);
+
+ glyph_t glyphs[char_table_entries];
+
+ QGlyphLayout g;
+ g.glyphs = glyphs;
+ g.numGlyphs = char_table_entries;
int ng = char_table_entries;
- stringToCMap(ch, char_table_entries, &glyphs, &ng, GlyphIndicesOnly);
+ if (!stringToCMap(ch, char_table_entries, &g, &ng, GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(ng == char_table_entries);
+
while (--ng) {
- if (glyphs.glyphs[ng]) {
- glyph_metrics_t gi = const_cast<QFontEngineFT *>(this)->boundingBox(glyphs.glyphs[ng]);
+ if (glyphs[ng]) {
+ glyph_metrics_t gi = const_cast<QFontEngineFT *>(this)->boundingBox(glyphs[ng]);
lbearing = qMin(lbearing, gi.x);
rbearing = qMin(rbearing, (gi.xoff - gi.x - gi.width));
}
@@ -1525,7 +1534,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
return false;
}
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (freetype->symbol_map) {
FT_Face face = freetype->face;
@@ -1561,8 +1569,6 @@ bool QFontEngineFT::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs
FT_Face face = freetype->face;
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = uc < QFreetypeFace::cmapCacheSize ? freetype->cmapCache[uc] : 0;
if (!glyphs->glyphs[glyph_pos]) {
{
@@ -1607,24 +1613,23 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
// Since we are passing Format_None to loadGlyph, use same default format logic as loadGlyph
GlyphFormat acceptableFormat = (defaultFormat != Format_None) ? defaultFormat : Format_Mono;
if (g && g->format == acceptableFormat) {
- glyphs->advances_x[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
+ glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
} else {
if (!face)
face = lockFace();
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
- glyphs->advances_x[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
- : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
+ glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
+ : QFixed::fromFixed(face->glyph->metrics.horiAdvance);
if (!cacheEnabled)
delete g;
}
- glyphs->advances_y[i] = 0;
}
if (face)
unlockFace();
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances[i] = glyphs->advances[i].round();
}
}
diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h
index a04f4bd0ac..532ebaf8ff 100644
--- a/src/gui/text/qfontengine_p.h
+++ b/src/gui/text/qfontengine_p.h
@@ -121,7 +121,6 @@ public:
};
enum ShaperFlag {
- RightToLeft = 0x0001,
DesignMetrics = 0x0002,
GlyphIndicesOnly = 0x0004
};
diff --git a/src/gui/text/qfontengine_qpa.cpp b/src/gui/text/qfontengine_qpa.cpp
index 28b95bd509..cb40a5388a 100644
--- a/src/gui/text/qfontengine_qpa.cpp
+++ b/src/gui/text/qfontengine_qpa.cpp
@@ -353,13 +353,10 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
const uchar *cmap = externalCMap ? externalCMap : (fontData + cmapOffset);
- bool mirrored = flags & QFontEngine::RightToLeft;
int glyph_pos = 0;
if (symbol) {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
if(!glyphs->glyphs[glyph_pos] && uc < 0x100)
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
@@ -368,8 +365,6 @@ bool QFontEngineQPA::stringToCMap(const QChar *str, int len, QGlyphLayout *glyph
} else {
for (int i = 0; i < len; ++i) {
unsigned int uc = getChar(str, i, len);
- if (mirrored)
- uc = QChar::mirroredChar(uc);
glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
#if 0 && defined(DEBUG_FONTENGINE)
QChar c(uc);
@@ -399,8 +394,7 @@ void QFontEngineQPA::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFla
glyphs->glyphs[i] = 0;
continue;
}
- glyphs->advances_x[i] = g->advance;
- glyphs->advances_y[i] = 0;
+ glyphs->advances[i] = g->advance;
}
}
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 1a66657cbd..2f4709afe4 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -458,12 +458,19 @@ int QFontMetrics::leftBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal lb;
- engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ engine->getGlyphBearings(glyph, &lb);
return qRound(lb);
}
@@ -493,12 +500,19 @@ int QFontMetrics::rightBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal rb;
- engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ engine->getGlyphBearings(glyph, 0, &rb);
return qRound(rb);
}
@@ -538,15 +552,12 @@ int QFontMetrics::width(const QString &text, int len, int flags) const
int numGlyphs = len;
QVarLengthGlyphLayoutArray glyphs(numGlyphs);
QFontEngine *engine = d->engineForScript(QChar::Script_Common);
- if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) {
- glyphs.resize(numGlyphs);
- if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0))
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- }
+ if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0))
+ Q_UNREACHABLE();
QFixed width;
for (int i = 0; i < numGlyphs; ++i)
- width += glyphs.advances_x[i];
+ width += glyphs.advances[i];
return qRound(width);
}
@@ -594,10 +605,20 @@ int QFontMetrics::width(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- return qRound(glyphs.advances_x[0]);
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ return qRound(advance);
}
/*! \obsolete
@@ -639,10 +660,20 @@ int QFontMetrics::charWidth(const QString &text, int pos) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- width = qRound(glyphs.advances_x[0]);
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ width = qRound(advance);
}
return width;
}
@@ -708,10 +739,18 @@ QRect QFontMetrics::boundingRect(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t gm = engine->boundingBox(glyph);
return QRect(qRound(gm.x), qRound(gm.y), qRound(gm.width), qRound(gm.height));
}
@@ -1326,12 +1365,19 @@ qreal QFontMetricsF::leftBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal lb;
- engine->getGlyphBearings(glyphs.glyphs[0], &lb);
+ engine->getGlyphBearings(glyph, &lb);
return lb;
}
@@ -1361,12 +1407,19 @@ qreal QFontMetricsF::rightBearing(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
qreal rb;
- engine->getGlyphBearings(glyphs.glyphs[0], 0, &rb);
+ engine->getGlyphBearings(glyph, 0, &rb);
return rb;
}
@@ -1431,10 +1484,20 @@ qreal QFontMetricsF::width(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- return glyphs.advances_x[0].toReal();
+ QFixed advance;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyph_t glyph;
+ glyphs.glyphs = &glyph;
+ glyphs.advances = &advance;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ return advance.toReal();
}
/*!
@@ -1496,10 +1559,18 @@ QRectF QFontMetricsF::boundingRect(QChar ch) const
d->alterCharForCapitalization(ch);
- QGlyphLayoutArray<10> glyphs;
- int nglyphs = 9;
- engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- glyph_metrics_t gm = engine->boundingBox(glyphs.glyphs[0]);
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &glyph;
+
+ int nglyphs = 1;
+ if (!engine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ glyph_metrics_t gm = engine->boundingBox(glyph);
return QRectF(gm.x.toReal(), gm.y.toReal(), gm.width.toReal(), gm.height.toReal());
}
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index 152e15a54d..2109b16bb5 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -201,12 +201,22 @@ static void checkRanges(QPdf::ByteStream &ts, QByteArray &ranges, int &nranges)
QVector<int> QFontSubset::getReverseMap() const
{
QVector<int> reverseMap(0x10000, 0);
- QGlyphLayoutArray<10> glyphs;
+
+ glyph_t glyph;
+
+ QGlyphLayout glyphs;
+ glyphs.glyphs = &glyph;
+ glyphs.numGlyphs = 1;
+
for (uint uc = 0; uc < 0x10000; ++uc) {
QChar ch(uc);
- int nglyphs = 10;
- fontEngine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly);
- int idx = glyph_indices.indexOf(glyphs.glyphs[0]);
+
+ int nglyphs = 1;
+ if (!fontEngine->stringToCMap(&ch, 1, &glyphs, &nglyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ int idx = glyph_indices.indexOf(glyph);
if (idx >= 0 && !reverseMap.at(idx))
reverseMap[idx] = uc;
}
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index d2e7df9c10..c09f27b665 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -397,13 +397,7 @@ _hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data,
QFontEngine *fe = (QFontEngine *)font_data;
Q_ASSERT(fe);
- glyph_t glyphs[2] = { 0, 0 };
-
- QGlyphLayout g;
- g.numGlyphs = 2;
- g.glyphs = glyphs;
-
- QChar chars[4];
+ QChar chars[2];
int numChars = 0;
if (Q_UNLIKELY(QChar::requiresSurrogates(unicode))) {
chars[numChars++] = QChar(QChar::highSurrogate(unicode));
@@ -422,11 +416,14 @@ _hb_qt_font_get_glyph(hb_font_t * /*font*/, void *font_data,
}
#endif
- int numGlyphs = g.numGlyphs;
- bool ok = fe->stringToCMap(chars, numChars, &g, &numGlyphs, QFontEngine::GlyphIndicesOnly);
- Q_ASSERT(ok); Q_UNUSED(ok)
+ QGlyphLayout g;
+ g.numGlyphs = numChars;
+ g.glyphs = glyph;
- *glyph = g.glyphs[0];
+ int numGlyphs = numChars;
+ if (!fe->stringToCMap(chars, numChars, &g, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
+ Q_ASSERT(numGlyphs == 1);
return true;
}
@@ -439,18 +436,16 @@ _hb_qt_font_get_glyph_h_advance(hb_font_t *font, void *font_data,
QFontEngine *fe = (QFontEngine *)font_data;
Q_ASSERT(fe);
- QFixed advance_x;
- QFixed advance_y;
+ QFixed advance;
QGlyphLayout g;
g.numGlyphs = 1;
g.glyphs = &glyph;
- g.advances_x = &advance_x;
- g.advances_y = &advance_y;
+ g.advances = &advance;
fe->recalcAdvances(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
- return g.advances_x[0].value();
+ return advance.value();
}
static hb_position_t
@@ -490,18 +485,16 @@ _hb_qt_font_get_glyph_h_kerning(hb_font_t *font, void *font_data,
Q_ASSERT(fe);
glyph_t glyphs[2] = { first_glyph, second_glyph };
- QFixed advance_x;
- QFixed advance_y;
+ QFixed advance;
QGlyphLayout g;
g.numGlyphs = 2;
g.glyphs = glyphs;
- g.advances_x = &advance_x;
- g.advances_y = &advance_y;
+ g.advances = &advance;
fe->doKerning(&g, QFontEngine::ShaperFlags(hb_qt_font_get_use_design_metrics(font)));
- return g.advances_x[0].value();
+ return advance.value();
}
static hb_position_t
@@ -710,7 +703,11 @@ _hb_qt_font_create(QFontEngine *fe)
const int x_ppem = (fe->fontDef.pixelSize * fe->fontDef.stretch) / 100;
hb_font_set_funcs(font, hb_qt_get_font_funcs(), (void *)fe, NULL);
+#ifdef Q_OS_MAC
+ hb_font_set_scale(font, QFixed(x_ppem).value(), QFixed(y_ppem).value());
+#else
hb_font_set_scale(font, QFixed(x_ppem).value(), -QFixed(y_ppem).value());
+#endif
hb_font_set_ppem(font, x_ppem, y_ppem);
return font;
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 37610a9099..7936831e13 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -289,13 +289,11 @@ QFontEngineMulti *QPlatformFontDatabase::fontEngineMulti(QFontEngine *fontEngine
Returns the font engine that can be used to render the font described by
the font definition, \a fontDef, in the specified \a script.
*/
-QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle)
+QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
- Q_UNUSED(script);
- Q_UNUSED(handle);
QByteArray *fileDataPtr = static_cast<QByteArray *>(handle);
QFontEngineQPA *engine = new QFontEngineQPA(fontDef,*fileDataPtr);
- //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family << script;
+ //qDebug() << fontDef.pixelSize << fontDef.weight << fontDef.style << fontDef.stretch << fontDef.styleHint << fontDef.styleStrategy << fontDef.family;
return engine;
}
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 6053f11051..5f2c9a74ba 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -97,7 +97,7 @@ public:
virtual ~QPlatformFontDatabase();
virtual void populateFontDatabase();
virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
- virtual QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual void releaseHandle(void *handle);
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index b1b910422c..449278df06 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -479,16 +479,8 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const
QGlyphLayout glyphs;
glyphs.numGlyphs = numGlyphs;
glyphs.glyphs = glyphIndexes.data();
- if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) {
- glyphIndexes.resize(numGlyphs);
-
- glyphs.numGlyphs = numGlyphs;
- glyphs.glyphs = glyphIndexes.data();
- if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly)) {
- Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
- return QVector<quint32>();
- }
- }
+ if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &numGlyphs, QFontEngine::GlyphIndicesOnly))
+ Q_UNREACHABLE();
glyphIndexes.resize(numGlyphs);
return glyphIndexes;
@@ -565,13 +557,12 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
if (!d->isValid() || numGlyphs <= 0)
return false;
+ QVarLengthArray<QFixed> tmpAdvances(numGlyphs);
+
QGlyphLayout glyphs;
glyphs.glyphs = const_cast<glyph_t *>(glyphIndexes);
glyphs.numGlyphs = numGlyphs;
- QVarLengthArray<QFixed> advances_x(numGlyphs);
- QVarLengthArray<QFixed> advances_y(numGlyphs);
- glyphs.advances_x = advances_x.data();
- glyphs.advances_y = advances_y.data();
+ glyphs.advances = tmpAdvances.data();
bool design = layoutFlags & UseDesignMetrics;
@@ -580,7 +571,7 @@ bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *adv
d->fontEngine->doKerning(&glyphs, design ? QFontEngine::DesignMetrics : QFontEngine::ShaperFlag(0));
for (int i=0; i<numGlyphs; ++i)
- advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal());
+ advances[i] = QPointF(tmpAdvances[i].toReal(), 0.0);
return true;
}
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index d12f3cccd8..ac9762b183 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -174,7 +174,6 @@ void QTextCursorPrivate::remove()
} else {
priv->remove(pos1, pos2-pos1, op);
adjusted_anchor = anchor = position;
- priv->finishEdit();
}
}
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 4a34f0d3c3..fa54776b6d 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -551,6 +551,39 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option)
}
/*!
+ \property QTextDocument::baseUrl
+ \since 5.3
+ \brief the base URL used to resolve relative resource URLs within the document.
+
+ Resource URLs are resolved to be within the same directory as the target of the base
+ URL meaning any portion of the path after the last '/' will be ignored.
+
+ \table
+ \header \li Base URL \li Relative URL \li Resolved URL
+ \row \li file:///path/to/content \li images/logo.png \li file:///path/to/images/logo.png
+ \row \li file:///path/to/content/ \li images/logo.png \li file:///path/to/content/images/logo.png
+ \row \li file:///path/to/content/index.html \li images/logo.png \li file:///path/to/content/images/logo.png
+ \row \li file:///path/to/content/images/ \li ../images/logo.png \li file:///path/to/content/images/logo.png
+ \endtable
+*/
+QUrl QTextDocument::baseUrl() const
+{
+ Q_D(const QTextDocument);
+ return d->baseUrl;
+}
+
+void QTextDocument::setBaseUrl(const QUrl &url)
+{
+ Q_D(QTextDocument);
+ if (d->baseUrl != url) {
+ d->baseUrl = url;
+ if (d->lout)
+ d->lout->documentChanged(0, 0, d->length());
+ emit baseUrlChanged(url);
+ }
+}
+
+/*!
\since 4.8
The default cursor movement style is used by all QTextCursor objects
@@ -1849,11 +1882,12 @@ void QTextDocument::print(QPagedPaintDevice *printer) const
QVariant QTextDocument::resource(int type, const QUrl &name) const
{
Q_D(const QTextDocument);
- QVariant r = d->resources.value(name);
+ const QUrl url = d->baseUrl.resolved(name);
+ QVariant r = d->resources.value(url);
if (!r.isValid()) {
- r = d->cachedResources.value(name);
+ r = d->cachedResources.value(url);
if (!r.isValid())
- r = const_cast<QTextDocument *>(this)->loadResource(type, name);
+ r = const_cast<QTextDocument *>(this)->loadResource(type, url);
}
return r;
}
@@ -1924,27 +1958,29 @@ QVariant QTextDocument::loadResource(int type, const QUrl &name)
}
// if resource was not loaded try to load it here
- if (!qobject_cast<QTextDocument *>(p) && r.isNull() && name.isRelative()) {
- QUrl currentURL = d->url;
+ if (!qobject_cast<QTextDocument *>(p) && r.isNull()) {
QUrl resourceUrl = name;
- // For the second case QUrl can merge "#someanchor" with "foo.html"
- // correctly to "foo.html#someanchor"
- if (!(currentURL.isRelative()
- || (currentURL.scheme() == QLatin1String("file")
- && !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
- || (name.hasFragment() && name.path().isEmpty())) {
- resourceUrl = currentURL.resolved(name);
- } else {
- // this is our last resort when current url and new url are both relative
- // we try to resolve against the current working directory in the local
- // file system.
- QFileInfo fi(currentURL.toLocalFile());
- if (fi.exists()) {
- resourceUrl =
- QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
- } else if (currentURL.isEmpty()) {
- resourceUrl.setScheme(QLatin1String("file"));
+ if (name.isRelative()) {
+ QUrl currentURL = d->url;
+ // For the second case QUrl can merge "#someanchor" with "foo.html"
+ // correctly to "foo.html#someanchor"
+ if (!(currentURL.isRelative()
+ || (currentURL.scheme() == QLatin1String("file")
+ && !QFileInfo(currentURL.toLocalFile()).isAbsolute()))
+ || (name.hasFragment() && name.path().isEmpty())) {
+ resourceUrl = currentURL.resolved(name);
+ } else {
+ // this is our last resort when current url and new url are both relative
+ // we try to resolve against the current working directory in the local
+ // file system.
+ QFileInfo fi(currentURL.toLocalFile());
+ if (fi.exists()) {
+ resourceUrl =
+ QUrl::fromLocalFile(fi.absolutePath() + QDir::separator()).resolved(name);
+ } else if (currentURL.isEmpty()) {
+ resourceUrl.setScheme(QLatin1String("file"));
+ }
}
}
@@ -2124,13 +2160,21 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format)
html += QLatin1String("pt;");
attributesEmitted = true;
} else if (format.hasProperty(QTextFormat::FontSizeAdjustment)) {
- static const char * const sizeNames[] = {
- "small", "medium", "large", "x-large", "xx-large"
+ static const char sizeNameData[] =
+ "small" "\0"
+ "medium" "\0"
+ "xx-large" ;
+ static const quint8 sizeNameOffsets[] = {
+ 0, // "small"
+ sizeof("small"), // "medium"
+ sizeof("small") + sizeof("medium") + 3, // "large" )
+ sizeof("small") + sizeof("medium") + 1, // "x-large" )> compressed into "xx-large"
+ sizeof("small") + sizeof("medium"), // "xx-large" )
};
const char *name = 0;
const int idx = format.intProperty(QTextFormat::FontSizeAdjustment) + 1;
if (idx >= 0 && idx <= 4) {
- name = sizeNames[idx];
+ name = sizeNameData + sizeNameOffsets[idx];
}
if (name) {
html += QLatin1String(" font-size:");
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index d8f52e9f98..854cb29ed9 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -47,6 +47,7 @@
#include <QtCore/qrect.h>
#include <QtCore/qvariant.h>
#include <QtGui/qfont.h>
+#include <QtCore/qurl.h>
QT_BEGIN_NAMESPACE
@@ -63,7 +64,6 @@ class QTextFormat;
class QTextFrame;
class QTextBlock;
class QTextCodec;
-class QUrl;
class QVariant;
class QRectF;
class QTextOption;
@@ -116,6 +116,7 @@ class Q_GUI_EXPORT QTextDocument : public QObject
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
Q_PROPERTY(qreal documentMargin READ documentMargin WRITE setDocumentMargin)
QDOC_PROPERTY(QTextOption defaultTextOption READ defaultTextOption WRITE setDefaultTextOption)
+ Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl NOTIFY baseUrlChanged)
public:
explicit QTextDocument(QObject *parent = 0);
@@ -258,6 +259,9 @@ public:
QTextOption defaultTextOption() const;
void setDefaultTextOption(const QTextOption &option);
+ QUrl baseUrl() const;
+ void setBaseUrl(const QUrl &url);
+
Qt::CursorMoveStyle defaultCursorMoveStyle() const;
void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style);
@@ -270,7 +274,7 @@ Q_SIGNALS:
void modificationChanged(bool m);
void cursorPositionChanged(const QTextCursor &cursor);
void blockCountChanged(int newBlockCount);
-
+ void baseUrlChanged(const QUrl &url);
void documentLayoutChanged();
public Q_SLOTS:
diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h
index 8d4cab30ae..fa22131c9e 100644
--- a/src/gui/text/qtextdocument_p.h
+++ b/src/gui/text/qtextdocument_p.h
@@ -355,6 +355,7 @@ public:
QString url;
qreal indentWidth;
qreal documentMargin;
+ QUrl baseUrl;
void mergeCachedResources(const QTextDocumentPrivate *priv);
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index df67fb581a..3bd1e2a801 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -489,7 +489,7 @@ void QTextHtmlImporter::import()
&& currentNode->id != Html_unknown)
{
hasBlock = false;
- } else if (hasBlock) {
+ } else if (blockTagClosed && hasBlock) {
// when collapsing subsequent block tags we need to clear the block format
QTextBlockFormat blockFormat = currentNode->blockFormat;
blockFormat.setIndent(indent);
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index febdaaa86c..eb31c520ed 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -241,7 +241,8 @@ using namespace std;
static const char *directions[] = {
"DirL", "DirR", "DirEN", "DirES", "DirET", "DirAN", "DirCS", "DirB", "DirS", "DirWS", "DirON",
- "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN"
+ "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN",
+ "DirLRI", "DirRLI", "DirFSI", "DirPDI"
};
#endif
@@ -928,21 +929,8 @@ void QTextEngine::shapeText(int item) const
int nGlyphs = initialGlyphs.numGlyphs;
QFontEngine::ShaperFlags shaperFlags(QFontEngine::GlyphIndicesOnly);
- if (si.analysis.bidiLevel % 2)
- shaperFlags |= QFontEngine::RightToLeft;
-
- if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) {
- nGlyphs = qMax(nGlyphs, itemLength); // ### needed for QFontEngine::stringToCMap() to not fail twice
- if (!ensureSpace(nGlyphs)) {
- Q_UNREACHABLE(); // ### report OOM error somehow
- return;
- }
- initialGlyphs = availableGlyphs(&si);
- if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags)) {
- Q_UNREACHABLE(); // ### if this happens there is a bug in the fontengine
- return;
- }
- }
+ if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags))
+ Q_UNREACHABLE();
uint lastEngine = ~0u;
for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) {
@@ -1014,17 +1002,17 @@ void QTextEngine::shapeText(int item) const
for (int i = 1; i < si.num_glyphs; ++i) {
if (glyphs.attributes[i].clusterStart) {
if (letterSpacingIsAbsolute)
- glyphs.advances_x[i-1] += letterSpacing;
+ glyphs.advances[i - 1] += letterSpacing;
else {
- QFixed &advance = glyphs.advances_x[i-1];
+ QFixed &advance = glyphs.advances[i - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
}
if (letterSpacingIsAbsolute)
- glyphs.advances_x[si.num_glyphs-1] += letterSpacing;
+ glyphs.advances[si.num_glyphs - 1] += letterSpacing;
else {
- QFixed &advance = glyphs.advances_x[si.num_glyphs-1];
+ QFixed &advance = glyphs.advances[si.num_glyphs - 1];
advance += (letterSpacing - 100) * advance / 100;
}
}
@@ -1036,13 +1024,13 @@ void QTextEngine::shapeText(int item) const
if (i + 1 == si.num_glyphs
||(glyphs.attributes[i+1].justification != QGlyphAttributes::Space
&& glyphs.attributes[i+1].justification != QGlyphAttributes::Arabic_Space))
- glyphs.advances_x[i] += wordSpacing;
+ glyphs.advances[i] += wordSpacing;
}
}
}
for (int i = 0; i < si.num_glyphs; ++i)
- si.width += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ si.width += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
#ifdef QT_ENABLE_HARFBUZZ_NG
@@ -1139,8 +1127,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
for (uint i = 0; i < num_glyphs; ++i) {
g.glyphs[i] = infos[i].codepoint;
- g.advances_x[i] = QFixed::fromFixed(positions[i].x_advance);
- g.advances_y[i] = QFixed::fromFixed(positions[i].y_advance);
+ g.advances[i] = QFixed::fromFixed(positions[i].x_advance);
g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset);
g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset);
@@ -1163,6 +1150,13 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
g.glyphs[i] |= (engineIdx << 24);
}
+#ifdef Q_OS_MAC
+ if (actualFontEngine->fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
+ for (uint i = 0; i < num_glyphs; ++i)
+ g.advances[i] = g.advances[i].round();
+ }
+#endif
+
glyphs_shaped += num_glyphs;
}
@@ -1238,7 +1232,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
if (fontEngine->type() == QFontEngine::Multi) {
actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
- shaper_item.glyphIndicesPresent = true;
+ if ((si.analysis.bidiLevel % 2) == 0)
+ shaper_item.glyphIndicesPresent = true;
}
shaper_item.font = (HB_Font)actualFontEngine->harfbuzzFont();
@@ -1256,7 +1251,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs);
shaper_item.attributes = reinterpret_cast<HB_GlyphAttributes *>(g.attributes);
- shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances_x);
+ shaper_item.advances = reinterpret_cast<HB_Fixed *>(g.advances);
shaper_item.offsets = reinterpret_cast<HB_FixedPoint *>(g.offsets);
if (engineIdx != 0 && shaper_item.glyphIndicesPresent) {
@@ -1360,9 +1355,9 @@ void QTextEngine::shape(int item) const
if (layoutData->items[item].analysis.flags == QScriptAnalysis::Object) {
ensureSpace(1);
if (block.docHandle()) {
- QTextFormat format = formats()->format(formatIndex(&layoutData->items[item]));
docLayout()->resizeInlineObject(QTextInlineObject(item, const_cast<QTextEngine *>(this)),
- layoutData->items[item].position + block.position(), format);
+ layoutData->items[item].position + block.position(),
+ format(&layoutData->items[item]));
}
} else if (layoutData->items[item].analysis.flags == QScriptAnalysis::Tab) {
// set up at least the ascent/descent/leading of the script item for the tab
@@ -1394,7 +1389,7 @@ void QTextEngine::invalidate()
minWidth = 0;
maxWidth = 0;
if (specialData)
- specialData->resolvedFormatIndices.clear();
+ specialData->resolvedFormats.clear();
resetFontEngineCache();
}
@@ -1468,8 +1463,18 @@ void QTextEngine::itemize() const
{
QVarLengthArray<uchar> scripts(length);
QUnicodeTools::initScripts(string, length, scripts.data());
- for (int i = 0; i < length; ++i)
- analysis[i].script = scripts.at(i);
+ for (int i = 0; i < length; ++i) {
+ ushort script = scripts.at(i);
+ switch (script) {
+ case QChar::Script_Hiragana:
+ case QChar::Script_Katakana:
+ script = QChar::Script_Han;
+ break;
+ default:
+ break;
+ }
+ analysis[i].script = script;
+ }
}
const ushort *uc = string;
@@ -1563,10 +1568,9 @@ void QTextEngine::itemize() const
#ifndef QT_NO_RAWFONT
if (useRawFont && specialData) {
int lastIndex = 0;
- const QTextFormatCollection *collection = formats();
for (int i = 0; i < specialData->addFormats.size(); ++i) {
const QTextLayout::FormatRange &range = specialData->addFormats.at(i);
- const QTextCharFormat format = collection->charFormat(specialData->addFormatIndices.at(i));
+ const QTextCharFormat &format = range.format;
if (format.hasProperty(QTextFormat::FontCapitalization)) {
itemizer.generate(lastIndex, range.start - lastIndex, QFont::MixedCase);
itemizer.generate(range.start, range.length, format.fontCapitalization());
@@ -1674,7 +1678,7 @@ QFixed QTextEngine::width(int from, int len) const
// qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd);
for (int i = glyphStart; i < glyphEnd; i++)
- w += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ w += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
}
}
@@ -1963,11 +1967,22 @@ static void set(QJustificationPoint *point, int type, const QGlyphLayout &glyph,
if (type >= QGlyphAttributes::Arabic_Normal) {
QChar ch(0x640); // Kashida character
- QGlyphLayoutArray<8> glyphs;
- int nglyphs = 7;
- fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0);
- if (glyphs.glyphs[0] && glyphs.advances_x[0] != 0) {
- point->kashidaWidth = glyphs.advances_x[0];
+
+ glyph_t kashidaGlyph;
+ QFixed kashidaWidth;
+
+ QGlyphLayout glyphs;
+ glyphs.numGlyphs = 1;
+ glyphs.glyphs = &kashidaGlyph;
+ glyphs.advances = &kashidaWidth;
+
+ int nglyphs = 1;
+ if (!fe->stringToCMap(&ch, 1, &glyphs, &nglyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nglyphs == 1);
+
+ if (kashidaGlyph != 0 && kashidaWidth != 0) {
+ point->kashidaWidth = kashidaWidth;
} else {
point->type = QGlyphAttributes::NoJustification;
point->kashidaWidth = 0;
@@ -2209,7 +2224,7 @@ QTextEngine::LayoutData::LayoutData(const QString &str, void **stack_memory, int
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
- available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::spaceNeededForGlyphLayout(1);
+ available_glyphs = ((int)allocated - space_charAttributes - space_logClusters)*(int)sizeof(void*)/(int)QGlyphLayout::SpaceNeeded;
if (available_glyphs < str.length()) {
// need to allocate on the heap
@@ -2251,7 +2266,7 @@ bool QTextEngine::LayoutData::reallocate(int totalGlyphs)
int space_charAttributes = sizeof(QCharAttributes)*string.length()/sizeof(void*) + 1;
int space_logClusters = sizeof(unsigned short)*string.length()/sizeof(void*) + 1;
- int space_glyphs = QGlyphLayout::spaceNeededForGlyphLayout(totalGlyphs)/sizeof(void*) + 2;
+ int space_glyphs = (totalGlyphs * QGlyphLayout::SpaceNeeded) / sizeof(void *) + 2;
int newAllocated = space_charAttributes + space_glyphs + space_logClusters;
// These values can be negative if the length of string/glyphs causes overflow,
@@ -2298,8 +2313,7 @@ void QGlyphLayout::grow(char *address, int totalGlyphs)
// move the existing data
memmove(newLayout.attributes, oldLayout.attributes, numGlyphs * sizeof(QGlyphAttributes));
memmove(newLayout.justifications, oldLayout.justifications, numGlyphs * sizeof(QGlyphJustification));
- memmove(newLayout.advances_y, oldLayout.advances_y, numGlyphs * sizeof(QFixed));
- memmove(newLayout.advances_x, oldLayout.advances_x, numGlyphs * sizeof(QFixed));
+ memmove(newLayout.advances, oldLayout.advances, numGlyphs * sizeof(QFixed));
memmove(newLayout.glyphs, oldLayout.glyphs, numGlyphs * sizeof(glyph_t));
}
@@ -2328,8 +2342,12 @@ void QTextEngine::freeMemory()
int QTextEngine::formatIndex(const QScriptItem *si) const
{
- if (specialData && !specialData->resolvedFormatIndices.isEmpty())
- return specialData->resolvedFormatIndices.at(si - &layoutData->items[0]);
+ if (specialData && !specialData->resolvedFormats.isEmpty()) {
+ QTextFormatCollection *collection = formats();
+ Q_ASSERT(collection);
+ return collection->indexForFormat(specialData->resolvedFormats.at(si - &layoutData->items[0]));
+ }
+
QTextDocumentPrivate *p = block.docHandle();
if (!p)
return -1;
@@ -2442,23 +2460,6 @@ void QTextEngine::setPreeditArea(int position, const QString &preeditText)
clearLineData();
}
-QList<QTextLayout::FormatRange> QTextEngine::additionalFormats() const
-{
- QList<QTextLayout::FormatRange> formatList;
- if (!specialData)
- return formatList;
-
- formatList = specialData->addFormats;
- if (!specialData->addFormatIndices.isEmpty()) {
- const QTextFormatCollection *formats = this->formats();
- Q_ASSERT(formats);
- for (int i = 0; i < specialData->addFormatIndices.size(); ++i)
- formatList[i].format = formats->charFormat(specialData->addFormatIndices.at(i));
- }
-
- return formatList;
-}
-
void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList)
{
if (formatList.isEmpty()) {
@@ -2469,7 +2470,6 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
specialData = 0;
} else {
specialData->addFormats.clear();
- specialData->addFormatIndices.clear();
}
} else {
if (!specialData) {
@@ -2484,19 +2484,17 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
void QTextEngine::indexAdditionalFormats()
{
- specialData->addFormatIndices.resize(specialData->addFormats.count());
-
- QTextFormatCollection *formats = this->formats();
-
- if (!formats) {
+ QTextFormatCollection *collection = formats();
+ if (!collection) {
Q_ASSERT(!block.docHandle());
specialData->formats.reset(new QTextFormatCollection);
- formats = specialData->formats.data();
+ collection = specialData->formats.data();
}
+ // replace with shared copies
for (int i = 0; i < specialData->addFormats.count(); ++i) {
- specialData->addFormatIndices[i] = formats->indexForFormat(specialData->addFormats.at(i).format);
- specialData->addFormats[i].format = QTextCharFormat();
+ QTextCharFormat &format = specialData->addFormats[i].format;
+ format = collection->charFormat(collection->indexForFormat(format));
}
}
@@ -2510,7 +2508,8 @@ static inline bool nextCharJoins(const QString &string, int pos)
++pos;
if (pos == string.length())
return false;
- return string.at(pos).joining() != QChar::OtherJoining;
+ QChar::JoiningType joining = string.at(pos).joiningType();
+ return joining != QChar::Joining_None && joining != QChar::Joining_Transparent;
}
static inline bool prevCharJoins(const QString &string, int pos)
@@ -2519,19 +2518,15 @@ static inline bool prevCharJoins(const QString &string, int pos)
--pos;
if (pos == 0)
return false;
- QChar::Joining joining = string.at(pos - 1).joining();
- return (joining == QChar::Dual || joining == QChar::Center);
+ QChar::JoiningType joining = string.at(pos - 1).joiningType();
+ return joining == QChar::Joining_Dual || joining == QChar::Joining_Causing;
}
static inline bool isRetainableControlCode(QChar c)
{
- return (c.unicode() == 0x202a // LRE
- || c.unicode() == 0x202b // LRE
- || c.unicode() == 0x202c // PDF
- || c.unicode() == 0x202d // LRO
- || c.unicode() == 0x202e // RLO
- || c.unicode() == 0x200e // LRM
- || c.unicode() == 0x200f); // RLM
+ return (c.unicode() >= 0x202a && c.unicode() <= 0x202e) // LRE, RLE, PDF, LRO, RLO
+ || (c.unicode() >= 0x200e && c.unicode() <= 0x200f) // LRM, RLM
+ || (c.unicode() >= 0x2066 && c.unicode() <= 0x2069); // LRM, RLM
}
static QString stringMidRetainingBidiCC(const QString &string,
@@ -2619,14 +2614,14 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
if (feForEllipsis->type() == QFontEngine::Mac)
feForEllipsis = fe;
- if (feForEllipsis->canRender(&ellipsisChar, 1)) {
- int nGlyphs = 1;
- feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0);
- }
+ int nGlyphs = 1;
+ if (!feForEllipsis->stringToCMap(&ellipsisChar, 1, &ellipsisGlyph, &nGlyphs, 0))
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 1);
}
if (ellipsisGlyph.glyphs[0]) {
- ellipsisWidth = ellipsisGlyph.advances_x[0];
+ ellipsisWidth = ellipsisGlyph.advances[0];
ellipsisText = ellipsisChar;
} else {
QString dotDotDot(QLatin1String("..."));
@@ -2634,10 +2629,11 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
QGlyphLayoutArray<3> glyphs;
int nGlyphs = 3;
if (!fe->stringToCMap(dotDotDot.constData(), 3, &glyphs, &nGlyphs, 0))
- // should never happen...
- return layoutData->string;
+ Q_UNREACHABLE();
+ Q_ASSERT(nGlyphs == 3);
+
for (int i = 0; i < nGlyphs; ++i)
- ellipsisWidth += glyphs.advances_x[i];
+ ellipsisWidth += glyphs.advances[i];
ellipsisText = dotDotDot;
}
}
@@ -2786,7 +2782,7 @@ void QTextEngine::splitItem(int item, int pos) const
QFixed w = 0;
const QGlyphLayout g = shapedGlyphs(&oldItem);
for(int j = 0; j < breakGlyph; ++j)
- w += g.advances_x[j] * !g.attributes[j].dontPrint;
+ w += g.advances[j] * !g.attributes[j].dontPrint;
newItem.width = oldItem.width - w;
oldItem.width = w;
@@ -2859,9 +2855,9 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const
QGlyphLayout glyphs = this->shapedGlyphs(&item);
const int end = qMin(item.position + item.num_glyphs, tabSectionEnd) - item.position;
for (int i=0; i < end; i++)
- length += glyphs.advances_x[i] * !glyphs.attributes[i].dontPrint;
+ length += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
if (end + item.position == tabSectionEnd && tabSpec.type == QTextOption::DelimiterTab) // remove half of matching char
- length -= glyphs.advances_x[end] / 2 * !glyphs.attributes[end].dontPrint;
+ length -= glyphs.advances[end] / 2 * !glyphs.attributes[end].dontPrint;
}
switch (tabSpec.type) {
@@ -2915,14 +2911,13 @@ public:
void QTextEngine::resolveAdditionalFormats() const
{
if (!specialData || specialData->addFormats.isEmpty()
- || !specialData->resolvedFormatIndices.isEmpty())
+ || !specialData->resolvedFormats.isEmpty())
return;
QTextFormatCollection *collection = formats();
- specialData->resolvedFormatIndices.clear();
- QVector<int> indices(layoutData->items.count());
-
+ specialData->resolvedFormats.clear();
+ QVector<QTextCharFormat> resolvedFormats(layoutData->items.count());
QVarLengthArray<int, 64> addFormatSortedByStart;
addFormatSortedByStart.reserve(specialData->addFormats.count());
@@ -2958,21 +2953,24 @@ void QTextEngine::resolveAdditionalFormats() const
currentFormats.remove(currentFormatIterator - currentFormats.begin());
++endIt;
}
- QTextCharFormat format;
+
+ QTextCharFormat &format = resolvedFormats[i];
if (block.docHandle()) {
// when we have a docHandle, formatIndex might still return a valid index based
// on the preeditPosition. for all other cases, we cleared the resolved format indices
format = collection->charFormat(formatIndex(si));
}
-
- foreach (int cur, currentFormats) {
- Q_ASSERT(specialData->addFormats.at(cur).start <= si->position
- && specialData->addFormats.at(cur).start + specialData->addFormats.at(cur).length >= end);
- format.merge(collection->format(specialData->addFormatIndices.at(cur)));
+ if (!currentFormats.isEmpty()) {
+ foreach (int cur, currentFormats) {
+ const QTextLayout::FormatRange &range = specialData->addFormats.at(cur);
+ Q_ASSERT(range.start <= si->position && range.start + range.length >= end);
+ format.merge(range.format);
+ }
+ format = collection->charFormat(collection->indexForFormat(format)); // get shared copy
}
- indices[i] = collection->indexForFormat(format);
}
- specialData->resolvedFormatIndices = indices;
+
+ specialData->resolvedFormats = resolvedFormats;
}
QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line)
@@ -3026,7 +3024,7 @@ QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, in
break;
}
if (clusterLength)
- return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
+ return glyphs.advances[glyph_pos] * offsetInCluster / clusterLength;
}
return 0;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index fb71ab40b8..1616a78937 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -190,11 +190,15 @@ Q_DECLARE_TYPEINFO(QGlyphJustification, Q_PRIMITIVE_TYPE);
struct QGlyphLayout
{
+ enum {
+ SpaceNeeded = sizeof(glyph_t) + sizeof(QFixed) + sizeof(QFixedPoint)
+ + sizeof(QGlyphAttributes) + sizeof(QGlyphJustification)
+ };
+
// init to 0 not needed, done when shaping
QFixedPoint *offsets; // 8 bytes per element
glyph_t *glyphs; // 4 bytes per element
- QFixed *advances_x; // 4 bytes per element
- QFixed *advances_y; // 4 bytes per element
+ QFixed *advances; // 4 bytes per element
QGlyphJustification *justifications; // 4 bytes per element
QGlyphAttributes *attributes; // 2 bytes per element
@@ -208,9 +212,7 @@ struct QGlyphLayout
int offset = totalGlyphs * sizeof(QFixedPoint);
glyphs = reinterpret_cast<glyph_t *>(address + offset);
offset += totalGlyphs * sizeof(glyph_t);
- advances_x = reinterpret_cast<QFixed *>(address + offset);
- offset += totalGlyphs * sizeof(QFixed);
- advances_y = reinterpret_cast<QFixed *>(address + offset);
+ advances = reinterpret_cast<QFixed *>(address + offset);
offset += totalGlyphs * sizeof(QFixed);
justifications = reinterpret_cast<QGlyphJustification *>(address + offset);
offset += totalGlyphs * sizeof(QGlyphJustification);
@@ -221,8 +223,7 @@ struct QGlyphLayout
inline QGlyphLayout mid(int position, int n = -1) const {
QGlyphLayout copy = *this;
copy.glyphs += position;
- copy.advances_x += position;
- copy.advances_y += position;
+ copy.advances += position;
copy.offsets += position;
copy.justifications += position;
copy.attributes += position;
@@ -233,27 +234,20 @@ struct QGlyphLayout
return copy;
}
- static inline int spaceNeededForGlyphLayout(int totalGlyphs) {
- return totalGlyphs * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification));
- }
-
inline QFixed effectiveAdvance(int item) const
- { return (advances_x[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
+ { return (advances[item] + QFixed::fromFixed(justifications[item].space_18d6)) * !attributes[item].dontPrint; }
inline void clear(int first = 0, int last = -1) {
if (last == -1)
last = numGlyphs;
if (first == 0 && last == numGlyphs
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
- memset(offsets, 0, spaceNeededForGlyphLayout(numGlyphs));
+ memset(offsets, 0, (numGlyphs * SpaceNeeded));
} else {
const int num = last - first;
memset(offsets + first, 0, num * sizeof(QFixedPoint));
memset(glyphs + first, 0, num * sizeof(glyph_t));
- memset(advances_x + first, 0, num * sizeof(QFixed));
- memset(advances_y + first, 0, num * sizeof(QFixed));
+ memset(advances + first, 0, num * sizeof(QFixed));
memset(justifications + first, 0, num * sizeof(QGlyphJustification));
memset(attributes + first, 0, num * sizeof(QGlyphAttributes));
}
@@ -272,7 +266,7 @@ private:
typedef QVarLengthArray<void *> Array;
public:
QVarLengthGlyphLayoutArray(int totalGlyphs)
- : Array(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1)
+ : Array((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1)
, QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs)
{
memset(Array::data(), 0, Array::size() * sizeof(void *));
@@ -280,7 +274,7 @@ public:
void resize(int totalGlyphs)
{
- Array::resize(spaceNeededForGlyphLayout(totalGlyphs) / sizeof(void *) + 1);
+ Array::resize((totalGlyphs * SpaceNeeded) / sizeof(void *) + 1);
*((QGlyphLayout *)this) = QGlyphLayout(reinterpret_cast<char *>(Array::data()), totalGlyphs);
memset(Array::data(), 0, Array::size() * sizeof(void *));
@@ -297,10 +291,7 @@ public:
}
private:
- void *buffer[(N * (sizeof(glyph_t) + sizeof(QGlyphAttributes)
- + sizeof(QFixed) + sizeof(QFixed) + sizeof(QFixedPoint)
- + sizeof(QGlyphJustification)))
- / sizeof(void *) + 1];
+ void *buffer[(N * SpaceNeeded) / sizeof(void *) + 1];
};
struct QScriptItem;
@@ -449,7 +440,6 @@ public:
typedef QList<ItemDecoration> ItemDecorationList;
- QTextEngine(LayoutData *data);
QTextEngine();
QTextEngine(const QString &str, const QFont &f);
~QTextEngine();
@@ -553,6 +543,7 @@ public:
mutable QScriptLineArray lines;
+private:
struct FontEngineCache {
FontEngineCache();
mutable QFontEngine *prevFontEngine;
@@ -570,6 +561,7 @@ public:
};
mutable FontEngineCache feCache;
+public:
QString text;
mutable QFont fnt;
#ifndef QT_NO_RAWFONT
@@ -611,7 +603,8 @@ public:
void setPreeditArea(int position, const QString &text);
inline bool hasFormats() const { return block.docHandle() || (specialData && !specialData->addFormats.isEmpty()); }
- QList<QTextLayout::FormatRange> additionalFormats() const;
+ inline QList<QTextLayout::FormatRange> additionalFormats() const
+ { return specialData ? specialData->addFormats : QList<QTextLayout::FormatRange>(); }
void setAdditionalFormats(const QList<QTextLayout::FormatRange> &formatList);
private:
@@ -621,8 +614,7 @@ private:
int preeditPosition;
QString preeditText;
QList<QTextLayout::FormatRange> addFormats;
- QVector<int> addFormatIndices;
- QVector<int> resolvedFormatIndices;
+ QVector<QTextCharFormat> resolvedFormats;
// only used when no docHandle is available
QScopedPointer<QTextFormatCollection> formats;
};
diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp
index 2389427da0..4854af0d01 100644
--- a/src/gui/text/qtextformat.cpp
+++ b/src/gui/text/qtextformat.cpp
@@ -524,7 +524,7 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
\value BlockFormat The object formats a text block
\value CharFormat The object formats a single character
\value ListFormat The object formats a list
- \value TableFormat The object formats a table
+ \omitvalue TableFormat Unused Value, a table's FormatType is FrameFormat.
\value FrameFormat The object formats a frame
\value UserFormat
@@ -706,6 +706,15 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
*/
/*!
+ \fn bool QTextFormat::isEmpty() const
+ \since 5.3
+
+ Returns true if the format does not store any properties; false otherwise.
+
+ \sa propertyCount(), properties()
+*/
+
+/*!
\fn bool QTextFormat::isCharFormat() const
Returns \c true if this text format is a \c CharFormat; otherwise
@@ -1870,36 +1879,93 @@ QStringList QTextCharFormat::anchorNames() const
*/
/*!
+ \enum QTextCharFormat::FontPropertiesInheritanceBehavior
+ \since 5.3
+
+ This enum specifies how the setFont() function should behave with
+ respect to unset font properties.
+
+ \value FontPropertiesSpecifiedOnly If a property is not explicitly set, do not
+ change the text format's property value.
+ \value FontPropertiesAll If a property is not explicitly set, override the
+ text format's property with a default value.
+
+ \sa setFont()
+*/
+
+/*!
+ \overload
+
Sets the text format's \a font.
+
+ \sa font()
*/
void QTextCharFormat::setFont(const QFont &font)
{
- setFontFamily(font.family());
+ setFont(font, FontPropertiesAll);
+}
- const qreal pointSize = font.pointSizeF();
- if (pointSize > 0) {
- setFontPointSize(pointSize);
- } else {
- const int pixelSize = font.pixelSize();
- if (pixelSize > 0)
- setProperty(QTextFormat::FontPixelSize, pixelSize);
+/*!
+ \since 5.3
+
+ Sets the text format's \a font.
+
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is treated like as it were set with default value;
+ If \a behavior is QTextCharFormat::FontPropertiesAll, the font property that
+ has not been explicitly set is ignored and the respective property value
+ remains unchanged.
+
+ \sa font()
+*/
+void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior)
+{
+ const uint mask = behavior == FontPropertiesAll ? uint(QFont::AllPropertiesResolved)
+ : font.resolve();
+
+ if (mask & QFont::FamilyResolved)
+ setFontFamily(font.family());
+ if (mask & QFont::SizeResolved) {
+ const qreal pointSize = font.pointSizeF();
+ if (pointSize > 0) {
+ setFontPointSize(pointSize);
+ } else {
+ const int pixelSize = font.pixelSize();
+ if (pixelSize > 0)
+ setProperty(QTextFormat::FontPixelSize, pixelSize);
+ }
}
- setFontWeight(font.weight());
- setFontItalic(font.italic());
- setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
- setFontOverline(font.overline());
- setFontStrikeOut(font.strikeOut());
- setFontFixedPitch(font.fixedPitch());
- setFontCapitalization(font.capitalization());
- setFontWordSpacing(font.wordSpacing());
- setFontLetterSpacingType(font.letterSpacingType());
- setFontLetterSpacing(font.letterSpacing());
- setFontStretch(font.stretch());
- setFontStyleHint(font.styleHint());
- setFontStyleStrategy(font.styleStrategy());
- setFontHintingPreference(font.hintingPreference());
- setFontKerning(font.kerning());
+ if (mask & QFont::WeightResolved)
+ setFontWeight(font.weight());
+ if (mask & QFont::StyleResolved)
+ setFontItalic(font.style() != QFont::StyleNormal);
+ if (mask & QFont::UnderlineResolved)
+ setUnderlineStyle(font.underline() ? SingleUnderline : NoUnderline);
+ if (mask & QFont::OverlineResolved)
+ setFontOverline(font.overline());
+ if (mask & QFont::StrikeOutResolved)
+ setFontStrikeOut(font.strikeOut());
+ if (mask & QFont::FixedPitchResolved)
+ setFontFixedPitch(font.fixedPitch());
+ if (mask & QFont::CapitalizationResolved)
+ setFontCapitalization(font.capitalization());
+ if (mask & QFont::LetterSpacingResolved)
+ setFontWordSpacing(font.wordSpacing());
+ if (mask & QFont::LetterSpacingResolved) {
+ setFontLetterSpacingType(font.letterSpacingType());
+ setFontLetterSpacing(font.letterSpacing());
+ }
+ if (mask & QFont::StretchResolved)
+ setFontStretch(font.stretch());
+ if (mask & QFont::StyleHintResolved)
+ setFontStyleHint(font.styleHint());
+ if (mask & QFont::StyleStrategyResolved)
+ setFontStyleStrategy(font.styleStrategy());
+ if (mask & QFont::HintingPreferenceResolved)
+ setFontHintingPreference(font.hintingPreference());
+ if (mask & QFont::KerningResolved)
+ setFontKerning(font.kerning());
}
/*!
@@ -3376,19 +3442,6 @@ bool QTextFormatCollection::hasFormatCached(const QTextFormat &format) const
return false;
}
-QTextFormat QTextFormatCollection::objectFormat(int objectIndex) const
-{
- if (objectIndex == -1)
- return QTextFormat();
- return format(objFormats.at(objectIndex));
-}
-
-void QTextFormatCollection::setObjectFormat(int objectIndex, const QTextFormat &f)
-{
- const int formatIndex = indexForFormat(f);
- objFormats[objectIndex] = formatIndex;
-}
-
int QTextFormatCollection::objectFormatIndex(int objectIndex) const
{
if (objectIndex == -1)
diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h
index 2098369811..5369001a03 100644
--- a/src/gui/text/qtextformat.h
+++ b/src/gui/text/qtextformat.h
@@ -141,7 +141,9 @@ public:
BlockFormat = 1,
CharFormat = 2,
ListFormat = 3,
+#if QT_DEPRECATED_SINCE(5, 3)
TableFormat = 4,
+#endif
FrameFormat = 5,
UserFormat = 100
@@ -295,6 +297,7 @@ public:
void merge(const QTextFormat &other);
inline bool isValid() const { return type() != InvalidFormat; }
+ inline bool isEmpty() const { return propertyCount() == 0; }
int type() const;
@@ -407,7 +410,13 @@ public:
QTextCharFormat();
bool isValid() const { return isCharFormat(); }
- void setFont(const QFont &font);
+
+ enum FontPropertiesInheritanceBehavior {
+ FontPropertiesSpecifiedOnly,
+ FontPropertiesAll
+ };
+ void setFont(const QFont &font, FontPropertiesInheritanceBehavior behavior);
+ void setFont(const QFont &font); // ### Qt6: Merge with above
QFont font() const;
inline void setFontFamily(const QString &family)
diff --git a/src/gui/text/qtextformat_p.h b/src/gui/text/qtextformat_p.h
index 6b2958a4b6..e3998d4f3f 100644
--- a/src/gui/text/qtextformat_p.h
+++ b/src/gui/text/qtextformat_p.h
@@ -68,8 +68,10 @@ public:
QTextFormatCollection(const QTextFormatCollection &rhs);
QTextFormatCollection &operator=(const QTextFormatCollection &rhs);
- QTextFormat objectFormat(int objectIndex) const;
- void setObjectFormat(int objectIndex, const QTextFormat &format);
+ inline QTextFormat objectFormat(int objectIndex) const
+ { return format(objectFormatIndex(objectIndex)); }
+ inline void setObjectFormat(int objectIndex, const QTextFormat &format)
+ { setObjectFormatIndex(objectIndex, indexForFormat(format)); }
int objectFormatIndex(int objectIndex) const;
void setObjectFormatIndex(int objectIndex, int formatIndex);
diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp
index 3cb61b9eae..e8a02c44b2 100644
--- a/src/gui/text/qtexthtmlparser.cpp
+++ b/src/gui/text/qtexthtmlparser.cpp
@@ -1361,33 +1361,7 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector<QCss::Declaration>
QFont f;
int adjustment = -255;
extractor.extractFont(&f, &adjustment);
- if (f.resolve() & QFont::SizeResolved) {
- if (f.pointSize() > 0) {
- charFormat.setFontPointSize(f.pointSize());
- } else if (f.pixelSize() > 0) {
- charFormat.setProperty(QTextFormat::FontPixelSize, f.pixelSize());
- }
- }
- if (f.resolve() & QFont::StyleResolved)
- charFormat.setFontItalic(f.style() != QFont::StyleNormal);
-
- if (f.resolve() & QFont::WeightResolved)
- charFormat.setFontWeight(f.weight());
-
- if (f.resolve() & QFont::FamilyResolved)
- charFormat.setFontFamily(f.family());
-
- if (f.resolve() & QFont::UnderlineResolved)
- charFormat.setUnderlineStyle(f.underline() ? QTextCharFormat::SingleUnderline : QTextCharFormat::NoUnderline);
-
- if (f.resolve() & QFont::OverlineResolved)
- charFormat.setFontOverline(f.overline());
-
- if (f.resolve() & QFont::StrikeOutResolved)
- charFormat.setFontStrikeOut(f.strikeOut());
-
- if (f.resolve() & QFont::CapitalizationResolved)
- charFormat.setFontCapitalization(f.capitalization());
+ charFormat.setFont(f, QTextCharFormat::FontPropertiesSpecifiedOnly);
if (adjustment >= -1)
charFormat.setProperty(QTextFormat::FontSizeAdjustment, adjustment);
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 66341e186a..0c9866c6cf 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -239,9 +239,7 @@ int QTextInlineObject::formatIndex() const
*/
QTextFormat QTextInlineObject::format() const
{
- if (!eng->block.docHandle())
- return QTextFormat();
- return eng->formats()->format(eng->formatIndex(&eng->layoutData->items[itm]));
+ return eng->format(&eng->layoutData->items[itm]);
}
/*!
@@ -1693,7 +1691,7 @@ static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &gly
} while (pos < end && logClusters[pos] == glyphPosition);
do { // calculate the textWidth for the rest of the current cluster.
if (!glyphs.attributes[glyphPosition].dontPrint)
- line.textWidth += glyphs.advances_x[glyphPosition];
+ line.textWidth += glyphs.advances[glyphPosition];
++glyphPosition;
} while (glyphPosition < current.num_glyphs && !glyphs.attributes[glyphPosition].clusterStart);
@@ -1812,9 +1810,10 @@ void QTextLine::layout_helper(int maxGlyphs)
lbh.whiteSpaceOrObject = true;
lbh.tmpData.length++;
- QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));
- if (eng->block.docHandle())
- eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format);
+ if (eng->block.docHandle()) {
+ QTextInlineObject inlineObject(item, eng);
+ eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, inlineObject.format());
+ }
lbh.tmpData.textWidth += current.width;
@@ -1871,9 +1870,9 @@ void QTextLine::layout_helper(int maxGlyphs)
// and thus become invisible again.
//
if (line.length)
- lbh.softHyphenWidth = lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
+ lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
else if (breakany)
- lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
+ lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
}
// The actual width of the text needs to take the right bearing into account. The
@@ -2249,14 +2248,12 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
if (relativeFrom != (iterator.itemStart - si.position) && !rtl) {
for (int i=itemGlyphsStart; i<glyphsStart; ++i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
- pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
- glyphLayout.advances_y[i].toReal());
+ pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
} else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) {
for (int i=itemGlyphsEnd; i>glyphsEnd; --i) {
QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
- pos += QPointF((glyphLayout.advances_x[i] + justification).toReal(),
- glyphLayout.advances_y[i].toReal());
+ pos.rx() += (glyphLayout.advances[i] + justification).toReal();
}
}
@@ -2295,10 +2292,8 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which),
subLayout, pos, subFlags, x, width));
- for (int i = 0; i < subLayout.numGlyphs; i++) {
- pos += QPointF(subLayout.advances_x[i].toReal(),
- subLayout.advances_y[i].toReal());
- }
+ for (int i = 0; i < subLayout.numGlyphs; ++i)
+ pos.rx() += subLayout.advances[i].toReal();
if (rtl)
end = start;
diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp
index d1a39c6ab6..bd1e970583 100644
--- a/src/gui/text/qtextobject.cpp
+++ b/src/gui/text/qtextobject.cpp
@@ -1233,6 +1233,56 @@ QString QTextBlock::text() const
return text;
}
+/*!
+ \since 5.3
+
+ Returns the block's text format options as a list of continuous ranges
+ of QTextCharFormat. The range's character format is used when inserting text
+ within the range boundaries.
+
+ \sa charFormat(), blockFormat()
+*/
+QList<QTextLayout::FormatRange> QTextBlock::textFormats() const
+{
+ QList<QTextLayout::FormatRange> formats;
+ if (!p || !n)
+ return formats;
+
+ const QTextFormatCollection *formatCollection = p->formatCollection();
+
+ int start = 0;
+ int cur = start;
+ int format = -1;
+
+ const int pos = position();
+ QTextDocumentPrivate::FragmentIterator it = p->find(pos);
+ QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char
+ for (; it != end; ++it) {
+ const QTextFragmentData * const frag = it.value();
+ if (format != it.value()->format) {
+ if (cur - start > 0) {
+ QTextLayout::FormatRange range;
+ range.start = start;
+ range.length = cur - start;
+ range.format = formatCollection->charFormat(format);
+ formats.append(range);
+ }
+
+ format = frag->format;
+ start = cur;
+ }
+ cur += frag->size_array[0];
+ }
+ if (cur - start > 0) {
+ QTextLayout::FormatRange range;
+ range.start = start;
+ range.length = cur - start;
+ range.format = formatCollection->charFormat(format);
+ formats.append(range);
+ }
+
+ return formats;
+}
/*!
Returns the text document this text block belongs to, or 0 if the
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index 87f2cf6197..6a127f0315 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -44,6 +44,7 @@
#include <QtCore/qobject.h>
#include <QtGui/qtextformat.h>
+#include <QtGui/qtextlayout.h>
#include <QtGui/qglyphrun.h>
QT_BEGIN_NAMESPACE
@@ -55,7 +56,6 @@ class QTextDocumentPrivate;
class QTextCursor;
class QTextBlock;
class QTextFragment;
-class QTextLayout;
class QTextList;
class Q_GUI_EXPORT QTextObject : public QObject
@@ -223,6 +223,8 @@ public:
QString text() const;
+ QList<QTextLayout::FormatRange> textFormats() const;
+
const QTextDocument *document() const;
QTextList *textList() const;
diff --git a/src/gui/util/qabstractlayoutstyleinfo.cpp b/src/gui/util/qabstractlayoutstyleinfo.cpp
new file mode 100644
index 0000000000..4f7c635594
--- /dev/null
+++ b/src/gui/util/qabstractlayoutstyleinfo.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractlayoutstyleinfo_p.h"
+
+QT_BEGIN_NAMESPACE
+
+bool QAbstractLayoutStyleInfo::hasChanged() const
+{
+ if (m_changed == Unknown)
+ m_changed = hasChangedCore() ? Changed : Unchanged;
+ return m_changed == Changed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qabstractlayoutstyleinfo_p.h b/src/gui/util/qabstractlayoutstyleinfo_p.h
new file mode 100644
index 0000000000..52f151c5d2
--- /dev/null
+++ b/src/gui/util/qabstractlayoutstyleinfo_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTLAYOUTSTYLEINFO_P_H
+#define QABSTRACTLAYOUTSTYLEINFO_P_H
+
+#include <QtCore/qnamespace.h>
+#include "qlayoutpolicy_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+class Q_GUI_EXPORT QAbstractLayoutStyleInfo {
+public:
+ typedef enum {
+ Unknown = 0,
+ Changed,
+ Unchanged
+ } ChangedState;
+
+ QAbstractLayoutStyleInfo() : m_isWindow(false), m_changed(Changed) {}
+ virtual ~QAbstractLayoutStyleInfo() {}
+ virtual qreal combinedLayoutSpacing(QLayoutPolicy::ControlTypes /*controls1*/,
+ QLayoutPolicy::ControlTypes /*controls2*/, Qt::Orientation /*orientation*/) const {
+ return -1;
+ }
+
+ virtual qreal perItemSpacing(QLayoutPolicy::ControlType /*control1*/,
+ QLayoutPolicy::ControlType /*control2*/,
+ Qt::Orientation /*orientation*/) const {
+ return -1;
+ }
+
+ virtual qreal spacing(Qt::Orientation orientation) const = 0;
+
+ virtual bool hasChangedCore() const = 0;
+
+ void updateChanged(ChangedState change) {
+ m_changed = change;
+ }
+
+ bool hasChanged() const;
+
+ virtual void invalidate() { updateChanged(Changed);}
+
+ virtual qreal windowMargin(Qt::Orientation orientation) const = 0;
+
+ bool isWindow() const {
+ return m_isWindow;
+ }
+
+protected:
+ unsigned m_isWindow : 1;
+ mutable unsigned m_changed : 2;
+};
+
+QT_END_NAMESPACE
+
+#endif // QABSTRACTLAYOUTSTYLEINFO_P_H
diff --git a/src/widgets/graphicsview/qgridlayoutengine.cpp b/src/gui/util/qgridlayoutengine.cpp
index a1affdb55e..10b4a2ee35 100644
--- a/src/widgets/graphicsview/qgridlayoutengine.cpp
+++ b/src/gui/util/qgridlayoutengine.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtWidgets module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -45,9 +45,7 @@
#include <math.h>
-#include "qgraphicslayoutitem.h"
#include "qgridlayoutengine_p.h"
-#include "qstyleoption.h"
#include "qvarlengtharray.h"
#include <QtDebug>
@@ -138,7 +136,7 @@ void QGridLayoutBox::normalize()
Q_ASSERT((q_minimumDescent < 0.0) == (q_minimumAscent < 0.0));
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGridLayoutBox::dump(int indent) const
{
qDebug("%*sBox (%g <= %g <= %g [%g/%g])", indent, "", q_minimumSize, q_preferredSize,
@@ -462,7 +460,7 @@ void QGridLayoutRowData::stealBox(int start, int end, int which, qreal *position
}
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGridLayoutRowData::dump(int indent) const
{
qDebug("%*sData", indent, "");
@@ -484,10 +482,9 @@ void QGridLayoutRowData::dump(int indent) const
}
#endif
-QGridLayoutItem::QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem *layoutItem,
- int row, int column, int rowSpan, int columnSpan,
- Qt::Alignment alignment, int itemAtIndex)
- : q_engine(engine), q_layoutItem(layoutItem), q_alignment(alignment)
+QGridLayoutItem::QGridLayoutItem(int row, int column, int rowSpan, int columnSpan,
+ Qt::Alignment alignment)
+ : q_alignment(alignment)
{
q_firstRows[Hor] = column;
q_firstRows[Ver] = row;
@@ -495,8 +492,6 @@ QGridLayoutItem::QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem
q_rowSpans[Ver] = rowSpan;
q_stretches[Hor] = -1;
q_stretches[Ver] = -1;
-
- q_engine->insertItem(this, itemAtIndex);
}
int QGridLayoutItem::firstRow(Qt::Orientation orientation) const
@@ -545,11 +540,11 @@ int QGridLayoutItem::stretchFactor(Qt::Orientation orientation) const
if (stretch >= 0)
return stretch;
- QSizePolicy::Policy policy = sizePolicy(orientation);
+ QLayoutPolicy::Policy policy = sizePolicy(orientation);
- if (policy & QSizePolicy::ExpandFlag) {
+ if (policy & QLayoutPolicy::ExpandFlag) {
return 1;
- } else if (policy & QSizePolicy::GrowFlag) {
+ } else if (policy & QLayoutPolicy::GrowFlag) {
return -1; // because we max it up
} else {
return 0;
@@ -562,58 +557,28 @@ void QGridLayoutItem::setStretchFactor(int stretch, Qt::Orientation orientation)
q_stretches[orientation == Qt::Vertical] = stretch;
}
-QSizePolicy::Policy QGridLayoutItem::sizePolicy(Qt::Orientation orientation) const
-{
- QSizePolicy sizePolicy(q_layoutItem->sizePolicy());
- return (orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy()
- : sizePolicy.verticalPolicy();
-}
-
-/*
- returns \c true if the size policy returns \c true for either hasHeightForWidth()
- or hasWidthForHeight()
- */
-bool QGridLayoutItem::hasDynamicConstraint() const
-{
- return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()
- || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight();
-}
-
-Qt::Orientation QGridLayoutItem::dynamicConstraintOrientation() const
-{
- if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth())
- return Qt::Vertical;
- else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight())
- return Qt::Horizontal;
-}
-
-QSizePolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /* side */) const
-{
- return q_layoutItem->sizePolicy().controlType();
-}
-
-QSizeF QGridLayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+QLayoutPolicy::ControlTypes QGridLayoutItem::controlTypes(LayoutSide /*side*/) const
{
- return q_layoutItem->effectiveSizeHint(which, constraint);
+ return QLayoutPolicy::DefaultType;
}
QGridLayoutBox QGridLayoutItem::box(Qt::Orientation orientation, qreal constraint) const
{
QGridLayoutBox result;
- QSizePolicy::Policy policy = sizePolicy(orientation);
+ QLayoutPolicy::Policy policy = sizePolicy(orientation);
if (orientation == Qt::Horizontal) {
QSizeF constraintSize(-1.0, constraint);
result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).width();
- if (policy & QSizePolicy::ShrinkFlag) {
+ if (policy & QLayoutPolicy::ShrinkFlag) {
result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).width();
} else {
result.q_minimumSize = result.q_preferredSize;
}
- if (policy & (QSizePolicy::GrowFlag | QSizePolicy::ExpandFlag)) {
+ if (policy & (QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag)) {
result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).width();
} else {
result.q_maximumSize = result.q_preferredSize;
@@ -623,84 +588,82 @@ QGridLayoutBox QGridLayoutItem::box(Qt::Orientation orientation, qreal constrain
result.q_preferredSize = sizeHint(Qt::PreferredSize, constraintSize).height();
- if (policy & QSizePolicy::ShrinkFlag) {
+ if (policy & QLayoutPolicy::ShrinkFlag) {
result.q_minimumSize = sizeHint(Qt::MinimumSize, constraintSize).height();
} else {
result.q_minimumSize = result.q_preferredSize;
}
- if (policy & (QSizePolicy::GrowFlag | QSizePolicy::ExpandFlag)) {
+ if (policy & (QLayoutPolicy::GrowFlag | QLayoutPolicy::ExpandFlag)) {
result.q_maximumSize = sizeHint(Qt::MaximumSize, constraintSize).height();
} else {
result.q_maximumSize = result.q_preferredSize;
}
- result.q_minimumDescent = sizeHint(Qt::MinimumDescent, constraintSize).height();
- if (result.q_minimumDescent >= 0.0)
- result.q_minimumAscent = result.q_minimumSize - result.q_minimumDescent;
+ if (alignment() & Qt::AlignBaseline) {
+ result.q_minimumDescent = sizeHint(Qt::MinimumDescent, constraintSize).height();
+ if (result.q_minimumDescent != -1.0) {
+ const qreal minSizeHint = sizeHint(Qt::MinimumSize, constraintSize).height();
+ result.q_minimumDescent -= (minSizeHint - result.q_minimumSize);
+ result.q_minimumAscent = result.q_minimumSize - result.q_minimumDescent;
+ }
+ }
}
- if (policy & QSizePolicy::IgnoreFlag)
+ if (policy & QLayoutPolicy::IgnoreFlag)
result.q_preferredSize = result.q_minimumSize;
return result;
}
QRectF QGridLayoutItem::geometryWithin(qreal x, qreal y, qreal width, qreal height,
- qreal rowDescent) const
-{
- rowDescent = -1.0; // ### This disables the descent
-
- QGridLayoutBox vBox = box(Qt::Vertical);
- if (vBox.q_minimumDescent < 0.0 || rowDescent < 0.0) {
- qreal cellWidth = width;
- qreal cellHeight = height;
-
-
- QSizeF size = effectiveMaxSize(QSizeF(-1,-1));
- if (hasDynamicConstraint()) {
- if (dynamicConstraintOrientation() == Qt::Vertical) {
- if (size.width() > cellWidth)
- size = effectiveMaxSize(QSizeF(cellWidth, -1));
- } else if (size.height() > cellHeight) {
- size = effectiveMaxSize(QSizeF(-1, cellHeight));
- }
- }
- size = size.boundedTo(QSizeF(cellWidth, cellHeight));
- width = size.width();
- height = size.height();
-
- Qt::Alignment align = q_engine->effectiveAlignment(this);
- switch (align & Qt::AlignHorizontal_Mask) {
- case Qt::AlignHCenter:
- x += (cellWidth - width)/2;
- break;
- case Qt::AlignRight:
- x += cellWidth - width;
- break;
- default:
- break;
+ qreal rowDescent, Qt::Alignment align) const
+{
+ const qreal cellWidth = width;
+ const qreal cellHeight = height;
+
+ QSizeF size = effectiveMaxSize(QSizeF(-1,-1));
+ if (hasDynamicConstraint()) {
+ if (dynamicConstraintOrientation() == Qt::Vertical) {
+ if (size.width() > cellWidth)
+ size = effectiveMaxSize(QSizeF(cellWidth, -1));
+ } else if (size.height() > cellHeight) {
+ size = effectiveMaxSize(QSizeF(-1, cellHeight));
}
- switch (align & Qt::AlignVertical_Mask) {
- case Qt::AlignVCenter:
- y += (cellHeight - height)/2;
- break;
- case Qt::AlignBottom:
- y += cellHeight - height;
- break;
- default:
- break;
- }
- return QRectF(x, y, width, height);
- } else {
- qreal descent = vBox.q_minimumDescent;
- qreal ascent = vBox.q_minimumSize - descent;
- return QRectF(x, y + height - rowDescent - ascent, width, ascent + descent);
}
-}
+ size = size.boundedTo(QSizeF(cellWidth, cellHeight));
+ width = size.width();
+ height = size.height();
-void QGridLayoutItem::setGeometry(const QRectF &rect)
-{
- q_layoutItem->setGeometry(rect);
+ switch (align & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignHCenter:
+ x += (cellWidth - width)/2;
+ break;
+ case Qt::AlignRight:
+ x += cellWidth - width;
+ break;
+ default:
+ break;
+ }
+
+ switch (align & Qt::AlignVertical_Mask) {
+ case Qt::AlignVCenter:
+ y += (cellHeight - height)/2;
+ break;
+ case Qt::AlignBottom:
+ y += cellHeight - height;
+ break;
+ case Qt::AlignBaseline: {
+ width = qMin(effectiveMaxSize(QSizeF(-1,-1)).width(), width);
+ QGridLayoutBox vBox = box(Qt::Vertical);
+ const qreal descent = vBox.q_minimumDescent;
+ const qreal ascent = vBox.q_minimumSize - descent;
+ y += (cellHeight - rowDescent - ascent);
+ height = ascent + descent;
+ break; }
+ default:
+ break;
+ }
+ return QRectF(x, y, width, height);
}
void QGridLayoutItem::transpose()
@@ -722,7 +685,7 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori
/*!
\internal
returns the effective maximumSize, will take the sizepolicy into
- consideration. (i.e. if sizepolicy does not have QSizePolicy::Grow, then
+ consideration. (i.e. if sizepolicy does not have QLayoutPolicy::Grow, then
maxSizeHint will be the preferredSize)
Note that effectiveSizeHint does not take sizePolicy into consideration,
(since it only evaluates the hints, as the name implies)
@@ -730,10 +693,10 @@ void QGridLayoutItem::insertOrRemoveRows(int row, int delta, Qt::Orientation ori
QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const
{
QSizeF size = constraint;
- bool vGrow = (sizePolicy(Qt::Vertical) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag;
- bool hGrow = (sizePolicy(Qt::Horizontal) & QSizePolicy::GrowFlag) == QSizePolicy::GrowFlag;
+ bool vGrow = (sizePolicy(Qt::Vertical) & QLayoutPolicy::GrowFlag) == QLayoutPolicy::GrowFlag;
+ bool hGrow = (sizePolicy(Qt::Horizontal) & QLayoutPolicy::GrowFlag) == QLayoutPolicy::GrowFlag;
if (!vGrow || !hGrow) {
- QSizeF pref = layoutItem()->effectiveSizeHint(Qt::PreferredSize, constraint);
+ QSizeF pref = sizeHint(Qt::PreferredSize, constraint);
if (!vGrow)
size.setHeight(pref.height());
if (!hGrow)
@@ -741,7 +704,7 @@ QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const
}
if (!size.isValid()) {
- QSizeF maxSize = layoutItem()->effectiveSizeHint(Qt::MaximumSize, size);
+ QSizeF maxSize = sizeHint(Qt::MaximumSize, size);
if (size.width() == -1)
size.setWidth(maxSize.width());
if (size.height() == -1)
@@ -750,10 +713,10 @@ QSizeF QGridLayoutItem::effectiveMaxSize(const QSizeF &constraint) const
return size;
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGridLayoutItem::dump(int indent) const
{
- qDebug("%*s%p (%d, %d) %d x %d", indent, "", q_layoutItem, firstRow(), firstColumn(),
+ qDebug("%*s (%d, %d) %d x %d", indent, "", firstRow(), firstColumn(), //###
rowSpan(), columnSpan());
if (q_stretches[Hor] >= 0)
@@ -777,7 +740,7 @@ void QGridLayoutRowInfo::insertOrRemoveRows(int row, int delta)
insertOrRemoveItems(boxes, row, delta);
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGridLayoutRowInfo::dump(int indent) const
{
qDebug("%*sInfo (count: %d)", indent, "", count);
@@ -800,9 +763,10 @@ void QGridLayoutRowInfo::dump(int indent) const
}
#endif
-QGridLayoutEngine::QGridLayoutEngine()
+QGridLayoutEngine::QGridLayoutEngine(Qt::Alignment defaultAlignment)
{
m_visualDirection = Qt::LeftToRight;
+ m_defaultAlignment = defaultAlignment;
invalidate();
}
@@ -827,15 +791,6 @@ QGridLayoutItem *QGridLayoutEngine::itemAt(int index) const
return q_items.at(index);
}
-int QGridLayoutEngine::indexOf(QGraphicsLayoutItem *item) const
-{
- for (int i = 0; i < q_items.size(); ++i) {
- if (item == q_items.at(i)->layoutItem())
- return i;
- }
- return -1;
-}
-
int QGridLayoutEngine::effectiveFirstRow(Qt::Orientation orientation) const
{
ensureEffectiveFirstAndLastRows();
@@ -850,7 +805,6 @@ int QGridLayoutEngine::effectiveLastRow(Qt::Orientation orientation) const
void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations)
{
- Q_ASSERT(spacing >= 0.0);
if (orientations & Qt::Horizontal)
q_defaultSpacings[Hor].setUserValue(spacing);
if (orientations & Qt::Vertical)
@@ -859,14 +813,10 @@ void QGridLayoutEngine::setSpacing(qreal spacing, Qt::Orientations orientations)
invalidate();
}
-qreal QGridLayoutEngine::spacing(const QLayoutStyleInfo &styleInfo, Qt::Orientation orientation) const
+qreal QGridLayoutEngine::spacing(Qt::Orientation orientation, const QAbstractLayoutStyleInfo *styleInfo) const
{
- if (q_defaultSpacings[orientation == Qt::Vertical].isDefault()) {
- QStyle *style = styleInfo.style();
- QStyleOption option;
- option.initFrom(styleInfo.widget());
- qreal defaultSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing
- : QStyle::PM_LayoutHorizontalSpacing, &option, styleInfo.widget());
+ if (!q_defaultSpacings[orientation == Qt::Vertical].isUser()) {
+ qreal defaultSpacing = styleInfo->spacing(orientation);
q_defaultSpacings[orientation == Qt::Vertical].setCachedValue(defaultSpacing);
}
return q_defaultSpacings[orientation == Qt::Vertical].value();
@@ -915,22 +865,6 @@ int QGridLayoutEngine::rowStretchFactor(int row, Qt::Orientation orientation) co
return 0;
}
-void QGridLayoutEngine::setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch,
- Qt::Orientation orientation)
-{
- Q_ASSERT(stretch >= 0);
-
- if (QGridLayoutItem *item = findLayoutItem(layoutItem))
- item->setStretchFactor(stretch, orientation);
-}
-
-int QGridLayoutEngine::stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const
-{
- if (QGridLayoutItem *item = findLayoutItem(layoutItem))
- return item->stretchFactor(orientation);
- return 0;
-}
-
void QGridLayoutEngine::setRowSizeHint(Qt::SizeHint which, int row, qreal size,
Qt::Orientation orientation)
{
@@ -969,20 +903,6 @@ Qt::Alignment QGridLayoutEngine::rowAlignment(int row, Qt::Orientation orientati
return q_infos[orientation == Qt::Vertical].alignments.value(row);
}
-void QGridLayoutEngine::setAlignment(QGraphicsLayoutItem *layoutItem, Qt::Alignment alignment)
-{
- if (QGridLayoutItem *item = findLayoutItem(layoutItem))
- item->setAlignment(alignment);
- invalidate();
-}
-
-Qt::Alignment QGridLayoutEngine::alignment(QGraphicsLayoutItem *layoutItem) const
-{
- if (QGridLayoutItem *item = findLayoutItem(layoutItem))
- return item->alignment();
- return 0;
-}
-
Qt::Alignment QGridLayoutEngine::effectiveAlignment(const QGridLayoutItem *layoutItem) const
{
Qt::Alignment align = layoutItem->alignment();
@@ -990,12 +910,15 @@ Qt::Alignment QGridLayoutEngine::effectiveAlignment(const QGridLayoutItem *layou
// no vertical alignment, respect the row alignment
int y = layoutItem->firstRow();
align |= (rowAlignment(y, Qt::Vertical) & Qt::AlignVertical_Mask);
+ if (!(align & Qt::AlignVertical_Mask))
+ align |= (m_defaultAlignment & Qt::AlignVertical_Mask);
}
if (!(align & Qt::AlignHorizontal_Mask)) {
// no horizontal alignment, respect the column alignment
int x = layoutItem->firstColumn();
align |= (rowAlignment(x, Qt::Horizontal) & Qt::AlignHorizontal_Mask);
}
+
return align;
}
@@ -1044,15 +967,6 @@ void QGridLayoutEngine::removeItem(QGridLayoutItem *item)
q_items.removeAll(item);
}
-QGridLayoutItem *QGridLayoutEngine::findLayoutItem(QGraphicsLayoutItem *layoutItem) const
-{
- for (int i = q_items.count() - 1; i >= 0; --i) {
- QGridLayoutItem *item = q_items.at(i);
- if (item->layoutItem() == layoutItem)
- return item;
- }
- return 0;
-}
QGridLayoutItem *QGridLayoutEngine::itemAt(int row, int column, Qt::Orientation orientation) const
{
@@ -1069,7 +983,9 @@ void QGridLayoutEngine::invalidate()
q_cachedEffectiveFirstRows[Ver] = -1;
q_cachedEffectiveLastRows[Hor] = -1;
q_cachedEffectiveLastRows[Ver] = -1;
- q_cachedDataForStyleInfo.invalidate();
+ q_totalBoxesValid = false;
+ q_sizeHintValid[Hor] = false;
+ q_sizeHintValid[Ver] = false;
q_cachedSize = QSizeF();
q_cachedConstraintOrientation = UnknownConstraint;
}
@@ -1080,13 +996,12 @@ static void visualRect(QRectF *geom, Qt::LayoutDirection dir, const QRectF &cont
geom->moveRight(contentsRect.right() - (geom->left() - contentsRect.left()));
}
-void QGridLayoutEngine::setGeometries(const QLayoutStyleInfo &styleInfo,
- const QRectF &contentsGeometry)
+void QGridLayoutEngine::setGeometries(const QRectF &contentsGeometry, const QAbstractLayoutStyleInfo *styleInfo)
{
if (rowCount() < 1 || columnCount() < 1)
return;
- ensureGeometries(styleInfo, contentsGeometry.size());
+ ensureGeometries(contentsGeometry.size(), styleInfo);
for (int i = q_items.count() - 1; i >= 0; --i) {
QGridLayoutItem *item = q_items.at(i);
@@ -1102,22 +1017,21 @@ void QGridLayoutEngine::setGeometries(const QLayoutStyleInfo &styleInfo,
height += q_yy[item->lastRow()] - y;
QRectF geom = item->geometryWithin(contentsGeometry.x() + x, contentsGeometry.y() + y,
- width, height, q_descents[item->lastRow()]);
+ width, height, q_descents[item->lastRow()], effectiveAlignment(item));
visualRect(&geom, visualDirection(), contentsGeometry);
item->setGeometry(geom);
}
}
// ### candidate for deletion
-QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo,
- const QRectF &contentsGeometry, int row, int column, int rowSpan,
- int columnSpan) const
+QRectF QGridLayoutEngine::cellRect(const QRectF &contentsGeometry, int row, int column, int rowSpan,
+ int columnSpan, const QAbstractLayoutStyleInfo *styleInfo) const
{
if (uint(row) >= uint(rowCount()) || uint(column) >= uint(columnCount())
|| rowSpan < 1 || columnSpan < 1)
return QRectF();
- ensureGeometries(styleInfo, contentsGeometry.size());
+ ensureGeometries(contentsGeometry.size(), styleInfo);
int lastColumn = qMax(column + columnSpan, columnCount()) - 1;
int lastRow = qMax(row + rowSpan, rowCount()) - 1;
@@ -1135,21 +1049,18 @@ QRectF QGridLayoutEngine::cellRect(const QLayoutStyleInfo &styleInfo,
return QRectF(contentsGeometry.x() + x, contentsGeometry.y() + y, width, height);
}
-QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which,
- const QSizeF &constraint) const
+QSizeF QGridLayoutEngine::sizeHint(Qt::SizeHint which, const QSizeF &constraint,
+ const QAbstractLayoutStyleInfo *styleInfo) const
{
- QGridLayoutBox sizehint_totalBoxes[NOrientations];
- bool sizeHintCalculated = false;
if (hasDynamicConstraint() && rowCount() > 0 && columnCount() > 0) {
+ QGridLayoutBox sizehint_totalBoxes[NOrientations];
+ bool sizeHintCalculated = false;
if (constraintOrientation() == Qt::Vertical) {
//We have items whose height depends on their width
if (constraint.width() >= 0) {
- if (q_cachedDataForStyleInfo != styleInfo)
- ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
- else
- sizehint_totalBoxes[Hor] = q_totalBoxes[Hor];
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
QVector<qreal> sizehint_xx;
QVector<qreal> sizehint_widths;
@@ -1160,13 +1071,13 @@ QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHi
//constraints to find the row heights
q_columnData.calculateGeometries(0, columnCount(), width, sizehint_xx.data(), sizehint_widths.data(),
0, sizehint_totalBoxes[Hor], q_infos[Hor]);
- ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical);
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], sizehint_xx.data(), sizehint_widths.data(), Qt::Vertical, styleInfo);
sizeHintCalculated = true;
}
} else {
if (constraint.height() >= 0) {
//We have items whose width depends on their height
- ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
+ ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
QVector<qreal> sizehint_yy;
QVector<qreal> sizehint_heights;
@@ -1177,44 +1088,26 @@ QSizeF QGridLayoutEngine::sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHi
//constraints to find the column widths
q_rowData.calculateGeometries(0, rowCount(), height, sizehint_yy.data(), sizehint_heights.data(),
0, sizehint_totalBoxes[Ver], q_infos[Ver]);
- ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal);
+ ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], sizehint_yy.data(), sizehint_heights.data(), Qt::Horizontal, styleInfo);
sizeHintCalculated = true;
}
}
+ if (sizeHintCalculated)
+ return QSizeF(sizehint_totalBoxes[Hor].q_sizes(which), sizehint_totalBoxes[Ver].q_sizes(which));
}
- if (!sizeHintCalculated) {
- //No items with height for width, so it doesn't matter which order we do these in
- if (q_cachedDataForStyleInfo != styleInfo) {
- ensureColumnAndRowData(&q_columnData, &sizehint_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
- ensureColumnAndRowData(&q_rowData, &sizehint_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
- } else {
- sizehint_totalBoxes[Hor] = q_totalBoxes[Hor];
- sizehint_totalBoxes[Ver] = q_totalBoxes[Ver];
- }
- }
-
- switch (which) {
- case Qt::MinimumSize:
- return QSizeF(sizehint_totalBoxes[Hor].q_minimumSize, sizehint_totalBoxes[Ver].q_minimumSize);
- case Qt::PreferredSize:
- return QSizeF(sizehint_totalBoxes[Hor].q_preferredSize, sizehint_totalBoxes[Ver].q_preferredSize);
- case Qt::MaximumSize:
- return QSizeF(sizehint_totalBoxes[Hor].q_maximumSize, sizehint_totalBoxes[Ver].q_maximumSize);
- case Qt::MinimumDescent:
- return QSizeF(-1.0, sizehint_totalBoxes[Hor].q_minimumDescent); // ### doesn't work
- default:
- break;
- }
- return QSizeF();
+ //No items with height for width, so it doesn't matter which order we do these in
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
+ return QSizeF(q_totalBoxes[Hor].q_sizes(which), q_totalBoxes[Ver].q_sizes(which));
}
-QSizePolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const
+QLayoutPolicy::ControlTypes QGridLayoutEngine::controlTypes(LayoutSide side) const
{
Qt::Orientation orientation = (side == Top || side == Bottom) ? Qt::Vertical : Qt::Horizontal;
int row = (side == Top || side == Left) ? effectiveFirstRow(orientation)
: effectiveLastRow(orientation);
- QSizePolicy::ControlTypes result = 0;
+ QLayoutPolicy::ControlTypes result = 0;
for (int column = columnCount(orientation) - 1; column >= 0; --column) {
if (QGridLayoutItem *item = itemAt(row, column, orientation))
@@ -1246,7 +1139,7 @@ Qt::LayoutDirection QGridLayoutEngine::visualDirection() const
return m_visualDirection;
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGridLayoutEngine::dump(int indent) const
{
qDebug("%*sEngine", indent, "");
@@ -1377,26 +1270,19 @@ void QGridLayoutEngine::insertOrRemoveRows(int row, int delta, Qt::Orientation o
regenerateGrid();
}
-void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo,
- qreal *colPositions, qreal *colSizes,
- Qt::Orientation orientation) const
+void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const
{
- const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
+ const int ButtonMask = QLayoutPolicy::ButtonBox | QLayoutPolicy::PushButton;
const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
const QGridLayoutRowInfo &columnInfo = q_infos[orientation == Qt::Horizontal];
LayoutSide top = (orientation == Qt::Vertical) ? Top : Left;
LayoutSide bottom = (orientation == Qt::Vertical) ? Bottom : Right;
- QStyle *style = styleInfo.style();
- QStyleOption option;
- option.initFrom(styleInfo.widget());
-
const QLayoutParameter<qreal> &defaultSpacing = q_defaultSpacings[orientation == Qt::Vertical];
- qreal innerSpacing = 0.0;
- if (style)
- innerSpacing = (qreal)style->pixelMetric(orientation == Qt::Vertical ? QStyle::PM_LayoutVerticalSpacing
- : QStyle::PM_LayoutHorizontalSpacing,
- &option, styleInfo.widget());
+ qreal innerSpacing = styleInfo->spacing(orientation);
if (innerSpacing >= 0.0)
defaultSpacing.setCachedValue(innerSpacing);
@@ -1453,7 +1339,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
continue;
QGridLayoutBox &rowBox = rowData->boxes[row];
- if (option.state & QStyle::State_Window) {
+ if (styleInfo->isWindow()) {
nextToNextToLastRowAdHocData = nextToLastRowAdHocData;
nextToLastRowAdHocData = lastRowAdHocData;
lastRowAdHocData.init(row);
@@ -1471,7 +1357,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
if (itemRow == row && itemColumn == column) {
int itemStretch = item->stretchFactor(orientation);
- if (!(item->sizePolicy(orientation) & QSizePolicy::IgnoreFlag))
+ if (!(item->sizePolicy(orientation) & QLayoutPolicy::IgnoreFlag))
hasIgnoreFlag = false;
int itemRowSpan = item->rowSpan(orientation);
@@ -1509,7 +1395,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
}
if (effectiveRowSpan == 1) {
- QSizePolicy::ControlTypes controls = item->controlTypes(top);
+ QLayoutPolicy::ControlTypes controls = item->controlTypes(top);
if (controls & ButtonMask)
lastRowAdHocData.q_hasButtons = true;
if (controls & ~ButtonMask)
@@ -1534,7 +1420,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
}
/*
- Heuristic: Detect button boxes that don't use QSizePolicy::ButtonBox.
+ Heuristic: Detect button boxes that don't use QLayoutPolicy::ButtonBox.
This is somewhat ad hoc but it usually does the trick.
*/
bool lastRowIsButtonBox = (lastRowAdHocData.hasOnlyButtons()
@@ -1557,25 +1443,24 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
QGridLayoutItem *item2 = itemAt(row, column, orientation);
if (item1 && item2 && item1 != item2) {
- QSizePolicy::ControlTypes controls1 = item1->controlTypes(bottom);
- QSizePolicy::ControlTypes controls2 = item2->controlTypes(top);
+ QLayoutPolicy::ControlTypes controls1 = item1->controlTypes(bottom);
+ QLayoutPolicy::ControlTypes controls2 = item2->controlTypes(top);
- if (controls2 & QSizePolicy::PushButton) {
+ if (controls2 & QLayoutPolicy::PushButton) {
if ((row == nextToLastRowAdHocData.q_row && lastTwoRowsIsButtonBox)
|| (row == lastRowAdHocData.q_row && lastRowIsButtonBox)) {
- controls2 &= ~QSizePolicy::PushButton;
- controls2 |= QSizePolicy::ButtonBox;
+ controls2 &= ~QLayoutPolicy::PushButton;
+ controls2 |= QLayoutPolicy::ButtonBox;
}
}
- qreal spacing = style->combinedLayoutSpacing(controls1, controls2,
- orientation, &option,
- styleInfo.widget());
+ qreal spacing = styleInfo->combinedLayoutSpacing(controls1, controls2,
+ orientation);
if (orientation == Qt::Horizontal) {
qreal width1 = rowData->boxes.at(prevRow).q_minimumSize;
qreal width2 = rowData->boxes.at(row).q_minimumSize;
- QRectF rect1 = item1->geometryWithin(0.0, 0.0, width1, FLT_MAX, -1.0);
- QRectF rect2 = item2->geometryWithin(0.0, 0.0, width2, FLT_MAX, -1.0);
+ QRectF rect1 = item1->geometryWithin(0.0, 0.0, width1, FLT_MAX, -1.0, effectiveAlignment(item1));
+ QRectF rect2 = item2->geometryWithin(0.0, 0.0, width2, FLT_MAX, -1.0, effectiveAlignment(item2));
spacing -= (width1 - (rect1.x() + rect1.width())) + rect2.x();
} else {
const QGridLayoutBox &box1 = rowData->boxes.at(prevRow);
@@ -1587,9 +1472,9 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
qreal rowDescent2 = fixedDescent(box2.q_minimumDescent,
box2.q_minimumAscent, height2);
QRectF rect1 = item1->geometryWithin(0.0, 0.0, FLT_MAX, height1,
- rowDescent1);
+ rowDescent1, effectiveAlignment(item1));
QRectF rect2 = item2->geometryWithin(0.0, 0.0, FLT_MAX, height2,
- rowDescent2);
+ rowDescent2, effectiveAlignment(item2));
spacing -= (height1 - (rect1.y() + rect1.height())) + rect2.y();
}
rowSpacing = qMax(spacing, rowSpacing);
@@ -1607,11 +1492,7 @@ void QGridLayoutEngine::fillRowData(QGridLayoutRowData *rowData, const QLayoutSt
int prevRow = lastRowIsButtonBox ? nextToLastRowAdHocData.q_row
: nextToNextToLastRowAdHocData.q_row;
if (!defaultSpacing.isUser() && !rowInfo.spacings.value(prevRow).isUser()) {
- qreal windowMargin = style->pixelMetric(orientation == Qt::Vertical
- ? QStyle::PM_LayoutBottomMargin
- : QStyle::PM_LayoutRightMargin,
- &option, styleInfo.widget());
-
+ qreal windowMargin = styleInfo->windowMargin(orientation);
qreal &rowSpacing = rowData->spacings[prevRow];
rowSpacing = qMax(windowMargin, rowSpacing);
}
@@ -1644,20 +1525,30 @@ void QGridLayoutEngine::ensureEffectiveFirstAndLastRows() const
}
void QGridLayoutEngine::ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox,
- const QLayoutStyleInfo &styleInfo,
- qreal *colPositions, qreal *colSizes,
- Qt::Orientation orientation) const
-{
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const
+{
+ const int o = (orientation == Qt::Vertical ? Ver : Hor);
+ if (q_sizeHintValid[o] && !colPositions && !colSizes) {
+ if (totalBox != &q_totalBoxes[o])
+ *totalBox = q_totalBoxes[o];
+ return;
+ }
rowData->reset(rowCount(orientation));
- fillRowData(rowData, styleInfo, colPositions, colSizes, orientation);
+ fillRowData(rowData, colPositions, colSizes, orientation, styleInfo);
const QGridLayoutRowInfo &rowInfo = q_infos[orientation == Qt::Vertical];
rowData->distributeMultiCells(rowInfo);
*totalBox = rowData->totalBox(0, rowCount(orientation));
- //We have items whose width depends on their height
+
+ if (!colPositions && !colSizes) {
+ q_totalBoxes[o] = *totalBox;
+ q_sizeHintValid[o] = true;
+ }
}
/**
- returns \c false if the layout has contradicting constraints (i.e. some items with a horizontal
+ returns false if the layout has contradicting constraints (i.e. some items with a horizontal
constraint and other items with a vertical constraint)
*/
bool QGridLayoutEngine::ensureDynamicConstraint() const
@@ -1699,13 +1590,13 @@ Qt::Orientation QGridLayoutEngine::constraintOrientation() const
return (Qt::Orientation)q_cachedConstraintOrientation;
}
-void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
- const QSizeF &size) const
+void QGridLayoutEngine::ensureGeometries(const QSizeF &size,
+ const QAbstractLayoutStyleInfo *styleInfo) const
{
- if (q_cachedDataForStyleInfo == styleInfo && q_cachedSize == size)
+ if (!styleInfo->hasChanged() && q_totalBoxesValid && q_cachedSize == size)
return;
- q_cachedDataForStyleInfo = styleInfo;
+ q_totalBoxesValid = true;
q_cachedSize = size;
q_xx.resize(columnCount());
@@ -1715,25 +1606,24 @@ void QGridLayoutEngine::ensureGeometries(const QLayoutStyleInfo &styleInfo,
q_descents.resize(rowCount());
if (constraintOrientation() != Qt::Horizontal) {
- // We might have items whose height depends on their width,
- // or none of the items has a dynamic constraint.
- ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, NULL, NULL, Qt::Horizontal);
+ //We might have items whose width depends on their height
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], NULL, NULL, Qt::Horizontal, styleInfo);
//Calculate column widths and positions, and put results in q_xx.data() and q_widths.data() so that we can use this information as
//constraints to find the row heights
q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
0, q_totalBoxes[Hor], q_infos[Hor] );
- ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, q_xx.data(), q_widths.data(), Qt::Vertical);
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], q_xx.data(), q_widths.data(), Qt::Vertical, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
} else {
- // We have items whose width depends on their height
- ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], styleInfo, NULL, NULL, Qt::Vertical);
+ //We have items whose height depends on their width
+ ensureColumnAndRowData(&q_rowData, &q_totalBoxes[Ver], NULL, NULL, Qt::Vertical, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data() so that we can use this information as
//constraints to find the column widths
q_rowData.calculateGeometries(0, rowCount(), size.height(), q_yy.data(), q_heights.data(),
q_descents.data(), q_totalBoxes[Ver], q_infos[Ver]);
- ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], styleInfo, q_yy.data(), q_heights.data(), Qt::Horizontal);
+ ensureColumnAndRowData(&q_columnData, &q_totalBoxes[Hor], q_yy.data(), q_heights.data(), Qt::Horizontal, styleInfo);
//Calculate row heights and positions, and put results in q_yy.data() and q_heights.data()
q_columnData.calculateGeometries(0, columnCount(), size.width(), q_xx.data(), q_widths.data(),
0, q_totalBoxes[Hor], q_infos[Hor]);
diff --git a/src/widgets/graphicsview/qgridlayoutengine_p.h b/src/gui/util/qgridlayoutengine_p.h
index fbc5bd6ad2..9650e7fffe 100644
--- a/src/widgets/graphicsview/qgridlayoutengine_p.h
+++ b/src/gui/util/qgridlayoutengine_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtWidgets module of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -58,13 +58,17 @@
#include "qlist.h"
#include "qmap.h"
#include "qpair.h"
-#include "qvector.h"
-#include "qgraphicslayout_p.h"
+#include <QtCore/qvector.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qrect.h>
#include <float.h>
+#include "qlayoutpolicy_p.h"
+#include "qabstractlayoutstyleinfo_p.h"
+
+// #define QGRIDLAYOUTENGINE_DEBUG
QT_BEGIN_NAMESPACE
-class QGraphicsLayoutItem;
class QStyle;
class QWidget;
@@ -136,7 +140,7 @@ public:
};
-class QGridLayoutBox
+class Q_GUI_EXPORT QGridLayoutBox
{
public:
inline QGridLayoutBox()
@@ -147,7 +151,7 @@ public:
void combine(const QGridLayoutBox &other);
void normalize();
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void dump(int indent = 0) const;
#endif
// This code could use the union-struct-array trick, but a compiler
@@ -237,7 +241,7 @@ public:
QGridLayoutBox totalBox(int start, int end) const;
void stealBox(int start, int end, int which, qreal *positions, qreal *sizes);
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void dump(int indent = 0) const;
#endif
@@ -249,14 +253,31 @@ public:
bool hasIgnoreFlag;
};
-class QGridLayoutEngine;
+class QGridLayoutRowInfo
+{
+public:
+ inline QGridLayoutRowInfo() : count(0) {}
+
+ void insertOrRemoveRows(int row, int delta);
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
+ void dump(int indent = 0) const;
+#endif
-class QGridLayoutItem
+ int count;
+ QVector<QStretchParameter> stretches;
+ QVector<QLayoutParameter<qreal> > spacings;
+ QVector<Qt::Alignment> alignments;
+ QVector<QGridLayoutBox> boxes;
+};
+
+
+class Q_GUI_EXPORT QGridLayoutItem
{
public:
- QGridLayoutItem(QGridLayoutEngine *engine, QGraphicsLayoutItem *layoutItem, int row, int column,
- int rowSpan = 1, int columnSpan = 1, Qt::Alignment alignment = 0,
- int itemAtIndex = -1);
+ QGridLayoutItem(int row, int column, int rowSpan = 1, int columnSpan = 1,
+ Qt::Alignment alignment = 0);
+ virtual ~QGridLayoutItem() {}
inline int firstRow() const { return q_firstRows[Ver]; }
inline int firstColumn() const { return q_firstRows[Hor]; }
@@ -280,58 +301,44 @@ public:
inline Qt::Alignment alignment() const { return q_alignment; }
inline void setAlignment(Qt::Alignment alignment) { q_alignment = alignment; }
- QSizePolicy::Policy sizePolicy(Qt::Orientation orientation) const;
+ virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const = 0;
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const = 0;
- bool hasDynamicConstraint() const;
- Qt::Orientation dynamicConstraintOrientation() const;
+ virtual void setGeometry(const QRectF &rect) = 0;
+ /*
+ returns true if the size policy returns true for either hasHeightForWidth()
+ or hasWidthForHeight()
+ */
+ virtual bool hasDynamicConstraint() const { return false; }
+ virtual Qt::Orientation dynamicConstraintOrientation() const { return Qt::Horizontal; }
+
+
+ virtual QLayoutPolicy::ControlTypes controlTypes(LayoutSide side) const;
- QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
- QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
+ QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent, Qt::Alignment align) const;
QGridLayoutBox box(Qt::Orientation orientation, qreal constraint = -1.0) const;
- QRectF geometryWithin(qreal x, qreal y, qreal width, qreal height, qreal rowDescent) const;
- QGraphicsLayoutItem *layoutItem() const { return q_layoutItem; }
- void setGeometry(const QRectF &rect);
void transpose();
void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical);
QSizeF effectiveMaxSize(const QSizeF &constraint) const;
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void dump(int indent = 0) const;
#endif
private:
- QGridLayoutEngine *q_engine; // ### needed?
- QGraphicsLayoutItem *q_layoutItem;
int q_firstRows[NOrientations];
int q_rowSpans[NOrientations];
int q_stretches[NOrientations];
Qt::Alignment q_alignment;
-};
-class QGridLayoutRowInfo
-{
-public:
- inline QGridLayoutRowInfo() : count(0) {}
-
- void insertOrRemoveRows(int row, int delta);
-
-#ifdef QT_DEBUG
- void dump(int indent = 0) const;
-#endif
-
- int count;
- QVector<QStretchParameter> stretches;
- QVector<QLayoutParameter<qreal> > spacings;
- QVector<Qt::Alignment> alignments;
- QVector<QGridLayoutBox> boxes;
};
-class QGridLayoutEngine
+class Q_GUI_EXPORT QGridLayoutEngine
{
public:
- QGridLayoutEngine();
+ QGridLayoutEngine(Qt::Alignment defaultAlignment = Qt::Alignment(0));
inline ~QGridLayoutEngine() { qDeleteAll(q_items); }
int rowCount(Qt::Orientation orientation) const;
@@ -341,13 +348,12 @@ public:
// returns the number of items inserted, which may be less than (rowCount * columnCount)
int itemCount() const;
QGridLayoutItem *itemAt(int index) const;
- int indexOf(QGraphicsLayoutItem *item) const;
int effectiveFirstRow(Qt::Orientation orientation = Qt::Vertical) const;
int effectiveLastRow(Qt::Orientation orientation = Qt::Vertical) const;
void setSpacing(qreal spacing, Qt::Orientations orientations);
- qreal spacing(const QLayoutStyleInfo &styleInfo, Qt::Orientation orientation) const;
+ qreal spacing(Qt::Orientation orientation, const QAbstractLayoutStyleInfo *styleInfo) const;
// ### setSpacingAfterRow(), spacingAfterRow()
void setRowSpacing(int row, qreal spacing, Qt::Orientation orientation = Qt::Vertical);
qreal rowSpacing(int row, Qt::Orientation orientation = Qt::Vertical) const;
@@ -355,10 +361,6 @@ public:
void setRowStretchFactor(int row, int stretch, Qt::Orientation orientation = Qt::Vertical);
int rowStretchFactor(int row, Qt::Orientation orientation = Qt::Vertical) const;
- void setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch,
- Qt::Orientation orientation);
- int stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const;
-
void setRowSizeHint(Qt::SizeHint which, int row, qreal size,
Qt::Orientation orientation = Qt::Vertical);
qreal rowSizeHint(Qt::SizeHint which, int row,
@@ -367,15 +369,24 @@ public:
void setRowAlignment(int row, Qt::Alignment alignment, Qt::Orientation orientation);
Qt::Alignment rowAlignment(int row, Qt::Orientation orientation) const;
- void setAlignment(QGraphicsLayoutItem *layoutItem, Qt::Alignment alignment);
- Qt::Alignment alignment(QGraphicsLayoutItem *layoutItem) const;
Qt::Alignment effectiveAlignment(const QGridLayoutItem *layoutItem) const;
void insertItem(QGridLayoutItem *item, int index);
void addItem(QGridLayoutItem *item);
void removeItem(QGridLayoutItem *item);
- QGridLayoutItem *findLayoutItem(QGraphicsLayoutItem *layoutItem) const;
+ void deleteItems()
+ {
+ const QList<QGridLayoutItem *> oldItems = q_items;
+ q_items.clear(); // q_items are used as input when the grid is regenerated in removeRows
+ // The following calls to removeRows are suboptimal
+ int rows = rowCount(Qt::Vertical);
+ removeRows(0, rows, Qt::Vertical);
+ rows = rowCount(Qt::Horizontal);
+ removeRows(0, rows, Qt::Horizontal);
+ qDeleteAll(oldItems);
+ }
+
QGridLayoutItem *itemAt(int row, int column, Qt::Orientation orientation = Qt::Vertical) const;
inline void insertRow(int row, Qt::Orientation orientation = Qt::Vertical)
{ insertOrRemoveRows(row, +1, orientation); }
@@ -383,11 +394,11 @@ public:
{ insertOrRemoveRows(row, -count, orientation); }
void invalidate();
- void setGeometries(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry);
- QRectF cellRect(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry, int row,
- int column, int rowSpan, int columnSpan) const;
- QSizeF sizeHint(const QLayoutStyleInfo &styleInfo, Qt::SizeHint which,
- const QSizeF &constraint) const;
+ void setGeometries(const QRectF &contentsGeometry, const QAbstractLayoutStyleInfo *styleInfo);
+ QRectF cellRect(const QRectF &contentsGeometry, int row, int column, int rowSpan, int columnSpan,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+ QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
// heightForWidth / widthForHeight support
QSizeF dynamicallyConstrainedSizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
@@ -396,11 +407,11 @@ public:
Qt::Orientation constraintOrientation() const;
- QSizePolicy::ControlTypes controlTypes(LayoutSide side) const;
+ QLayoutPolicy::ControlTypes controlTypes(LayoutSide side) const;
void transpose();
void setVisualDirection(Qt::LayoutDirection direction);
Qt::LayoutDirection visualDirection() const;
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void dump(int indent = 0) const;
#endif
@@ -413,23 +424,26 @@ private:
inline int internalGridColumnCount() const { return grossRoundUp(columnCount()); }
void setItemAt(int row, int column, QGridLayoutItem *item);
void insertOrRemoveRows(int row, int delta, Qt::Orientation orientation = Qt::Vertical);
- void fillRowData(QGridLayoutRowData *rowData, const QLayoutStyleInfo &styleInfo,
- qreal *colPositions, qreal *colSizes,
- Qt::Orientation orientation = Qt::Vertical) const;
+ void fillRowData(QGridLayoutRowData *rowData,
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
void ensureEffectiveFirstAndLastRows() const;
void ensureColumnAndRowData(QGridLayoutRowData *rowData, QGridLayoutBox *totalBox,
- const QLayoutStyleInfo &styleInfo,
- qreal *colPositions, qreal *colSizes,
- Qt::Orientation orientation) const;
-
- void ensureGeometries(const QLayoutStyleInfo &styleInfo, const QSizeF &size) const;
+ const qreal *colPositions, const qreal *colSizes,
+ Qt::Orientation orientation,
+ const QAbstractLayoutStyleInfo *styleInfo) const;
+ void ensureGeometries(const QSizeF &size, const QAbstractLayoutStyleInfo *styleInfo) const;
+protected:
+ QList<QGridLayoutItem *> q_items;
+private:
// User input
QVector<QGridLayoutItem *> q_grid;
- QList<QGridLayoutItem *> q_items;
QLayoutParameter<qreal> q_defaultSpacings[NOrientations];
QGridLayoutRowInfo q_infos[NOrientations];
Qt::LayoutDirection m_visualDirection;
+ Qt::Alignment m_defaultAlignment;
// Lazily computed from the above user input
mutable int q_cachedEffectiveFirstRows[NOrientations];
@@ -437,13 +451,14 @@ private:
mutable quint8 q_cachedConstraintOrientation : 3;
// Layout item input
- mutable QLayoutStyleInfo q_cachedDataForStyleInfo;
mutable QGridLayoutRowData q_columnData;
mutable QGridLayoutRowData q_rowData;
mutable QGridLayoutBox q_totalBoxes[NOrientations];
// Output
mutable QSizeF q_cachedSize;
+ mutable bool q_totalBoxesValid;
+ mutable bool q_sizeHintValid[NOrientations];
mutable QVector<qreal> q_xx;
mutable QVector<qreal> q_yy;
mutable QVector<qreal> q_widths;
diff --git a/src/gui/util/qlayoutpolicy.cpp b/src/gui/util/qlayoutpolicy.cpp
new file mode 100644
index 0000000000..9a154768eb
--- /dev/null
+++ b/src/gui/util/qlayoutpolicy.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qlayoutpolicy_p.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+void QLayoutPolicy::setControlType(ControlType type)
+{
+ /*
+ The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
+ etc. In memory, we pack it onto the available bits (CTSize) in
+ setControlType(), and unpack it here.
+
+ Example:
+
+ 0x00000001 maps to 0
+ 0x00000002 maps to 1
+ 0x00000004 maps to 2
+ 0x00000008 maps to 3
+ etc.
+ */
+
+ int i = 0;
+ while (true) {
+ if (type & (0x1 << i)) {
+ bits.ctype = i;
+ return;
+ }
+ ++i;
+ }
+}
+
+QLayoutPolicy::ControlType QLayoutPolicy::controlType() const
+{
+ return QLayoutPolicy::ControlType(1 << bits.ctype);
+}
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \relates QLayoutPolicy
+
+ Writes the size \a policy to the data stream \a stream.
+
+ \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
+*/
+QDataStream &operator<<(QDataStream &stream, const QLayoutPolicy &policy)
+{
+ // The order here is for historical reasons. (compatibility with Qt4)
+ quint32 data = (policy.bits.horPolicy | // [0, 3]
+ policy.bits.verPolicy << 4 | // [4, 7]
+ policy.bits.hfw << 8 | // [8]
+ policy.bits.ctype << 9 | // [9, 13]
+ policy.bits.wfh << 14 | // [14]
+ //policy.bits.padding << 15 | // [15]
+ policy.bits.verStretch << 16 | // [16, 23]
+ policy.bits.horStretch << 24); // [24, 31]
+ return stream << data;
+}
+
+#define VALUE_OF_BITS(data, bitstart, bitcount) ((data >> bitstart) & ((1 << bitcount) -1))
+
+/*!
+ \relates QLayoutPolicy
+
+ Reads the size \a policy from the data stream \a stream.
+
+ \sa{Serializing Qt Data Types}{Format of the QDataStream operators}
+*/
+QDataStream &operator>>(QDataStream &stream, QLayoutPolicy &policy)
+{
+ quint32 data;
+ stream >> data;
+ policy.bits.horPolicy = VALUE_OF_BITS(data, 0, 4);
+ policy.bits.verPolicy = VALUE_OF_BITS(data, 4, 4);
+ policy.bits.hfw = VALUE_OF_BITS(data, 8, 1);
+ policy.bits.ctype = VALUE_OF_BITS(data, 9, 5);
+ policy.bits.wfh = VALUE_OF_BITS(data, 14, 1);
+ policy.bits.padding = 0;
+ policy.bits.verStretch = VALUE_OF_BITS(data, 16, 8);
+ policy.bits.horStretch = VALUE_OF_BITS(data, 24, 8);
+ return stream;
+}
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QLayoutPolicy &p)
+{
+ dbg.nospace() << "QLayoutPolicy(horizontalPolicy = " << p.horizontalPolicy()
+ << ", verticalPolicy = " << p.verticalPolicy() << ')';
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/util/qlayoutpolicy_p.h b/src/gui/util/qlayoutpolicy_p.h
new file mode 100644
index 0000000000..664afef1a4
--- /dev/null
+++ b/src/gui/util/qlayoutpolicy_p.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Layouts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLAYOUTPOLICY_H
+#define QLAYOUTPOLICY_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qnamespace.h>
+
+#ifndef QT_NO_DATASTREAM
+# include <QtCore/qdatastream.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+
+class QVariant;
+
+class Q_GUI_EXPORT QLayoutPolicy
+{
+ Q_ENUMS(Policy)
+
+public:
+ enum PolicyFlag {
+ GrowFlag = 1,
+ ExpandFlag = 2,
+ ShrinkFlag = 4,
+ IgnoreFlag = 8
+ };
+
+ enum Policy {
+ Fixed = 0,
+ Minimum = GrowFlag,
+ Maximum = ShrinkFlag,
+ Preferred = GrowFlag | ShrinkFlag,
+ MinimumExpanding = GrowFlag | ExpandFlag,
+ Expanding = GrowFlag | ShrinkFlag | ExpandFlag,
+ Ignored = ShrinkFlag | GrowFlag | IgnoreFlag
+ };
+
+ enum ControlType {
+ DefaultType = 0x00000001,
+ ButtonBox = 0x00000002,
+ CheckBox = 0x00000004,
+ ComboBox = 0x00000008,
+ Frame = 0x00000010,
+ GroupBox = 0x00000020,
+ Label = 0x00000040,
+ Line = 0x00000080,
+ LineEdit = 0x00000100,
+ PushButton = 0x00000200,
+ RadioButton = 0x00000400,
+ Slider = 0x00000800,
+ SpinBox = 0x00001000,
+ TabWidget = 0x00002000,
+ ToolButton = 0x00004000
+ };
+ Q_DECLARE_FLAGS(ControlTypes, ControlType)
+
+ QLayoutPolicy() : data(0) { }
+
+ QLayoutPolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType)
+ : data(0) {
+ bits.horPolicy = horizontal;
+ bits.verPolicy = vertical;
+ setControlType(type);
+ }
+ Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); }
+ Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); }
+ ControlType controlType() const;
+
+ void setHorizontalPolicy(Policy d) { bits.horPolicy = d; }
+ void setVerticalPolicy(Policy d) { bits.verPolicy = d; }
+ void setControlType(ControlType type);
+
+ Qt::Orientations expandingDirections() const {
+ Qt::Orientations result;
+ if (verticalPolicy() & ExpandFlag)
+ result |= Qt::Vertical;
+ if (horizontalPolicy() & ExpandFlag)
+ result |= Qt::Horizontal;
+ return result;
+ }
+
+ void setHeightForWidth(bool b) { bits.hfw = b; }
+ bool hasHeightForWidth() const { return bits.hfw; }
+ void setWidthForHeight(bool b) { bits.wfh = b; }
+ bool hasWidthForHeight() const { return bits.wfh; }
+
+ bool operator==(const QLayoutPolicy& s) const { return data == s.data; }
+ bool operator!=(const QLayoutPolicy& s) const { return data != s.data; }
+
+ int horizontalStretch() const { return static_cast<int>(bits.horStretch); }
+ int verticalStretch() const { return static_cast<int>(bits.verStretch); }
+ void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+ void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); }
+
+ void transpose();
+
+
+private:
+#ifndef QT_NO_DATASTREAM
+ friend QDataStream &operator<<(QDataStream &, const QLayoutPolicy &);
+ friend QDataStream &operator>>(QDataStream &, QLayoutPolicy &);
+#endif
+ QLayoutPolicy(int i) : data(i) { }
+
+ union {
+ struct {
+ quint32 horStretch : 8;
+ quint32 verStretch : 8;
+ quint32 horPolicy : 4;
+ quint32 verPolicy : 4;
+ quint32 ctype : 5;
+ quint32 hfw : 1;
+ quint32 wfh : 1;
+ quint32 padding : 1; // feel free to use
+ } bits;
+ quint32 data;
+ };
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QLayoutPolicy::ControlTypes)
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &, const QLayoutPolicy &);
+QDataStream &operator>>(QDataStream &, QLayoutPolicy &);
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QLayoutPolicy &);
+#endif
+
+inline void QLayoutPolicy::transpose() {
+ Policy hData = horizontalPolicy();
+ Policy vData = verticalPolicy();
+ int hStretch = horizontalStretch();
+ int vStretch = verticalStretch();
+ setHorizontalPolicy(vData);
+ setVerticalPolicy(hData);
+ setHorizontalStretch(vStretch);
+ setVerticalStretch(hStretch);
+}
+
+QT_END_NAMESPACE
+
+#endif // QLAYOUTPOLICY_H
diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp
index ed3b3b6dd6..dbb8575397 100644
--- a/src/gui/util/qvalidator.cpp
+++ b/src/gui/util/qvalidator.cpp
@@ -401,7 +401,7 @@ static qlonglong pow10(int exp)
QValidator::State QIntValidator::validate(QString & input, int&) const
{
QByteArray buff;
- if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
return Invalid;
}
@@ -418,7 +418,7 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
return Intermediate;
bool ok, overflow;
- qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
if (overflow || !ok)
return Invalid;
@@ -440,11 +440,11 @@ QValidator::State QIntValidator::validate(QString & input, int&) const
void QIntValidator::fixup(QString &input) const
{
QByteArray buff;
- if (!locale().d->validateChars(input, QLocalePrivate::IntegerMode, &buff)) {
+ if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff)) {
return;
}
bool ok, overflow;
- qlonglong entered = QLocalePrivate::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
+ qlonglong entered = QLocaleData::bytearrayToLongLong(buff.constData(), 10, &ok, &overflow);
if (ok && !overflow)
input = locale().toString(entered);
}
@@ -532,7 +532,7 @@ public:
QDoubleValidator::Notation notation;
- QValidator::State validateWithLocale(QString & input, QLocalePrivate::NumberMode numMode, const QLocale &locale) const;
+ QValidator::State validateWithLocale(QString & input, QLocaleData::NumberMode numMode, const QLocale &locale) const;
};
@@ -639,24 +639,24 @@ QValidator::State QDoubleValidator::validate(QString & input, int &) const
{
Q_D(const QDoubleValidator);
- QLocalePrivate::NumberMode numMode = QLocalePrivate::DoubleStandardMode;
+ QLocaleData::NumberMode numMode = QLocaleData::DoubleStandardMode;
switch (d->notation) {
case StandardNotation:
- numMode = QLocalePrivate::DoubleStandardMode;
+ numMode = QLocaleData::DoubleStandardMode;
break;
case ScientificNotation:
- numMode = QLocalePrivate::DoubleScientificMode;
+ numMode = QLocaleData::DoubleScientificMode;
break;
}
return d->validateWithLocale(input, numMode, locale());
}
-QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocalePrivate::NumberMode numMode, const QLocale &locale) const
+QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QLocaleData::NumberMode numMode, const QLocale &locale) const
{
Q_Q(const QDoubleValidator);
QByteArray buff;
- if (!locale.d->validateChars(input, numMode, &buff, q->dec))
+ if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec))
return QValidator::Invalid;
if (buff.isEmpty())
@@ -669,7 +669,7 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL
return QValidator::Invalid;
bool ok, overflow;
- double i = QLocalePrivate::bytearrayToDouble(buff.constData(), &ok, &overflow);
+ double i = QLocaleData::bytearrayToDouble(buff.constData(), &ok, &overflow);
if (overflow)
return QValidator::Invalid;
if (!ok)
diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
index dfb221667e..79c83599b9 100644
--- a/src/gui/util/util.pri
+++ b/src/gui/util/util.pri
@@ -3,8 +3,14 @@
HEADERS += \
util/qdesktopservices.h \
util/qhexstring_p.h \
- util/qvalidator.h
+ util/qvalidator.h \
+ util/qgridlayoutengine_p.h \
+ util/qabstractlayoutstyleinfo_p.h \
+ util/qlayoutpolicy_p.h
SOURCES += \
util/qdesktopservices.cpp \
- util/qvalidator.cpp
+ util/qvalidator.cpp \
+ util/qgridlayoutengine.cpp \
+ util/qabstractlayoutstyleinfo.cpp \
+ util/qlayoutpolicy.cpp
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index aaaf05b551..3017417da8 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -7,6 +7,8 @@ HEADERS += \
access/qhttpnetworkreply_p.h \
access/qhttpnetworkconnection_p.h \
access/qhttpnetworkconnectionchannel_p.h \
+ access/qabstractprotocolhandler_p.h \
+ access/qhttpprotocolhandler_p.h \
access/qnetworkaccessauthenticationmanager_p.h \
access/qnetworkaccessmanager.h \
access/qnetworkaccessmanager_p.h \
@@ -43,6 +45,8 @@ SOURCES += \
access/qhttpnetworkreply.cpp \
access/qhttpnetworkconnection.cpp \
access/qhttpnetworkconnectionchannel.cpp \
+ access/qabstractprotocolhandler.cpp \
+ access/qhttpprotocolhandler.cpp \
access/qnetworkaccessauthenticationmanager.cpp \
access/qnetworkaccessmanager.cpp \
access/qnetworkaccesscache.cpp \
diff --git a/src/network/access/qabstractprotocolhandler.cpp b/src/network/access/qabstractprotocolhandler.cpp
new file mode 100644
index 0000000000..e72bb63236
--- /dev/null
+++ b/src/network/access/qabstractprotocolhandler.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qabstractprotocolhandler_p.h>
+#include <private/qhttpnetworkconnectionchannel_p.h>
+
+#ifndef QT_NO_HTTP
+
+QT_BEGIN_NAMESPACE
+
+QAbstractProtocolHandler::QAbstractProtocolHandler(QHttpNetworkConnectionChannel *channel)
+ : m_channel(channel), m_reply(0), m_socket(m_channel->socket), m_connection(m_channel->connection)
+{
+ Q_ASSERT(m_channel);
+ Q_ASSERT(m_socket);
+ Q_ASSERT(m_connection);
+}
+
+QAbstractProtocolHandler::~QAbstractProtocolHandler()
+{
+}
+
+void QAbstractProtocolHandler::setReply(QHttpNetworkReply *reply)
+{
+ m_reply = reply;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_HTTP
diff --git a/src/network/access/qabstractprotocolhandler_p.h b/src/network/access/qabstractprotocolhandler_p.h
new file mode 100644
index 0000000000..387d08ccac
--- /dev/null
+++ b/src/network/access/qabstractprotocolhandler_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTPROTOCOLHANDLER_H
+#define QABSTRACTPROTOCOLHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_HTTP
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QHttpNetworkConnectionChannel;
+class QHttpNetworkReply;
+class QAbstractSocket;
+class QHttpNetworkConnection;
+
+class QAbstractProtocolHandler {
+public:
+ QAbstractProtocolHandler(QHttpNetworkConnectionChannel *channel);
+ virtual ~QAbstractProtocolHandler();
+
+ virtual void _q_receiveReply() = 0;
+ virtual void _q_readyRead() = 0;
+ virtual bool sendRequest() = 0;
+ void setReply(QHttpNetworkReply *reply);
+
+protected:
+ QHttpNetworkConnectionChannel *m_channel;
+ QHttpNetworkReply *m_reply;
+ QAbstractSocket *m_socket;
+ QHttpNetworkConnection *m_connection;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_HTTP
+
+#endif // QABSTRACTPROTOCOLHANDLER_H
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index e0996c4072..66c97f7485 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -512,7 +512,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
- QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
+ QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false));
request.setHeaderField("Authorization", response);
channels[i].authenticationCredentialsSent = true;
}
@@ -524,7 +524,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
- QByteArray response = priv->calculateResponse(request.d->methodName(), request.d->uri(false));
+ QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false));
request.setHeaderField("Proxy-Authorization", response);
channels[i].proxyCredentialsSent = true;
}
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 2aaaad24ac..526326c3fd 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -139,6 +139,7 @@ private:
friend class QHttpNetworkReply;
friend class QHttpNetworkReplyPrivate;
friend class QHttpNetworkConnectionChannel;
+ friend class QHttpProtocolHandler;
Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
Q_PRIVATE_SLOT(d_func(), void _q_hostLookupFinished(QHostInfo))
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index 6e786893ed..6f06c18732 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -48,6 +49,8 @@
#ifndef QT_NO_HTTP
+#include <private/qhttpprotocolhandler_p.h>
+
#ifndef QT_NO_SSL
# include <QtNetwork/qsslkey.h>
# include <QtNetwork/qsslcipher.h>
@@ -78,6 +81,7 @@ QHttpNetworkConnectionChannel::QHttpNetworkConnectionChannel()
, proxyAuthMethod(QAuthenticatorPrivate::None)
, authenticationCredentialsSent(false)
, proxyCredentialsSent(false)
+ , protocolHandler(0)
#ifndef QT_NO_SSL
, ignoreAllSslErrors(false)
#endif
@@ -163,8 +167,8 @@ void QHttpNetworkConnectionChannel::init()
if (!sslConfiguration.isNull())
sslSocket->setSslConfiguration(sslConfiguration);
}
-
#endif
+ protocolHandler.reset(new QHttpProtocolHandler(this));
#ifndef QT_NO_NETWORKPROXY
if (proxy.type() != QNetworkProxy::NoProxy)
@@ -193,349 +197,21 @@ void QHttpNetworkConnectionChannel::close()
bool QHttpNetworkConnectionChannel::sendRequest()
{
- if (!reply) {
- // heh, how should that happen!
- qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply";
- state = QHttpNetworkConnectionChannel::IdleState;
- return false;
- }
-
- switch (state) {
- case QHttpNetworkConnectionChannel::IdleState: { // write the header
- if (!ensureConnection()) {
- // wait for the connection (and encryption) to be done
- // sendRequest will be called again from either
- // _q_connected or _q_encrypted
- return false;
- }
- QString scheme = request.url().scheme();
- if (scheme == QLatin1String("preconnect-http")
- || scheme == QLatin1String("preconnect-https")) {
- state = QHttpNetworkConnectionChannel::IdleState;
- reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
- allDone();
- connection->preConnectFinished(); // will only decrease the counter
- reply = 0; // so we can reuse this channel
- return true; // we have a working connection and are done
- }
-
- written = 0; // excluding the header
- bytesTotal = 0;
-
- QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
- replyPrivate->clear();
- replyPrivate->connection = connection;
- replyPrivate->connectionChannel = this;
- replyPrivate->autoDecompress = request.d->autoDecompress;
- replyPrivate->pipeliningUsed = false;
-
- // if the url contains authentication parameters, use the new ones
- // both channels will use the new authentication parameters
- if (!request.url().userInfo().isEmpty() && request.withCredentials()) {
- QUrl url = request.url();
- QAuthenticator &auth = authenticator;
- if (url.userName() != auth.user()
- || (!url.password().isEmpty() && url.password() != auth.password())) {
- auth.setUser(url.userName(QUrl::FullyDecoded));
- auth.setPassword(url.password(QUrl::FullyDecoded));
- connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false);
- }
- // clear the userinfo, since we use the same request for resending
- // userinfo in url can conflict with the one in the authenticator
- url.setUserInfo(QString());
- request.setUrl(url);
- }
- // Will only be false if Qt WebKit is performing a cross-origin XMLHttpRequest
- // and withCredentials has not been set to true.
- if (request.withCredentials())
- connection->d_func()->createAuthorization(socket, request);
-#ifndef QT_NO_NETWORKPROXY
- QByteArray header = QHttpNetworkRequestPrivate::header(request,
- (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
-#else
- QByteArray header = QHttpNetworkRequestPrivate::header(request, false);
-#endif
- socket->write(header);
- // flushing is dangerous (QSslSocket calls transmit which might read or error)
-// socket->flush();
- QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
- if (uploadByteDevice) {
- // connect the signals so this function gets called again
- QObject::connect(uploadByteDevice, SIGNAL(readyRead()),this, SLOT(_q_uploadDataReadyRead()));
-
- bytesTotal = request.contentLength();
-
- state = QHttpNetworkConnectionChannel::WritingState; // start writing data
- sendRequest(); //recurse
- } else {
- state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
- sendRequest(); //recurse
- }
-
- break;
- }
- case QHttpNetworkConnectionChannel::WritingState:
- {
- // write the data
- QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
- if (!uploadByteDevice || bytesTotal == written) {
- if (uploadByteDevice)
- emit reply->dataSendProgress(written, bytesTotal);
- state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
- sendRequest(); // recurse
- break;
- }
-
- // only feed the QTcpSocket buffer when there is less than 32 kB in it
- const qint64 socketBufferFill = 32*1024;
- const qint64 socketWriteMaxSize = 16*1024;
-
-
-#ifndef QT_NO_SSL
- QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
- // if it is really an ssl socket, check more than just bytesToWrite()
- while ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0))
- <= socketBufferFill && bytesTotal != written)
-#else
- while (socket->bytesToWrite() <= socketBufferFill
- && bytesTotal != written)
-#endif
- {
- // get pointer to upload data
- qint64 currentReadSize = 0;
- qint64 desiredReadSize = qMin(socketWriteMaxSize, bytesTotal - written);
- const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);
-
- if (currentReadSize == -1) {
- // premature eof happened
- connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
- return false;
- } else if (readPointer == 0 || currentReadSize == 0) {
- // nothing to read currently, break the loop
- break;
- } else {
- qint64 currentWriteSize = socket->write(readPointer, currentReadSize);
- if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
- // socket broke down
- connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
- return false;
- } else {
- written += currentWriteSize;
- uploadByteDevice->advanceReadPointer(currentWriteSize);
-
- emit reply->dataSendProgress(written, bytesTotal);
-
- if (written == bytesTotal) {
- // make sure this function is called once again
- state = QHttpNetworkConnectionChannel::WaitingState;
- sendRequest();
- break;
- }
- }
- }
- }
- break;
- }
-
- case QHttpNetworkConnectionChannel::WaitingState:
- {
- QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
- if (uploadByteDevice) {
- QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(_q_uploadDataReadyRead()));
- }
-
- // HTTP pipelining
- //connection->d_func()->fillPipeline(socket);
- //socket->flush();
-
- // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
- // this is needed if the sends an reply before we have finished sending the request. In that
- // case receiveReply had been called before but ignored the server reply
- if (socket->bytesAvailable())
- QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
- break;
- }
- case QHttpNetworkConnectionChannel::ReadingState:
- // ignore _q_bytesWritten in these states
- // fall through
- default:
- break;
- }
- return true;
+ Q_ASSERT(!protocolHandler.isNull());
+ return protocolHandler->sendRequest();
}
void QHttpNetworkConnectionChannel::_q_receiveReply()
{
- Q_ASSERT(socket);
-
- if (!reply) {
- if (socket->bytesAvailable() > 0)
- qWarning() << "QHttpNetworkConnectionChannel::_q_receiveReply() called without QHttpNetworkReply,"
- << socket->bytesAvailable() << "bytes on socket.";
- close();
- return;
- }
-
- // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
- // this function is called from _q_disconnected which is called because
- // of ~QHttpNetworkConnectionPrivate
- if (!qobject_cast<QHttpNetworkConnection*>(connection)) {
- return;
- }
-
- QAbstractSocket::SocketState socketState = socket->state();
-
- // connection might be closed to signal the end of data
- if (socketState == QAbstractSocket::UnconnectedState) {
- if (socket->bytesAvailable() <= 0) {
- if (reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
- // finish this reply. this case happens when the server did not send a content length
- reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
- allDone();
- return;
- } else {
- handleUnexpectedEOF();
- return;
- }
- } else {
- // socket not connected but still bytes for reading.. just continue in this function
- }
- }
-
- // read loop for the response
- qint64 bytes = 0;
- qint64 lastBytes = bytes;
- do {
- lastBytes = bytes;
-
- QHttpNetworkReplyPrivate::ReplyState state = reply->d_func()->state;
- switch (state) {
- case QHttpNetworkReplyPrivate::NothingDoneState: {
- state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
- // fallthrough
- }
- case QHttpNetworkReplyPrivate::ReadingStatusState: {
- qint64 statusBytes = reply->d_func()->readStatus(socket);
- if (statusBytes == -1) {
- // connection broke while reading status. also handled if later _q_disconnected is called
- handleUnexpectedEOF();
- return;
- }
- bytes += statusBytes;
- lastStatus = reply->d_func()->statusCode;
- break;
- }
- case QHttpNetworkReplyPrivate::ReadingHeaderState: {
- QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
- qint64 headerBytes = replyPrivate->readHeader(socket);
- if (headerBytes == -1) {
- // connection broke while reading headers. also handled if later _q_disconnected is called
- handleUnexpectedEOF();
- return;
- }
- bytes += headerBytes;
- // If headers were parsed successfully now it is the ReadingDataState
- if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
- if (replyPrivate->isCompressed() && replyPrivate->autoDecompress) {
- // remove the Content-Length from header
- replyPrivate->removeAutoDecompressHeader();
- } else {
- replyPrivate->autoDecompress = false;
- }
- if (replyPrivate->statusCode == 100) {
- replyPrivate->clearHttpLayerInformation();
- replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
- break; // ignore
- }
- if (replyPrivate->shouldEmitSignals())
- emit reply->headerChanged();
- // After headerChanged had been emitted
- // we can suddenly have a replyPrivate->userProvidedDownloadBuffer
- // this is handled in the ReadingDataState however
-
- if (!replyPrivate->expectContent()) {
- replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
- allDone();
- break;
- }
- }
- break;
- }
- case QHttpNetworkReplyPrivate::ReadingDataState: {
- QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
- if (socket->state() == QAbstractSocket::ConnectedState &&
- replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) {
- // (only do the following when still connected, not when we have already been disconnected and there is still data)
- // We already have some HTTP body data. We don't read more from the socket until
- // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more,
- // we could not limit our read buffer usage.
- // We only do this when shouldEmitSignals==true because our HTTP parsing
- // always needs to parse the 401/407 replies. Therefore they don't really obey
- // to the read buffer maximum size, but we don't care since they should be small.
- return;
- }
-
- if (replyPrivate->userProvidedDownloadBuffer) {
- // the user provided a direct buffer where we should put all our data in.
- // this only works when we can tell the user the content length and he/she can allocate
- // the buffer in that size.
- // note that this call will read only from the still buffered data
- qint64 haveRead = replyPrivate->readBodyVeryFast(socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
- if (haveRead > 0) {
- bytes += haveRead;
- replyPrivate->totalProgress += haveRead;
- // the user will get notified of it via progress signal
- emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- } else if (haveRead == 0) {
- // Happens since this called in a loop. Currently no bytes available.
- } else if (haveRead < 0) {
- connection->d_func()->emitReplyError(socket, reply, QNetworkReply::RemoteHostClosedError);
- break;
- }
- } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
- && replyPrivate->bodyLength > 0) {
- // bulk files like images should fulfill these properties and
- // we can therefore save on memory copying
- qint64 haveRead = replyPrivate->readBodyFast(socket, &replyPrivate->responseData);
- bytes += haveRead;
- replyPrivate->totalProgress += haveRead;
- if (replyPrivate->shouldEmitSignals()) {
- emit reply->readyRead();
- emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- }
- }
- else
- {
- // use the traditional slower reading (for compressed encoding, chunked encoding,
- // no content-length etc)
- qint64 haveRead = replyPrivate->readBody(socket, &replyPrivate->responseData);
- if (haveRead > 0) {
- bytes += haveRead;
- replyPrivate->totalProgress += haveRead;
- if (replyPrivate->shouldEmitSignals()) {
- emit reply->readyRead();
- emit reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
- }
- } else if (haveRead == -1) {
- // Some error occurred
- connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolFailure);
- break;
- }
- }
- // still in ReadingDataState? This function will be called again by the socket's readyRead
- if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState)
- break;
+ Q_ASSERT(!protocolHandler.isNull());
+ protocolHandler->_q_receiveReply();
+}
- // everything done, fall through
- }
- case QHttpNetworkReplyPrivate::AllDoneState:
- allDone();
- break;
- default:
- break;
- }
- } while (bytes != lastBytes && reply);
+void QHttpNetworkConnectionChannel::_q_readyRead()
+{
+ Q_ASSERT(!protocolHandler.isNull());
+ protocolHandler->_q_readyRead();
}
// called when unexpectedly reading a -1 or when data is expected but socket is closed
@@ -724,6 +400,7 @@ void QHttpNetworkConnectionChannel::allDone()
if (!resendCurrent) {
request = QHttpNetworkRequest();
reply = 0;
+ protocolHandler->setReply(0);
}
// move next from pipeline to current request
@@ -738,6 +415,7 @@ void QHttpNetworkConnectionChannel::allDone()
request = messagePair.first;
reply = messagePair.second;
+ protocolHandler->setReply(messagePair.second);
state = QHttpNetworkConnectionChannel::ReadingState;
resendCurrent = false;
@@ -982,32 +660,6 @@ bool QHttpNetworkConnectionChannel::isSocketReading() const
return (state & QHttpNetworkConnectionChannel::ReadingState);
}
-//private slots
-void QHttpNetworkConnectionChannel::_q_readyRead()
-{
- if (socket->state() == QAbstractSocket::ConnectedState && socket->bytesAvailable() == 0) {
- // We got a readyRead but no bytes are available..
- // This happens for the Unbuffered QTcpSocket
- // Also check if socket is in ConnectedState since
- // this function may also be invoked via the event loop.
- char c;
- qint64 ret = socket->peek(&c, 1);
- if (ret < 0) {
- _q_error(socket->error());
- // We still need to handle the reply so it emits its signals etc.
- if (reply)
- _q_receiveReply();
- return;
- }
- }
-
- if (isSocketWaiting() || isSocketReading()) {
- state = QHttpNetworkConnectionChannel::ReadingState;
- if (reply)
- _q_receiveReply();
- }
-}
-
void QHttpNetworkConnectionChannel::_q_bytesWritten(qint64 bytes)
{
Q_UNUSED(bytes);
@@ -1224,6 +876,8 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
reply->d_func()->errorString = errorString;
emit reply->finishedWithError(errorCode, errorString);
reply = 0;
+ if (protocolHandler)
+ protocolHandler->setReply(0);
}
// send the next request
QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection);
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index c8138b5453..7230eb2543 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -66,6 +66,7 @@
#include <private/qhttpnetworkreply_p.h>
#include <private/qhttpnetworkconnection_p.h>
+#include <private/qabstractprotocolhandler_p.h>
#ifndef QT_NO_HTTP
@@ -117,6 +118,7 @@ public:
QAuthenticator proxyAuthenticator;
bool authenticationCredentialsSent;
bool proxyCredentialsSent;
+ QScopedPointer<QAbstractProtocolHandler> protocolHandler;
#ifndef QT_NO_SSL
bool ignoreAllSslErrors;
QList<QSslError> ignoreSslErrorsList;
@@ -193,6 +195,8 @@ public:
void _q_sslErrors(const QList<QSslError> &errors); // ssl errors from the socket
void _q_encryptedBytesWritten(qint64 bytes); // proceed sending
#endif
+
+ friend class QHttpProtocolHandler;
};
QT_END_NAMESPACE
diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h
index 7aea9f14ec..583c3e426f 100644
--- a/src/network/access/qhttpnetworkreply_p.h
+++ b/src/network/access/qhttpnetworkreply_p.h
@@ -164,6 +164,7 @@ private:
friend class QHttpNetworkConnection;
friend class QHttpNetworkConnectionPrivate;
friend class QHttpNetworkConnectionChannel;
+ friend class QHttpProtocolHandler;
};
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index d9f9b555d7..3786f9b992 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -87,9 +87,9 @@ bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &ot
&& (preConnect == other.preConnect);
}
-QByteArray QHttpNetworkRequestPrivate::methodName() const
+QByteArray QHttpNetworkRequest::methodName() const
{
- switch (operation) {
+ switch (d->operation) {
case QHttpNetworkRequest::Get:
return "GET";
case QHttpNetworkRequest::Head:
@@ -107,24 +107,24 @@ QByteArray QHttpNetworkRequestPrivate::methodName() const
case QHttpNetworkRequest::Connect:
return "CONNECT";
case QHttpNetworkRequest::Custom:
- return customVerb;
+ return d->customVerb;
default:
break;
}
return QByteArray();
}
-QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const
+QByteArray QHttpNetworkRequest::uri(bool throughProxy) const
{
QUrl::FormattingOptions format(QUrl::RemoveFragment | QUrl::RemoveUserInfo | QUrl::FullyEncoded);
// for POST, query data is send as content
- if (operation == QHttpNetworkRequest::Post && !uploadByteDevice)
+ if (d->operation == QHttpNetworkRequest::Post && !d->uploadByteDevice)
format |= QUrl::RemoveQuery;
// for requests through proxy, the Request-URI contains full url
if (!throughProxy)
format |= QUrl::RemoveScheme | QUrl::RemoveAuthority;
- QUrl copy = url;
+ QUrl copy = d->url;
if (copy.path().isEmpty())
copy.setPath(QStringLiteral("/"));
QByteArray uri = copy.toEncoded(format);
@@ -137,9 +137,9 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request
QByteArray ba;
ba.reserve(40 + fields.length()*25); // very rough lower bound estimation
- ba += request.d->methodName();
+ ba += request.methodName();
ba += ' ';
- ba += request.d->uri(throughProxy);
+ ba += request.uri(throughProxy);
ba += " HTTP/";
ba += QByteArray::number(request.majorVersion());
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index ce9fbb1509..f224f7329d 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -126,11 +126,15 @@ public:
void setUploadByteDevice(QNonContiguousByteDevice *bd);
QNonContiguousByteDevice* uploadByteDevice() const;
+ QByteArray methodName() const;
+ QByteArray uri(bool throughProxy) const;
+
private:
QSharedDataPointer<QHttpNetworkRequestPrivate> d;
friend class QHttpNetworkRequestPrivate;
friend class QHttpNetworkConnectionPrivate;
friend class QHttpNetworkConnectionChannel;
+ friend class QHttpProtocolHandler;
};
class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate
@@ -141,8 +145,6 @@ public:
QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other);
~QHttpNetworkRequestPrivate();
bool operator==(const QHttpNetworkRequestPrivate &other) const;
- QByteArray methodName() const;
- QByteArray uri(bool throughProxy) const;
static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy);
diff --git a/src/network/access/qhttpprotocolhandler.cpp b/src/network/access/qhttpprotocolhandler.cpp
new file mode 100644
index 0000000000..15cba48285
--- /dev/null
+++ b/src/network/access/qhttpprotocolhandler.cpp
@@ -0,0 +1,431 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qhttpprotocolhandler_p.h>
+#include <private/qnoncontiguousbytedevice_p.h>
+#include <private/qhttpnetworkconnectionchannel_p.h>
+
+#ifndef QT_NO_HTTP
+
+QT_BEGIN_NAMESPACE
+
+QHttpProtocolHandler::QHttpProtocolHandler(QHttpNetworkConnectionChannel *channel)
+ : QAbstractProtocolHandler(channel)
+{
+}
+
+void QHttpProtocolHandler::_q_receiveReply()
+{
+ Q_ASSERT(m_socket);
+
+ if (!m_reply) {
+ if (m_socket->bytesAvailable() > 0)
+ qWarning() << "QAbstractProtocolHandler::_q_receiveReply() called without QHttpNetworkReply,"
+ << m_socket->bytesAvailable() << "bytes on socket.";
+ m_channel->close();
+ return;
+ }
+
+ // only run when the QHttpNetworkConnection is not currently being destructed, e.g.
+ // this function is called from _q_disconnected which is called because
+ // of ~QHttpNetworkConnectionPrivate
+ if (!qobject_cast<QHttpNetworkConnection*>(m_connection)) {
+ return;
+ }
+
+ QAbstractSocket::SocketState socketState = m_socket->state();
+
+ // connection might be closed to signal the end of data
+ if (socketState == QAbstractSocket::UnconnectedState) {
+ if (m_socket->bytesAvailable() <= 0) {
+ if (m_reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) {
+ // finish this reply. this case happens when the server did not send a content length
+ m_reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
+ m_channel->allDone();
+ return;
+ } else {
+ m_channel->handleUnexpectedEOF();
+ return;
+ }
+ } else {
+ // socket not connected but still bytes for reading.. just continue in this function
+ }
+ }
+
+ // read loop for the response
+ qint64 bytes = 0;
+ qint64 lastBytes = bytes;
+ do {
+ lastBytes = bytes;
+
+ QHttpNetworkReplyPrivate::ReplyState state = m_reply->d_func()->state;
+ switch (state) {
+ case QHttpNetworkReplyPrivate::NothingDoneState: {
+ m_reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState;
+ // fallthrough
+ }
+ case QHttpNetworkReplyPrivate::ReadingStatusState: {
+ qint64 statusBytes = m_reply->d_func()->readStatus(m_socket);
+ if (statusBytes == -1) {
+ // connection broke while reading status. also handled if later _q_disconnected is called
+ m_channel->handleUnexpectedEOF();
+ return;
+ }
+ bytes += statusBytes;
+ m_channel->lastStatus = m_reply->d_func()->statusCode;
+ break;
+ }
+ case QHttpNetworkReplyPrivate::ReadingHeaderState: {
+ QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
+ qint64 headerBytes = replyPrivate->readHeader(m_socket);
+ if (headerBytes == -1) {
+ // connection broke while reading headers. also handled if later _q_disconnected is called
+ m_channel->handleUnexpectedEOF();
+ return;
+ }
+ bytes += headerBytes;
+ // If headers were parsed successfully now it is the ReadingDataState
+ if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState) {
+ if (replyPrivate->isCompressed() && replyPrivate->autoDecompress) {
+ // remove the Content-Length from header
+ replyPrivate->removeAutoDecompressHeader();
+ } else {
+ replyPrivate->autoDecompress = false;
+ }
+ if (replyPrivate->statusCode == 100) {
+ replyPrivate->clearHttpLayerInformation();
+ replyPrivate->state = QHttpNetworkReplyPrivate::ReadingStatusState;
+ break; // ignore
+ }
+ if (replyPrivate->shouldEmitSignals())
+ emit m_reply->headerChanged();
+ // After headerChanged had been emitted
+ // we can suddenly have a replyPrivate->userProvidedDownloadBuffer
+ // this is handled in the ReadingDataState however
+
+ if (!replyPrivate->expectContent()) {
+ replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState;
+ m_channel->allDone();
+ break;
+ }
+ }
+ break;
+ }
+ case QHttpNetworkReplyPrivate::ReadingDataState: {
+ QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
+ if (m_socket->state() == QAbstractSocket::ConnectedState &&
+ replyPrivate->downstreamLimited && !replyPrivate->responseData.isEmpty() && replyPrivate->shouldEmitSignals()) {
+ // (only do the following when still connected, not when we have already been disconnected and there is still data)
+ // We already have some HTTP body data. We don't read more from the socket until
+ // this is fetched by QHttpNetworkAccessHttpBackend. If we would read more,
+ // we could not limit our read buffer usage.
+ // We only do this when shouldEmitSignals==true because our HTTP parsing
+ // always needs to parse the 401/407 replies. Therefore they don't really obey
+ // to the read buffer maximum size, but we don't care since they should be small.
+ return;
+ }
+
+ if (replyPrivate->userProvidedDownloadBuffer) {
+ // the user provided a direct buffer where we should put all our data in.
+ // this only works when we can tell the user the content length and he/she can allocate
+ // the buffer in that size.
+ // note that this call will read only from the still buffered data
+ qint64 haveRead = replyPrivate->readBodyVeryFast(m_socket, replyPrivate->userProvidedDownloadBuffer + replyPrivate->totalProgress);
+ if (haveRead > 0) {
+ bytes += haveRead;
+ replyPrivate->totalProgress += haveRead;
+ // the user will get notified of it via progress signal
+ emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+ } else if (haveRead == 0) {
+ // Happens since this called in a loop. Currently no bytes available.
+ } else if (haveRead < 0) {
+ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::RemoteHostClosedError);
+ break;
+ }
+ } else if (!replyPrivate->isChunked() && !replyPrivate->autoDecompress
+ && replyPrivate->bodyLength > 0) {
+ // bulk files like images should fulfill these properties and
+ // we can therefore save on memory copying
+ qint64 haveRead = replyPrivate->readBodyFast(m_socket, &replyPrivate->responseData);
+ bytes += haveRead;
+ replyPrivate->totalProgress += haveRead;
+ if (replyPrivate->shouldEmitSignals()) {
+ emit m_reply->readyRead();
+ emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+ }
+ }
+ else
+ {
+ // use the traditional slower reading (for compressed encoding, chunked encoding,
+ // no content-length etc)
+ qint64 haveRead = replyPrivate->readBody(m_socket, &replyPrivate->responseData);
+ if (haveRead > 0) {
+ bytes += haveRead;
+ replyPrivate->totalProgress += haveRead;
+ if (replyPrivate->shouldEmitSignals()) {
+ emit m_reply->readyRead();
+ emit m_reply->dataReadProgress(replyPrivate->totalProgress, replyPrivate->bodyLength);
+ }
+ } else if (haveRead == -1) {
+ // Some error occurred
+ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::ProtocolFailure);
+ break;
+ }
+ }
+ // still in ReadingDataState? This function will be called again by the socket's readyRead
+ if (replyPrivate->state == QHttpNetworkReplyPrivate::ReadingDataState)
+ break;
+
+ // everything done, fall through
+ }
+ case QHttpNetworkReplyPrivate::AllDoneState:
+ m_channel->allDone();
+ break;
+ default:
+ break;
+ }
+ } while (bytes != lastBytes && m_reply);
+}
+
+void QHttpProtocolHandler::_q_readyRead()
+{
+ if (m_socket->state() == QAbstractSocket::ConnectedState && m_socket->bytesAvailable() == 0) {
+ // We got a readyRead but no bytes are available..
+ // This happens for the Unbuffered QTcpSocket
+ // Also check if socket is in ConnectedState since
+ // this function may also be invoked via the event loop.
+ char c;
+ qint64 ret = m_socket->peek(&c, 1);
+ if (ret < 0) {
+ m_channel->_q_error(m_socket->error());
+ // We still need to handle the reply so it emits its signals etc.
+ if (m_reply)
+ _q_receiveReply();
+ return;
+ }
+ }
+
+ if (m_channel->isSocketWaiting() || m_channel->isSocketReading()) {
+ m_channel->state = QHttpNetworkConnectionChannel::ReadingState;
+ if (m_reply)
+ _q_receiveReply();
+ }
+}
+
+bool QHttpProtocolHandler::sendRequest()
+{
+ m_reply = m_channel->reply;
+
+ if (!m_reply) {
+ // heh, how should that happen!
+ qWarning() << "QAbstractProtocolHandler::sendRequest() called without QHttpNetworkReply";
+ m_channel->state = QHttpNetworkConnectionChannel::IdleState;
+ return false;
+ }
+
+ switch (m_channel->state) {
+ case QHttpNetworkConnectionChannel::IdleState: { // write the header
+ if (!m_channel->ensureConnection()) {
+ // wait for the connection (and encryption) to be done
+ // sendRequest will be called again from either
+ // _q_connected or _q_encrypted
+ return false;
+ }
+ QString scheme = m_channel->request.url().scheme();
+ if (scheme == QLatin1String("preconnect-http")
+ || scheme == QLatin1String("preconnect-https")) {
+ m_channel->state = QHttpNetworkConnectionChannel::IdleState;
+ m_reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState;
+ m_channel->allDone();
+ m_connection->preConnectFinished(); // will only decrease the counter
+ m_reply = 0; // so we can reuse this channel
+ return true; // we have a working connection and are done
+ }
+
+ m_channel->written = 0; // excluding the header
+ m_channel->bytesTotal = 0;
+
+ QHttpNetworkReplyPrivate *replyPrivate = m_reply->d_func();
+ replyPrivate->clear();
+ replyPrivate->connection = m_connection;
+ replyPrivate->connectionChannel = m_channel;
+ replyPrivate->autoDecompress = m_channel->request.d->autoDecompress;
+ replyPrivate->pipeliningUsed = false;
+
+ // if the url contains authentication parameters, use the new ones
+ // both channels will use the new authentication parameters
+ if (!m_channel->request.url().userInfo().isEmpty() && m_channel->request.withCredentials()) {
+ QUrl url = m_channel->request.url();
+ QAuthenticator &auth = m_channel->authenticator;
+ if (url.userName() != auth.user()
+ || (!url.password().isEmpty() && url.password() != auth.password())) {
+ auth.setUser(url.userName());
+ auth.setPassword(url.password());
+ m_connection->d_func()->copyCredentials(m_connection->d_func()->indexOf(m_socket), &auth, false);
+ }
+ // clear the userinfo, since we use the same request for resending
+ // userinfo in url can conflict with the one in the authenticator
+ url.setUserInfo(QString());
+ m_channel->request.setUrl(url);
+ }
+ // Will only be false if Qt WebKit is performing a cross-origin XMLHttpRequest
+ // and withCredentials has not been set to true.
+ if (m_channel->request.withCredentials())
+ m_connection->d_func()->createAuthorization(m_socket, m_channel->request);
+#ifndef QT_NO_NETWORKPROXY
+ QByteArray header = QHttpNetworkRequestPrivate::header(m_channel->request,
+ (m_connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
+#else
+ QByteArray header = QHttpNetworkRequestPrivate::header(m_channel->request, false);
+#endif
+ m_socket->write(header);
+ // flushing is dangerous (QSslSocket calls transmit which might read or error)
+// m_socket->flush();
+ QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
+ if (uploadByteDevice) {
+ // connect the signals so this function gets called again
+ QObject::connect(uploadByteDevice, SIGNAL(readyRead()), m_channel, SLOT(_q_uploadDataReadyRead()));
+
+ m_channel->bytesTotal = m_channel->request.contentLength();
+
+ m_channel->state = QHttpNetworkConnectionChannel::WritingState; // start writing data
+ sendRequest(); //recurse
+ } else {
+ m_channel->state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
+ sendRequest(); //recurse
+ }
+
+ break;
+ }
+ case QHttpNetworkConnectionChannel::WritingState:
+ {
+ // write the data
+ QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
+ if (!uploadByteDevice || m_channel->bytesTotal == m_channel->written) {
+ if (uploadByteDevice)
+ emit m_reply->dataSendProgress(m_channel->written, m_channel->bytesTotal);
+ m_channel->state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
+ sendRequest(); // recurse
+ break;
+ }
+
+ // only feed the QTcpSocket buffer when there is less than 32 kB in it
+ const qint64 socketBufferFill = 32*1024;
+ const qint64 socketWriteMaxSize = 16*1024;
+
+
+#ifndef QT_NO_SSL
+ QSslSocket *sslSocket = qobject_cast<QSslSocket*>(m_socket);
+ // if it is really an ssl socket, check more than just bytesToWrite()
+ while ((m_socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0))
+ <= socketBufferFill && m_channel->bytesTotal != m_channel->written)
+#else
+ while (m_socket->bytesToWrite() <= socketBufferFill
+ && m_channel->bytesTotal != m_channel->written)
+#endif
+ {
+ // get pointer to upload data
+ qint64 currentReadSize = 0;
+ qint64 desiredReadSize = qMin(socketWriteMaxSize, m_channel->bytesTotal - m_channel->written);
+ const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);
+
+ if (currentReadSize == -1) {
+ // premature eof happened
+ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::UnknownNetworkError);
+ return false;
+ } else if (readPointer == 0 || currentReadSize == 0) {
+ // nothing to read currently, break the loop
+ break;
+ } else {
+ qint64 currentWriteSize = m_socket->write(readPointer, currentReadSize);
+ if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
+ // socket broke down
+ m_connection->d_func()->emitReplyError(m_socket, m_reply, QNetworkReply::UnknownNetworkError);
+ return false;
+ } else {
+ m_channel->written += currentWriteSize;
+ uploadByteDevice->advanceReadPointer(currentWriteSize);
+
+ emit m_reply->dataSendProgress(m_channel->written, m_channel->bytesTotal);
+
+ if (m_channel->written == m_channel->bytesTotal) {
+ // make sure this function is called once again
+ m_channel->state = QHttpNetworkConnectionChannel::WaitingState;
+ sendRequest();
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case QHttpNetworkConnectionChannel::WaitingState:
+ {
+ QNonContiguousByteDevice* uploadByteDevice = m_channel->request.uploadByteDevice();
+ if (uploadByteDevice) {
+ QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), m_channel, SLOT(_q_uploadDataReadyRead()));
+ }
+
+ // HTTP pipelining
+ //m_connection->d_func()->fillPipeline(m_socket);
+ //m_socket->flush();
+
+ // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
+ // this is needed if the sends an reply before we have finished sending the request. In that
+ // case receiveReply had been called before but ignored the server reply
+ if (m_socket->bytesAvailable())
+ QMetaObject::invokeMethod(m_channel, "_q_receiveReply", Qt::QueuedConnection);
+ break;
+ }
+ case QHttpNetworkConnectionChannel::ReadingState:
+ // ignore _q_bytesWritten in these states
+ // fall through
+ default:
+ break;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_HTTP
diff --git a/src/network/access/qhttpprotocolhandler_p.h b/src/network/access/qhttpprotocolhandler_p.h
new file mode 100644
index 0000000000..2bbc044b6c
--- /dev/null
+++ b/src/network/access/qhttpprotocolhandler_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTPPROTOCOLHANDLER_H
+#define QHTTPPROTOCOLHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the Network Access API. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qabstractprotocolhandler_p.h>
+
+#ifndef QT_NO_HTTP
+
+QT_BEGIN_NAMESPACE
+
+class QHttpProtocolHandler : public QAbstractProtocolHandler {
+public:
+ QHttpProtocolHandler(QHttpNetworkConnectionChannel *channel);
+
+private:
+ virtual void _q_receiveReply() Q_DECL_OVERRIDE;
+ virtual void _q_readyRead() Q_DECL_OVERRIDE;
+ virtual bool sendRequest() Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_HTTP
+
+#endif
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index ee3911c72c..b7e8bb3f72 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -60,6 +60,10 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
QNetworkReply::NetworkError code;
// we've got an error
switch (httpStatusCode) {
+ case 400: // Bad Request
+ code = QNetworkReply::ProtocolInvalidOperationError;
+ break;
+
case 401: // Authorization required
code = QNetworkReply::AuthenticationRequiredError;
break;
@@ -80,15 +84,34 @@ static QNetworkReply::NetworkError statusCodeFromHttp(int httpStatusCode, const
code = QNetworkReply::ProxyAuthenticationRequiredError;
break;
+ case 409: // Resource Conflict
+ code = QNetworkReply::ContentConflictError;
+ break;
+
+ case 410: // Content no longer available
+ code = QNetworkReply::ContentGoneError;
+ break;
+
case 418: // I'm a teapot
code = QNetworkReply::ProtocolInvalidOperationError;
break;
+ case 500: // Internal Server Error
+ code = QNetworkReply::InternalServerError;
+ break;
+
+ case 501: // Server does not support this functionality
+ code = QNetworkReply::OperationNotImplementedError;
+ break;
+
+ case 503: // Service unavailable
+ code = QNetworkReply::ServiceUnavailableError;
+ break;
default:
if (httpStatusCode > 500) {
// some kind of server error
- code = QNetworkReply::ProtocolUnknownError;
+ code = QNetworkReply::UnknownServerError;
} else if (httpStatusCode >= 400) {
// content error we did not handle above
code = QNetworkReply::UnknownContentError;
diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp
index a871c04d56..664bc8282c 100644
--- a/src/network/access/qnetworkcookie.cpp
+++ b/src/network/access/qnetworkcookie.cpp
@@ -51,6 +51,7 @@
#include "QtCore/qstring.h"
#include "QtCore/qstringlist.h"
#include "QtCore/qurl.h"
+#include "QtNetwork/qhostaddress.h"
#include "private/qobject_p.h"
QT_BEGIN_NAMESPACE
@@ -466,12 +467,19 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const
}
if (!d->domain.isEmpty()) {
result += "; domain=";
- QString domainNoDot = d->domain;
- if (domainNoDot.startsWith(QLatin1Char('.'))) {
+ if (d->domain.startsWith(QLatin1Char('.'))) {
result += '.';
- domainNoDot = domainNoDot.mid(1);
+ result += QUrl::toAce(d->domain.mid(1));
+ } else {
+ QHostAddress hostAddr(d->domain);
+ if (hostAddr.protocol() == QAbstractSocket::IPv6Protocol) {
+ result += '[';
+ result += d->domain.toUtf8();
+ result += ']';
+ } else {
+ result += QUrl::toAce(d->domain);
+ }
}
- result += QUrl::toAce(domainNoDot);
}
if (!d->path.isEmpty()) {
result += "; path=";
@@ -1015,14 +1023,20 @@ void QNetworkCookie::normalize(const QUrl &url)
d->path = defaultPath;
}
- if (d->domain.isEmpty())
+ if (d->domain.isEmpty()) {
d->domain = url.host();
- else if (!d->domain.startsWith(QLatin1Char('.')))
- // Ensure the domain starts with a dot if its field was not empty
- // in the HTTP header. There are some servers that forget the
- // leading dot and this is actually forbidden according to RFC 2109,
- // but all browsers accept it anyway so we do that as well.
- d->domain.prepend(QLatin1Char('.'));
+ } else {
+ QHostAddress hostAddress(d->domain);
+ if (hostAddress.protocol() != QAbstractSocket::IPv4Protocol
+ && hostAddress.protocol() != QAbstractSocket::IPv6Protocol
+ && !d->domain.startsWith(QLatin1Char('.'))) {
+ // Ensure the domain starts with a dot if its field was not empty
+ // in the HTTP header. There are some servers that forget the
+ // leading dot and this is actually forbidden according to RFC 2109,
+ // but all browsers accept it anyway so we do that as well.
+ d->domain.prepend(QLatin1Char('.'));
+ }
+ }
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index ba6f706f7a..faa8464463 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -173,6 +173,21 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
again, but this failed for example because the upload data
could not be read a second time.
+ \value ContentConflictError the request could not be completed due
+ to a conflict with the current state of the resource.
+
+ \value ContentGoneError the requested resource is no longer
+ available at the server.
+
+ \value InternalServerError the server encountered an unexpected
+ condition which prevented it from fulfilling the request.
+
+ \value OperationNotImplementedError the server does not support the
+ functionality required to fulfill the request.
+
+ \value ServiceUnavailableError the server is unable to handle the
+ request at this time.
+
\value ProtocolUnknownError the Network Access API cannot
honor the request because the protocol is not known
@@ -191,6 +206,9 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
\value ProtocolFailure a breakdown in protocol was
detected (parsing error, invalid or unexpected responses, etc.)
+ \value UnknownServerError an unknown error related to
+ the server response was detected
+
\sa error()
*/
diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h
index a7db2d189c..f11a5e816a 100644
--- a/src/network/access/qnetworkreply.h
+++ b/src/network/access/qnetworkreply.h
@@ -93,12 +93,20 @@ public:
ContentNotFoundError,
AuthenticationRequiredError,
ContentReSendError,
+ ContentConflictError,
+ ContentGoneError,
UnknownContentError = 299,
// protocol errors
ProtocolUnknownError = 301,
ProtocolInvalidOperationError,
- ProtocolFailure = 399
+ ProtocolFailure = 399,
+
+ // Server side errors (401-499)
+ InternalServerError = 401,
+ OperationNotImplementedError,
+ ServiceUnavailableError,
+ UnknownServerError = 499
};
~QNetworkReply();
diff --git a/src/network/doc/snippets/network/tcpwait.cpp b/src/network/doc/snippets/network/tcpwait.cpp
index fb44e2ded9..e5e4c1ed40 100644
--- a/src/network/doc/snippets/network/tcpwait.cpp
+++ b/src/network/doc/snippets/network/tcpwait.cpp
@@ -55,13 +55,13 @@ int main(int argv, char **args)
char buffer[50];
forever {
- numRead = socket.read(buffer, 50);
+ numRead = socket.read(buffer, 50);
- // do whatever with array
+ // do whatever with array
- numReadTotal += numRead;
+ numReadTotal += numRead;
if (numRead == 0 && !socket.waitForReadyRead())
- break;
+ break;
}
//! [0]
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index 97f52fdb6e..9b584be206 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -33,9 +33,17 @@ android {
}
win32: {
- HEADERS += kernel/qnetworkinterface_win_p.h
- SOURCES += kernel/qdnslookup_win.cpp kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp
- LIBS_PRIVATE += -ldnsapi
+ !winrt {
+ HEADERS += kernel/qnetworkinterface_win_p.h
+ SOURCES += kernel/qdnslookup_win.cpp \
+ kernel/qhostinfo_win.cpp \
+ kernel/qnetworkinterface_win.cpp
+ LIBS_PRIVATE += -ldnsapi
+ } else {
+ SOURCES += kernel/qdnslookup_winrt.cpp \
+ kernel/qhostinfo_winrt.cpp \
+ kernel/qnetworkinterface_winrt.cpp
+ }
}
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 8c16486878..edbbbf5a75 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -55,9 +55,11 @@
#include <qmutex.h>
#include <private/qmutexpool_p.h>
#include <rpc.h>
+#ifndef Q_OS_WINRT
#define SECURITY_WIN32 1
#include <security.h>
#endif
+#endif
//#define NTLMV1_CLIENT
@@ -69,7 +71,7 @@ QT_BEGIN_NAMESPACE
static QByteArray qNtlmPhase1();
static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx);
static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
#endif
@@ -328,7 +330,7 @@ bool QAuthenticator::isNull() const
return !d;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
class QNtlmWindowsHandles
{
public:
@@ -340,7 +342,7 @@ public:
QAuthenticatorPrivate::QAuthenticatorPrivate()
: method(None)
- #ifdef Q_OS_WIN
+ #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
, ntlmWindowsHandles(0)
#endif
, hasFailed(false)
@@ -354,7 +356,7 @@ QAuthenticatorPrivate::QAuthenticatorPrivate()
QAuthenticatorPrivate::~QAuthenticatorPrivate()
{
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (ntlmWindowsHandles)
delete ntlmWindowsHandles;
#endif
@@ -485,7 +487,7 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
case QAuthenticatorPrivate::Ntlm:
methodString = "NTLM ";
if (challenge.isEmpty()) {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QByteArray phase1Token;
if (user.isEmpty()) // Only pull from system if no user was specified in authenticator
phase1Token = qNtlmPhase1_SSPI(this);
@@ -502,7 +504,7 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
phase = Phase2;
}
} else {
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QByteArray phase3Token;
if (ntlmWindowsHandles)
phase3Token = qNtlmPhase3_SSPI(this, QByteArray::fromBase64(challenge));
@@ -1475,7 +1477,7 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
return rc;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// See http://davenport.sourceforge.net/ntlm.html
// and libcurl http_ntlm.c
@@ -1513,7 +1515,6 @@ static bool q_NTLM_SSPI_library_load()
return true;
}
-#ifdef Q_OS_WIN
// Phase 1:
static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx)
{
@@ -1631,8 +1632,6 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray&
return result;
}
-#endif // Q_OS_WIN
-
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
QT_END_NAMESPACE
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index 53675d083b..97a402901e 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -363,6 +363,25 @@ void QDnsLookup::setType(Type type)
}
/*!
+ \property QDnsLookup::nameserver
+ \brief the nameserver to use for DNS lookup.
+*/
+
+QHostAddress QDnsLookup::nameserver() const
+{
+ return d_func()->nameserver;
+}
+
+void QDnsLookup::setNameserver(const QHostAddress &nameserver)
+{
+ Q_D(QDnsLookup);
+ if (nameserver != d->nameserver) {
+ d->nameserver = nameserver;
+ emit nameserverChanged(nameserver);
+ }
+}
+
+/*!
Returns the list of canonical name records associated with this lookup.
*/
@@ -463,7 +482,7 @@ void QDnsLookup::lookup()
Q_D(QDnsLookup);
d->isFinished = false;
d->reply = QDnsLookupReply();
- d->runnable = new QDnsLookupRunnable(d->type, QUrl::toAce(d->name));
+ d->runnable = new QDnsLookupRunnable(d->type, QUrl::toAce(d->name), d->nameserver);
connect(d->runnable, SIGNAL(finished(QDnsLookupReply)),
this, SLOT(_q_lookupFinished(QDnsLookupReply)),
Qt::BlockingQueuedConnection);
@@ -971,7 +990,7 @@ void QDnsLookupRunnable::run()
}
// Perform request.
- query(requestType, requestName, &reply);
+ query(requestType, requestName, nameserver, &reply);
// Sort results.
if (!theDnsLookupSeedStorage()->hasLocalData()) {
diff --git a/src/network/kernel/qdnslookup.h b/src/network/kernel/qdnslookup.h
index 1df21d866e..ffbef61f92 100644
--- a/src/network/kernel/qdnslookup.h
+++ b/src/network/kernel/qdnslookup.h
@@ -180,6 +180,7 @@ class Q_NETWORK_EXPORT QDnsLookup : public QObject
Q_PROPERTY(QString errorString READ errorString NOTIFY finished)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(Type type READ type WRITE setType NOTIFY typeChanged)
+ Q_PROPERTY(QHostAddress nameserver READ nameserver WRITE setNameserver NOTIFY nameserverChanged)
public:
enum Error
@@ -209,6 +210,7 @@ public:
explicit QDnsLookup(QObject *parent = 0);
QDnsLookup(Type type, const QString &name, QObject *parent = 0);
+ QDnsLookup(Type type, const QString &name, const QHostAddress &nameserver, QObject *parent = 0);
~QDnsLookup();
Error error() const;
@@ -221,6 +223,9 @@ public:
Type type() const;
void setType(QDnsLookup::Type);
+ QHostAddress nameserver() const;
+ void setNameserver(const QHostAddress &nameserver);
+
QList<QDnsDomainNameRecord> canonicalNameRecords() const;
QList<QDnsHostAddressRecord> hostAddressRecords() const;
QList<QDnsMailExchangeRecord> mailExchangeRecords() const;
@@ -238,6 +243,7 @@ Q_SIGNALS:
void finished();
void nameChanged(const QString &name);
void typeChanged(Type type);
+ void nameserverChanged(const QHostAddress &nameserver);
private:
Q_DECLARE_PRIVATE(QDnsLookup)
diff --git a/src/network/kernel/qdnslookup_android.cpp b/src/network/kernel/qdnslookup_android.cpp
index dff81dba0c..1ace5727c2 100644
--- a/src/network/kernel/qdnslookup_android.cpp
+++ b/src/network/kernel/qdnslookup_android.cpp
@@ -43,10 +43,11 @@
QT_BEGIN_NAMESPACE
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
Q_UNUSED(requestType);
Q_UNUSED(requestName);
+ Q_UNUSED(nameserver);
Q_UNUSED(reply);
qWarning() << Q_FUNC_INFO << "Not yet supported on Android";
reply->error = QDnsLookup::ResolverError;
diff --git a/src/network/kernel/qdnslookup_p.h b/src/network/kernel/qdnslookup_p.h
index 692b9088fe..7c0b0e862a 100644
--- a/src/network/kernel/qdnslookup_p.h
+++ b/src/network/kernel/qdnslookup_p.h
@@ -100,6 +100,7 @@ public:
bool isFinished;
QString name;
QDnsLookup::Type type;
+ QHostAddress nameserver;
QDnsLookupReply reply;
QDnsLookupRunnable *runnable;
@@ -111,9 +112,10 @@ class QDnsLookupRunnable : public QObject, public QRunnable
Q_OBJECT
public:
- QDnsLookupRunnable(QDnsLookup::Type type, const QByteArray &name)
+ QDnsLookupRunnable(QDnsLookup::Type type, const QByteArray &name, const QHostAddress &nameserver)
: requestType(type)
, requestName(name)
+ , nameserver(nameserver)
{ }
void run();
@@ -121,9 +123,10 @@ signals:
void finished(const QDnsLookupReply &reply);
private:
- static void query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply);
+ static void query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply);
QDnsLookup::Type requestType;
QByteArray requestName;
+ QHostAddress nameserver;
};
class QDnsLookupThreadPool : public QThreadPool
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 9fb488cee6..26834dff57 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -115,7 +115,7 @@ static void resolveLibrary()
local_res_nquery = res_nquery_proto(lib.resolve("res_nquery"));
}
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
// Load dn_expand, res_ninit and res_nquery on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false);
@@ -142,6 +142,43 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
reply->errorString = tr("Resolver initialization failed");
return;
}
+
+ //Check if a nameserver was set. If so, use it
+ if (!nameserver.isNull()) {
+ if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) {
+ state.nsaddr_list[0].sin_addr.s_addr = htonl(nameserver.toIPv4Address());
+ state.nscount = 1;
+ } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
+#if defined(Q_OS_LINUX)
+ struct sockaddr_in6 *ns;
+ ns = state._u._ext.nsaddrs[0];
+ // nsaddrs will be NULL if no nameserver is set in /etc/resolv.conf
+ if (!ns) {
+ // Memory allocated here will be free'd in res_close() as we
+ // have done res_init() above.
+ ns = (struct sockaddr_in6*) calloc(1, sizeof(struct sockaddr_in6));
+ Q_CHECK_PTR(ns);
+ state._u._ext.nsaddrs[0] = ns;
+ }
+ // Set nsmap[] to indicate that nsaddrs[0] is an IPv6 address
+ // See: https://sourceware.org/ml/libc-hacker/2002-05/msg00035.html
+ state._u._ext.nsmap[0] = MAXNS + 1;
+ state._u._ext.nscount6 = 1;
+ ns->sin6_family = AF_INET6;
+ ns->sin6_port = htons(53);
+
+ Q_IPV6ADDR ipv6Address = nameserver.toIPv6Address();
+ for (int i=0; i<16; i++) {
+ ns->sin6_addr.s6_addr[i] = ipv6Address[i];
+ }
+#else
+ qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
+ return;
+#endif
+ }
+ }
#ifdef QDNSLOOKUP_DEBUG
state.options |= RES_DEBUG;
#endif
diff --git a/src/network/kernel/qdnslookup_win.cpp b/src/network/kernel/qdnslookup_win.cpp
index bf80a23297..6f58e64440 100644
--- a/src/network/kernel/qdnslookup_win.cpp
+++ b/src/network/kernel/qdnslookup_win.cpp
@@ -48,15 +48,33 @@
#include <qt_windows.h>
#include <windns.h>
+#include <memory.h>
QT_BEGIN_NAMESPACE
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
// Perform DNS query.
PDNS_RECORD dns_records = 0;
const QString requestNameUtf16 = QString::fromUtf8(requestName.data(), requestName.size());
- const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, NULL, &dns_records, NULL);
+ IP4_ARRAY srvList;
+ memset(&srvList, 0, sizeof(IP4_ARRAY));
+ if (!nameserver.isNull()) {
+ if (nameserver.protocol() == QAbstractSocket::IPv4Protocol) {
+ // The below code is referenced from: http://support.microsoft.com/kb/831226
+ srvList.AddrCount = 1;
+ srvList.AddrArray[0] = htonl(nameserver.toIPv4Address());
+ } else if (nameserver.protocol() == QAbstractSocket::IPv6Protocol) {
+ // For supoprting IPv6 nameserver addresses, we'll need to switch
+ // from DnsQuey() to DnsQueryEx() as it supports passing an IPv6
+ // address in the nameserver list
+ qWarning() << Q_FUNC_INFO << "IPv6 addresses for nameservers is currently not supported";
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = tr("IPv6 addresses for nameservers is currently not supported");
+ return;
+ }
+ }
+ const DNS_STATUS status = DnsQuery_W(reinterpret_cast<const wchar_t*>(requestNameUtf16.utf16()), requestType, DNS_QUERY_STANDARD, &srvList, &dns_records, NULL);
switch (status) {
case ERROR_SUCCESS:
break;
diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp
new file mode 100644
index 0000000000..6ac944934a
--- /dev/null
+++ b/src/network/kernel/qdnslookup_winrt.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdnslookup_p.h"
+
+#include <qurl.h>
+#include <qdebug.h>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+
+QT_BEGIN_NAMESPACE
+
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
+{
+ // TODO: Add nameserver support for winRT
+ if (!nameserver.isNull())
+ qWarning() << "Ignoring nameserver as its currently not supported on WinRT";
+
+ // TODO: is there any way to do "proper" dns lookup?
+ if (requestType != QDnsLookup::A && requestType != QDnsLookup::AAAA
+ && requestType != QDnsLookup::ANY) {
+ reply->error = QDnsLookup::InvalidRequestError;
+ reply->errorString = QLatin1String("WinRT only supports IPv4 and IPv6 requests");
+ return;
+ }
+
+ QString aceHostname = QUrl::fromAce(requestName);
+ if (aceHostname.isEmpty()) {
+ reply->error = QDnsLookup::InvalidRequestError;
+ reply->errorString = requestName.isEmpty() ? tr("No hostname given") : tr("Invalid hostname");
+ return;
+ }
+
+ IHostNameFactory *hostnameFactory;
+
+ HStringReference classId(RuntimeClass_Windows_Networking_HostName);
+ if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory))) {
+ reply->error = QDnsLookup::ResolverError;
+ reply->errorString = QLatin1String("Could not obtain hostname factory");
+ return;
+ }
+ IHostName *host;
+ HStringReference hostNameRef((const wchar_t*)aceHostname.utf16());
+ hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ hostnameFactory->Release();
+
+ IDatagramSocketStatics *datagramSocketStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+
+ IAsyncOperation<IVectorView<EndpointPair*> *> *op;
+ HSTRING proto;
+ WindowsCreateString(L"0", 1, &proto);
+ datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op);
+ datagramSocketStatics->Release();
+ host->Release();
+
+ IVectorView<EndpointPair*> *endpointPairs = 0;
+ HRESULT hr = op->GetResults(&endpointPairs);
+ int waitCount = 0;
+ while (hr == E_ILLEGAL_METHOD_CALL) {
+ WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
+ hr = op->GetResults(&endpointPairs);
+ if (++waitCount > 1200) // Wait for 1 minute max
+ return;
+ }
+ op->Release();
+
+ if (!endpointPairs)
+ return;
+
+ unsigned int size;
+ endpointPairs->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ IEndpointPair *endpointpair;
+ endpointPairs->GetAt(i, &endpointpair);
+ IHostName *remoteHost;
+ endpointpair->get_RemoteHostName(&remoteHost);
+ endpointpair->Release();
+ HostNameType type;
+ remoteHost->get_Type(&type);
+ if (type == HostNameType_Bluetooth || type == HostNameType_DomainName
+ || (requestType != QDnsLookup::ANY
+ && ((type == HostNameType_Ipv4 && requestType == QDnsLookup::AAAA)
+ || (type == HostNameType_Ipv6 && requestType == QDnsLookup::A))))
+ continue;
+
+ HSTRING name;
+ remoteHost->get_CanonicalName(&name);
+ remoteHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ QDnsHostAddressRecord record;
+ record.d->name = aceHostname;
+ record.d->value = QHostAddress(QString::fromWCharArray(rawString, length));
+ reply->hostAddressRecords.append(record);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 18fd6dee58..0ab72191dc 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE
// sockaddr_in6 size changed between old and new SDK
// Only the new version is the correct one, so always
// use this structure.
-#if defined(Q_OS_WINCE)
+#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# if !defined(u_char)
# define u_char unsigned char
# endif
@@ -448,10 +448,12 @@ QHostAddress::QHostAddress(const QString &address)
QHostAddress::QHostAddress(const struct sockaddr *sockaddr)
: d(new QHostAddressPrivate)
{
+#ifndef Q_OS_WINRT
if (sockaddr->sa_family == AF_INET)
setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
else if (sockaddr->sa_family == AF_INET6)
setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
+#endif
}
/*!
@@ -604,11 +606,13 @@ bool QHostAddress::setAddress(const QString &address)
*/
void QHostAddress::setAddress(const struct sockaddr *sockaddr)
{
+#ifndef Q_OS_WINRT
clear();
if (sockaddr->sa_family == AF_INET)
setAddress(htonl(((sockaddr_in *)sockaddr)->sin_addr.s_addr));
else if (sockaddr->sa_family == AF_INET6)
setAddress(((qt_sockaddr_in6 *)sockaddr)->sin6_addr.qt_s6_addr);
+#endif
}
/*!
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index d25372ece6..025e3f3e00 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -508,7 +508,7 @@ QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), was
{
moveToThread(QCoreApplicationPrivate::mainThread());
connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection);
- threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel
+ threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel
}
QHostInfoLookupManager::~QHostInfoLookupManager()
diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp
index 32b7318335..df8c8b145a 100644
--- a/src/network/kernel/qhostinfo_unix.cpp
+++ b/src/network/kernel/qhostinfo_unix.cpp
@@ -259,10 +259,10 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
} else if (result == EAI_NONAME
|| result == EAI_FAIL
#ifdef EAI_NODATA
- // EAI_NODATA is deprecated in RFC 3493
- || result == EAI_NODATA
+ // EAI_NODATA is deprecated in RFC 3493
+ || result == EAI_NODATA
#endif
- ) {
+ ) {
results.setError(QHostInfo::HostNotFound);
results.setErrorString(tr("Host not found"));
} else {
diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp
new file mode 100644
index 0000000000..928c9e4628
--- /dev/null
+++ b/src/network/kernel/qhostinfo_winrt.cpp
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhostinfo_p.h"
+
+#include <qurl.h>
+
+#include <ppltasks.h>
+#include <wrl.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+#include <windows.networking.connectivity.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+
+QT_BEGIN_NAMESPACE
+
+//#define QHOSTINFO_DEBUG
+
+QHostInfo QHostInfoAgent::fromName(const QString &hostName)
+{
+ QHostInfo results;
+
+ QHostAddress address;
+ if (address.setAddress(hostName)) {
+ // Reverse lookup
+ // TODO: is there a replacement for getnameinfo for winrt?
+ Q_UNIMPLEMENTED();
+ return results;
+ }
+
+ QByteArray aceHostname = QUrl::toAce(hostName);
+ results.setHostName(hostName);
+ if (aceHostname.isEmpty()) {
+ results.setError(QHostInfo::HostNotFound);
+ results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname"));
+ return results;
+ }
+
+ IHostNameFactory *hostnameFactory;
+
+ HStringReference classId(RuntimeClass_Windows_Networking_HostName);
+ if (FAILED(GetActivationFactory(classId.Get(), &hostnameFactory)))
+ Q_ASSERT(false, "Could not obtain hostname factory.");
+
+ IHostName *host;
+ HStringReference hostNameRef((const wchar_t*)hostName.utf16());
+ hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ hostnameFactory->Release();
+
+ IDatagramSocketStatics *datagramSocketStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+
+ IAsyncOperation<IVectorView<EndpointPair*> *> *op;
+ HSTRING proto;
+ WindowsCreateString(L"0", 1, &proto);
+ datagramSocketStatics->GetEndpointPairsAsync(host, proto, &op);
+ datagramSocketStatics->Release();
+ host->Release();
+
+ IVectorView<EndpointPair*> *endpointPairs = 0;
+ HRESULT hr = op->GetResults(&endpointPairs);
+ int waitCount = 0;
+ while (hr == E_ILLEGAL_METHOD_CALL) {
+ WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE);
+ hr = op->GetResults(&endpointPairs);
+ if (++waitCount > 1200) // Wait for 1 minute max
+ return results;
+ }
+ op->Release();
+
+ if (!endpointPairs)
+ return results;
+
+ unsigned int size;
+ endpointPairs->get_Size(&size);
+ QList<QHostAddress> addresses;
+ for (unsigned int i = 0; i < size; ++i) {
+ IEndpointPair *endpointpair;
+ endpointPairs->GetAt(i, &endpointpair);
+ IHostName *remoteHost;
+ endpointpair->get_RemoteHostName(&remoteHost);
+ endpointpair->Release();
+ if (!remoteHost)
+ continue;
+ HostNameType type;
+ remoteHost->get_Type(&type);
+ if (type == HostNameType_DomainName)
+ continue;
+
+ HSTRING name;
+ remoteHost->get_CanonicalName(&name);
+ remoteHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ QHostAddress addr;
+ addr.setAddress(QString::fromWCharArray(rawString, length));
+ if (!addresses.contains(addr))
+ addresses.append(addr);
+ }
+ results.setAddresses(addresses);
+
+ return results;
+}
+
+QString QHostInfo::localHostName()
+{
+ INetworkInformationStatics *statics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics);
+
+ IVectorView<HostName*> *hostNames = 0;
+ statics->GetHostNames(&hostNames);
+ statics->Release();
+ if (!hostNames)
+ return QString();
+
+ unsigned int size;
+ hostNames->get_Size(&size);
+ if (size == 0)
+ return QString();
+
+ for (unsigned int i = 0; i < size; ++i) {
+ IHostName *hostName;
+ hostNames->GetAt(i, &hostName);
+ HostNameType type;
+ hostName->get_Type(&type);
+ if (type != HostNameType_DomainName)
+ continue;
+
+ HSTRING name;
+ hostName->get_CanonicalName(&name);
+ hostName->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ return QString::fromWCharArray(rawString, length);
+ }
+ IHostName *firstHost;
+ hostNames->GetAt(0, &firstHost);
+ hostNames->Release();
+
+ HSTRING name;
+ firstHost->get_CanonicalName(&name);
+ firstHost->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ return QString::fromWCharArray(rawString, length);
+}
+
+// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp
+
+QT_END_NAMESPACE
diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp
index d3c830a66f..d0e2eca1e0 100644
--- a/src/network/kernel/qnetworkinterface_unix.cpp
+++ b/src/network/kernel/qnetworkinterface_unix.cpp
@@ -228,7 +228,7 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa
memcpy(req.ifr_name, oldName, qMin<int>(oldName.length() + 1, sizeof(req.ifr_name) - 1));
} else
#endif
- {
+ {
// use this name anyways
iface->name = QString::fromLatin1(req.ifr_name);
}
diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp
new file mode 100644
index 0000000000..6a814c85d4
--- /dev/null
+++ b/src/network/kernel/qnetworkinterface_winrt.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnetworkinterface.h"
+#include "qnetworkinterface_p.h"
+
+#ifndef QT_NO_NETWORKINTERFACE
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <windows.networking.h>
+#include <windows.networking.connectivity.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+
+#include <qhostinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+struct HostNameInfo {
+ GUID adapterId;
+ unsigned char prefixLength;
+ QString address;
+};
+
+static QList<QNetworkInterfacePrivate *> interfaceListing()
+{
+ QList<QNetworkInterfacePrivate *> interfaces;
+
+ QList<HostNameInfo> hostList;
+
+ INetworkInformationStatics *hostNameStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &hostNameStatics);
+
+ IVectorView<HostName*> *hostNames = 0;
+ hostNameStatics->GetHostNames(&hostNames);
+ hostNameStatics->Release();
+ if (!hostNames)
+ return interfaces;
+
+ unsigned int hostNameCount;
+ hostNames->get_Size(&hostNameCount);
+ for (unsigned i = 0; i < hostNameCount; ++i) {
+ HostNameInfo hostInfo;
+ IHostName *hostName;
+ hostNames->GetAt(i, &hostName);
+
+ HostNameType type;
+ hostName->get_Type(&type);
+ if (type == HostNameType_DomainName)
+ continue;
+
+ IIPInformation *ipInformation;
+ hostName->get_IPInformation(&ipInformation);
+ INetworkAdapter *currentAdapter;
+ ipInformation->get_NetworkAdapter(&currentAdapter);
+
+ currentAdapter->get_NetworkAdapterId(&hostInfo.adapterId);
+ currentAdapter->Release();
+
+ IReference<unsigned char> *prefixLengthReference;
+ ipInformation->get_PrefixLength(&prefixLengthReference);
+ ipInformation->Release();
+
+ prefixLengthReference->get_Value(&hostInfo.prefixLength);
+ prefixLengthReference->Release();
+
+ // invalid prefixes
+ if ((type == HostNameType_Ipv4 && hostInfo.prefixLength > 32)
+ || (type == HostNameType_Ipv6 && hostInfo.prefixLength > 128))
+ continue;
+
+ HSTRING name;
+ hostName->get_CanonicalName(&name);
+ hostName->Release();
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(name, &length);
+ hostInfo.address = QString::fromWCharArray(rawString, length);
+
+ hostList << hostInfo;
+ }
+ hostNames->Release();
+
+ INetworkInformationStatics *networkInfoStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &networkInfoStatics);
+ IVectorView<ConnectionProfile *> *connectionProfiles = 0;
+ networkInfoStatics->GetConnectionProfiles(&connectionProfiles);
+ networkInfoStatics->Release();
+ if (!connectionProfiles)
+ return interfaces;
+
+ unsigned int size;
+ connectionProfiles->get_Size(&size);
+ for (unsigned int i = 0; i < size; ++i) {
+ QNetworkInterfacePrivate *iface = new QNetworkInterfacePrivate;
+ interfaces << iface;
+
+ IConnectionProfile *profile;
+ connectionProfiles->GetAt(i, &profile);
+
+ NetworkConnectivityLevel connectivityLevel;
+ profile->GetNetworkConnectivityLevel(&connectivityLevel);
+ if (connectivityLevel != NetworkConnectivityLevel_None)
+ iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning;
+
+ INetworkAdapter *adapter;
+ profile->get_NetworkAdapter(&adapter);
+ profile->Release();
+ UINT32 type;
+ adapter->get_IanaInterfaceType(&type);
+ if (type == 23)
+ iface->flags |= QNetworkInterface::IsPointToPoint;
+ GUID id;
+ adapter->get_NetworkAdapterId(&id);
+ adapter->Release();
+ OLECHAR adapterName[39]={0};
+ StringFromGUID2(id, adapterName, 39);
+ iface->name = QString::fromWCharArray(adapterName);
+
+ // According to http://stackoverflow.com/questions/12936193/how-unique-is-the-ethernet-network-adapter-id-in-winrt-it-is-derived-from-the-m
+ // obtaining the MAC address using WinRT API is impossible
+ // iface->hardwareAddress = ?
+
+ for (int i = 0; i < hostList.length(); ++i) {
+ const HostNameInfo hostInfo = hostList.at(i);
+ if (id != hostInfo.adapterId)
+ continue;
+
+ QNetworkAddressEntry entry;
+ entry.setIp(QHostAddress(hostInfo.address));
+ entry.setPrefixLength(hostInfo.prefixLength);
+ iface->addressEntries << entry;
+
+ hostList.takeAt(i);
+ --i;
+ }
+ }
+ connectionProfiles->Release();
+ return interfaces;
+}
+
+QList<QNetworkInterfacePrivate *> QNetworkInterfaceManager::scan()
+{
+ return interfaceListing();
+}
+
+QString QHostInfo::localDomainName()
+{
+ return QString();
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_NETWORKINTERFACE
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index bebdf728a7..0345537d1c 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -372,9 +372,22 @@
IP_MULTICAST_LOOP (multicast loopback) socket option.
\value TypeOfServiceOption This option is not supported on
- Windows. This maps to the IP_TOS socket option.
+ Windows. This maps to the IP_TOS socket option. For possible values,
+ see table below.
- Possible values for the \e{TypeOfServiceOption} are:
+ \value SendBufferSizeSocketOption Sets the socket send buffer size
+ in bytes at the OS level. This maps to the SO_SNDBUF socket option.
+ This option does not affect the QIODevice or QAbstractSocket buffers.
+ This enum value has been introduced in Qt 5.3.
+
+ \value ReceiveBufferSizeSocketOption Sets the socket receive
+ buffer size in bytes at the OS level.
+ This maps to the SO_RCVBUF socket option.
+ This option does not affect the QIODevice or QAbstractSocket buffers
+ (see \l{QAbstractSocket::}{setReadBufferSize()}).
+ This enum value has been introduced in Qt 5.3.
+
+ Possible values for \e{TypeOfServiceOption} are:
\table
\header \li Value \li Description
@@ -735,8 +748,8 @@ bool QAbstractSocketPrivate::canReadNotification()
return true;
}
- if (!hasData && socketEngine)
- socketEngine->setReadNotificationEnabled(true);
+ if (isBuffered && socketEngine)
+ socketEngine->setReadNotificationEnabled(readBufferMaxSize == 0 || readBufferMaxSize > q->bytesAvailable());
// reset the read socket notifier state if we reentered inside the
// readyRead() connected slot.
@@ -1904,6 +1917,14 @@ void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, cons
case TypeOfServiceOption:
d_func()->socketEngine->setOption(QAbstractSocketEngine::TypeOfServiceOption, value.toInt());
break;
+
+ case SendBufferSizeSocketOption:
+ d_func()->socketEngine->setOption(QAbstractSocketEngine::SendBufferSocketOption, value.toInt());
+ break;
+
+ case ReceiveBufferSizeSocketOption:
+ d_func()->socketEngine->setOption(QAbstractSocketEngine::ReceiveBufferSocketOption, value.toInt());
+ break;
}
}
@@ -1938,6 +1959,14 @@ QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option)
case TypeOfServiceOption:
ret = d_func()->socketEngine->option(QAbstractSocketEngine::TypeOfServiceOption);
break;
+
+ case SendBufferSizeSocketOption:
+ ret = d_func()->socketEngine->option(QAbstractSocketEngine::SendBufferSocketOption);
+ break;
+
+ case ReceiveBufferSizeSocketOption:
+ ret = d_func()->socketEngine->option(QAbstractSocketEngine::ReceiveBufferSocketOption);
+ break;
}
if (ret == -1)
return QVariant();
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 46114abf73..8b019cf0fb 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -115,7 +115,9 @@ public:
KeepAliveOption, // SO_KEEPALIVE
MulticastTtlOption, // IP_MULTICAST_TTL
MulticastLoopbackOption, // IP_MULTICAST_LOOPBACK
- TypeOfServiceOption //IP_TOS
+ TypeOfServiceOption, //IP_TOS
+ SendBufferSizeSocketOption, //SO_SNDBUF
+ ReceiveBufferSizeSocketOption //SO_RCVBUF
};
enum BindFlag {
DefaultForPlatform = 0x0,
diff --git a/src/network/socket/qabstractsocketengine.cpp b/src/network/socket/qabstractsocketengine.cpp
index 1275461d7d..d8abe01241 100644
--- a/src/network/socket/qabstractsocketengine.cpp
+++ b/src/network/socket/qabstractsocketengine.cpp
@@ -41,7 +41,11 @@
#include "qabstractsocketengine_p.h"
+#ifndef Q_OS_WINRT
#include "qnativesocketengine_p.h"
+#else
+#include "qnativesocketengine_winrt_p.h"
+#endif
#include "qmutex.h"
#include "qnetworkproxy.h"
diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h
index 1dec96762c..6a30012562 100644
--- a/src/network/socket/qabstractsocketengine_p.h
+++ b/src/network/socket/qabstractsocketengine_p.h
@@ -150,7 +150,7 @@ public:
virtual bool waitForRead(int msecs = 30000, bool *timedOut = 0) = 0;
virtual bool waitForWrite(int msecs = 30000, bool *timedOut = 0) = 0;
virtual bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
- bool checkRead, bool checkWrite,
+ bool checkRead, bool checkWrite,
int msecs = 30000, bool *timedOut = 0) = 0;
QAbstractSocket::SocketError error() const;
diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp
index f7f8aab182..791227002d 100644
--- a/src/network/socket/qlocalserver.cpp
+++ b/src/network/socket/qlocalserver.cpp
@@ -131,7 +131,7 @@ QLocalServer::QLocalServer(QObject *parent)
QLocalServer::~QLocalServer()
{
if (isListening())
- close();
+ close();
}
/*!
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index 97a9b98c30..fc1afa48c9 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -162,8 +162,8 @@ public:
bool waitForRead(int msecs = 30000, bool *timedOut = 0);
bool waitForWrite(int msecs = 30000, bool *timedOut = 0);
bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
- bool checkRead, bool checkWrite,
- int msecs = 30000, bool *timedOut = 0);
+ bool checkRead, bool checkWrite,
+ int msecs = 30000, bool *timedOut = 0);
bool isReadNotificationEnabled() const;
void setReadNotificationEnabled(bool enable);
@@ -271,7 +271,7 @@ public:
qint64 nativeWrite(const char *data, qint64 length);
int nativeSelect(int timeout, bool selectForRead) const;
int nativeSelect(int timeout, bool checkRead, bool checkWrite,
- bool *selectForRead, bool *selectForWrite) const;
+ bool *selectForRead, bool *selectForWrite) const;
#ifdef Q_OS_WIN
void setPortAndAddress(sockaddr_in * sockAddrIPv4, qt_sockaddr_in6 * sockAddrIPv6,
quint16 port, const QHostAddress & address, sockaddr ** sockAddrPtr, QT_SOCKLEN_T *sockAddrSize);
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index e076f2b4bf..b6035b5500 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -144,7 +144,7 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc
int protocol = (socketProtocol == QAbstractSocket::IPv6Protocol || socketProtocol == QAbstractSocket::AnyIPProtocol) ? AF_INET6 : AF_INET;
int type = (socketType == QAbstractSocket::UdpSocket) ? SOCK_DGRAM : SOCK_STREAM;
- int socket = qt_safe_socket(protocol, type, 0);
+ int socket = qt_safe_socket(protocol, type, 0);
if (socket <= 0 && socketProtocol == QAbstractSocket::AnyIPProtocol && errno == EAFNOSUPPORT) {
protocol = AF_INET;
socket = qt_safe_socket(protocol, type, 0);
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index 751ac9b182..b1c9073eb9 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -186,7 +186,7 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt
*address = a;
}
if (port)
- WSANtohs(socketDescriptor, sa6->sin6_port, port);
+ WSANtohs(socketDescriptor, sa6->sin6_port, port);
} else
if (sa->a.sa_family == AF_INET) {
@@ -194,11 +194,11 @@ static inline void qt_socket_getPortAndAddress(SOCKET socketDescriptor, const qt
unsigned long addr;
WSANtohl(socketDescriptor, sa4->sin_addr.s_addr, &addr);
QHostAddress a;
- a.setAddress(addr);
- if (address)
- *address = a;
+ a.setAddress(addr);
+ if (address)
+ *address = a;
if (port)
- WSANtohs(socketDescriptor, sa4->sin_port, port);
+ WSANtohs(socketDescriptor, sa4->sin_port, port);
}
}
@@ -276,7 +276,7 @@ QWindowsSockInit::QWindowsSockInit()
// IPv6 requires Winsock v2.0 or better.
if (WSAStartup(MAKEWORD(2,0), &wsadata) != 0) {
- qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed.");
+ qWarning("QTcpSocketAPI: WinSock v2.0 initialization failed.");
} else {
version = 0x20;
}
@@ -940,14 +940,14 @@ int QNativeSocketEnginePrivate::nativeAccept()
break;
}
} else if (acceptedDescriptor != -1 && QAbstractEventDispatcher::instance()) {
- // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket
- // with the same attributes as the listening socket including the current
- // WSAAsyncSelect(). To be able to change the socket to blocking mode the
- // WSAAsyncSelect() call must be cancled.
- QSocketNotifier n(acceptedDescriptor, QSocketNotifier::Read);
- n.setEnabled(true);
- n.setEnabled(false);
- }
+ // Because of WSAAsyncSelect() WSAAccept returns a non blocking socket
+ // with the same attributes as the listening socket including the current
+ // WSAAsyncSelect(). To be able to change the socket to blocking mode the
+ // WSAAsyncSelect() call must be cancled.
+ QSocketNotifier n(acceptedDescriptor, QSocketNotifier::Read);
+ n.setEnabled(true);
+ n.setEnabled(false);
+ }
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeAccept() == %i", acceptedDescriptor);
#endif
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
new file mode 100644
index 0000000000..2a61325471
--- /dev/null
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -0,0 +1,1182 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qt_windows.h>
+
+#include "qnativesocketengine_winrt_p.h"
+
+#include <qcoreapplication.h>
+#include <qabstracteventdispatcher.h>
+#include <qsocketnotifier.h>
+#include <qdatetime.h>
+#include <qnetworkinterface.h>
+#include <qelapsedtimer.h>
+#include <qthread.h>
+#include <qabstracteventdispatcher.h>
+
+#include <private/qeventdispatcher_winrt_p.h>
+
+#include <wrl.h>
+#include <windows.foundation.collections.h>
+#include <windows.storage.streams.h>
+#include <windows.networking.h>
+#include <windows.networking.sockets.h>
+#include <robuffer.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Storage::Streams;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Connectivity;
+using namespace ABI::Windows::Networking::Sockets;
+
+typedef ITypedEventHandler<StreamSocketListener *, StreamSocketListenerConnectionReceivedEventArgs *> ClientConnectedHandler;
+typedef ITypedEventHandler<DatagramSocket *, DatagramSocketMessageReceivedEventArgs *> DatagramReceivedHandler;
+typedef IAsyncOperationWithProgressCompletedHandler<IBuffer *, UINT32> SocketReadCompletedHandler;
+typedef IAsyncOperationWithProgressCompletedHandler<UINT32, UINT32> SocketWriteCompletedHandler;
+
+QT_BEGIN_NAMESPACE
+
+// Common constructs
+#define Q_CHECK_VALID_SOCKETLAYER(function, returnValue) do { \
+ if (!isValid()) { \
+ qWarning(""#function" was called on an uninitialized socket device"); \
+ return returnValue; \
+ } } while (0)
+#define Q_CHECK_INVALID_SOCKETLAYER(function, returnValue) do { \
+ if (isValid()) { \
+ qWarning(""#function" was called on an already initialized socket device"); \
+ return returnValue; \
+ } } while (0)
+#define Q_CHECK_STATE(function, checkState, returnValue) do { \
+ if (d->socketState != (checkState)) { \
+ qWarning(""#function" was not called in "#checkState); \
+ return (returnValue); \
+ } } while (0)
+#define Q_CHECK_NOT_STATE(function, checkState, returnValue) do { \
+ if (d->socketState == (checkState)) { \
+ qWarning(""#function" was called in "#checkState); \
+ return (returnValue); \
+ } } while (0)
+#define Q_CHECK_STATES(function, state1, state2, returnValue) do { \
+ if (d->socketState != (state1) && d->socketState != (state2)) { \
+ qWarning(""#function" was called" \
+ " not in "#state1" or "#state2); \
+ return (returnValue); \
+ } } while (0)
+#define Q_CHECK_TYPE(function, type, returnValue) do { \
+ if (d->socketType != (type)) { \
+ qWarning(#function" was called by a" \
+ " socket other than "#type""); \
+ return (returnValue); \
+ } } while (0)
+#define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
+
+typedef QHash<qintptr, IStreamSocket *> TcpSocketHash;
+
+struct SocketHandler
+{
+ SocketHandler() : socketCount(0) {}
+ qintptr socketCount;
+ TcpSocketHash pendingTcpSockets;
+};
+
+Q_GLOBAL_STATIC(SocketHandler, gSocketHandler)
+
+QString qt_QStringFromHSTRING(HSTRING string)
+{
+ UINT32 length;
+ PCWSTR rawString = WindowsGetStringRawBuffer(string, &length);
+ return QString::fromWCharArray(rawString, length);
+}
+
+class ByteArrayBuffer : public Microsoft::WRL::RuntimeClass<RuntimeClassFlags<WinRtClassicComMix>,
+ IBuffer, Windows::Storage::Streams::IBufferByteAccess>
+{
+public:
+ ByteArrayBuffer(int size) : m_bytes(size, Qt::Uninitialized), m_length(0)
+ {
+ }
+
+ ByteArrayBuffer(const char *data, int size) : m_bytes(data, size), m_length(size)
+ {
+ }
+
+ HRESULT __stdcall Buffer(byte **value)
+ {
+ *value = reinterpret_cast<byte *>(m_bytes.data());
+ return S_OK;
+ }
+
+ HRESULT __stdcall get_Capacity(UINT32 *value)
+ {
+ *value = m_bytes.size();
+ return S_OK;
+ }
+
+ HRESULT __stdcall get_Length(UINT32 *value)
+ {
+ *value = m_length;
+ return S_OK;
+ }
+
+ HRESULT __stdcall put_Length(UINT32 value)
+ {
+ Q_ASSERT(value <= UINT32(m_bytes.size()));
+ m_length = value;
+ return S_OK;
+ }
+
+ QNativeSocketEngine *engine() const
+ {
+ return m_engine;
+ }
+
+ void setEngine(QNativeSocketEngine *engine)
+ {
+ m_engine = engine;
+ }
+
+ ComPtr<IInputStream> inputStream() const
+ {
+ return m_stream;
+ }
+
+ void setInputStream(ComPtr<IInputStream> stream)
+ {
+ m_stream = stream;
+ }
+
+private:
+ QByteArray m_bytes;
+ UINT32 m_length;
+ QPointer<QNativeSocketEngine> m_engine;
+ ComPtr<IInputStream> m_stream;
+};
+
+QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
+ : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent)
+{
+}
+
+QNativeSocketEngine::~QNativeSocketEngine()
+{
+ close();
+}
+
+bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol)
+{
+ Q_D(QNativeSocketEngine);
+ if (isValid())
+ close();
+
+ // Create the socket
+ if (!d->createNewSocket(type, protocol))
+ return false;
+
+ d->socketType = type;
+ d->socketProtocol = protocol;
+ return true;
+}
+
+bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState)
+{
+ Q_D(QNativeSocketEngine);
+
+ if (isValid())
+ close();
+
+ d->socketDescriptor = socketDescriptor;
+
+ // Currently, only TCP sockets are initialized this way.
+ SocketHandler *handler = gSocketHandler();
+ d->tcp = handler->pendingTcpSockets.value(socketDescriptor, Q_NULLPTR);
+ d->socketType = QAbstractSocket::TcpSocket;
+
+ if (!d->tcp || !d->fetchConnectionParameters())
+ return false;
+
+ d->socketState = socketState;
+ return true;
+}
+
+qintptr QNativeSocketEngine::socketDescriptor() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->socketDescriptor;
+}
+
+bool QNativeSocketEngine::isValid() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->socketDescriptor != -1;
+}
+
+bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 port)
+{
+ const QString addressString = address.toString();
+ return connectToHostByName(addressString, port);
+}
+
+bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
+{
+ Q_D(QNativeSocketEngine);
+ HStringReference hostNameRef(reinterpret_cast<LPCWSTR>(name.utf16()));
+ ComPtr<IHostNameFactory> hostNameFactory;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
+ &hostNameFactory);
+ ComPtr<IHostName> remoteHost;
+ if (FAILED(hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost))) {
+ qWarning("QNativeSocketEnginePrivate::nativeConnect:: Could not create hostname");
+ return false;
+ }
+
+ const QString portString = QString::number(port);
+ HStringReference portReference(reinterpret_cast<LPCWSTR>(portString.utf16()));
+ ComPtr<IAsyncAction> action;
+ HRESULT hr = E_FAIL;
+ if (d->socketType == QAbstractSocket::TcpSocket)
+ hr = d->tcp->ConnectAsync(remoteHost.Get(), portReference.Get(), &action);
+ else if (d->socketType == QAbstractSocket::UdpSocket)
+ hr = d->udp->ConnectAsync(remoteHost.Get(), portReference.Get(), &action);
+ if (FAILED(hr)) {
+ qWarning("QNativeSocketEnginePrivate::nativeConnect:: Could not obtain connect action");
+ return false;
+ }
+
+ action->put_Completed(Callback<IAsyncActionCompletedHandler>(&QNativeSocketEnginePrivate::interruptEventDispatcher).Get());
+ hr = action->GetResults();
+ while ((hr = action->GetResults()) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
+ if (hr == 0x8007274c) { // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
+ d->setError(QAbstractSocket::NetworkError, d->ConnectionTimeOutErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ return false;
+ }
+ if (hr == 0x8007274d) { // No connection could be made because the target machine actively refused it.
+ d->setError(QAbstractSocket::ConnectionRefusedError, d->ConnectionRefusedErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ return false;
+ }
+ if (FAILED(hr)) {
+ d->setError(QAbstractSocket::UnknownSocketError, d->UnknownSocketErrorString);
+ d->socketState = QAbstractSocket::UnconnectedState;
+ return false;
+ }
+
+ if (d->socketType == QAbstractSocket::TcpSocket) {
+ UINT32 capacity;
+ hr = d->inputBuffer->get_Capacity(&capacity);
+ if (FAILED(hr))
+ return false;
+ IInputStream *stream;
+ hr = d->tcp->get_InputStream(&stream);
+ if (FAILED(hr))
+ return false;
+ ByteArrayBuffer *buffer = static_cast<ByteArrayBuffer *>(d->inputBuffer.Get());
+ buffer->setEngine(this);
+ buffer->setInputStream(stream);
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> op;
+ hr = stream->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op);
+ if (FAILED(hr))
+ return false;
+ hr = op->put_Completed(Callback<SocketReadCompletedHandler>(&QNativeSocketEnginePrivate::handleReadyRead).Get());
+ if (FAILED(hr))
+ return false;
+ }
+ d->socketState = QAbstractSocket::ConnectedState;
+ return true;
+}
+
+bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port)
+{
+ Q_D(QNativeSocketEngine);
+ ComPtr<IHostName> hostAddress;
+ if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) {
+ ComPtr<IHostNameFactory> hostNameFactory;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
+ &hostNameFactory);
+ const QString addressString = address.toString();
+ HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16()));
+ hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress);
+ }
+
+ HRESULT hr;
+ QString portQString = port ? QString::number(port) : QString();
+ HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16()));
+
+ ComPtr<IAsyncAction> op;
+ if (d->socketType == QAbstractSocket::TcpSocket) {
+ if (!d->tcpListener
+ && FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(),
+ &d->tcpListener))) {
+ qWarning("Failed to create listener");
+ return false;
+ }
+
+ EventRegistrationToken token;
+ d->tcpListener->add_ConnectionReceived(Callback<ClientConnectedHandler>(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &token);
+ hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op);
+ if (FAILED(hr)) {
+ qWarning("Unable to bind"); // ### Set error message
+ return false;
+ }
+ } else if (d->socketType == QAbstractSocket::UdpSocket) {
+ hr = d->udp->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op);
+ if (FAILED(hr)) {
+ qWarning("unable to bind"); // ### Set error message
+ return false;
+ }
+ }
+
+ if (op) {
+ // Wait for connection to enter bound state - TODO: timeout, check result
+ while ((hr = op->GetResults()) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+
+ d->socketState = QAbstractSocket::BoundState;
+ d->fetchConnectionParameters();
+ return true;
+ }
+
+ return false;
+}
+
+bool QNativeSocketEngine::listen()
+{
+ Q_D(QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::listen(), false);
+ Q_CHECK_STATE(QNativeSocketEngine::listen(), QAbstractSocket::BoundState, false);
+ Q_CHECK_TYPE(QNativeSocketEngine::listen(), QAbstractSocket::TcpSocket, false);
+
+ if (d->tcpListener && d->socketDescriptor != -1) {
+ d->socketState = QAbstractSocket::ListeningState;
+ return true;
+ }
+ return false;
+}
+
+int QNativeSocketEngine::accept()
+{
+ Q_D(QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::accept(), -1);
+ Q_CHECK_STATE(QNativeSocketEngine::accept(), QAbstractSocket::ListeningState, -1);
+ Q_CHECK_TYPE(QNativeSocketEngine::accept(), QAbstractSocket::TcpSocket, -1);
+
+ if (d->socketDescriptor == -1 || d->pendingConnections.isEmpty())
+ return -1;
+
+ // Start processing incoming data
+ if (d->socketType == QAbstractSocket::TcpSocket) {
+ IStreamSocket *socket = d->pendingConnections.takeFirst();
+
+ UINT32 capacity;
+ d->inputBuffer->get_Capacity(&capacity);
+ IInputStream *stream;
+ socket->get_InputStream(&stream);
+ // TODO: delete buffer and stream on socket close
+ ByteArrayBuffer *buffer = static_cast<ByteArrayBuffer *>(d->inputBuffer.Get());
+ buffer->setEngine(this);
+ buffer->setInputStream(stream);
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> op;
+ stream->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op);
+ op->put_Completed(Callback<SocketReadCompletedHandler>(&QNativeSocketEnginePrivate::handleReadyRead).Get());
+ d->currentConnections.append(socket);
+
+ SocketHandler *handler = gSocketHandler();
+ handler->pendingTcpSockets.insert(++handler->socketCount, socket);
+ return handler->socketCount;
+ }
+
+ return -1;
+}
+
+void QNativeSocketEngine::close()
+{
+ Q_D(QNativeSocketEngine);
+ if (d->socketDescriptor != -1) {
+ IClosable *socket = 0;
+ if (d->socketType == QAbstractSocket::TcpSocket)
+ d->tcp->QueryInterface(IID_PPV_ARGS(&socket));
+ else if (d->socketType == QAbstractSocket::UdpSocket)
+ d->udp->QueryInterface(IID_PPV_ARGS(&socket));
+
+ if (socket) {
+ d->closingDown = true;
+ socket->Close();
+ socket->Release();
+ closeNotification();
+ d->socketDescriptor = -1;
+ }
+ d->socketDescriptor = -1;
+ }
+ d->socketState = QAbstractSocket::UnconnectedState;
+ d->hasSetSocketError = false;
+ d->localPort = 0;
+ d->localAddress.clear();
+ d->peerPort = 0;
+ d->peerAddress.clear();
+}
+
+bool QNativeSocketEngine::joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
+{
+ Q_UNUSED(groupAddress);
+ Q_UNUSED(iface);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+bool QNativeSocketEngine::leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
+{
+ Q_UNUSED(groupAddress);
+ Q_UNUSED(iface);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+QNetworkInterface QNativeSocketEngine::multicastInterface() const
+{
+ Q_UNIMPLEMENTED();
+ return QNetworkInterface();
+}
+
+bool QNativeSocketEngine::setMulticastInterface(const QNetworkInterface &iface)
+{
+ Q_UNUSED(iface);
+ Q_UNIMPLEMENTED();
+ return false;
+}
+
+qint64 QNativeSocketEngine::bytesAvailable() const
+{
+ Q_D(const QNativeSocketEngine);
+ if (d->socketType != QAbstractSocket::TcpSocket)
+ return -1;
+
+ if (d->inputBuffer) {
+ UINT32 len;
+ d->inputBuffer->get_Length(&len);
+ return len;
+ }
+
+ return -1;
+}
+
+qint64 QNativeSocketEngine::read(char *data, qint64 maxlen)
+{
+ Q_D(QNativeSocketEngine);
+ if (d->socketType != QAbstractSocket::TcpSocket)
+ return -1;
+
+ ComPtr<IDataReaderStatics> dataReaderStatics;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(), &dataReaderStatics);
+ ComPtr<IDataReader> reader;
+
+ dataReaderStatics->FromBuffer(d->inputBuffer.Get(), &reader);
+
+ UINT32 bufferCapacity;
+ d->inputBuffer->get_Capacity(&bufferCapacity);
+ qint64 lengthToRead = maxlen < bufferCapacity ? maxlen : bufferCapacity;
+
+ UINT32 bufferLength;
+ d->inputBuffer->get_Length(&bufferLength);
+
+ lengthToRead = bufferLength < lengthToRead ? bufferLength : lengthToRead;
+ reader->ReadBytes(lengthToRead, (unsigned char*)data);
+ return lengthToRead;
+}
+
+template <typename T>
+static qint64 nativeWrite(T *socket, const char *data, qint64 len)
+{
+ ComPtr<IOutputStream> stream;
+ HRESULT hr = socket->get_OutputStream(&stream);
+ if (FAILED(hr))
+ return -1;
+ ComPtr<ByteArrayBuffer> buffer = Make<ByteArrayBuffer>(data, len);
+ ComPtr<IAsyncOperationWithProgress<UINT32, UINT32>> op;
+ hr = stream->WriteAsync(buffer.Get(), &op);
+ if (FAILED(hr))
+ return -1;
+ UINT32 bytesWritten;
+ while ((hr = op->GetResults(&bytesWritten)) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ return bytesWritten;
+}
+
+qint64 QNativeSocketEngine::write(const char *data, qint64 len)
+{
+ Q_D(QNativeSocketEngine);
+ qint64 bytesWritten = -1;
+ if (d->socketType == QAbstractSocket::TcpSocket)
+ bytesWritten = ::nativeWrite(d->tcp, data, len);
+ else if (d->socketType == QAbstractSocket::UdpSocket)
+ bytesWritten = ::nativeWrite(d->udp, data, len);
+ if (bytesWritten != -1 && d->notifyOnWrite)
+ writeNotification();
+ return bytesWritten;
+
+}
+
+qint64 QNativeSocketEngine::readDatagram(char *data, qint64 maxlen, QHostAddress *addr, quint16 *port)
+{
+ Q_D(QNativeSocketEngine);
+ if (d->socketType != QAbstractSocket::UdpSocket)
+ return -1;
+
+ QHostAddress returnAddress;
+ quint16 returnPort;
+
+ for (int i = 0; i < d->pendingDatagrams.size(); ++i) {
+ IDatagramSocketMessageReceivedEventArgs *arg = d->pendingDatagrams.at(i);
+ ComPtr<IHostName> remoteHost;
+ HSTRING remoteHostString;
+ HSTRING remotePort;
+ arg->get_RemoteAddress(&remoteHost);
+ arg->get_RemotePort(&remotePort);
+ remoteHost->get_CanonicalName(&remoteHostString);
+ returnAddress.setAddress(qt_QStringFromHSTRING(remoteHostString));
+ returnPort = qt_QStringFromHSTRING(remotePort).toInt();
+ ComPtr<IDataReader> reader;
+ arg->GetDataReader(&reader);
+ if (!reader)
+ continue;
+
+ BYTE buffer[1024];
+ reader->ReadBytes(maxlen, buffer);
+ *addr = returnAddress;
+ *port = returnPort;
+ arg = d->pendingDatagrams.takeFirst();
+
+ // TODO: fill data
+ Q_UNUSED(data);
+ arg->Release();
+ delete arg;
+ --i;
+ return maxlen;
+ }
+
+ return -1;
+}
+
+qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 len, const QHostAddress &addr, quint16 port)
+{
+ Q_D(QNativeSocketEngine);
+ if (d->socketType != QAbstractSocket::UdpSocket)
+ return -1;
+
+ ComPtr<IHostName> remoteHost;
+ ComPtr<IHostNameFactory> hostNameFactory;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
+ &hostNameFactory))) {
+ qWarning("QNativeSocketEnginePrivate::nativeSendDatagram: could not obtain hostname factory");
+ return -1;
+ }
+ const QString addressString = addr.toString();
+ HStringReference hostNameRef(reinterpret_cast<LPCWSTR>(addressString.utf16()));
+ hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost);
+
+ ComPtr<IAsyncOperation<IOutputStream *>> streamOperation;
+ ComPtr<IOutputStream> stream;
+ const QString portString = QString::number(port);
+ HStringReference portRef(reinterpret_cast<LPCWSTR>(portString.utf16()));
+ if (FAILED(d->udp->GetOutputStreamAsync(remoteHost.Get(), portRef.Get(), &streamOperation)))
+ return -1;
+ HRESULT hr;
+ while (hr = streamOperation->GetResults(&stream) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ ComPtr<IDataWriterFactory> dataWriterFactory;
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(), &dataWriterFactory);
+ ComPtr<IDataWriter> writer;
+ dataWriterFactory->CreateDataWriter(stream.Get(), &writer);
+ writer->WriteBytes(len, (unsigned char *)data);
+ return len;
+}
+
+bool QNativeSocketEngine::hasPendingDatagrams() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->pendingDatagrams.length() > 0;
+}
+
+qint64 QNativeSocketEngine::pendingDatagramSize() const
+{
+ Q_D(const QNativeSocketEngine);
+ qint64 ret = 0;
+ foreach (IDatagramSocketMessageReceivedEventArgs *arg, d->pendingDatagrams) {
+ ComPtr<IDataReader> reader;
+ UINT32 unconsumedBufferLength;
+ arg->GetDataReader(&reader);
+ if (!reader)
+ return -1;
+ reader->get_UnconsumedBufferLength(&unconsumedBufferLength);
+ ret += unconsumedBufferLength;
+ }
+ return ret;
+}
+
+qint64 QNativeSocketEngine::bytesToWrite() const
+{
+ return 0;
+}
+
+qint64 QNativeSocketEngine::receiveBufferSize() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->option(QAbstractSocketEngine::ReceiveBufferSocketOption);
+}
+
+void QNativeSocketEngine::setReceiveBufferSize(qint64 bufferSize)
+{
+ Q_D(QNativeSocketEngine);
+ d->setOption(QAbstractSocketEngine::ReceiveBufferSocketOption, bufferSize);
+}
+
+qint64 QNativeSocketEngine::sendBufferSize() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->option(QAbstractSocketEngine::SendBufferSocketOption);
+}
+
+void QNativeSocketEngine::setSendBufferSize(qint64 bufferSize)
+{
+ Q_D(QNativeSocketEngine);
+ d->setOption(QAbstractSocketEngine::SendBufferSocketOption, bufferSize);
+}
+
+int QNativeSocketEngine::option(QAbstractSocketEngine::SocketOption option) const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->option(option);
+}
+
+bool QNativeSocketEngine::setOption(QAbstractSocketEngine::SocketOption option, int value)
+{
+ Q_D(QNativeSocketEngine);
+ return d->setOption(option, value);
+}
+
+bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
+{
+ Q_D(const QNativeSocketEngine);
+ Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::waitForRead(), false);
+ Q_CHECK_NOT_STATE(QNativeSocketEngine::waitForRead(),
+ QAbstractSocket::UnconnectedState, false);
+
+ if (timedOut)
+ *timedOut = false;
+
+ QElapsedTimer timer;
+ timer.start();
+ while (msecs > timer.elapsed()) {
+ // Servers with active connections are ready for reading
+ if (!d->currentConnections.isEmpty())
+ return true;
+
+ // If we are a client, we are ready to read if our buffer has data
+ UINT32 length;
+ if (FAILED(d->inputBuffer->get_Length(&length)))
+ return false;
+ if (length)
+ return true;
+
+ // Nothing to do, wait for more events
+ QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::WaitForMoreEvents);
+ }
+
+ d->setError(QAbstractSocket::SocketTimeoutError,
+ QNativeSocketEnginePrivate::TimeOutErrorString);
+
+ if (timedOut)
+ *timedOut = true;
+ return false;
+}
+
+bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
+{
+ Q_UNUSED(msecs);
+ Q_UNUSED(timedOut);
+ return false;
+}
+
+bool QNativeSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, bool checkRead, bool checkWrite, int msecs, bool *timedOut)
+{
+ Q_UNUSED(readyToRead);
+ Q_UNUSED(readyToWrite);
+ Q_UNUSED(checkRead);
+ Q_UNUSED(checkWrite);
+ Q_UNUSED(msecs);
+ Q_UNUSED(timedOut);
+ return false;
+}
+
+bool QNativeSocketEngine::isReadNotificationEnabled() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->notifyOnRead;
+}
+
+void QNativeSocketEngine::setReadNotificationEnabled(bool enable)
+{
+ Q_D(QNativeSocketEngine);
+ d->notifyOnRead = enable;
+}
+
+bool QNativeSocketEngine::isWriteNotificationEnabled() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->notifyOnWrite;
+}
+
+void QNativeSocketEngine::setWriteNotificationEnabled(bool enable)
+{
+ Q_D(QNativeSocketEngine);
+ d->notifyOnWrite = enable;
+ if (enable && d->socketState == QAbstractSocket::ConnectedState) {
+ if (bytesToWrite())
+ return; // will be emitted as a result of bytes written
+ writeNotification();
+ d->notifyOnWrite = false;
+ }
+}
+
+bool QNativeSocketEngine::isExceptionNotificationEnabled() const
+{
+ Q_D(const QNativeSocketEngine);
+ return d->notifyOnException;
+}
+
+void QNativeSocketEngine::setExceptionNotificationEnabled(bool enable)
+{
+ Q_D(QNativeSocketEngine);
+ d->notifyOnException = enable;
+}
+
+bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
+{
+ Q_UNUSED(socketProtocol);
+ SocketHandler *handler = gSocketHandler();
+ switch (socketType) {
+ case QAbstractSocket::TcpSocket: {
+ if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocket).Get(),
+ reinterpret_cast<IInspectable **>(&tcp)))) {
+ qWarning("Failed to create StreamSocket instance");
+ return false;
+ }
+ socketDescriptor = ++handler->socketCount;
+ return true;
+ }
+ case QAbstractSocket::UdpSocket: {
+ if (FAILED(RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(),
+ reinterpret_cast<IInspectable **>(&udp)))) {
+ qWarning("Failed to create stream socket");
+ return false;
+ }
+ EventRegistrationToken token;
+ udp->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &token);
+ socketDescriptor = ++handler->socketCount;
+ return true;
+ }
+ default:
+ qWarning("Invalid socket type");
+ return false;
+ }
+ return false;
+}
+
+QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
+ : QAbstractSocketEnginePrivate()
+ , notifyOnRead(true)
+ , notifyOnWrite(true)
+ , notifyOnException(false)
+ , closingDown(false)
+ , socketDescriptor(-1)
+{
+ ComPtr<ByteArrayBuffer> buffer = Make<ByteArrayBuffer>(8192);
+ inputBuffer = buffer;
+}
+
+QNativeSocketEnginePrivate::~QNativeSocketEnginePrivate()
+{
+}
+
+void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, ErrorString errorString) const
+{
+ if (hasSetSocketError) {
+ // Only set socket errors once for one engine; expect the
+ // socket to recreate its engine after an error. Note: There's
+ // one exception: SocketError(11) bypasses this as it's purely
+ // a temporary internal error condition.
+ // Another exception is the way the waitFor*() functions set
+ // an error when a timeout occurs. After the call to setError()
+ // they reset the hasSetSocketError to false
+ return;
+ }
+ if (error != QAbstractSocket::SocketError(11))
+ hasSetSocketError = true;
+
+ socketError = error;
+
+ switch (errorString) {
+ case NonBlockingInitFailedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unable to initialize non-blocking socket");
+ break;
+ case BroadcastingInitFailedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unable to initialize broadcast socket");
+ break;
+ // should not happen anymore
+ case NoIpV6ErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Attempt to use IPv6 socket on a platform with no IPv6 support");
+ break;
+ case RemoteHostClosedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("The remote host closed the connection");
+ break;
+ case TimeOutErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Network operation timed out");
+ break;
+ case ResourceErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Out of resources");
+ break;
+ case OperationUnsupportedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unsupported socket operation");
+ break;
+ case ProtocolUnsupportedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Protocol type not supported");
+ break;
+ case InvalidSocketErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Invalid socket descriptor");
+ break;
+ case HostUnreachableErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Host unreachable");
+ break;
+ case NetworkUnreachableErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Network unreachable");
+ break;
+ case AccessErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Permission denied");
+ break;
+ case ConnectionTimeOutErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Connection timed out");
+ break;
+ case ConnectionRefusedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Connection refused");
+ break;
+ case AddressInuseErrorString:
+ socketErrorString = QNativeSocketEngine::tr("The bound address is already in use");
+ break;
+ case AddressNotAvailableErrorString:
+ socketErrorString = QNativeSocketEngine::tr("The address is not available");
+ break;
+ case AddressProtectedErrorString:
+ socketErrorString = QNativeSocketEngine::tr("The address is protected");
+ break;
+ case DatagramTooLargeErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Datagram was too large to send");
+ break;
+ case SendDatagramErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unable to send a message");
+ break;
+ case ReceiveDatagramErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unable to receive a message");
+ break;
+ case WriteErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unable to write");
+ break;
+ case ReadErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Network error");
+ break;
+ case PortInuseErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Another socket is already listening on the same port");
+ break;
+ case NotSocketErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Operation on non-socket");
+ break;
+ case InvalidProxyTypeString:
+ socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation");
+ break;
+ case TemporaryErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Temporary error");
+ break;
+ case UnknownSocketErrorString:
+ socketErrorString = QNativeSocketEngine::tr("Unknown error");
+ break;
+ }
+}
+
+int QNativeSocketEnginePrivate::option(QAbstractSocketEngine::SocketOption opt) const
+{
+ ComPtr<IStreamSocketControl> control;
+ if (socketType == QAbstractSocket::TcpSocket) {
+ if (FAILED(tcp->get_Control(&control))) {
+ qWarning("QNativeSocketEnginePrivate::option: Could not obtain socket control");
+ return -1;
+ }
+ }
+ switch (opt) {
+ case QAbstractSocketEngine::NonBlockingSocketOption:
+ case QAbstractSocketEngine::BroadcastSocketOption:
+ case QAbstractSocketEngine::ReceiveOutOfBandData:
+ return 1;
+ case QAbstractSocketEngine::SendBufferSocketOption:
+ if (socketType == QAbstractSocket::UdpSocket)
+ return -1;
+
+ UINT32 bufferSize;
+ if (FAILED(control->get_OutboundBufferSizeInBytes(&bufferSize))) {
+ qWarning("Could not obtain OutboundBufferSizeInBytes information vom socket control");
+ return -1;
+ }
+ return bufferSize;
+ case QAbstractSocketEngine::LowDelayOption:
+ if (socketType == QAbstractSocket::UdpSocket)
+ return -1;
+
+ boolean noDelay;
+ if (FAILED(control->get_NoDelay(&noDelay))) {
+ qWarning("Could not obtain NoDelay information from socket control");
+ return -1;
+ }
+ return noDelay;
+ case QAbstractSocketEngine::KeepAliveOption:
+ if (socketType == QAbstractSocket::UdpSocket)
+ return -1;
+
+ boolean keepAlive;
+ if (FAILED(control->get_KeepAlive(&keepAlive))) {
+ qWarning("Could not obtain KeepAlive information from socket control");
+ return -1;
+ }
+ return keepAlive;
+ case QAbstractSocketEngine::ReceiveBufferSocketOption:
+ case QAbstractSocketEngine::AddressReusable:
+ case QAbstractSocketEngine::BindExclusively:
+ case QAbstractSocketEngine::MulticastTtlOption:
+ case QAbstractSocketEngine::MulticastLoopbackOption:
+ case QAbstractSocketEngine::TypeOfServiceOption:
+ default:
+ return -1;
+ }
+ return -1;
+}
+
+bool QNativeSocketEnginePrivate::setOption(QAbstractSocketEngine::SocketOption opt, int v)
+{
+ ComPtr<IStreamSocketControl> control;
+ if (socketType == QAbstractSocket::TcpSocket) {
+ if (FAILED(tcp->get_Control(&control))) {
+ qWarning("QNativeSocketEnginePrivate::setOption: Could not obtain socket control");
+ return false;
+ }
+ }
+ switch (opt) {
+ case QAbstractSocketEngine::NonBlockingSocketOption:
+ case QAbstractSocketEngine::BroadcastSocketOption:
+ case QAbstractSocketEngine::ReceiveOutOfBandData:
+ return v != 0;
+ case QAbstractSocketEngine::SendBufferSocketOption:
+ if (socketType == QAbstractSocket::UdpSocket)
+ return false;
+
+ if (FAILED(control->put_OutboundBufferSizeInBytes(v))) {
+ qWarning("Could not set OutboundBufferSizeInBytes");
+ return false;
+ }
+ return true;
+ case QAbstractSocketEngine::LowDelayOption: {
+ if (socketType == QAbstractSocket::UdpSocket)
+ return false;
+
+ boolean noDelay = v;
+ if (FAILED(control->put_NoDelay(noDelay))) {
+ qWarning("Could not obtain NoDelay information from socket control");
+ return false;
+ }
+ return true;
+ }
+ case QAbstractSocketEngine::KeepAliveOption: {
+ if (socketType == QAbstractSocket::UdpSocket)
+ return false;
+
+ boolean keepAlive = v;
+ if (FAILED(control->put_KeepAlive(keepAlive))) {
+ qWarning("Could not set KeepAlive value");
+ return false;
+ }
+ return true;
+ }
+ case QAbstractSocketEngine::ReceiveBufferSocketOption:
+ case QAbstractSocketEngine::AddressReusable:
+ case QAbstractSocketEngine::BindExclusively:
+ case QAbstractSocketEngine::MulticastTtlOption:
+ case QAbstractSocketEngine::MulticastLoopbackOption:
+ case QAbstractSocketEngine::TypeOfServiceOption:
+ default:
+ return false;
+ }
+ return false;
+}
+
+bool QNativeSocketEnginePrivate::fetchConnectionParameters()
+{
+ localPort = 0;
+ localAddress.clear();
+ peerPort = 0;
+ peerAddress.clear();
+
+ if (socketType == QAbstractSocket::TcpSocket) {
+ ComPtr<IHostName> hostName;
+ HSTRING tmpHString;
+ ComPtr<IStreamSocketInformation> info;
+ if (FAILED(tcp->get_Information(&info))) {
+ qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket info");
+ return false;
+ }
+ info->get_LocalAddress(&hostName);
+ if (hostName) {
+ hostName->get_CanonicalName(&tmpHString);
+ localAddress.setAddress(qt_QStringFromHSTRING(tmpHString));
+ info->get_LocalPort(&tmpHString);
+ localPort = qt_QStringFromHSTRING(tmpHString).toInt();
+ }
+ if (!localPort && tcpListener) {
+ ComPtr<IStreamSocketListenerInformation> listenerInfo = 0;
+ tcpListener->get_Information(&listenerInfo);
+ listenerInfo->get_LocalPort(&tmpHString);
+ localPort = qt_QStringFromHSTRING(tmpHString).toInt();
+ localAddress == QHostAddress::Any;
+ }
+ info->get_RemoteAddress(&hostName);
+ if (hostName) {
+ hostName->get_CanonicalName(&tmpHString);
+ peerAddress.setAddress(qt_QStringFromHSTRING(tmpHString));
+ info->get_RemotePort(&tmpHString);
+ peerPort = qt_QStringFromHSTRING(tmpHString).toInt();
+ }
+ } else if (socketType == QAbstractSocket::UdpSocket) {
+ ComPtr<IHostName> hostName;
+ HSTRING tmpHString;
+ ComPtr<IDatagramSocketInformation> info;
+ if (FAILED(udp->get_Information(&info))) {
+ qWarning("QNativeSocketEnginePrivate::fetchConnectionParameters: Could not obtain socket information");
+ return false;
+ }
+ info->get_LocalAddress(&hostName);
+ if (hostName) {
+ hostName->get_CanonicalName(&tmpHString);
+ localAddress.setAddress(qt_QStringFromHSTRING(tmpHString));
+ info->get_LocalPort(&tmpHString);
+ localPort = qt_QStringFromHSTRING(tmpHString).toInt();
+ }
+
+ info->get_RemoteAddress(&hostName);
+ if (hostName) {
+ hostName->get_CanonicalName(&tmpHString);
+ peerAddress.setAddress(qt_QStringFromHSTRING(tmpHString));
+ info->get_RemotePort(&tmpHString);
+ peerPort = qt_QStringFromHSTRING(tmpHString).toInt();
+ }
+ }
+ return true;
+}
+
+HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener *listener, IStreamSocketListenerConnectionReceivedEventArgs *args)
+{
+ Q_Q(QNativeSocketEngine);
+ Q_ASSERT(tcpListener.Get() == listener);
+ IStreamSocket *socket;
+ args->get_Socket(&socket);
+ pendingConnections.append(socket);
+ q->connectionNotification();
+ q->readNotification();
+ return interruptEventDispatcher(0, Completed);
+}
+
+HRESULT QNativeSocketEnginePrivate::interruptEventDispatcher(IAsyncAction *, AsyncStatus)
+{
+ if (QThread *thread = QThread::currentThread()) {
+ if (QAbstractEventDispatcher *dispatcher = thread->eventDispatcher())
+ dispatcher->interrupt();
+ }
+ return S_OK;
+}
+
+HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncOperationWithProgress<IBuffer *, UINT32> *asyncInfo, AsyncStatus)
+{
+ ByteArrayBuffer *buffer = 0;
+ HRESULT hr = asyncInfo->GetResults((IBuffer **)&buffer);
+ if (FAILED(hr))
+ return hr;
+ UINT32 len;
+ buffer->get_Length(&len);
+ QNativeSocketEngine *q = buffer->engine();
+ if (!q)
+ return S_OK;
+ if (len > 0 && q->isReadNotificationEnabled()) {
+ q->readNotification();
+ }
+
+ // Continue reading ### TODO: read into offset!!!
+ UINT32 capacity;
+ buffer->get_Capacity(&capacity);
+ ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> op;
+ if (SUCCEEDED(buffer->inputStream()->ReadAsync(buffer, capacity, InputStreamOptions_Partial, &op))) {
+ if (q)
+ return op->put_Completed(Callback<SocketReadCompletedHandler>(&QNativeSocketEnginePrivate::handleReadyRead).Get());
+ else
+ return op->put_Completed(nullptr);
+ }
+
+ return E_FAIL;
+}
+
+HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args)
+{
+ Q_Q(QNativeSocketEngine);
+ Q_ASSERT(udp == socket);
+ pendingDatagrams.append(args);
+ q->readNotification();
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h
new file mode 100644
index 0000000000..b5be5fa830
--- /dev/null
+++ b/src/network/socket/qnativesocketengine_winrt_p.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QNATIVESOCKETENGINE_WINRT_P_H
+#define QNATIVESOCKETENGINE_WINRT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+#include "QtNetwork/qhostaddress.h"
+#include "private/qabstractsocketengine_p.h"
+#include <wrl.h>
+#include <windows.networking.sockets.h>
+
+QT_BEGIN_NAMESPACE
+
+class QNativeSocketEnginePrivate;
+
+class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine
+{
+ Q_OBJECT
+public:
+ QNativeSocketEngine(QObject *parent = 0);
+ ~QNativeSocketEngine();
+
+ bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol);
+ bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState);
+
+ qintptr socketDescriptor() const;
+
+ bool isValid() const;
+
+ bool connectToHost(const QHostAddress &address, quint16 port);
+ bool connectToHostByName(const QString &name, quint16 port);
+ bool bind(const QHostAddress &address, quint16 port);
+ bool listen();
+ int accept();
+ void close();
+
+#ifndef QT_NO_NETWORKINTERFACE
+ bool joinMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ bool leaveMulticastGroup(const QHostAddress &groupAddress,
+ const QNetworkInterface &iface);
+ QNetworkInterface multicastInterface() const;
+ bool setMulticastInterface(const QNetworkInterface &iface);
+#endif
+
+ qint64 bytesAvailable() const;
+
+ qint64 read(char *data, qint64 maxlen);
+ qint64 write(const char *data, qint64 len);
+
+ qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
+ quint16 *port = 0);
+ qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
+ quint16 port);
+ bool hasPendingDatagrams() const;
+ qint64 pendingDatagramSize() const;
+
+ qint64 bytesToWrite() const;
+
+ qint64 receiveBufferSize() const;
+ void setReceiveBufferSize(qint64 bufferSize);
+
+ qint64 sendBufferSize() const;
+ void setSendBufferSize(qint64 bufferSize);
+
+ int option(SocketOption option) const;
+ bool setOption(SocketOption option, int value);
+
+ bool waitForRead(int msecs = 30000, bool *timedOut = 0);
+ bool waitForWrite(int msecs = 30000, bool *timedOut = 0);
+ bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite,
+ bool checkRead, bool checkWrite,
+ int msecs = 30000, bool *timedOut = 0);
+
+ bool isReadNotificationEnabled() const;
+ void setReadNotificationEnabled(bool enable);
+ bool isWriteNotificationEnabled() const;
+ void setWriteNotificationEnabled(bool enable);
+ bool isExceptionNotificationEnabled() const;
+ void setExceptionNotificationEnabled(bool enable);
+
+private:
+ Q_DECLARE_PRIVATE(QNativeSocketEngine)
+ Q_DISABLE_COPY(QNativeSocketEngine)
+};
+
+class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QNativeSocketEngine)
+public:
+ QNativeSocketEnginePrivate();
+ ~QNativeSocketEnginePrivate();
+
+ qintptr socketDescriptor;
+
+ bool notifyOnRead, notifyOnWrite, notifyOnException;
+ bool closingDown;
+
+ enum ErrorString {
+ NonBlockingInitFailedErrorString,
+ BroadcastingInitFailedErrorString,
+ NoIpV6ErrorString,
+ RemoteHostClosedErrorString,
+ TimeOutErrorString,
+ ResourceErrorString,
+ OperationUnsupportedErrorString,
+ ProtocolUnsupportedErrorString,
+ InvalidSocketErrorString,
+ HostUnreachableErrorString,
+ NetworkUnreachableErrorString,
+ AccessErrorString,
+ ConnectionTimeOutErrorString,
+ ConnectionRefusedErrorString,
+ AddressInuseErrorString,
+ AddressNotAvailableErrorString,
+ AddressProtectedErrorString,
+ DatagramTooLargeErrorString,
+ SendDatagramErrorString,
+ ReceiveDatagramErrorString,
+ WriteErrorString,
+ ReadErrorString,
+ PortInuseErrorString,
+ NotSocketErrorString,
+ InvalidProxyTypeString,
+ TemporaryErrorString,
+
+ UnknownSocketErrorString = -1
+ };
+
+ void setError(QAbstractSocket::SocketError error, ErrorString errorString) const;
+
+ // native functions
+ int option(QNativeSocketEngine::SocketOption option) const;
+ bool setOption(QNativeSocketEngine::SocketOption option, int value);
+
+ bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol);
+
+ bool checkProxy(const QHostAddress &address);
+ bool fetchConnectionParameters();
+private:
+ union {
+ ABI::Windows::Networking::Sockets::IStreamSocket *tcp;
+ ABI::Windows::Networking::Sockets::IDatagramSocket *udp;
+ };
+ Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
+ Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> inputBuffer;
+ QList<ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *> pendingDatagrams;
+ QList<ABI::Windows::Networking::Sockets::IStreamSocket *> pendingConnections;
+ QList<ABI::Windows::Networking::Sockets::IStreamSocket *> currentConnections;
+
+ HRESULT handleNewDatagram(ABI::Windows::Networking::Sockets::IDatagramSocket *socket,
+ ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args);
+ HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener,
+ ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args);
+ static HRESULT interruptEventDispatcher(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus);
+ static HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus);
+};
+
+QT_END_NAMESPACE
+
+#endif // QNATIVESOCKETENGINE_WINRT_P_H
diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp
index 6818ff6354..b62c4a6bef 100644
--- a/src/network/socket/qsocks5socketengine.cpp
+++ b/src/network/socket/qsocks5socketengine.cpp
@@ -735,9 +735,10 @@ void QSocks5SocketEnginePrivate::reauthenticate()
proxyInfo.setPassword(auth.password());
data->authenticator = new QSocks5PasswordAuthenticator(proxyInfo.user(), proxyInfo.password());
- data->controlSocket->blockSignals(true);
- data->controlSocket->abort();
- data->controlSocket->blockSignals(false);
+ {
+ const QSignalBlocker blocker(data->controlSocket);
+ data->controlSocket->abort();
+ }
data->controlSocket->connectToHost(proxyInfo.hostName(), proxyInfo.port());
} else {
// authentication failure
diff --git a/src/network/socket/socket.pri b/src/network/socket/socket.pri
index c0c6d750d9..7e3a54e303 100644
--- a/src/network/socket/socket.pri
+++ b/src/network/socket/socket.pri
@@ -24,8 +24,10 @@ SOURCES += socket/qabstractsocketengine.cpp \
socket/qlocalsocket.cpp \
socket/qlocalserver.cpp
-SOURCES += socket/qnativesocketengine.cpp
-HEADERS += socket/qnativesocketengine_p.h
+!winrt {
+ SOURCES += socket/qnativesocketengine.cpp
+ HEADERS += socket/qnativesocketengine_p.h
+}
unix: {
SOURCES += socket/qnativesocketengine_unix.cpp \
@@ -36,11 +38,20 @@ unix: {
unix:HEADERS += \
socket/qnet_unix_p.h
-win32:SOURCES += socket/qnativesocketengine_win.cpp \
+win32:!winrt:SOURCES += socket/qnativesocketengine_win.cpp \
socket/qlocalsocket_win.cpp \
socket/qlocalserver_win.cpp
-win32:!wince*: LIBS_PRIVATE += -ladvapi32
+win32:!wince*:!winrt:LIBS_PRIVATE += -ladvapi32
+
+winrt {
+ SOURCES += socket/qnativesocketengine_winrt.cpp \
+ socket/qlocalsocket_tcp.cpp \
+ socket/qlocalserver_tcp.cpp
+ HEADERS += socket/qnativesocketengine_winrt_p.h
+
+ DEFINES += QT_LOCALSOCKET_TCP
+}
wince*: {
SOURCES -= socket/qlocalsocket_win.cpp \
diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp
index cdb0ed9063..bb5d93e528 100644
--- a/src/network/ssl/qsslcipher.cpp
+++ b/src/network/ssl/qsslcipher.cpp
@@ -79,6 +79,26 @@ QSslCipher::QSslCipher()
/*!
Constructs a QSslCipher object for the cipher determined by \a
+ name. The constructor accepts only supported ciphers (i.e., the
+ \a name must identify a cipher in the list of ciphers returned by
+ QSslSocket::supportedCiphers()).
+
+ You can call isNull() after construction to check if \a name
+ correctly identified a supported cipher.
+*/
+QSslCipher::QSslCipher(const QString &name)
+ : d(new QSslCipherPrivate)
+{
+ foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
+ if (cipher.name() == name) {
+ *this = cipher;
+ return;
+ }
+ }
+}
+
+/*!
+ Constructs a QSslCipher object for the cipher determined by \a
name and \a protocol. The constructor accepts only supported
ciphers (i.e., the \a name and \a protocol must identify a cipher
in the list of ciphers returned by
diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h
index e351d7949b..4cebffa7ae 100644
--- a/src/network/ssl/qsslcipher.h
+++ b/src/network/ssl/qsslcipher.h
@@ -57,6 +57,7 @@ class Q_NETWORK_EXPORT QSslCipher
{
public:
QSslCipher();
+ QSslCipher(const QString &name);
QSslCipher(const QString &name, QSsl::SslProtocol protocol);
QSslCipher(const QSslCipher &other);
~QSslCipher();
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 4aad7c04c5..1e859ae6e6 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -52,6 +53,9 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
|QSsl::SslOptionDisableCompression
|QSsl::SslOptionDisableSessionPersistence;
+const char QSslConfiguration::NextProtocolSpdy3_0[] = "spdy/3";
+const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
+
/*!
\class QSslConfiguration
\brief The QSslConfiguration class holds the configuration and state of an SSL connection
@@ -113,6 +117,33 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
*/
/*!
+ \enum QSslConfiguration::NextProtocolNegotiationStatus
+
+ Describes the status of the Next Protocol Negotiation (NPN).
+
+ \value NextProtocolNegotiationNone No application protocol
+ has been negotiated (yet).
+
+ \value NextProtocolNegotiationNegotiated A next protocol
+ has been negotiated (see nextNegotiatedProtocol()).
+
+ \value NextProtocolNegotiationUnsupported The client and
+ server could not agree on a common next application protocol.
+*/
+
+/*!
+ \variable QSslConfiguration::NextProtocolSpdy3_0
+ \brief The value used for negotiating SPDY 3.0 during the Next
+ Protocol Negotiation.
+*/
+
+/*!
+ \variable QSslConfiguration::NextProtocolHttp1_1
+ \brief The value used for negotiating HTTP 1.1 during the Next
+ Protocol Negotiation.
+*/
+
+/*!
Constructs an empty SSL configuration. This configuration contains
no valid settings and the state will be empty. isNull() will
return true after this constructor is called.
@@ -185,7 +216,10 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
d->sslOptions == other.d->sslOptions &&
d->sslSession == other.d->sslSession &&
- d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint;
+ d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint &&
+ d->nextAllowedProtocols == other.d->nextAllowedProtocols &&
+ d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol &&
+ d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus;
}
/*!
@@ -221,7 +255,10 @@ bool QSslConfiguration::isNull() const
d->peerCertificateChain.count() == 0 &&
d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
d->sslSession.isNull() &&
- d->sslSessionTicketLifeTimeHint == -1);
+ d->sslSessionTicketLifeTimeHint == -1 &&
+ d->nextAllowedProtocols.isEmpty() &&
+ d->nextNegotiatedProtocol.isNull() &&
+ d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone);
}
/*!
@@ -653,6 +690,71 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const
}
/*!
+ \since 5.3
+
+ This function returns the protocol negotiated with the server
+ if the Next Protocol Negotiation (NPN) TLS extension was enabled.
+ In order for the NPN extension to be enabled, setAllowedNextProtocols()
+ needs to be called explicitly before connecting to the server.
+
+ If no protocol could be negotiated or the extension was not enabled,
+ this function returns a QByteArray which is null.
+
+ \sa setAllowedNextProtocols(), nextProtocolNegotiationStatus()
+ */
+QByteArray QSslConfiguration::nextNegotiatedProtocol() const
+{
+ return d->nextNegotiatedProtocol;
+}
+
+/*!
+ \since 5.3
+
+ This function sets the allowed \a protocols to be negotiated with the
+ server through the Next Protocol Negotiation (NPN) TLS extension; each
+ element in \a protocols must define one allowed protocol.
+ The function must be called explicitly before connecting to send the NPN
+ extension in the SSL handshake.
+ Whether or not the negotiation succeeded can be queried through
+ nextProtocolNegotiationStatus().
+
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ */
+void QSslConfiguration::setAllowedNextProtocols(QList<QByteArray> protocols)
+{
+ d->nextAllowedProtocols = protocols;
+}
+
+/*!
+ \since 5.3
+
+ This function returns the allowed protocols to be negotiated with the
+ server through the Next Protocol Negotiation (NPN) TLS extension, as set
+ by setAllowedNextProtocols().
+
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ */
+QList<QByteArray> QSslConfiguration::allowedNextProtocols() const
+{
+ return d->nextAllowedProtocols;
+}
+
+/*!
+ \since 5.3
+
+ This function returns the status of the Next Protocol Negotiation (NPN).
+ If the feature has not been enabled through setAllowedNextProtocols(),
+ this function returns NextProtocolNegotiationNone.
+ The status will be set before emitting the encrypted() signal.
+
+ \sa setAllowedNextProtocols(), allowedNextProtocols(), nextNegotiatedProtocol(), QSslConfiguration::NextProtocolNegotiationStatus
+ */
+QSslConfiguration::NextProtocolNegotiationStatus QSslConfiguration::nextProtocolNegotiationStatus() const
+{
+ return d->nextProtocolNegotiationStatus;
+}
+
+/*!
Returns the default SSL configuration to be used in new SSL
connections.
@@ -663,7 +765,7 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const
\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
+ supported SSL ciphers that are 128 bits or more
\endlist
\sa QSslSocket::supportedCiphers(), setDefaultConfiguration()
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index a48eceb63e..587187ca06 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -131,6 +132,21 @@ public:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
+ enum NextProtocolNegotiationStatus {
+ NextProtocolNegotiationNone,
+ NextProtocolNegotiationNegotiated,
+ NextProtocolNegotiationUnsupported
+ };
+
+ void setAllowedNextProtocols(QList<QByteArray> protocols);
+ QList<QByteArray> allowedNextProtocols() const;
+
+ QByteArray nextNegotiatedProtocol() const;
+ NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const;
+
+ static const char NextProtocolSpdy3_0[];
+ static const char NextProtocolHttp1_1[];
+
private:
friend class QSslSocket;
friend class QSslConfigurationPrivate;
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 71ee8d2bfe..d183c3335c 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -86,7 +87,8 @@ public:
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
sslOptions(QSslConfigurationPrivate::defaultSslOptions),
- sslSessionTicketLifeTimeHint(-1)
+ sslSessionTicketLifeTimeHint(-1),
+ nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone)
{ }
QSslCertificate peerCertificate;
@@ -114,6 +116,10 @@ public:
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;
+ QList<QByteArray> nextAllowedProtocols;
+ QByteArray nextNegotiatedProtocol;
+ QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index adf42fb79a..551804ec79 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -263,6 +264,45 @@ init_context:
return sslContext;
}
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+
+static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg)
+{
+ QSslContext::NPNContext *ctx = reinterpret_cast<QSslContext::NPNContext *>(arg);
+
+ // comment out to debug:
+// QList<QByteArray> supportedVersions;
+// for (unsigned int i = 0; i < inlen; ) {
+// QByteArray version(reinterpret_cast<const char *>(&in[i+1]), in[i]);
+// supportedVersions << version;
+// i += in[i] + 1;
+// }
+
+ int proto = q_SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+ switch (proto) {
+ case OPENSSL_NPN_UNSUPPORTED:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationNone;
+ break;
+ case OPENSSL_NPN_NEGOTIATED:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ break;
+ case OPENSSL_NPN_NO_OVERLAP:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationUnsupported;
+ break;
+ default:
+ qWarning("OpenSSL sent unknown NPN status");
+ }
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+QSslContext::NPNContext QSslContext::npnContext() const
+{
+ return m_npnContext;
+}
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
// Needs to be deleted by caller
SSL* QSslContext::createSsl()
{
@@ -283,6 +323,26 @@ SSL* QSslContext::createSsl()
session = 0;
}
}
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ QList<QByteArray> protocols = sslConfiguration.d->nextAllowedProtocols;
+ if (!protocols.isEmpty()) {
+ m_supportedNPNVersions.clear();
+ for (int a = 0; a < protocols.count(); ++a) {
+ if (protocols.at(a).size() > 255) {
+ qWarning() << "TLS NPN extension" << protocols.at(a)
+ << "is too long and will be truncated to 255 characters.";
+ protocols[a] = protocols.at(a).left(255);
+ }
+ m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a));
+ }
+ m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
+ m_npnContext.len = m_supportedNPNVersions.count();
+ m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
+ q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ }
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
return ssl;
}
diff --git a/src/network/ssl/qsslcontext_p.h b/src/network/ssl/qsslcontext_p.h
index 2b596798a6..20b27c1ce7 100644
--- a/src/network/ssl/qsslcontext_p.h
+++ b/src/network/ssl/qsslcontext_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -72,6 +73,21 @@ public:
QByteArray sessionASN1() const;
void setSessionASN1(const QByteArray &sessionASN1);
int sessionTicketLifeTimeHint() const;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ // must be public because we want to use it from an OpenSSL callback
+ struct NPNContext {
+ NPNContext() : data(0),
+ len(0),
+ status(QSslConfiguration::NextProtocolNegotiationNone)
+ { }
+ unsigned char *data;
+ unsigned short len;
+ QSslConfiguration::NextProtocolNegotiationStatus status;
+ };
+ NPNContext npnContext() const;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
protected:
QSslContext();
@@ -84,6 +100,10 @@ private:
QSslError::SslError errorCode;
QString errorStr;
QSslConfiguration sslConfiguration;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ QByteArray m_supportedNPNVersions;
+ NPNContext m_npnContext;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
};
#endif // QT_NO_SSL
diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp
index cf62f44855..95eed6e4b3 100644
--- a/src/network/ssl/qsslkey.cpp
+++ b/src/network/ssl/qsslkey.cpp
@@ -256,7 +256,7 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
a valid key.
*/
QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat encoding,
- QSsl::KeyType type, const QByteArray &passPhrase)
+ QSsl::KeyType type, const QByteArray &passPhrase)
: d(new QSslKeyPrivate)
{
QByteArray encoded;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 38b493a769..6edf4efae0 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -905,6 +906,9 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.sslOptions = configuration.d->sslOptions;
d->configuration.sslSession = configuration.sessionTicket();
d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
+ d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
+ d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
+ d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
// if the CA certificates were set explicitly (either via
// QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
@@ -1195,12 +1199,9 @@ void QSslSocket::setCiphers(const QString &ciphers)
Q_D(QSslSocket);
d->configuration.ciphers.clear();
foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) {
- for (int i = 0; i < 3; ++i) {
- // ### Crude
- QSslCipher cipher(cipherName, QSsl::SslProtocol(i));
- if (!cipher.isNull())
- d->configuration.ciphers << cipher;
- }
+ QSslCipher cipher(cipherName);
+ if (!cipher.isNull())
+ d->configuration.ciphers << cipher;
}
}
@@ -1953,6 +1954,7 @@ void QSslSocketPrivate::init()
*/
QList<QSslCipher> QSslSocketPrivate::defaultCiphers()
{
+ QSslSocketPrivate::ensureInitialized();
QMutexLocker locker(&globalData()->mutex);
return globalData()->config->ciphers;
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 69b9e53884..3421154114 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -596,6 +596,7 @@ void QSslSocketPrivate::resetDefaultCiphers()
SSL *mySsl = q_SSL_new(myCtx);
QList<QSslCipher> ciphers;
+ QList<QSslCipher> defaultCiphers;
STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(mySsl);
for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
@@ -603,8 +604,11 @@ void QSslSocketPrivate::resetDefaultCiphers()
if (cipher->valid) {
QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
if (!ciph.isNull()) {
+ // Unconditionally exclude ADH ciphers since they offer no MITM protection
if (!ciph.name().toLower().startsWith(QLatin1String("adh")))
ciphers << ciph;
+ if (ciph.usedBits() >= 128)
+ defaultCiphers << ciph;
}
}
}
@@ -614,7 +618,7 @@ void QSslSocketPrivate::resetDefaultCiphers()
q_SSL_free(mySsl);
setDefaultSupportedCiphers(ciphers);
- setDefaultCiphers(ciphers);
+ setDefaultCiphers(defaultCiphers);
}
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
@@ -1482,6 +1486,15 @@ void QSslSocketBackendPrivate::continueHandshake()
}
}
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ const unsigned char *proto;
+ unsigned int proto_len;
+ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
+ QByteArray nextProtocol(reinterpret_cast<const char *>(proto), proto_len);
+ configuration.nextNegotiatedProtocol = nextProtocol;
+ configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
connectionEncrypted = true;
emit q->encrypted();
if (autoStartHandshake && pendingClose) {
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index ddf53f18f4..79bce22b0d 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -346,6 +347,20 @@ DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+DEFINEFUNC6(int, SSL_select_next_proto, unsigned char **out, out, unsigned char *outlen, outlen,
+ const unsigned char *in, in, unsigned int inlen, inlen,
+ const unsigned char *client, client, unsigned int client_len, client_len,
+ return -1, return)
+DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s,
+ int (*cb) (SSL *ssl, unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen, void *arg), cb,
+ void *arg, arg, return, DUMMYARG)
+DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s,
+ const unsigned char **data, data, unsigned *len, len, return, DUMMYARG)
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
@@ -815,6 +830,11 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSLeay_version)
RESOLVEFUNC(i2d_SSL_SESSION)
RESOLVEFUNC(d2i_SSL_SESSION)
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ RESOLVEFUNC(SSL_select_next_proto)
+ RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb)
+ RESOLVEFUNC(SSL_get0_next_proto_negotiated)
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 7e1a1c983c..500fe9493b 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -79,13 +80,13 @@ QT_BEGIN_NAMESPACE
// **************** Shared declarations ******************
// ret func(arg)
-# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
- typedef ret (*_q_PTR_##func)(arg); \
- static _q_PTR_##func _q_##func = 0; \
- ret q_##func(arg) { \
+# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
+ typedef ret (*_q_PTR_##func)(arg); \
+ static _q_PTR_##func _q_##func = 0; \
+ ret q_##func(arg) { \
if (Q_UNLIKELY(!_q_##func)) { \
qsslSocketUnresolvedSymbolWarning(#func); \
- err; \
+ err; \
} \
funcret _q_##func(a); \
}
@@ -180,8 +181,8 @@ QT_BEGIN_NAMESPACE
// **************** Static declarations ******************
// ret func(arg)
-# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
- ret q_##func(arg) { funcret func(a); }
+# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
+ ret q_##func(arg) { funcret func(a); }
// ret func(arg1, arg2)
# define DEFINEFUNC2(ret, func, arg1, a, arg2, b, err, funcret) \
@@ -384,7 +385,7 @@ int q_X509_cmp(X509 *a, X509 *b);
#ifdef SSLEAY_MACROS
void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
#define q_X509_dup(x509) (X509 *)q_ASN1_dup((i2d_of_void *)q_i2d_X509, \
- (d2i_of_void *)q_d2i_X509,(char *)x509)
+ (d2i_of_void *)q_d2i_X509,(char *)x509)
#else
X509 *q_X509_dup(X509 *a);
#endif
@@ -429,22 +430,22 @@ STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
#define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#ifdef SSLEAY_MACROS
-int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
-int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
+int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
-#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
+#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
(RSA *)q_PEM_ASN1_read_bio( \
(void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u)
-#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
+#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
(DSA *)q_PEM_ASN1_read_bio( \
(void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u)
-#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
- bp,(char *)x,enc,kstr,klen,cb,u)
-#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
- bp,(char *)x,enc,kstr,klen,cb,u)
+#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+ PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
+ bp,(char *)x,enc,kstr,klen,cb,u)
+#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+ PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
+ bp,(char *)x,enc,kstr,klen,cb,u)
#endif
#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
#define q_SSL_CTX_set_mode(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
@@ -461,9 +462,9 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_X509_get_notAfter(x) X509_get_notAfter(x)
#define q_X509_get_notBefore(x) X509_get_notBefore(x)
#define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
- (char *)(rsa))
+ (char *)(rsa))
#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
- (char *)(dsa))
+ (char *)(dsa))
#define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf()
void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
@@ -473,6 +474,20 @@ const char *q_SSLeay_version(int type);
int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+int q_SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ const unsigned char *client, unsigned int client_len);
+void q_SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+ int (*cb) (SSL *ssl, unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen, void *arg),
+ void *arg);
+void q_SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+ unsigned *len);
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
// Helper function
class QDateTime;
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index a89d37bc5d..394eb99307 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -163,7 +163,10 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader;
code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader;
- code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader;
+ if (!QOpenGLFunctions::isES())
+ code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop;
+ else
+ code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES;
code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader;
code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader;
code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader;
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 05d923ca17..90bd7edf54 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -305,25 +305,23 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
static const char* const qglslAffinePositionWithTextureBrushVertexShader
= qglslPositionWithTextureBrushVertexShader;
-#if defined(QT_OPENGL_ES_2)
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
-static const char* const qglslTextureBrushSrcFragmentShader = "\n\
+static const char* const qglslTextureBrushSrcFragmentShader_ES = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
-#else
-static const char* const qglslTextureBrushSrcFragmentShader = "\n\
+
+static const char* const qglslTextureBrushSrcFragmentShader_desktop = "\n\
varying highp vec2 brushTextureCoords; \n\
uniform sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
-#endif
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
varying highp vec2 brushTextureCoords; \n\
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index e0df4ccdf6..6160554472 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -184,7 +184,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui
uint current_color = ARGB_COMBINE_ALPHA(colors[0], alpha);
qreal incr = 1.0 / qreal(size);
qreal fpos = 1.5 * incr;
- colorTable[pos++] = qtToGlColor(PREMUL(current_color));
+ colorTable[pos++] = qtToGlColor(qPremultiply(current_color));
while (fpos <= s.first().first) {
colorTable[pos] = colorTable[pos - 1];
@@ -193,13 +193,13 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui
}
if (colorInterpolation)
- current_color = PREMUL(current_color);
+ current_color = qPremultiply(current_color);
for (int i = 0; i < s.size() - 1; ++i) {
qreal delta = 1/(s[i+1].first - s[i].first);
uint next_color = ARGB_COMBINE_ALPHA(colors[i+1], alpha);
if (colorInterpolation)
- next_color = PREMUL(next_color);
+ next_color = qPremultiply(next_color);
while (fpos < s[i+1].first && pos < size) {
int dist = int(256 * ((fpos - s[i].first) * delta));
@@ -207,7 +207,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui
if (colorInterpolation)
colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
else
- colorTable[pos] = qtToGlColor(PREMUL(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
+ colorTable[pos] = qtToGlColor(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
++pos;
fpos += incr;
}
@@ -216,7 +216,7 @@ void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, ui
Q_ASSERT(s.size() > 0);
- uint last_color = qtToGlColor(PREMUL(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
+ uint last_color = qtToGlColor(qPremultiply(ARGB_COMBINE_ALPHA(colors[s.size() - 1], alpha)));
for (;pos < size; ++pos)
colorTable[pos] = last_color;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 3b29923586..32dd7be7ba 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -539,33 +539,35 @@ void QGL2PaintEngineEx::beginNativePainting()
d->funcs.glDisableVertexAttribArray(i);
#ifndef QT_OPENGL_ES_2
- const QGLContext *ctx = d->ctx;
- const QGLFormat &fmt = d->device->format();
- if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
- || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
- || fmt.profile() == QGLFormat::CompatibilityProfile)
- {
- // be nice to people who mix OpenGL 1.x code with QPainter commands
- // by setting modelview and projection matrices to mirror the GL 1
- // paint engine
- const QTransform& mtx = state()->matrix;
-
- float mv_matrix[4][4] =
+ if (!QOpenGLFunctions::isES()) {
+ const QGLContext *ctx = d->ctx;
+ const QGLFormat &fmt = d->device->format();
+ if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
+ || (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
+ || fmt.profile() == QGLFormat::CompatibilityProfile)
{
- { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
- { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
- { 0, 0, 1, 0 },
- { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
- };
-
- const QSize sz = d->device->size();
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf(&mv_matrix[0][0]);
+ // be nice to people who mix OpenGL 1.x code with QPainter commands
+ // by setting modelview and projection matrices to mirror the GL 1
+ // paint engine
+ const QTransform& mtx = state()->matrix;
+
+ float mv_matrix[4][4] =
+ {
+ { float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
+ { float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
+ { 0, 0, 1, 0 },
+ { float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
+ };
+
+ const QSize sz = d->device->size();
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(&mv_matrix[0][0]);
+ }
}
#endif
@@ -595,9 +597,11 @@ void QGL2PaintEngineExPrivate::resetGLState()
ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
#ifndef QT_OPENGL_ES_2
- // gl_Color, corresponding to vertex attribute 3, may have been changed
- float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
- funcs.glVertexAttrib4fv(3, color);
+ if (!QOpenGLFunctions::isES()) {
+ // gl_Color, corresponding to vertex attribute 3, may have been changed
+ float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ funcs.glVertexAttrib4fv(3, color);
+ }
#endif
}
@@ -1352,11 +1356,13 @@ void QGL2PaintEngineEx::renderHintsChanged()
state()->renderHintsChanged = true;
#if !defined(QT_OPENGL_ES_2)
- if ((state()->renderHints & QPainter::Antialiasing)
- || (state()->renderHints & QPainter::HighQualityAntialiasing))
- glEnable(GL_MULTISAMPLE);
- else
- glDisable(GL_MULTISAMPLE);
+ if (!QOpenGLFunctions::isES()) {
+ if ((state()->renderHints & QPainter::Antialiasing)
+ || (state()->renderHints & QPainter::HighQualityAntialiasing))
+ glEnable(GL_MULTISAMPLE);
+ else
+ glDisable(GL_MULTISAMPLE);
+ }
#endif
Q_D(QGL2PaintEngineEx);
@@ -2027,21 +2033,23 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_SCISSOR_TEST);
#if !defined(QT_OPENGL_ES_2)
- glDisable(GL_MULTISAMPLE);
+ if (!QOpenGLFunctions::isES())
+ glDisable(GL_MULTISAMPLE);
#endif
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLFunctions::isES()) {
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
-#endif
-
-#if defined(QT_OPENGL_ES_2)
+ d->multisamplingAlwaysEnabled = false;
+ } else {
+ d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
+ }
+#else
// OpenGL ES can't switch MSAA off, so if the gl paint device is
// multisampled, it's always multisampled.
d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
-#else
- d->multisamplingAlwaysEnabled = false;
#endif
return true;
diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
index d96ab36e2b..d506b7e4b9 100644
--- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
+++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp
@@ -319,23 +319,24 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
uchar g = src[x] >> 8;
uchar b = src[x];
quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding.
-#if defined(QT_OPENGL_ES_2)
- // swizzle the bits to accommodate for the GL_RGBA upload.
- src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
-#else
- src[x] = (src[x] & 0x00ffffff) | (avg << 24);
-#endif
+ if (QOpenGLFunctions::isES()) {
+ // swizzle the bits to accommodate for the GL_RGBA upload.
+ src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
+ } else {
+ src[x] = (src[x] & 0x00ffffff) | (avg << 24);
+ }
}
}
}
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
if (mask.format() == QImage::Format_RGB32) {
-#if defined(QT_OPENGL_ES_2)
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
-#else
- glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
+ GLenum format = GL_RGBA;
+#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLFunctions::isES())
+ format = GL_BGRA;
#endif
+ glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits());
} else {
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index b01ca80829..4d9208d983 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -8,9 +8,6 @@ irix-cc*:QMAKE_CXXFLAGS += -no_prelink -ptused
QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf
-ANDROID_LIB_DEPENDENCY_REPLACEMENTS = \
- "plugins/platforms/android/libqtforandroid.so:plugins/platforms/android/libqtforandroidGL.so"
-
load(qt_module)
contains(QT_CONFIG, opengl):CONFIG += opengl
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 40a8b1921c..e027de02e0 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1699,10 +1699,12 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
return QImage();
int w = size.width();
int h = size.height();
-#if !defined(QT_OPENGL_ES_2)
- //### glGetTexImage not in GL ES 2.0, need to do something else here!
- glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
-#endif
+#ifndef QT_OPENGL_ES
+ if (!QOpenGLFunctions::isES()) {
+ //### glGetTexImage not in GL ES 2.0, need to do something else here!
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
+ }
+#endif // QT_OPENGL_ES
convertFromGLImage(img, w, h, alpha_format, include_alpha);
return img;
}
@@ -2282,17 +2284,20 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
glBindTexture(target, tx_id);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering);
-#if defined(QT_OPENGL_ES_2)
- bool genMipmap = false;
-#endif
+ bool genMipmap = !QOpenGLFunctions::isES();
if (glFormat.directRendering()
&& (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap))
&& target == GL_TEXTURE_2D
&& (options & QGLContext::MipmapBindOption))
{
#if !defined(QT_OPENGL_ES_2)
- glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
- glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ if (genMipmap) {
+ glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
+ glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
+ } else {
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+ genMipmap = true;
+ }
#else
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
genMipmap = true;
@@ -2421,11 +2426,11 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
printf(" - did byte swapping (%d ms)\n", time.elapsed());
#endif
}
-#ifdef QT_OPENGL_ES
- // OpenGL/ES requires that the internal and external formats be
- // identical.
- internalFormat = externalFormat;
-#endif
+ if (QOpenGLFunctions::isES()) {
+ // OpenGL/ES requires that the internal and external formats be
+ // identical.
+ internalFormat = externalFormat;
+ }
#ifdef QGL_BIND_TEXTURE_DEBUG
printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
img.format(), externalFormat, internalFormat, pixel_type);
@@ -2434,10 +2439,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
const QImage &constRef = img; // to avoid detach in bits()...
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
-#if defined(QT_OPENGL_ES_2)
- if (genMipmap)
- glGenerateMipmap(target);
-#endif
+ if (genMipmap && QOpenGLFunctions::isES())
+ functions->glGenerateMipmap(target);
#ifndef QT_NO_DEBUG
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
@@ -2518,31 +2521,32 @@ int QGLContextPrivate::maxTextureSize()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
-#if defined(QT_OPENGL_ES)
- return max_texture_size;
-#else
- GLenum proxy = GL_PROXY_TEXTURE_2D;
-
- GLint size;
- GLint next = 64;
- glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
- if (size == 0) {
- return max_texture_size;
- }
- do {
- size = next;
- next = size * 2;
+#ifndef QT_OPENGL_ES
+ if (!QOpenGLFunctions::isES()) {
+ GLenum proxy = GL_PROXY_TEXTURE_2D;
- if (next > max_texture_size)
- break;
+ GLint size;
+ GLint next = 64;
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
- } while (next > size);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
+ if (size == 0) {
+ return max_texture_size;
+ }
+ do {
+ size = next;
+ next = size * 2;
- max_texture_size = size;
- return max_texture_size;
+ if (next > max_texture_size)
+ break;
+ glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
+ } while (next > size);
+
+ max_texture_size = size;
+ }
#endif
+
+ return max_texture_size;
}
/*!
@@ -2696,7 +2700,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
Q_UNUSED(textureHeight);
Q_UNUSED(textureTarget);
#else
- if (textureTarget != GL_TEXTURE_2D) {
+ if (textureTarget != GL_TEXTURE_2D && !QOpenGLFunctions::isES()) {
if (textureWidth == -1 || textureHeight == -1) {
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
@@ -2763,35 +2767,38 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
#endif
#ifndef QT_OPENGL_ES_2
+ if (!QOpenGLFunctions::isES()) {
#ifdef QT_OPENGL_ES
- if (textureTarget != GL_TEXTURE_2D) {
- qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
- return;
- }
+ if (textureTarget != GL_TEXTURE_2D) {
+ qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
+ return;
+ }
#else
- const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
- GLint oldTexture;
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
+ const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
+ GLint oldTexture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
#endif
- glEnable(textureTarget);
- glBindTexture(textureTarget, textureId);
+ glEnable(textureTarget);
+ glBindTexture(textureTarget, textureId);
- qDrawTextureRect(target, -1, -1, textureTarget);
+ qDrawTextureRect(target, -1, -1, textureTarget);
#ifdef QT_OPENGL_ES
- glDisable(textureTarget);
-#else
- if (!wasEnabled)
glDisable(textureTarget);
- glBindTexture(textureTarget, oldTexture);
+#else
+ if (!wasEnabled)
+ glDisable(textureTarget);
+ glBindTexture(textureTarget, oldTexture);
#endif
+ return;
+ }
#else
Q_UNUSED(target);
Q_UNUSED(textureId);
Q_UNUSED(textureTarget);
- qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
#endif
+ qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
}
/*!
@@ -2821,40 +2828,42 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
Q_UNUSED(point);
Q_UNUSED(textureId);
Q_UNUSED(textureTarget);
- qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
#else
-
- const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
- GLint oldTexture;
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
-
- glEnable(textureTarget);
- glBindTexture(textureTarget, textureId);
-
- GLint textureWidth;
- GLint textureHeight;
-
- glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
- glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
-
- if (d_ptr->active_engine &&
- d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
- QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
- if (!eng->isNativePaintingActive()) {
- QRectF dest(point, QSizeF(textureWidth, textureHeight));
- QRectF src(0, 0, textureWidth, textureHeight);
- QSize size(textureWidth, textureHeight);
- if (eng->drawTexture(dest, textureId, size, src))
- return;
+ if (!QOpenGLFunctions::isES()) {
+ const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
+ GLint oldTexture;
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
+
+ glEnable(textureTarget);
+ glBindTexture(textureTarget, textureId);
+
+ GLint textureWidth;
+ GLint textureHeight;
+
+ glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
+ glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
+
+ if (d_ptr->active_engine &&
+ d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
+ QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
+ if (!eng->isNativePaintingActive()) {
+ QRectF dest(point, QSizeF(textureWidth, textureHeight));
+ QRectF src(0, 0, textureWidth, textureHeight);
+ QSize size(textureWidth, textureHeight);
+ if (eng->drawTexture(dest, textureId, size, src))
+ return;
+ }
}
- }
- qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
+ qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
- if (!wasEnabled)
- glDisable(textureTarget);
- glBindTexture(textureTarget, oldTexture);
+ if (!wasEnabled)
+ glDisable(textureTarget);
+ glBindTexture(textureTarget, oldTexture);
+ return;
+ }
#endif
+ qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
}
/*!
@@ -4163,7 +4172,7 @@ void QGLWidget::glDraw()
return;
makeCurrent();
#ifndef QT_OPENGL_ES
- if (d->glcx->deviceIsPixmap())
+ if (d->glcx->deviceIsPixmap() && !QOpenGLFunctions::isES())
glDrawBuffer(GL_FRONT);
#endif
QSize readback_target_size = d->glcx->d_ptr->readback_target_size;
@@ -4206,18 +4215,20 @@ void QGLWidget::qglColor(const QColor& c) const
#ifdef QT_OPENGL_ES
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
#else
- Q_D(const QGLWidget);
- const QGLContext *ctx = QGLContext::currentContext();
- if (ctx) {
- if (ctx->format().rgba())
- glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
- else if (!d->cmap.isEmpty()) { // QGLColormap in use?
- int i = d->cmap.find(c.rgb());
- if (i < 0)
- i = d->cmap.findNearest(c.rgb());
- glIndexi(i);
- } else
- glIndexi(ctx->colorIndex(c));
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(const QGLWidget);
+ const QGLContext *ctx = QGLContext::currentContext();
+ if (ctx) {
+ if (ctx->format().rgba())
+ glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+ else if (!d->cmap.isEmpty()) { // QGLColormap in use?
+ int i = d->cmap.find(c.rgb());
+ if (i < 0)
+ i = d->cmap.findNearest(c.rgb());
+ glIndexi(i);
+ } else
+ glIndexi(ctx->colorIndex(c));
+ }
}
#endif //QT_OPENGL_ES
#else
@@ -4238,18 +4249,23 @@ void QGLWidget::qglClearColor(const QColor& c) const
#ifdef QT_OPENGL_ES
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
#else
- Q_D(const QGLWidget);
- const QGLContext *ctx = QGLContext::currentContext();
- if (ctx) {
- if (ctx->format().rgba())
- glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
- else if (!d->cmap.isEmpty()) { // QGLColormap in use?
- int i = d->cmap.find(c.rgb());
- if (i < 0)
- i = d->cmap.findNearest(c.rgb());
- glClearIndex(i);
- } else
- glClearIndex(ctx->colorIndex(c));
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(const QGLWidget);
+ const QGLContext *ctx = QGLContext::currentContext();
+ if (ctx) {
+ if (ctx->format().rgba())
+ glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+ else if (!d->cmap.isEmpty()) { // QGLColormap in use?
+ int i = d->cmap.find(c.rgb());
+ if (i < 0)
+ i = d->cmap.findNearest(c.rgb());
+ glClearIndex(i);
+ } else {
+ glClearIndex(ctx->colorIndex(c));
+ }
+ }
+ } else {
+ glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
}
#endif
}
@@ -4411,72 +4427,75 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
{
#ifndef QT_OPENGL_ES
- Q_D(QGLWidget);
- if (str.isEmpty() || !isValid())
- return;
-
- GLint view[4];
- bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
- if (!use_scissor_testing)
- glGetIntegerv(GL_VIEWPORT, &view[0]);
- int width = d->glcx->device()->width();
- int height = d->glcx->device()->height();
- bool auto_swap = autoBufferSwap();
-
- QPaintEngine *engine = paintEngine();
-
- qt_save_gl_state();
-
- QPainter *p;
- bool reuse_painter = false;
- if (engine->isActive()) {
- reuse_painter = true;
- p = engine->painter();
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QGLWidget);
+ if (str.isEmpty() || !isValid())
+ return;
+
+ GLint view[4];
+ bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
+ if (!use_scissor_testing)
+ glGetIntegerv(GL_VIEWPORT, &view[0]);
+ int width = d->glcx->device()->width();
+ int height = d->glcx->device()->height();
+ bool auto_swap = autoBufferSwap();
+
+ QPaintEngine *engine = paintEngine();
+
+ qt_save_gl_state();
+
+ QPainter *p;
+ bool reuse_painter = false;
+ if (engine->isActive()) {
+ reuse_painter = true;
+ p = engine->painter();
+
+ glDisable(GL_DEPTH_TEST);
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0, width, height, 0, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+
+ glLoadIdentity();
+ } else {
+ setAutoBufferSwap(false);
+ // disable glClear() as a result of QPainter::begin()
+ d->disable_clear_on_painter_begin = true;
+ p = new QPainter(this);
+ }
- glDisable(GL_DEPTH_TEST);
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, width, height, 0, 0, 1);
- glMatrixMode(GL_MODELVIEW);
+ QRect viewport(view[0], view[1], view[2], view[3]);
+ if (!use_scissor_testing && viewport != rect()) {
+ // if the user hasn't set a scissor box, we set one that
+ // covers the current viewport
+ glScissor(view[0], view[1], view[2], view[3]);
+ glEnable(GL_SCISSOR_TEST);
+ } else if (use_scissor_testing) {
+ // use the scissor box set by the user
+ glEnable(GL_SCISSOR_TEST);
+ }
- glLoadIdentity();
- } else {
- setAutoBufferSwap(false);
- // disable glClear() as a result of QPainter::begin()
- d->disable_clear_on_painter_begin = true;
- p = new QPainter(this);
- }
+ qt_gl_draw_text(p, x, y, str, font);
- QRect viewport(view[0], view[1], view[2], view[3]);
- if (!use_scissor_testing && viewport != rect()) {
- // if the user hasn't set a scissor box, we set one that
- // covers the current viewport
- glScissor(view[0], view[1], view[2], view[3]);
- glEnable(GL_SCISSOR_TEST);
- } else if (use_scissor_testing) {
- // use the scissor box set by the user
- glEnable(GL_SCISSOR_TEST);
- }
+ if (!reuse_painter) {
+ p->end();
+ delete p;
+ setAutoBufferSwap(auto_swap);
+ d->disable_clear_on_painter_begin = false;
+ }
- qt_gl_draw_text(p, x, y, str, font);
+ qt_restore_gl_state();
- if (!reuse_painter) {
- p->end();
- delete p;
- setAutoBufferSwap(auto_swap);
- d->disable_clear_on_painter_begin = false;
+ return;
}
-
- qt_restore_gl_state();
-
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(str);
Q_UNUSED(font);
- qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
#endif
+ qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
}
/*! \overload
@@ -4503,80 +4522,83 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font)
{
#ifndef QT_OPENGL_ES
- Q_D(QGLWidget);
- if (str.isEmpty() || !isValid())
- return;
+ if (!QOpenGLFunctions::isES()) {
+ Q_D(QGLWidget);
+ if (str.isEmpty() || !isValid())
+ return;
+
+ bool auto_swap = autoBufferSwap();
+
+ int width = d->glcx->device()->width();
+ int height = d->glcx->device()->height();
+ GLdouble model[4 * 4], proj[4 * 4];
+ GLint view[4];
+ glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
+ glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
+ glGetIntegerv(GL_VIEWPORT, &view[0]);
+ GLdouble win_x = 0, win_y = 0, win_z = 0;
+ qgluProject(x, y, z, &model[0], &proj[0], &view[0],
+ &win_x, &win_y, &win_z);
+ win_y = height - win_y; // y is inverted
- bool auto_swap = autoBufferSwap();
+ QPaintEngine *engine = paintEngine();
- int width = d->glcx->device()->width();
- int height = d->glcx->device()->height();
- GLdouble model[4 * 4], proj[4 * 4];
- GLint view[4];
- glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
- glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
- glGetIntegerv(GL_VIEWPORT, &view[0]);
- GLdouble win_x = 0, win_y = 0, win_z = 0;
- qgluProject(x, y, z, &model[0], &proj[0], &view[0],
- &win_x, &win_y, &win_z);
- win_y = height - win_y; // y is inverted
+ QPainter *p;
+ bool reuse_painter = false;
+ bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
+ bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
- QPaintEngine *engine = paintEngine();
+ qt_save_gl_state();
- QPainter *p;
- bool reuse_painter = false;
- bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
- bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
+ if (engine->isActive()) {
+ reuse_painter = true;
+ p = engine->painter();
+ } else {
+ setAutoBufferSwap(false);
+ // disable glClear() as a result of QPainter::begin()
+ d->disable_clear_on_painter_begin = true;
+ p = new QPainter(this);
+ }
- qt_save_gl_state();
+ QRect viewport(view[0], view[1], view[2], view[3]);
+ if (!use_scissor_testing && viewport != rect()) {
+ glScissor(view[0], view[1], view[2], view[3]);
+ glEnable(GL_SCISSOR_TEST);
+ } else if (use_scissor_testing) {
+ glEnable(GL_SCISSOR_TEST);
+ }
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glViewport(0, 0, width, height);
+ glOrtho(0, width, height, 0, 0, 1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glAlphaFunc(GL_GREATER, 0.0);
+ glEnable(GL_ALPHA_TEST);
+ if (use_depth_testing)
+ glEnable(GL_DEPTH_TEST);
+ glTranslated(0, 0, -win_z);
+ qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
+
+ if (!reuse_painter) {
+ p->end();
+ delete p;
+ setAutoBufferSwap(auto_swap);
+ d->disable_clear_on_painter_begin = false;
+ }
- if (engine->isActive()) {
- reuse_painter = true;
- p = engine->painter();
- } else {
- setAutoBufferSwap(false);
- // disable glClear() as a result of QPainter::begin()
- d->disable_clear_on_painter_begin = true;
- p = new QPainter(this);
- }
+ qt_restore_gl_state();
- QRect viewport(view[0], view[1], view[2], view[3]);
- if (!use_scissor_testing && viewport != rect()) {
- glScissor(view[0], view[1], view[2], view[3]);
- glEnable(GL_SCISSOR_TEST);
- } else if (use_scissor_testing) {
- glEnable(GL_SCISSOR_TEST);
- }
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glViewport(0, 0, width, height);
- glOrtho(0, width, height, 0, 0, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glAlphaFunc(GL_GREATER, 0.0);
- glEnable(GL_ALPHA_TEST);
- if (use_depth_testing)
- glEnable(GL_DEPTH_TEST);
- glTranslated(0, 0, -win_z);
- qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
-
- if (!reuse_painter) {
- p->end();
- delete p;
- setAutoBufferSwap(auto_swap);
- d->disable_clear_on_painter_begin = false;
+ return;
}
-
- qt_restore_gl_state();
-
#else // QT_OPENGL_ES
Q_UNUSED(x);
Q_UNUSED(y);
Q_UNUSED(z);
Q_UNUSED(str);
Q_UNUSED(font);
- qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
#endif
+ qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
}
QGLFormat QGLWidget::format() const
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index 8b66c891bb..4f4df8d2e4 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -321,21 +321,23 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
d->context = new QOpenGLContext;
#if !defined(QT_OPENGL_ES)
- // On desktop, request latest released version
- QSurfaceFormat format;
+ if (!QOpenGLFunctions::isES()) {
+ // On desktop, request latest released version
+ QSurfaceFormat format;
#if defined(Q_OS_MAC)
- // OS X is limited to OpenGL 3.2 Core Profile at present
- // so set that here. If we use compatibility profile it
- // only reports 2.x contexts.
- format.setMajorVersion(3);
- format.setMinorVersion(2);
- format.setProfile(QSurfaceFormat::CoreProfile);
+ // OS X is limited to OpenGL 3.2 Core Profile at present
+ // so set that here. If we use compatibility profile it
+ // only reports 2.x contexts.
+ format.setMajorVersion(3);
+ format.setMinorVersion(2);
+ format.setProfile(QSurfaceFormat::CoreProfile);
#else
- format.setMajorVersion(4);
- format.setMinorVersion(3);
-#endif
- d->context->setFormat(format);
+ format.setMajorVersion(4);
+ format.setMinorVersion(3);
#endif
+ d->context->setFormat(format);
+ }
+#endif // QT_OPENGL_ES
d->context->create();
d->context->makeCurrent(d->window);
}
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp
index 1c9545990f..5491bad628 100644
--- a/src/opengl/qglbuffer.cpp
+++ b/src/opengl/qglbuffer.cpp
@@ -344,18 +344,20 @@ void QGLBuffer::destroy()
bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
- Q_D(QGLBuffer);
- if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
- return false;
- while (glGetError() != GL_NO_ERROR) ; // Clear error state.
- d->funcs->glGetBufferSubData(d->type, offset, count, data);
- return glGetError() == GL_NO_ERROR;
+ if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
+ Q_D(QGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return glGetError() == GL_NO_ERROR;
+ }
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
- return false;
#endif
+ return false;
}
/*!
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index a9871967f2..b4821ccf61 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -373,8 +373,11 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
GLenum format = f->format().internalTextureFormat();
reqAlpha = (format != GL_RGB
-#ifndef QT_OPENGL_ES
- && format != GL_RGB5 && format != GL_RGB8
+#ifdef GL_RGB5
+ && format != GL_RGB5
+#endif
+#ifdef GL_RGB8
+ && format != GL_RGB8
#endif
);
}
@@ -592,8 +595,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
GL_DEPTH_COMPONENT16, size.width(), size.height());
}
#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_DEPTH_COMPONENT, size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT24, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT16, size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
+ GL_DEPTH_COMPONENT, size.width(), size.height());
+ }
#endif
} else {
#ifdef QT_OPENGL_ES
@@ -605,7 +617,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
size.width(), size.height());
}
#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
+ if (QOpenGLFunctions::isES()) {
+ if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
+ size.width(), size.height());
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size.width(), size.height());
+ }
+ } else {
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
+ }
#endif
}
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
@@ -621,23 +643,18 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
funcs.glGenRenderbuffers(1, &stencil_buffer);
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
- if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
-#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX8, size.width(), size.height());
-#else
- funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
- GL_STENCIL_INDEX, size.width(), size.height());
-#endif
- } else {
+
#ifdef QT_OPENGL_ES
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
- size.width(), size.height());
+ GLenum storage = GL_STENCIL_INDEX8;
#else
- funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
- size.width(), size.height());
+ GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif
- }
+
+ if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
+ funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
+ else
+ funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
+
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, stencil_buffer);
valid = checkFramebufferStatus();
@@ -830,7 +847,13 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, size, NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -844,7 +867,13 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, QSize(width, height), NoAttachment, target,
+#ifndef QT_OPENGL_ES_2
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#else
+ GL_RGBA
+#endif
+ );
}
/*! \overload
@@ -893,6 +922,12 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, QSize(width, height), attachment, target, internal_format);
}
@@ -914,6 +949,12 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
+ if (!internal_format)
+#ifdef QT_OPENGL_ES_2
+ internal_format = GL_RGBA;
+#else
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
d->init(this, size, attachment, target, internal_format);
}
@@ -976,7 +1017,7 @@ bool QGLFramebufferObject::isValid() const
bool QGLFramebufferObject::bind()
{
if (!isValid())
- return false;
+ return false;
Q_D(QGLFramebufferObject);
QGL_FUNC_CONTEXT;
if (!ctx)
@@ -1008,7 +1049,7 @@ bool QGLFramebufferObject::bind()
bool QGLFramebufferObject::release()
{
if (!isValid())
- return false;
+ return false;
Q_D(QGLFramebufferObject);
QGL_FUNC_CONTEXT;
if (!ctx)
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index 9312a23822..affa47cac7 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -63,17 +63,11 @@ public:
QGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
QGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
-#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
- QGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
- QGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
-#else
+
QGLFramebufferObject(const QSize &size, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QGLFramebufferObject(int width, int height, Attachment attachment,
- GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
-#endif
+ GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h
index 0f1128e8f6..3b36c5c2b6 100644
--- a/src/opengl/qglframebufferobject_p.h
+++ b/src/opengl/qglframebufferobject_p.h
@@ -60,12 +60,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
class QGLFramebufferObjectFormatPrivate
{
public:
@@ -74,9 +68,13 @@ public:
samples(0),
attachment(QGLFramebufferObject::NoAttachment),
target(GL_TEXTURE_2D),
- internal_format(DEFAULT_FORMAT),
mipmap(false)
{
+#ifndef QT_OPENGL_ES_2
+ internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#else
+ internal_format = GL_RGBA;
+#endif
}
QGLFramebufferObjectFormatPrivate
(const QGLFramebufferObjectFormatPrivate *other)
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index 2e8caa30f6..e75f9cf915 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -213,94 +213,94 @@ QGLFunctions::QGLFunctions(const QGLContext *context)
static int qt_gl_resolve_features()
{
-#if defined(QT_OPENGL_ES_2)
- int features = QGLFunctions::Multitexture |
- QGLFunctions::Shaders |
- QGLFunctions::Buffers |
- QGLFunctions::Framebuffers |
- QGLFunctions::BlendColor |
- QGLFunctions::BlendEquation |
- QGLFunctions::BlendEquationSeparate |
- QGLFunctions::BlendFuncSeparate |
- QGLFunctions::BlendSubtract |
- QGLFunctions::CompressedTextures |
- QGLFunctions::Multisample |
- QGLFunctions::StencilSeparate;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- return features;
-#elif defined(QT_OPENGL_ES)
- int features = QGLFunctions::Multitexture |
- QGLFunctions::Buffers |
- QGLFunctions::CompressedTextures |
- QGLFunctions::Multisample;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_framebuffer_object"))
- features |= QGLFunctions::Framebuffers;
- if (extensions.match("GL_OES_blend_equation_separate"))
- features |= QGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_OES_blend_func_separate"))
- features |= QGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_OES_blend_subtract"))
- features |= QGLFunctions::BlendSubtract;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- return features;
-#else
- int features = 0;
- QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
- QOpenGLExtensionMatcher extensions;
-
- // Recognize features by extension name.
- if (extensions.match("GL_ARB_multitexture"))
- features |= QGLFunctions::Multitexture;
- if (extensions.match("GL_ARB_shader_objects"))
- features |= QGLFunctions::Shaders;
- if (extensions.match("GL_EXT_framebuffer_object") ||
+ if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
+ int features = QGLFunctions::Multitexture |
+ QGLFunctions::Shaders |
+ QGLFunctions::Buffers |
+ QGLFunctions::Framebuffers |
+ QGLFunctions::BlendColor |
+ QGLFunctions::BlendEquation |
+ QGLFunctions::BlendEquationSeparate |
+ QGLFunctions::BlendFuncSeparate |
+ QGLFunctions::BlendSubtract |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample |
+ QGLFunctions::StencilSeparate;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QGLFunctions::NPOTTextures;
+ return features;
+ } if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
+ int features = QGLFunctions::Multitexture |
+ QGLFunctions::Buffers |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample;
+ QOpenGLExtensionMatcher extensions;
+ if (extensions.match("GL_OES_framebuffer_object"))
+ features |= QGLFunctions::Framebuffers;
+ if (extensions.match("GL_OES_blend_equation_separate"))
+ features |= QGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_OES_blend_func_separate"))
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_OES_blend_subtract"))
+ features |= QGLFunctions::BlendSubtract;
+ if (extensions.match("GL_OES_texture_npot"))
+ features |= QGLFunctions::NPOTTextures;
+ if (extensions.match("GL_IMG_texture_npot"))
+ features |= QGLFunctions::NPOTTextures;
+ return features;
+ } else {
+ int features = 0;
+ QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
+ QOpenGLExtensionMatcher extensions;
+
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_framebuffer_object") ||
extensions.match("GL_ARB_framebuffer_object"))
- features |= QGLFunctions::Framebuffers;
- if (extensions.match("GL_EXT_blend_color"))
- features |= QGLFunctions::BlendColor;
- if (extensions.match("GL_EXT_blend_equation_separate"))
- features |= QGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_EXT_blend_func_separate"))
- features |= QGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_EXT_blend_subtract"))
- features |= QGLFunctions::BlendSubtract;
- if (extensions.match("GL_ARB_texture_compression"))
- features |= QGLFunctions::CompressedTextures;
- if (extensions.match("GL_ARB_multisample"))
- features |= QGLFunctions::Multisample;
- if (extensions.match("GL_ARB_texture_non_power_of_two"))
- features |= QGLFunctions::NPOTTextures;
-
- // Recognize features by minimum OpenGL version.
- if (versions & QGLFormat::OpenGL_Version_1_2) {
- features |= QGLFunctions::BlendColor |
- QGLFunctions::BlendEquation;
- }
- if (versions & QGLFormat::OpenGL_Version_1_3) {
- features |= QGLFunctions::Multitexture |
- QGLFunctions::CompressedTextures |
- QGLFunctions::Multisample;
- }
- if (versions & QGLFormat::OpenGL_Version_1_4)
- features |= QGLFunctions::BlendFuncSeparate;
- if (versions & QGLFormat::OpenGL_Version_1_5)
- features |= QGLFunctions::Buffers;
- if (versions & QGLFormat::OpenGL_Version_2_0) {
- features |= QGLFunctions::Shaders |
- QGLFunctions::StencilSeparate |
- QGLFunctions::BlendEquationSeparate |
- QGLFunctions::NPOTTextures;
- }
- return features;
-#endif
+ features |= QGLFunctions::Framebuffers;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QGLFunctions::BlendSubtract;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QGLFunctions::NPOTTextures;
+
+ // Recognize features by minimum OpenGL version.
+ if (versions & QGLFormat::OpenGL_Version_1_2) {
+ features |= QGLFunctions::BlendColor |
+ QGLFunctions::BlendEquation;
+ }
+ if (versions & QGLFormat::OpenGL_Version_1_3) {
+ features |= QGLFunctions::Multitexture |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample;
+ }
+ if (versions & QGLFormat::OpenGL_Version_1_4)
+ features |= QGLFunctions::BlendFuncSeparate;
+ if (versions & QGLFormat::OpenGL_Version_1_5)
+ features |= QGLFunctions::Buffers;
+ if (versions & QGLFormat::OpenGL_Version_2_0) {
+ features |= QGLFunctions::Shaders |
+ QGLFunctions::StencilSeparate |
+ QGLFunctions::BlendEquationSeparate |
+ QGLFunctions::NPOTTextures;
+ }
+ return features;
+ }
}
/*!
diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h
index fd867d7a91..7fc7966a09 100644
--- a/src/opengl/qglfunctions.h
+++ b/src/opengl/qglfunctions.h
@@ -51,6 +51,7 @@
#include <QtOpenGL/qgl.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/qopenglfunctions.h>
QT_BEGIN_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index ebc9f296eb..51e7648d72 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -361,7 +361,8 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
glBindTexture(GL_TEXTURE_2D, texture_id);
#ifndef QT_OPENGL_ES
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
+ GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#else
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
#endif
@@ -487,7 +488,8 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
{
Q_D(QGLPixelBuffer);
#ifndef QT_OPENGL_ES
- return d->qctx->bindTexture(image, target, GLint(GL_RGBA8));
+ GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+ return d->qctx->bindTexture(image, target, GLint(format));
#else
return d->qctx->bindTexture(image, target, GL_RGBA);
#endif
@@ -505,7 +507,8 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
{
Q_D(QGLPixelBuffer);
#ifndef QT_OPENGL_ES
- return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8));
+ GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+ return d->qctx->bindTexture(pixmap, target, GLint(format));
#else
return d->qctx->bindTexture(pixmap, target, GL_RGBA);
#endif
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 84e4c26ed1..6b8d38ef42 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -47,6 +47,7 @@
#include <QtCore/qfile.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -246,7 +247,8 @@ bool QGLShaderPrivate::create()
if (shaderType == QGLShader::Vertex)
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
#if !defined(QT_OPENGL_ES_2)
- else if (shaderType == QGLShader::Geometry)
+ else if (shaderType == QGLShader::Geometry
+ && !QOpenGLFunctions::isES())
shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
#endif
else
@@ -428,11 +430,14 @@ bool QGLShader::compileSourceCode(const char *source)
srclen.append(GLint(headerLen));
}
#ifdef QGL_DEFINE_QUALIFIERS
- src.append(qualifierDefines);
- srclen.append(GLint(sizeof(qualifierDefines) - 1));
+ if (!QOpenGLFunctions::isES()) {
+ src.append(qualifierDefines);
+ srclen.append(GLint(sizeof(qualifierDefines) - 1));
+ }
#endif
#ifdef QGL_REDEFINE_HIGHP
- if (d->shaderType == Fragment) {
+ if (d->shaderType == Fragment
+ && QOpenGLFunctions::isES()) {
src.append(redefineHighp);
srclen.append(GLint(sizeof(redefineHighp) - 1));
}
@@ -562,13 +567,15 @@ public:
void initializeGeometryShaderFunctions()
{
- QOpenGLContext *context = QOpenGLContext::currentContext();
- glProgramParameteri = (type_glProgramParameteri)
- context->getProcAddress("glProgramParameteri");
-
- if (!glProgramParameteri) {
+ if (!QOpenGLFunctions::isES()) {
+ QOpenGLContext *context = QOpenGLContext::currentContext();
glProgramParameteri = (type_glProgramParameteri)
- context->getProcAddress("glProgramParameteriEXT");
+ context->getProcAddress("glProgramParameteri");
+
+ if (!glProgramParameteri) {
+ glProgramParameteri = (type_glProgramParameteri)
+ context->getProcAddress("glProgramParameteriEXT");
+ }
}
}
@@ -929,7 +936,8 @@ bool QGLShaderProgram::link()
#if !defined(QT_OPENGL_ES_2)
// Set up the geometry shader parameters
- if (d->glfuncs->glProgramParameteri) {
+ if (!QOpenGLFunctions::isES()
+ && d->glfuncs->glProgramParameteri) {
foreach (QGLShader *shader, d->shaders) {
if (shader->shaderType() & QGLShader::Geometry) {
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
@@ -3060,7 +3068,8 @@ int QGLShaderProgram::maxGeometryOutputVertices() const
{
GLint n = 0;
#if !defined(QT_OPENGL_ES_2)
- glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
+ if (!QOpenGLFunctions::isES())
+ glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
#endif
return n;
}
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
index 12ae5965df..50c39a12e0 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.mm
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -121,6 +121,7 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
<< NSOpenGLPFASamples << (NSOpenGLPixelFormatAttribute) format.samples();
}
+ attrs << NSOpenGLPFAAllowOfflineRenderers;
attrs << 0;
NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs.constData()];
diff --git a/src/platformsupport/devicediscovery/devicediscovery.pri b/src/platformsupport/devicediscovery/devicediscovery.pri
index 9a58eeedfe..9748129225 100644
--- a/src/platformsupport/devicediscovery/devicediscovery.pri
+++ b/src/platformsupport/devicediscovery/devicediscovery.pri
@@ -1,12 +1,17 @@
-linux:contains(QT_CONFIG, evdev) {
- HEADERS += $$PWD/qdevicediscovery_p.h
+HEADERS += $$PWD/qdevicediscovery_p.h
+linux {
contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
-
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
- } else {
+ # Use our own define. QT_NO_LIBUDEV may not be set on non-Linux systems.
+ DEFINES += QDEVICEDISCOVERY_UDEV
+ } else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
+ } else {
+ SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
+} else {
+ SOURCES += $$PWD/qdevicediscovery_dummy.cpp
}
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp
index de4075feff..53e042272b 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_dummy.cpp
@@ -39,23 +39,34 @@
**
****************************************************************************/
-#include "qandroidopenglplatformscreen.h"
-#include "qandroidopenglplatformwindow.h"
-#include "androidjnimenu.h"
+#include "qdevicediscovery_p.h"
QT_BEGIN_NAMESPACE
-QAndroidOpenGLPlatformScreen::QAndroidOpenGLPlatformScreen(EGLDisplay display)
- : QEglFSScreen(display)
+QDeviceDiscovery *QDeviceDiscovery::create(QDeviceTypes types, QObject *parent)
{
+ return new QDeviceDiscovery(types, parent);
}
-void QAndroidOpenGLPlatformScreen::topWindowChanged(QPlatformWindow *window)
+QDeviceDiscovery::QDeviceDiscovery(QDeviceTypes types, QObject *parent)
+ : QObject(parent),
+ m_types(types)
{
- QtAndroidMenu::setActiveTopLevelWindow(window->window());
- QAndroidOpenGLPlatformWindow *platformWindow = static_cast<QAndroidOpenGLPlatformWindow *>(window);
- if (platformWindow != 0)
- platformWindow->updateStatusBarVisibility();
+}
+
+QDeviceDiscovery::~QDeviceDiscovery()
+{
+}
+
+QStringList QDeviceDiscovery::scanConnectedDevices()
+{
+ return QStringList();
+}
+
+bool QDeviceDiscovery::checkDeviceType(const QString &device)
+{
+ Q_UNUSED(device);
+ return false;
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_p.h b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
index 5485b73fd7..0e21118324 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_p.h
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_p.h
@@ -44,8 +44,9 @@
#include <QObject>
#include <QSocketNotifier>
+#include <QStringList>
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
#include <libudev.h>
#endif
@@ -88,13 +89,13 @@ signals:
void deviceDetected(const QString &deviceNode);
void deviceRemoved(const QString &deviceNode);
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
private slots:
void handleUDevNotification();
#endif
private:
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
QDeviceDiscovery(QDeviceTypes types, struct udev *udev, QObject *parent = 0);
bool checkDeviceType(struct udev_device *dev);
#else
@@ -104,7 +105,7 @@ private:
QDeviceTypes m_types;
-#ifndef QT_NO_LIBUDEV
+#ifdef QDEVICEDISCOVERY_UDEV
void startWatching();
void stopWatching();
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 506f4ab4ea..c026ff5a4b 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -3,11 +3,33 @@ contains(QT_CONFIG,egl) {
$$PWD/qeglconvenience_p.h \
$$PWD/qeglplatformcontext_p.h \
$$PWD/qeglpbuffer_p.h
+
SOURCES += \
$$PWD/qeglconvenience.cpp \
$$PWD/qeglplatformcontext.cpp \
$$PWD/qeglpbuffer.cpp
+ unix {
+ HEADERS += \
+ $$PWD/qeglplatformcursor_p.h \
+ $$PWD/qeglplatformwindow_p.h \
+ $$PWD/qeglplatformscreen_p.h \
+ $$PWD/qeglcompositor_p.h \
+ $$PWD/qeglplatformbackingstore_p.h \
+ $$PWD/qeglplatformintegration_p.h
+
+ SOURCES += \
+ $$PWD/qeglplatformcursor.cpp \
+ $$PWD/qeglplatformwindow.cpp \
+ $$PWD/qeglplatformscreen.cpp \
+ $$PWD/qeglcompositor.cpp \
+ $$PWD/qeglplatformbackingstore.cpp \
+ $$PWD/qeglplatformintegration.cpp
+ }
+
+ # Avoid X11 header collision
+ DEFINES += MESA_EGL_NO_X11_HEADERS
+
contains(QT_CONFIG,xlib) {
HEADERS += \
$$PWD/qxlibeglintegration_p.h
@@ -15,5 +37,15 @@ contains(QT_CONFIG,egl) {
$$PWD/qxlibeglintegration.cpp
}
CONFIG += egl
-}
+} else: contains(QT_CONFIG,dynamicgl) {
+ HEADERS += \
+ $$PWD/qeglconvenience_p.h \
+ $$PWD/qeglplatformcontext_p.h \
+ $$PWD/qeglpbuffer_p.h
+
+ SOURCES += \
+ $$PWD/qeglconvenience.cpp \
+ $$PWD/qeglplatformcontext.cpp \
+ $$PWD/qeglpbuffer.cpp
+}
diff --git a/src/platformsupport/eglconvenience/qeglcompositor.cpp b/src/platformsupport/eglconvenience/qeglcompositor.cpp
new file mode 100644
index 0000000000..a38f00d4f6
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglcompositor.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/private/qopengltextureblitter_p.h>
+#include <qpa/qplatformbackingstore.h>
+
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static QEGLCompositor *compositor = 0;
+
+QEGLCompositor::QEGLCompositor()
+ : m_context(0),
+ m_window(0),
+ m_blitter(0)
+{
+ Q_ASSERT(!compositor);
+ m_updateTimer.setSingleShot(true);
+ m_updateTimer.setInterval(0);
+ connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
+}
+
+QEGLCompositor::~QEGLCompositor()
+{
+ Q_ASSERT(compositor == this);
+ if (m_blitter) {
+ m_blitter->destroy();
+ delete m_blitter;
+ }
+ compositor = 0;
+}
+
+void QEGLCompositor::schedule(QOpenGLContext *context, QEGLPlatformWindow *window)
+{
+ m_context = context;
+ m_window = window;
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start();
+}
+
+void QEGLCompositor::renderAll()
+{
+ Q_ASSERT(m_context && m_window);
+ m_context->makeCurrent(m_window->window());
+
+ if (!m_blitter) {
+ m_blitter = new QOpenGLTextureBlitter;
+ m_blitter->create();
+ }
+ m_blitter->bind();
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QList<QEGLPlatformWindow *> windows = screen->windows();
+ for (int i = 0; i < windows.size(); ++i)
+ render(windows.at(i));
+
+ m_blitter->release();
+ m_context->swapBuffers(m_window->window());
+
+ for (int i = 0; i < windows.size(); ++i)
+ windows.at(i)->composited();
+}
+
+void QEGLCompositor::render(QEGLPlatformWindow *window)
+{
+ const QPlatformTextureList *textures = window->textures();
+ if (!textures)
+ return;
+
+ const QRect targetWindowRect(QPoint(0, 0), window->screen()->geometry().size());
+ glViewport(0, 0, targetWindowRect.width(), targetWindowRect.height());
+
+ for (int i = 0; i < textures->count(); ++i) {
+ uint textureId = textures->textureId(i);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i),
+ targetWindowRect);
+ m_blitter->setSwizzleRB(window->isRaster());
+
+ if (textures->count() > 1 && i == textures->count() - 1) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ glDisable(GL_BLEND);
+ } else if (textures->count() == 1) {
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
+ } else {
+ m_blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
+ }
+ }
+}
+
+QEGLCompositor *QEGLCompositor::instance()
+{
+ if (!compositor)
+ compositor = new QEGLCompositor;
+ return compositor;
+}
+
+void QEGLCompositor::destroy()
+{
+ delete compositor;
+ compositor = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiossoftwareinputhandler.h b/src/platformsupport/eglconvenience/qeglcompositor_p.h
index 5dad6b8d86..370345ada6 100644
--- a/src/plugins/platforms/ios/qiossoftwareinputhandler.h
+++ b/src/platformsupport/eglconvenience/qeglcompositor_p.h
@@ -39,33 +39,42 @@
**
****************************************************************************/
-#ifndef QIOSSOFTWAREINPUTHANDLER_H
-#define QIOSSOFTWAREINPUTHANDLER_H
+#ifndef QEGLCOMPOSITOR_H
+#define QEGLCOMPOSITOR_H
-#include <QtCore/QObject>
-#include <QtCore/QPointer>
-#include <QtWidgets/QWidget>
+#include <QtCore/QTimer>
QT_BEGIN_NAMESPACE
-class QIOSSoftwareInputHandler : public QObject
+class QOpenGLContext;
+class QOpenGLTextureBlitter;
+class QEGLPlatformWindow;
+
+class QEGLCompositor : public QObject
{
Q_OBJECT
public:
- QIOSSoftwareInputHandler() : m_CurrentFocusWidget(0), m_CurrentFocusObject(0) {}
- bool eventFilter(QObject *obj, QEvent *event);
+ void schedule(QOpenGLContext *context, QEGLPlatformWindow *window);
+
+ static QEGLCompositor *instance();
+ static void destroy();
private slots:
- void activeFocusChanged(bool focus);
+ void renderAll();
private:
- bool closeSoftwareInputPanel(QWidget *widget);
+ QEGLCompositor();
+ ~QEGLCompositor();
+
+ void render(QEGLPlatformWindow *window);
- QPointer<QWidget> m_currentFocusWidget;
- QPointer<QObject> m_currentFocusObject;
+ QOpenGLContext *m_context;
+ QEGLPlatformWindow *m_window;
+ QTimer m_updateTimer;
+ QOpenGLTextureBlitter *m_blitter;
};
QT_END_NAMESPACE
-#endif
+#endif // QEGLCOMPOSITOR_H
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index 32f553a3f5..a36d0b83d4 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -40,6 +40,13 @@
****************************************************************************/
#include <QByteArray>
+#include <QOpenGLFunctions>
+
+#ifdef Q_OS_LINUX
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <private/qmath_p.h>
+#endif
#include "qeglconvenience_p.h"
@@ -237,12 +244,15 @@ EGLConfig QEglConfigChooser::chooseConfig()
configureAttributes.append(EGL_OPENVG_BIT);
break;
#ifdef EGL_VERSION_1_4
-# if !defined(QT_OPENGL_ES_2)
case QSurfaceFormat::DefaultRenderableType:
-# endif
- case QSurfaceFormat::OpenGL:
- configureAttributes.append(EGL_OPENGL_BIT);
+ if (!QOpenGLFunctions::isES())
+ configureAttributes.append(EGL_OPENGL_BIT);
+ else
+ configureAttributes.append(EGL_OPENGL_ES2_BIT);
break;
+ case QSurfaceFormat::OpenGL:
+ configureAttributes.append(EGL_OPENGL_BIT);
+ break;
#endif
case QSurfaceFormat::OpenGLES:
if (m_format.majorVersion() == 1) {
@@ -347,11 +357,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
format.setRenderableType(QSurfaceFormat::OpenVG);
#ifdef EGL_VERSION_1_4
- else if ((referenceFormat.renderableType() == QSurfaceFormat::OpenGL
-# if !defined(QT_OPENGL_ES_2)
- || referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
-# endif
- ) && (renderableType & EGL_OPENGL_BIT))
+ else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL
+ && (renderableType & EGL_OPENGL_BIT))
+ format.setRenderableType(QSurfaceFormat::OpenGL);
+ else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
+ && !QOpenGLFunctions::isES()
+ && (renderableType & EGL_OPENGL_BIT))
format.setRenderableType(QSurfaceFormat::OpenGL);
#endif
else
@@ -365,6 +376,7 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
format.setStencilBufferSize(stencilSize);
format.setSamples(sampleCount);
format.setStereo(false); // EGL doesn't support stereo buffers
+ format.setSwapInterval(referenceFormat.swapInterval());
// Clear the EGL error state because some of the above may
// have errored out because the attribute is not applicable
@@ -426,4 +438,108 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config)
qWarning("\n");
}
+#ifdef Q_OS_LINUX
+
+QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize)
+{
+ const int defaultPhysicalDpi = 100;
+ static QSizeF size;
+
+ if (size.isEmpty()) {
+ // Note: in millimeters
+ int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt();
+ int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt();
+
+ if (width && height) {
+ size.setWidth(width);
+ size.setHeight(height);
+ return size;
+ }
+
+ struct fb_var_screeninfo vinfo;
+ int w = -1;
+ int h = -1;
+ QSize screenResolution;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+ qWarning("eglconvenience: Could not query screen info");
+ } else {
+ w = vinfo.width;
+ h = vinfo.height;
+ screenResolution = QSize(vinfo.xres, vinfo.yres);
+ }
+ } else {
+ // Use the provided screen size, when available, since some platforms may have their own
+ // specific way to query it. Otherwise try querying it from the framebuffer.
+ screenResolution = screenSize.isEmpty() ? q_screenSizeFromFb(framebufferDevice) : screenSize;
+ }
+
+ size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
+ size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
+ }
+
+ return size;
+}
+
+QSize q_screenSizeFromFb(int framebufferDevice)
+{
+ const int defaultWidth = 800;
+ const int defaultHeight = 600;
+ static QSize size;
+
+ if (size.isEmpty()) {
+ int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt();
+ int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt();
+
+ if (width && height) {
+ size.setWidth(width);
+ size.setHeight(height);
+ return size;
+ }
+
+ struct fb_var_screeninfo vinfo;
+ int xres = -1;
+ int yres = -1;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
+ qWarning("eglconvenience: Could not read screen info");
+ } else {
+ xres = vinfo.xres;
+ yres = vinfo.yres;
+ }
+ }
+
+ size.setWidth(xres <= 0 ? defaultWidth : xres);
+ size.setHeight(yres <= 0 ? defaultHeight : yres);
+ }
+
+ return size;
+}
+
+int q_screenDepthFromFb(int framebufferDevice)
+{
+ const int defaultDepth = 32;
+ static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
+
+ if (depth == 0) {
+ struct fb_var_screeninfo vinfo;
+
+ if (framebufferDevice != -1) {
+ if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1)
+ qWarning("eglconvenience: Could not query screen info");
+ else
+ depth = vinfo.bits_per_pixel;
+ }
+
+ if (depth <= 0)
+ depth = defaultDepth;
+ }
+
+ return depth;
+}
+
+#endif // Q_OS_LINUX
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h
index 35c225cc2f..8616275e53 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience_p.h
+++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h
@@ -42,11 +42,11 @@
#ifndef QEGLCONVENIENCE_H
#define QEGLCONVENIENCE_H
-
#include <QtGui/QSurfaceFormat>
#include <QtCore/QVector>
-
+#include <QtCore/QSizeF>
#include <EGL/egl.h>
+
QT_BEGIN_NAMESPACE
QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format);
@@ -56,6 +56,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
void q_printEglConfig(EGLDisplay display, EGLConfig config);
+#ifdef Q_OS_UNIX
+QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize = QSize());
+QSize q_screenSizeFromFb(int framebufferDevice);
+int q_screenDepthFromFb(int framebufferDevice);
+#endif
+
class QEglConfigChooser
{
public:
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
index 919314e9aa..295f8756c4 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp
+++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
@@ -45,6 +45,18 @@
QT_BEGIN_NAMESPACE
+/*!
+ \class QEGLPbuffer
+ \brief A pbuffer-based implementation of QPlatformOffscreenSurface for EGL.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ To use this implementation in the platform plugin simply
+ reimplement QPlatformIntegration::createPlatformOffscreenSurface()
+ and return a new instance of this class.
+*/
+
QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
: QPlatformOffscreenSurface(offscreenSurface)
, m_format(format)
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
new file mode 100644
index 0000000000..24e9ccd39f
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QOpenGLContext>
+
+#include "qeglplatformbackingstore_p.h"
+#include "qeglcompositor_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformBackingStore
+ \brief A backing store implementation for EGL and GLES.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This implementation uploads raster-rendered widget windows into
+ textures and composites them onto a single native window using
+ QEGLCompositor. This means that multiple top-level widgets are
+ supported without creating actual native windows for each of them.
+
+ The class is ready to be used as-is, the default
+ QEGLPlatformIntegration::createPlatformBackingStore()
+ implementation creates an instance which is ready to be used
+ without further customization.
+
+ If QEGLCompositor is not suitable, this backing store
+ implementation can also be used without it. In this case a
+ subclass must reimplement composite() and schedule an update in
+ its custom compositor when this function is called. The textures
+ are accessible via QEGLPlatformWindow::texture().
+*/
+
+QEGLPlatformBackingStore::QEGLPlatformBackingStore(QWindow *window)
+ : QPlatformBackingStore(window),
+ m_window(static_cast<QEGLPlatformWindow *>(window->handle())),
+ m_bsTexture(0),
+ m_textures(new QPlatformTextureList),
+ m_lockedWidgetTextures(0)
+{
+ m_window->setBackingStore(this);
+}
+
+QEGLPlatformBackingStore::~QEGLPlatformBackingStore()
+{
+ delete m_textures;
+}
+
+QPaintDevice *QEGLPlatformBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QEGLPlatformBackingStore::updateTexture()
+{
+ if (!m_bsTexture) {
+ glGenTextures(1, &m_bsTexture);
+ glBindTexture(GL_TEXTURE_2D, m_bsTexture);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ // QOpenGLTextureBlitter requires GL_REPEAT for the time being
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_image.width(), m_image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ } else {
+ glBindTexture(GL_TEXTURE_2D, m_bsTexture);
+ }
+
+ if (!m_dirty.isNull()) {
+ QRegion fixed;
+ QRect imageRect = m_image.rect();
+
+ foreach (const QRect &rect, m_dirty.rects()) {
+ // intersect with image rect to be sure
+ QRect r = imageRect & rect;
+
+ // if the rect is wide enough it's cheaper to just
+ // extend it instead of doing an image copy
+ if (r.width() >= imageRect.width() / 2) {
+ r.setX(0);
+ r.setWidth(imageRect.width());
+ }
+
+ fixed |= r;
+ }
+
+ foreach (const QRect &rect, fixed.rects()) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's no gap between scanlines
+ if (rect.width() == imageRect.width()) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
+ }
+
+ m_dirty = QRegion();
+ }
+}
+
+void QEGLPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ // Called for ordinary raster windows. This is rare since RasterGLSurface
+ // support is claimed which leads to having all QWidget windows marked as
+ // RasterGLSurface instead of just Raster. These go through
+ // compositeAndFlush() instead of this function.
+
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
+ return;
+
+ screen->compositingContext()->makeCurrent(dstWin->window());
+ updateTexture();
+ m_textures->clear();
+ m_textures->appendTexture(m_bsTexture, window->geometry());
+ composite(screen->compositingContext(), dstWin);
+}
+
+void QEGLPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context)
+{
+ // QOpenGLWidget content provided as textures. The raster content should go on top.
+
+ Q_UNUSED(region);
+ Q_UNUSED(offset);
+ Q_UNUSED(context);
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || !dstWin->isRaster())
+ return;
+
+ screen->compositingContext()->makeCurrent(dstWin->window());
+
+ m_textures->clear();
+ for (int i = 0; i < textures->count(); ++i) {
+ uint textureId = textures->textureId(i);
+ QRect geom = textures->geometry(i);
+ m_textures->appendTexture(textureId, geom);
+ }
+
+ updateTexture();
+ m_textures->appendTexture(m_bsTexture, window->geometry());
+
+ textures->lock(true);
+ m_lockedWidgetTextures = textures;
+
+ composite(screen->compositingContext(), dstWin);
+}
+
+void QEGLPlatformBackingStore::composite(QOpenGLContext *context, QEGLPlatformWindow *window)
+{
+ QEGLCompositor::instance()->schedule(context, window);
+}
+
+void QEGLPlatformBackingStore::composited()
+{
+ if (m_lockedWidgetTextures) {
+ QPlatformTextureList *textureList = m_lockedWidgetTextures;
+ m_lockedWidgetTextures = 0; // may reenter so null before unlocking
+ textureList->lock(false);
+ }
+}
+
+void QEGLPlatformBackingStore::beginPaint(const QRegion &rgn)
+{
+ m_dirty |= rgn;
+}
+
+void QEGLPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(m_window->screen());
+ QEGLPlatformWindow *dstWin = screen->compositingWindow();
+ if (!dstWin || (!dstWin->isRaster() && dstWin->window()->surfaceType() != QSurface::RasterGLSurface))
+ return;
+
+ m_image = QImage(size, QImage::Format_RGB32);
+ m_window->create();
+
+ screen->compositingContext()->makeCurrent(dstWin->window());
+ if (m_bsTexture) {
+ glDeleteTextures(1, &m_bsTexture);
+ m_bsTexture = 0;
+ }
+}
+
+QImage QEGLPlatformBackingStore::toImage() const
+{
+ return m_image;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
new file mode 100644
index 0000000000..cb1e5999b0
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformbackingstore_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMBACKINGSTORE_H
+#define QEGLPLATFORMBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+
+#include <QImage>
+#include <QRegion>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLContext;
+class QPlatformTextureList;
+class QEGLPlatformWindow;
+
+class QEGLPlatformBackingStore : public QPlatformBackingStore
+{
+public:
+ QEGLPlatformBackingStore(QWindow *window);
+ ~QEGLPlatformBackingStore();
+
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
+
+ void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
+
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
+
+ QImage toImage() const Q_DECL_OVERRIDE;
+ void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context) Q_DECL_OVERRIDE;
+
+ const QPlatformTextureList *textures() const { return m_textures; }
+
+ virtual void composite(QOpenGLContext *context, QEGLPlatformWindow *window);
+
+ void composited();
+
+private:
+ void updateTexture();
+
+ QEGLPlatformWindow *m_window;
+ QImage m_image;
+ QRegion m_dirty;
+ uint m_bsTexture;
+ QPlatformTextureList *m_textures;
+ QPlatformTextureList *m_lockedWidgetTextures;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMBACKINGSTORE_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 716b01b4d9..3a34748fc7 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -40,12 +40,28 @@
****************************************************************************/
#include "qeglplatformcontext_p.h"
-
#include "qeglconvenience_p.h"
-
#include <qpa/qplatformwindow.h>
-
-#include <EGL/egl.h>
+#include <QtGui/QOpenGLFunctions>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformContext
+ \brief An EGL context implementation.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ Implement QPlatformOpenGLContext using EGL. To use it in platform
+ plugins a subclass must be created since
+ eglSurfaceForPlatformSurface() has to be reimplemented. This
+ function is used for mapping platform surfaces (windows) to EGL
+ surfaces and is necessary since different platform plugins may
+ have different ways of handling native windows (for example, a
+ plugin may choose not to back every platform window by a real EGL
+ surface). Other than that, no further customization is necessary.
+ */
static inline void bindApi(const QSurfaceFormat &format)
{
@@ -54,9 +70,12 @@ static inline void bindApi(const QSurfaceFormat &format)
eglBindAPI(EGL_OPENVG_API);
break;
#ifdef EGL_VERSION_1_4
-# if !defined(QT_OPENGL_ES_2)
case QSurfaceFormat::DefaultRenderableType:
-# endif
+ if (!QOpenGLFunctions::isES())
+ eglBindAPI(EGL_OPENGL_API);
+ else
+ eglBindAPI(EGL_OPENGL_ES_API);
+ break;
case QSurfaceFormat::OpenGL:
eglBindAPI(EGL_OPENGL_API);
break;
@@ -72,6 +91,9 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform
EGLenum eglApi)
: m_eglDisplay(display)
, m_eglConfig(q_configFromGLFormat(display, format))
+ , m_swapInterval(-1)
+ , m_swapIntervalEnvChecked(false)
+ , m_swapIntervalFromEnv(-1)
{
init(format, share);
Q_UNUSED(eglApi);
@@ -81,6 +103,9 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform
EGLConfig config, EGLenum eglApi)
: m_eglDisplay(display)
, m_eglConfig(config)
+ , m_swapInterval(-1)
+ , m_swapIntervalEnvChecked(false)
+ , m_swapIntervalFromEnv(-1)
{
init(format, share);
Q_UNUSED(eglApi);
@@ -106,11 +131,8 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
{
- Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface->surface()->supportsOpenGL());
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::makeCurrent: %p\n",this);
-#endif
bindApi(m_format);
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
@@ -145,14 +167,32 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
}
#endif
+
+ if (ok) {
+ if (!m_swapIntervalEnvChecked) {
+ m_swapIntervalEnvChecked = true;
+ if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) {
+ QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
+ bool ok;
+ const int swapInterval = swapIntervalString.toInt(&ok);
+ if (ok)
+ m_swapIntervalFromEnv = swapInterval;
+ }
+ }
+ const int requestedSwapInterval = m_swapIntervalFromEnv >= 0
+ ? m_swapIntervalFromEnv
+ : surface->format().swapInterval();
+ if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) {
+ m_swapInterval = requestedSwapInterval;
+ eglSwapInterval(eglDisplay(), m_swapInterval);
+ }
+ }
+
return ok;
}
QEGLPlatformContext::~QEGLPlatformContext()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::~QEglContext(): %p\n",this);
-#endif
if (m_eglContext != EGL_NO_CONTEXT) {
eglDestroyContext(m_eglDisplay, m_eglContext);
m_eglContext = EGL_NO_CONTEXT;
@@ -161,9 +201,6 @@ QEGLPlatformContext::~QEGLPlatformContext()
void QEGLPlatformContext::doneCurrent()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::doneCurrent:%p\n",this);
-#endif
bindApi(m_format);
bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!ok)
@@ -172,9 +209,6 @@ void QEGLPlatformContext::doneCurrent()
void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::swapBuffers:%p\n",this);
-#endif
bindApi(m_format);
EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
@@ -184,9 +218,6 @@ void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglContext::getProcAddress%p\n",this);
-#endif
bindApi(m_format);
return eglGetProcAddress(procName.constData());
}
@@ -210,3 +241,5 @@ EGLConfig QEGLPlatformContext::eglConfig() const
{
return m_eglConfig;
}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
index 7c05894246..d62082faa2 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -46,6 +46,8 @@
#include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
+QT_BEGIN_NAMESPACE
+
class QEGLPlatformContext : public QPlatformOpenGLContext
{
public:
@@ -79,6 +81,11 @@ private:
EGLDisplay m_eglDisplay;
EGLConfig m_eglConfig;
QSurfaceFormat m_format;
+ int m_swapInterval;
+ bool m_swapIntervalEnvChecked;
+ int m_swapIntervalFromEnv;
};
+QT_END_NAMESPACE
+
#endif //QEGLPLATFORMCONTEXT_H
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
index 0066426769..1c87e1d27d 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
@@ -39,19 +39,46 @@
**
****************************************************************************/
-#include "qeglfscursor.h"
#include <qpa/qwindowsysteminterface.h>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtDebug>
+#include <QtPlatformSupport/private/qdevicediscovery_p.h>
+
+#include "qeglplatformcursor_p.h"
+#include "qeglplatformintegration_p.h"
+
QT_BEGIN_NAMESPACE
-QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
- : m_screen(screen), m_program(0), m_vertexCoordEntry(0), m_textureCoordEntry(0), m_textureEntry(0)
+/*!
+ \class QEGLPlatformCursor
+ \brief Mouse cursor implementation using OpenGL.
+ \since 5.2
+ \internal
+ \ingroup qpa
+ */
+
+QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen)
+ : m_visible(true),
+ m_screen(screen),
+ m_program(0),
+ m_vertexCoordEntry(0),
+ m_textureCoordEntry(0),
+ m_textureEntry(0),
+ m_deviceListener(0)
{
+ QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
+ if (!hideCursorVal.isEmpty())
+ m_visible = hideCursorVal.toInt() == 0;
+ if (!m_visible)
+ return;
+
+ // Try to load the cursor atlas. If this fails, m_visible is set to false and
+ // paintOnScreen() and setCurrentCursor() become no-ops.
initCursorAtlas();
// initialize the cursor
@@ -61,15 +88,54 @@ QEglFSCursor::QEglFSCursor(QEglFSScreen *screen)
#endif
}
-QEglFSCursor::~QEglFSCursor()
+QEGLPlatformCursor::~QEGLPlatformCursor()
{
resetResources();
+ delete m_deviceListener;
+}
+
+void QEGLPlatformCursor::setMouseDeviceDiscovery(QDeviceDiscovery *dd)
+{
+ if (m_visible && dd) {
+ m_deviceListener = new QEGLPlatformCursorDeviceListener(dd, this);
+ updateMouseStatus();
+ }
+}
+
+void QEGLPlatformCursor::updateMouseStatus()
+{
+ m_visible = m_deviceListener->hasMouse();
+}
+
+QEGLPlatformCursorDeviceListener::QEGLPlatformCursorDeviceListener(QDeviceDiscovery *dd, QEGLPlatformCursor *cursor)
+ : m_cursor(cursor)
+{
+ m_mouseCount = dd->scanConnectedDevices().count();
+ connect(dd, SIGNAL(deviceDetected(QString)), SLOT(onDeviceAdded()));
+ connect(dd, SIGNAL(deviceRemoved(QString)), SLOT(onDeviceRemoved()));
+}
+
+bool QEGLPlatformCursorDeviceListener::hasMouse() const
+{
+ return m_mouseCount > 0;
+}
+
+void QEGLPlatformCursorDeviceListener::onDeviceAdded()
+{
+ ++m_mouseCount;
+ m_cursor->updateMouseStatus();
+}
+
+void QEGLPlatformCursorDeviceListener::onDeviceRemoved()
+{
+ --m_mouseCount;
+ m_cursor->updateMouseStatus();
}
-void QEglFSCursor::resetResources()
+void QEGLPlatformCursor::resetResources()
{
if (QOpenGLContext::currentContext()) {
- glDeleteProgram(m_program);
+ delete m_program;
glDeleteTextures(1, &m_cursor.customCursorTexture);
glDeleteTextures(1, &m_cursorAtlas.texture);
}
@@ -79,46 +145,7 @@ void QEglFSCursor::resetResources()
m_cursorAtlas.texture = 0;
}
-GLuint QEglFSCursor::createShader(GLenum shaderType, const char *program)
-{
- GLuint shader = glCreateShader(shaderType);
- glShaderSource(shader, 1 /* count */, &program, NULL /* lengths */);
- glCompileShader(shader);
- GLint status;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
- if (status == GL_TRUE)
- return shader;
-
- GLint length;
- glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetShaderInfoLog(shader, length, NULL, infoLog);
- qDebug("%s shader compilation error: %s", shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment", infoLog);
- delete [] infoLog;
- return 0;
-}
-
-GLuint QEglFSCursor::createProgram(GLuint vshader, GLuint fshader)
-{
- GLuint program = glCreateProgram();
- glAttachShader(program, vshader);
- glAttachShader(program, fshader);
- glLinkProgram(program);
- GLint status;
- glGetProgramiv(program, GL_LINK_STATUS, &status);
- if (status == GL_TRUE)
- return program;
-
- GLint length;
- glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
- char *infoLog = new char[length];
- glGetProgramInfoLog(program, length, NULL, infoLog);
- qDebug("program link error: %s", infoLog);
- delete [] infoLog;
- return 0;
-}
-
-void QEglFSCursor::createShaderPrograms()
+void QEGLPlatformCursor::createShaderPrograms()
{
static const char *textureVertexProgram =
"attribute highp vec2 vertexCoordEntry;\n"
@@ -136,18 +163,17 @@ void QEglFSCursor::createShaderPrograms()
" gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
"}\n";
- GLuint vertexShader = createShader(GL_VERTEX_SHADER, textureVertexProgram);
- GLuint fragmentShader = createShader(GL_FRAGMENT_SHADER, textureFragmentProgram);
- m_program = createProgram(vertexShader, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ m_program->link();
- m_vertexCoordEntry = glGetAttribLocation(m_program, "vertexCoordEntry");
- m_textureCoordEntry = glGetAttribLocation(m_program, "textureCoordEntry");
- m_textureEntry = glGetUniformLocation(m_program, "texture");
+ m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
+ m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
+ m_textureEntry = m_program->attributeLocation("texture");
}
-void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
+void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image)
{
if (!*texture)
glGenTextures(1, texture);
@@ -161,25 +187,29 @@ void QEglFSCursor::createCursorTexture(uint *texture, const QImage &image)
GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
}
-void QEglFSCursor::initCursorAtlas()
+void QEGLPlatformCursor::initCursorAtlas()
{
static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
if (json.isEmpty())
json = ":/cursor.json";
- QFile file(json);
- file.open(QFile::ReadOnly);
+ QFile file(QString::fromUtf8(json));
+ if (!file.open(QFile::ReadOnly)) {
+ m_visible = false;
+ return;
+ }
+
QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
QJsonObject object = doc.object();
- QString atlas = object.value("image").toString();
+ QString atlas = object.value(QLatin1String("image")).toString();
Q_ASSERT(!atlas.isEmpty());
- const int cursorsPerRow = object.value("cursorsPerRow").toDouble();
+ const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();
Q_ASSERT(cursorsPerRow);
m_cursorAtlas.cursorsPerRow = cursorsPerRow;
- const QJsonArray hotSpots = object.value("hotSpots").toArray();
+ const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray();
Q_ASSERT(hotSpots.count() == Qt::LastCursor);
for (int i = 0; i < hotSpots.count(); i++) {
QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());
@@ -195,7 +225,7 @@ void QEglFSCursor::initCursorAtlas()
}
#ifndef QT_NO_CURSOR
-void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
+void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window)
{
Q_UNUSED(window);
const QRect oldCursorRect = cursorRect();
@@ -203,8 +233,11 @@ void QEglFSCursor::changeCursor(QCursor *cursor, QWindow *window)
update(oldCursorRect | cursorRect());
}
-bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
+bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor)
{
+ if (!m_visible)
+ return false;
+
const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
return false;
@@ -237,30 +270,30 @@ bool QEglFSCursor::setCurrentCursor(QCursor *cursor)
}
#endif
-void QEglFSCursor::update(const QRegion &rgn)
+void QEGLPlatformCursor::update(const QRegion &rgn)
{
QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(m_cursor.pos), rgn);
QWindowSystemInterface::flushWindowSystemEvents();
}
-QRect QEglFSCursor::cursorRect() const
+QRect QEGLPlatformCursor::cursorRect() const
{
return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
}
-QPoint QEglFSCursor::pos() const
+QPoint QEGLPlatformCursor::pos() const
{
return m_cursor.pos;
}
-void QEglFSCursor::setPos(const QPoint &pos)
+void QEGLPlatformCursor::setPos(const QPoint &pos)
{
const QRect oldCursorRect = cursorRect();
m_cursor.pos = pos;
update(oldCursorRect | cursorRect());
}
-void QEglFSCursor::pointerEvent(const QMouseEvent &event)
+void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event)
{
if (event.type() != QEvent::MouseMove)
return;
@@ -269,8 +302,11 @@ void QEglFSCursor::pointerEvent(const QMouseEvent &event)
update(oldCursorRect | cursorRect());
}
-void QEglFSCursor::paintOnScreen()
+void QEGLPlatformCursor::paintOnScreen()
{
+ if (!m_visible)
+ return;
+
const QRectF cr = cursorRect();
const QRect screenRect(m_screen->geometry());
const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;
@@ -282,11 +318,10 @@ void QEglFSCursor::paintOnScreen()
draw(r);
}
-void QEglFSCursor::draw(const QRectF &r)
+void QEGLPlatformCursor::draw(const QRectF &r)
{
if (!m_program) {
// one time initialization
- initializeOpenGLFunctions();
createShaderPrograms();
if (!m_cursorAtlas.texture) {
@@ -306,7 +341,7 @@ void QEglFSCursor::draw(const QRectF &r)
Q_ASSERT(m_cursor.texture);
- glUseProgram(m_program);
+ m_program->bind();
const GLfloat x1 = r.left();
const GLfloat x2 = r.right();
@@ -332,13 +367,13 @@ void QEglFSCursor::draw(const QRectF &r)
glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
+ m_program->enableAttributeArray(m_vertexCoordEntry);
+ m_program->enableAttributeArray(m_textureCoordEntry);
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, cursorCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
+ m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2);
+ m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
- glUniform1i(m_textureEntry, 0);
+ m_program->setUniformValue(m_textureEntry, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -347,10 +382,10 @@ void QEglFSCursor::draw(const QRectF &r)
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
+ m_program->disableAttributeArray(m_textureCoordEntry);
+ m_program->disableAttributeArray(m_vertexCoordEntry);
- glUseProgram(0);
+ m_program->release();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscursor.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
index 71ff73b8f3..d1402d1457 100644
--- a/src/plugins/platforms/eglfs/qeglfscursor.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
@@ -39,49 +39,64 @@
**
****************************************************************************/
-#ifndef QEGLFSCURSOR_H
-#define QEGLFSCURSOR_H
+#ifndef QEGLPLATFORMCURSOR_H
+#define QEGLPLATFORMCURSOR_H
#include <qpa/qplatformcursor.h>
-#include <QtGui/QOpenGLFunctions>
-#include "qeglfsscreen.h"
+#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
class QOpenGLShaderProgram;
-class QEglFSScreen;
+class QDeviceDiscovery;
+class QEGLPlatformCursor;
-class QEglFSCursor : public QPlatformCursor, public QOpenGLFunctions
+class QEGLPlatformCursorDeviceListener : public QObject
+{
+ Q_OBJECT
+
+public:
+ QEGLPlatformCursorDeviceListener(QDeviceDiscovery *dd, QEGLPlatformCursor *cursor);
+ bool hasMouse() const;
+
+private slots:
+ void onDeviceAdded();
+ void onDeviceRemoved();
+
+private:
+ QEGLPlatformCursor *m_cursor;
+ int m_mouseCount;
+};
+
+class QEGLPlatformCursor : public QPlatformCursor
{
public:
- QEglFSCursor(QEglFSScreen *screen);
- ~QEglFSCursor();
+ QEGLPlatformCursor(QPlatformScreen *screen);
+ ~QEGLPlatformCursor();
#ifndef QT_NO_CURSOR
void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE;
#endif
void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
-
QPoint pos() const Q_DECL_OVERRIDE;
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
QRect cursorRect() const;
-
- virtual void paintOnScreen();
-
+ void paintOnScreen();
void resetResources();
-protected:
+ void setMouseDeviceDiscovery(QDeviceDiscovery *dd);
+ void updateMouseStatus();
+
+private:
#ifndef QT_NO_CURSOR
bool setCurrentCursor(QCursor *cursor);
#endif
void draw(const QRectF &rect);
void update(const QRegion &region);
-
- GLuint createShader(GLenum shaderType, const char *program);
- GLuint createProgram(GLuint vshader, GLuint fshader);
-
- QEglFSScreen *m_screen;
+ void createShaderPrograms();
+ static void createCursorTexture(uint *texture, const QImage &image);
+ void initCursorAtlas();
// current cursor information
struct Cursor {
@@ -97,11 +112,6 @@ protected:
bool customCursorPending;
} m_cursor;
-private:
- void createShaderPrograms();
- static void createCursorTexture(uint *texture, const QImage &image);
- void initCursorAtlas();
-
// cursor atlas information
struct CursorAtlas {
CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
@@ -113,13 +123,15 @@ private:
QImage image; // valid until it's uploaded
} m_cursorAtlas;
- GLuint m_program;
+ bool m_visible;
+ QPlatformScreen *m_screen;
+ QOpenGLShaderProgram *m_program;
int m_vertexCoordEntry;
int m_textureCoordEntry;
int m_textureEntry;
+ QEGLPlatformCursorDeviceListener *m_deviceListener;
};
QT_END_NAMESPACE
-#endif // QEGLFSCURSOR_H
-
+#endif // QEGLPLATFORMCURSOR_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
new file mode 100644
index 0000000000..a961035e22
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOffscreenSurface>
+#include <QtGui/QGuiApplication>
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
+
+#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixservices_p.h>
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtPlatformSupport/private/qfbvthandler_p.h>
+
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
+#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
+#include <QtPlatformSupport/private/qevdevtouch_p.h>
+#endif
+
+#include "qeglplatformintegration_p.h"
+#include "qeglplatformcontext_p.h"
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformbackingstore_p.h"
+#include "qeglplatformscreen_p.h"
+#include "qeglplatformcursor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformIntegration
+ \brief Base class for EGL-based QPlatformIntegration implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This class provides most of the necessary platform integration for
+ an EGL-based Unix system. Platform plugins must subclass this and
+ reimplement the virtuals for creating platform screens and windows
+ since they will most likely wish to use a subclass for these.
+
+ The backing store, native interface accessors, font database,
+ basic capability flags, etc. are provided out of the box, no
+ further customization is needed.
+
+ \note It is critical that this class' implementation of
+ initialize() is called. Therefore subclasses should either avoid
+ to reimplement this function or call the base class
+ implementation.
+ */
+
+QEGLPlatformIntegration::QEGLPlatformIntegration()
+ : m_screen(0),
+ m_display(EGL_NO_DISPLAY),
+ m_inputContext(0),
+ m_fontDb(new QGenericUnixFontDatabase),
+ m_services(new QGenericUnixServices)
+{
+}
+
+QEGLPlatformIntegration::~QEGLPlatformIntegration()
+{
+ delete m_screen;
+ if (m_display != EGL_NO_DISPLAY)
+ eglTerminate(m_display);
+}
+
+void QEGLPlatformIntegration::initialize()
+{
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ qFatal("Could not bind GL_ES API");
+
+ m_display = eglGetDisplay(nativeDisplay());
+ if (m_display == EGL_NO_DISPLAY)
+ qFatal("Could not open egl display");
+
+ EGLint major, minor;
+ if (!eglInitialize(m_display, &major, &minor))
+ qFatal("Could not initialize egl display");
+
+ m_screen = createScreen();
+ screenAdded(m_screen);
+
+ m_inputContext = QPlatformInputContextFactory::create();
+
+ m_vtHandler.reset(new QFbVtHandler);
+}
+
+QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const
+{
+ return createUnixEventDispatcher();
+}
+
+QPlatformServices *QEGLPlatformIntegration::services() const
+{
+ return m_services.data();
+}
+
+QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const
+{
+ return m_fontDb.data();
+}
+
+QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QEGLPlatformBackingStore(window);
+}
+
+QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const
+{
+ QWindowSystemInterface::flushWindowSystemEvents();
+ QEGLPlatformWindow *w = createWindow(window);
+ w->create();
+ if (window->type() != Qt::ToolTip)
+ w->requestActivateWindow();
+ return w;
+}
+
+QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(context->screen()->handle());
+ // If there is a "root" window into which raster and QOpenGLWidget content is
+ // composited, all other contexts must share with its context.
+ QOpenGLContext *compositingContext = screen ? screen->compositingContext() : 0;
+ return createContext(context->format(),
+ compositingContext ? compositingContext->handle() : context->shareHandle(),
+ display());
+}
+
+QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(surface->screen()->handle());
+ return createOffscreenSurface(screen->display(), surface->requestedFormat(), surface);
+}
+
+bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps: return true;
+ case OpenGL: return true;
+ case ThreadedOpenGL: return true;
+ case WindowManagement: return false;
+ case RasterGLSurface: return true;
+ default: return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const
+{
+ return const_cast<QEGLPlatformIntegration *>(this);
+}
+
+enum ResourceType {
+ EglDisplay,
+ EglWindow,
+ EglContext
+};
+
+static int resourceType(const QByteArray &key)
+{
+ static const QByteArray names[] = { // match ResourceType
+ QByteArrayLiteral("egldisplay"),
+ QByteArrayLiteral("eglwindow"),
+ QByteArrayLiteral("eglcontext")
+ };
+ const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
+ const QByteArray *result = std::find(names, end, key);
+ if (result == end)
+ result = std::find(names, end, key.toLower());
+ return int(result - names);
+}
+
+void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ result = m_screen->display();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglDisplay:
+ if (window && window->handle())
+ result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display();
+ else
+ result = m_screen->display();
+ break;
+ case EglWindow:
+ if (window && window->handle())
+ result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow());
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ void *result = 0;
+
+ switch (resourceType(resource)) {
+ case EglContext:
+ if (context->handle())
+ result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static void *eglContextForContext(QOpenGLContext *context)
+{
+ Q_ASSERT(context);
+
+ QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
+ if (!handle)
+ return 0;
+
+ return handle->eglContext();
+}
+
+QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "get_egl_context")
+ return NativeResourceForContextFunction(eglContextForContext);
+
+ return 0;
+}
+
+void QEGLPlatformIntegration::createInputHandlers()
+{
+#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
+ new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
+ QEvdevMouseManager *mouseMgr = new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens()) {
+ QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->handle()->cursor());
+ if (cursor)
+ cursor->setMouseDeviceDiscovery(mouseMgr->deviceDiscovery());
+ }
+ new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
new file mode 100644
index 0000000000..f665455383
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMINTEGRATION_H
+#define QEGLPLATFORMINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformnativeinterface.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEGLPlatformScreen;
+class QEGLPlatformWindow;
+class QEGLPlatformContext;
+class QFbVtHandler;
+
+class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
+{
+public:
+ QEGLPlatformIntegration();
+ ~QEGLPlatformIntegration();
+
+ void initialize() Q_DECL_OVERRIDE;
+
+ QEGLPlatformScreen *screen() const { return m_screen; }
+ EGLDisplay display() const { return m_display; }
+
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ // QPlatformNativeInterface
+ void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+
+protected:
+ virtual QEGLPlatformScreen *createScreen() const = 0;
+ virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
+ virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const = 0;
+ virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const = 0;
+
+ virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; }
+
+ void createInputHandlers();
+
+private:
+ QEGLPlatformScreen *m_screen;
+ EGLDisplay m_display;
+ QPlatformInputContext *m_inputContext;
+ QScopedPointer<QPlatformFontDatabase> m_fontDb;
+ QScopedPointer<QPlatformServices> m_services;
+ QScopedPointer<QFbVtHandler> m_vtHandler;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMINTEGRATION_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
new file mode 100644
index 0000000000..72e7f6a6df
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglcompositor_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformScreen
+ \brief Base class for EGL-based platform screen implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ This class provides a lightweight base for QPlatformScreen
+ implementations. It covers basic window stack management which is
+ necessary when compositing multiple raster (widget-based) windows
+ together into one single native surface.
+
+ Reimplementing the virtuals are essential when using
+ QEGLPlatformBackingStore. The context and the window returned from
+ these are the ones that are used when compositing the textures
+ generated from the raster (widget) based windows.
+
+ \note It is up to the QEGLPlatformWindow subclasses to use the
+ functions, like addWindow(), removeWindow(), etc., provided here.
+ */
+
+QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy)
+ : m_dpy(dpy)
+{
+}
+
+QEGLPlatformScreen::~QEGLPlatformScreen()
+{
+ QEGLCompositor::destroy();
+}
+
+void QEGLPlatformScreen::addWindow(QEGLPlatformWindow *window)
+{
+ if (!m_windows.contains(window)) {
+ m_windows.append(window);
+ topWindowChanged(window);
+ }
+}
+
+void QEGLPlatformScreen::removeWindow(QEGLPlatformWindow *window)
+{
+ m_windows.removeOne(window);
+ if (!m_windows.isEmpty())
+ topWindowChanged(m_windows.last());
+}
+
+void QEGLPlatformScreen::moveToTop(QEGLPlatformWindow *window)
+{
+ m_windows.removeOne(window);
+ m_windows.append(window);
+ topWindowChanged(window);
+}
+
+void QEGLPlatformScreen::changeWindowIndex(QEGLPlatformWindow *window, int newIdx)
+{
+ int idx = m_windows.indexOf(window);
+ if (idx != -1 && idx != newIdx) {
+ m_windows.move(idx, newIdx);
+ if (newIdx == m_windows.size() - 1)
+ topWindowChanged(m_windows.last());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
new file mode 100644
index 0000000000..d0d8a52a87
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMSCREEN_H
+#define QEGLPLATFORMSCREEN_H
+
+#include <QtCore/QList>
+#include <qpa/qplatformscreen.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLContext;
+class QEGLPlatformWindow;
+
+class QEGLPlatformScreen : public QPlatformScreen
+{
+public:
+ QEGLPlatformScreen(EGLDisplay dpy);
+ ~QEGLPlatformScreen();
+
+ QList<QEGLPlatformWindow *> windows() const { return m_windows; }
+
+ void addWindow(QEGLPlatformWindow *window);
+ void removeWindow(QEGLPlatformWindow *window);
+ void moveToTop(QEGLPlatformWindow *window);
+ void changeWindowIndex(QEGLPlatformWindow *window, int newIdx);
+
+ virtual void topWindowChanged(QEGLPlatformWindow *window) { Q_UNUSED(window); }
+
+ EGLDisplay display() const { return m_dpy; }
+
+ virtual QEGLPlatformWindow *compositingWindow() = 0;
+ virtual QOpenGLContext *compositingContext() = 0;
+
+private:
+ QList<QEGLPlatformWindow *> m_windows;
+ EGLDisplay m_dpy;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMSCREEN_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
new file mode 100644
index 0000000000..e9b79512ba
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include "qeglplatformwindow_p.h"
+#include "qeglplatformbackingstore_p.h"
+#include "qeglplatformscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QEGLPlatformWindow
+ \brief Base class for EGL-based platform window implementations.
+ \since 5.2
+ \internal
+ \ingroup qpa
+
+ Lightweight class providing some basic platform window operations
+ and interfacing with QEGLPlatformBackingStore.
+
+ Almost no QPlatformWindow functions are implemented here. This is
+ intentional because different platform plugins may use different
+ strategies for their window management (some may force fullscreen
+ windows, some may not, some may share the underlying native
+ surface, some may not, etc.) and therefore it is not sensible to
+ enforce anything for these functions.
+
+ \note Subclasses are responsible for invoking this class'
+ implementation of create(). When using QEGLPlatformScreen, the
+ subclasses of this class are expected to utilize the window stack
+ management functions (addWindow() etc.) provided there.
+ */
+
+QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w)
+ : QPlatformWindow(w),
+ m_winId(0)
+{
+}
+
+static WId newWId()
+{
+ static WId id = 0;
+
+ if (id == std::numeric_limits<WId>::max())
+ qWarning("QEGLPlatformWindow: Out of window IDs");
+
+ return ++id;
+}
+
+void QEGLPlatformWindow::create()
+{
+ m_winId = newWId();
+
+ // Save the original surface type before changing to OpenGLSurface.
+ m_raster = (window()->surfaceType() == QSurface::RasterSurface);
+ if (m_raster) // change to OpenGL, but not for RasterGLSurface
+ window()->setSurfaceType(QSurface::OpenGLSurface);
+
+ if (window()->type() == Qt::Desktop) {
+ QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
+ QPlatformWindow::setGeometry(fullscreenRect);
+ QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
+ return;
+ }
+}
+
+bool QEGLPlatformWindow::isRaster() const
+{
+ return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
+}
+
+const QPlatformTextureList *QEGLPlatformWindow::textures() const
+{
+ if (m_backingStore)
+ return m_backingStore->textures();
+
+ return 0;
+}
+
+void QEGLPlatformWindow::composited()
+{
+ if (m_backingStore)
+ m_backingStore->composited();
+}
+
+WId QEGLPlatformWindow::winId() const
+{
+ return m_winId;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
new file mode 100644
index 0000000000..17a1d07a79
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLPLATFORMWINDOW_H
+#define QEGLPLATFORMWINDOW_H
+
+#include <qpa/qplatformwindow.h>
+#include <EGL/egl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QEGLPlatformBackingStore;
+class QPlatformTextureList;
+
+class QEGLPlatformWindow : public QPlatformWindow
+{
+public:
+ QEGLPlatformWindow(QWindow *w);
+
+ virtual void create();
+
+ QEGLPlatformBackingStore *backingStore() { return m_backingStore; }
+ void setBackingStore(QEGLPlatformBackingStore *backingStore) { m_backingStore = backingStore; }
+ const QPlatformTextureList *textures() const;
+ void composited();
+ bool isRaster() const;
+
+ WId winId() const Q_DECL_OVERRIDE;
+
+ virtual EGLNativeWindowType eglWindow() const = 0;
+
+private:
+ QEGLPlatformBackingStore *m_backingStore;
+ bool m_raster;
+ WId m_winId;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLPLATFORMWINDOW_H
diff --git a/src/platformsupport/fbconvenience/fbconvenience.pri b/src/platformsupport/fbconvenience/fbconvenience.pri
index 6ccaa50af5..4634f57fb4 100644
--- a/src/platformsupport/fbconvenience/fbconvenience.pri
+++ b/src/platformsupport/fbconvenience/fbconvenience.pri
@@ -1,10 +1,11 @@
SOURCES += $$PWD/qfbscreen.cpp \
$$PWD/qfbbackingstore.cpp \
$$PWD/qfbwindow.cpp \
- $$PWD/qfbcursor.cpp
+ $$PWD/qfbcursor.cpp \
+ $$PWD/qfbvthandler.cpp
HEADERS += $$PWD/qfbscreen_p.h \
$$PWD/qfbbackingstore_p.h \
$$PWD/qfbwindow_p.h \
- $$PWD/qfbcursor_p.h
-
+ $$PWD/qfbcursor_p.h \
+ $$PWD/qfbvthandler_p.h
diff --git a/src/plugins/platforms/kms/qkmsvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp
index 5e5afd3161..edfd13d9bf 100644
--- a/src/plugins/platforms/kms/qkmsvthandler.cpp
+++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,11 +39,17 @@
**
****************************************************************************/
-#include <qkmsvthandler.h>
+#include "qfbvthandler_p.h"
#include <QtCore/private/qcrashhandler_p.h>
#include <QtGui/private/qguiapplication_p.h>
+
+#if defined(Q_OS_LINUX) && !defined(QT_NO_EVDEV)
+#define HAS_VT
+#endif
+
+#ifdef HAS_VT
+
#include <sys/ioctl.h>
-#include <linux/vt.h>
#include <linux/kd.h>
#ifdef K_OFF
@@ -52,46 +58,51 @@
#define KBD_OFF_MODE K_RAW
#endif
+#endif // HAS_VT
+
QT_BEGIN_NAMESPACE
-QKmsVTHandler *QKmsVTHandler::self = 0;
+QFbVtHandler *QFbVtHandler::self = 0;
-QKmsVTHandler::QKmsVTHandler(QObject *parent)
+QFbVtHandler::QFbVtHandler(QObject *parent)
: QObject(parent), m_tty(-1)
{
Q_ASSERT(!self);
self = this;
+#ifdef HAS_VT
if (!isatty(0))
return;
m_tty = 0;
-
- ioctl(m_tty, KDGKBMODE, &m_oldKbdMode);
- if (!qgetenv("QT_KMS_TTYKBD").toInt()) {
- ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE);
+ ::ioctl(m_tty, KDGKBMODE, &m_oldKbdMode);
+ if (!qgetenv("QT_QPA_ENABLE_TERMINAL_KEYBOARD").toInt()) {
+ ::ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE);
QGuiApplicationPrivate *appd = QGuiApplicationPrivate::instance();
Q_ASSERT(appd);
QSegfaultHandler::initialize(appd->argv, appd->argc);
QSegfaultHandler::installCrashHandler(crashHandler);
}
+#endif
}
-QKmsVTHandler::~QKmsVTHandler()
+QFbVtHandler::~QFbVtHandler()
{
self->cleanup();
self = 0;
}
-void QKmsVTHandler::cleanup()
+void QFbVtHandler::cleanup()
{
if (m_tty == -1)
return;
- ioctl(m_tty, KDSKBMODE, m_oldKbdMode);
+#ifdef HAS_VT
+ ::ioctl(m_tty, KDSKBMODE, m_oldKbdMode);
+#endif
}
-void QKmsVTHandler::crashHandler()
+void QFbVtHandler::crashHandler()
{
Q_ASSERT(self);
self->cleanup();
diff --git a/src/plugins/platforms/kms/qkmsvthandler.h b/src/platformsupport/fbconvenience/qfbvthandler_p.h
index 8c4f511bc8..d98cd5a9d1 100644
--- a/src/plugins/platforms/kms/qkmsvthandler.h
+++ b/src/platformsupport/fbconvenience/qfbvthandler_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,26 +39,26 @@
**
****************************************************************************/
-#ifndef QKMSVTHANDLER_H
-#define QKMSVTHANDLER_H
+#ifndef QFBVTHANDLER_H
+#define QFBVTHANDLER_H
#include <QObject>
QT_BEGIN_NAMESPACE
-class QKmsVTHandler : public QObject
+class QFbVtHandler : public QObject
{
Q_OBJECT
public:
- QKmsVTHandler(QObject *parent = 0);
- ~QKmsVTHandler();
+ QFbVtHandler(QObject *parent = 0);
+ ~QFbVtHandler();
private:
void cleanup();
static void crashHandler();
- static QKmsVTHandler *self;
+ static QFbVtHandler *self;
int m_tty;
int m_oldKbdMode;
};
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 33f3601b97..1ed5ede3e8 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -113,27 +113,18 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
-QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *usrPtr)
+QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
- QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
- engine = new QFontEngineFT(fontDef);
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
QFontEngineFT::GlyphFormat format = antialias? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (!engine->supportsScript(script)) {
- qWarning(" OpenType support missing for script %d", int(script));
+
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+ if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
}
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
index 4d6fd2ceeb..45d7218ece 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
@@ -58,7 +58,7 @@ class QBasicFontDatabase : public QPlatformFontDatabase
{
public:
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 8c3ca2d229..8b16e7520a 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -69,21 +69,52 @@ static inline bool requiresOpenType(int writingSystem)
|| writingSystem == QFontDatabase::Khmer || writingSystem == QFontDatabase::Nko);
}
-static int getFCWeight(int fc_weight)
+static inline int weightFromFcWeight(int fcweight)
{
- int qtweight = QFont::Black;
- if (fc_weight <= (FC_WEIGHT_LIGHT + FC_WEIGHT_REGULAR) / 2)
- qtweight = QFont::Light;
- else if (fc_weight <= (FC_WEIGHT_REGULAR + FC_WEIGHT_MEDIUM) / 2)
- qtweight = QFont::Normal;
- else if (fc_weight <= (FC_WEIGHT_MEDIUM + FC_WEIGHT_BOLD) / 2)
- qtweight = QFont::DemiBold;
- else if (fc_weight <= (FC_WEIGHT_BOLD + FC_WEIGHT_BLACK) / 2)
- qtweight = QFont::Bold;
+ // Font Config uses weights from 0 to 215 (the highest enum value) while QFont ranges from
+ // 0 to 99. The spacing between the values for the enums are uneven so a linear mapping from
+ // Font Config values to Qt would give surprising results. So, we do a piecewise linear
+ // mapping. This ensures that where there is a corresponding enum on both sides (for example
+ // FC_WEIGHT_DEMIBOLD and QFont::DemiBold) we map one to the other but other values map
+ // to intermediate Qt weights.
+ const int maxWeight = 99;
+ int qtweight;
+ if (fcweight < 0)
+ qtweight = 0;
+ else if (fcweight <= FC_WEIGHT_LIGHT)
+ qtweight = (fcweight * QFont::Light) / FC_WEIGHT_LIGHT;
+ else if (fcweight <= FC_WEIGHT_NORMAL)
+ qtweight = QFont::Light + ((fcweight - FC_WEIGHT_LIGHT) * (QFont::Normal - QFont::Light)) / (FC_WEIGHT_NORMAL - FC_WEIGHT_LIGHT);
+ else if (fcweight <= FC_WEIGHT_DEMIBOLD)
+ qtweight = QFont::Normal + ((fcweight - FC_WEIGHT_NORMAL) * (QFont::DemiBold - QFont::Normal)) / (FC_WEIGHT_DEMIBOLD - FC_WEIGHT_NORMAL);
+ else if (fcweight <= FC_WEIGHT_BOLD)
+ qtweight = QFont::DemiBold + ((fcweight - FC_WEIGHT_DEMIBOLD) * (QFont::Bold - QFont::DemiBold)) / (FC_WEIGHT_BOLD - FC_WEIGHT_DEMIBOLD);
+ else if (fcweight <= FC_WEIGHT_BLACK)
+ qtweight = QFont::Bold + ((fcweight - FC_WEIGHT_BOLD) * (QFont::Black - QFont::Bold)) / (FC_WEIGHT_BLACK - FC_WEIGHT_BOLD);
+ else if (fcweight <= FC_WEIGHT_ULTRABLACK)
+ qtweight = QFont::Black + ((fcweight - FC_WEIGHT_BLACK) * (maxWeight - QFont::Black)) / (FC_WEIGHT_ULTRABLACK - FC_WEIGHT_BLACK);
+ else
+ qtweight = maxWeight;
return qtweight;
}
+static inline int stretchFromFcWidth(int fcwidth)
+{
+ // Font Config enums for width match pretty closely with those used by Qt so just use
+ // Font Config values directly while enforcing the same limits imposed by QFont.
+ const int maxStretch = 4000;
+ int qtstretch;
+ if (fcwidth < 1)
+ qtstretch = 1;
+ else if (fcwidth > maxStretch)
+ qtstretch = maxStretch;
+ else
+ qtstretch = fcwidth;
+
+ return qtstretch;
+}
+
static const char *specialLanguages[] = {
"", // Unknown
"", // Inherited
@@ -300,15 +331,14 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
-void QFontconfigDatabase::populateFontDatabase()
+static void populateFromPattern(FcPattern *pattern)
{
- FcFontSet *fonts;
-
QString familyName;
FcChar8 *value = 0;
int weight_value;
int slant_value;
int spacing_value;
+ int width_value;
FcChar8 *file_value;
int indexValue;
FcChar8 *foundry_value;
@@ -316,13 +346,117 @@ void QFontconfigDatabase::populateFontDatabase()
FcBool scalable;
FcBool antialias;
+ if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
+ return;
+
+ familyName = QString::fromUtf8((const char *)value);
+
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_REGULAR;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_REGULAR;
+ if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
+ width_value = FC_WIDTH_NORMAL;
+ if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
+ style_value = 0;
+ if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ bool hasLang = false;
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j));
+ hasLang = true;
+ }
+ }
+ }
+ if (!hasLang)
+ // none of our known languages, add it to the other set
+ writingSystems.setSupported(QFontDatabase::Other);
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ // Note: weight should really be an int but registerFont incorrectly uses an enum
+ QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
+
+ double pixel_size = 0;
+ if (!scalable)
+ FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ bool fixedPitch = spacing_value >= FC_MONO;
+ // Note: stretch should really be an int but registerFont incorrectly uses an enum
+ QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
+ QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
+ QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+
+ for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
+
+}
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcInitReinitialize();
+ FcFontSet *fonts;
+
{
FcObjectSet *os = FcObjectSetCreate();
FcPattern *pattern = FcPatternCreate();
const char *properties [] = {
FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT,
FC_SPACING, FC_FILE, FC_INDEX,
- FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT,
+ FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
FC_WIDTH,
#if FC_VERSION >= 20297
FC_CAPABILITY,
@@ -339,102 +473,8 @@ void QFontconfigDatabase::populateFontDatabase()
FcPatternDestroy(pattern);
}
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_REGULAR;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_REGULAR;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
- if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- bool hasLang = false;
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang) {
- writingSystems.setSupported(QFontDatabase::WritingSystem(j));
- hasLang = true;
- }
- }
- }
- if (!hasLang)
- // none of our known languages, add it to the other set
- writingSystems.setSupported(QFontDatabase::Other);
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- QFont::Weight weight = QFont::Weight(getFCWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable) {
- int width = 100;
- FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width);
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
- }
-
- bool fixedPitch = spacing_value >= FC_MONO;
- QFont::Stretch stretch = QFont::Unstretched;
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
-
- for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
- QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
- }
+ for (int i = 0; i < fonts->nfont; i++)
+ populateFromPattern(fonts->fonts[i]);
FcFontSetDestroy (fonts);
@@ -476,20 +516,18 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
return new QFontEngineMultiFontConfig(fontEngine, script);
}
-QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
+QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
if (!usrPtr)
return 0;
QFontDef fontDef = f;
- QFontEngineFT *engine;
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
QFontEngine::FaceId fid;
fid.filename = QFile::encodeName(fontfile->fileName);
fid.index = fontfile->indexValue;
bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
- engine = new QFontEngineFT(fontDef);
QFontEngineFT::GlyphFormat format;
// try and get the pattern
@@ -509,8 +547,24 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
FcPatternAdd(pattern,FC_INDEX,value,true);
FcResult result;
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
FcPattern *match = FcFontMatch(0, pattern, &result);
+
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+
if (match) {
+ //Respect the file and index of the font config match
+ FcChar8 *file_value;
+ int indexValue;
+
+ if (FcPatternGetString(match, FC_FILE, 0, &file_value) == FcResultMatch)
+ fid.filename = (const char *)file_value;
+ if (FcPatternGetInteger(match, FC_INDEX, 0, &indexValue) == FcResultMatch)
+ fid.index = indexValue;
+
QFontEngineFT::HintStyle default_hint_style;
if (f.hintingPreference != QFont::PreferDefaultHinting) {
switch (f.hintingPreference) {
@@ -587,25 +641,18 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, QChar::Script sc
format = subpixelType == QFontEngineFT::Subpixel_None
? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
engine->subpixelType = subpixelType;
- } else
+ } else {
format = QFontEngineFT::Format_Mono;
+ }
FcPatternDestroy(match);
- } else
+ } else {
format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ }
FcPatternDestroy(pattern);
- if (!engine->init(fid,antialias,format)) {
- delete engine;
- engine = 0;
- return engine;
- }
- if (engine->invalid()) {
- delete engine;
- engine = 0;
- } else if (!engine->supportsScript(script)) {
- qWarning(" OpenType support missing for script %d", int(script));
+ if (!engine->init(fid, antialias, format) || engine->invalid()) {
delete engine;
engine = 0;
}
@@ -715,6 +762,7 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
QStringList families;
+
FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
if (!set) {
FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
@@ -727,28 +775,24 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcBlanks *blanks = FcConfigGetBlanks(0);
int count = 0;
- FcPattern *pattern = 0;
+ FcPattern *pattern;
do {
pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
fontData, id, blanks, &count);
if (!pattern)
return families;
- FcPatternDel(pattern, FC_FILE);
- QByteArray cs = fileName.toUtf8();
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
-
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
}
+ populateFromPattern(pattern);
- if (!FcFontSetAdd(set, pattern))
- return families;
+ FcFontSetAdd(set, pattern);
++id;
- } while (pattern && id < count);
+ } while (id < count);
return families;
}
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index 6d6dae680e..9f1fd28144 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -52,7 +52,7 @@ class QFontconfigDatabase : public QBasicFontDatabase
public:
void populateFontDatabase();
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
QString resolveFontFamilyAlias(const QString &family) const;
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 38c44e3f35..ab2e9c1f1a 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -278,10 +278,8 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
-QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, QChar::Script script, void *usrPtr)
+QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
- Q_UNUSED(script);
-
qreal scaledPointSize = f.pixelSize;
// When 96 DPI is forced, the Mac plugin will use DPI 72 for some
@@ -474,104 +472,120 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
return fallbackLists[styleLookupKey.arg(styleHint)];
}
-#ifdef Q_OS_MACX
+#if HAVE_CORETEXT
+static CFArrayRef createDescriptorArrayForFont(CTFontRef font)
+{
+ CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(array, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ return array;
+}
+#endif
+
QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- CTFontRef font = NULL;
+ QCFType<CFArrayRef> fonts;
+ QStringList families;
+#if HAVE_CORETEXT
+ if (&CTFontManagerRegisterGraphicsFont) {
+ CFErrorRef error = 0;
if (!fontData.isEmpty()) {
QByteArray* fontDataCopy = new QByteArray(fontData);
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
- CGFontRef cgFont = CGFontCreateWithDataProvider(dataProvider);
+ QCFType<CGFontRef> cgFont = CGFontCreateWithDataProvider(dataProvider);
if (cgFont) {
- CFErrorRef error;
- bool success = CTFontManagerRegisterGraphicsFont(cgFont, &error);
- if (success) {
- font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
- m_applicationGraphicsFonts.append(QCFType<CGFontRef>::constructFromGet(cgFont));
- } else {
- NSLog(@"Unable to register font: %@", error);
- CFRelease(error);
+ if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
+ QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
+ fonts = createDescriptorArrayForFont(font);
+ m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
}
- CGFontRelease(cgFont);
}
} else {
- CFErrorRef error;
QCFType<CFURLRef> fontURL = CFURLCreateWithFileSystemPath(NULL, QCFString(fileName), kCFURLPOSIXPathStyle, false);
- bool success = CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error);
- if (success) {
- const void *keys[] = { kCTFontURLAttribute };
- const void *values[] = { fontURL };
- QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(NULL, keys, values, 1,
- &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
- font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
- m_applicationURLFonts.append(QCFType<CFURLRef>::constructFromGet(fontURL));
- } else {
- NSLog(@"Unable to register font: %@", error);
- CFRelease(error);
+ if (CTFontManagerRegisterFontsForURL(fontURL, kCTFontManagerScopeProcess, &error)) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_6, __IPHONE_7_0)
+ if (&CTFontManagerCreateFontDescriptorsFromURL)
+ fonts = CTFontManagerCreateFontDescriptorsFromURL(fontURL);
+ else
+#endif
+ {
+ // We're limited to a single font per file, unless we dive into the font tables
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
+ QCFType<CTFontDescriptorRef> descriptor = CTFontDescriptorCreateWithAttributes(attributes);
+ QCFType<CTFontRef> font = CTFontCreateWithFontDescriptor(descriptor, 0.0, NULL);
+ fonts = createDescriptorArrayForFont(font);
+ }
+
+ m_applicationFonts.append(QVariant::fromValue(QCFType<CFURLRef>::constructFromGet(fontURL)));
}
}
- if (font) {
- QStringList families;
- families.append(QCFString(CTFontCopyFamilyName(font)));
-
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
- populateFromDescriptor(descriptor);
-
- CFRelease(font);
- return families;
+ if (error) {
+ NSLog(@"Unable to register font: %@", error);
+ CFRelease(error);
}
- } else
+ }
+#endif
+#if HAVE_CORETEXT && HAVE_ATS
+ else
#endif
+#if HAVE_ATS
{
- ATSFontContainerRef fontContainer;
- OSStatus e;
+ ATSFontContainerRef fontContainer;
+ OSStatus e;
- if (!fontData.isEmpty()) {
- e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
- kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
- kATSOptionFlagsDefault, &fontContainer);
- } else {
- FSRef ref;
- OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
- if (qt_mac_create_fsref(fileName, &ref) != noErr)
- return QStringList();
- e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
- kATSOptionFlagsDefault, &fontContainer);
- }
-
- if (e == noErr) {
- ItemCount fontCount = 0;
- e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount);
- if (e != noErr)
- return QStringList();
-
- QVarLengthArray<ATSFontRef> containedFonts(fontCount);
- e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
- if (e != noErr)
- return QStringList();
-
- QStringList families;
- for (int i = 0; i < containedFonts.size(); ++i) {
- QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
- QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
- populateFromDescriptor(descriptor);
- families.append(QCFString(CTFontCopyFamilyName(font)));
+ if (!fontData.isEmpty()) {
+ e = ATSFontActivateFromMemory((void *) fontData.constData(), fontData.size(),
+ kATSFontContextLocal, kATSFontFormatUnspecified, NULL,
+ kATSOptionFlagsDefault, &fontContainer);
+ } else {
+ FSRef ref;
+ OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
+ if (qt_mac_create_fsref(fileName, &ref) != noErr)
+ return QStringList();
+ e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
+ kATSOptionFlagsDefault, &fontContainer);
}
- m_applicationFonts.append(fontContainer);
- return families;
+ if (e == noErr) {
+ ItemCount fontCount = 0;
+ e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, 0, 0, &fontCount);
+ if (e != noErr)
+ return QStringList();
+
+ QVarLengthArray<ATSFontRef> containedFonts(fontCount);
+ e = ATSFontFindFromContainer(fontContainer, kATSOptionFlagsDefault, fontCount, containedFonts.data(), &fontCount);
+ if (e != noErr)
+ return QStringList();
+
+ CFMutableArrayRef fontsArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ for (int i = 0; i < containedFonts.size(); ++i) {
+ QCFType<CTFontRef> font = CTFontCreateWithPlatformFont(containedFonts[i], 12.0, NULL, NULL);
+ CFArrayAppendValue(fontsArray, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ }
+
+ fonts = fontsArray;
+
+ m_applicationFonts.append(QVariant::fromValue(fontContainer));
+ }
}
+#endif
+
+ if (fonts) {
+ const int numFonts = CFArrayGetCount(fonts);
+ for (int i = 0; i < numFonts; ++i) {
+ CTFontDescriptorRef fontDescriptor = CTFontDescriptorRef(CFArrayGetValueAtIndex(fonts, i));
+ populateFromDescriptor(fontDescriptor);
+ QCFType<CFStringRef> familyName = CFStringRef(CTFontDescriptorCopyLocalizedAttribute(fontDescriptor, kCTFontFamilyNameAttribute, NULL));
+ families.append(QCFString(familyName));
+ }
}
- return QStringList();
+ return families;
}
-#endif
QFont QCoreTextFontDatabase::defaultFont() const
{
@@ -596,25 +610,31 @@ QList<int> QCoreTextFontDatabase::standardSizes() const
void QCoreTextFontDatabase::removeApplicationFonts()
{
-#ifdef Q_OS_MACX
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8) {
- CFErrorRef error;
- for (int i = 0; i < m_applicationGraphicsFonts.count(); ++i)
- CTFontManagerUnregisterGraphicsFont(m_applicationGraphicsFonts[i], &error);
- m_applicationGraphicsFonts.clear();
-
- for (int i = 0; i < m_applicationURLFonts.count(); ++i)
- CTFontManagerUnregisterFontsForURL(m_applicationURLFonts[i], kCTFontManagerScopeProcess, &error);
- m_applicationURLFonts.clear();
- } else
+ foreach (const QVariant &font, m_applicationFonts) {
+#if HAVE_CORETEXT
+ if (&CTFontManagerUnregisterGraphicsFont && &CTFontManagerUnregisterFontsForURL) {
+ CFErrorRef error;
+ if (font.canConvert(qMetaTypeId<QCFType<CGFontRef> >())) {
+ CTFontManagerUnregisterGraphicsFont(font.value<QCFType<CGFontRef> >(), &error);
+ } else if (font.canConvert(qMetaTypeId<QCFType<CFURLRef> >())) {
+ CTFontManagerUnregisterFontsForURL(font.value<QCFType<CFURLRef> >(), kCTFontManagerScopeProcess, &error);
+ }
+ }
#endif
- {
- for (int i = 0; i < m_applicationFonts.count(); ++i)
- ATSFontDeactivate(m_applicationFonts[i], 0, kATSOptionFlagsDoNotNotify);
+#if HAVE_CORETEXT && HAVE_ATS
+ else
+#endif
+#if HAVE_ATS
+ if (font.canConvert(qMetaTypeId<ATSFontContainerRef>())) {
+ ATSFontDeactivate(font.value<ATSFontContainerRef>(), 0, kATSOptionFlagsDoNotNotify);
+ }
+#endif
+ }
+
m_applicationFonts.clear();
+
+#if HAVE_ATS
ATSFontNotify(kATSFontNotifyActionFontsChanged, 0);
- }
#endif
}
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index ee1016509b..1560d36644 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -42,6 +42,10 @@
#ifndef QCORETEXTFONTDATABASE_H
#define QCORETEXTFONTDATABASE_H
+#include <qglobal.h>
+#define HAVE_CORETEXT QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_8, __IPHONE_4_1)
+#define HAVE_ATS QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_5, __IPHONE_NA)
+
#include <qpa/qplatformfontdatabase.h>
#include <private/qcore_mac_p.h>
@@ -52,6 +56,14 @@
#include <CoreGraphics/CoreGraphics.h>
#endif
+#if HAVE_CORETEXT
+Q_DECLARE_METATYPE(QCFType<CGFontRef>);
+Q_DECLARE_METATYPE(QCFType<CFURLRef>);
+#endif
+#if HAVE_ATS
+Q_DECLARE_METATYPE(ATSFontContainerRef);
+#endif
+
QT_BEGIN_NAMESPACE
class QCoreTextFontDatabase : public QPlatformFontDatabase
@@ -60,12 +72,10 @@ public:
QCoreTextFontDatabase();
~QCoreTextFontDatabase();
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
-#ifdef Q_OS_MACX
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
-#endif
void releaseHandle(void *handle);
QFont defaultFont() const;
QList<int> standardSizes() const;
@@ -78,13 +88,8 @@ private:
mutable QHash<QString, QString> familyNameToPsName;
void removeApplicationFonts();
-#ifdef Q_OS_MACX
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
- QVector<QCFType<CGFontRef> > m_applicationGraphicsFonts;
- QVector<QCFType<CFURLRef> > m_applicationURLFonts;
-#endif
- QVector<ATSFontContainerRef> m_applicationFonts;
-#endif
+
+ QVector<QVariant> m_applicationFonts;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 9b8f10f588..31a015ae9f 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -63,15 +63,12 @@ static void loadAdvancesForGlyphs(CTFontRef ctfont,
for (int i = 0; i < len; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
+ glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < len; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
+ for (int i = 0; i < len; ++i)
+ glyphs->advances[i] = glyphs->advances[i].round();
}
}
@@ -191,6 +188,8 @@ void QCoreTextFontEngine::init()
avgCharWidth = QFontEngine::averageCharWidth();
cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
+
+ setUserData(QVariant::fromValue((void *)cgFont));
}
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
@@ -228,15 +227,12 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *
for (int i = 0; i < glyph_pos; ++i) {
if (glyphs->glyphs[i] & 0xff000000)
continue;
- glyphs->advances_x[i] = QFixed::fromReal(advances[i].width);
- glyphs->advances_y[i] = QFixed::fromReal(advances[i].height);
+ glyphs->advances[i] = QFixed::fromReal(advances[i].width);
}
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
- for (int i = 0; i < glyph_pos; ++i) {
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
- glyphs->advances_y[i] = glyphs->advances_y[i].round();
- }
+ for (int i = 0; i < glyph_pos; ++i)
+ glyphs->advances[i] = glyphs->advances[i].round();
}
return true;
}
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
index 11d9377db7..4630b12a57 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience.cpp
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -39,6 +39,10 @@
**
****************************************************************************/
+// We have to include this before the X11 headers dragged in by
+// qglxconvenience_p.h.
+#include <QtCore/QByteArray>
+
#include "qglxconvenience_p.h"
#include <QtCore/QVector>
@@ -116,6 +120,27 @@ QVector<int> qglx_buildSpec(const QSurfaceFormat &format, int drawableBit)
GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat &format, int drawableBit)
{
+ // Allow forcing LIBGL_ALWAYS_SOFTWARE for Qt 5 applications only.
+ // This is most useful with drivers that only support OpenGL 1.
+ // We need OpenGL 2, but the user probably doesn't want
+ // LIBGL_ALWAYS_SOFTWARE in OpenGL 1 apps.
+ static bool checkedForceSoftwareOpenGL = false;
+ static bool forceSoftwareOpenGL = false;
+ if (!checkedForceSoftwareOpenGL) {
+ // If LIBGL_ALWAYS_SOFTWARE is already set, don't mess with it.
+ // We want to unset LIBGL_ALWAYS_SOFTWARE at the end so it does not
+ // get inherited by other processes, of course only if it wasn't
+ // already set before.
+ if (!qEnvironmentVariableIsEmpty("QT_XCB_FORCE_SOFTWARE_OPENGL")
+ && !qEnvironmentVariableIsSet("LIBGL_ALWAYS_SOFTWARE"))
+ forceSoftwareOpenGL = true;
+
+ checkedForceSoftwareOpenGL = true;
+ }
+
+ if (forceSoftwareOpenGL)
+ qputenv("LIBGL_ALWAYS_SOFTWARE", QByteArrayLiteral("1"));
+
bool reduced = true;
GLXFBConfig chosenConfig = 0;
QSurfaceFormat reducedFormat = format;
@@ -159,6 +184,10 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QSurfaceFormat
reducedFormat = qglx_reduceSurfaceFormat(reducedFormat,&reduced);
}
+ // unset LIBGL_ALWAYS_SOFTWARE now so other processes don't inherit it
+ if (forceSoftwareOpenGL)
+ qunsetenv("LIBGL_ALWAYS_SOFTWARE");
+
return chosenConfig;
}
diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
index 225b3d41ef..3f656668aa 100644
--- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
+++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboard_defaultmap_p.h
@@ -641,6 +641,7 @@ const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
{ KEY_VOLUMEUP, 0xffff, Qt::Key_VolumeUp, 0x00, 0x00, 0x0000 },
{ KEY_PAUSE, 0xffff, Qt::Key_Pause, 0x00, 0x00, 0x0000 },
{ KEY_STOP, 0xffff, Qt::Key_Stop, 0x00, 0x00, 0x0000 },
+ { KEY_SETUP, 0xffff, Qt::Key_Settings, 0x00, 0x00, 0x0000 },
{ KEY_RECORD, 0xffff, Qt::Key_MediaRecord, 0x00, 0x00, 0x0000 },
{ KEY_REWIND, 0xffff, Qt::Key_AudioRewind, 0x00, 0x00, 0x0000 },
{ KEY_PLAYPAUSE, 0xffff, Qt::Key_MediaTogglePlayPause, 0x00, 0x00, 0x0000 },
@@ -651,6 +652,9 @@ const QEvdevKeyboardMap::Mapping QEvdevKeyboardHandler::s_keymap_default[] = {
// 0x160 ->
{ KEY_SELECT, 0xffff, Qt::Key_Select, 0x00, 0x00, 0x0000 },
{ KEY_CLEAR, 0xffff, Qt::Key_Clear, 0x00, 0x00, 0x0000 },
+ { KEY_EXIT, 0xffff, Qt::Key_Exit, 0x00, 0x00, 0x0000 },
+ { KEY_INFO, 0xffff, Qt::Key_Info, 0x00, 0x00, 0x0000 },
+ { KEY_PROGRAM, 0xffff, Qt::Key_Guide, 0x00, 0x00, 0x0000 },
{ KEY_CALENDAR, 0xffff, Qt::Key_Calendar, 0x00, 0x00, 0x0000 },
{ KEY_RED, 0xffff, Qt::Key_Red, 0x00, 0x00, 0x0000 },
{ KEY_GREEN, 0xffff, Qt::Key_Green, 0x00, 0x00, 0x0000 },
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
index 6abe933371..d52a16ea75 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager_p.h
@@ -59,6 +59,8 @@ public:
QEvdevMouseManager(const QString &key, const QString &specification, QObject *parent = 0);
~QEvdevMouseManager();
+ QDeviceDiscovery *deviceDiscovery() { return m_deviceDiscovery; }
+
public slots:
void handleMouseEvent(int x, int y, Qt::MouseButtons buttons);
void handleWheelEvent(int delta, Qt::Orientation orientation);
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index f44d53a00e..4a1d67f4b5 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -57,6 +57,7 @@
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
+#include <qpa/qplatformdialoghelper.h>
#include <algorithm>
@@ -407,7 +408,7 @@ QVariant QKdeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
return QVariant(true);
case QPlatformTheme::DialogButtonBoxLayout:
- return QVariant(2); // QDialogButtonBox::KdeLayout
+ return QVariant(QPlatformDialogHelper::KdeLayout);
case QPlatformTheme::ToolButtonStyle:
return QVariant(d->toolButtonStyle);
case QPlatformTheme::ToolBarIconSize:
@@ -503,7 +504,7 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
case QPlatformTheme::DialogButtonBoxButtonsHaveIcons:
return QVariant(true);
case QPlatformTheme::DialogButtonBoxLayout:
- return QVariant(3); // QDialogButtonBox::GnomeLayout
+ return QVariant(QPlatformDialogHelper::GnomeLayout);
case QPlatformTheme::SystemIconThemeName:
case QPlatformTheme::SystemIconFallbackThemeName:
return QVariant(QString(QStringLiteral("gnome")));
@@ -537,6 +538,25 @@ const QFont *QGnomeTheme::font(Font type) const
}
}
+QString QGnomeTheme::standardButtonText(int button) const
+{
+ switch (button) {
+ case QPlatformDialogHelper::Ok:
+ return QCoreApplication::translate("QGnomeTheme", "&OK");
+ case QPlatformDialogHelper::Save:
+ return QCoreApplication::translate("QGnomeTheme", "&Save");
+ case QPlatformDialogHelper::Cancel:
+ return QCoreApplication::translate("QGnomeTheme", "&Cancel");
+ case QPlatformDialogHelper::Close:
+ return QCoreApplication::translate("QGnomeTheme", "&Close");
+ case QPlatformDialogHelper::Discard:
+ return QCoreApplication::translate("QGnomeTheme", "Close without Saving");
+ default:
+ break;
+ }
+ return QPlatformTheme::standardButtonText(button);
+}
+
/*!
\brief Creates a UNIX theme according to the detected desktop environment.
*/
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
index 03445776f4..36fcdd8dce 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
@@ -86,8 +86,8 @@ class QKdeThemePrivate;
class QKdeTheme : public QPlatformTheme
{
Q_DECLARE_PRIVATE(QKdeTheme)
- QKdeTheme(const QString &kdeHome, int kdeVersion);
public:
+ QKdeTheme(const QString &kdeHome, int kdeVersion);
static QPlatformTheme *createKdeTheme();
virtual QVariant themeHint(ThemeHint hint) const;
@@ -109,6 +109,7 @@ public:
QGnomeTheme();
virtual QVariant themeHint(ThemeHint hint) const;
virtual const QFont *font(Font type) const;
+ QString standardButtonText(int button) const Q_DECL_OVERRIDE;
static const char *name;
};
diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp
index b24106d223..7d3668ee5a 100644
--- a/src/plugins/accessible/widgets/itemviews.cpp
+++ b/src/plugins/accessible/widgets/itemviews.cpp
@@ -1057,9 +1057,10 @@ QRect QAccessibleTableCell::rect() const
QRect r;
r = view->visualRect(m_index);
- if (!r.isNull())
+ if (!r.isNull()) {
r.translate(view->viewport()->mapTo(view, QPoint(0,0)));
r.translate(view->mapToGlobal(QPoint(0, 0)));
+ }
return r;
}
diff --git a/src/plugins/bearer/connman/connman.pro b/src/plugins/bearer/connman/connman.pro
index cccdff0fdb..0da2dfacf6 100644
--- a/src/plugins/bearer/connman/connman.pro
+++ b/src/plugins/bearer/connman/connman.pro
@@ -5,6 +5,8 @@ PLUGIN_CLASS_NAME = QConnmanEnginePlugin
load(qt_plugin)
QT = core network-private dbus
+CONFIG += link_pkgconfig
+packagesExist(connectionagent) { DEFINES += QT_HAS_CONNECTIONAGENT }
HEADERS += qconnmanservice_linux_p.h \
qofonoservice_linux_p.h \
diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp
index eac0d2b813..aee56eb034 100644
--- a/src/plugins/bearer/connman/qconnmanengine.cpp
+++ b/src/plugins/bearer/connman/qconnmanengine.cpp
@@ -41,7 +41,6 @@
#include "qconnmanengine.h"
#include "qconnmanservice_linux_p.h"
-#include "qofonoservice_linux_p.h"
#include "../qnetworksession_impl.h"
#include <QtNetwork/private/qnetworkconfiguration_p.h>
@@ -55,7 +54,11 @@
#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusMessage>
#include <QtDBus/QDBusReply>
-
+#ifdef QT_HAS_CONNECTIONAGENT
+#include <sys/inotify.h>
+#include <fcntl.h>
+#include <qcore_unix_p.h>
+#endif
#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
@@ -63,7 +66,10 @@ QT_BEGIN_NAMESPACE
QConnmanEngine::QConnmanEngine(QObject *parent)
: QBearerEngineImpl(parent),
- connmanManager(new QConnmanManagerInterface(this))
+ connmanManager(new QConnmanManagerInterface(this)),
+ ofonoManager(new QOfonoManagerInterface(this)),
+ ofonoNetwork(0),
+ ofonoContextManager(0)
{
qDBusRegisterMetaType<ConnmanMap>();
qDBusRegisterMetaType<ConnmanMapList>();
@@ -72,6 +78,9 @@ QConnmanEngine::QConnmanEngine(QObject *parent)
QConnmanEngine::~QConnmanEngine()
{
+#ifdef QT_HAS_CONNECTIONAGENT
+ qt_safe_close(inotifyFileDescriptor);
+#endif
}
bool QConnmanEngine::connmanAvailable() const
@@ -82,26 +91,56 @@ bool QConnmanEngine::connmanAvailable() const
void QConnmanEngine::initialize()
{
- connect(connmanManager,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(propertyChangedContext(QString,QString,QDBusVariant)));
+ QMutexLocker locker(&mutex);
+ connect(ofonoManager,SIGNAL(modemChanged()),this,SLOT(changedModem()));
+
+ ofonoNetwork = new QOfonoNetworkRegistrationInterface(ofonoManager->currentModem(),this);
+ ofonoContextManager = new QOfonoDataConnectionManagerInterface(ofonoManager->currentModem(),this);
+ connect(ofonoContextManager,SIGNAL(roamingAllowedChanged(bool)),this,SLOT(reEvaluateCellular()));
connect(connmanManager,SIGNAL(servicesChanged(ConnmanMapList, QList<QDBusObjectPath>)),
this, SLOT(updateServices(ConnmanMapList, QList<QDBusObjectPath>)));
- foreach (const QString &techPath, connmanManager->getTechnologies()) {
- QConnmanTechnologyInterface *tech;
- tech = new QConnmanTechnologyInterface(techPath, this);
+ connect(connmanManager,SIGNAL(servicesReady(QStringList)),this,SLOT(servicesReady(QStringList)));
+ connect(connmanManager,SIGNAL(scanFinished()),this,SLOT(finishedScan()));
- connect(tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant)));
+ foreach (const QString &servPath, connmanManager->getServices()) {
+ addServiceConfiguration(servPath);
+ }
+ Q_EMIT updateCompleted();
+#ifdef QT_HAS_CONNECTIONAGENT
+ QSettings confFile(QStringLiteral("nemomobile"),QStringLiteral("connectionagent"));
+
+ inotifyFileDescriptor = ::inotify_init();
+ inotifyWatcher = ::inotify_add_watch(inotifyFileDescriptor, QFile::encodeName(confFile.fileName()), IN_MODIFY);
+ if (inotifyWatcher > 0) {
+ QSocketNotifier *notifier = new QSocketNotifier(inotifyFileDescriptor, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(inotifyActivated()));
}
+#endif
+}
- foreach (const QString &servPath, connmanManager->getServices()) {
+void QConnmanEngine::changedModem()
+{
+ QMutexLocker locker(&mutex);
+ if (ofonoNetwork)
+ delete ofonoNetwork;
+
+ ofonoNetwork = new QOfonoNetworkRegistrationInterface(ofonoManager->currentModem(),this);
+
+ if (ofonoContextManager)
+ delete ofonoContextManager;
+ ofonoContextManager = new QOfonoDataConnectionManagerInterface(ofonoManager->currentModem(),this);
+}
+
+void QConnmanEngine::servicesReady(const QStringList &list)
+{
+ QMutexLocker locker(&mutex);
+ foreach (const QString &servPath, list) {
addServiceConfiguration(servPath);
}
- // Get current list of access points.
- getConfigurations();
+ Q_EMIT updateCompleted();
}
QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations()
@@ -129,13 +168,6 @@ QList<QNetworkConfigurationPrivate *> QConnmanEngine::getConfigurations()
return fetchedConfigurations;
}
-void QConnmanEngine::doRequestUpdate()
-{
- connmanManager->requestScan("");
- getConfigurations();
- emit updateCompleted();
-}
-
QString QConnmanEngine::getInterfaceFromId(const QString &id)
{
QMutexLocker locker(&mutex);
@@ -151,24 +183,25 @@ bool QConnmanEngine::hasIdentifier(const QString &id)
void QConnmanEngine::connectToId(const QString &id)
{
QMutexLocker locker(&mutex);
- QString servicePath = serviceFromId(id);
- QConnmanServiceInterface serv(servicePath);
- if(!serv.isValid()) {
+
+ QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id);
+
+ if (!serv->isValid()) {
emit connectionError(id, QBearerEngineImpl::InterfaceLookupError);
} else {
- serv.connect();
+ serv->connect();
}
}
void QConnmanEngine::disconnectFromId(const QString &id)
{
QMutexLocker locker(&mutex);
- QString servicePath = serviceFromId(id);
- QConnmanServiceInterface serv(servicePath);
- if(!serv.isValid()) {
+ QConnmanServiceInterface *serv = connmanServiceInterfaces.value(id);
+
+ if (!serv->isValid()) {
emit connectionError(id, DisconnectionError);
} else {
- serv.disconnect();
+ serv->disconnect();
}
}
@@ -178,31 +211,32 @@ void QConnmanEngine::requestUpdate()
QTimer::singleShot(0, this, SLOT(doRequestUpdate()));
}
+void QConnmanEngine::doRequestUpdate()
+{
+ connmanManager->requestScan("wifi");
+}
+
+void QConnmanEngine::finishedScan()
+{
+}
+
void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)
{
+ QMutexLocker locker(&mutex);
+
foreach (const QDBusObjectPath &objectPath, removed) {
- removeConfiguration(QString::number(qHash(objectPath.path())));
+ removeConfiguration(objectPath.path());
}
foreach (const ConnmanMap &connmanMap, changed) {
- const QString id = QString::number(qHash(connmanMap.objectPath.path()));
+ const QString id = connmanMap.objectPath.path();
if (accessPointConfigurations.contains(id)) {
- configurationChange(id);
+ configurationChange(connmanServiceInterfaces.value(id));
} else {
addServiceConfiguration(connmanMap.objectPath.path());
}
}
-}
-
-QString QConnmanEngine::serviceFromId(const QString &id)
-{
- QMutexLocker locker(&mutex);
- foreach (const QString &service, serviceNetworks) {
- if (id == QString::number(qHash(service)))
- return service;
- }
-
- return QString();
+ Q_EMIT updateCompleted();
}
QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id)
@@ -211,25 +245,24 @@ QNetworkSession::State QConnmanEngine::sessionStateForId(const QString &id)
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
- if (!ptr)
+ if (!ptr || !ptr->isValid)
return QNetworkSession::Invalid;
- if (!ptr->isValid) {
- return QNetworkSession::Invalid;
+ QString service = id;
+ QConnmanServiceInterface *serv = connmanServiceInterfaces.value(service);
- }
- QString service = serviceFromId(id);
- QConnmanServiceInterface serv(service);
- QString servState = serv.getState();
+ QString servState = serv->state();
- if(serv.isFavorite() && (servState == "idle" || servState == "failure")) {
+ if (serv->favorite() && (servState == QLatin1String("idle") || servState == QLatin1String("failure"))) {
return QNetworkSession::Disconnected;
}
- if(servState == "association" || servState == "configuration" || servState == "login") {
+ if (servState == QLatin1String("association") || servState == QLatin1String("configuration")
+ || servState == QLatin1String("ready")) {
return QNetworkSession::Connecting;
}
- if(servState == "ready" || servState == "online") {
+
+ if (servState == QLatin1String("online")) {
return QNetworkSession::Connected;
}
@@ -300,88 +333,36 @@ QNetworkSessionPrivate *QConnmanEngine::createSessionBackend()
QNetworkConfigurationPrivatePointer QConnmanEngine::defaultConfiguration()
{
- return QNetworkConfigurationPrivatePointer();
-}
-
-void QConnmanEngine::propertyChangedContext(const QString &path,const QString &item, const QDBusVariant &value)
-{
- Q_UNUSED(path);
-
- QMutexLocker locker(&mutex);
- if(item == "Services") {
- QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant());
- QStringList list = qdbus_cast<QStringList>(arg);
-
- if(list.count() > accessPointConfigurations.count()) {
- foreach (const QString &service, list) {
- addServiceConfiguration(service);
- }
- }
- }
-
- if(item == "Technologies") {
- QDBusArgument arg = qvariant_cast<QDBusArgument>(value.variant());
- QStringList newlist = qdbus_cast<QStringList>(arg);
- if(newlist.count() > 0) {
- QMap<QString,QConnmanTechnologyInterface *> oldtech = technologies;
-
- foreach (const QString &listPath, newlist) {
- if(!oldtech.contains(listPath)) {
- QConnmanTechnologyInterface *tech;
- tech = new QConnmanTechnologyInterface(listPath,this);
- connect(tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant)));
- technologies.insert(listPath, tech);
- }
- }
- }
- }
- if(item == "State") {
-// qDebug() << value.variant();
- }
-}
-
-void QConnmanEngine::servicePropertyChangedContext(const QString &path,const QString &item, const QDBusVariant &value)
-{
- QMutexLocker locker(&mutex);
- if(item == "State") {
- configurationChange(QString::number(qHash(path)));
-
- if(value.variant().toString() == "failure") {
- QConnmanServiceInterface serv(path);
- emit connectionError(QString::number(qHash(path)), ConnectError);
+ const QMutexLocker locker(&mutex);
+ Q_FOREACH (const QString &servPath, connmanManager->getServices()) {
+ if (connmanServiceInterfaces.contains(servPath)) {
+ if (accessPointConfigurations.contains(servPath))
+ return accessPointConfigurations.value(servPath);
}
}
+ return QNetworkConfigurationPrivatePointer();
}
-void QConnmanEngine::technologyPropertyChangedContext(const QString & path, const QString &item, const QDBusVariant &value)
+void QConnmanEngine::serviceStateChanged(const QString &state)
{
- if(item == "State") {
- if(value.variant().toString() == "offline") {
- QConnmanTechnologyInterface tech(path);
- disconnect(&tech,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(technologyPropertyChangedContext(QString,QString,QDBusVariant)));
+ QConnmanServiceInterface *service = qobject_cast<QConnmanServiceInterface *>(sender());
+ configurationChange(service);
- technologies.remove(path);
- }
+ if (state == QStringLiteral("failure")) {
+ emit connectionError(service->path(), ConnectError);
}
}
-void QConnmanEngine::configurationChange(const QString &id)
+void QConnmanEngine::configurationChange(QConnmanServiceInterface *serv)
{
QMutexLocker locker(&mutex);
+ QString id = serv->path();
if (accessPointConfigurations.contains(id)) {
bool changed = false;
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(id);
-
- QString servicePath = serviceFromId(id);
- QConnmanServiceInterface *serv;
- serv = new QConnmanServiceInterface(servicePath);
- QString networkName = serv->getName();
-
- QNetworkConfiguration::StateFlags curState = getStateForService(servicePath);
-
+ QString networkName = serv->name();
+ QNetworkConfiguration::StateFlags curState = getStateForService(serv->path());
ptr->mutex.lock();
if (!ptr->isValid) {
@@ -414,26 +395,31 @@ void QConnmanEngine::configurationChange(const QString &id)
QNetworkConfiguration::StateFlags QConnmanEngine::getStateForService(const QString &service)
{
QMutexLocker locker(&mutex);
- QConnmanServiceInterface serv(service);
+ QConnmanServiceInterface *serv = connmanServiceInterfaces.value(service);
+ QString state = serv->state();
+
QNetworkConfiguration::StateFlags flag = QNetworkConfiguration::Defined;
- if (serv.getType() == "cellular") {
- if (serv.isSetupRequired() || !serv.isAutoConnect() || (serv.isRoaming() && isAlwaysAskRoaming())) {
- flag = ( flag | QNetworkConfiguration::Defined);
+
+ if (serv->type() == QLatin1String("cellular")) {
+
+ if (!serv->autoConnect()
+ || (serv->roaming()
+ && (isAlwaysAskRoaming() || !isRoamingAllowed(serv->path())))) {
+ flag = (flag | QNetworkConfiguration::Defined);
} else {
- flag = ( flag | QNetworkConfiguration::Discovered);
+ flag = (flag | QNetworkConfiguration::Discovered);
}
} else {
- if (serv.isFavorite()) {
- if (serv.isAutoConnect()) {
- flag = ( flag | QNetworkConfiguration::Discovered);
+ if (serv->favorite()) {
+ if (serv->autoConnect()) {
+ flag = (flag | QNetworkConfiguration::Discovered);
}
} else {
flag = QNetworkConfiguration::Undefined;
}
}
-
- if (serv.getState() == "ready" || serv.getState() == "online") {
- flag = ( flag | QNetworkConfiguration::Active);
+ if (state == QLatin1String("online")) {
+ flag = (flag | QNetworkConfiguration::Active);
}
return flag;
@@ -441,51 +427,35 @@ QNetworkConfiguration::StateFlags QConnmanEngine::getStateForService(const QStri
QNetworkConfiguration::BearerType QConnmanEngine::typeToBearer(const QString &type)
{
- if (type == "wifi")
+ if (type == QLatin1String("wifi"))
return QNetworkConfiguration::BearerWLAN;
- if (type == "ethernet")
+ if (type == QLatin1String("ethernet"))
return QNetworkConfiguration::BearerEthernet;
- if (type == "bluetooth")
+ if (type == QLatin1String("bluetooth"))
return QNetworkConfiguration::BearerBluetooth;
- if (type == "cellular") {
+ if (type == QLatin1String("cellular")) {
return ofonoTechToBearerType(type);
}
- if (type == "wimax")
+ if (type == QLatin1String("wimax"))
return QNetworkConfiguration::BearerWiMAX;
-// if(type == "gps")
-// if(type == "vpn")
-
return QNetworkConfiguration::BearerUnknown;
}
QNetworkConfiguration::BearerType QConnmanEngine::ofonoTechToBearerType(const QString &/*type*/)
{
- QOfonoManagerInterface ofonoManager(this);
- QOfonoNetworkRegistrationInterface ofonoNetwork(ofonoManager.currentModem().path(),this);
-
- if(ofonoNetwork.isValid()) {
- foreach (const QDBusObjectPath &op,ofonoNetwork.getOperators() ) {
- QOfonoNetworkOperatorInterface opIface(op.path(),this);
-
- foreach (const QString &opTech, opIface.getTechnologies()) {
-
- if(opTech == "gsm") {
- return QNetworkConfiguration::Bearer2G;
- }
- if(opTech == "edge"){
- return QNetworkConfiguration::BearerCDMA2000; //wrong, I know
- }
- if(opTech == "umts"){
- return QNetworkConfiguration::BearerWCDMA;
- }
- if(opTech == "hspa"){
- return QNetworkConfiguration::BearerHSPA;
- }
- if(opTech == "lte"){
- return QNetworkConfiguration::BearerWiMAX; //not exact
- }
- }
+ if (ofonoNetwork) {
+ QString currentTechnology = ofonoNetwork->getTechnology();
+ if (currentTechnology == QLatin1String("gsm")) {
+ return QNetworkConfiguration::Bearer2G;
+ } else if (currentTechnology == QLatin1String("edge")) {
+ return QNetworkConfiguration::BearerCDMA2000; //wrong, I know
+ } else if (currentTechnology == QLatin1String("umts")) {
+ return QNetworkConfiguration::BearerWCDMA;
+ } else if (currentTechnology == QLatin1String("hspa")) {
+ return QNetworkConfiguration::BearerHSPA;
+ } else if (currentTechnology == QLatin1String("lte")) {
+ return QNetworkConfiguration::BearerWiMAX; //not exact
}
}
return QNetworkConfiguration::BearerUnknown;
@@ -493,12 +463,9 @@ QNetworkConfiguration::BearerType QConnmanEngine::ofonoTechToBearerType(const QS
bool QConnmanEngine::isRoamingAllowed(const QString &context)
{
- QOfonoManagerInterface ofonoManager(this);
- QString modemPath = ofonoManager.currentModem().path();
- QOfonoDataConnectionManagerInterface dc(modemPath,this);
- foreach (const QDBusObjectPath &dcPath,dc.getPrimaryContexts()) {
- if(dcPath.path().contains(context.section("_",-1))) {
- return dc.isRoamingAllowed();
+ foreach (const QString &dcPath, ofonoContextManager->contexts()) {
+ if (dcPath.contains(context.section("_",-1))) {
+ return ofonoContextManager->roamingAllowed();
}
}
return false;
@@ -510,14 +477,11 @@ void QConnmanEngine::removeConfiguration(const QString &id)
if (accessPointConfigurations.contains(id)) {
- QString service = serviceFromId(id);
- QConnmanServiceInterface serv(service);
-
- disconnect(&serv,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(servicePropertyChangedContext(QString,QString,QDBusVariant)));
-
- serviceNetworks.removeOne(service);
-
+ disconnect(connmanServiceInterfaces.value(id),SIGNAL(stateChanged(QString)),
+ this,SLOT(serviceStateChanged(QString)));
+ serviceNetworks.removeOne(id);
+ QConnmanServiceInterface *service = connmanServiceInterfaces.take(id);
+ delete service;
QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(id);
foundConfigurations.removeOne(ptr.data());
locker.unlock();
@@ -529,35 +493,32 @@ void QConnmanEngine::removeConfiguration(const QString &id)
void QConnmanEngine::addServiceConfiguration(const QString &servicePath)
{
QMutexLocker locker(&mutex);
- QConnmanServiceInterface *serv;
- serv = new QConnmanServiceInterface(servicePath);
+ if (!connmanServiceInterfaces.contains(servicePath)) {
+ QConnmanServiceInterface *serv = new QConnmanServiceInterface(servicePath);
+ connmanServiceInterfaces.insert(serv->path(),serv);
+ }
- const QString id = QString::number(qHash(servicePath));
+ if (!accessPointConfigurations.contains(servicePath)) {
- if (!accessPointConfigurations.contains(id)) {
serviceNetworks.append(servicePath);
- connect(serv,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SLOT(servicePropertyChangedContext(QString,QString,QDBusVariant)));
+ connect(connmanServiceInterfaces.value(servicePath),SIGNAL(stateChanged(QString)),
+ this,SLOT(serviceStateChanged(QString)));
+
QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate();
+ QConnmanServiceInterface *service = connmanServiceInterfaces.value(servicePath);
- QString networkName = serv->getName();
+ QString networkName = service->name();
- const QString connectionType = serv->getType();
- if (connectionType == "ethernet") {
+ const QString connectionType = service->type();
+ if (connectionType == QLatin1String("ethernet")) {
cpPriv->bearerType = QNetworkConfiguration::BearerEthernet;
- } else if (connectionType == "wifi") {
+ } else if (connectionType == QLatin1String("wifi")) {
cpPriv->bearerType = QNetworkConfiguration::BearerWLAN;
- } else if (connectionType == "cellular") {
- cpPriv->bearerType = ofonoTechToBearerType("cellular");
- if(servicePath.isEmpty()) {
- networkName = serv->getAPN();
- if(networkName.isEmpty()) {
- networkName = serv->getName();
- }
- }
- cpPriv->roamingSupported = isRoamingAllowed(servicePath);
- } else if (connectionType == "wimax") {
+ } else if (connectionType == QLatin1String("cellular")) {
+ cpPriv->bearerType = ofonoTechToBearerType(QLatin1String("cellular"));
+ cpPriv->roamingSupported = service->roaming() && isRoamingAllowed(servicePath);
+ } else if (connectionType == QLatin1String("wimax")) {
cpPriv->bearerType = QNetworkConfiguration::BearerWiMAX;
} else {
cpPriv->bearerType = QNetworkConfiguration::BearerUnknown;
@@ -565,10 +526,10 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath)
cpPriv->name = networkName;
cpPriv->isValid = true;
- cpPriv->id = id;
+ cpPriv->id = servicePath;
cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
- if(serv->getSecurity() == "none") {
+ if (service->security() == QStringLiteral("none")) {
cpPriv->purpose = QNetworkConfiguration::PublicPurpose;
} else {
cpPriv->purpose = QNetworkConfiguration::PrivatePurpose;
@@ -578,13 +539,16 @@ void QConnmanEngine::addServiceConfiguration(const QString &servicePath)
QNetworkConfigurationPrivatePointer ptr(cpPriv);
accessPointConfigurations.insert(ptr->id, ptr);
- foundConfigurations.append(cpPriv);
- configInterfaces[cpPriv->id] = serv->getInterface();
+ if (connectionType == QLatin1String("cellular")) {
+ foundConfigurations.append(cpPriv);
+ } else {
+ foundConfigurations.prepend(cpPriv);
+ }
+ configInterfaces[cpPriv->id] = service->serviceInterface();
locker.unlock();
- emit configurationAdded(ptr);
+ Q_EMIT configurationAdded(ptr);
locker.relock();
- emit updateCompleted();
}
}
@@ -595,10 +559,39 @@ bool QConnmanEngine::requiresPolling() const
bool QConnmanEngine::isAlwaysAskRoaming()
{
- QSettings confFile(QStringLiteral("nemomobile"), QStringLiteral("connectionagent"));
+#ifdef QT_HAS_CONNECTIONAGENT
+ QSettings confFile(QStringLiteral("nemomobile"),QStringLiteral("connectionagent"));
confFile.beginGroup(QStringLiteral("Connectionagent"));
return confFile.value(QStringLiteral("askForRoaming")).toBool();
+#else
+ return false;
+#endif
}
+
+void QConnmanEngine::reEvaluateCellular()
+{
+ Q_FOREACH (const QString &servicePath, connmanManager->getServices()) {
+ if (servicePath.contains("cellular") && accessPointConfigurations.contains(servicePath)) {
+ configurationChange(connmanServiceInterfaces.value(servicePath));
+ }
+ }
+}
+
+void QConnmanEngine::inotifyActivated()
+{
+#ifdef QT_HAS_CONNECTIONAGENT
+
+ char buffer[1024];
+ int len = qt_safe_read(inotifyFileDescriptor, (void *)buffer, sizeof(buffer));
+ if (len > 0) {
+ struct inotify_event *event = (struct inotify_event *)buffer;
+ if (event->wd == inotifyWatcher && (event->mask & IN_MODIFY) == 0) {
+ QTimer::singleShot(1000, this, SLOT(reEvaluateCellular())); //give this time to finish write
+ }
+ }
+#endif
+}
+
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h
index 49a1a91d29..4a4e91659b 100644
--- a/src/plugins/bearer/connman/qconnmanengine.h
+++ b/src/plugins/bearer/connman/qconnmanengine.h
@@ -56,6 +56,7 @@
#include "../qbearerengine_impl.h"
#include "qconnmanservice_linux_p.h"
+#include "qofonoservice_linux_p.h"
#include <QMap>
#include <QVariant>
@@ -91,28 +92,32 @@ public:
virtual quint64 bytesReceived(const QString &id);
virtual quint64 startTime(const QString &id);
-
virtual QNetworkConfigurationManager::Capabilities capabilities() const;
virtual QNetworkConfigurationPrivatePointer defaultConfiguration();
- void configurationChange(const QString &id);
QList<QNetworkConfigurationPrivate *> getConfigurations();
-
private Q_SLOTS:
void doRequestUpdate();
- void servicePropertyChangedContext(const QString &,const QString &,const QDBusVariant &);
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
- void technologyPropertyChangedContext(const QString &,const QString &, const QDBusVariant &);
void updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed);
+ void servicesReady(const QStringList &);
+ void finishedScan();
+ void changedModem();
+ void serviceStateChanged(const QString &state);
+ void configurationChange(QConnmanServiceInterface * service);
+ void reEvaluateCellular();
+ void inotifyActivated();
private:
QConnmanManagerInterface *connmanManager;
+ QOfonoManagerInterface *ofonoManager;
+ QOfonoNetworkRegistrationInterface *ofonoNetwork;
+ QOfonoDataConnectionManagerInterface *ofonoContextManager;
+
QList<QNetworkConfigurationPrivate *> foundConfigurations;
- QString serviceFromId(const QString &id);
QString networkFromId(const QString &id);
QNetworkConfiguration::StateFlags getStateForService(const QString &service);
@@ -130,6 +135,11 @@ private:
QNetworkConfiguration::BearerType ofonoTechToBearerType(const QString &type);
bool isRoamingAllowed(const QString &context);
bool isAlwaysAskRoaming();
+ QMap <QString,QConnmanServiceInterface *> connmanServiceInterfaces;
+
+ int inotifyWatcher;
+ int inotifyFileDescriptor;
+
protected:
bool requiresPolling() const;
};
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
index 6d9ee265c6..46b24f77dd 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp
+++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp
@@ -75,708 +75,380 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, ConnmanMap &map)
}
QConnmanManagerInterface::QConnmanManagerInterface( QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
- QLatin1String(CONNMAN_MANAGER_PATH),
+ : QDBusAbstractInterface(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
CONNMAN_MANAGER_INTERFACE,
QDBusConnection::systemBus(), parent)
{
qDBusRegisterMetaType<ConnmanMap>();
qDBusRegisterMetaType<ConnmanMapList>();
-}
-QConnmanManagerInterface::~QConnmanManagerInterface()
-{
-}
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> props_reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this);
-void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- if(!connection().connect(QLatin1String(CONNMAN_SERVICE),
- QLatin1String(CONNMAN_MANAGER_PATH),
- QLatin1String(CONNMAN_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
- qWarning() << "PropertyChanged not connected";
- }
- }
+ QObject::connect(watcher,SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(propertiesReply(QDBusPendingCallWatcher*)));
- static const QMetaMethod stateChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::stateChanged);
- if (signal == stateChangedSignal) {
- if (!connection().connect(QLatin1String(CONNMAN_SERVICE),
- QLatin1String(CONNMAN_MANAGER_PATH),
- QLatin1String(CONNMAN_MANAGER_INTERFACE),
- QLatin1String("StateChanged"),
- this,SIGNAL(stateChanged(QString)))) {
- qWarning() << "StateChanged not connected";
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
+ QStringLiteral(CONNMAN_SERVICE_INTERFACE),
+ QStringLiteral("PropertyChanged"),
+ this,SLOT(changedProperty(QString,QDBusVariant)));
- }
- }
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QConnmanDBusHelper *helper;
- helper = new QConnmanDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- QLatin1String(CONNMAN_MANAGER_PATH),
- QLatin1String(CONNMAN_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
+ QStringLiteral(CONNMAN_SERVICE_INTERFACE),
+ QStringLiteral("TechnologyAdded"),
+ this,SLOT(technologyAdded(QDBusObjectPath,QVariantMap)));
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
- }
- static const QMetaMethod servicesChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::servicesChanged);
- if (signal == servicesChangedSignal) {
- if (!connection().connect(QLatin1String(CONNMAN_SERVICE),
- QLatin1String(CONNMAN_MANAGER_PATH),
- QLatin1String(CONNMAN_MANAGER_INTERFACE),
- QLatin1String("ServicesChanged"),
- this,SLOT(onServicesChanged(ConnmanMapList, QList<QDBusObjectPath>)))) {
- qWarning() << "servicesChanged not connected";
- }
- }
-}
-
-void QConnmanManagerInterface::onServicesChanged(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)
-{
- emit servicesChanged(changed, removed);
-}
-
-
-void QConnmanManagerInterface::disconnectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
- }
-}
-
-QVariant QConnmanManagerInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << "does not contain" << property;
- }
- return var;
-}
-
-QVariantMap QConnmanManagerInterface::getProperties()
-{
- if(this->isValid()) {
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
- } else return QVariantMap();
-}
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
+ QStringLiteral(CONNMAN_SERVICE_INTERFACE),
+ QStringLiteral("TechnologyRemoved"),
+ this,SLOT(technologyRemoved(QDBusObjectPath)));
-QString QConnmanManagerInterface::getState()
-{
- QDBusReply<QString > reply = this->call("GetState");
- return reply.value();
-}
+ QList<QVariant> argumentList2;
+ QDBusPendingReply<ConnmanMapList> serv_reply = asyncCallWithArgumentList(QLatin1String("GetServices"), argumentList2);
+ QDBusPendingCallWatcher *watcher2 = new QDBusPendingCallWatcher(serv_reply, this);
-bool QConnmanManagerInterface::setProperty(const QString &name, const QDBusVariant &value)
-{
- Q_UNUSED(name);
- Q_UNUSED(value);
- return false;
-}
+ QObject::connect(watcher2,SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(servicesReply(QDBusPendingCallWatcher*)));
-QDBusObjectPath QConnmanManagerInterface::createProfile(const QString &/*name*/)
-{
- return QDBusObjectPath();
}
-bool QConnmanManagerInterface::removeProfile(QDBusObjectPath /*path*/)
+QConnmanManagerInterface::~QConnmanManagerInterface()
{
- return false;
}
-bool QConnmanManagerInterface::requestScan(const QString &type)
+void QConnmanManagerInterface::changedProperty(const QString &name, const QDBusVariant &value)
{
- QDBusReply<QString> reply = this->call(QLatin1String("RequestScan"), QVariant::fromValue(type));
-
- bool ok = true;
- if(reply.error().type() == QDBusError::InvalidArgs) {
- qWarning() << reply.error().message();
- ok = false;
- }
- return ok;
+ propertiesCacheMap[name] = value.variant();
}
-bool QConnmanManagerInterface::enableTechnology(const QString &type)
+void QConnmanManagerInterface::propertiesReply(QDBusPendingCallWatcher *call)
{
- QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("EnableTechnology"), QVariant::fromValue(type));
- bool ok = true;
- if(reply.error().type() == QDBusError::InvalidArgs) {
- qWarning() << reply.error().message();
- ok = false;
- }
- return ok;
-}
+ QDBusPendingReply<QVariantMap> props_reply = *call;
-bool QConnmanManagerInterface::disableTechnology(const QString &type)
-{
- QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("DisableTechnology"), QVariant::fromValue(type));
- bool ok = true;
- if(reply.error().type() == QDBusError::InvalidArgs) {
- qWarning() << reply.error().message();
- ok = false;
+ if (props_reply.isError()) {
+ qDebug() << props_reply.error().message();
+ } else {
+ propertiesCacheMap = props_reply.value();
}
- return ok;
+ call->deleteLater();
}
-QDBusObjectPath QConnmanManagerInterface::connectService(QVariantMap &map)
+void QConnmanManagerInterface::servicesReply(QDBusPendingCallWatcher *call)
{
- QDBusReply<QDBusObjectPath > reply = this->call(QLatin1String("ConnectService"), QVariant::fromValue(map));
- if(!reply.isValid()) {
- qDebug() << reply.error().message();
+ QDBusPendingReply<ConnmanMapList> serv_reply = *call;
+ if (serv_reply.isError()) {
+ qDebug() << serv_reply.error().message();
+ } else {
+ servicesList.clear(); //connman list changes order
+ ConnmanMap connmanobj;
+ Q_FOREACH (connmanobj, serv_reply.value()) {
+ servicesList << connmanobj.objectPath.path();
+ }
+ Q_EMIT servicesReady(servicesList);
}
- return reply;
+ call->deleteLater();
}
-void QConnmanManagerInterface::registerAgent(QDBusObjectPath &/*path*/)
-{
-}
-
-void QConnmanManagerInterface::unregisterAgent(QDBusObjectPath /*path*/)
+void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal)
{
-}
-
-void QConnmanManagerInterface::registerCounter(const QString &path, quint32 interval)
-{ QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("RegisterCounter"),
- QVariant::fromValue(path),
- QVariant::fromValue(interval));
- if(reply.error().type() == QDBusError::InvalidArgs) {
- qWarning() << reply.error().message();
+ static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::propertyChanged);
+ if (signal == propertyChangedSignal) {
+ if (!connection().connect(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
+ QStringLiteral(CONNMAN_MANAGER_INTERFACE),
+ QStringLiteral("PropertyChanged"),
+ this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
+ qWarning() << "PropertyChanged not connected";
+ }
}
-}
-void QConnmanManagerInterface::unregisterCounter(const QString &path)
-{ QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("UnregisterCounter"),
- QVariant::fromValue(path));
- if(reply.error().type() == QDBusError::InvalidArgs) {
- qWarning() << reply.error().message();
+ static const QMetaMethod servicesChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::servicesChanged);
+ if (signal == servicesChangedSignal) {
+ if (!connection().connect(QStringLiteral(CONNMAN_SERVICE),
+ QStringLiteral(CONNMAN_MANAGER_PATH),
+ QStringLiteral(CONNMAN_MANAGER_INTERFACE),
+ QStringLiteral("ServicesChanged"),
+ this,SLOT(onServicesChanged(ConnmanMapList, QList<QDBusObjectPath>)))) {
+ qWarning() << "servicesChanged not connected";
+ }
}
}
-QString QConnmanManagerInterface::requestSession(const QString &bearerName)
-{
- QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("RequestSession"),
- QVariant::fromValue(bearerName));
- return QString();
-}
-
-void QConnmanManagerInterface::releaseSession()
-{
- QDBusReply<QList<QDBusObjectPath> > reply = this->call(QLatin1String("ReleaseSession"));
-}
-
-
-QDBusObjectPath QConnmanManagerInterface::lookupService(const QString &service)
+void QConnmanManagerInterface::onServicesChanged(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)
{
- QDBusReply<QDBusObjectPath > reply = this->call(QLatin1String("LookupService"), QVariant::fromValue(service));
- if(!reply.isValid()) {
- qDebug() << reply.error().message();
+ ConnmanMap connmanobj;
+ servicesList.clear(); //connman list changes order
+ Q_FOREACH (connmanobj, changed) {
+ const QString svcPath(connmanobj.objectPath.path());
+ servicesList << svcPath;
}
- return reply;
-}
-// properties
-
-QStringList QConnmanManagerInterface::getAvailableTechnologies()
-{
- QVariant var = getProperty("AvailableTechnologies");
- return qdbus_cast<QStringList>(var);
+ Q_EMIT servicesChanged(changed, removed);
}
-QStringList QConnmanManagerInterface::getEnabledTechnologies()
+QVariant QConnmanManagerInterface::getProperty(const QString &property)
{
- QVariant var = getProperty("EnabledTechnologies");
- return qdbus_cast<QStringList>(var);
+ QVariant var;
+ var = propertiesCacheMap.value(property);
+ return var;
}
-QStringList QConnmanManagerInterface::getConnectedTechnologies()
+QVariantMap QConnmanManagerInterface::getProperties()
{
- QVariant var = getProperty("ConnectedTechnologies");
- return qdbus_cast<QStringList>(var);
+ if (propertiesCacheMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ propertiesCacheMap = reply.value();
+ }
+ }
+ return propertiesCacheMap;
}
-QString QConnmanManagerInterface::getDefaultTechnology()
+QString QConnmanManagerInterface::getState()
{
- QVariant var = getProperty("DefaultTechnology");
- return qdbus_cast<QString>(var);
+ return getProperty(QStringLiteral("State")).toString();
}
bool QConnmanManagerInterface::getOfflineMode()
{
- QVariant var = getProperty("OfflineMode");
+ QVariant var = getProperty(QStringLiteral("OfflineMode"));
return qdbus_cast<bool>(var);
}
-QString QConnmanManagerInterface::getActiveProfile()
-{
- QVariant var = getProperty("ActiveProfile");
- return qdbus_cast<QString>(var);
-}
-
-QStringList QConnmanManagerInterface::getProfiles()
-{
- QVariant var = getProperty("Profiles");
- return qdbus_cast<QStringList>(var);
-}
-
QStringList QConnmanManagerInterface::getTechnologies()
{
- QStringList list;
- QDBusReply<ConnmanMapList> replyList = this->call(QLatin1String("GetTechnologies"));
- if (replyList.isValid()) {
- Q_FOREACH (ConnmanMap map, replyList.value()) {
- list << map.objectPath.path();
- }
- } else {
- // try for older version
- QVariant var = getProperty("Technologies");
- if (!var.isNull()) {
- list = qdbus_cast<QStringList>(var);
+ if (technologiesMap.isEmpty()) {
+ QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetTechnologies"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ Q_FOREACH (ConnmanMap map, reply.value()) {
+ if (!technologiesMap.contains(map.objectPath.path())) {
+ technologyAdded(map.objectPath, map.propertyMap);
+ }
+ }
}
}
- return list;
+ return technologiesMap.keys();
}
QStringList QConnmanManagerInterface::getServices()
{
- QStringList list;
- QDBusReply<ConnmanMapList> replyList = this->call(QLatin1String("GetServices"));
- if (replyList.isValid()) {
- Q_FOREACH (ConnmanMap map, replyList.value()) {
- list << map.objectPath.path();
- }
- } else {
- QVariant var = getProperty("Services");
- if (!var.isNull()) {
- list = qdbus_cast<QStringList>(var);
+ if (servicesList.isEmpty()) {
+ QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetServices"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ Q_FOREACH (ConnmanMap map, reply.value()) {
+ servicesList << map.objectPath.path();
+ }
}
}
- return list;
+ return servicesList;
}
-QString QConnmanManagerInterface::getPathForTechnology(const QString &name)
+void QConnmanManagerInterface::requestScan(const QString &type)
{
- foreach (const QString &path, getTechnologies()) {
- if(path.contains(name)) {
- return path;
+ Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
+ if (tech->type() == type) {
+ tech->scan();
}
}
- return "";
-}
-
-
-//////////////////////////
-QConnmanProfileInterface::QConnmanProfileInterface(const QString &dbusPathName,QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
- dbusPathName,
- CONNMAN_PROFILE_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QConnmanProfileInterface::~QConnmanProfileInterface()
-{
}
-void QConnmanProfileInterface::connectNotify(const QMetaMethod &signal)
+void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, const QVariantMap &)
{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanProfileInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- this->path(),
- QLatin1String(CONNMAN_PROFILE_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)));
+ if (!technologiesList.contains(path.path())) {
+ technologiesList << path.path();
+ QConnmanTechnologyInterface *tech;
+ tech = new QConnmanTechnologyInterface(path.path(),this);
+ technologiesMap.insert(path.path(),tech);
+ connect(tech,SIGNAL(scanFinished()),this,SIGNAL(scanFinished()));
}
}
-void QConnmanProfileInterface::disconnectNotify(const QMetaMethod &signal)
+void QConnmanManagerInterface::technologyRemoved(const QDBusObjectPath &path)
{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanProfileInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
+ if (technologiesList.contains(path.path())) {
+ technologiesList.removeOne(path.path());
+ QConnmanTechnologyInterface * tech = technologiesMap.take(path.path());
+ delete tech;
}
}
-QVariantMap QConnmanProfileInterface::getProperties()
+QConnmanServiceInterface::QConnmanServiceInterface(const QString &dbusPathName,QObject *parent)
+ : QDBusAbstractInterface(QStringLiteral(CONNMAN_SERVICE),
+ dbusPathName,
+ CONNMAN_SERVICE_INTERFACE,
+ QDBusConnection::systemBus(), parent)
{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> props_reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
-QVariant QConnmanProfileInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- }
- return var;
-}
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this);
-// properties
-QString QConnmanProfileInterface::getName()
-{
+ QObject::connect(watcher,SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(propertiesReply(QDBusPendingCallWatcher*)));
- QVariant var = getProperty("Name");
- return qdbus_cast<QString>(var);
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ path(),
+ QStringLiteral(CONNMAN_SERVICE_INTERFACE),
+ QStringLiteral("PropertyChanged"),
+ this,SLOT(changedProperty(QString,QDBusVariant)));
}
-bool QConnmanProfileInterface::isOfflineMode()
-{
- QVariant var = getProperty("OfflineMode");
- return qdbus_cast<bool>(var);
-}
-
-QStringList QConnmanProfileInterface::getServices()
+QConnmanServiceInterface::~QConnmanServiceInterface()
{
- QVariant var = getProperty("Services");
- return qdbus_cast<QStringList>(var);
}
-
-///////////////////////////
-QConnmanServiceInterface::QConnmanServiceInterface(const QString &dbusPathName,QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
- dbusPathName,
- CONNMAN_SERVICE_INTERFACE,
- QDBusConnection::systemBus(), parent)
+QVariantMap QConnmanServiceInterface::getProperties()
{
+ if (propertiesCacheMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ propertiesCacheMap = reply.value();
+ Q_EMIT propertiesReady();
+ }
+ }
+ return propertiesCacheMap;
}
-QConnmanServiceInterface::~QConnmanServiceInterface()
+void QConnmanServiceInterface::propertiesReply(QDBusPendingCallWatcher *call)
{
+ QDBusPendingReply<QVariantMap> props_reply = *call;
+ if (props_reply.isError()) {
+ qDebug() << props_reply.error().message();
+ return;
+ }
+ propertiesCacheMap = props_reply.value();
+ Q_EMIT propertiesReady();
}
void QConnmanServiceInterface::connectNotify(const QMetaMethod &signal)
{
static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanServiceInterface::propertyChanged);
if (signal == propertyChangedSignal) {
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- this->path(),
- QLatin1String(CONNMAN_SERVICE_INTERFACE),
- QLatin1String("PropertyChanged"),
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ path(),
+ QStringLiteral(CONNMAN_SERVICE_INTERFACE),
+ QStringLiteral("PropertyChanged"),
this,SIGNAL(propertyChanged(QString,QDBusVariant)));
}
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QConnmanServiceInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QConnmanDBusHelper *helper;
- helper = new QConnmanDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- this->path(),
- QLatin1String(CONNMAN_SERVICE_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
- }
-}
-
-void QConnmanServiceInterface::disconnectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanServiceInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
- }
}
-QVariantMap QConnmanServiceInterface::getProperties()
+void QConnmanServiceInterface::changedProperty(const QString &name, const QDBusVariant &value)
{
- if(this->isValid()) {
- QDBusReply<QVariantMap> reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
- }
- else
- return QVariantMap();
+ propertiesCacheMap[name] = value.variant();
+ if (name == QStringLiteral("State"))
+ Q_EMIT stateChanged(value.variant().toString());
}
QVariant QConnmanServiceInterface::getProperty(const QString &property)
{
QVariant var;
QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- }
+ var = map.value(property);
return var;
}
void QConnmanServiceInterface::connect()
{
- this->asyncCall(QLatin1String("Connect"));
+ asyncCall(QLatin1String("Connect"));
}
void QConnmanServiceInterface::disconnect()
{
- QDBusReply<QVariantMap> reply = this->call(QLatin1String("Disconnect"));
+ asyncCall(QLatin1String("Disconnect"));
}
void QConnmanServiceInterface::remove()
{
- QDBusReply<QVariantMap> reply = this->call(QLatin1String("Remove"));
+ asyncCall(QLatin1String("Remove"));
}
// properties
-QString QConnmanServiceInterface::getState()
+QString QConnmanServiceInterface::state()
{
- QVariant var = getProperty("State");
+ QVariant var = getProperty(QStringLiteral("State"));
return qdbus_cast<QString>(var);
}
-QString QConnmanServiceInterface::getError()
+QString QConnmanServiceInterface::lastError()
{
- QVariant var = getProperty("Error");
+ QVariant var = getProperty(QStringLiteral("Error"));
return qdbus_cast<QString>(var);
}
-QString QConnmanServiceInterface::getName()
+QString QConnmanServiceInterface::name()
{
- QVariant var = getProperty("Name");
+ QVariant var = getProperty(QStringLiteral("Name"));
return qdbus_cast<QString>(var);
}
-QString QConnmanServiceInterface::getType()
+QString QConnmanServiceInterface::type()
{
- QVariant var = getProperty("Type");
+ QVariant var = getProperty(QStringLiteral("Type"));
return qdbus_cast<QString>(var);
}
-QString QConnmanServiceInterface::getMode()
+QString QConnmanServiceInterface::security()
{
- QVariant var = getProperty("Mode");
+ QVariant var = getProperty(QStringLiteral("Security"));
return qdbus_cast<QString>(var);
}
-QString QConnmanServiceInterface::getSecurity()
+bool QConnmanServiceInterface::favorite()
{
- QVariant var = getProperty("Security");
- return qdbus_cast<QString>(var);
-}
-
-QString QConnmanServiceInterface::getPassphrase()
-{
- QVariant var = getProperty("Passphrase");
- return qdbus_cast<QString>(var);
-}
-
-bool QConnmanServiceInterface::isPassphraseRequired()
-{
- QVariant var = getProperty("PassphraseRequired");
- return qdbus_cast<bool>(var);
-}
-
-quint8 QConnmanServiceInterface::getSignalStrength()
-{
- QVariant var = getProperty("Strength");
- return qdbus_cast<quint8>(var);
-}
-
-bool QConnmanServiceInterface::isFavorite()
-{
- QVariant var = getProperty("Favorite");
+ QVariant var = getProperty(QStringLiteral("Favorite"));
return qdbus_cast<bool>(var);
}
-bool QConnmanServiceInterface::isImmutable()
+bool QConnmanServiceInterface::autoConnect()
{
- QVariant var = getProperty("Immutable");
+ QVariant var = getProperty(QStringLiteral("AutoConnect"));
return qdbus_cast<bool>(var);
}
-bool QConnmanServiceInterface::isAutoConnect()
+bool QConnmanServiceInterface::roaming()
{
- QVariant var = getProperty("AutoConnect");
+ QVariant var = getProperty(QStringLiteral("Roaming"));
return qdbus_cast<bool>(var);
}
-bool QConnmanServiceInterface::isSetupRequired()
-{
- QVariant var = getProperty("SetupRequired");
- return qdbus_cast<bool>(var);
-}
-
-QString QConnmanServiceInterface::getAPN()
-{
- QVariant var = getProperty("APN");
- return qdbus_cast<QString>(var);
-}
-
-QString QConnmanServiceInterface::getMCC()
-{
- QVariant var = getProperty("MCC");
- return qdbus_cast<QString>(var);
-}
-
-QString QConnmanServiceInterface::getMNC()
-{
- QVariant var = getProperty("MNC");
- return qdbus_cast<QString>(var);
-}
-
-bool QConnmanServiceInterface::isRoaming()
-{
- QVariant var = getProperty("Roaming");
- return qdbus_cast<bool>(var);
-}
-
-QStringList QConnmanServiceInterface::getNameservers()
-{
- QVariant var = getProperty("NameServers");
- return qdbus_cast<QStringList>(var);
-}
-
-QStringList QConnmanServiceInterface::getDomains()
-{
- QVariant var = getProperty("Domains");
- return qdbus_cast<QStringList>(var);
-}
-
-QVariantMap QConnmanServiceInterface::getIPv4()
+QVariantMap QConnmanServiceInterface::ethernet()
{
- QVariant var = getProperty("IPv4");
+ QVariant var = getProperty(QStringLiteral("Ethernet"));
return qdbus_cast<QVariantMap >(var);
}
-QVariantMap QConnmanServiceInterface::getIPv4Configuration()
-{
- QVariant var = getProperty("IPv4.Configuration");
- return qdbus_cast<QVariantMap >(var);
-}
-
-QVariantMap QConnmanServiceInterface::getProxy()
-{
- QVariant var = getProperty("Proxy");
- return qdbus_cast<QVariantMap >(var);
-}
-
-QVariantMap QConnmanServiceInterface::getEthernet()
-{
- QVariant var = getProperty("Ethernet");
- return qdbus_cast<QVariantMap >(var);
-}
-
-QString QConnmanServiceInterface::getMethod()
-{
- QVariant var;
- QVariantMap map = getEthernet();
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "Method") {
- return it.value().toString();
- }
- }
- return QString();
-}
-
-QString QConnmanServiceInterface::getInterface()
-{
- QVariant var;
- QVariantMap map = getEthernet();
-
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "Interface") {
- return it.value().toString();
- }
- }
-
- return QString();
-}
-
-QString QConnmanServiceInterface::getMacAddress()
-{
- QVariant var;
- QVariantMap map = getEthernet();
-
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "Address") {
- return it.value().toString();
- }
- }
- return QString();
-}
-
-quint16 QConnmanServiceInterface::getMtu()
-{
- quint16 mtu=0;
- QVariant var;
- QVariantMap map = getEthernet();
-
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "MTU") {
- return it.value().toUInt();
- }
- }
- return mtu;
-}
-
-quint16 QConnmanServiceInterface::getSpeed()
+QString QConnmanServiceInterface::serviceInterface()
{
- quint16 speed=0;
- QVariant var;
- QVariantMap map = getEthernet();
-
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "Speed") {
- return it.value().toUInt();
- }
- }
- return speed;
+ QVariantMap map = ethernet();
+ return map.value(QStringLiteral("Interface")).toString();
}
-QString QConnmanServiceInterface::getDuplex()
-{
- QVariant var;
- QVariantMap map = getEthernet();
-
- QMapIterator<QString,QVariant> it(map);
- while(it.hasNext()) {
- it.next();
- if(it.key() == "Duplex") {
- return it.value().toString();
- }
- }
- return QString();
-}
-
-
bool QConnmanServiceInterface::isOfflineMode()
{
- QVariant var = getProperty("OfflineMode");
+ QVariant var = getProperty(QStringLiteral("OfflineMode"));
return qdbus_cast<bool>(var);
}
-QStringList QConnmanServiceInterface::getServices()
+QStringList QConnmanServiceInterface::services()
{
- QVariant var = getProperty("Services");
+ QVariant var = getProperty(QStringLiteral("Services"));
return qdbus_cast<QStringList>(var);
}
-
//////////////////////////
QConnmanTechnologyInterface::QConnmanTechnologyInterface(const QString &dbusPathName,QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
+ : QDBusAbstractInterface(QStringLiteral(CONNMAN_SERVICE),
dbusPathName,
CONNMAN_TECHNOLOGY_INTERFACE,
QDBusConnection::systemBus(), parent)
@@ -791,154 +463,52 @@ void QConnmanTechnologyInterface::connectNotify(const QMetaMethod &signal)
{
static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanTechnologyInterface::propertyChanged);
if (signal == propertyChangedSignal) {
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- this->path(),
- QLatin1String(CONNMAN_TECHNOLOGY_INTERFACE),
- QLatin1String("PropertyChanged"),
+ QDBusConnection::systemBus().connect(QStringLiteral(CONNMAN_SERVICE),
+ path(),
+ QStringLiteral(CONNMAN_TECHNOLOGY_INTERFACE),
+ QStringLiteral("PropertyChanged"),
this,SIGNAL(propertyChanged(QString,QDBusVariant)));
}
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QConnmanTechnologyInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QConnmanDBusHelper *helper;
- helper = new QConnmanDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
- this->path(),
- QLatin1String(CONNMAN_TECHNOLOGY_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
- }
}
-void QConnmanTechnologyInterface::disconnectNotify(const QMetaMethod &signal)
+QVariantMap QConnmanTechnologyInterface::properties()
{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanTechnologyInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
+ if (propertiesMap.isEmpty()) {
+ QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
+ reply.waitForFinished();
+ propertiesMap = reply.value();
}
-}
-
-QVariantMap QConnmanTechnologyInterface::getProperties()
-{
- QDBusReply<QVariantMap> reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
+ return propertiesMap;
}
QVariant QConnmanTechnologyInterface::getProperty(const QString &property)
{
QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- }
+ QVariantMap map = properties();
+ var = map.value(property);
return var;
}
-// properties
-QString QConnmanTechnologyInterface::getState()
-{
- QVariant var = getProperty("State");
- return qdbus_cast<QString>(var);
-}
-
-QString QConnmanTechnologyInterface::getName()
-{
- QVariant var = getProperty("Name");
- return qdbus_cast<QString>(var);
-}
-
-QString QConnmanTechnologyInterface::getType()
+QString QConnmanTechnologyInterface::type()
{
- QVariant var = getProperty("Type");
+ QVariant var = getProperty(QStringLiteral("Type"));
return qdbus_cast<QString>(var);
}
-
-//////////////////////////////////
-QConnmanAgentInterface::QConnmanAgentInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
- dbusPathName,
- CONNMAN_AGENT_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QConnmanAgentInterface::~QConnmanAgentInterface()
-{
-}
-
-void QConnmanAgentInterface::connectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-}
-
-void QConnmanAgentInterface::disconnectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-}
-
-
-void QConnmanAgentInterface::release()
-{
-}
-
-void QConnmanAgentInterface::reportError(QDBusObjectPath &/*path*/, const QString &/*error*/)
-{
-}
-
-void QConnmanAgentInterface::cancel()
-{
-}
-
-
-/////////////////////////////////////////
-QConnmanCounterInterface::QConnmanCounterInterface(const QString &dbusPathName,QObject *parent)
- : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
- dbusPathName,
- CONNMAN_COUNTER_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QConnmanCounterInterface::~QConnmanCounterInterface()
-{
-}
-
-quint32 QConnmanCounterInterface::getReceivedByteCount()
-{
- return 0;
-}
-
-quint32 QConnmanCounterInterface::getTransmittedByteCount()
-{
- return 0;
-}
-
-quint64 QConnmanCounterInterface::getTimeOnline()
-{
- return 0;
-}
-
-/////////////////////////////////////////
-QConnmanDBusHelper::QConnmanDBusHelper(QObject * parent)
- : QObject(parent)
-{
-}
-
-QConnmanDBusHelper::~QConnmanDBusHelper()
+void QConnmanTechnologyInterface::scan()
{
+ QDBusPendingReply<> reply = asyncCall(QLatin1String("Scan"));
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
+ this, SLOT(scanReply(QDBusPendingCallWatcher*)));
}
-void QConnmanDBusHelper::propertyChanged(const QString &item, const QDBusVariant &var)
+void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call)
{
- QDBusMessage msg = this->message();
- Q_EMIT propertyChangedContext(msg.path() ,item, var);
+ Q_EMIT scanFinished();
+ call->deleteLater();
}
-/////////////////
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
index dd3f847cfd..250f90e2d0 100644
--- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h
+++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h
@@ -71,22 +71,12 @@
#ifndef __CONNMAN_DBUS_H
-#define CONNMAN_SERVICE "net.connman"
-#define CONNMAN_PATH "/net/connman"
-
-#define CONNMAN_DEBUG_INTERFACE CONNMAN_SERVICE ".Debug"
-#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
-#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
-#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
-
-#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
-#define CONNMAN_MANAGER_PATH "/"
-
-#define CONNMAN_TASK_INTERFACE CONNMAN_SERVICE ".Task"
-#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
-#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
-#define CONNMAN_PROVIDER_INTERFACE CONNMAN_SERVICE ".Provider"
-#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_SERVICE "net.connman"
+#define CONNMAN_PATH "/net/connman"
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_MANAGER_PATH "/"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
#endif
QT_BEGIN_NAMESPACE
@@ -108,6 +98,9 @@ QT_BEGIN_NAMESPACE
QDBusArgument &operator<<(QDBusArgument &argument, const ConnmanMap &obj);
const QDBusArgument &operator>>(const QDBusArgument &argument, ConnmanMap &obj);
+class QConnmanTechnologyInterface;
+class QConnmanServiceInterface;
+
class QConnmanManagerInterface : public QDBusAbstractInterface
{
Q_OBJECT
@@ -117,39 +110,16 @@ public:
QConnmanManagerInterface( QObject *parent = 0);
~QConnmanManagerInterface();
- QDBusObjectPath path() const;
-
+ QDBusObjectPath path() const;
QVariantMap getProperties();
- bool setProperty(const QString &name, const QDBusVariant &value);
- QDBusObjectPath createProfile(const QString &name);
- bool removeProfile(QDBusObjectPath path);
- bool requestScan(const QString &type);
- bool enableTechnology(const QString &type);
- bool disableTechnology(const QString &type);
- QDBusObjectPath connectService(QVariantMap &map);
- void registerAgent(QDBusObjectPath &path);
- void unregisterAgent(QDBusObjectPath path);
- void registerCounter(const QString &path, quint32 interval);
- void unregisterCounter(const QString &path);
-
- QString requestSession(const QString &bearerName);
- void releaseSession();
-
- // properties
+
QString getState();
- QStringList getAvailableTechnologies();
- QStringList getEnabledTechnologies();
- QStringList getConnectedTechnologies();
- QString getDefaultTechnology();
bool getOfflineMode();
- QString getActiveProfile();
- QStringList getProfiles();
- QStringList getTechnologies();
+ QStringList getTechnologies();
QStringList getServices();
- QDBusObjectPath lookupService(const QString &);
-
- QString getPathForTechnology(const QString &tech);
+ void requestScan(const QString &type);
+ QHash<QString, QConnmanTechnologyInterface *> technologiesMap;
Q_SIGNALS:
void propertyChanged(const QString &, const QDBusVariant &value);
@@ -157,41 +127,28 @@ Q_SIGNALS:
void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
void servicesChanged(const ConnmanMapList&, const QList<QDBusObjectPath> &);
+ void servicesReady(const QStringList &);
+ void scanFinished();
+
protected:
void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
QVariant getProperty(const QString &);
+private:
+ QVariantMap propertiesCacheMap;
+ QStringList servicesList;
+ QStringList technologiesList;
+
private slots:
void onServicesChanged(const ConnmanMapList&, const QList<QDBusObjectPath> &);
+ void changedProperty(const QString &, const QDBusVariant &value);
-};
+ void propertiesReply(QDBusPendingCallWatcher *call);
+ void servicesReply(QDBusPendingCallWatcher *call);
-class QConnmanProfileInterfacePrivate;
-class QConnmanProfileInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
+ void technologyAdded(const QDBusObjectPath &technology, const QVariantMap &properties);
+ void technologyRemoved(const QDBusObjectPath &technology);
- explicit QConnmanProfileInterface(const QString &dbusPathName,QObject *parent = 0);
- ~QConnmanProfileInterface();
-
- QVariantMap getProperties();
-// properties
- QString getName();
- bool isOfflineMode();
- QStringList getServices();
-
-Q_SIGNALS:
- void propertyChanged(const QString &, const QDBusVariant &value);
-private:
- QConnmanProfileInterfacePrivate *d;
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
};
class QConnmanServiceInterface : public QDBusAbstractInterface
@@ -208,52 +165,37 @@ public:
void connect();
void disconnect();
void remove();
- // void moveBefore(QDBusObjectPath &service);
- // void moveAfter(QDBusObjectPath &service);
// properties
- QString getState();
- QString getError();
- QString getName();
- QString getType();
- QString getMode();
- QString getSecurity();
- QString getPassphrase();
- bool isPassphraseRequired();
- quint8 getSignalStrength();
- bool isFavorite();
- bool isImmutable();
- bool isAutoConnect();
- bool isSetupRequired();
- QString getAPN();
- QString getMCC();
- QString getMNC();
- bool isRoaming();
- QStringList getNameservers();
- QStringList getDomains();
- QVariantMap getIPv4();
- QVariantMap getIPv4Configuration();
- QVariantMap getProxy();
- QVariantMap getEthernet();
-
- QString getMethod();
- QString getInterface();
- QString getMacAddress();
- quint16 getMtu();
- quint16 getSpeed();
- QString getDuplex();
+ QString state();
+ QString lastError();
+ QString name();
+ QString type();
+ QString security();
+ bool favorite();
+ bool autoConnect();
+ bool roaming();
+ QVariantMap ethernet();
+ QString serviceInterface();
bool isOfflineMode();
- QStringList getServices();
+ QStringList services();
Q_SIGNALS:
void propertyChanged(const QString &, const QDBusVariant &value);
void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
+ void propertiesReady();
+ void stateChanged(const QString &state);
protected:
void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
QVariant getProperty(const QString &);
+private:
+ QVariantMap propertiesCacheMap;
+private slots:
+ void propertiesReply(QDBusPendingCallWatcher *call);
+ void changedProperty(const QString &, const QDBusVariant &value);
+
};
class QConnmanTechnologyInterface : public QDBusAbstractInterface
@@ -265,72 +207,21 @@ public:
explicit QConnmanTechnologyInterface(const QString &dbusPathName,QObject *parent = 0);
~QConnmanTechnologyInterface();
- QVariantMap getProperties();
-// properties
- QString getState();
- QString getName();
- QString getType();
+ QString type();
+ void scan();
Q_SIGNALS:
void propertyChanged(const QString &, const QDBusVariant &value);
void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
+ void scanFinished();
protected:
void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
QVariant getProperty(const QString &);
-
-};
-
-class QConnmanAgentInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-
- explicit QConnmanAgentInterface(const QString &dbusPathName,QObject *parent = 0);
- ~QConnmanAgentInterface();
-
- void release();
- void reportError(QDBusObjectPath &path, const QString &error);
-// dict requestInput(QDBusObjectPath &path, dict fields);
- void cancel();
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
-};
-
-class QConnmanCounterInterfacePrivate;
-class QConnmanCounterInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-
- explicit QConnmanCounterInterface(const QString &dbusPathName, QObject *parent = 0);
- ~QConnmanCounterInterface();
-
-// void release();
- QString getInterface();
- quint32 getReceivedByteCount();
- quint32 getTransmittedByteCount();
- quint64 getTimeOnline();
-
private:
- QConnmanCounterInterfacePrivate *d;
-};
-
-class QConnmanDBusHelper: public QObject, protected QDBusContext
- {
- Q_OBJECT
- public:
- QConnmanDBusHelper(QObject *parent = 0);
- ~QConnmanDBusHelper();
+ QVariantMap properties();
+ QVariantMap propertiesMap;
+ void scanReply(QDBusPendingCallWatcher *call);
- public slots:
- void propertyChanged(const QString &, const QDBusVariant &);
-
-Q_SIGNALS:
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
};
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/connman/qofonoservice_linux.cpp
index 1983276d94..f5da52a341 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux.cpp
+++ b/src/plugins/bearer/connman/qofonoservice_linux.cpp
@@ -75,256 +75,133 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, ObjectPathPropert
QT_BEGIN_NAMESPACE
QOfonoManagerInterface::QOfonoManagerInterface( QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
- QLatin1String(OFONO_MANAGER_PATH),
+ : QDBusAbstractInterface(QStringLiteral(OFONO_SERVICE),
+ QStringLiteral(OFONO_MANAGER_PATH),
OFONO_MANAGER_INTERFACE,
QDBusConnection::systemBus(), parent)
{
qDBusRegisterMetaType<ObjectPathProperties>();
qDBusRegisterMetaType<PathPropertiesList>();
+
+ QDBusConnection::systemBus().connect(QStringLiteral(OFONO_SERVICE),
+ QStringLiteral(OFONO_MANAGER_PATH),
+ QStringLiteral(OFONO_MANAGER_INTERFACE),
+ QStringLiteral("ModemAdded"),
+ this,SLOT(modemAdded(QDBusObjectPath, QVariantMap)));
+ QDBusConnection::systemBus().connect(QStringLiteral(OFONO_SERVICE),
+ QStringLiteral(OFONO_MANAGER_PATH),
+ QStringLiteral(OFONO_MANAGER_INTERFACE),
+ QStringLiteral("ModemRemoved"),
+ this,SLOT(modemRemoved(QDBusObjectPath)));
}
QOfonoManagerInterface::~QOfonoManagerInterface()
{
}
-QList <QDBusObjectPath> QOfonoManagerInterface::getModems()
+QStringList QOfonoManagerInterface::getModems()
{
- QList <QDBusObjectPath> modemList;
- QList<QVariant> argumentList;
- QDBusReply<PathPropertiesList > reply = this->asyncCallWithArgumentList(QLatin1String("GetModems"), argumentList);
- if (reply.isValid()) {
- foreach (ObjectPathProperties modem, reply.value()) {
- modemList << modem.path;
+ if (modemList.isEmpty()) {
+ QList<QVariant> argumentList;
+ QDBusPendingReply<PathPropertiesList> reply = asyncCallWithArgumentList(QLatin1String("GetModems"), argumentList);
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ foreach (ObjectPathProperties modem, reply.value()) {
+ modemList << modem.path.path();
+ }
+ } else {
+ qDebug() << reply.error().message();
}
}
return modemList;
}
-QDBusObjectPath QOfonoManagerInterface::currentModem()
+QString QOfonoManagerInterface::currentModem()
{
- QList<QDBusObjectPath> modems = getModems();
- foreach (const QDBusObjectPath &modem, modems) {
- QOfonoModemInterface device(modem.path());
+ QStringList modems = getModems();
+ foreach (const QString &modem, modems) {
+ QOfonoModemInterface device(modem);
if (device.isPowered() && device.isOnline())
return modem;
}
- return QDBusObjectPath();
-}
-
-
-void QOfonoManagerInterface::connectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoManagerInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- QLatin1String(OFONO_MANAGER_PATH),
- QLatin1String(OFONO_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
- qWarning() << "PropertyCHanged not connected";
- }
- }
-
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoManagerInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QOfonoDBusHelper *helper;
- helper = new QOfonoDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
- QLatin1String(OFONO_MANAGER_PATH),
- QLatin1String(OFONO_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)));
- }
+ return QString();
}
-void QOfonoManagerInterface::disconnectNotify(const QMetaMethod &signal)
+void QOfonoManagerInterface::modemAdded(const QDBusObjectPath &path, const QVariantMap &/*var*/)
{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoManagerInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
+ if (!modemList.contains(path.path())) {
+ modemList << path.path();
+ Q_EMIT modemChanged();
}
}
-QVariant QOfonoManagerInterface::getProperty(const QString &property)
+void QOfonoManagerInterface::modemRemoved(const QDBusObjectPath &path)
{
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- return map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
+ if (modemList.contains(path.path())) {
+ modemList.removeOne(path.path());
+ Q_EMIT modemChanged();
}
- return QVariant();
-}
-
-QVariantMap QOfonoManagerInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- if (reply.isValid())
- return reply.value();
- else
- return QVariantMap();
-}
-
-QOfonoDBusHelper::QOfonoDBusHelper(QObject * parent)
- : QObject(parent)
-{
-}
-
-QOfonoDBusHelper::~QOfonoDBusHelper()
-{
-}
-
-void QOfonoDBusHelper::propertyChanged(const QString &item, const QDBusVariant &var)
-{
- QDBusMessage msg = this->message();
- Q_EMIT propertyChangedContext(msg.path() ,item, var);
}
QOfonoModemInterface::QOfonoModemInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ : QDBusAbstractInterface(QStringLiteral(OFONO_SERVICE),
dbusPathName,
OFONO_MODEM_INTERFACE,
QDBusConnection::systemBus(), parent)
{
+ QDBusConnection::systemBus().connect(QStringLiteral(OFONO_SERVICE),
+ path(),
+ OFONO_MODEM_INTERFACE,
+ QStringLiteral("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
}
QOfonoModemInterface::~QOfonoModemInterface()
{
}
-bool QOfonoModemInterface::isPowered()
+void QOfonoModemInterface::propertyChanged(const QString &name,const QDBusVariant &value)
{
- QVariant var = getProperty("Powered");
- return qdbus_cast<bool>(var);
+ propertiesMap[name] = value.variant();
}
-bool QOfonoModemInterface::isOnline()
+bool QOfonoModemInterface::isPowered()
{
- QVariant var = getProperty("Online");
+ QVariant var = getProperty(QStringLiteral("Powered"));
return qdbus_cast<bool>(var);
}
-QString QOfonoModemInterface::getName()
-{
- QVariant var = getProperty("Name");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoModemInterface::getManufacturer()
-{
- QVariant var = getProperty("Manufacturer");
- return qdbus_cast<QString>(var);
-
-}
-
-QString QOfonoModemInterface::getModel()
-{
-
- QVariant var = getProperty("Model");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoModemInterface::getRevision()
-{
- QVariant var = getProperty("Revision");
- return qdbus_cast<QString>(var);
-
-}
-QString QOfonoModemInterface::getSerial()
-{
- QVariant var = getProperty("Serial");
- return qdbus_cast<QString>(var);
-
-}
-
-QStringList QOfonoModemInterface::getFeatures()
-{
- //sms, sim
- QVariant var = getProperty("Features");
- return qdbus_cast<QStringList>(var);
-}
-
-QStringList QOfonoModemInterface::getInterfaces()
-{
- QVariant var = getProperty("Interfaces");
- return qdbus_cast<QStringList>(var);
-}
-
-QString QOfonoModemInterface::defaultInterface()
+bool QOfonoModemInterface::isOnline()
{
- foreach (const QString &modem,getInterfaces()) {
- return modem;
- }
- return QString();
+ QVariant var = getProperty(QStringLiteral("Online"));
+ return qdbus_cast<bool>(var);
}
-
-void QOfonoModemInterface::connectNotify(const QMetaMethod &signal)
+QVariantMap QOfonoModemInterface::getProperties()
{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoModemInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_MODEM_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
- qWarning() << "PropertyCHanged not connected";
- }
+ if (propertiesMap.isEmpty()) {
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
}
-
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoModemInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QOfonoDBusHelper *helper;
- helper = new QOfonoDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_MODEM_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
- }}
-
-void QOfonoModemInterface::disconnectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoModemInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
}
-}
-
-QVariantMap QOfonoModemInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
+ return propertiesMap;
}
QVariant QOfonoModemInterface::getProperty(const QString &property)
{
QVariant var;
QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
+ var = map.value(property);
return var;
}
QOfonoNetworkRegistrationInterface::QOfonoNetworkRegistrationInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
+ : QDBusAbstractInterface(QStringLiteral(OFONO_SERVICE),
dbusPathName,
OFONO_NETWORK_REGISTRATION_INTERFACE,
QDBusConnection::systemBus(), parent)
@@ -335,337 +212,33 @@ QOfonoNetworkRegistrationInterface::~QOfonoNetworkRegistrationInterface()
{
}
-QString QOfonoNetworkRegistrationInterface::getStatus()
-{
- /*
- "unregistered" Not registered to any network
- "registered" Registered to home network
- "searching" Not registered, but searching
- "denied" Registration has been denied
- "unknown" Status is unknown
- "roaming" Registered, but roaming*/
- QVariant var = getProperty("Status");
- return qdbus_cast<QString>(var);
-}
-
-quint16 QOfonoNetworkRegistrationInterface::getLac()
-{
- QVariant var = getProperty("LocationAreaCode");
- return var.value<quint16>();
-}
-
-
-quint32 QOfonoNetworkRegistrationInterface::getCellId()
-{
- QVariant var = getProperty("CellId");
- return var.value<quint32>();
-}
-
QString QOfonoNetworkRegistrationInterface::getTechnology()
{
- // "gsm", "edge", "umts", "hspa","lte"
- QVariant var = getProperty("Technology");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoNetworkRegistrationInterface::getOperatorName()
-{
- QVariant var = getProperty("Name");
+ QVariant var = getProperty(QStringLiteral("Technology"));
return qdbus_cast<QString>(var);
}
-int QOfonoNetworkRegistrationInterface::getSignalStrength()
-{
- QVariant var = getProperty("Strength");
- return qdbus_cast<int>(var);
-
-}
-
-QString QOfonoNetworkRegistrationInterface::getBaseStation()
-{
- QVariant var = getProperty("BaseStation");
- return qdbus_cast<QString>(var);
-}
-
-QList <QDBusObjectPath> QOfonoNetworkRegistrationInterface::getOperators()
-{
- QList <QDBusObjectPath> operatorList;
- QList<QVariant> argumentList;
- QDBusReply<PathPropertiesList > reply = this->asyncCallWithArgumentList(QLatin1String("GetOperators"),
- argumentList);
- if (reply.isValid()) {
- foreach (ObjectPathProperties netop, reply.value()) {
- operatorList << netop.path;
- }
- }
- return operatorList;
-}
-
-void QOfonoNetworkRegistrationInterface::connectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoNetworkRegistrationInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_NETWORK_REGISTRATION_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
- qWarning() << "PropertyCHanged not connected";
- }
- }
-
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoNetworkRegistrationInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QOfonoDBusHelper *helper;
- helper = new QOfonoDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_NETWORK_REGISTRATION_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
- }
-}
-
-void QOfonoNetworkRegistrationInterface::disconnectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoNetworkRegistrationInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
- }
-}
-
QVariant QOfonoNetworkRegistrationInterface::getProperty(const QString &property)
{
QVariant var;
QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
+ var = map.value(property);
return var;
}
QVariantMap QOfonoNetworkRegistrationInterface::getProperties()
{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
-
-
-
-QOfonoNetworkOperatorInterface::QOfonoNetworkOperatorInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
- dbusPathName,
- OFONO_NETWORK_OPERATOR_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QOfonoNetworkOperatorInterface::~QOfonoNetworkOperatorInterface()
-{
-}
-
-QString QOfonoNetworkOperatorInterface::getName()
-{
- QVariant var = getProperty("Name");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoNetworkOperatorInterface::getStatus()
-{
- // "unknown", "available", "current" and "forbidden"
- QVariant var = getProperty("Status");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoNetworkOperatorInterface::getMcc()
-{
- QVariant var = getProperty("MobileCountryCode");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoNetworkOperatorInterface::getMnc()
-{
- QVariant var = getProperty("MobileNetworkCode");
- return qdbus_cast<QString>(var);
-}
-
-QStringList QOfonoNetworkOperatorInterface::getTechnologies()
-{
- QVariant var = getProperty("Technologies");
- return qdbus_cast<QStringList>(var);
-}
-
-void QOfonoNetworkOperatorInterface::connectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoNetworkOperatorInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-// if (!connection().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_NETWORK_OPERATOR_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
-// qWarning() << "PropertyCHanged not connected";
-// }
-// }
-
-// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoNetworkOperatorInterface::propertyChangedContext);
-// if (signal == propertyChangedContextSignal) {
-// QOfonoDBusHelper *helper;
-// helper = new QOfonoDBusHelper(this);
-
-// QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_NETWORK_OPERATOR_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
-// QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
-// this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
-// }
-}
-
-void QOfonoNetworkOperatorInterface::disconnectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoNetworkOperatorInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-
-// }
-}
-
-QVariant QOfonoNetworkOperatorInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
- return var;
-}
-
-QVariantMap QOfonoNetworkOperatorInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
-
-QOfonoSimInterface::QOfonoSimInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
- dbusPathName,
- OFONO_SIM_MANAGER_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QOfonoSimInterface::~QOfonoSimInterface()
-{
-}
-
-bool QOfonoSimInterface::isPresent()
-{
- QVariant var = getProperty("Present");
- return qdbus_cast<bool>(var);
-}
-
-QString QOfonoSimInterface::getHomeMcc()
-{
- QVariant var = getProperty("MobileCountryCode");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoSimInterface::getHomeMnc()
-{
- QVariant var = getProperty("MobileNetworkCode");
- return qdbus_cast<QString>(var);
-}
-
-// QStringList subscriberNumbers();
-// QMap<QString,QString> serviceNumbers();
-QString QOfonoSimInterface::pinRequired()
-{
- QVariant var = getProperty("PinRequired");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoSimInterface::lockedPins()
-{
- QVariant var = getProperty("LockedPins");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoSimInterface::cardIdentifier()
-{
- QVariant var = getProperty("CardIdentifier");
- return qdbus_cast<QString>(var);
-}
-
-void QOfonoSimInterface::connectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoSimInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-// if (!connection().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_SIM_MANAGER_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
-// qWarning() << "PropertyCHanged not connected";
-// }
-// }
-
-// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoSimInterface::propertyChangedContext);
-// if (signal == propertyChangedContextSignal) {
-// QOfonoDBusHelper *helper;
-// helper = new QOfonoDBusHelper(this);
-
-// QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_SIM_MANAGER_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
-// QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
-// this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
-// }
-}
-
-void QOfonoSimInterface::disconnectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoSimInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-
-// }
-}
-
-QVariant QOfonoSimInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
+ if (propertiesMap.isEmpty()) {
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
+ } else {
+ qDebug() << reply.error().message();
+ }
}
- return var;
-}
-
-QVariantMap QOfonoSimInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
+ return propertiesMap;
}
QOfonoDataConnectionManagerInterface::QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent)
@@ -674,340 +247,62 @@ QOfonoDataConnectionManagerInterface::QOfonoDataConnectionManagerInterface(const
OFONO_DATA_CONNECTION_MANAGER_INTERFACE,
QDBusConnection::systemBus(), parent)
{
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
+ path(),
+ QLatin1String(OFONO_MODEM_INTERFACE),
+ QLatin1String("PropertyChanged"),
+ this,SLOT(propertyChanged(QString,QDBusVariant)));
}
QOfonoDataConnectionManagerInterface::~QOfonoDataConnectionManagerInterface()
{
}
-QList<QDBusObjectPath> QOfonoDataConnectionManagerInterface::getPrimaryContexts()
+QStringList QOfonoDataConnectionManagerInterface::contexts()
{
- QList <QDBusObjectPath> contextList;
- QList<QVariant> argumentList;
- QDBusReply<PathPropertiesList > reply = this->asyncCallWithArgumentList(QLatin1String("GetContexts"),
- argumentList);
- if (reply.isValid()) {
- foreach (ObjectPathProperties context, reply.value()) {
- contextList << context.path;
+ if (contextList.isEmpty()) {
+ QDBusPendingReply<PathPropertiesList > reply = call(QLatin1String("GetContexts"));
+ reply.waitForFinished();
+ if (!reply.isError()) {
+ foreach (ObjectPathProperties context, reply.value()) {
+ contextList << context.path.path();
+ }
}
}
return contextList;
}
-bool QOfonoDataConnectionManagerInterface::isAttached()
-{
- QVariant var = getProperty("Attached");
- return qdbus_cast<bool>(var);
-}
-
-bool QOfonoDataConnectionManagerInterface::isRoamingAllowed()
+bool QOfonoDataConnectionManagerInterface::roamingAllowed()
{
- QVariant var = getProperty("RoamingAllowed");
+ QVariant var = getProperty(QStringLiteral("RoamingAllowed"));
return qdbus_cast<bool>(var);
}
-bool QOfonoDataConnectionManagerInterface::isPowered()
-{
- QVariant var = getProperty("Powered");
- return qdbus_cast<bool>(var);
-}
-
-void QOfonoDataConnectionManagerInterface::connectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoDataConnectionManagerInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-// if (!connection().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_DATA_CONNECTION_MANAGER_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
-// qWarning() << "PropertyCHanged not connected";
-// }
-// }
-
-// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoDataConnectionManagerInterface::propertyChangedContext);
-// if (signal == propertyChangedContextSignal) {
-// QOfonoDBusHelper *helper;
-// helper = new QOfonoDBusHelper(this);
-
-// QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_DATA_CONNECTION_MANAGER_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
-// QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
-// this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
-// }
-}
-
-void QOfonoDataConnectionManagerInterface::disconnectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoDataConnectionManagerInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-
-// }
-}
-
QVariant QOfonoDataConnectionManagerInterface::getProperty(const QString &property)
{
QVariant var;
QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
+ var = map.value(property);
return var;
}
QVariantMap QOfonoDataConnectionManagerInterface::getProperties()
{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
-
-QOfonoConnectionContextInterface::QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
- dbusPathName,
- OFONO_DATA_CONTEXT_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QOfonoConnectionContextInterface::~QOfonoConnectionContextInterface()
-{
-}
-
-bool QOfonoConnectionContextInterface::isActive()
-{
- QVariant var = getProperty("Active");
- return qdbus_cast<bool>(var);
-}
-
-QString QOfonoConnectionContextInterface::getApName()
-{
- QVariant var = getProperty("AccessPointName");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoConnectionContextInterface::getType()
-{
- QVariant var = getProperty("Type");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoConnectionContextInterface::getName()
-{
- QVariant var = getProperty("Name");
- return qdbus_cast<QString>(var);
-}
-
-QVariantMap QOfonoConnectionContextInterface::getSettings()
-{
- QVariant var = getProperty("Settings");
- return qdbus_cast<QVariantMap>(var);
-}
-
-QString QOfonoConnectionContextInterface::getInterface()
-{
- QVariant var = getProperty("Interface");
- return qdbus_cast<QString>(var);
-}
-
-QString QOfonoConnectionContextInterface::getAddress()
-{
- QVariant var = getProperty("Address");
- return qdbus_cast<QString>(var);
-}
-
-bool QOfonoConnectionContextInterface::setActive(bool on)
-{
-// this->setProperty("Active", QVariant(on));
-
- return setProp("Active", QVariant::fromValue(on));
-}
-
-bool QOfonoConnectionContextInterface::setApn(const QString &name)
-{
- return setProp("AccessPointName", QVariant::fromValue(name));
-}
-
-void QOfonoConnectionContextInterface::connectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-// if (!connection().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_DATA_CONTEXT_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
-// qWarning() << "PropertyCHanged not connected";
-// }
-// }
-
-// static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChangedContext);
-// if (signal == propertyChangedContextSignal) {
-// QOfonoDBusHelper *helper;
-// helper = new QOfonoDBusHelper(this);
-
-// QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
-// this->path(),
-// QLatin1String(OFONO_DATA_CONTEXT_INTERFACE),
-// QLatin1String("PropertyChanged"),
-// helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
-// QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
-// this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)), Qt::UniqueConnection);
-// }
-}
-
-void QOfonoConnectionContextInterface::disconnectNotify(const QMetaMethod &signal)
-{
- Q_UNUSED(signal);
-// static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoConnectionContextInterface::propertyChanged);
-// if (signal == propertyChangedSignal) {
-
-// }
-}
-
-QVariant QOfonoConnectionContextInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
- return var;
-}
-
-QVariantMap QOfonoConnectionContextInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
-
-bool QOfonoConnectionContextInterface::setProp(const QString &property, const QVariant &var)
-{
- QList<QVariant> args;
- args << QVariant::fromValue(property) << QVariant::fromValue(QDBusVariant(var));
-
- QDBusMessage reply = this->callWithArgumentList(QDBus::AutoDetect,
- QLatin1String("SetProperty"),
- args);
- bool ok = true;
- if (reply.type() != QDBusMessage::ReplyMessage) {
- qWarning() << reply.errorMessage();
- ok = false;
- }
- qWarning() << reply.errorMessage();
- return ok;
-}
-
-QOfonoSmsInterface::QOfonoSmsInterface(const QString &dbusPathName, QObject *parent)
- : QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
- dbusPathName,
- OFONO_SMS_MANAGER_INTERFACE,
- QDBusConnection::systemBus(), parent)
-{
-}
-
-QOfonoSmsInterface::~QOfonoSmsInterface()
-{
-}
-
-void QOfonoSmsInterface::connectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoSmsInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_SMS_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
- qWarning() << "PropertyCHanged not connected";
- }
- }
-
- static const QMetaMethod propertyChangedContextSignal = QMetaMethod::fromSignal(&QOfonoSmsInterface::propertyChangedContext);
- if (signal == propertyChangedContextSignal) {
- QOfonoDBusHelper *helper;
- helper = new QOfonoDBusHelper(this);
-
- QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_SMS_MANAGER_INTERFACE),
- QLatin1String("PropertyChanged"),
- helper,SLOT(propertyChanged(QString,QDBusVariant)));
-
-
- QObject::connect(helper,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)),
- this,SIGNAL(propertyChangedContext(QString,QString,QDBusVariant)));
- }
-
- static const QMetaMethod immediateMessageSignal = QMetaMethod::fromSignal(&QOfonoSmsInterface::immediateMessage);
- if (signal == immediateMessageSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_SMS_MANAGER_INTERFACE),
- QLatin1String("ImmediateMessage"),
- this,SIGNAL(immediateMessage(QString,QVariantMap)))) {
- qWarning() << "PropertyCHanged not connected";
- }
- }
-
- static const QMetaMethod incomingMessageSignal = QMetaMethod::fromSignal(&QOfonoSmsInterface::incomingMessage);
- if (signal == incomingMessageSignal) {
- if (!connection().connect(QLatin1String(OFONO_SERVICE),
- this->path(),
- QLatin1String(OFONO_SMS_MANAGER_INTERFACE),
- QLatin1String("IncomingMessage"),
- this,SIGNAL(incomingMessage(QString,QVariantMap)))) {
- qWarning() << "PropertyCHanged not connected";
+ if (propertiesMap.isEmpty()) {
+ QList<QVariant> argumentList;
+ QDBusPendingReply<QVariantMap> reply = asyncCallWithArgumentList(QLatin1String("GetProperties"), argumentList);
+ if (!reply.isError()) {
+ propertiesMap = reply.value();
}
}
+ return propertiesMap;
}
-void QOfonoSmsInterface::disconnectNotify(const QMetaMethod &signal)
-{
- static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QOfonoSmsInterface::propertyChanged);
- if (signal == propertyChangedSignal) {
-
- }
-}
-
-QVariant QOfonoSmsInterface::getProperty(const QString &property)
-{
- QVariant var;
- QVariantMap map = getProperties();
- if (map.contains(property)) {
- var = map.value(property);
- } else {
- qDebug() << Q_FUNC_INFO << "does not contain" << property;
- }
- return var;
-}
-
-QVariantMap QOfonoSmsInterface::getProperties()
-{
- QDBusReply<QVariantMap > reply = this->call(QLatin1String("GetProperties"));
- return reply.value();
-}
-
-void QOfonoSmsInterface::sendMessage(const QString &to, const QString &message)
+void QOfonoDataConnectionManagerInterface::propertyChanged(const QString &name, const QDBusVariant &value)
{
- QDBusReply<QString> reply = this->call(QLatin1String("SendMessage"),
- QVariant::fromValue(to),
- QVariant::fromValue(message));
- if (reply.error().type() == QDBusError::InvalidArgs)
- qWarning("%s", qPrintable(reply.error().message()));
+ propertiesMap[name] = value.variant();
+ if (name == QStringLiteral("RoamingAllowed"))
+ Q_EMIT roamingAllowedChanged(value.variant().toBool());
}
QT_END_NAMESPACE
diff --git a/src/plugins/bearer/connman/qofonoservice_linux_p.h b/src/plugins/bearer/connman/qofonoservice_linux_p.h
index 25bffacceb..8fea465fd0 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux_p.h
+++ b/src/plugins/bearer/connman/qofonoservice_linux_p.h
@@ -68,21 +68,13 @@
#ifndef QT_NO_BEARERMANAGEMENT
#ifndef QT_NO_DBUS
-#define OFONO_SERVICE "org.ofono"
+#define OFONO_SERVICE "org.ofono"
#define OFONO_MANAGER_INTERFACE "org.ofono.Manager"
#define OFONO_MANAGER_PATH "/"
+
#define OFONO_MODEM_INTERFACE "org.ofono.Modem"
#define OFONO_NETWORK_REGISTRATION_INTERFACE "org.ofono.NetworkRegistration"
-#define OFONO_NETWORK_OPERATOR_INTERFACE "org.ofono.NetworkOperator"
#define OFONO_DATA_CONNECTION_MANAGER_INTERFACE "org.ofono.ConnectionManager"
-#define OFONO_SIM_MANAGER_INTERFACE "org.ofono.SimManager"
-#define OFONO_DATA_CONTEXT_INTERFACE "org.ofono.ConnectionContext"
-
-#define OFONO_SMS_MANAGER_INTERFACE "org.ofono.SmsManager"
-#define OFONO_PHONEBOOK_INTERFACE "org.ofono.Phonebook"
-#define OFONO_MESSAGE_WAITING_INTERFACE "org.ofono.MessageWaiting"
-
-
QT_BEGIN_NAMESPACE
@@ -108,35 +100,15 @@ public:
QOfonoManagerInterface( QObject *parent = 0);
~QOfonoManagerInterface();
- QDBusObjectPath path() const;
-
- QVariantMap getProperties();
- bool setProperty(const QString &name, const QDBusVariant &value);
- QList <QDBusObjectPath> getModems();
- QDBusObjectPath currentModem();
-
-Q_SIGNALS:
- void propertyChanged(const QString &, const QDBusVariant &value);
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
-
-};
-
-
-class QOfonoDBusHelper: public QObject, protected QDBusContext
- {
- Q_OBJECT
- public:
- QOfonoDBusHelper(QObject *parent = 0);
- ~QOfonoDBusHelper();
-
- public slots:
- void propertyChanged(const QString &, const QDBusVariant &);
- Q_SIGNALS:
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
+ QStringList getModems();
+ QString currentModem();
+signals:
+ void modemChanged();
+private:
+ QStringList modemList;
+private slots:
+ void modemAdded(const QDBusObjectPath &path, const QVariantMap &var);
+ void modemRemoved(const QDBusObjectPath &path);
};
class QOfonoModemInterface : public QDBusAbstractInterface
@@ -148,27 +120,13 @@ public:
explicit QOfonoModemInterface(const QString &dbusModemPathName, QObject *parent = 0);
~QOfonoModemInterface();
- QVariantMap getProperties();
- //properties
bool isPowered();
bool isOnline();
- QString getName();
- QString getManufacturer();
- QString getModel();
- QString getRevision();
- QString getSerial();
-
- QStringList getFeatures(); //sms, sim
- QStringList getInterfaces();
- QString defaultInterface();
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
+private:
+ QVariantMap getProperties();
+ QVariantMap propertiesMap;
QVariant getProperty(const QString &);
-Q_SIGNALS:
void propertyChanged(const QString &, const QDBusVariant &value);
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
};
@@ -181,80 +139,16 @@ public:
explicit QOfonoNetworkRegistrationInterface(const QString &dbusModemPathName, QObject *parent = 0);
~QOfonoNetworkRegistrationInterface();
- QVariantMap getProperties();
-
- //properties
- QString getStatus();
- quint16 getLac();
- quint32 getCellId();
QString getTechnology();
- QString getOperatorName();
- int getSignalStrength();
- QString getBaseStation();
- QList <QDBusObjectPath> getOperators();
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
-Q_SIGNALS:
- void propertyChanged(const QString &, const QDBusVariant &value);
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
-
-};
-
-class QOfonoNetworkOperatorInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-//modem or operator paths
- explicit QOfonoNetworkOperatorInterface(const QString &dbusPathName, QObject *parent = 0);
- ~QOfonoNetworkOperatorInterface();
-
- QVariantMap getProperties();
-
- //properties
- QString getName();
- QString getStatus();// "unknown", "available", "current" and "forbidden"
- QString getMcc();
- QString getMnc();
- QStringList getTechnologies();
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
-};
-
-class QOfonoSimInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-
- explicit QOfonoSimInterface(const QString &dbusModemPathName, QObject *parent = 0);
- ~QOfonoSimInterface();
+private:
QVariantMap getProperties();
-
- //properties
- bool isPresent();
- QString getHomeMcc();
- QString getHomeMnc();
-// QStringList subscriberNumbers();
-// QMap<QString,QString> serviceNumbers();
- QString pinRequired();
- QString lockedPins();
- QString cardIdentifier();
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
QVariant getProperty(const QString &);
+ QVariantMap propertiesMap;
+Q_SIGNALS:
+ void propertyChanged(const QString &, const QDBusVariant &value);
};
-
class QOfonoDataConnectionManagerInterface : public QDBusAbstractInterface
{
Q_OBJECT
@@ -264,82 +158,20 @@ public:
explicit QOfonoDataConnectionManagerInterface(const QString &dbusPathName, QObject *parent = 0);
~QOfonoDataConnectionManagerInterface();
+ QStringList contexts();
+ bool roamingAllowed();
+Q_SIGNALS:
+ void roamingAllowedChanged(bool);
+private:
QVariantMap getProperties();
-
- //properties
- QList<QDBusObjectPath> getPrimaryContexts();
- bool isAttached();
- bool isRoamingAllowed();
- bool isPowered();
-
- bool setPower(bool on);
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
-};
-
-
-class QOfonoConnectionContextInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-
- explicit QOfonoConnectionContextInterface(const QString &dbusPathName, QObject *parent = 0);
- ~QOfonoConnectionContextInterface();
-
- QVariantMap getProperties();
-
- //properties
- bool isActive();
- QString getApName();
- QString getType();
- QString getName();
- QVariantMap getSettings();
- QString getInterface();
- QString getAddress();
-
- bool setActive(bool on);
- bool setApn(const QString &name);
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
- QVariant getProperty(const QString &);
- bool setProp(const QString &, const QVariant &var);
-};
-
-class QOfonoSmsInterface : public QDBusAbstractInterface
-{
- Q_OBJECT
-
-public:
-
- explicit QOfonoSmsInterface(const QString &dbusModemPathName, QObject *parent = 0);
- ~QOfonoSmsInterface();
-
- QVariantMap getProperties();
- void sendMessage(const QString &to, const QString &message);
-
- //properties
- QString serviceCenterAddress();
- bool useDeliveryReports();
- QString bearer();
-
-protected:
- void connectNotify(const QMetaMethod &signal);
- void disconnectNotify(const QMetaMethod &signal);
+ QVariantMap propertiesMap;
QVariant getProperty(const QString &);
-
-Q_SIGNALS:
+ QStringList contextList;
+private slots:
void propertyChanged(const QString &, const QDBusVariant &value);
- void propertyChangedContext(const QString &,const QString &,const QDBusVariant &);
- void immediateMessage(const QString &message, const QVariantMap &info);
- void incomingMessage(const QString &message, const QVariantMap &info);
};
+
QT_END_NAMESPACE
#endif // QT_NO_DBUS
diff --git a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
index 7febe27ad2..74a25c1370 100644
--- a/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
+++ b/src/plugins/bearer/networkmanager/qnetworkmanagerservice.h
@@ -99,28 +99,28 @@ typedef enum
NM_ACTIVE_CONNECTION_STATE_ACTIVATED
} NMActiveConnectionState;
-#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
+#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
-#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
-#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
-#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
+#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
+#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
+#define NM_DBUS_INTERFACE_DEVICE NM_DBUS_INTERFACE ".Device"
#define NM_DBUS_INTERFACE_DEVICE_WIRED NM_DBUS_INTERFACE_DEVICE ".Wired"
#define NM_DBUS_INTERFACE_DEVICE_WIRELESS NM_DBUS_INTERFACE_DEVICE ".Wireless"
#define NM_DBUS_PATH_ACCESS_POINT NM_DBUS_PATH "/AccessPoint"
#define NM_DBUS_INTERFACE_ACCESS_POINT NM_DBUS_INTERFACE ".AccessPoint"
-#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings"
+#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings"
-#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection"
-#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings"
+#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection"
+#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings"
#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
-#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings"
-#define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings"
+#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings"
+#define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings"
-#define NM_802_11_AP_FLAGS_NONE 0x00000000
-#define NM_802_11_AP_FLAGS_PRIVACY 0x00000001
+#define NM_802_11_AP_FLAGS_NONE 0x00000000
+#define NM_802_11_AP_FLAGS_PRIVACY 0x00000001
#endif
QT_BEGIN_NAMESPACE
@@ -433,7 +433,7 @@ class QNetworkManagerIp4Config : public QObject
public:
explicit QNetworkManagerIp4Config(const QString &dbusPathName, QObject *parent = 0);
- ~QNetworkManagerIp4Config();
+ ~QNetworkManagerIp4Config();
QStringList domains() const;
bool isValid();
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 2490a4ffbe..c206e99e57 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -8,6 +8,7 @@ QT += gui-private
LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
+DEFINES += COMPOSE_X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
SOURCES += $$PWD/main.cpp \
$$PWD/qcomposeplatforminputcontext.cpp \
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 817c3f11bc..e2810c8448 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -58,6 +58,7 @@
#include <locale.h> // LC_CTYPE
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
+#include <clocale> // LC_CTYPE
TableGenerator::TableGenerator() : m_state(NoErrors),
m_systemComposeDir(QString())
@@ -72,17 +73,13 @@ TableGenerator::TableGenerator() : m_state(NoErrors),
void TableGenerator::initPossibleLocations()
{
- // AFAICT there is no way to know the exact location
- // of the compose files. It depends on how Xlib was configured
- // on a specific platform. During the "./configure" process
- // xlib generates a config.h file which contains a bunch of defines,
- // including XLOCALEDIR which points to the location of the compose file dir.
// To add an extra system path use the QTCOMPOSE environment variable
if (qEnvironmentVariableIsSet("QTCOMPOSE")) {
m_possibleLocations.append(QString(qgetenv("QTCOMPOSE")));
}
- m_possibleLocations.append(QStringLiteral("/usr/share/X11/locale"));
- m_possibleLocations.append(QStringLiteral("/usr/lib/X11/locale"));
+
+ m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/share/X11/locale"));
+ m_possibleLocations.append(QStringLiteral(COMPOSE_X11_PREFIX "/lib/X11/locale"));
}
void TableGenerator::findComposeFile()
diff --git a/src/plugins/platforms/android/src/android.json b/src/plugins/platforms/android/android.json
index 6843bd3301..6843bd3301 100644
--- a/src/plugins/platforms/android/src/android.json
+++ b/src/plugins/platforms/android/android.json
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index aa5ab4ddbd..243eea071a 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -1,3 +1,82 @@
-TEMPLATE = subdirs
+TARGET = qtforandroid
-SUBDIRS += raster opengl
+PLUGIN_TYPE = platforms
+
+# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
+# Yes, the plugin imports itself statically
+DEFINES += QT_STATICPLUGIN
+
+load(qt_plugin)
+
+!contains(ANDROID_PLATFORM, android-9) {
+ INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
+ LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
+} else {
+ LIBS += -ljnigraphics -landroid
+}
+
+QT += core-private gui-private platformsupport-private
+
+CONFIG += qpa/genericunixfontdatabase
+
+OTHER_FILES += $$PWD/android.json
+
+INCLUDEPATH += $$PWD
+
+SOURCES += $$PWD/androidplatformplugin.cpp \
+ $$PWD/androidjnimain.cpp \
+ $$PWD/androidjniaccessibility.cpp \
+ $$PWD/androidjniinput.cpp \
+ $$PWD/androidjnimenu.cpp \
+ $$PWD/androidjniclipboard.cpp \
+ $$PWD/qandroidplatformintegration.cpp \
+ $$PWD/qandroidplatformservices.cpp \
+ $$PWD/qandroidassetsfileenginehandler.cpp \
+ $$PWD/qandroidinputcontext.cpp \
+ $$PWD/qandroidplatformaccessibility.cpp \
+ $$PWD/qandroidplatformfontdatabase.cpp \
+ $$PWD/qandroidplatformdialoghelpers.cpp \
+ $$PWD/qandroidplatformclipboard.cpp \
+ $$PWD/qandroidplatformtheme.cpp \
+ $$PWD/qandroidplatformmenubar.cpp \
+ $$PWD/qandroidplatformmenu.cpp \
+ $$PWD/qandroidplatformmenuitem.cpp \
+ $$PWD/qandroidsystemlocale.cpp \
+ $$PWD/qandroidplatformscreen.cpp \
+ $$PWD/qandroidplatformwindow.cpp \
+ $$PWD/qandroidplatformopenglwindow.cpp \
+ $$PWD/qandroidplatformrasterwindow.cpp \
+ $$PWD/qandroidplatformbackingstore.cpp \
+ $$PWD/qandroidplatformopenglcontext.cpp \
+ $$PWD/qandroidplatformforeignwindow.cpp
+
+HEADERS += $$PWD/qandroidplatformintegration.h \
+ $$PWD/androidjnimain.h \
+ $$PWD/androidjniaccessibility.h \
+ $$PWD/androidjniinput.h \
+ $$PWD/androidjnimenu.h \
+ $$PWD/androidjniclipboard.h \
+ $$PWD/qandroidplatformservices.h \
+ $$PWD/qandroidassetsfileenginehandler.h \
+ $$PWD/qandroidinputcontext.h \
+ $$PWD/qandroidplatformaccessibility.h \
+ $$PWD/qandroidplatformfontdatabase.h \
+ $$PWD/qandroidplatformclipboard.h \
+ $$PWD/qandroidplatformdialoghelpers.h \
+ $$PWD/qandroidplatformtheme.h \
+ $$PWD/qandroidplatformmenubar.h \
+ $$PWD/qandroidplatformmenu.h \
+ $$PWD/qandroidplatformmenuitem.h \
+ $$PWD/qandroidsystemlocale.h \
+ $$PWD/androidsurfaceclient.h \
+ $$PWD/qandroidplatformscreen.h \
+ $$PWD/qandroidplatformwindow.h \
+ $$PWD/qandroidplatformopenglwindow.h \
+ $$PWD/qandroidplatformrasterwindow.h \
+ $$PWD/qandroidplatformbackingstore.h \
+ $$PWD/qandroidplatformopenglcontext.h \
+ $$PWD/qandroidplatformforeignwindow.h
+
+#Non-standard install directory, QTBUG-29859
+DESTDIR = $$DESTDIR/android
+target.path = $${target.path}/android
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index b987c49c9c..b987c49c9c 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
diff --git a/src/plugins/platforms/android/src/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h
index e708138c33..e708138c33 100644
--- a/src/plugins/platforms/android/src/androidjniaccessibility.h
+++ b/src/plugins/platforms/android/androidjniaccessibility.h
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp
index 05270ac374..05270ac374 100644
--- a/src/plugins/platforms/android/src/androidjniclipboard.cpp
+++ b/src/plugins/platforms/android/androidjniclipboard.cpp
diff --git a/src/plugins/platforms/android/src/androidjniclipboard.h b/src/plugins/platforms/android/androidjniclipboard.h
index 15cd93202e..15cd93202e 100644
--- a/src/plugins/platforms/android/src/androidjniclipboard.h
+++ b/src/plugins/platforms/android/androidjniclipboard.h
diff --git a/src/plugins/platforms/android/src/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 8ce95532d3..55d44b7377 100644
--- a/src/plugins/platforms/android/src/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -471,6 +471,9 @@ namespace QtAndroidInput
case 0x000000ba: // KEYCODE_PROG_BLUE
return Qt::Key_Blue;
+ case 0x000000a5: // KEYCODE_INFO
+ return Qt::Key_Info;
+
case 0x000000a6: // KEYCODE_CHANNEL_UP
return Qt::Key_ChannelUp;
@@ -483,9 +486,15 @@ namespace QtAndroidInput
case 0x000000a9: // KEYCODE_ZOOM_OUT
return Qt::Key_ZoomOut;
+ case 0x000000ac: // KEYCODE_GUIDE
+ return Qt::Key_Guide;
+
case 0x000000af: // KEYCODE_CAPTIONS
return Qt::Key_Subtitle;
+ case 0x000000b0: // KEYCODE_SETTINGS
+ return Qt::Key_Settings;
+
case 0x000000d0: // KEYCODE_CALENDAR
return Qt::Key_Calendar;
diff --git a/src/plugins/platforms/android/src/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index a78c7519db..a78c7519db 100644
--- a/src/plugins/platforms/android/src/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 40f3cc714e..28a5da4b5d 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -53,6 +53,7 @@
#include <qdebug.h>
#include <qglobal.h>
#include <qobjectdefs.h>
+#include <QtCore/private/qjni_p.h>
#include <stdlib.h>
#include "androidjnimain.h"
@@ -69,17 +70,10 @@
#include <android/asset_manager_jni.h>
#include "qandroidassetsfileenginehandler.h"
#include <android/api-level.h>
+#include <QtCore/private/qjnihelpers_p.h>
#include <qpa/qwindowsysteminterface.h>
-#ifdef ANDROID_PLUGIN_OPENGL
-# include "qandroidopenglplatformwindow.h"
-#endif
-
-#include <android/native_window_jni.h>
-
-static jmethodID m_redrawSurfaceMethodID = 0;
-
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
static JavaVM *m_javaVM = NULL;
@@ -89,6 +83,10 @@ static jmethodID m_loadClassMethodID = NULL;
static AAssetManager *m_assetManager = NULL;
static jobject m_resourcesObj;
static jobject m_activityObject = NULL;
+static jmethodID m_createSurfaceMethodID = 0;
+static jmethodID m_insertNativeViewMethodID = 0;
+static jmethodID m_setSurfaceGeometryMethodID = 0;
+static jmethodID m_destroySurfaceMethodID = 0;
static bool m_activityActive = true; // defaults to true because when the platform plugin is
// initialized, QtActivity::onResume() has already been called
@@ -109,17 +107,19 @@ static Main m_main = NULL;
static void *m_mainLibraryHnd = NULL;
static QList<QByteArray> m_applicationParams;
-#ifndef ANDROID_PLUGIN_OPENGL
-static jobject m_surface = NULL;
-#else
-static EGLNativeWindowType m_nativeWindow = 0;
-static QSemaphore m_waitForWindowSemaphore;
-static bool m_waitForWindow = false;
-#endif
+struct SurfaceData
+{
+ ~SurfaceData() { delete surface; }
+ QJNIObjectPrivate *surface = 0;
+ AndroidSurfaceClient *client = 0;
+};
+
+QHash<int, AndroidSurfaceClient *> m_surfaces;
+static QMutex m_surfacesMutex;
+static int m_surfaceId = 1;
static QSemaphore m_quitAppSemaphore;
-static QMutex m_surfaceMutex(QMutex::Recursive);
static QSemaphore m_pauseApplicationSemaphore;
static QMutex m_pauseApplicationMutex;
@@ -139,128 +139,18 @@ static const char m_qtTag[] = "Qt";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
-static inline void checkPauseApplication()
-{
- m_pauseApplicationMutex.lock();
- if (m_pauseApplication) {
- m_pauseApplicationMutex.unlock();
- m_pauseApplicationSemaphore.acquire(); // wait until surface is created
-
- m_pauseApplicationMutex.lock();
- m_pauseApplication = false;
- m_pauseApplicationMutex.unlock();
-
- //FIXME
-// QWindowSystemInterface::handleScreenAvailableGeometryChange(0);
-// QWindowSystemInterface::handleScreenGeometryChange(0);
- } else {
- m_pauseApplicationMutex.unlock();
- }
-}
-
namespace QtAndroid
{
-#ifndef ANDROID_PLUGIN_OPENGL
- void flushImage(const QPoint &pos, const QImage &image, const QRect &destinationRect)
- {
- checkPauseApplication();
- QMutexLocker locker(&m_surfaceMutex);
- if (!m_surface)
- return;
- AttachedJNIEnv env;
- if (!env.jniEnv)
- return;
-
- int bpp = 2;
- AndroidBitmapInfo info;
- int ret;
-
- if ((ret = AndroidBitmap_getInfo(env.jniEnv, m_surface, &info)) < 0) {
- qWarning() << "AndroidBitmap_getInfo() failed ! error=" << ret;
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- if (info.format != ANDROID_BITMAP_FORMAT_RGB_565) {
- qWarning() << "Bitmap format is not RGB_565!";
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- void *pixels;
- unsigned char *screenBits;
- if ((ret = AndroidBitmap_lockPixels(env.jniEnv, m_surface, &pixels)) < 0) {
- qWarning() << "AndroidBitmap_lockPixels() failed! error=" << ret;
- m_javaVM->DetachCurrentThread();
- return;
- }
-
- screenBits = static_cast<unsigned char *>(pixels);
- int sbpl = info.stride;
- int swidth = info.width;
- int sheight = info.height;
-
- unsigned sposx = pos.x() + destinationRect.x();
- unsigned sposy = pos.y() + destinationRect.y();
-
- screenBits += sposy * sbpl;
-
- unsigned ibpl = image.bytesPerLine();
- unsigned iposx = destinationRect.x();
- unsigned iposy = destinationRect.y();
-
- const unsigned char *imageBits = static_cast<const unsigned char *>(image.bits());
- imageBits += iposy * ibpl;
-
- unsigned width = swidth - sposx < unsigned(destinationRect.width())
- ? (swidth-sposx)
- : destinationRect.width();
- unsigned height = sheight - sposy < unsigned(destinationRect.height())
- ? (sheight - sposy)
- : destinationRect.height();
-
- for (unsigned y = 0; y < height; y++) {
- memcpy(screenBits + y*sbpl + sposx*bpp,
- imageBits + y*ibpl + iposx*bpp,
- width*bpp);
- }
- AndroidBitmap_unlockPixels(env.jniEnv, m_surface);
-
- env.jniEnv->CallStaticVoidMethod(m_applicationClass,
- m_redrawSurfaceMethodID,
- jint(destinationRect.left()),
- jint(destinationRect.top()),
- jint(destinationRect.right() + 1),
- jint(destinationRect.bottom() + 1));
-#warning FIXME dirty hack, figure out why it needs to add 1 to right and bottom !!!!
- }
-
-#else // for #ifndef ANDROID_PLUGIN_OPENGL
- EGLNativeWindowType nativeWindow(bool waitForWindow)
- {
- m_surfaceMutex.lock();
- if (!m_nativeWindow && waitForWindow) {
- m_waitForWindow = true;
- m_surfaceMutex.unlock();
- m_waitForWindowSemaphore.acquire();
- m_waitForWindow = false;
- return m_nativeWindow;
- }
- m_surfaceMutex.unlock();
- return m_nativeWindow;
- }
-#endif
-
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
{
- m_surfaceMutex.lock();
+ m_surfacesMutex.lock();
m_androidPlatformIntegration = androidPlatformIntegration;
- m_surfaceMutex.unlock();
+ m_surfacesMutex.unlock();
}
QAndroidPlatformIntegration *androidPlatformIntegration()
{
- QMutexLocker locker(&m_surfaceMutex);
+ QMutexLocker locker(&m_surfacesMutex);
return m_androidPlatformIntegration;
}
@@ -352,14 +242,17 @@ namespace QtAndroid
jobject createBitmap(QImage img, JNIEnv *env)
{
- if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
- img = img.convertToFormat(QImage::Format_ARGB32);
+ if (!m_bitmapClass)
+ return 0;
+
+ if (img.format() != QImage::Format_RGBA8888 && img.format() != QImage::Format_RGB16)
+ img = img.convertToFormat(QImage::Format_RGBA8888);
jobject bitmap = env->CallStaticObjectMethod(m_bitmapClass,
m_createBitmapMethodID,
img.width(),
img.height(),
- img.format() == QImage::Format_ARGB32
+ img.format() == QImage::Format_RGBA8888
? m_ARGB_8888_BitmapConfigValue
: m_RGB_565_BitmapConfigValue);
if (!bitmap)
@@ -392,9 +285,24 @@ namespace QtAndroid
return bitmap;
}
+ jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env)
+ {
+ if (format != QImage::Format_RGBA8888
+ && format != QImage::Format_RGB16)
+ return 0;
+
+ return env->CallStaticObjectMethod(m_bitmapClass,
+ m_createBitmapMethodID,
+ width,
+ height,
+ format == QImage::Format_RGB16
+ ? m_RGB_565_BitmapConfigValue
+ : m_ARGB_8888_BitmapConfigValue);
+ }
+
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env)
{
- if (!bitmap)
+ if (!bitmap || !m_bitmapDrawableClass || !m_resourcesObj)
return 0;
return env->NewObject(m_bitmapDrawableClass,
@@ -425,25 +333,103 @@ namespace QtAndroid
return manufacturer + QStringLiteral(" ") + model;
}
+
+ int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop)
+ {
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return -1;
+
+ m_surfacesMutex.lock();
+ int surfaceId = m_surfaceId++;
+ m_surfaces[surfaceId] = client;
+ m_surfacesMutex.unlock();
+
+ jint x = 0, y = 0, w = -1, h = -1;
+ if (!geometry.isNull()) {
+ x = geometry.x();
+ y = geometry.y();
+ w = std::max(geometry.width(), 1);
+ h = std::max(geometry.height(), 1);
+ }
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_createSurfaceMethodID,
+ surfaceId,
+ jboolean(onTop),
+ x, y, w, h);
+ return surfaceId;
+ }
+
+ int insertNativeView(jobject view, const QRect &geometry)
+ {
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return 0;
+
+ m_surfacesMutex.lock();
+ const int surfaceId = m_surfaceId++;
+ m_surfacesMutex.unlock();
+
+ jint x = 0, y = 0, w = -1, h = -1;
+ if (!geometry.isNull()) {
+ x = geometry.x();
+ y = geometry.y();
+ w = std::max(geometry.width(), 1);
+ h = std::max(geometry.height(), 1);
+ }
+
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_insertNativeViewMethodID,
+ surfaceId,
+ view,
+ x, y, w, h);
+
+ return surfaceId;
+ }
+
+ void setSurfaceGeometry(int surfaceId, const QRect &geometry)
+ {
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return;
+ jint x = 0, y = 0, w = -1, h = -1;
+ if (!geometry.isNull()) {
+ x = geometry.x();
+ y = geometry.y();
+ w = geometry.width();
+ h = geometry.height();
+ }
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_setSurfaceGeometryMethodID,
+ surfaceId,
+ x, y, w, h);
+ }
+
+
+ void destroySurface(int surfaceId)
+ {
+ QMutexLocker lock(&m_surfacesMutex);
+ const auto &it = m_surfaces.find(surfaceId);
+ if (it == m_surfaces.end())
+ return;
+
+ m_surfaces.remove(surfaceId);
+ QJNIEnvironmentPrivate env;
+ if (!env)
+ return;
+
+ env->CallStaticVoidMethod(m_applicationClass,
+ m_destroySurfaceMethodID,
+ surfaceId);
+ }
} // namespace QtAndroid
+
static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- m_surface = 0;
-#else
- m_nativeWindow = 0;
- m_waitForWindow = false;
-#endif
-
m_androidPlatformIntegration = 0;
m_androidAssetsFileEngineHandler = new AndroidAssetsFileEngineHandler();
-
-#ifdef ANDROID_PLUGIN_OPENGL
return true;
-#else
- return false;
-#endif
}
static void *startMainMethod(void */*data*/)
@@ -519,132 +505,43 @@ static jboolean startQtApplication(JNIEnv *env, jobject /*object*/, jstring para
return pthread_create(&appThread, NULL, startMainMethod, NULL) == 0;
}
-static void pauseQtApp(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
- m_pauseApplicationMutex.lock();
-
- if (m_androidPlatformIntegration)
- m_androidPlatformIntegration->pauseApp();
- m_pauseApplication = true;
-
- m_pauseApplicationMutex.unlock();
- m_surfaceMutex.unlock();
-}
-
-static void resumeQtApp(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
- m_pauseApplicationMutex.lock();
- if (m_androidPlatformIntegration)
- m_androidPlatformIntegration->resumeApp();
-
- if (m_pauseApplication)
- m_pauseApplicationSemaphore.release();
-
- m_pauseApplicationMutex.unlock();
- m_surfaceMutex.unlock();
-}
static void quitQtAndroidPlugin(JNIEnv *env, jclass /*clazz*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface) {
- env->DeleteGlobalRef(m_surface);
- m_surface = 0;
- }
-#else
Q_UNUSED(env);
-#endif
-
m_androidPlatformIntegration = 0;
delete m_androidAssetsFileEngineHandler;
}
static void terminateQt(JNIEnv *env, jclass /*clazz*/)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface)
- env->DeleteGlobalRef(m_surface);
-#endif
env->DeleteGlobalRef(m_applicationClass);
env->DeleteGlobalRef(m_classLoaderObject);
- env->DeleteGlobalRef(m_resourcesObj);
- env->DeleteGlobalRef(m_activityObject);
- env->DeleteGlobalRef(m_bitmapClass);
- env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
- env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
- env->DeleteGlobalRef(m_bitmapDrawableClass);
-}
-
-static void setSurface(JNIEnv *env, jobject /*thiz*/, jobject jSurface)
-{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface)
- env->DeleteGlobalRef(m_surface);
- m_surface = env->NewGlobalRef(jSurface);
-#else
- m_surfaceMutex.lock();
- EGLNativeWindowType nativeWindow = ANativeWindow_fromSurface(env, jSurface);
- bool sameNativeWindow = (nativeWindow != 0 && nativeWindow == m_nativeWindow);
-
- m_nativeWindow = nativeWindow;
- if (m_waitForWindow)
- m_waitForWindowSemaphore.release();
-
- if (m_androidPlatformIntegration) {
- // Use the desktop size.
- // On some devices, the getters for the native window size gives wrong values
- QSize size = QAndroidPlatformIntegration::defaultDesktopSize();
-
- QPlatformScreen *screen = m_androidPlatformIntegration->screen();
- QRect geometry(QPoint(0, 0), size);
- if (screen) {
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen->screen(), geometry);
- QWindowSystemInterface::handleScreenGeometryChange(screen->screen(), geometry);
- }
-
- if (!sameNativeWindow) {
- m_surfaceMutex.unlock();
- m_androidPlatformIntegration->surfaceChanged();
- } else {
- // Resize all top level windows, since they share the same surface
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
-
- if (window != 0) {
- window->lock();
- window->scheduleResize(size);
-
- QWindowSystemInterface::handleExposeEvent(window->window(),
- QRegion(window->window()->geometry()));
- window->unlock();
- }
- }
-
- m_surfaceMutex.unlock();
- }
-
- } else {
- m_surfaceMutex.unlock();
- }
-#endif // for #ifndef ANDROID_PLUGIN_OPENGL
+ if (m_resourcesObj)
+ env->DeleteGlobalRef(m_resourcesObj);
+ if (m_activityObject)
+ env->DeleteGlobalRef(m_activityObject);
+ if (m_bitmapClass)
+ env->DeleteGlobalRef(m_bitmapClass);
+ if (m_ARGB_8888_BitmapConfigValue)
+ env->DeleteGlobalRef(m_ARGB_8888_BitmapConfigValue);
+ if (m_RGB_565_BitmapConfigValue)
+ env->DeleteGlobalRef(m_RGB_565_BitmapConfigValue);
+ if (m_bitmapDrawableClass)
+ env->DeleteGlobalRef(m_bitmapDrawableClass);
+ m_androidPlatformIntegration = 0;
+ delete m_androidAssetsFileEngineHandler;
}
-static void destroySurface(JNIEnv *env, jobject /*thiz*/)
+static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface, jint w, jint h)
{
-#ifndef ANDROID_PLUGIN_OPENGL
- if (m_surface) {
- env->DeleteGlobalRef(m_surface);
- m_surface = 0;
+ QMutexLocker lock(&m_surfacesMutex);
+ const auto &it = m_surfaces.find(id);
+ if (it == m_surfaces.end()) {
+ qWarning()<<"Can't find surface" << id;
+ return;
}
-#else
- Q_UNUSED(env);
- m_nativeWindow = 0;
- if (m_androidPlatformIntegration != 0)
- m_androidPlatformIntegration->invalidateNativeSurface();
-#endif
+ it.value()->surfaceChanged(env, jSurface, w, h);
}
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
@@ -667,16 +564,6 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
}
}
-static void lockSurface(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.lock();
-}
-
-static void unlockSurface(JNIEnv */*env*/, jobject /*thiz*/)
-{
- m_surfaceMutex.unlock();
-}
-
static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
{
if (!m_androidPlatformIntegration)
@@ -687,12 +574,8 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
QWindowSystemInterface::handleExposeEvent(w, QRegion(w->geometry()));
}
-#ifndef ANDROID_PLUGIN_OPENGL
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
-#else
- qWarning("updateWindow: Dirty screen not implemented yet on OpenGL");
-#endif
}
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
@@ -738,21 +621,25 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new
}
}
+static void onActivityResult(JNIEnv */*env*/, jclass /*cls*/,
+ jint requestCode,
+ jint resultCode,
+ jobject data)
+{
+ QtAndroidPrivate::handleActivityResult(requestCode, resultCode, data);
+}
+
static JNINativeMethod methods[] = {
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
- {"pauseQtApp", "()V", (void *)pauseQtApp},
- {"resumeQtApp", "()V", (void *)resumeQtApp},
{"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
{"terminateQt", "()V", (void *)terminateQt},
{"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics},
- {"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface},
- {"destroySurface", "()V", (void *)destroySurface},
- {"lockSurface", "()V", (void *)lockSurface},
- {"unlockSurface", "()V", (void *)unlockSurface},
+ {"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
{"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
- {"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}
+ {"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged},
+ {"onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult}
};
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
@@ -802,43 +689,49 @@ static int registerNatives(JNIEnv *env)
return JNI_FALSE;
}
- GET_AND_CHECK_STATIC_METHOD(m_redrawSurfaceMethodID, m_applicationClass, "redrawSurface", "(IIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_createSurfaceMethodID, m_applicationClass, "createSurface", "(IZIIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_insertNativeViewMethodID, m_applicationClass, "insertNativeView", "(ILandroid/view/View;IIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_setSurfaceGeometryMethodID, m_applicationClass, "setSurfaceGeometry", "(IIIII)V");
+ GET_AND_CHECK_STATIC_METHOD(m_destroySurfaceMethodID, m_applicationClass, "destroySurface", "(I)V");
jmethodID methodID;
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "activity", "()Landroid/app/Activity;");
jobject activityObject = env->CallStaticObjectMethod(m_applicationClass, methodID);
- m_activityObject = env->NewGlobalRef(activityObject);
GET_AND_CHECK_STATIC_METHOD(methodID, m_applicationClass, "classLoader", "()Ljava/lang/ClassLoader;");
m_classLoaderObject = env->NewGlobalRef(env->CallStaticObjectMethod(m_applicationClass, methodID));
-
clazz = env->GetObjectClass(m_classLoaderObject);
GET_AND_CHECK_METHOD(m_loadClassMethodID, clazz, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
- GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
- m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+ if (activityObject) {
+ m_activityObject = env->NewGlobalRef(activityObject);
- GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
- m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+ FIND_AND_CHECK_CLASS("android/content/ContextWrapper");
+ GET_AND_CHECK_METHOD(methodID, clazz, "getAssets", "()Landroid/content/res/AssetManager;");
+ m_assetManager = AAssetManager_fromJava(env, env->CallObjectMethod(activityObject, methodID));
+
+ GET_AND_CHECK_METHOD(methodID, clazz, "getResources", "()Landroid/content/res/Resources;");
+ m_resourcesObj = env->NewGlobalRef(env->CallObjectMethod(activityObject, methodID));
+
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
+ m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass
+ , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
+ FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config");
+ jfieldID fieldId;
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
+ m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+ GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;");
+ m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
+
+ FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable");
+ m_bitmapDrawableClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+ GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID,
+ m_bitmapDrawableClass,
+ "<init>",
+ "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
+ }
- FIND_AND_CHECK_CLASS("android/graphics/Bitmap");
- m_bitmapClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_STATIC_METHOD(m_createBitmapMethodID, m_bitmapClass
- , "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
- FIND_AND_CHECK_CLASS("android/graphics/Bitmap$Config");
- jfieldID fieldId;
- GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
- m_ARGB_8888_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
- GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "RGB_565", "Landroid/graphics/Bitmap$Config;");
- m_RGB_565_BitmapConfigValue = env->NewGlobalRef(env->GetStaticObjectField(clazz, fieldId));
-
- FIND_AND_CHECK_CLASS("android/graphics/drawable/BitmapDrawable");
- m_bitmapDrawableClass = static_cast<jclass>(env->NewGlobalRef(clazz));
- GET_AND_CHECK_METHOD(m_bitmapDrawableConstructorMethodID,
- m_bitmapDrawableClass,
- "<init>",
- "(Landroid/content/res/Resources;Landroid/graphics/Bitmap;)V");
return JNI_TRUE;
}
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index a7b7072ba3..eb604c8da8 100644
--- a/src/plugins/platforms/android/src/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -1,7 +1,7 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -45,16 +45,11 @@
#include <android/log.h>
-#ifdef ANDROID_PLUGIN_OPENGL
-# include <EGL/eglplatform.h>
-#endif
-
-#include <QtCore/qsize.h>
-
#include <jni.h>
#include <android/asset_manager.h>
-class QImage;
+#include <QImage>
+
class QRect;
class QPoint;
class QThread;
@@ -62,6 +57,7 @@ class QAndroidPlatformIntegration;
class QWidget;
class QString;
class QWindow;
+class AndroidSurfaceClient;
namespace QtAndroid
{
@@ -69,11 +65,11 @@ namespace QtAndroid
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration);
void setQtThread(QThread *thread);
-#ifndef ANDROID_PLUGIN_OPENGL
- void flushImage(const QPoint &pos, const QImage &image, const QRect &rect);
-#else
- EGLNativeWindowType nativeWindow(bool waitToCreate = true);
-#endif
+
+ int createSurface(AndroidSurfaceClient * client, const QRect &geometry, bool onTop);
+ int insertNativeView(jobject view, const QRect &geometry);
+ void setSurfaceGeometry(int surfaceId, const QRect &geometry);
+ void destroySurface(int surfaceId);
QWindow *topLevelWindowAt(const QPoint &globalPos);
int desktopWidthPixels();
@@ -91,6 +87,7 @@ namespace QtAndroid
void hideStatusBar();
jobject createBitmap(QImage img, JNIEnv *env = 0);
+ jobject createBitmap(int width, int height, QImage::Format format, JNIEnv *env);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);
struct AttachedJNIEnv
diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index dbdd7c9b8e..dc2afe2b03 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -143,6 +143,9 @@ namespace QtAndroidMenu
void setActiveTopLevelWindow(QWindow *window)
{
Qt::WindowFlags flags = window ? window->flags() : Qt::WindowFlags();
+ if (!window)
+ return;
+
bool isNonRegularWindow = flags & (Qt::Desktop | Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
if (isNonRegularWindow)
return;
@@ -195,9 +198,9 @@ namespace QtAndroidMenu
static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon())
{
- env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable);
- env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked);
- env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled);
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled));
if (!icon.isNull()) { // isNull() only checks the d pointer, not the actual image data.
int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt());
@@ -207,13 +210,13 @@ namespace QtAndroidMenu
: QIcon::Disabled,
QIcon::On).toImage();
if (!img.isNull()) { // Make sure we have a valid image.
- env->CallObjectMethod(menuItem,
- setIconMenuItemMethodID,
- createBitmapDrawable(createBitmap(img, env), env));
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem,
+ setIconMenuItemMethodID,
+ createBitmapDrawable(createBitmap(img, env), env)));
}
}
- env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible);
+ env->DeleteLocalRef(env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible));
}
static int addAllMenuItemsToMenu(JNIEnv *env, jobject menu, QAndroidPlatformMenu *platformMenu) {
@@ -239,6 +242,7 @@ namespace QtAndroidMenu
item->isEnabled(),
item->isVisible(),
item->icon());
+ env->DeleteLocalRef(menuItem);
}
return order;
diff --git a/src/plugins/platforms/android/src/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h
index 7c5422f67b..7c5422f67b 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.h
+++ b/src/plugins/platforms/android/androidjnimenu.h
diff --git a/src/plugins/platforms/android/src/androidplatformplugin.cpp b/src/plugins/platforms/android/androidplatformplugin.cpp
index 2cf5aa1e01..2cf5aa1e01 100644
--- a/src/plugins/platforms/android/src/androidplatformplugin.cpp
+++ b/src/plugins/platforms/android/androidplatformplugin.cpp
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/androidsurfaceclient.h
index 9f8807b995..254e47123b 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/androidsurfaceclient.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,24 +39,20 @@
**
****************************************************************************/
-#ifndef QANDROIDPLATFORMSCREEN_H
-#define QANDROIDPLATFORMSCREEN_H
+#ifndef ANDROIDSURFACECLIENT_H
+#define ANDROIDSURFACECLIENT_H
+#include <QMutex>
+#include <jni.h>
-#include <QtPlatformSupport/private/qfbscreen_p.h>
-
-class QAndroidPlatformScreen: public QFbScreen
+class AndroidSurfaceClient
{
- Q_OBJECT
public:
- QAndroidPlatformScreen();
- void topWindowChanged(QWindow *w);
- QDpi logicalDpi() const;
- Qt::ScreenOrientation orientation() const;
- Qt::ScreenOrientation nativeOrientation() const;
-
-public slots:
- QRegion doRedraw();
+ virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h) = 0;
+ void lockSurface() { m_surfaceMutex.lock(); }
+ void unlockSurface() { m_surfaceMutex.unlock(); }
+protected:
+ QMutex m_surfaceMutex;
};
-#endif
+#endif // ANDROIDSURFACECLIENT_H
diff --git a/src/plugins/platforms/android/opengl/opengl.pro b/src/plugins/platforms/android/opengl/opengl.pro
deleted file mode 100644
index ea050ca3a0..0000000000
--- a/src/plugins/platforms/android/opengl/opengl.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-TARGET = qtforandroidGL
-
-PLUGIN_TYPE = platforms
-load(qt_plugin)
-
-# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
-# Yes, the plugin imports itself statically
-DEFINES += QT_STATICPLUGIN ANDROID_PLUGIN_OPENGL
-
-!equals(ANDROID_PLATFORM, android-9) {
- INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
- LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
-} else {
- LIBS += -ljnigraphics -landroid
-}
-
-EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/../src/opengl/qeglfshooks_android.cpp
-
-INCLUDEPATH += $$PWD/../src/opengl/
-
-HEADERS += \
- $$PWD/../src/opengl/qandroidopenglcontext.h \
- $$PWD/../src/opengl/qandroidopenglplatformwindow.h \
- $$PWD/../src/opengl/qandroidopenglplatformscreen.h
-
-SOURCES += \
- $$PWD/../src/opengl/qandroidopenglcontext.cpp \
- $$PWD/../src/opengl/qandroidopenglplatformwindow.cpp \
- $$PWD/../src/opengl/qandroidopenglplatformscreen.cpp
-
-include($$PWD/../../eglfs/eglfs.pri)
-include($$PWD/../src/src.pri)
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index 95844fc649..5f77d1645a 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -293,6 +293,7 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file
AAssetDir *assetDir = AAssetManager_openDir(m_assetManager, path.constData() + prefixSize);
if (assetDir) {
if (AAssetDir_getNextFileName(assetDir)) {
+ AAssetDir_rewind(assetDir);
aad = new QSharedPointer<AndroidAssetDir>(new AndroidAssetDir(assetDir));
m_assetsCacheMutext.lock();
m_assetsCache.insert(path, aad);
diff --git a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index 7bd560886c..7bd560886c 100644
--- a/src/plugins/platforms/android/src/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 326972e71e..326972e71e 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
diff --git a/src/plugins/platforms/android/src/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index 041bd0dc49..041bd0dc49 100644
--- a/src/plugins/platforms/android/src/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
index 229368345b..229368345b 100644
--- a/src/plugins/platforms/android/src/qandroidplatformaccessibility.cpp
+++ b/src/plugins/platforms/android/qandroidplatformaccessibility.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformaccessibility.h b/src/plugins/platforms/android/qandroidplatformaccessibility.h
index 1b87f11919..1b87f11919 100644
--- a/src/plugins/platforms/android/src/qandroidplatformaccessibility.h
+++ b/src/plugins/platforms/android/qandroidplatformaccessibility.h
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
new file mode 100644
index 0000000000..1df7ce3179
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformbackingstore.h"
+#include "qandroidplatformscreen.h"
+#include "qandroidplatformrasterwindow.h"
+#include <qpa/qplatformscreen.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+ Q_ASSERT(window->handle());
+ (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this);
+}
+
+QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
+{
+ return &m_image;
+}
+
+void QAndroidPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(offset);
+
+ (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->repaint(region);
+}
+
+void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents);
+
+ if (m_image.size() != size)
+ m_image = QImage(size, window()->screen()->handle()->format());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h
new file mode 100644
index 0000000000..e6ea3dcce0
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMBACKINGSTORE_H
+#define QANDROIDPLATFORMBACKINGSTORE_H
+
+#include <qpa/qplatformbackingstore.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformBackingStore : public QPlatformBackingStore
+{
+public:
+ explicit QAndroidPlatformBackingStore(QWindow *window);
+ virtual QPaintDevice *paintDevice();
+ virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+ virtual void resize(const QSize &size, const QRegion &staticContents);
+ const QImage image() { return m_image; }
+
+protected:
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMBACKINGSTORE_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
index bc48b4935b..bc48b4935b 100644
--- a/src/plugins/platforms/android/src/qandroidplatformclipboard.cpp
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformclipboard.h b/src/plugins/platforms/android/qandroidplatformclipboard.h
index 644f326934..644f326934 100644
--- a/src/plugins/platforms/android/src/qandroidplatformclipboard.h
+++ b/src/plugins/platforms/android/qandroidplatformclipboard.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
index 6a93fbb76e..e76eedbfd9 100644
--- a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.cpp
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
@@ -41,6 +41,8 @@
#include "qandroidplatformdialoghelpers.h"
#include "androidjnimain.h"
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
namespace QtAndroidDialogHelpers {
static jclass g_messageDialogHelperClass = 0;
@@ -59,49 +61,6 @@ void QAndroidPlatformMessageDialogHelper::exec()
m_loop.exec();
}
-static QString standardButtonText(int sbutton)
-{
- switch (sbutton) {
- case QMessageDialogOptions::Ok:
- return QAndroidPlatformMessageDialogHelper::tr("OK");
- case QMessageDialogOptions::Save:
- return QAndroidPlatformMessageDialogHelper::tr("Save");
- case QMessageDialogOptions::Open:
- return QAndroidPlatformMessageDialogHelper::tr("Open");
- case QMessageDialogOptions::Cancel:
- return QAndroidPlatformMessageDialogHelper::tr("Cancel");
- case QMessageDialogOptions::Close:
- return QAndroidPlatformMessageDialogHelper::tr("Close");
- case QMessageDialogOptions::Apply:
- return QAndroidPlatformMessageDialogHelper::tr("Apply");
- case QMessageDialogOptions::Reset:
- return QAndroidPlatformMessageDialogHelper::tr("Reset");
- case QMessageDialogOptions::Help:
- return QAndroidPlatformMessageDialogHelper::tr("Help");
- case QMessageDialogOptions::Discard:
- return QAndroidPlatformMessageDialogHelper::tr("Discard");
- case QMessageDialogOptions::Yes:
- return QAndroidPlatformMessageDialogHelper::tr("Yes");
- case QMessageDialogOptions::YesToAll:
- return QAndroidPlatformMessageDialogHelper::tr("Yes to All");
- case QMessageDialogOptions::No:
- return QAndroidPlatformMessageDialogHelper::tr("No");
- case QMessageDialogOptions::NoToAll:
- return QAndroidPlatformMessageDialogHelper::tr("No to All");
- case QMessageDialogOptions::SaveAll:
- return QAndroidPlatformMessageDialogHelper::tr("Save All");
- case QMessageDialogOptions::Abort:
- return QAndroidPlatformMessageDialogHelper::tr("Abort");
- case QMessageDialogOptions::Retry:
- return QAndroidPlatformMessageDialogHelper::tr("Retry");
- case QMessageDialogOptions::Ignore:
- return QAndroidPlatformMessageDialogHelper::tr("Ignore");
- case QMessageDialogOptions::RestoreDefaults:
- return QAndroidPlatformMessageDialogHelper::tr("Restore Defaults");
- } // switch
- return QString();
-}
-
bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
, Qt::WindowModality windowModality
, QWindow *parent)
@@ -131,9 +90,11 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
- for (int i = QMessageDialogOptions::FirstButton; i < QMessageDialogOptions::LastButton; i<<=1) {
- if ( opt->standardButtons() & i )
- m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(standardButtonText(i)).object());
+ for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
+ if ( opt->standardButtons() & i ) {
+ const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(i);
+ m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(text).object());
+ }
}
m_javaMessageDialog.callMethod<void>("show", "(J)V", jlong(static_cast<QObject*>(this)));
@@ -157,8 +118,8 @@ void QAndroidPlatformMessageDialogHelper::dialogResult(int buttonID)
return;
}
- QMessageDialogOptions::StandardButton standardButton = static_cast<QMessageDialogOptions::StandardButton>(buttonID);
- QMessageDialogOptions::ButtonRole role = QMessageDialogOptions::buttonRole(standardButton);
+ QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonID);
+ QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton);
emit clicked(standardButton, role);
}
diff --git a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
index 88ec91d936..88ec91d936 100644
--- a/src/plugins/platforms/android/src/qandroidplatformdialoghelpers.h
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 7f68b44ed8..7f68b44ed8 100644
--- a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
index 3cbfe95d36..3cbfe95d36 100644
--- a/src/plugins/platforms/android/src/qandroidplatformfontdatabase.h
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
new file mode 100644
index 0000000000..e6f9acb2c9
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformforeignwindow.h"
+#include "androidjnimain.h"
+#include <QtCore/qvariant.h>
+
+QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window)
+ : QAndroidPlatformWindow(window)
+{
+ const WId wId = window->property("_q_foreignWinId").value<WId>();
+ if (wId) {
+ m_view = reinterpret_cast<jobject>(wId);
+ Q_ASSERT(m_view.isValid());
+ m_surfaceId = QtAndroid::insertNativeView(m_view.object(), geometry());
+ }
+}
+
+QAndroidPlatformForeignWindow::~QAndroidPlatformForeignWindow()
+{
+ if (m_surfaceId != -1)
+ QtAndroid::destroySurface(m_surfaceId);
+}
+
+void QAndroidPlatformForeignWindow::setGeometry(const QRect &rect)
+{
+ if (rect == geometry())
+ return;
+
+ QAndroidPlatformWindow::setGeometry(rect);
+ QtAndroid::setSurfaceGeometry(m_surfaceId, rect);
+}
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.h b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
new file mode 100644
index 0000000000..88c87d0540
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMFOREIGNWINDOW_H
+#define QANDROIDPLATFORMFOREIGNWINDOW_H
+
+#include "androidsurfaceclient.h"
+#include "qandroidplatformwindow.h"
+#include <QtCore/private/qjni_p.h>
+
+class QAndroidPlatformForeignWindow : public QAndroidPlatformWindow
+{
+public:
+ explicit QAndroidPlatformForeignWindow(QWindow *window);
+ ~QAndroidPlatformForeignWindow();
+ void setGeometry(const QRect &rect);
+
+private:
+ QJNIObjectPrivate m_view;
+ int m_surfaceId = -1;
+};
+
+#endif // QANDROIDPLATFORMFOREIGNWINDOW_H
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 9bfb6e9a70..5848e94aca 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -40,34 +40,32 @@
****************************************************************************/
#include "qandroidplatformintegration.h"
-#include "qabstracteventdispatcher.h"
-#include "androidjnimain.h"
-#include <QtGui/qguiapplication.h>
-#include <qpa/qwindowsysteminterface.h>
+
+#include <QGuiApplication>
+#include <QOpenGLContext>
#include <QThread>
+
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
+
+#warning sort the headers
+#include "androidjnimain.h"
+#include "qabstracteventdispatcher.h"
+#include "qandroidplatformrasterwindow.h"
+#include "qandroidplatformopenglwindow.h"
+#include "qandroidplatformbackingstore.h"
#include "qandroidplatformservices.h"
#include "qandroidplatformfontdatabase.h"
#include "qandroidplatformclipboard.h"
#include "qandroidplatformaccessibility.h"
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-
-#ifndef ANDROID_PLUGIN_OPENGL
-# include "qandroidplatformscreen.h"
-# include "qandroidplatformwindow.h"
-# include <QtPlatformSupport/private/qfbbackingstore_p.h>
-#else
-# include "qeglfswindow.h"
-# include "androidjnimenu.h"
-# include "qandroidopenglcontext.h"
-# include "qandroidopenglplatformwindow.h"
-# include "qandroidopenglplatformscreen.h"
-# include "qeglfshooks.h"
-# include <QtGui/qopenglcontext.h>
-#endif
-
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformscreen.h"
#include "qandroidplatformtheme.h"
#include "qandroidsystemlocale.h"
+#include "qandroidplatformforeignwindow.h"
+
QT_BEGIN_NAMESPACE
@@ -106,12 +104,21 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
-#ifndef ANDROID_PLUGIN_OPENGL
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ qFatal("Could not bind GL_ES API");
+
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ qFatal("Could not open egl display");
+
+ EGLint major, minor;
+ if (!eglInitialize(m_eglDisplay, &major, &minor))
+ qFatal("Could not initialize egl display");
+
m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
m_primaryScreen->setGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
-#endif
m_mainThread = QThread::currentThread();
QtAndroid::setAndroidPlatformIntegration(this);
@@ -140,83 +147,53 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
switch (cap) {
case ThreadedPixmaps: return true;
case ApplicationState: return true;
- case NativeWidgets: return false;
-
+ case NativeWidgets: return true;
+ case OpenGL: return true;
+ case ForeignWindows: return true;
case ThreadedOpenGL:
if (needsWorkaround())
return false;
// fall through
default:
-#ifndef ANDROID_PLUGIN_OPENGL
- return QPlatformIntegration::hasCapability(cap);
-#else
- return QEglFSIntegration::hasCapability(cap);
-#endif
+ return QPlatformIntegration::hasCapability(cap);
}
}
-#ifndef ANDROID_PLUGIN_OPENGL
QPlatformBackingStore *QAndroidPlatformIntegration::createPlatformBackingStore(QWindow *window) const
{
- return new QFbBackingStore(window);
+ return new QAndroidPlatformBackingStore(window);
}
-QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
+QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- QAndroidPlatformWindow *platformWindow = new QAndroidPlatformWindow(window);
- platformWindow->setWindowState(window->windowState());
-
- return platformWindow;
+ QSurfaceFormat format(context->format());
+ format.setAlphaBufferSize(8);
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ return new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
}
-QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-#else // !ANDROID_PLUGIN_OPENGL
QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *window) const
{
- QAndroidOpenGLPlatformWindow *platformWindow = new QAndroidOpenGLPlatformWindow(window);
- platformWindow->create();
- platformWindow->requestActivateWindow();
- platformWindow->setWindowState(window->windowState());
- QtAndroidMenu::setActiveTopLevelWindow(window);
-
- return platformWindow;
-}
-
-void QAndroidPlatformIntegration::invalidateNativeSurface()
-{
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
- if (window != 0)
- window->invalidateSurface();
- }
-}
-
-void QAndroidPlatformIntegration::surfaceChanged()
-{
- QAndroidOpenGLPlatformWindow::updateStaticNativeWindow();
- foreach (QWindow *w, QGuiApplication::topLevelWindows()) {
- QAndroidOpenGLPlatformWindow *window =
- static_cast<QAndroidOpenGLPlatformWindow *>(w->handle());
- if (window != 0)
- window->resetSurface();
- }
+ if (window->type() == Qt::ForeignWindow)
+ return new QAndroidPlatformForeignWindow(window);
+ else if (window->surfaceType() == QSurface::RasterSurface)
+ return new QAndroidPlatformRasterWindow(window);
+ else
+ return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
}
-QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
{
- return new QAndroidOpenGLContext(this,
- QEglFSHooks::hooks()->surfaceFormatFor(context->format()),
- context->shareHandle(),
- display());
+ return createUnixEventDispatcher();
}
-#endif // ANDROID_PLUGIN_OPENGL
QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
{
+ if (m_eglDisplay != EGL_NO_DISPLAY)
+ eglTerminate(m_eglDisplay);
+
delete m_androidPlatformNativeInterface;
delete m_androidFDB;
delete m_androidSystemLocale;
@@ -227,6 +204,7 @@ QAndroidPlatformIntegration::~QAndroidPlatformIntegration()
QtAndroid::setAndroidPlatformIntegration(NULL);
}
+
QPlatformFontDatabase *QAndroidPlatformIntegration::fontDatabase() const
{
return m_androidFDB;
@@ -317,8 +295,6 @@ QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
}
#endif
-
-#ifndef ANDROID_PLUGIN_OPENGL
void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
{
if (m_primaryScreen)
@@ -330,36 +306,5 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
if (m_primaryScreen)
QMetaObject::invokeMethod(m_primaryScreen, "setPhysicalSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
}
-#else
-void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
-{
- m_defaultGeometryWidth = width;
- m_defaultGeometryHeight = height;
-}
-
-void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
-{
- m_defaultPhysicalSizeWidth = width;
- m_defaultPhysicalSizeHeight = height;
-}
-
-QEglFSScreen *QAndroidPlatformIntegration::createScreen() const
-{
- return new QAndroidOpenGLPlatformScreen(display());
-}
-
-#endif
-
-void QAndroidPlatformIntegration::pauseApp()
-{
- if (QAbstractEventDispatcher::instance(m_mainThread))
- QAbstractEventDispatcher::instance(m_mainThread)->interrupt();
-}
-
-void QAndroidPlatformIntegration::resumeApp()
-{
- if (QAbstractEventDispatcher::instance(m_mainThread))
- QAbstractEventDispatcher::instance(m_mainThread)->wakeUp();
-}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index caf26244a7..2d685bc567 100644
--- a/src/plugins/platforms/android/src/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -46,14 +46,11 @@
#include <qpa/qplatformmenu.h>
#include <qpa/qplatformnativeinterface.h>
+#include <EGL/egl.h>
#include <jni.h>
#include "qandroidinputcontext.h"
-#ifndef ANDROID_PLUGIN_OPENGL
-# include "qandroidplatformscreen.h"
-#else
-# include "qeglfsintegration.h"
-#endif
+#include "qandroidplatformscreen.h"
QT_BEGIN_NAMESPACE
@@ -62,10 +59,6 @@ class QAndroidPlatformServices;
class QAndroidSystemLocale;
class QPlatformAccessibility;
-#ifdef ANDROID_PLUGIN_OPENGL
-class QAndroidOpenGLPlatformWindow;
-#endif
-
class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
{
public:
@@ -74,12 +67,7 @@ public:
QHash<int, QFont> m_fonts;
};
-class QAndroidPlatformIntegration
-#ifndef ANDROID_PLUGIN_OPENGL
- : public QPlatformIntegration
-#else
- : public QEglFSIntegration
-#endif
+class QAndroidPlatformIntegration : public QPlatformIntegration
{
friend class QAndroidPlatformScreen;
@@ -89,17 +77,11 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
-#ifndef ANDROID_PLUGIN_OPENGL
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QAbstractEventDispatcher *createEventDispatcher() const;
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
-#else
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- void invalidateNativeSurface();
- void surfaceChanged();
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
-#endif
virtual void setDesktopSize(int width, int height);
virtual void setDisplayMetrics(int width, int height);
@@ -120,13 +102,11 @@ public:
#endif
QVariant styleHint(StyleHint hint) const;
- Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const Q_DECL_OVERRIDE;
+ Qt::WindowState defaultWindowState(Qt::WindowFlags flags) const;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
- void pauseApp();
- void resumeApp();
static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh);
static void setDefaultDesktopSize(int gw, int gh);
static void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
@@ -140,20 +120,13 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
-#ifdef ANDROID_PLUGIN_OPENGL
- QEglFSScreen *createScreen() const;
-#endif
-
static bool needsWorkaround();
-
+ EGLDisplay m_eglDisplay;
private:
- friend class QEglFSAndroidHooks;
QTouchDevice *m_touchDevice;
-#ifndef ANDROID_PLUGIN_OPENGL
QAndroidPlatformScreen *m_primaryScreen;
-#endif
QThread *m_mainThread;
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index 1ecabb25e2..1ecabb25e2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h
index 305b64168a..305b64168a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenu.h
+++ b/src/plugins/platforms/android/qandroidplatformmenu.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
index 134062fb32..134062fb32 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenubar.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h
index 56915335c2..56915335c2 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenubar.h
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
index bd37834d2a..bd37834d2a 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenuitem.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h b/src/plugins/platforms/android/qandroidplatformmenuitem.h
index 5861e8e195..5861e8e195 100644
--- a/src/plugins/platforms/android/src/qandroidplatformmenuitem.h
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.h
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index d94bb241f7..59ca69c004 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,49 +40,31 @@
**
****************************************************************************/
-#include "qandroidopenglcontext.h"
-#include "qandroidopenglplatformwindow.h"
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformintegration.h"
-#include <QtCore/qdebug.h>
-#include <qpa/qwindowsysteminterface.h>
-
+#include <QSurface>
#include <QtGui/private/qopenglcontext_p.h>
QT_BEGIN_NAMESPACE
-QAndroidOpenGLContext::QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
- const QSurfaceFormat &format,
- QPlatformOpenGLContext *share,
- EGLDisplay display,
- EGLenum eglApi)
- : QEglFSContext(format, share, display, eglApi)
- , m_platformIntegration(integration)
+QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
+ :QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API)
{
}
-void QAndroidOpenGLContext::swapBuffers(QPlatformSurface *surface)
+void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
{
- QEglFSContext::swapBuffers(surface);
+ QEGLPlatformContext::swapBuffers(surface);
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- QAndroidOpenGLPlatformWindow *window = static_cast<QAndroidOpenGLPlatformWindow *>(surface);
- window->lock();
- QSize size = window->scheduledResize();
- if (size.isValid()) {
- QRect geometry(QPoint(0, 0), size);
- window->setGeometry(geometry);
- QWindowSystemInterface::handleGeometryChange(window->window(), geometry);
- QWindowSystemInterface::handleExposeEvent(window->window(), QRegion(geometry));
- window->scheduleResize(QSize());
- }
- window->unlock();
- }
+ if (surface->surface()->surfaceClass() == QSurface::Window)
+ static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig());
}
-bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
+bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
{
- bool ret = QEglFSContext::makeCurrent(surface);
+ bool ret = QEGLPlatformContext::makeCurrent(surface);
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
@@ -94,4 +77,11 @@ bool QAndroidOpenGLContext::makeCurrent(QPlatformSurface *surface)
return ret;
}
+EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+{
+ if (surface->surface()->surfaceClass() == QSurface::Window)
+ return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
+ return EGL_NO_SURFACE;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
index c419ae8392..29e5f596d5 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglcontext.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,31 +40,24 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLCONTEXT_H
-#define QANDROIDOPENGLCONTEXT_H
+#ifndef QANDROIDPLATFORMOPENGLCONTEXT_H
+#define QANDROIDPLATFORMOPENGLCONTEXT_H
-#include <QtCore/qreadwritelock.h>
-#include "qeglfscontext.h"
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
-class QAndroidPlatformIntegration;
-class QAndroidOpenGLContext : public QEglFSContext
+class QAndroidPlatformOpenGLContext : public QEGLPlatformContext
{
public:
- QAndroidOpenGLContext(const QAndroidPlatformIntegration *integration,
- const QSurfaceFormat &format,
- QPlatformOpenGLContext *share,
- EGLDisplay display,
- EGLenum eglApi = EGL_OPENGL_ES_API);
-
+ QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
void swapBuffers(QPlatformSurface *surface);
bool makeCurrent(QPlatformSurface *surface);
private:
- const QAndroidPlatformIntegration *m_platformIntegration;
+ virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
};
QT_END_NAMESPACE
-#endif // QANDROIDOPENGLCONTEXT_H
+#endif // QANDROIDPLATFORMOPENGLCONTEXT_H
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
new file mode 100644
index 0000000000..9df6610a99
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformopenglwindow.h"
+
+#include "androidjnimain.h"
+
+#include <QSurfaceFormat>
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <android/native_window.h>
+#include <android/native_window_jni.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformOpenGLWindow::QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display)
+ :QAndroidPlatformWindow(window), m_eglDisplay(display)
+{
+ lockSurface();
+ m_nativeSurfaceId = QtAndroid::createSurface(this, geometry(), bool(window->flags() & Qt::WindowStaysOnTopHint));
+ m_surfaceWaitCondition.wait(&m_surfaceMutex);
+ unlockSurface();
+}
+
+QAndroidPlatformOpenGLWindow::~QAndroidPlatformOpenGLWindow()
+{
+ m_surfaceWaitCondition.wakeOne();
+ lockSurface();
+ if (m_nativeSurfaceId != -1)
+ QtAndroid::destroySurface(m_nativeSurfaceId);
+ clearEgl();
+ unlockSurface();
+}
+
+void QAndroidPlatformOpenGLWindow::setGeometry(const QRect &rect)
+{
+ if (rect == geometry())
+ return;
+
+ QAndroidPlatformWindow::setGeometry(rect);
+ QtAndroid::setSurfaceGeometry(m_nativeSurfaceId, rect);
+}
+
+EGLSurface QAndroidPlatformOpenGLWindow::eglSurface(EGLConfig config)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ m_surfaceMutex.unlock();
+ checkNativeSurface(config);
+ m_surfaceMutex.lock();
+ }
+ return m_eglSurface;
+}
+
+void QAndroidPlatformOpenGLWindow::checkNativeSurface(EGLConfig config)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
+ return;
+
+ createEgl(config);
+
+ // we've create another surface, the window should be repainted
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+}
+
+void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
+{
+ clearEgl();
+ QJNIEnvironmentPrivate env;
+ m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
+ m_androidSurfaceObject = QJNIObjectPrivate();
+ m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
+ if (m_eglSurface == EGL_NO_SURFACE) {
+ EGLint error = eglGetError();
+ eglTerminate(m_eglDisplay);
+ qFatal("EGL Error : Could not create the egl surface: error = 0x%x\n", error);
+ }
+}
+
+void QAndroidPlatformOpenGLWindow::clearEgl()
+{
+ eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(m_eglDisplay, m_eglSurface);
+ m_eglSurface = EGL_NO_SURFACE;
+ }
+
+ if (m_nativeWindow) {
+ ANativeWindow_release(m_nativeWindow);
+ m_nativeWindow = 0;
+ }
+}
+
+void QAndroidPlatformOpenGLWindow::surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h)
+{
+ Q_UNUSED(jniEnv);
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+ lockSurface();
+ m_androidSurfaceObject = surface;
+ m_surfaceWaitCondition.wakeOne();
+ unlockSurface();
+
+ // repaint the window
+ QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformopenglwindow.h b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
new file mode 100644
index 0000000000..7af8b722aa
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformopenglwindow.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
+#define QANDROIDPLATFORMOPENGLWINDOW_H
+
+#include <EGL/egl.h>
+#include <QWaitCondition>
+#include <QtCore/private/qjni_p.h>
+
+#include "androidsurfaceclient.h"
+#include "qandroidplatformwindow.h"
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
+{
+public:
+ explicit QAndroidPlatformOpenGLWindow(QWindow *window, EGLDisplay display);
+ ~QAndroidPlatformOpenGLWindow();
+
+ void setGeometry(const QRect &rect);
+ EGLSurface eglSurface(EGLConfig config);
+
+ void checkNativeSurface(EGLConfig config);
+
+protected:
+ virtual void surfaceChanged(JNIEnv *jniEnv, jobject surface, int w, int h);
+ void createEgl(EGLConfig config);
+ void clearEgl();
+
+private:
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface = EGL_NO_SURFACE;
+ EGLNativeWindowType m_nativeWindow = nullptr;
+
+ int m_nativeSurfaceId = -1;
+ QJNIObjectPrivate m_androidSurfaceObject;
+ QWaitCondition m_surfaceWaitCondition;
+};
+
+QT_END_NAMESPACE
+#endif // QANDROIDPLATFORMOPENGLWINDOW_H
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
new file mode 100644
index 0000000000..68545c6562
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformrasterwindow.h"
+
+#include "qandroidplatformscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformRasterWindow::QAndroidPlatformRasterWindow(QWindow *window)
+ :QAndroidPlatformWindow(window)
+{
+
+}
+
+void QAndroidPlatformRasterWindow::repaint(const QRegion &region)
+{
+ QRect currentGeometry = geometry().translated(mapToGlobal(QPoint(0,0)));
+
+ QRect dirtyClient = region.boundingRect();
+ QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
+ currentGeometry.top() + dirtyClient.top(),
+ dirtyClient.width(),
+ dirtyClient.height());
+ QRect mOldGeometryLocal = m_oldGeometry;
+ m_oldGeometry = currentGeometry;
+ // If this is a move, redraw the previous location
+ if (mOldGeometryLocal != currentGeometry)
+ platformScreen()->setDirty(mOldGeometryLocal);
+ platformScreen()->setDirty(dirtyRegion);
+}
+
+void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
+{
+ m_oldGeometry = geometry();
+ QAndroidPlatformWindow::setGeometry(rect);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.h b/src/plugins/platforms/android/qandroidplatformrasterwindow.h
new file mode 100644
index 0000000000..50c0d497af
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMRASTERWINDOW_H
+#define QANDROIDPLATFORMRASTERWINDOW_H
+
+#include "qandroidplatformwindow.h"
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformBackingStore;
+class QAndroidPlatformRasterWindow : public QObject, public QAndroidPlatformWindow
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformRasterWindow(QWindow *window);
+
+ void setBackingStore(QAndroidPlatformBackingStore *store) { m_backingStore = store; }
+ QAndroidPlatformBackingStore *backingStore() const { return m_backingStore; }
+ void repaint(const QRegion&region);
+
+public slots:
+ void setGeometry(const QRect &rect);
+
+private:
+ QAndroidPlatformBackingStore *m_backingStore = nullptr;
+ QRect m_oldGeometry;
+
+};
+
+QT_END_NAMESPACE
+#endif // QANDROIDPLATFORMRASTERWINDOW_H
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
new file mode 100644
index 0000000000..dd86a80d23
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -0,0 +1,352 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QTime>
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include "qandroidplatformscreen.h"
+#include "qandroidplatformbackingstore.h"
+#include "qandroidplatformintegration.h"
+#include "androidjnimain.h"
+#include "androidjnimenu.h"
+#include "qandroidplatformrasterwindow.h"
+
+#include <android/bitmap.h>
+#include <android/native_window_jni.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef QANDROIDPLATFORMSCREEN_DEBUG
+class ScopedProfiler
+{
+public:
+ ScopedProfiler(const QString &msg)
+ {
+ m_msg = msg;
+ }
+ ~ScopedProfiler()
+ {
+ qDebug() << m_msg << m_timer.elapsed();
+ }
+
+private:
+ QTime m_timer;
+ QString m_msg;
+};
+
+# define PROFILE_SCOPE ScopedProfiler ___sp___(__func__)
+#else
+# define PROFILE_SCOPE
+#endif
+
+QAndroidPlatformScreen::QAndroidPlatformScreen():QObject(),QPlatformScreen()
+{
+ m_geometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ // Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
+ // is way much faster than 32
+ if (qgetenv("QT_ANDROID_RASTER_IMAGE_DEPTH").toInt() == 16) {
+ m_format = QImage::Format_RGB16;
+ m_depth = 16;
+ } else {
+ m_format = QImage::Format_ARGB32_Premultiplied;
+ m_depth = 32;
+ }
+ m_physicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
+ m_physicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
+ m_redrawTimer.setSingleShot(true);
+ m_redrawTimer.setInterval(0);
+ connect(&m_redrawTimer, SIGNAL(timeout()), this, SLOT(doRedraw()));
+}
+
+QAndroidPlatformScreen::~QAndroidPlatformScreen()
+{
+ if (m_id != -1) {
+ QtAndroid::destroySurface(m_id);
+ m_surfaceWaitCondition.wakeOne();
+ if (m_nativeSurface)
+ ANativeWindow_release(m_nativeSurface);
+ }
+}
+
+QWindow *QAndroidPlatformScreen::topWindow() const
+{
+ foreach (QAndroidPlatformWindow *w, m_windowStack)
+ if (w->window()->type() == Qt::Window || w->window()->type() == Qt::Dialog)
+ return w->window();
+ return 0;
+}
+
+QWindow *QAndroidPlatformScreen::topLevelAt(const QPoint &p) const
+{
+ foreach (QAndroidPlatformWindow *w, m_windowStack) {
+ if (w->geometry().contains(p, false) && w->window()->isVisible())
+ return w->window();
+ }
+ return 0;
+}
+
+void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ m_windowStack.prepend(window);
+ if (window->isRaster())
+ setDirty(window->geometry());
+
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ m_windowStack.removeOne(window);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::raise(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ int index = m_windowStack.indexOf(window);
+ if (index <= 0)
+ return;
+ m_windowStack.move(index, 0);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::lower(QAndroidPlatformWindow *window)
+{
+ if (window->parent())
+ return;
+
+ int index = m_windowStack.indexOf(window);
+ if (index == -1 || index == (m_windowStack.size() - 1))
+ return;
+ m_windowStack.move(index, m_windowStack.size() - 1);
+ if (window->isRaster()) {
+ setDirty(window->geometry());
+ }
+ QWindow *w = topWindow();
+ QWindowSystemInterface::handleWindowActivated(w);
+ topWindowChanged(w);
+}
+
+void QAndroidPlatformScreen::scheduleUpdate()
+{
+ if (!m_redrawTimer.isActive())
+ m_redrawTimer.start();
+}
+
+void QAndroidPlatformScreen::setDirty(const QRect &rect)
+{
+ QRect intersection = rect.intersected(m_geometry);
+ m_repaintRegion += intersection;
+ scheduleUpdate();
+}
+
+void QAndroidPlatformScreen::setPhysicalSize(const QSize &size)
+{
+ m_physicalSize = size;
+}
+
+void QAndroidPlatformScreen::setGeometry(const QRect &rect)
+{
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_geometry == rect)
+ return;
+
+ m_geometry = rect;
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
+ resizeMaximizedWindows();
+
+ if (m_id != -1) {
+ if (m_nativeSurface) {
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = 0;
+ }
+ QtAndroid::setSurfaceGeometry(m_id, rect);
+ }
+}
+
+void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
+{
+ QtAndroidMenu::setActiveTopLevelWindow(w);
+
+ if (w != 0) {
+ QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
+ if (platformWindow != 0)
+ platformWindow->updateStatusBarVisibility();
+ }
+}
+
+void QAndroidPlatformScreen::doRedraw()
+{
+ PROFILE_SCOPE;
+
+ if (m_repaintRegion.isEmpty())
+ return;
+
+ QVector<QRect> rects = m_repaintRegion.rects();
+
+ QMutexLocker lock(&m_surfaceMutex);
+ if (m_id == -1) {
+ m_id = QtAndroid::createSurface(this, m_geometry, true);
+ m_surfaceWaitCondition.wait(&m_surfaceMutex);
+ }
+
+ if (!m_nativeSurface)
+ return;
+
+ ANativeWindow_Buffer nativeWindowBuffer;
+ ARect nativeWindowRect;
+ QRect br = m_repaintRegion.boundingRect();
+ nativeWindowRect.top = br.top();
+ nativeWindowRect.left = br.left();
+ nativeWindowRect.bottom = br.bottom() + 1; // for some reason that I don't understand the QRect bottom needs to +1 to be the same with ARect bottom
+ nativeWindowRect.right = br.right() + 1; // same for the right
+
+ int ret;
+ if ((ret = ANativeWindow_lock(m_nativeSurface, &nativeWindowBuffer, &nativeWindowRect)) < 0) {
+ qWarning() << "ANativeWindow_lock() failed! error=" << ret;
+ return;
+ }
+
+ int bpp = 4;
+ QImage::Format format = QImage::Format_RGBA8888_Premultiplied;
+ if (nativeWindowBuffer.format == WINDOW_FORMAT_RGB_565) {
+ bpp = 2;
+ format = QImage::Format_RGB16;
+ }
+
+ QImage screenImage(reinterpret_cast<uchar *>(nativeWindowBuffer.bits)
+ , nativeWindowBuffer.width, nativeWindowBuffer.height
+ , nativeWindowBuffer.stride * bpp , format);
+
+ QPainter compositePainter(&screenImage);
+ compositePainter.setCompositionMode(QPainter::CompositionMode_Source);
+
+ for (int rectIndex = 0; rectIndex < rects.size(); rectIndex++) {
+ QRegion visibleRegion = rects[rectIndex];
+ foreach (QAndroidPlatformWindow *window, m_windowStack) {
+ if (!window->window()->isVisible()
+ || !window->isRaster())
+ continue;
+
+ foreach (const QRect &rect, visibleRegion.rects()) {
+ QRect targetRect = window->geometry();
+ targetRect &= rect;
+
+ if (targetRect.isNull())
+ continue;
+
+ visibleRegion -= targetRect;
+ QRect windowRect = targetRect.translated(-window->geometry().topLeft());
+ QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformRasterWindow *>(window)->backingStore();
+ if (backingStore)
+ compositePainter.drawImage(targetRect.topLeft(), backingStore->image(), windowRect);
+ }
+ }
+
+ foreach (const QRect &rect, visibleRegion.rects()) {
+ compositePainter.fillRect(rect, QColor(Qt::transparent));
+ }
+ }
+
+ ret = ANativeWindow_unlockAndPost(m_nativeSurface);
+ if (ret >= 0)
+ m_repaintRegion = QRegion();
+}
+
+QDpi QAndroidPlatformScreen::logicalDpi() const
+{
+ qreal lDpi = QtAndroid::scaledDensity() * 72;
+ return QDpi(lDpi, lDpi);
+}
+
+Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
+{
+ return QAndroidPlatformIntegration::m_orientation;
+}
+
+Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
+{
+ return QAndroidPlatformIntegration::m_nativeOrientation;
+}
+
+void QAndroidPlatformScreen::surfaceChanged(JNIEnv *env, jobject surface, int w, int h)
+{
+ lockSurface();
+ if (surface && w && h) {
+ if (m_nativeSurface)
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = ANativeWindow_fromSurface(env, surface);
+ QMetaObject::invokeMethod(this, "setDirty", Qt::QueuedConnection, Q_ARG(QRect, QRect(0, 0, w, h)));
+ } else {
+ if (m_nativeSurface) {
+ ANativeWindow_release(m_nativeSurface);
+ m_nativeSurface = 0;
+ }
+ }
+ unlockSurface();
+ m_surfaceWaitCondition.wakeOne();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
new file mode 100644
index 0000000000..d3de937548
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMSCREEN_H
+#define QANDROIDPLATFORMSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <QList>
+#include <QPainter>
+#include <QTimer>
+#include <QWaitCondition>
+#include <QtCore/private/qjni_p.h>
+
+#include "androidsurfaceclient.h"
+
+#include <android/native_window.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAndroidPlatformWindow;
+class QAndroidPlatformBackingStore;
+
+class QAndroidPlatformScreen: public QObject, public QPlatformScreen, public AndroidSurfaceClient
+{
+ Q_OBJECT
+public:
+ QAndroidPlatformScreen();
+ ~QAndroidPlatformScreen();
+
+ QRect geometry() const { return m_geometry; }
+ int depth() const { return m_depth; }
+ QImage::Format format() const { return m_format; }
+ QSizeF physicalSize() const { return m_physicalSize; }
+
+ inline QWindow *topWindow() const;
+ QWindow *topLevelAt(const QPoint & p) const;
+
+ // compositor api
+ void addWindow(QAndroidPlatformWindow *window);
+ void removeWindow(QAndroidPlatformWindow *window);
+ void raise(QAndroidPlatformWindow *window);
+ void lower(QAndroidPlatformWindow *window);
+
+ void scheduleUpdate();
+ void topWindowChanged(QWindow *w);
+
+public slots:
+ void setDirty(const QRect &rect);
+ void setPhysicalSize(const QSize &size);
+ void setGeometry(const QRect &rect);
+
+protected:
+ typedef QList<QAndroidPlatformWindow *> WindowStackType;
+ WindowStackType m_windowStack;
+ QRegion m_repaintRegion;
+ QTimer m_redrawTimer;
+
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSizeF m_physicalSize;
+
+private:
+ QDpi logicalDpi() const;
+ Qt::ScreenOrientation orientation() const;
+ Qt::ScreenOrientation nativeOrientation() const;
+ void surfaceChanged(JNIEnv *env, jobject surface, int w, int h);
+
+private slots:
+ void doRedraw();
+
+private:
+ int m_id = -1;
+ ANativeWindow* m_nativeSurface = nullptr;
+ QWaitCondition m_surfaceWaitCondition;
+};
+
+QT_END_NAMESPACE
+#endif
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 0df882f1f0..0df882f1f0 100644
--- a/src/plugins/platforms/android/src/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
diff --git a/src/plugins/platforms/android/src/qandroidplatformservices.h b/src/plugins/platforms/android/qandroidplatformservices.h
index 8368b19043..8368b19043 100644
--- a/src/plugins/platforms/android/src/qandroidplatformservices.h
+++ b/src/plugins/platforms/android/qandroidplatformservices.h
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 308bb70faf..039b19f861 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -46,11 +46,44 @@
#include "qandroidplatformdialoghelpers.h"
#include <QVariant>
#include <QFileInfo>
+#include <QCoreApplication>
#include <qandroidplatformintegration.h>
QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface)
{
m_androidPlatformNativeInterface = androidPlatformNativeInterface;
+ QColor background(229, 229, 229);
+ QColor light = background.lighter(150);
+ QColor mid(background.darker(130));
+ QColor midLight = mid.lighter(110);
+ QColor base(249, 249, 249);
+ QColor disabledBase(background);
+ QColor dark = background.darker(150);
+ QColor darkDisabled = dark.darker(110);
+ QColor text = Qt::black;
+ QColor highlightedText = Qt::black;
+ QColor disabledText = QColor(190, 190, 190);
+ QColor button(241, 241, 241);
+ QColor shadow(201, 201, 201);
+ QColor highlight(148, 210, 231);
+ QColor disabledShadow = shadow.lighter(150);
+
+ m_defaultPalette = QPalette(Qt::black,background,light,dark,mid,text,base);
+ m_defaultPalette.setBrush(QPalette::Midlight, midLight);
+ m_defaultPalette.setBrush(QPalette::Button, button);
+ m_defaultPalette.setBrush(QPalette::Shadow, shadow);
+ m_defaultPalette.setBrush(QPalette::HighlightedText, highlightedText);
+
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow);
+
+ m_defaultPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight);
+ m_defaultPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight);
+ m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Highlight, highlight.lighter(150));
}
QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const
@@ -101,7 +134,7 @@ const QPalette *QAndroidPlatformTheme::palette(Palette type) const
QHash<int, QPalette>::const_iterator it = m_androidPlatformNativeInterface->m_palettes.find(paletteType(type));
if (it != m_androidPlatformNativeInterface->m_palettes.end())
return &(it.value());
- return 0;
+ return &m_defaultPalette;
}
static inline int fontType(QPlatformTheme::Font type)
@@ -152,6 +185,21 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const
}
}
+QString QAndroidPlatformTheme::standardButtonText(int button) const
+{
+ switch (button) {
+ case QPlatformDialogHelper::Yes:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "Yes");
+ case QPlatformDialogHelper::YesToAll:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "Yes to All");
+ case QPlatformDialogHelper::No:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "No");
+ case QPlatformDialogHelper::NoToAll:
+ return QCoreApplication::translate("QAndroidPlatformTheme", "No to All");
+ }
+ return QPlatformTheme::standardButtonText(button);
+}
+
bool QAndroidPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
{
if (type == MessageDialog)
diff --git a/src/plugins/platforms/android/src/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index 9614e51f80..fecd7ca8e9 100644
--- a/src/plugins/platforms/android/src/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -56,12 +56,14 @@ public:
virtual const QPalette *palette(Palette type = SystemPalette) const;
virtual const QFont *font(Font type = SystemFont) const;
virtual QVariant themeHint(ThemeHint hint) const;
+ QString standardButtonText(int button) const Q_DECL_OVERRIDE;
virtual bool usePlatformNativeDialog(DialogType type) const;
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
private:
QAndroidPlatformNativeInterface * m_androidPlatformNativeInterface;
+ QPalette m_defaultPalette;
};
#endif // QANDROIDPLATFORMTHEME_H
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 7ff18526d9..b4231f0283 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,63 +41,122 @@
****************************************************************************/
#include "qandroidplatformwindow.h"
+#include "qandroidplatformopenglcontext.h"
+#include "qandroidplatformscreen.h"
#include "androidjnimain.h"
#include <qpa/qwindowsysteminterface.h>
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
- : QFbWindow(window)
+ : QPlatformWindow(window)
{
+ m_windowFlags = Qt::Widget;
+ m_windowState = Qt::WindowNoState;
+ static QAtomicInt winIdGenerator(1);
+ m_windowId = winIdGenerator.fetchAndAddRelaxed(1);
+ setWindowState(window->windowState());
}
-void QAndroidPlatformWindow::setGeometry(const QRect &rect)
+void QAndroidPlatformWindow::lower()
{
- QFbWindow::setGeometry(rect);
+ platformScreen()->lower(this);
}
-void QAndroidPlatformWindow::propagateSizeHints()
+void QAndroidPlatformWindow::raise()
{
- //shut up warning from default implementation
+ updateStatusBarVisibility();
+ platformScreen()->raise(this);
}
-void QAndroidPlatformWindow::updateStatusBarVisibility()
+void QAndroidPlatformWindow::setGeometry(const QRect &rect)
{
- Qt::WindowFlags flags = window()->flags();
- bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
- if (!isNonRegularWindow) {
- if (mWindowState & Qt::WindowFullScreen)
- QtAndroid::hideStatusBar();
- else if (mWindowState & Qt::WindowMaximized)
- QtAndroid::showStatusBar();
- }
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ QPlatformWindow::setGeometry(rect);
}
-void QAndroidPlatformWindow::raise()
+void QAndroidPlatformWindow::setVisible(bool visible)
{
- updateStatusBarVisibility();
- QFbWindow::raise();
+ if (visible)
+ updateStatusBarVisibility();
+
+ if (visible) {
+ if (m_windowState & Qt::WindowFullScreen)
+ setGeometry(platformScreen()->geometry());
+ else if (m_windowState & Qt::WindowMaximized)
+ setGeometry(platformScreen()->availableGeometry());
+ }
+
+ QPlatformWindow::setVisible(visible);
+
+ if (visible)
+ platformScreen()->addWindow(this);
+ else
+ platformScreen()->removeWindow(this);
+
+ // The Android Activity is activated before Qt is initialized, causing the application state to
+ // never be set to 'active'. We explicitly set this state when the first window becomes visible.
+ if (visible)
+ QtAndroid::setApplicationActive();
}
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)
{
- if (mWindowState == state)
+ if (m_windowState == state)
return;
+ QPlatformWindow::setWindowState(state);
+ m_windowState = state;
+
if (window()->isVisible())
updateStatusBarVisibility();
+}
- QFbWindow::setWindowState(state);
+void QAndroidPlatformWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ if (m_windowFlags == flags)
+ return;
+
+ m_windowFlags = flags;
}
-void QAndroidPlatformWindow::setVisible(bool visible)
+Qt::WindowFlags QAndroidPlatformWindow::windowFlags() const
{
- if (visible)
- updateStatusBarVisibility();
+ return m_windowFlags;
+}
- QFbWindow::setVisible(visible);
+void QAndroidPlatformWindow::setParent(const QPlatformWindow *window)
+{
+ Q_UNUSED(window);
+}
- // The Android Activity is activated before Qt is initialized, causing the application state to
- // never be set to 'active'. We explicitly set this state when the first window becomes visible.
- if (visible)
- QtAndroid::setApplicationActive();
+QAndroidPlatformScreen *QAndroidPlatformWindow::platformScreen() const
+{
+ return static_cast<QAndroidPlatformScreen *>(window()->screen()->handle());
+}
+
+void QAndroidPlatformWindow::propagateSizeHints()
+{
+ //shut up warning from default implementation
+}
+
+void QAndroidPlatformWindow::requestActivateWindow()
+{
+ platformScreen()->topWindowChanged(window());
+}
+
+void QAndroidPlatformWindow::updateStatusBarVisibility()
+{
+ Qt::WindowFlags flags = window()->flags();
+ bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
+ if (!isNonRegularWindow) {
+ if (m_windowState & Qt::WindowFullScreen)
+ QtAndroid::hideStatusBar();
+ else if (m_windowState & Qt::WindowMaximized)
+ QtAndroid::showStatusBar();
+ }
}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index e4ff0444d4..764dd3ab86 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
@@ -39,53 +40,48 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLPLATFORMWINDOW_H
-#define QANDROIDOPENGLPLATFORMWINDOW_H
-
-#include "qeglfswindow.h"
-#include <QtCore/qmutex.h>
-#include <QtCore/qreadwritelock.h>
+#ifndef ANDROIDPLATFORMWINDOW_H
+#define ANDROIDPLATFORMWINDOW_H
+#include <qobject.h>
+#include <qrect.h>
+#include <qpa/qplatformwindow.h>
QT_BEGIN_NAMESPACE
-class QAndroidOpenGLPlatformWindow : public QEglFSWindow
+class QAndroidPlatformScreen;
+
+class QAndroidPlatformWindow: public QPlatformWindow
{
public:
- QAndroidOpenGLPlatformWindow(QWindow *window);
- ~QAndroidOpenGLPlatformWindow();
-
- QSize scheduledResize() const { return m_scheduledResize; }
- void scheduleResize(const QSize &size) { m_scheduledResize = size; }
-
- void lock() { m_lock.lock(); }
- void unlock() { m_lock.unlock(); }
-
- bool isExposed() const;
+ explicit QAndroidPlatformWindow(QWindow *window);
+ void lower();
void raise();
- void invalidateSurface();
- void resetSurface();
- void setWindowState(Qt::WindowState state);
-
void setVisible(bool visible);
- void destroy();
+ void setWindowState(Qt::WindowState state);
+ void setWindowFlags(Qt::WindowFlags flags);
+ Qt::WindowFlags windowFlags() const;
+ void setParent(const QPlatformWindow *window);
+ WId winId() const { return m_windowId; }
+
+ QAndroidPlatformScreen *platformScreen() const;
- static void updateStaticNativeWindow();
+ void propagateSizeHints();
+ void requestActivateWindow();
void updateStatusBarVisibility();
+ inline bool isRaster() const { return window()->surfaceType() == QSurface::RasterSurface; }
-private:
- QSize m_scheduledResize;
- QMutex m_lock;
- Qt::WindowState m_state;
+protected:
+ void setGeometry(const QRect &rect);
- static QReadWriteLock m_staticSurfaceLock;
- static EGLSurface m_staticSurface;
- static EGLNativeWindowType m_staticNativeWindow;
- static QBasicAtomicInt m_referenceCount;
+protected:
+ Qt::WindowFlags m_windowFlags;
+ Qt::WindowState m_windowState;
+
+ WId m_windowId;
};
QT_END_NAMESPACE
-
-#endif // QANDROIDOPENGLPLATFORMWINDOW_H
+#endif // ANDROIDPLATFORMWINDOW_H
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp b/src/plugins/platforms/android/qandroidsystemlocale.cpp
index a20f970a44..a20f970a44 100644
--- a/src/plugins/platforms/android/src/qandroidsystemlocale.cpp
+++ b/src/plugins/platforms/android/qandroidsystemlocale.cpp
diff --git a/src/plugins/platforms/android/src/qandroidsystemlocale.h b/src/plugins/platforms/android/qandroidsystemlocale.h
index fc2f6fad98..fc2f6fad98 100644
--- a/src/plugins/platforms/android/src/qandroidsystemlocale.h
+++ b/src/plugins/platforms/android/qandroidsystemlocale.h
diff --git a/src/plugins/platforms/android/raster/raster.pro b/src/plugins/platforms/android/raster/raster.pro
deleted file mode 100644
index 53d8ee7a2b..0000000000
--- a/src/plugins/platforms/android/raster/raster.pro
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = qtforandroid
-
-PLUGIN_TYPE = platforms
-
-# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp
-# Yes, the plugin imports itself statically
-DEFINES += QT_STATICPLUGIN
-
-load(qt_plugin)
-
-!contains(ANDROID_PLATFORM, android-9) {
- INCLUDEPATH += $$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/include
- LIBS += -L$$NDK_ROOT/platforms/android-9/arch-$$ANDROID_ARCHITECTURE/usr/lib -ljnigraphics -landroid
-} else {
- LIBS += -ljnigraphics -landroid
-}
-
-include($$PWD/../src/src.pri)
-include($$PWD/../src/raster/raster.pri)
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp b/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
deleted file mode 100644
index 6ed805174b..0000000000
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformwindow.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qandroidopenglplatformwindow.h"
-#include "androidjnimain.h"
-#include "qandroidplatformintegration.h"
-#include <qpa/qwindowsysteminterface.h>
-
-QT_BEGIN_NAMESPACE
-
-EGLSurface QAndroidOpenGLPlatformWindow::m_staticSurface = 0;
-EGLNativeWindowType QAndroidOpenGLPlatformWindow::m_staticNativeWindow = 0;
-QReadWriteLock QAndroidOpenGLPlatformWindow::m_staticSurfaceLock;
-QBasicAtomicInt QAndroidOpenGLPlatformWindow::m_referenceCount = Q_BASIC_ATOMIC_INITIALIZER(0);
-
-QAndroidOpenGLPlatformWindow::QAndroidOpenGLPlatformWindow(QWindow *window)
- : QEglFSWindow(window)
- , m_state(Qt::WindowNoState)
-{
-}
-
-QAndroidOpenGLPlatformWindow::~QAndroidOpenGLPlatformWindow()
-{
- destroy();
-}
-
-bool QAndroidOpenGLPlatformWindow::isExposed() const
-{
- return QtAndroid::nativeWindow(false) != 0 && QEglFSWindow::isExposed();
-}
-
-void QAndroidOpenGLPlatformWindow::invalidateSurface()
-{
- QWindowSystemInterface::handleExposeEvent(window(), QRegion()); // Obscure event
- QWindowSystemInterface::flushWindowSystemEvents();
-
- m_window = 0;
- m_surface = 0;
-
- if (!m_referenceCount.deref()){
- QWriteLocker locker(&m_staticSurfaceLock);
-
- EGLDisplay display = (static_cast<QEglFSScreen *>(window()->screen()->handle()))->display();
- eglDestroySurface(display, m_staticSurface);
-
- m_staticSurface = 0;
- m_staticNativeWindow = 0;
- }
-}
-
-void QAndroidOpenGLPlatformWindow::updateStaticNativeWindow()
-{
- QWriteLocker locker(&m_staticSurfaceLock);
- m_staticNativeWindow = QtAndroid::nativeWindow(false);
-}
-
-void QAndroidOpenGLPlatformWindow::resetSurface()
-{
- // Only add a reference if we're not already holding one, otherwise we're just updating
- // the native window pointer
- if (m_window == 0)
- m_referenceCount.ref();
-
- if (m_staticSurface == 0) {
- QWriteLocker locker(&m_staticSurfaceLock);
- QEglFSWindow::resetSurface();
- m_staticSurface = m_surface;
- m_staticNativeWindow = m_window;
- } else {
- QReadLocker locker(&m_staticSurfaceLock);
- m_window = m_staticNativeWindow;
- m_surface = m_staticSurface;
- }
-
- {
- lock();
- // Use the desktop size.
- // On some devices, the getters for the native window size gives wrong values
- scheduleResize(QAndroidPlatformIntegration::defaultDesktopSize());
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
- unlock();
- }
-
- QWindowSystemInterface::flushWindowSystemEvents();
-}
-
-void QAndroidOpenGLPlatformWindow::destroy()
-{
- if (!m_referenceCount.deref()) {
- QEglFSWindow::destroy();
- } else {
- m_window = 0;
- m_surface = 0;
- }
-}
-
-void QAndroidOpenGLPlatformWindow::updateStatusBarVisibility()
-{
- Qt::WindowFlags flags = window()->flags();
- bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window;
- if (!isNonRegularWindow) {
- if (m_state & Qt::WindowFullScreen)
- QtAndroid::hideStatusBar();
- else if (m_state & Qt::WindowMaximized)
- QtAndroid::showStatusBar();
- }
-}
-
-void QAndroidOpenGLPlatformWindow::raise()
-{
- updateStatusBarVisibility();
-}
-
-void QAndroidOpenGLPlatformWindow::setWindowState(Qt::WindowState state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
- if (window()->isVisible())
- updateStatusBarVisibility();
-}
-
-void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
-{
- if (visible)
- updateStatusBarVisibility();
-
- QEglFSWindow::setVisible(visible);
-
- // The Android Activity is activated before Qt is initialized, causing the application state to
- // never be set to 'active'. We explicitly set this state when the first window becomes visible.
- if (visible)
- QtAndroid::setApplicationActive();
-
- QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
- QWindowSystemInterface::flushWindowSystemEvents();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
deleted file mode 100644
index 278cd553f4..0000000000
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfshooks.h"
-#include "androidjnimain.h"
-#include "qandroidplatformintegration.h"
-
-#include <android/native_window.h>
-#include <jni.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEglFSAndroidHooks: public QEglFSHooks
-{
-public:
- void platformInit();
- void platformDestroy();
- EGLNativeDisplayType platformDisplay() const;
- QSize screenSize() const;
- QSizeF physicalScreenSize() const;
- QDpi logicalDpi() const;
- Qt::ScreenOrientation orientation() const;
- Qt::ScreenOrientation nativeOrientation() const;
- int screenDepth() const;
- QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format);
- void destroyNativeWindow(EGLNativeWindowType window);
- bool hasCapability(QPlatformIntegration::Capability cap) const;
- QEglFSCursor *createCursor(QEglFSScreen *screen) const;
-};
-
-void QEglFSAndroidHooks::platformInit()
-{
-}
-
-void QEglFSAndroidHooks::platformDestroy()
-{
-}
-
-EGLNativeDisplayType QEglFSAndroidHooks::platformDisplay() const
-{
- return EGL_DEFAULT_DISPLAY;
-}
-
-QSize QEglFSAndroidHooks::screenSize() const
-{
- return QAndroidPlatformIntegration::defaultDesktopSize();
-}
-
-QSizeF QEglFSAndroidHooks::physicalScreenSize() const
-{
- return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
-}
-
-QDpi QEglFSAndroidHooks::logicalDpi() const
-{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
- return QDpi(lDpi, lDpi);
-}
-
-Qt::ScreenOrientation QEglFSAndroidHooks::orientation() const
-{
- return QAndroidPlatformIntegration::m_orientation;
-}
-
-Qt::ScreenOrientation QEglFSAndroidHooks::nativeOrientation() const
-{
- return QAndroidPlatformIntegration::m_nativeOrientation;
-}
-
-EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format)
-{
- Q_UNUSED(platformWindow);
- Q_UNUSED(size);
- Q_UNUSED(format);
- ANativeWindow *window = QtAndroid::nativeWindow();
- if (window != 0)
- ANativeWindow_acquire(window);
-
- return window;
-}
-
-void QEglFSAndroidHooks::destroyNativeWindow(EGLNativeWindowType window)
-{
- if (window != 0)
- ANativeWindow_release(window);
-}
-
-bool QEglFSAndroidHooks::hasCapability(QPlatformIntegration::Capability capability) const
-{
- switch (capability) {
- case QPlatformIntegration::OpenGL: return true;
- case QPlatformIntegration::ThreadedOpenGL: return true;
- default: return false;
- };
-}
-
-int QEglFSAndroidHooks::screenDepth() const
-{
- // ### Hardcoded
- return 32;
-}
-
-QSurfaceFormat QEglFSAndroidHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
-{
- QSurfaceFormat ret(inputFormat);
- ret.setAlphaBufferSize(8);
- ret.setRedBufferSize(8);
- ret.setGreenBufferSize(8);
- ret.setBlueBufferSize(8);
- return ret;
-}
-
-QEglFSCursor *QEglFSAndroidHooks::createCursor(QEglFSScreen *screen) const
-{
- Q_UNUSED(screen);
- return 0;
-}
-
-static QEglFSAndroidHooks eglFSAndroidHooks;
-QEglFSHooks *platformHooks = &eglFSAndroidHooks;
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/raster/raster.pri b/src/plugins/platforms/android/src/raster/raster.pri
deleted file mode 100644
index 86e5aa235f..0000000000
--- a/src/plugins/platforms/android/src/raster/raster.pri
+++ /dev/null
@@ -1,7 +0,0 @@
-INCLUDEPATH += $$PWD
-
-SOURCES += $$PWD/qandroidplatformscreen.cpp \
- $$PWD/qandroidplatformwindow.cpp
-
-HEADERS += $$PWD/qandroidplatformscreen.h \
- $$PWD/qandroidplatformwindow.h
diff --git a/src/plugins/platforms/android/src/src.pri b/src/plugins/platforms/android/src/src.pri
deleted file mode 100644
index 9b64e846f7..0000000000
--- a/src/plugins/platforms/android/src/src.pri
+++ /dev/null
@@ -1,55 +0,0 @@
-load(qt_plugin)
-
-QT += core-private gui-private platformsupport-private
-
-CONFIG += qpa/genericunixfontdatabase
-
-OTHER_FILES += $$PWD/android.json
-
-INCLUDEPATH += $$PWD
-INCLUDEPATH += $$PWD/../../../../3rdparty/android/src
-
-SOURCES += $$PWD/androidplatformplugin.cpp \
- $$PWD/androidjnimain.cpp \
- $$PWD/androidjniaccessibility.cpp \
- $$PWD/androidjniinput.cpp \
- $$PWD/androidjnimenu.cpp \
- $$PWD/androidjniclipboard.cpp \
- $$PWD/qandroidplatformintegration.cpp \
- $$PWD/qandroidplatformservices.cpp \
- $$PWD/qandroidassetsfileenginehandler.cpp \
- $$PWD/qandroidinputcontext.cpp \
- $$PWD/qandroidplatformaccessibility.cpp \
- $$PWD/qandroidplatformfontdatabase.cpp \
- $$PWD/qandroidplatformdialoghelpers.cpp \
- $$PWD/qandroidplatformclipboard.cpp \
- $$PWD/qandroidplatformtheme.cpp \
- $$PWD/qandroidplatformmenubar.cpp \
- $$PWD/qandroidplatformmenu.cpp \
- $$PWD/qandroidplatformmenuitem.cpp \
- $$PWD/qandroidsystemlocale.cpp
-
-
-HEADERS += $$PWD/qandroidplatformintegration.h \
- $$PWD/androidjnimain.h \
- $$PWD/androidjniaccessibility.h \
- $$PWD/androidjniinput.h \
- $$PWD/androidjnimenu.h \
- $$PWD/androidjniclipboard.h \
- $$PWD/qandroidplatformservices.h \
- $$PWD/qandroidassetsfileenginehandler.h \
- $$PWD/qandroidinputcontext.h \
- $$PWD/qandroidplatformaccessibility.h \
- $$PWD/qandroidplatformfontdatabase.h \
- $$PWD/qandroidplatformclipboard.h \
- $$PWD/qandroidplatformdialoghelpers.h \
- $$PWD/qandroidplatformtheme.h \
- $$PWD/qandroidplatformmenubar.h \
- $$PWD/qandroidplatformmenu.h \
- $$PWD/qandroidplatformmenuitem.h \
- $$PWD/qandroidsystemlocale.h
-
-
-#Non-standard install directory, QTBUG-29859
-DESTDIR = $$DESTDIR/android
-target.path = $${target.path}/android
diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp
index 3db1618a50..1fe80b28b1 100644
--- a/src/plugins/platforms/cocoa/messages.cpp
+++ b/src/plugins/platforms/cocoa/messages.cpp
@@ -93,4 +93,9 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
return QPlatformMenuItem::NoRole;
}
+QString msgDialogButtonDiscard()
+{
+ return QCoreApplication::translate("QCocoaTheme", "Don't Save");
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/messages.h b/src/plugins/platforms/cocoa/messages.h
index 09705c1e21..97f3ea7009 100644
--- a/src/plugins/platforms/cocoa/messages.h
+++ b/src/plugins/platforms/cocoa/messages.h
@@ -53,6 +53,8 @@ QString qt_mac_applicationmenu_string(int type);
QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption);
+QString msgDialogButtonDiscard();
+
QT_END_NAMESPACE
#endif // MESSAGES_H
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.h b/src/plugins/platforms/cocoa/qcocoaapplication.h
index ffb12ea846..bb218bcabe 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.h
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.h
@@ -86,7 +86,7 @@
//
/*
- Cocoa Application Categories
+ Cocoa Application Categories
*/
#include "qglobal.h"
#include "private/qcore_mac_p.h"
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index f9767ce716..327ca00ad6 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -114,7 +114,7 @@ static void cleanupCocoaApplicationDelegate()
- (void)updateScreens:(NSNotification *)notification
{
Q_UNUSED(notification);
- if (QCocoaIntegration *ci = dynamic_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration()))
+ if (QCocoaIntegration *ci = QCocoaIntegration::instance())
ci->updateScreens();
}
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index ee69cd7d86..29eed73535 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -75,7 +75,9 @@
#include "qcocoaeventdispatcher.h"
#include "qcocoaautoreleasepool.h"
+#include "qcocoawindow.h"
+#include "qcocoahelpers.h"
#include "qguiapplication.h"
#include "qevent.h"
#include "qhash.h"
@@ -95,11 +97,6 @@ QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
-enum {
- QtCocoaEventSubTypeWakeup = SHRT_MAX,
- QtCocoaEventSubTypePostMessage = SHRT_MAX-1
-};
-
static inline CFRunLoopRef mainRunLoop()
{
return CFRunLoopGetMain();
@@ -625,7 +622,7 @@ NSModalSession QCocoaEventDispatcherPrivate::currentModalSession()
if (!info.session) {
QCocoaAutoReleasePool pool;
- NSWindow *nswindow = static_cast<NSWindow *>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("nswindow", info.window));
+ NSWindow *nswindow = static_cast<QCocoaWindow *>(info.window->handle())->nativeWindow();
if (!nswindow)
continue;
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 8f74a71b1e..6f76892d93 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -42,6 +42,7 @@
#include "qcocoaglcontext.h"
#include "qcocoawindow.h"
#include "qcocoaautoreleasepool.h"
+#include "qcocoahelpers.h"
#include <qdebug.h>
#include <QtCore/private/qcore_mac_p.h>
#include <QtPlatformSupport/private/cglconvenience_p.h>
@@ -143,7 +144,7 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
[pixelFormat release];
- const GLint interval = 1;
+ const GLint interval = format.swapInterval() >= 0 ? format.swapInterval() : 1;
[m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
if (format.alphaBufferSize() > 0) {
@@ -151,6 +152,11 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
[m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
}
+
+ // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
+ const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
+ [m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
+
updateSurfaceFormat();
}
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 3e402673f3..419bf631aa 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -116,6 +116,7 @@ inline NSPoint qt_mac_flipPoint(const QPoint &p)
inline NSPoint qt_mac_flipPoint(const QPointF &p)
{ return NSMakePoint(p.x(), qt_mac_flipYCoordinate(p.y())); }
+NSRect qt_mac_flipRect(const QRect &rect);
NSRect qt_mac_flipRect(const QRect &rect, QWindow *window);
Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum);
@@ -161,6 +162,39 @@ CGContextRef qt_mac_cg_context(QPaintDevice *pdev);
CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy);
QImage qt_mac_toQImage(CGImageRef image);
+template<typename T>
+T qt_mac_resolveOption(const T &fallback, const QByteArray &environment)
+{
+ // check for environment variable
+ if (!environment.isEmpty()) {
+ QByteArray env = qgetenv(environment);
+ if (!env.isEmpty())
+ return T(env.toInt()); // works when T is bool, int.
+ }
+
+ return fallback;
+}
+
+template<typename T>
+T qt_mac_resolveOption(const T &fallback, QWindow *window, const QByteArray &property, const QByteArray &environment)
+{
+ // check for environment variable
+ if (!environment.isEmpty()) {
+ QByteArray env = qgetenv(environment);
+ if (!env.isEmpty())
+ return T(env.toInt()); // works when T is bool, int.
+ }
+
+ // check for window property
+ if (window && !property.isNull()) {
+ QVariant windowProperty = window->property(property);
+ if (windowProperty.isValid())
+ return windowProperty.value<T>();
+ }
+
+ // return default value.
+ return fallback;
+}
QT_END_NAMESPACE
#endif //QCOCOAHELPERS_H
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 4a5696b35e..d27c134fa3 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -585,6 +585,12 @@ QString qt_mac_applicationName()
return appName;
}
+NSRect qt_mac_flipRect(const QRect &rect)
+{
+ int flippedY = qt_mac_flipYCoordinate(rect.y() + rect.height());
+ return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height());
+}
+
/*
Mac window coordinates are in the first quadrant: 0, 0 is at the lower-left
corner of the primary screen. This function converts the given rect to an
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
index 79b1c0856f..f119699004 100644
--- a/src/plugins/platforms/cocoa/qcocoainputcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
@@ -43,6 +43,7 @@
#include "qcocoainputcontext.h"
#include "qcocoanativeinterface.h"
#include "qcocoaautoreleasepool.h"
+#include "qcocoawindow.h"
#include <QtCore/QRect>
#include <QtGui/QGuiApplication>
@@ -98,13 +99,12 @@ void QCocoaInputContext::reset()
{
QPlatformInputContext::reset();
- if (!mWindow) return;
+ if (!mWindow)
+ return;
- QCocoaNativeInterface *nativeInterface = qobject_cast<QCocoaNativeInterface *>(QGuiApplication::platformNativeInterface());
- if (!nativeInterface) return;
-
- QNSView *view = static_cast<QNSView *>(nativeInterface->nativeResourceForWindow("nsview", mWindow));
- if (!view) return;
+ QNSView *view = static_cast<QCocoaWindow *>(mWindow->handle())->qtView();
+ if (!view)
+ return;
QCocoaAutoReleasePool pool;
NSInputManager *currentIManager = [NSInputManager currentInputManager];
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 111329aaee..b1b73e5f08 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -46,6 +46,10 @@
#include "qcocoaautoreleasepool.h"
#include "qcocoacursor.h"
+#include "qcocoawindow.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoainputcontext.h"
+#include "qcocoaaccessibility.h"
#include "qcocoaclipboard.h"
#include "qcocoadrag.h"
#include "qcocoaservices.h"
@@ -53,6 +57,7 @@
#include <QtCore/QScopedPointer>
#include <qpa/qplatformintegration.h>
+#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
QT_BEGIN_NAMESPACE
@@ -103,23 +108,25 @@ public:
QCocoaIntegration();
~QCocoaIntegration();
+ static QCocoaIntegration *instance();
+
bool hasCapability(QPlatformIntegration::Capability cap) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const;
QAbstractEventDispatcher *createEventDispatcher() const;
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformNativeInterface *nativeInterface() const;
- QPlatformInputContext *inputContext() const;
- QPlatformAccessibility *accessibility() const;
- QPlatformClipboard *clipboard() const;
- QPlatformDrag *drag() const;
+ QCoreTextFontDatabase *fontDatabase() const;
+ QCocoaNativeInterface *nativeInterface() const;
+ QCocoaInputContext *inputContext() const;
+ QCocoaAccessibility *accessibility() const;
+ QCocoaClipboard *clipboard() const;
+ QCocoaDrag *drag() const;
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
- QPlatformServices *services() const;
+ QCocoaServices *services() const;
QVariant styleHint(StyleHint hint) const;
QList<int> possibleKeys(const QKeyEvent *event) const;
@@ -127,21 +134,27 @@ public:
void updateScreens();
QCocoaScreen *screenAtIndex(int index);
+ void setToolbar(QWindow *window, NSToolbar *toolbar);
+ NSToolbar *toolbar(QWindow *window) const;
+ void clearToolbars();
private:
+ static QCocoaIntegration *mInstance;
- QScopedPointer<QPlatformFontDatabase> mFontDb;
+ QScopedPointer<QCoreTextFontDatabase> mFontDb;
- QScopedPointer<QPlatformInputContext> mInputContext;
+ QScopedPointer<QCocoaInputContext> mInputContext;
#ifndef QT_NO_ACCESSIBILITY
- QScopedPointer<QPlatformAccessibility> mAccessibility;
+ QScopedPointer<QCocoaAccessibility> mAccessibility;
#endif
QScopedPointer<QPlatformTheme> mPlatformTheme;
QList<QCocoaScreen *> mScreens;
QCocoaClipboard *mCocoaClipboard;
QScopedPointer<QCocoaDrag> mCocoaDrag;
- QScopedPointer<QPlatformNativeInterface> mNativeInterface;
+ QScopedPointer<QCocoaNativeInterface> mNativeInterface;
QScopedPointer<QCocoaServices> mServices;
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
+
+ QHash<QWindow *, NSToolbar *> mToolbars;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 5f01274d98..0c1ddf9ad8 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -58,7 +58,6 @@
#include <qpa/qplatformaccessibility.h>
#include <QtCore/qcoreapplication.h>
-#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <IOKit/graphics/IOGraphicsLib.h>
static void initResources()
@@ -214,6 +213,8 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
return windowPixmap;
}
+QCocoaIntegration *QCocoaIntegration::mInstance = 0;
+
QCocoaIntegration::QCocoaIntegration()
: mFontDb(new QCoreTextFontDatabase())
, mInputContext(new QCocoaInputContext)
@@ -226,6 +227,10 @@ QCocoaIntegration::QCocoaIntegration()
, mServices(new QCocoaServices)
, mKeyboardMapper(new QCocoaKeyMapper)
{
+ if (mInstance != 0)
+ qWarning("Creating multiple Cocoa platform integrations is not supported");
+ mInstance = this;
+
initResources();
QCocoaAutoReleasePool pool;
@@ -273,6 +278,8 @@ QCocoaIntegration::QCocoaIntegration()
QCocoaIntegration::~QCocoaIntegration()
{
+ mInstance = 0;
+
qt_resetNSApplicationSendEvent();
QCocoaAutoReleasePool pool;
@@ -294,6 +301,13 @@ QCocoaIntegration::~QCocoaIntegration()
while (!mScreens.isEmpty()) {
delete mScreens.takeLast();
}
+
+ clearToolbars();
+}
+
+QCocoaIntegration *QCocoaIntegration::instance()
+{
+ return mInstance;
}
/*!
@@ -388,22 +402,22 @@ QAbstractEventDispatcher *QCocoaIntegration::createEventDispatcher() const
return new QCocoaEventDispatcher;
}
-QPlatformFontDatabase *QCocoaIntegration::fontDatabase() const
+QCoreTextFontDatabase *QCocoaIntegration::fontDatabase() const
{
return mFontDb.data();
}
-QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
+QCocoaNativeInterface *QCocoaIntegration::nativeInterface() const
{
return mNativeInterface.data();
}
-QPlatformInputContext *QCocoaIntegration::inputContext() const
+QCocoaInputContext *QCocoaIntegration::inputContext() const
{
return mInputContext.data();
}
-QPlatformAccessibility *QCocoaIntegration::accessibility() const
+QCocoaAccessibility *QCocoaIntegration::accessibility() const
{
#ifndef QT_NO_ACCESSIBILITY
return mAccessibility.data();
@@ -412,12 +426,12 @@ QPlatformAccessibility *QCocoaIntegration::accessibility() const
#endif
}
-QPlatformClipboard *QCocoaIntegration::clipboard() const
+QCocoaClipboard *QCocoaIntegration::clipboard() const
{
return mCocoaClipboard;
}
-QPlatformDrag *QCocoaIntegration::drag() const
+QCocoaDrag *QCocoaIntegration::drag() const
{
return mCocoaDrag.data();
}
@@ -434,7 +448,7 @@ QPlatformTheme *QCocoaIntegration::createPlatformTheme(const QString &name) cons
return QPlatformIntegration::createPlatformTheme(name);
}
-QPlatformServices *QCocoaIntegration::services() const
+QCocoaServices *QCocoaIntegration::services() const
{
return mServices.data();
}
@@ -454,4 +468,27 @@ QList<int> QCocoaIntegration::possibleKeys(const QKeyEvent *event) const
return mKeyboardMapper->possibleKeys(event);
}
+void QCocoaIntegration::setToolbar(QWindow *window, NSToolbar *toolbar)
+{
+ if (NSToolbar *prevToolbar = mToolbars.value(window))
+ [prevToolbar release];
+
+ [toolbar retain];
+ mToolbars.insert(window, toolbar);
+}
+
+NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const
+{
+ return mToolbars.value(window);
+}
+
+void QCocoaIntegration::clearToolbars()
+{
+ QHash<QWindow *, NSToolbar *>::const_iterator it = mToolbars.constBegin();
+ while (it != mToolbars.constEnd()) {
+ [it.value() release];
+ }
+ mToolbars.clear();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 5c59c73847..bf7e85619a 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -135,8 +135,14 @@ private:
// Request a unified title and toolbar look for the window.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
+
+ // Sets a NSToolbar instance for the given QWindow. The
+ // toolbar will be attached to the native NSWindow when
+ // that is created;
+ static void setNSToolbar(QWindow *window, void *nsToolbar);
};
+QT_END_NAMESPACE
+
#endif // QCOCOANATIVEINTERFACE_H
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index eb520b97c9..85ce96a8b6 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -47,6 +47,7 @@
#include "qmacmime.h"
#include "qcocoahelpers.h"
#include "qcocoaapplication.h"
+#include "qcocoaintegration.h"
#include <qbytearray.h>
#include <qwindow.h>
@@ -125,6 +126,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
if (resource.toLower() == "setcontentborderthickness")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
+ if (resource.toLower() == "setnstoolbar")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
return 0;
}
@@ -285,4 +288,16 @@ void QCocoaNativeInterface::setContentBorderThickness(QWindow *window, int topTh
cocoaWindow->setContentBorderThickness(topThickness, bottomThickness);
}
+void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
+{
+ if (!window)
+ return;
+
+ QCocoaIntegration::instance()->setToolbar(window, static_cast<NSToolbar *>(nsToolbar));
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->updateNSToolbar();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index e4237c9b3e..d60cdf10d1 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -73,6 +73,7 @@ public:
QPlatformTheme::IconOptions options = 0) const;
QVariant themeHint(ThemeHint hint) const;
+ QString standardButtonText(int button) const Q_DECL_OVERRIDE;
static const char *name;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index d863861288..dce1671800 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -42,6 +42,7 @@
#import <Cocoa/Cocoa.h>
#include "qcocoatheme.h"
+#include "messages.h"
#include <QtCore/QVariant>
@@ -278,7 +279,7 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
case QPlatformTheme::StyleNames:
return QStringList(QStringLiteral("macintosh"));
case QPlatformTheme::DialogButtonBoxLayout:
- return QVariant(1); // QDialogButtonBox::MacLayout
+ return QVariant(QPlatformDialogHelper::MacLayout);
case KeyboardScheme:
return QVariant(int(MacKeyboardScheme));
case TabAllWidgets:
@@ -300,6 +301,11 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const
return QPlatformTheme::themeHint(hint);
}
+QString QCocoaTheme::standardButtonText(int button) const
+{
+ return button == QPlatformDialogHelper::Discard ? msgDialogButtonDiscard() : QPlatformTheme::standardButtonText(button);
+}
+
QPlatformMenuItem *QCocoaTheme::createPlatformMenuItem() const
{
return new QCocoaMenuItem();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 452be90108..748280af6a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -52,19 +52,27 @@
QT_FORWARD_DECLARE_CLASS(QCocoaWindow)
-@interface QNSWindow : NSWindow {
+@interface QNSWindow : NSWindow
+{
@public QCocoaWindow *m_cocoaPlatformWindow;
}
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)windowStyle
+ qPlatformWindow:(QCocoaWindow *)qpw;
- (void)clearPlatformWindow;
-- (BOOL)canBecomeKeyWindow;
@end
-@interface QNSPanel : NSPanel {
+@interface QNSPanel : NSPanel
+{
@public QCocoaWindow *m_cocoaPlatformWindow;
}
+
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)windowStyle
+ qPlatformWindow:(QCocoaWindow *)qpw;
+
- (void)clearPlatformWindow;
-- (BOOL)canBecomeKeyWindow;
@end
@class QNSWindowDelegate;
@@ -100,6 +108,10 @@ public:
void setGeometry(const QRect &rect);
void setCocoaGeometry(const QRect &rect);
+ void clipChildWindows();
+ void clipWindow(const NSRect &clipRect);
+ void show(bool becauseOfAncestor = false);
+ void hide(bool becauseOfAncestor = false);
void setVisible(bool visible);
void setWindowFlags(Qt::WindowFlags flags);
void setWindowState(Qt::WindowState state);
@@ -127,6 +139,8 @@ public:
NSView *contentView() const;
void setContentView(NSView *contentView);
+ QNSView *qtView() const;
+ NSWindow *nativeWindow() const;
void setEmbeddedInForeignView(bool subwindow);
@@ -159,6 +173,7 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
void applyContentBorderThickness(NSWindow *window);
+ void updateNSToolbar();
qreal devicePixelRatio() const;
bool isWindowExposable();
@@ -167,16 +182,18 @@ public:
void updateExposedGeometry();
QWindow *childWindowAt(QPoint windowPoint);
protected:
- // NSWindow handling. The QCocoaWindow/QNSView can either be displayed
- // in an existing NSWindow or in one created by Qt.
void recreateWindow(const QPlatformWindow *parentWindow);
NSWindow *createNSWindow();
void setNSWindow(NSWindow *window);
void clearNSWindow(NSWindow *window);
+ bool shouldUseNSPanel();
+
QRect windowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
void syncWindowState(Qt::WindowState newState);
+ void reinsertChildWindow(QCocoaWindow *child);
+ void removeChildWindow(QCocoaWindow *child);
// private:
public: // for QNSView
@@ -186,11 +203,16 @@ public: // for QNSView
NSView *m_contentView;
QNSView *m_qtView;
NSWindow *m_nsWindow;
+ QCocoaWindow *m_forwardWindow;
// TODO merge to one variable if possible
bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy
bool m_contentViewIsToBeEmbedded; // true if the m_contentView is intended to be embedded in a "foreign" NSView hiearchy
+ QCocoaWindow *m_parentCocoaWindow;
+ bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow.
+ QList<QCocoaWindow *> m_childWindows;
+
QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags;
Qt::WindowState m_synchedWindowState;
@@ -211,6 +233,8 @@ public: // for QNSView
QRect m_exposedGeometry;
int m_registerTouchCount;
bool m_resizableTransientParent;
+ bool m_hiddenByClipping;
+ bool m_hiddenByAncestor;
static const int NoAlertRequest;
NSInteger m_alertRequest;
@@ -219,6 +243,11 @@ public: // for QNSView
bool m_drawContentBorderGradient;
int m_topContentBorderThickness;
int m_bottomContentBorderThickness;
+
+ // used by showFullScreen in fake mode
+ QRect m_normalGeometry;
+ Qt::WindowFlags m_oldWindowFlags;
+ NSApplicationPresentationOptions m_presentationOptions;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 211ecd60ab..d972782f31 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -45,6 +45,7 @@
#include "qcocoaeventdispatcher.h"
#include "qcocoaglcontext.h"
#include "qcocoahelpers.h"
+#include "qcocoanativeinterface.h"
#include "qnsview.h"
#include <QtCore/qfileinfo.h>
#include <QtCore/private/qcore_mac_p.h>
@@ -104,8 +105,29 @@ static bool isMouseEvent(NSEvent *ev)
@implementation QNSWindow
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)windowStyle
+ qPlatformWindow:(QCocoaWindow *)qpw
+{
+ self = [super initWithContentRect:contentRect
+ styleMask:windowStyle
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ // set up before the window is shown and needs a proper window)
+
+ if (self) {
+ m_cocoaPlatformWindow = qpw;
+ }
+ return self;
+}
+
- (BOOL)canBecomeKeyWindow
{
+ // Prevent child NSWindows from becoming the key window in
+ // order keep the active apperance of the top-level window.
+ if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild)
+ return NO;
+
// The default implementation returns NO for title-bar less windows,
// override and return yes here to make sure popup windows such as
// the combobox popup can become the key window.
@@ -118,7 +140,8 @@ static bool isMouseEvent(NSEvent *ev)
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
- if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->window()->transientParent())
+ if (!m_cocoaPlatformWindow || m_cocoaPlatformWindow->m_isNSWindowChild
+ || m_cocoaPlatformWindow->window()->transientParent())
canBecomeMain = NO;
return canBecomeMain;
@@ -126,6 +149,24 @@ static bool isMouseEvent(NSEvent *ev)
- (void) sendEvent: (NSEvent*) theEvent
{
+ if (m_cocoaPlatformWindow && m_cocoaPlatformWindow->m_forwardWindow) {
+ if (theEvent.type == NSLeftMouseUp || theEvent.type == NSLeftMouseDragged) {
+ QNSView *forwardView = m_cocoaPlatformWindow->m_qtView;
+ if (theEvent.type == NSLeftMouseUp) {
+ [forwardView mouseUp:theEvent];
+ m_cocoaPlatformWindow->m_forwardWindow = 0;
+ } else {
+ [forwardView mouseDragged:theEvent];
+ }
+
+ return;
+ }
+
+ if (theEvent.type == NSLeftMouseDown) {
+ m_cocoaPlatformWindow->m_forwardWindow = 0;
+ }
+ }
+
[super sendEvent: theEvent];
if (!m_cocoaPlatformWindow)
@@ -153,6 +194,22 @@ static bool isMouseEvent(NSEvent *ev)
@implementation QNSPanel
+- (id)initWithContentRect:(NSRect)contentRect
+ styleMask:(NSUInteger)windowStyle
+ qPlatformWindow:(QCocoaWindow *)qpw
+{
+ self = [super initWithContentRect:contentRect
+ styleMask:windowStyle
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ // set up before the window is shown and needs a proper window)
+
+ if (self) {
+ m_cocoaPlatformWindow = qpw;
+ }
+ return self;
+}
+
- (BOOL)canBecomeKeyWindow
{
if (!m_cocoaPlatformWindow)
@@ -160,7 +217,8 @@ static bool isMouseEvent(NSEvent *ev)
// Only tool or dialog windows should become key:
if (m_cocoaPlatformWindow
- && (m_cocoaPlatformWindow->window()->type() == Qt::Tool || m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
+ && (m_cocoaPlatformWindow->window()->type() == Qt::Tool ||
+ m_cocoaPlatformWindow->window()->type() == Qt::Dialog))
return YES;
return NO;
}
@@ -199,8 +257,11 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_contentView(nil)
, m_qtView(nil)
, m_nsWindow(0)
+ , m_forwardWindow(0)
, m_contentViewIsEmbedded(false)
, m_contentViewIsToBeEmbedded(false)
+ , m_parentCocoaWindow(0)
+ , m_isNSWindowChild(false)
, m_nsWindowDelegate(0)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
@@ -215,11 +276,14 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_isExposed(false)
, m_registerTouchCount(0)
, m_resizableTransientParent(false)
+ , m_hiddenByClipping(false)
+ , m_hiddenByAncestor(false)
, m_alertRequest(NoAlertRequest)
, monitor(nil)
, m_drawContentBorderGradient(false)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
+ , m_normalGeometry(QRect(0,0,-1,-1))
{
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
qDebug() << "QCocoaWindow::QCocoaWindow" << this;
@@ -239,9 +303,15 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
// problem, except if the appilcation wants to have a "custom" viewport.
// (like the hellogl example)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
- && tlw->surfaceType() == QSurface::OpenGLSurface)
- [m_contentView setWantsBestResolutionOpenGLSurface:YES];
+ && tlw->surfaceType() == QSurface::OpenGLSurface) {
+ BOOL enable = qt_mac_resolveOption(YES, tlw, "_q_mac_wantsBestResolutionOpenGLSurface",
+ "QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
+ [m_contentView setWantsBestResolutionOpenGLSurface:enable];
+ }
#endif
+ BOOL enable = qt_mac_resolveOption(NO, tlw, "_q_mac_wantsLayer",
+ "QT_MAC_WANTS_LAYER");
+ [m_contentView setWantsLayer:enable];
}
setGeometry(tlw->geometry());
recreateWindow(parent());
@@ -259,8 +329,21 @@ QCocoaWindow::~QCocoaWindow()
QCocoaAutoReleasePool pool;
clearNSWindow(m_nsWindow);
- if (parent())
+ if (m_isNSWindowChild) {
+ if (m_parentCocoaWindow)
+ m_parentCocoaWindow->removeChildWindow(this);
+ } else if (parent()) {
[m_contentView removeFromSuperview];
+ } else if (m_qtView) {
+ [[NSNotificationCenter defaultCenter] removeObserver:m_qtView
+ name:nil object:m_nsWindow];
+ }
+
+ foreach (QCocoaWindow *child, m_childWindows) {
+ [m_nsWindow removeChildWindow:child->m_nsWindow];
+ child->m_parentCocoaWindow = 0;
+ }
+
[m_contentView release];
[m_nsWindow release];
[m_nsWindowDelegate release];
@@ -272,8 +355,16 @@ QSurfaceFormat QCocoaWindow::format() const
return window()->requestedFormat();
}
-void QCocoaWindow::setGeometry(const QRect &rect)
+void QCocoaWindow::setGeometry(const QRect &rectIn)
{
+ QRect rect = rectIn;
+ // This means it is a call from QWindow::setFramePosition() and
+ // the coordinates include the frame (size is still the contents rectangle).
+ if (qt_window_private(const_cast<QWindow *>(window()))->positionPolicy
+ == QWindowPrivate::WindowFrameInclusive) {
+ const QMargins margins = frameMargins();
+ rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top()));
+ }
if (geometry() == rect)
return;
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
@@ -291,7 +382,16 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
return;
}
- if (m_nsWindow) {
+ if (m_isNSWindowChild) {
+ QPlatformWindow::setGeometry(rect);
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSRect parentWindowFrame = [parentNSWindow contentRectForFrameRect:parentNSWindow.frame];
+ clipWindow(parentWindowFrame);
+
+ // call this here: updateGeometry in qnsview.mm is a no-op for this case
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ QWindowSystemInterface::handleExposeEvent(window(), rect);
+ } else if (m_nsWindow) {
NSRect bounds = qt_mac_flipRect(rect, window());
[m_nsWindow setFrame:[m_nsWindow frameRectForContentRect:bounds] display:YES animate:NO];
} else {
@@ -301,8 +401,99 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
}
+void QCocoaWindow::clipChildWindows()
+{
+ foreach (QCocoaWindow *childWindow, m_childWindows) {
+ childWindow->clipWindow(m_nsWindow.frame);
+ }
+}
+
+void QCocoaWindow::clipWindow(const NSRect &clipRect)
+{
+ if (!m_isNSWindowChild)
+ return;
+
+ NSRect clippedWindowRect = NSZeroRect;
+ if (!NSIsEmptyRect(clipRect)) {
+ NSRect windowFrame = qt_mac_flipRect(QRect(window()->mapToGlobal(QPoint(0, 0)), geometry().size()), window());
+ clippedWindowRect = NSIntersectionRect(windowFrame, clipRect);
+ // Clipping top/left offsets the content. Move it back.
+ NSPoint contentViewOffset = NSMakePoint(qMax(CGFloat(0), NSMinX(clippedWindowRect) - NSMinX(windowFrame)),
+ qMax(CGFloat(0), NSMaxY(windowFrame) - NSMaxY(clippedWindowRect)));
+ [m_contentView setBoundsOrigin:contentViewOffset];
+ }
+
+ if (NSIsEmptyRect(clippedWindowRect)) {
+ if (!m_hiddenByClipping) {
+ // We dont call hide() here as we will recurse further down
+ [m_nsWindow orderOut:nil];
+ m_hiddenByClipping = true;
+ }
+ } else {
+ [m_nsWindow setFrame:clippedWindowRect display:YES animate:NO];
+ if (m_hiddenByClipping) {
+ m_hiddenByClipping = false;
+ if (!m_hiddenByAncestor) {
+ [m_nsWindow orderFront:nil];
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ }
+ }
+ }
+
+ // recurse
+ foreach (QCocoaWindow *childWindow, m_childWindows) {
+ childWindow->clipWindow(clippedWindowRect);
+ }
+}
+
+void QCocoaWindow::hide(bool becauseOfAncestor)
+{
+ bool visible = [m_nsWindow isVisible];
+
+ if (!m_hiddenByAncestor && !visible) // Already explicitly hidden
+ return;
+ if (m_hiddenByAncestor && becauseOfAncestor) // Trying to hide some child again
+ return;
+
+ m_hiddenByAncestor = becauseOfAncestor;
+
+ if (!visible) // Could have been clipped before
+ return;
+
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->hide(true);
+
+ [m_nsWindow orderOut:nil];
+}
+
+void QCocoaWindow::show(bool becauseOfAncestor)
+{
+ if ([m_nsWindow isVisible])
+ return;
+
+ if (m_parentCocoaWindow && ![m_parentCocoaWindow->m_nsWindow isVisible]) {
+ m_hiddenByAncestor = true; // Parent still hidden, don't show now
+ } else if ((becauseOfAncestor == m_hiddenByAncestor) // Was NEITHER explicitly hidden
+ && !m_hiddenByClipping) { // ... NOR clipped
+ if (m_isNSWindowChild) {
+ m_hiddenByAncestor = false;
+ setCocoaGeometry(window()->geometry());
+ }
+ if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
+ [m_nsWindow orderFront:nil];
+ if (m_isNSWindowChild)
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->show(true);
+ }
+ }
+}
+
void QCocoaWindow::setVisible(bool visible)
{
+ if (m_isNSWindowChild && m_hiddenByClipping)
+ return;
+
QCocoaAutoReleasePool pool;
QCocoaWindow *parentCocoaWindow = 0;
if (window()->transientParent())
@@ -367,8 +558,10 @@ void QCocoaWindow::setVisible(bool visible)
m_hasModalSession = true;
} else if ([m_nsWindow canBecomeKeyWindow]) {
[m_nsWindow makeKeyAndOrderFront:nil];
+ foreach (QCocoaWindow *childWindow, m_childWindows)
+ childWindow->show(true);
} else {
- [m_nsWindow orderFront: nil];
+ show();
}
// We want the events to properly reach the popup, dialog, and tool
@@ -392,28 +585,30 @@ void QCocoaWindow::setVisible(bool visible)
// qDebug() << "close" << this;
if (m_glContext)
m_glContext->windowWasHidden();
+ QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
+ QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = 0;
+ if (cocoaEventDispatcher)
+ cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
if (m_nsWindow) {
if (m_hasModalSession) {
- QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
- Q_ASSERT(cocoaEventDispatcher != 0);
- QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = static_cast<QCocoaEventDispatcherPrivate *>(QObjectPrivate::get(cocoaEventDispatcher));
- cocoaEventDispatcherPrivate->endModalSession(window());
+ if (cocoaEventDispatcherPrivate)
+ cocoaEventDispatcherPrivate->endModalSession(window());
m_hasModalSession = false;
-
- [m_nsWindow orderOut:m_nsWindow];
- if (m_nsWindow == [NSApp keyWindow] && !cocoaEventDispatcherPrivate->currentModalSession()) {
- // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher
- // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that
- // the current NSWindow is still key after being ordered out. Then, after checking we
- // don't have any other modal session left, it's safe to make the main window key again.
- NSWindow *mainWindow = [NSApp mainWindow];
- if (mainWindow && [mainWindow canBecomeKeyWindow])
- [mainWindow makeKeyWindow];
- }
} else {
if ([m_nsWindow isSheet])
[NSApp endSheet:m_nsWindow];
- [m_nsWindow orderOut:m_nsWindow];
+ }
+
+ hide();
+ if (m_nsWindow == [NSApp keyWindow]
+ && !(cocoaEventDispatcherPrivate && cocoaEventDispatcherPrivate->currentModalSession())) {
+ // Probably because we call runModalSession: outside [NSApp run] in QCocoaEventDispatcher
+ // (e.g., when show()-ing a modal QDialog instead of exec()-ing it), it can happen that
+ // the current NSWindow is still key after being ordered out. Then, after checking we
+ // don't have any other modal session left, it's safe to make the main window key again.
+ NSWindow *mainWindow = [NSApp mainWindow];
+ if (mainWindow && [mainWindow canBecomeKeyWindow])
+ [mainWindow makeKeyWindow];
}
} else {
[m_contentView setHidden:YES];
@@ -520,7 +715,7 @@ void QCocoaWindow::setWindowShadow(Qt::WindowFlags flags)
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_nsWindow) {
+ if (m_nsWindow && !m_isNSWindowChild) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
[m_nsWindow setStyleMask:styleMask];
@@ -618,16 +813,55 @@ void QCocoaWindow::raise()
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!m_nsWindow)
return;
- if ([m_nsWindow isVisible])
- [m_nsWindow orderFront: m_nsWindow];
+ if (m_isNSWindowChild) {
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ siblings.removeOne(this);
+ siblings.append(this);
+ if (m_hiddenByClipping)
+ return;
+ }
+ if ([m_nsWindow isVisible]) {
+ if (m_isNSWindowChild) {
+ // -[NSWindow orderFront:] doesn't work with attached windows.
+ // The only solution is to remove and add the child window.
+ // This will place it on top of all the other NSWindows.
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ [parentNSWindow removeChildWindow:m_nsWindow];
+ [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ } else {
+ [m_nsWindow orderFront: m_nsWindow];
+ }
+ }
}
void QCocoaWindow::lower()
{
if (!m_nsWindow)
return;
- if ([m_nsWindow isVisible])
- [m_nsWindow orderBack: m_nsWindow];
+ if (m_isNSWindowChild) {
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ siblings.removeOne(this);
+ siblings.prepend(this);
+ if (m_hiddenByClipping)
+ return;
+ }
+ if ([m_nsWindow isVisible]) {
+ if (m_isNSWindowChild) {
+ // -[NSWindow orderBack:] doesn't work with attached windows.
+ // The only solution is to remove and add all the child windows except this one.
+ // This will keep the current window at the bottom while adding the others on top of it,
+ // hopefully in the same order (this is not documented anywhere in the Cocoa documentation).
+ NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSArray *children = [parentNSWindow.childWindows copy];
+ for (NSWindow *child in children)
+ if (m_nsWindow != child) {
+ [parentNSWindow removeChildWindow:child];
+ [parentNSWindow addChildWindow:child ordered:NSWindowAbove];
+ }
+ } else {
+ [m_nsWindow orderBack: m_nsWindow];
+ }
+ }
}
bool QCocoaWindow::isExposed() const
@@ -755,6 +989,16 @@ void QCocoaWindow::setContentView(NSView *contentView)
recreateWindow(parent()); // Adds the content view to parent NSView
}
+QNSView *QCocoaWindow::qtView() const
+{
+ return m_qtView;
+}
+
+NSWindow *QCocoaWindow::nativeWindow() const
+{
+ return m_nsWindow;
+}
+
void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
{
m_contentViewIsToBeEmbedded = embedded;
@@ -773,6 +1017,9 @@ void QCocoaWindow::windowWillMove()
void QCocoaWindow::windowDidMove()
{
+ if (m_isNSWindowChild)
+ return;
+
[m_qtView updateGeometry];
}
@@ -781,6 +1028,10 @@ void QCocoaWindow::windowDidResize()
if (!m_nsWindow)
return;
+ if (m_isNSWindowChild)
+ return;
+
+ clipChildWindows();
[m_qtView updateGeometry];
}
@@ -820,8 +1071,22 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
{
+ bool wasNSWindowChild = m_isNSWindowChild;
+ // TODO Set value for m_isNSWindowChild here
+ bool needsNSWindow = m_isNSWindowChild || !parentWindow;
+
+ QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
+ m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
+
+ bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
+
+ // No child QNSWindow should notify its QNSView
+ if (m_nsWindow && m_qtView && m_parentCocoaWindow && !oldParentCocoaWindow)
+ [[NSNotificationCenter defaultCenter] removeObserver:m_qtView
+ name:nil object:m_nsWindow];
+
// Remove current window (if any)
- if (m_nsWindow) {
+ if ((m_nsWindow && !needsNSWindow) || (usesNSPanel != shouldUseNSPanel())) {
clearNSWindow(m_nsWindow);
[m_nsWindow close];
[m_nsWindow release];
@@ -830,22 +1095,63 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindowDelegate = 0;
}
+ if (needsNSWindow) {
+ bool noPreviousWindow = m_nsWindow == 0;
+ if (noPreviousWindow)
+ m_nsWindow = createNSWindow();
+
+ // Only non-child QNSWindows should notify their QNSViews
+ // (but don't register more than once).
+ if (m_qtView && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
+ [[NSNotificationCenter defaultCenter] addObserver:m_qtView
+ selector:@selector(windowNotification:)
+ name:nil // Get all notifications
+ object:m_nsWindow];
+
+ if (oldParentCocoaWindow) {
+ if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
+ oldParentCocoaWindow->removeChildWindow(this);
+ m_forwardWindow = oldParentCocoaWindow;
+ }
+
+ setNSWindow(m_nsWindow);
+ }
+
if (m_contentViewIsToBeEmbedded) {
// An embedded window doesn't have its own NSWindow.
} else if (!parentWindow) {
- // Create a new NSWindow if this is a top-level window.
- m_nsWindow = createNSWindow();
- setNSWindow(m_nsWindow);
-
// QPlatformWindow subclasses must sync up with QWindow on creation:
propagateSizeHints();
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
setWindowState(window()->windowState());
+ } else if (m_isNSWindowChild) {
+ m_nsWindow.styleMask = NSBorderlessWindowMask;
+ m_nsWindow.hasShadow = NO;
+ m_nsWindow.level = NSNormalWindowLevel;
+ NSWindowCollectionBehavior collectionBehavior =
+ NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+ if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
+ collectionBehavior |= NSWindowCollectionBehaviorFullScreenAuxiliary;
+ m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
+ }
+#endif
+ m_nsWindow.collectionBehavior = collectionBehavior;
+ setCocoaGeometry(window()->geometry());
+
+ QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
+ if (siblings.contains(this)) {
+ if (!m_hiddenByClipping)
+ m_parentCocoaWindow->reinsertChildWindow(this);
+ } else {
+ if (!m_hiddenByClipping)
+ [m_parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ siblings.append(this);
+ }
} else {
// Child windows have no NSWindow, link the NSViews instead.
- const QCocoaWindow *parentCococaWindow = static_cast<const QCocoaWindow *>(parentWindow);
- [parentCococaWindow->m_contentView addSubview : m_contentView];
+ [m_parentCocoaWindow->m_contentView addSubview : m_contentView];
QRect rect = window()->geometry();
NSRect frame = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
[m_contentView setFrame:frame];
@@ -855,6 +1161,24 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
const qreal opacity = qt_window_private(window())->opacity;
if (!qFuzzyCompare(opacity, qreal(1.0)))
setOpacity(opacity);
+
+ // top-level QWindows may have an attached NSToolBar, call
+ // update function which will attach to the NSWindow.
+ if (!parentWindow)
+ updateNSToolbar();
+}
+
+void QCocoaWindow::reinsertChildWindow(QCocoaWindow *child)
+{
+ int childIndex = m_childWindows.indexOf(child);
+ Q_ASSERT(childIndex != -1);
+
+ for (int i = childIndex; i < m_childWindows.size(); i++) {
+ NSWindow *nsChild = m_childWindows[i]->m_nsWindow;
+ if (i != childIndex)
+ [m_nsWindow removeChildWindow:nsChild];
+ [m_nsWindow addChildWindow:nsChild ordered:NSWindowAbove];
+ }
}
void QCocoaWindow::requestActivateWindow()
@@ -864,6 +1188,14 @@ void QCocoaWindow::requestActivateWindow()
[ window makeKeyWindow ];
}
+bool QCocoaWindow::shouldUseNSPanel()
+{
+ Qt::WindowType type = window()->type();
+
+ return !m_isNSWindowChild &&
+ ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
+}
+
NSWindow * QCocoaWindow::createNSWindow()
{
QCocoaAutoReleasePool pool;
@@ -874,18 +1206,21 @@ NSWindow * QCocoaWindow::createNSWindow()
Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
- NSUInteger styleMask = windowStyleMask(flags);
+ NSUInteger styleMask;
+ if (m_isNSWindowChild) {
+ styleMask = NSBorderlessWindowMask;
+ } else {
+ styleMask = windowStyleMask(flags);
+ }
NSWindow *createdWindow = 0;
// Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
// and dialogs
- if ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog) {
+ if (shouldUseNSPanel()) {
QNSPanel *window;
window = [[QNSPanel alloc] initWithContentRect:frame
- styleMask: styleMask
- backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
- // before the window is shown and needs a proper window.).
+ styleMask: styleMask
+ qPlatformWindow:this];
if ((type & Qt::Popup) == Qt::Popup)
[window setHasShadow:YES];
[window setHidesOnDeactivate: NO];
@@ -899,17 +1234,12 @@ NSWindow * QCocoaWindow::createNSWindow()
[window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
}
#endif
- window->m_cocoaPlatformWindow = this;
createdWindow = window;
} else {
QNSWindow *window;
window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask: styleMask
- backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
- // before the window is shown and needs a proper window.).
- window->m_cocoaPlatformWindow = this;
-
+ styleMask: styleMask
+ qPlatformWindow:this];
createdWindow = window;
}
@@ -944,16 +1274,11 @@ void QCocoaWindow::setNSWindow(NSWindow *window)
// QCocoaWindow is deleted by Qt.
[window setReleasedWhenClosed : NO];
-
- if (m_qtView)
- [[NSNotificationCenter defaultCenter] addObserver:m_qtView
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:m_nsWindow];
-
- [m_contentView setPostsFrameChangedNotifications: NO];
- [window setContentView:m_contentView];
- [m_contentView setPostsFrameChangedNotifications: YES];
+ if (window.contentView != m_contentView) {
+ [m_contentView setPostsFrameChangedNotifications: NO];
+ [window setContentView:m_contentView];
+ [m_contentView setPostsFrameChangedNotifications: YES];
+ }
}
void QCocoaWindow::clearNSWindow(NSWindow *window)
@@ -961,14 +1286,22 @@ void QCocoaWindow::clearNSWindow(NSWindow *window)
[window setContentView:nil];
[window setDelegate:nil];
[window clearPlatformWindow];
- [[NSNotificationCenter defaultCenter] removeObserver:m_contentView
- name:nil object:window];
+
+ if (m_isNSWindowChild) {
+ m_parentCocoaWindow->removeChildWindow(this);
+ }
+}
+
+void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
+{
+ m_childWindows.removeOne(child);
+ [m_nsWindow removeChildWindow:child->m_nsWindow];
}
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::windowGeometry() const
{
- if (!m_nsWindow)
+ if (!m_nsWindow || m_isNSWindowChild)
return geometry();
NSRect rect = [m_nsWindow frame];
@@ -1015,13 +1348,35 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) {
+ bool fakeFullScreen = true;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- [m_nsWindow toggleFullScreen : m_nsWindow];
- } else {
- // TODO: "normal" fullscreen
+ if (window()->flags() & Qt::WindowFullscreenButtonHint) {
+ fakeFullScreen = false;
+ [m_nsWindow toggleFullScreen : m_nsWindow];
+ }
}
#endif
+ if (fakeFullScreen) {
+ if (newState & Qt::WindowFullScreen) {
+ QScreen *screen = window()->screen();
+ if (screen) {
+ if (m_normalGeometry.width() < 0) {
+ m_oldWindowFlags = m_windowFlags;
+ window()->setFlags(window()->flags() | Qt::FramelessWindowHint);
+ m_normalGeometry = windowGeometry();
+ setGeometry(screen->geometry());
+ m_presentationOptions = [NSApp presentationOptions];
+ [NSApp setPresentationOptions : m_presentationOptions | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock];
+ }
+ }
+ } else {
+ window()->setFlags(m_oldWindowFlags);
+ setGeometry(m_normalGeometry);
+ m_normalGeometry.setRect(0, 0, -1, -1);
+ [NSApp setPresentationOptions : m_presentationOptions];
+ }
+ }
}
// New state is now the current synched state
@@ -1054,16 +1409,21 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
// for a popup window.) Qt expects the set cursor to "stick":
// it should be accociated with the window until a different
// cursor is set.
-
- // Cocoa has different abstractions. We can set the cursor *now*:
- if (m_windowUnderMouse)
- [cursor set];
- // or we can set the cursor on mouse enter/leave using tracking
- // areas. This is done in QNSView, save the cursor:
if (m_windowCursor != cursor) {
[m_windowCursor release];
m_windowCursor = [cursor retain];
}
+
+ // Use the built in cursor rect API if the QCocoaWindow has a NSWindow.
+ // Othervise, set the cursor if this window is under the mouse. In
+ // this case QNSView::cursorUpdate will set the cursor as the pointer
+ // moves.
+ if (m_nsWindow && m_qtView) {
+ [m_nsWindow invalidateCursorRectsForView : m_qtView];
+ } else {
+ if (m_windowUnderMouse)
+ [cursor set];
+ }
}
void QCocoaWindow::registerTouch(bool enable)
@@ -1106,6 +1466,19 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
}
}
+void QCocoaWindow::updateNSToolbar()
+{
+ if (!m_nsWindow)
+ return;
+
+ NSToolbar *toolbar = QCocoaIntegration::instance()->toolbar(window());
+
+ if ([m_nsWindow toolbar] == toolbar)
+ return;
+
+ [m_nsWindow setToolbar: toolbar];
+ [m_nsWindow setShowsToolbarButton:YES];
+}
qreal QCocoaWindow::devicePixelRatio() const
{
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index ed9aad1654..58c732de98 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -229,7 +229,21 @@ static QTouchDevice *touchDevice = 0;
- (void)updateGeometry
{
QRect geometry;
- if (m_platformWindow->m_nsWindow) {
+
+ if (m_platformWindow->m_isNSWindowChild) {
+ return;
+#if 0
+ //geometry = qt_mac_toQRect([self frame]);
+ qDebug() << "nsview updateGeometry" << m_platformWindow->window();
+ QRect screenRect = qt_mac_toQRect([m_platformWindow->m_nsWindow convertRectToScreen:[self frame]]);
+ qDebug() << "screenRect" << screenRect;
+
+ screenRect.moveTop(qt_mac_flipYCoordinate(screenRect.y() + screenRect.height()));
+ geometry = QRect(m_platformWindow->window()->parent()->mapFromGlobal(screenRect.topLeft()), screenRect.size());
+ qDebug() << "geometry" << geometry;
+#endif
+ //geometry = QRect(screenRect.origin.x, qt_mac_flipYCoordinate(screenRect.origin.y + screenRect.size.height), screenRect.size.width, screenRect.size.height);
+ } else if (m_platformWindow->m_nsWindow) {
// top level window, get window rect and flip y.
NSRect rect = [self frame];
NSRect windowRect = [[self window] frame];
@@ -310,10 +324,9 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->exposeWindow();
} else if (notificationName == NSWindowDidChangeScreenNotification) {
if (m_window) {
- QCocoaIntegration *ci = static_cast<QCocoaIntegration *>(QGuiApplicationPrivate::platformIntegration());
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = ci->screenAtIndex(screenIndex);
+ QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen());
}
}
@@ -551,14 +564,20 @@ static QTouchDevice *touchDevice = 0;
QPointF qtWindowPoint;
QPointF qtScreenPoint;
- [self convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
+ QNSView *targetView = self;
+ if (m_platformWindow && m_platformWindow->m_forwardWindow
+ && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) {
+ targetView = m_platformWindow->m_forwardWindow->m_qtView;
+ }
+
+ [targetView convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
ulong timestamp = [theEvent timestamp] * 1000;
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
nativeDrag->setLastMouseEvent(theEvent, self);
Qt::KeyboardModifiers keyboardModifiers = [QNSView convertKeyModifiers:[theEvent modifierFlags]];
- QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
+ QWindowSystemInterface::handleMouseEvent(targetView->m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons, keyboardModifiers);
}
- (void)handleFrameStrutMouseEvent:(NSEvent *)theEvent
@@ -689,8 +708,18 @@ static QTouchDevice *touchDevice = 0;
-(void)cursorUpdate:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
- if (m_platformWindow->m_windowCursor)
+ // Set the cursor manually if there is no NSWindow.
+ if (!m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
[m_platformWindow->m_windowCursor set];
+ else
+ [super cursorUpdate:theEvent];
+}
+
+-(void)resetCursorRects
+{
+ // Use the cursor rect API if there is a NSWindow
+ if (m_platformWindow->m_nsWindow && m_platformWindow->m_windowCursor)
+ [self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
}
- (void)mouseMoved:(NSEvent *)theEvent
@@ -1619,7 +1648,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
Q_UNUSED(isLocal);
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
return qt_mac_mapDropActions(nativeDrag->currentDrag()->supportedActions());
}
@@ -1650,7 +1679,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
@@ -1678,14 +1707,14 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
if ([sender draggingSource] != nil) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed);
}
if (response.isAccepted()) {
- QCocoaDrag* nativeDrag = static_cast<QCocoaDrag *>(QGuiApplicationPrivate::platformIntegration()->drag());
+ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
nativeDrag->setAcceptedAction(response.acceptedAction());
}
return response.isAccepted();
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index e8f26aa8c4..a438950a55 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -45,7 +45,7 @@
#include "qcocoahelpers.h"
#include "qcocoaaccessibility.h"
#include "qcocoaaccessibilityelement.h"
-#include <qpa/qplatformintegration.h>
+#include "qcocoaintegration.h"
#include <QtGui/qaccessible.h>
#include <QtCore/QDebug>
@@ -63,7 +63,7 @@
- (id)accessibilityAttributeValue:(NSString *)attribute {
// activate accessibility updates
- QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+ QCocoaIntegration::instance()->accessibility()->setActive(true);
if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
if (m_window->accessibleRoot())
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index f363b1772f..3e92a45a62 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -591,20 +591,43 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
return;
switch (key) {
- case PPK_CollateCopies:
+
+ // The following keys are properties or derived values and so cannot be set
+ case PPK_PageRect:
+ break;
+ case PPK_PaperRect:
+ break;
+ case PPK_PaperSources:
+ break;
+ case PPK_SupportsMultipleCopies:
+ break;
+ case PPK_SupportedResolutions:
break;
+
+ // The following keys are settings that are unsupported by the Mac PrintEngine
case PPK_ColorMode:
break;
- case PPK_Creator:
+ case PPK_CustomBase:
break;
- case PPK_DocumentName:
+ case PPK_Duplex:
+ // TODO Add support using PMSetDuplex / PMGetDuplex
+ break;
+ case PPK_FontEmbedding:
break;
case PPK_PageOrder:
+ // TODO Check if can be supported via Cups Options
break;
case PPK_PaperSource:
+ // TODO Check if can be supported via Cups Options
+ break;
+ case PPK_PrinterProgram:
break;
case PPK_SelectionOption:
break;
+ case PPK_WindowsPageSize:
+ break;
+
+ // The following keys are properties and settings that are supported by the Mac PrintEngine
case PPK_Resolution: {
PMPrinter printer;
UInt32 count;
@@ -633,7 +656,15 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
break;
}
-
+ case PPK_CollateCopies:
+ PMSetCollate(d->settings(), value.toBool());
+ break;
+ case PPK_Creator:
+ d->m_creator = value.toString();
+ break;
+ case PPK_DocumentName:
+ PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString()));
+ break;
case PPK_FullPage:
d->fullPage = value.toBool();
break;
@@ -642,18 +673,15 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMSetCopies(d->settings(), value.toInt(), false);
break;
case PPK_Orientation: {
- if (d->state == QPrinter::Active) {
- qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change");
- } else {
- QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
- if (d->hasCustomPaperSize && (d->orient != newOrientation))
- d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
- d->orient = newOrientation;
- PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
- PMSetOrientation(d->format(), o, false);
- PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
- }
- break; }
+ QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
+ if (d->hasCustomPaperSize && (d->orient != newOrientation))
+ d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
+ d->orient = newOrientation;
+ PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
+ PMSetOrientation(d->format(), o, false);
+ PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
+ break;
+ }
case PPK_OutputFileName:
d->outputFilename = value.toString();
break;
@@ -709,9 +737,7 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->hasCustomPageMargins = true;
break;
}
-
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
}
@@ -724,16 +750,63 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
return *d->valueCache.find(key);
switch (key) {
- case PPK_CollateCopies:
- ret = false;
- break;
+
+ // The following keys are settings that are unsupported by the Mac PrintEngine
+ // Return sensible default values to ensure consistent behavior across platforms
case PPK_ColorMode:
ret = QPrinter::Color;
break;
+ case PPK_CustomBase:
+ // Special case, leave null
+ break;
+ case PPK_Duplex:
+ // TODO Add support using PMSetDuplex / PMGetDuplex
+ ret = QPrinter::DuplexNone;
+ break;
+ case PPK_FontEmbedding:
+ ret = false;
+ break;
+ case PPK_PageOrder:
+ // TODO Check if can be supported via Cups Options
+ ret = QPrinter::FirstPageFirst;
+ break;
+ case PPK_PaperSource:
+ // TODO Check if can be supported via Cups Options
+ ret = QPrinter::Auto;
+ break;
+ case PPK_PaperSources: {
+ // TODO Check if can be supported via Cups Options
+ QList<QVariant> out;
+ out << int(QPrinter::Auto);
+ ret = out;
+ break;
+ }
+ case PPK_PrinterProgram:
+ ret = QString();
+ break;
+ case PPK_SelectionOption:
+ ret = QString();
+ break;
+ case PPK_WindowsPageSize:
+ // Special case, leave null
+ break;
+
+ // The following keys are properties and settings that are supported by the Mac PrintEngine
+ case PPK_CollateCopies: {
+ Boolean status;
+ PMGetCollate(d->settings(), &status);
+ ret = bool(status);
+ break;
+ }
case PPK_Creator:
+ ret = d->m_creator;
break;
- case PPK_DocumentName:
+ case PPK_DocumentName: {
+ CFStringRef name;
+ PMPrintSettingsGetJobName(d->settings(), &name);
+ ret = QCFString::toQString(name);
break;
+ }
case PPK_FullPage:
ret = d->fullPage;
break;
@@ -757,10 +830,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_OutputFileName:
ret = d->outputFilename;
break;
- case PPK_PageOrder:
- break;
- case PPK_PaperSource:
- break;
case PPK_PageRect: {
// PageRect is returned in device pixels
QRect r;
@@ -855,8 +924,7 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = margins;
break;
}
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
return ret;
}
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
index 644a07184f..e3a8520811 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -125,6 +125,7 @@ public:
NSPrintInfo *printInfo;
PMResolution resolution;
QString outputFilename;
+ QString m_creator;
bool fullPage;
QPaintEngine *paintEngine;
bool hasCustomPaperSize;
diff --git a/src/plugins/platforms/direct2d/direct2d.json b/src/plugins/platforms/direct2d/direct2d.json
new file mode 100644
index 0000000000..aaea92f0ef
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "direct2d" ]
+}
diff --git a/src/plugins/platforms/direct2d/direct2d.pro b/src/plugins/platforms/direct2d/direct2d.pro
new file mode 100644
index 0000000000..4f986b57d7
--- /dev/null
+++ b/src/plugins/platforms/direct2d/direct2d.pro
@@ -0,0 +1,41 @@
+TARGET = qdirect2d
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWindowsDirect2DIntegrationPlugin
+load(qt_plugin)
+
+QT *= core-private
+QT *= gui-private
+QT *= platformsupport-private
+
+LIBS *= -ld2d1 -ld3d11 -ldwrite
+
+include(../windows/windows.pri)
+
+SOURCES += \
+ qwindowsdirect2dpaintengine.cpp \
+ qwindowsdirect2dpaintdevice.cpp \
+ qwindowsdirect2dplatformpixmap.cpp \
+ qwindowsdirect2dcontext.cpp \
+ qwindowsdirect2dbitmap.cpp \
+ qwindowsdirect2dbackingstore.cpp \
+ qwindowsdirect2dintegration.cpp \
+ qwindowsdirect2dplatformplugin.cpp \
+ qwindowsdirect2ddevicecontext.cpp \
+ qwindowsdirect2dnativeinterface.cpp \
+ qwindowsdirect2dwindow.cpp
+
+HEADERS += \
+ qwindowsdirect2dpaintengine.h \
+ qwindowsdirect2dpaintdevice.h \
+ qwindowsdirect2dplatformpixmap.h \
+ qwindowsdirect2dcontext.h \
+ qwindowsdirect2dhelpers.h \
+ qwindowsdirect2dbitmap.h \
+ qwindowsdirect2dbackingstore.h \
+ qwindowsdirect2dintegration.h \
+ qwindowsdirect2ddevicecontext.h \
+ qwindowsdirect2dnativeinterface.h \
+ qwindowsdirect2dwindow.h
+
+OTHER_FILES += direct2d.json
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
new file mode 100644
index 0000000000..079ad6f127
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+#include "qwindowsdirect2dwindow.h"
+
+#include "qwindowscontext.h"
+
+#include <QtGui/QWindow>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsDirect2DBackingStore
+ \brief Backing store for windows.
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+static inline QWindowsDirect2DPlatformPixmap *platformPixmap(QPixmap *p)
+{
+ return static_cast<QWindowsDirect2DPlatformPixmap *>(p->handle());
+}
+
+QWindowsDirect2DBackingStore::QWindowsDirect2DBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+{
+}
+
+QWindowsDirect2DBackingStore::~QWindowsDirect2DBackingStore()
+{
+}
+
+QPaintDevice *QWindowsDirect2DBackingStore::paintDevice()
+{
+ return m_pixmap.data();
+}
+
+void QWindowsDirect2DBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ QPlatformWindow *pw = window->handle();
+ if (pw && m_pixmap)
+ static_cast<QWindowsDirect2DWindow *>(pw)->flush(platformPixmap(m_pixmap.data())->bitmap(), region, offset);
+}
+
+void QWindowsDirect2DBackingStore::resize(const QSize &size, const QRegion &region)
+{
+ Q_UNUSED(region);
+
+ QScopedPointer<QPixmap> oldPixmap(m_pixmap.take());
+ m_pixmap.reset(new QPixmap(size.width(), size.height()));
+
+ if (oldPixmap) {
+ foreach (const QRect &rect, region.rects())
+ platformPixmap(m_pixmap.data())->copy(oldPixmap->handle(), rect);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
new file mode 100644
index 0000000000..9776d234e8
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DBACKINGSTORE_H
+#define QWINDOWSDIRECT2DBACKINGSTORE_H
+
+#include "qwindowsdirect2dplatformpixmap.h"
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/qpa/qplatformbackingstore.h>
+#include <QtGui/QPixmap>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBackingStore : public QPlatformBackingStore
+{
+ Q_DISABLE_COPY(QWindowsDirect2DBackingStore)
+
+public:
+ QWindowsDirect2DBackingStore(QWindow *window);
+ ~QWindowsDirect2DBackingStore();
+
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &staticContents) Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QPixmap> m_pixmap;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DBACKINGSTORE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
new file mode 100644
index 0000000000..85c56bc73e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <QtGui/QImage>
+#include <QtGui/QColor>
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmapPrivate
+{
+public:
+ QWindowsDirect2DBitmapPrivate(ID2D1DeviceContext *dc = 0, ID2D1Bitmap1 *bm = 0)
+ : bitmap(bm)
+ , deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ {
+ deviceContext->get()->SetTarget(bm);
+ }
+
+ D2D1_BITMAP_PROPERTIES1 bitmapProperties() const
+ {
+ FLOAT dpiX, dpiY;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return D2D1::BitmapProperties1(
+ D2D1_BITMAP_OPTIONS_TARGET,
+ D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,
+ D2D1_ALPHA_MODE_PREMULTIPLIED),
+ dpiX, dpiY);
+
+ }
+
+ bool resize(int width, int height, const void *data = 0, int pitch = 0)
+ {
+ deviceContext->get()->SetTarget(0);
+ bitmap.Reset();
+
+ D2D1_SIZE_U size = {
+ width, height
+ };
+
+ HRESULT hr = deviceContext->get()->CreateBitmap(size, data, pitch,
+ bitmapProperties(),
+ bitmap.ReleaseAndGetAddressOf());
+ if (SUCCEEDED(hr))
+ deviceContext->get()->SetTarget(bitmap.Get());
+ else
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+
+ return SUCCEEDED(hr);
+ }
+
+ QImage toImage(const QRect &rect)
+ {
+ if (!bitmap)
+ return QImage();
+
+ ComPtr<ID2D1Bitmap1> mappingCopy;
+
+ HRESULT hr = S_OK;
+ D2D1_SIZE_U size = bitmap->GetPixelSize();
+
+ D2D1_BITMAP_PROPERTIES1 properties = bitmapProperties();
+ properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ;
+
+ hr = deviceContext->get()->CreateBitmap(size, NULL, NULL,
+ properties, &mappingCopy);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ hr = mappingCopy->CopyFromBitmap(NULL, bitmap.Get(), NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy from bitmap: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ D2D1_MAPPED_RECT mappedRect;
+ hr = mappingCopy->Map(D2D1_MAP_OPTIONS_READ, &mappedRect);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not map: %#x", __FUNCTION__, hr);
+ return QImage();
+ }
+
+ return QImage(static_cast<const uchar *>(mappedRect.bits),
+ size.width, size.height, mappedRect.pitch,
+ QImage::Format_ARGB32_Premultiplied).copy(rect);
+ }
+
+ QScopedPointer<QWindowsDirect2DDeviceContext> deviceContext;
+ ComPtr<ID2D1Bitmap1> bitmap;
+};
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap()
+ : d_ptr(new QWindowsDirect2DBitmapPrivate)
+{
+}
+
+QWindowsDirect2DBitmap::QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DBitmapPrivate(dc, bitmap))
+{
+}
+
+QWindowsDirect2DBitmap::~QWindowsDirect2DBitmap()
+{
+}
+
+bool QWindowsDirect2DBitmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->resize(width, height);
+}
+
+bool QWindowsDirect2DBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ QImage converted = image.convertToFormat(QImage::Format_ARGB32_Premultiplied, flags);
+ return d->resize(converted.width(), converted.height(),
+ converted.constBits(), converted.bytesPerLine());
+}
+
+ID2D1Bitmap1* QWindowsDirect2DBitmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->bitmap.Get();
+}
+
+QWindowsDirect2DDeviceContext *QWindowsDirect2DBitmap::deviceContext() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+ return d->deviceContext.data();
+}
+
+void QWindowsDirect2DBitmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DBitmap);
+
+ d->deviceContext->begin();
+ d->deviceContext->get()->Clear(to_d2d_color_f(color));
+ d->deviceContext->end();
+}
+
+QImage QWindowsDirect2DBitmap::toImage(const QRect &rect)
+{
+ Q_D(QWindowsDirect2DBitmap);
+ return d->toImage(rect);
+}
+
+QSize QWindowsDirect2DBitmap::size() const
+{
+ Q_D(const QWindowsDirect2DBitmap);
+
+ D2D1_SIZE_U size = d->bitmap->GetPixelSize();
+ return QSize(size.width, size.height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
index 0d5daafa2c..d7015ef342 100644
--- a/src/plugins/platforms/eglfs/qeglfscompositor.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h
@@ -39,47 +39,43 @@
**
****************************************************************************/
-#ifndef QEGLFSCOMPOSITOR_H
-#define QEGLFSCOMPOSITOR_H
+#ifndef QWINDOWSDIRECT2DBITMAP_H
+#define QWINDOWSDIRECT2DBITMAP_H
-#include <QtCore/QTimer>
-#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QScopedPointer>
+#include <QtGui/QImage>
-QT_BEGIN_NAMESPACE
+struct ID2D1DeviceContext;
+struct ID2D1Bitmap1;
-class QEglFSScreen;
-class QEglFSWindow;
-class QOpenGLShaderProgram;
+QT_BEGIN_NAMESPACE
-class QEglFSCompositor : public QObject, public QOpenGLFunctions
+class QWindowsDirect2DDeviceContext;
+class QWindowsDirect2DBitmapPrivate;
+class QWindowsDirect2DBitmap
{
- Q_OBJECT
-
+ Q_DECLARE_PRIVATE(QWindowsDirect2DBitmap)
+ Q_DISABLE_COPY(QWindowsDirect2DBitmap)
public:
- void schedule(QEglFSScreen *screen);
+ QWindowsDirect2DBitmap();
+ QWindowsDirect2DBitmap(ID2D1Bitmap1 *bitmap, ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DBitmap();
- static QEglFSCompositor *instance();
- static void destroy();
+ bool resize(int width, int height);
+ bool fromImage(const QImage &image, Qt::ImageConversionFlags flags);
-private slots:
- void renderAll();
+ ID2D1Bitmap1* bitmap() const;
+ QWindowsDirect2DDeviceContext* deviceContext() const;
-private:
- QEglFSCompositor();
- ~QEglFSCompositor();
+ void fill(const QColor &color);
+ QImage toImage(const QRect &rect = QRect());
- void render(QEglFSWindow *window, uint texture, bool raster);
- void ensureProgram();
+ QSize size() const;
- QEglFSScreen *m_screen;
- QTimer m_updateTimer;
- QOpenGLShaderProgram *m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
- int m_isRasterEntry;
- bool m_initialized;
+private:
+ QScopedPointer<QWindowsDirect2DBitmapPrivate> d_ptr;
};
QT_END_NAMESPACE
-#endif // QEGLFSCOMPOSITOR_H
+#endif // QWINDOWSDIRECT2DBITMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
new file mode 100644
index 0000000000..58002fb0dd
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dintegration.h"
+
+#include <d3d11_1.h>
+#include <d2d1_1.h>
+#include <d2d1_1helper.h>
+#include <dxgi1_2.h>
+#include <wrl.h>
+#include <dwrite.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate
+{
+public:
+ bool init()
+ {
+ HRESULT hr;
+
+ D3D_FEATURE_LEVEL level;
+
+ D3D_DRIVER_TYPE typeAttempts[] = {
+ D3D_DRIVER_TYPE_HARDWARE,
+ D3D_DRIVER_TYPE_WARP
+ };
+ const int ntypes = int(sizeof(typeAttempts) / sizeof(typeAttempts[0]));
+
+ for (int i = 0; i < ntypes; i++) {
+ hr = D3D11CreateDevice(NULL,
+ typeAttempts[i],
+ NULL,
+ D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
+ NULL,
+ 0,
+ D3D11_SDK_VERSION,
+ &d3dDevice,
+ &level,
+ &d3dDeviceContext);
+
+ if (SUCCEEDED(hr))
+ break;
+ }
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ ComPtr<IDXGIDevice> dxgiDevice;
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+
+ hr = d3dDevice.As(&dxgiDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: DXGI Device interface query failed on D3D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiDevice->GetParent(IID_PPV_ARGS(&dxgiAdapter));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ D2D1_FACTORY_OPTIONS options = {};
+
+#ifdef QT_D2D_DEBUG_OUTPUT
+ qDebug("Turning on Direct2D debugging messages");
+ options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
+#endif // QT_D2D_DEBUG_OUTPUT
+
+ hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, d2dFactory.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create D2D Device: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
+ static_cast<IUnknown **>(&directWriteFactory));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite factory: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ hr = directWriteFactory->GetGdiInterop(&directWriteGdiInterop);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create DirectWrite GDI Interop: %#x", __FUNCTION__, hr);
+ return false;
+ }
+
+ return true;
+ }
+
+ ComPtr<ID3D11Device> d3dDevice;
+ ComPtr<ID2D1Factory1> d2dFactory;
+ ComPtr<ID2D1Device> d2dDevice;
+ ComPtr<IDXGIFactory2> dxgiFactory;
+ ComPtr<ID3D11DeviceContext> d3dDeviceContext;
+ ComPtr<IDWriteFactory> directWriteFactory;
+ ComPtr<IDWriteGdiInterop> directWriteGdiInterop;
+};
+
+QWindowsDirect2DContext::QWindowsDirect2DContext()
+ : d_ptr(new QWindowsDirect2DContextPrivate)
+{
+}
+
+QWindowsDirect2DContext::~QWindowsDirect2DContext() {}
+
+bool QWindowsDirect2DContext::init()
+{
+ Q_D(QWindowsDirect2DContext);
+ return d->init();
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DContext::instance()
+{
+ return QWindowsDirect2DIntegration::instance()->direct2DContext();
+}
+
+ID3D11Device *QWindowsDirect2DContext::d3dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDevice.Get();
+}
+
+ID2D1Device *QWindowsDirect2DContext::d2dDevice() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dDevice.Get();
+}
+
+ID2D1Factory1 *QWindowsDirect2DContext::d2dFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d2dFactory.Get();
+}
+
+IDXGIFactory2 *QWindowsDirect2DContext::dxgiFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->dxgiFactory.Get();
+}
+
+ID3D11DeviceContext *QWindowsDirect2DContext::d3dDeviceContext() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->d3dDeviceContext.Get();
+}
+
+IDWriteFactory *QWindowsDirect2DContext::dwriteFactory() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteFactory.Get();
+}
+
+IDWriteGdiInterop *QWindowsDirect2DContext::dwriteGdiInterop() const
+{
+ Q_D(const QWindowsDirect2DContext);
+ return d->directWriteGdiInterop.Get();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
new file mode 100644
index 0000000000..0025463dd5
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DCONTEXT_H
+#define QWINDOWSDIRECT2DCONTEXT_H
+
+#include <QtCore/QScopedPointer>
+
+struct ID3D11Device;
+struct ID2D1Device;
+struct ID2D1Factory1;
+struct IDXGIFactory2;
+struct ID3D11DeviceContext;
+struct IDWriteFactory;
+struct IDWriteGdiInterop;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContextPrivate;
+class QWindowsDirect2DContext
+{
+ Q_DECLARE_PRIVATE( QWindowsDirect2DContext )
+
+public:
+ QWindowsDirect2DContext();
+ virtual ~QWindowsDirect2DContext();
+
+ bool init();
+
+ static QWindowsDirect2DContext *instance();
+
+ ID3D11Device *d3dDevice() const;
+ ID2D1Device *d2dDevice() const;
+ ID2D1Factory1 *d2dFactory() const;
+ IDXGIFactory2 *dxgiFactory() const;
+ ID3D11DeviceContext *d3dDeviceContext() const;
+ IDWriteFactory *dwriteFactory() const;
+ IDWriteGdiInterop *dwriteGdiInterop() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DCONTEXT_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
new file mode 100644
index 0000000000..27e94e4be4
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include <wrl.h>
+
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DDeviceContextPrivate {
+public:
+ QWindowsDirect2DDeviceContextPrivate(ID2D1DeviceContext *dc)
+ : deviceContext(dc)
+ , refCount(0)
+ {
+ if (!dc) {
+ HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ &deviceContext);
+ if (FAILED(hr))
+ qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
+ }
+
+ Q_ASSERT(deviceContext);
+ }
+
+ void begin()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount >= 0);
+
+ if (refCount == 0)
+ deviceContext->BeginDraw();
+
+ refCount++;
+ }
+
+ bool end()
+ {
+ Q_ASSERT(deviceContext);
+ Q_ASSERT(refCount > 0);
+
+ bool success = true;
+ refCount--;
+
+ if (refCount == 0) {
+ D2D1_TAG tag1, tag2;
+ HRESULT hr = deviceContext->EndDraw(&tag1, &tag2);
+
+ if (FAILED(hr)) {
+ success = false;
+ qWarning("%s: EndDraw failed: %#x, tag1: %lld, tag2: %lld", __FUNCTION__, hr, tag1, tag2);
+ }
+ }
+
+ return success;
+ }
+
+ ComPtr<ID2D1DeviceContext> deviceContext;
+ int refCount;
+};
+
+QWindowsDirect2DDeviceContext::QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc)
+ : d_ptr(new QWindowsDirect2DDeviceContextPrivate(dc))
+{
+}
+
+QWindowsDirect2DDeviceContext::~QWindowsDirect2DDeviceContext()
+{
+
+}
+
+ID2D1DeviceContext *QWindowsDirect2DDeviceContext::get() const
+{
+ Q_D(const QWindowsDirect2DDeviceContext);
+ Q_ASSERT(d->deviceContext);
+
+ return d->deviceContext.Get();
+}
+
+void QWindowsDirect2DDeviceContext::begin()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ d->begin();
+}
+
+bool QWindowsDirect2DDeviceContext::end()
+{
+ Q_D(QWindowsDirect2DDeviceContext);
+ return d->end();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
new file mode 100644
index 0000000000..4986efb967
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DDEVICECONTEXT_H
+#define QWINDOWSDIRECT2DDEVICECONTEXT_H
+
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Convenience class for handling device contexts. We have to call BeginDraw
+ * before anything can happen, and EndDraw once we're done, for every frame and
+ * pretty much any kind of operation.
+ *
+ * Unfortunately, these calls cannot be interleaved, and there is no way to check
+ * what state a device context is in.
+ *
+ * The end result is that the following throws an error if we don't track it:
+ * QPixmap pmap;
+ * QPainter painter(&pmap);
+ * pmap.clear();
+ *
+ * Here BeginDraw would first be called through the paint device, then when we clear
+ * the pixmap we would have to call it again. There is no way to know what state
+ * the device context is in when performing the clear, and activating the dc is an
+ * error. Bummer.
+ *
+ * Hence we keep a reference count here and only activate/deactivate the device
+ * if the refcount is zero.
+ *
+ * In a nutshell: Do not call BeginDraw/EndDraw yourself on the device pointer, do
+ * so through the begin/end members below.
+ */
+
+class QWindowsDirect2DDeviceContextPrivate;
+class QWindowsDirect2DDeviceContext
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DDeviceContext)
+public:
+ QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc);
+ ~QWindowsDirect2DDeviceContext();
+
+ ID2D1DeviceContext *get() const;
+
+ void begin();
+ bool end();
+
+private:
+ QScopedPointer<QWindowsDirect2DDeviceContextPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DDEVICECONTEXT_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
new file mode 100644
index 0000000000..98248515e6
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dhelpers.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DHELPERS_H
+#define QWINDOWSDIRECT2DHELPERS_H
+
+#include <QtCore/QRectF>
+#include <QtCore/QSizeF>
+#include <QtCore/QPointF>
+#include <QtGui/QColor>
+#include <QtGui/QTransform>
+
+#include <d2d1_1helper.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECL_CONSTEXPR inline D2D1_RECT_U to_d2d_rect_u(const QRect &qrect)
+{
+ return D2D1::RectU(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_RECT_F to_d2d_rect_f(const QRectF &qrect)
+{
+ return D2D1::RectF(qrect.x(), qrect.y(), qrect.x() + qrect.width(), qrect.y() + qrect.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSizeF &qsize)
+{
+ return D2D1::SizeU(qsize.width(), qsize.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_SIZE_U to_d2d_size_u(const QSize &qsize)
+{
+ return D2D1::SizeU(qsize.width(), qsize.height());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_POINT_2F to_d2d_point_2f(const QPointF &qpoint)
+{
+ return D2D1::Point2F(qpoint.x(), qpoint.y());
+}
+
+Q_DECL_CONSTEXPR inline D2D1::ColorF to_d2d_color_f(const QColor &c)
+{
+ return D2D1::ColorF(c.redF(), c.greenF(), c.blueF(), c.alphaF());
+}
+
+Q_DECL_CONSTEXPR inline D2D1_MATRIX_3X2_F to_d2d_matrix_3x2_f(const QTransform &transform)
+{
+ Q_ASSERT(transform.isAffine());
+
+ return D2D1::Matrix3x2F(transform.m11(), transform.m12(),
+ transform.m21(), transform.m22(),
+ transform.m31(), transform.m32());
+}
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DHELPERS_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
new file mode 100644
index 0000000000..1a26d7029e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dintegration.h"
+#include "qwindowsdirect2dbackingstore.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dnativeinterface.h"
+#include "qwindowsdirect2dwindow.h"
+
+#include "qwindowscontext.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/private/qpixmap_raster_p.h>
+#include <QtGui/qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPrivate
+{
+public:
+ QWindowsDirect2DNativeInterface m_nativeInterface;
+ QWindowsDirect2DContext m_d2dContext;
+};
+
+QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
+{
+ QWindowsDirect2DIntegration *integration = new QWindowsDirect2DIntegration(paramList);
+
+ if (!integration->init()) {
+ delete integration;
+ integration = 0;
+ }
+
+ return integration;
+}
+
+QWindowsDirect2DIntegration::~QWindowsDirect2DIntegration()
+{
+
+}
+
+ QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::instance()
+ {
+ return static_cast<QWindowsDirect2DIntegration *>(QWindowsIntegration::instance());
+ }
+
+ QPlatformWindow *QWindowsDirect2DIntegration::createPlatformWindow(QWindow *window) const
+ {
+ QWindowsWindowData data = createWindowData(window);
+ return data.hwnd ? new QWindowsDirect2DWindow(window, data)
+ : Q_NULLPTR;
+ }
+
+ QPlatformNativeInterface *QWindowsDirect2DIntegration::nativeInterface() const
+ {
+ return &d->m_nativeInterface;
+ }
+
+QPlatformPixmap *QWindowsDirect2DIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ switch (type) {
+ case QPlatformPixmap::BitmapType:
+ return new QRasterPlatformPixmap(type);
+ break;
+ default:
+ return new QWindowsDirect2DPlatformPixmap(type);
+ break;
+ }
+}
+
+QPlatformBackingStore *QWindowsDirect2DIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWindowsDirect2DBackingStore(window);
+}
+
+QWindowsDirect2DContext *QWindowsDirect2DIntegration::direct2DContext() const
+{
+ return &d->m_d2dContext;
+}
+
+QWindowsDirect2DIntegration::QWindowsDirect2DIntegration(const QStringList &paramList)
+ : QWindowsIntegration(paramList)
+ , d(new QWindowsDirect2DIntegrationPrivate)
+{
+}
+
+bool QWindowsDirect2DIntegration::init()
+{
+ return d->m_d2dContext.init();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
new file mode 100644
index 0000000000..a46d5c0126
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DINTEGRATION_H
+#define QWINDOWSDIRECT2DINTEGRATION_H
+
+#include "qwindowsintegration.h"
+
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DContext;
+class QWindowsDirect2DIntegrationPrivate;
+
+class QWindowsDirect2DIntegration : public QWindowsIntegration
+{
+public:
+ static QWindowsDirect2DIntegration *create(const QStringList &paramList);
+
+ virtual ~QWindowsDirect2DIntegration();
+
+ static QWindowsDirect2DIntegration *instance();
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+ QWindowsDirect2DContext *direct2DContext() const;
+
+private:
+ explicit QWindowsDirect2DIntegration(const QStringList &paramList);
+ bool init();
+
+ QScopedPointer<QWindowsDirect2DIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DINTEGRATION_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
new file mode 100644
index 0000000000..6792d92de5
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dnativeinterface.h"
+
+#include <QtGui/QBackingStore>
+
+QT_BEGIN_NAMESPACE
+
+void *QWindowsDirect2DNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
+{
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+
+ // getDC is so common we don't want to print an "invalid key" line for it
+ if (resource == "getDC")
+ return 0;
+
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
new file mode 100644
index 0000000000..ee3f7f6eed
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dnativeinterface.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DNATIVEINTERFACE_H
+#define QWINDOWSDIRECT2DNATIVEINTERFACE_H
+
+#include "qwindowsnativeinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DNativeInterface : public QWindowsNativeInterface
+{
+ Q_OBJECT
+public:
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
new file mode 100644
index 0000000000..85dbaab2ce
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowswindow.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintDevicePrivate
+{
+public:
+ QWindowsDirect2DPaintDevicePrivate(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags f)
+ : engine(new QWindowsDirect2DPaintEngine(bitmap))
+ , bitmap(bitmap)
+ , flags(f)
+ {}
+
+ QScopedPointer<QWindowsDirect2DPaintEngine> engine;
+ QWindowsDirect2DBitmap *bitmap;
+ QInternal::PaintDeviceFlags flags;
+};
+
+QWindowsDirect2DPaintDevice::QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags)
+ : d_ptr(new QWindowsDirect2DPaintDevicePrivate(bitmap, flags))
+{
+}
+
+QPaintEngine *QWindowsDirect2DPaintDevice::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->engine.data();
+}
+
+int QWindowsDirect2DPaintDevice::devType() const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ return d->flags;
+}
+
+int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPaintDevice);
+
+ switch (metric) {
+ case QPaintDevice::PdmWidth:
+ return d->bitmap->bitmap()->GetPixelSize().width;
+ break;
+ case QPaintDevice::PdmHeight:
+ return d->bitmap->bitmap()->GetPixelSize().height;
+ break;
+ case QPaintDevice::PdmNumColors:
+ return INT_MAX;
+ break;
+ case QPaintDevice::PdmDepth:
+ return 32;
+ break;
+ case QPaintDevice::PdmDpiX:
+ case QPaintDevice::PdmPhysicalDpiX:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return x;
+ }
+ break;
+ case QPaintDevice::PdmDpiY:
+ case QPaintDevice::PdmPhysicalDpiY:
+ {
+ FLOAT x, y;
+ QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
+ return y;
+ }
+ break;
+ case QPaintDevice::PdmDevicePixelRatio:
+ return 1;
+ break;
+ case QPaintDevice::PdmWidthMM:
+ case QPaintDevice::PdmHeightMM:
+ return -1;
+ break;
+ }
+
+ return -1;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
new file mode 100644
index 0000000000..c799083d84
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTDEVICE_H
+#define QWINDOWSDIRECT2DPAINTDEVICE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/QPaintDevice>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintDevicePrivate;
+class QWindowsDirect2DPaintDevice : public QPaintDevice
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintDevice)
+
+public:
+ QWindowsDirect2DPaintDevice(QWindowsDirect2DBitmap *bitmap, QInternal::PaintDeviceFlags flags);
+ QPaintEngine *paintEngine() const Q_DECL_OVERRIDE;
+ int devType() const Q_DECL_OVERRIDE;
+
+protected:
+ int metric(PaintDeviceMetric metric) const Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsDirect2DPaintDevicePrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTDEVICE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
new file mode 100644
index 0000000000..e19a6be47b
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -0,0 +1,1168 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dpaintengine.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dhelpers.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2ddevicecontext.h"
+
+#include "qwindowsfontengine.h"
+#include "qwindowsfontenginedirectwrite.h"
+#include "qwindowsfontdatabase.h"
+#include "qwindowsintegration.h"
+
+#include <QtGui/private/qpaintengine_p.h>
+#include <QtGui/private/qtextengine_p.h>
+#include <QtGui/private/qfontengine_p.h>
+#include <QtGui/private/qstatictext_p.h>
+
+#include <wrl.h>
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+// The enum values below are set as tags on the device context
+// in the various draw methods. When EndDraw is called the device context
+// will report the last set tag number in case of errors
+// along with an error code
+
+// Microsoft keeps a list of d2d error codes here:
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd370979(v=vs.85).aspx
+enum {
+ D2DDebugDrawInitialStateTag = -1,
+ D2DDebugDrawImageTag = 1,
+ D2DDebugFillTag,
+ D2DDebugDrawPixmapTag,
+ D2DDebugDrawStaticTextItemTag,
+ D2DDebugDrawTextItemTag
+};
+#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
+
+Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
+
+static inline ID2D1Factory1 *factory()
+{
+ return QWindowsDirect2DContext::instance()->d2dFactory();
+}
+
+// XXX reduce code duplication between painterPathToPathGeometry and
+// vectorPathToID2D1PathGeometry, the two are quite similar
+
+static ComPtr<ID2D1PathGeometry1> painterPathToPathGeometry(const QPainterPath &path)
+{
+ ComPtr<ID2D1PathGeometry1> geometry;
+ ComPtr<ID2D1GeometrySink> sink;
+
+ HRESULT hr = factory()->CreatePathGeometry(&geometry);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ hr = geometry->Open(&sink);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ switch (path.fillRule()) {
+ case Qt::WindingFill:
+ sink->SetFillMode(D2D1_FILL_MODE_WINDING);
+ break;
+ case Qt::OddEvenFill:
+ sink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);
+ break;
+ }
+
+ bool inFigure = false;
+
+ for (int i = 0; i < path.elementCount(); i++) {
+ const QPainterPath::Element element = path.elementAt(i);
+
+ switch (element.type) {
+ case QPainterPath::MoveToElement:
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->BeginFigure(to_d2d_point_2f(element), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+ break;
+
+ case QPainterPath::LineToElement:
+ sink->AddLine(to_d2d_point_2f(element));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ const QPainterPath::Element data1 = path.elementAt(++i);
+ const QPainterPath::Element data2 = path.elementAt(++i);
+
+ Q_ASSERT(i < path.elementCount());
+
+ Q_ASSERT(data1.type == QPainterPath::CurveToDataElement);
+ Q_ASSERT(data2.type == QPainterPath::CurveToDataElement);
+
+ D2D1_BEZIER_SEGMENT segment;
+
+ segment.point1 = to_d2d_point_2f(element);
+ segment.point2 = to_d2d_point_2f(data1);
+ segment.point3 = to_d2d_point_2f(data2);
+
+ sink->AddBezier(segment);
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->Close();
+
+ return geometry;
+}
+
+static ComPtr<ID2D1PathGeometry1> vectorPathToID2D1PathGeometry(const QVectorPath &path, bool alias)
+{
+ ComPtr<ID2D1PathGeometry1> pathGeometry;
+ HRESULT hr = factory()->CreatePathGeometry(pathGeometry.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ if (path.isEmpty())
+ return pathGeometry;
+
+ ComPtr<ID2D1GeometrySink> sink;
+ hr = pathGeometry->Open(sink.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ return NULL;
+ }
+
+ sink->SetFillMode(path.hasWindingFill() ? D2D1_FILL_MODE_WINDING
+ : D2D1_FILL_MODE_ALTERNATE);
+
+ bool inFigure = false;
+
+ const QPainterPath::ElementType *types = path.elements();
+ const int count = path.elementCount();
+ const qreal *points = 0;
+
+ QScopedArrayPointer<qreal> rounded_points;
+
+ if (alias) {
+ // Aliased painting, round to whole numbers
+ rounded_points.reset(new qreal[count * 2]);
+ points = rounded_points.data();
+
+ for (int i = 0; i < (count * 2); i++)
+ rounded_points[i] = qRound(path.points()[i]);
+ } else {
+ // Antialiased painting, keep original numbers
+ points = path.points();
+ }
+
+ Q_ASSERT(points);
+
+ if (types) {
+ qreal x, y;
+
+ for (int i = 0; i < count; i++) {
+ x = points[i * 2];
+ y = points[i * 2 + 1];
+
+ switch (types[i]) {
+ case QPainterPath::MoveToElement:
+ if (inFigure)
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+
+ sink->BeginFigure(D2D1::Point2F(x, y), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+ break;
+
+ case QPainterPath::LineToElement:
+ sink->AddLine(D2D1::Point2F(x, y));
+ break;
+
+ case QPainterPath::CurveToElement:
+ {
+ Q_ASSERT((i + 2) < count);
+ Q_ASSERT(types[i+1] == QPainterPath::CurveToDataElement);
+ Q_ASSERT(types[i+2] == QPainterPath::CurveToDataElement);
+
+ i++;
+ const qreal x2 = points[i * 2];
+ const qreal y2 = points[i * 2 + 1];
+
+ i++;
+ const qreal x3 = points[i * 2];
+ const qreal y3 = points[i * 2 + 1];
+
+ D2D1_BEZIER_SEGMENT segment = {
+ D2D1::Point2F(x, y),
+ D2D1::Point2F(x2, y2),
+ D2D1::Point2F(x3, y3)
+ };
+
+ sink->AddBezier(segment);
+ }
+ break;
+
+ case QPainterPath::CurveToDataElement:
+ qWarning("%s: Unhandled Curve Data Element", __FUNCTION__);
+ break;
+ }
+ }
+ } else {
+ sink->BeginFigure(D2D1::Point2F(points[0], points[1]), D2D1_FIGURE_BEGIN_FILLED);
+ inFigure = true;
+
+ for (int i = 1; i < count; i++)
+ sink->AddLine(D2D1::Point2F(points[i * 2], points[i * 2 + 1]));
+ }
+
+ if (inFigure) {
+ if (path.hasImplicitClose())
+ sink->AddLine(D2D1::Point2F(points[0], points[1]));
+
+ sink->EndFigure(D2D1_FIGURE_END_OPEN);
+ }
+
+ sink->Close();
+
+ return pathGeometry;
+}
+
+class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
+{
+ Q_DECLARE_PUBLIC(QWindowsDirect2DPaintEngine)
+public:
+ QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm)
+ : bitmap(bm)
+ , clipPushed(false)
+ {
+ pen.reset();
+ brush.reset();
+
+ dc()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+ }
+
+ QWindowsDirect2DBitmap *bitmap;
+
+ QPainterPath clipPath;
+ bool clipPushed;
+
+ QPointF currentBrushOrigin;
+
+ struct {
+ bool emulate;
+ QPen qpen;
+ ComPtr<ID2D1Brush> brush;
+ ComPtr<ID2D1StrokeStyle1> strokeStyle;
+
+ inline void reset() {
+ emulate = false;
+ qpen = QPen();
+ brush.Reset();
+ strokeStyle.Reset();
+ }
+ } pen;
+
+ struct {
+ bool emulate;
+ QBrush qbrush;
+ ComPtr<ID2D1Brush> brush;
+
+ inline void reset() {
+ emulate = false;
+ brush.Reset();
+ qbrush = QBrush();
+ }
+ } brush;
+
+ inline ID2D1DeviceContext *dc() const
+ {
+ Q_ASSERT(bitmap);
+ return bitmap->deviceContext()->get();
+ }
+
+ inline D2D1_INTERPOLATION_MODE interpolationMode() const
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ // XXX are we choosing the right d2d interpolation modes?
+ return (q->state()->renderHints & QPainter::SmoothPixmapTransform) ? D2D1_INTERPOLATION_MODE_HIGH_QUALITY_CUBIC
+ : D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+ }
+
+ inline D2D1_ANTIALIAS_MODE antialiasMode() const
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ return (q->state()->renderHints & QPainter::Antialiasing) ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
+ : D2D1_ANTIALIAS_MODE_ALIASED;
+ }
+
+ void updateTransform()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ // Note the loss of info going from 3x3 to 3x2 matrix here
+ dc()->SetTransform(to_d2d_matrix_3x2_f(q->state()->transform()));
+ }
+
+ void updateOpacity()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ qreal opacity = q->state()->opacity;
+ if (brush.brush)
+ brush.brush->SetOpacity(opacity);
+ if (pen.brush)
+ pen.brush->SetOpacity(opacity);
+ }
+
+ void pushClip()
+ {
+ popClip();
+
+ ComPtr<ID2D1PathGeometry1> geometry = painterPathToPathGeometry(clipPath);
+ if (!geometry)
+ return;
+
+ dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
+ geometry.Get(),
+ antialiasMode(),
+ D2D1::IdentityMatrix(),
+ 1.0,
+ NULL,
+ D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
+ NULL);
+ clipPushed = true;
+ }
+
+ void popClip()
+ {
+ if (clipPushed) {
+ dc()->PopLayer();
+ clipPushed = false;
+ }
+ }
+
+ void updateClipEnabled()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ if (!q->state()->clipEnabled)
+ popClip();
+ else if (!clipPushed)
+ pushClip();
+ }
+
+ void updateClipPath(const QPainterPath &path, Qt::ClipOperation operation)
+ {
+ switch (operation) {
+ case Qt::NoClip:
+ popClip();
+ break;
+ case Qt::ReplaceClip:
+ clipPath = path;
+ pushClip();
+ break;
+ case Qt::IntersectClip:
+ clipPath &= path;
+ pushClip();
+ break;
+ }
+ }
+
+ void updateCompositionMode()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ QPainter::CompositionMode mode = q->state()->compositionMode();
+
+ switch (mode) {
+ case QPainter::CompositionMode_Source:
+ dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_COPY);
+ break;
+ case QPainter::CompositionMode_SourceOver:
+ dc()->SetPrimitiveBlend(D2D1_PRIMITIVE_BLEND_SOURCE_OVER);
+ break;
+
+ default:
+ qWarning("Unsupported composition mode: %d", mode);
+ break;
+ }
+ }
+
+ void updateBrush(const QBrush &newBrush)
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+
+ if (qbrush_fast_equals(brush.qbrush, newBrush))
+ return;
+
+ brush.brush = to_d2d_brush(newBrush, &brush.emulate);
+ brush.qbrush = newBrush;
+
+ if (brush.brush) {
+ brush.brush->SetOpacity(q->state()->opacity);
+ applyBrushOrigin(currentBrushOrigin);
+ }
+ }
+
+ void updateBrushOrigin()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+
+ negateCurrentBrushOrigin();
+ applyBrushOrigin(q->state()->brushOrigin);
+ }
+
+ void negateCurrentBrushOrigin()
+ {
+ if (brush.brush && !currentBrushOrigin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(-currentBrushOrigin.x(),
+ -currentBrushOrigin.y()));
+ }
+ }
+
+ void applyBrushOrigin(const QPointF &origin)
+ {
+ if (brush.brush && !origin.isNull()) {
+ D2D1_MATRIX_3X2_F transform;
+ brush.brush->GetTransform(&transform);
+
+ brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
+ * D2D1::Matrix3x2F::Translation(origin.x(), origin.y()));
+ }
+
+ currentBrushOrigin = origin;
+ }
+
+ void updatePen()
+ {
+ Q_Q(const QWindowsDirect2DPaintEngine);
+ const QPen &newPen = q->state()->pen;
+
+ if (qpen_fast_equals(newPen, pen.qpen))
+ return;
+
+ pen.reset();
+ pen.qpen = newPen;
+
+ if (newPen.style() == Qt::NoPen)
+ return;
+
+ pen.brush = to_d2d_brush(newPen.brush(), &pen.emulate);
+ if (!pen.brush)
+ return;
+
+ pen.brush->SetOpacity(q->state()->opacity);
+
+ D2D1_STROKE_STYLE_PROPERTIES1 props = {};
+
+ switch (newPen.capStyle()) {
+ case Qt::SquareCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_SQUARE;
+ break;
+ case Qt::RoundCap:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_ROUND;
+ case Qt::FlatCap:
+ default:
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+ break;
+ }
+
+ switch (newPen.joinStyle()) {
+ case Qt::BevelJoin:
+ props.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ break;
+ case Qt::RoundJoin:
+ props.lineJoin = D2D1_LINE_JOIN_ROUND;
+ break;
+ case Qt::MiterJoin:
+ default:
+ props.lineJoin = D2D1_LINE_JOIN_MITER;
+ break;
+ }
+
+ props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
+ props.dashOffset = newPen.dashOffset();
+ props.transformType = qIsNull(newPen.widthF()) ? D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE
+ : newPen.isCosmetic() ? D2D1_STROKE_TRANSFORM_TYPE_FIXED
+ : D2D1_STROKE_TRANSFORM_TYPE_NORMAL;
+
+ switch (newPen.style()) {
+ case Qt::SolidLine:
+ props.dashStyle = D2D1_DASH_STYLE_SOLID;
+ break;
+
+ case Qt::DotLine:
+ case Qt::DashDotLine:
+ case Qt::DashDotDotLine:
+ // Try and match Qt's raster engine in output as closely as possible
+ if (newPen.widthF() <= 1.0)
+ props.startCap = props.endCap = props.dashCap = D2D1_CAP_STYLE_FLAT;
+
+ // fall through
+ default:
+ props.dashStyle = D2D1_DASH_STYLE_CUSTOM;
+ break;
+ }
+
+ HRESULT hr;
+
+ if (props.dashStyle == D2D1_DASH_STYLE_CUSTOM) {
+ QVector<qreal> dashes = newPen.dashPattern();
+ QVector<FLOAT> converted(dashes.size());
+
+ for (int i = 0; i < dashes.size(); i++) {
+ converted[i] = dashes[i];
+ }
+
+ hr = factory()->CreateStrokeStyle(props, converted.constData(), converted.size(), &pen.strokeStyle);
+ } else {
+ hr = factory()->CreateStrokeStyle(props, NULL, 0, &pen.strokeStyle);
+ }
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create stroke style: %#x", __FUNCTION__, hr);
+ }
+
+ ComPtr<ID2D1Brush> to_d2d_brush(const QBrush &newBrush, bool *needsEmulation)
+ {
+ HRESULT hr;
+ ComPtr<ID2D1Brush> result;
+
+ Q_ASSERT(needsEmulation);
+
+ *needsEmulation = false;
+
+ switch (newBrush.style()) {
+ case Qt::NoBrush:
+ break;
+
+ case Qt::SolidPattern:
+ {
+ ComPtr<ID2D1SolidColorBrush> solid;
+
+ hr = dc()->CreateSolidColorBrush(to_d2d_color_f(newBrush.color()), &solid);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create solid color brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = solid.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert solid color brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::Dense1Pattern:
+ case Qt::Dense2Pattern:
+ case Qt::Dense3Pattern:
+ case Qt::Dense4Pattern:
+ case Qt::Dense5Pattern:
+ case Qt::Dense6Pattern:
+ case Qt::Dense7Pattern:
+ case Qt::HorPattern:
+ case Qt::VerPattern:
+ case Qt::CrossPattern:
+ case Qt::BDiagPattern:
+ case Qt::FDiagPattern:
+ case Qt::DiagCrossPattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QImage brushImg = qt_imageForBrush(newBrush.style(), false);
+ brushImg.setColor(0, newBrush.color().rgba());
+ brushImg.setColor(1, qRgba(0, 0, 0, 0));
+
+ QWindowsDirect2DBitmap bitmap;
+ bool success = bitmap.fromImage(brushImg, Qt::AutoColor);
+ if (!success) {
+ qWarning("%s: Could not create Direct2D bitmap from Qt pattern brush image", __FUNCTION__);
+ break;
+ }
+
+ hr = dc()->CreateBitmapBrush(bitmap.bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+
+ case Qt::LinearGradientPattern:
+ case Qt::RadialGradientPattern:
+ case Qt::ConicalGradientPattern:
+ *needsEmulation = true;
+ break;
+
+ case Qt::TexturePattern:
+ {
+ ComPtr<ID2D1BitmapBrush1> bitmapBrush;
+ D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = {
+ D2D1_EXTEND_MODE_WRAP,
+ D2D1_EXTEND_MODE_WRAP,
+ interpolationMode()
+ };
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(newBrush.texture().handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+ hr = dc()->CreateBitmapBrush(bitmap->bitmap(),
+ bitmapBrushProperties,
+ &bitmapBrush);
+
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create texture brush: %#x", __FUNCTION__, hr);
+ break;
+ }
+
+ hr = bitmapBrush.As(&result);
+ if (FAILED(hr))
+ qWarning("%s: Could not convert texture brush: %#x", __FUNCTION__, hr);
+ }
+ break;
+ }
+
+ if (result && !newBrush.transform().isIdentity())
+ result->SetTransform(to_d2d_matrix_3x2_f(newBrush.transform()));
+
+ return result;
+ }
+
+ void updateHints()
+ {
+ dc()->SetAntialiasMode(antialiasMode());
+ }
+};
+
+QWindowsDirect2DPaintEngine::QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap)
+ : QPaintEngineEx(*(new QWindowsDirect2DPaintEnginePrivate(bitmap)))
+{
+ QPaintEngine::PaintEngineFeatures unsupported =
+ // As of 1.1 Direct2D gradient support is deficient for linear and radial gradients
+ QPaintEngine::LinearGradientFill
+ | QPaintEngine::RadialGradientFill
+
+ // As of 1.1 Direct2D does not support conical gradients at all
+ | QPaintEngine::ConicalGradientFill
+
+ // As of 1.1 Direct2D does not natively support complex composition modes
+ // However, using Direct2D effects that implement them should be possible
+ | QPaintEngine::PorterDuff
+ | QPaintEngine::BlendModes
+ | QPaintEngine::RasterOpModes
+
+ // As of 1.1 Direct2D does not natively support perspective transforms
+ // However, writing a custom effect that implements them should be possible
+ // The built-in 3D transform effect unfortunately changes output image size, making
+ // it unusable for us.
+ | QPaintEngine::PerspectiveTransform;
+
+ gccaps &= ~unsupported;
+}
+
+bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ d->bitmap->deviceContext()->begin();
+ d->dc()->SetTransform(D2D1::Matrix3x2F::Identity());
+
+ QRect clip(0, 0, pdev->width(), pdev->height());
+ if (!systemClip().isEmpty())
+ clip &= systemClip().boundingRect();
+
+ d->dc()->PushAxisAlignedClip(to_d2d_rect_f(clip), D2D1_ANTIALIAS_MODE_ALIASED);
+
+ D2D_TAG(D2DDebugDrawInitialStateTag);
+
+ return true;
+}
+
+bool QWindowsDirect2DPaintEngine::end()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ // First pop any user-applied clipping
+ d->popClip();
+ // Now the system clip from begin() above
+ d->dc()->PopAxisAlignedClip();
+ return d->bitmap->deviceContext()->end();
+}
+
+QPaintEngine::Type QWindowsDirect2DPaintEngine::type() const
+{
+ return QPaintEngine::Direct2D;
+}
+
+void QWindowsDirect2DPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugFillTag);
+
+ if (path.isEmpty())
+ return;
+
+ d->updateBrush(brush);
+
+ if (d->brush.emulate) {
+ // We mostly (only?) get here when gradients are required.
+ // We could probably natively support linear and radial gradients that have pad reflect
+
+ QImage img(d->bitmap->size(), QImage::Format_ARGB32);
+ img.fill(Qt::transparent);
+
+ QPainter p;
+ QPaintEngine *engine = img.paintEngine();
+ if (engine->isExtended() && p.begin(&img)) {
+ QPaintEngineEx *extended = static_cast<QPaintEngineEx *>(engine);
+ extended->fill(path, brush);
+ if (!p.end())
+ qWarning("%s: Paint Engine end returned false", __FUNCTION__);
+
+ drawImage(img.rect(), img, img.rect());
+ } else {
+ qWarning("%s: Could not fall back to QImage", __FUNCTION__);
+ }
+
+ return;
+ }
+
+ if (!d->brush.brush)
+ return;
+
+ ComPtr<ID2D1Geometry> geometry = vectorPathToID2D1PathGeometry(path, d->antialiasMode() == D2D1_ANTIALIAS_MODE_ALIASED);
+ if (!geometry) {
+ qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
+ return;
+ }
+
+ d->dc()->FillGeometry(geometry.Get(), d->brush.brush.Get());
+}
+
+// For clipping we convert everything to painter paths since it allows
+// calculating intersections easily. It might be faster to convert to
+// ID2D1Geometry and use its operations, although that needs to measured.
+// The implementation would be more complex in any case.
+
+void QWindowsDirect2DPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
+{
+ clip(path.convertToPainterPath(), op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)
+{
+ QPainterPath p;
+ p.addRect(rect);
+ clip(p, op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QRegion &region, Qt::ClipOperation op)
+{
+ QPainterPath p;
+ p.addRegion(region);
+ clip(p, op);
+}
+
+void QWindowsDirect2DPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateClipPath(path, op);
+}
+
+void QWindowsDirect2DPaintEngine::clipEnabledChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateClipEnabled();
+}
+
+void QWindowsDirect2DPaintEngine::penChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updatePen();
+}
+
+void QWindowsDirect2DPaintEngine::brushChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateBrush(state()->brush);
+}
+
+void QWindowsDirect2DPaintEngine::brushOriginChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateBrushOrigin();
+}
+
+void QWindowsDirect2DPaintEngine::opacityChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateOpacity();
+}
+
+void QWindowsDirect2DPaintEngine::compositionModeChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateCompositionMode();
+}
+
+void QWindowsDirect2DPaintEngine::renderHintsChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateHints();
+}
+
+void QWindowsDirect2DPaintEngine::transformChanged()
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ d->updateTransform();
+}
+
+void QWindowsDirect2DPaintEngine::drawImage(const QRectF &rectangle, const QImage &image,
+ const QRectF &sr, Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawImageTag);
+
+ QPixmap pixmap = QPixmap::fromImage(image, flags);
+ drawPixmap(rectangle, pixmap, sr);
+}
+
+void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
+ const QPixmap &pm,
+ const QRectF &sr)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawPixmapTag);
+
+ if (pm.isNull())
+ return;
+
+ if (pm.handle()->pixelType() == QPlatformPixmap::BitmapType) {
+ QImage i = pm.toImage();
+ i.setColor(0, qRgba(0, 0, 0, 0));
+ i.setColor(1, d->pen.qpen.color().rgba());
+ drawImage(r, i, sr);
+ return;
+ }
+
+ QWindowsDirect2DPlatformPixmap *pp = static_cast<QWindowsDirect2DPlatformPixmap *>(pm.handle());
+ QWindowsDirect2DBitmap *bitmap = pp->bitmap();
+
+ if (bitmap->bitmap() != d->bitmap->bitmap()) {
+ // Good, src bitmap != dst bitmap
+ if (sr.isValid())
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode(),
+ to_d2d_rect_f(sr));
+ else
+ d->dc()->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode());
+ } else {
+ // Ok, so the source pixmap and destination pixmap is the same.
+ // D2D is not fond of this scenario, deal with it through
+ // an intermediate bitmap
+ QWindowsDirect2DBitmap intermediate;
+
+ if (sr.isValid()) {
+ bool r = intermediate.resize(sr.width(), sr.height());
+ if (!r) {
+ qWarning("%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
+ return;
+ }
+
+ D2D1_RECT_U d2d_sr = to_d2d_rect_u(sr.toRect());
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ &d2d_sr);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ } else {
+ bool r = intermediate.resize(bitmap->size().width(),
+ bitmap->size().height());
+ if (!r) {
+ qWarning("%s: Could not resize intermediate bitmap to source bitmap size", __FUNCTION__);
+ return;
+ }
+
+ HRESULT hr = intermediate.bitmap()->CopyFromBitmap(NULL,
+ bitmap->bitmap(),
+ NULL);
+ if (FAILED(hr)) {
+ qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ return;
+ }
+ }
+
+ d->dc()->DrawBitmap(intermediate.bitmap(),
+ to_d2d_rect_f(r), state()->opacity,
+ d->interpolationMode());
+ }
+}
+
+static ComPtr<IDWriteFontFace> fontFaceFromFontEngine(QFontEngine *fe)
+{
+ ComPtr<IDWriteFontFace> fontFace;
+
+ switch (fe->type()) {
+ case QFontEngine::Win:
+ {
+ QWindowsFontEngine *wfe = static_cast<QWindowsFontEngine *>(fe);
+ QSharedPointer<QWindowsFontEngineData> wfed = wfe->fontEngineData();
+
+ HGDIOBJ oldfont = wfe->selectDesignFont();
+ HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFaceFromHdc(wfed->hdc, &fontFace);
+ DeleteObject(SelectObject(wfed->hdc, oldfont));
+ if (FAILED(hr))
+ qWarning("%s: Could not create DirectWrite fontface from HDC: %#x", __FUNCTION__, hr);
+
+ }
+ break;
+
+#ifndef QT_NO_DIRECTWRITE
+
+ case QFontEngine::DirectWrite:
+ {
+ QWindowsFontEngineDirectWrite *wfedw = static_cast<QWindowsFontEngineDirectWrite *>(fe);
+ fontFace = wfedw->directWriteFontFace();
+ }
+ break;
+
+#endif // QT_NO_DIRECTWRITE
+
+ default:
+ qWarning("%s: Unknown font engine!", __FUNCTION__);
+ break;
+ }
+
+ return fontFace;
+}
+
+void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawStaticTextItemTag);
+
+ if (qpen_style(d->pen.qpen) == Qt::NoPen)
+ return;
+
+ if (staticTextItem->numGlyphs == 0)
+ return;
+
+ // If we can't support the current configuration with Direct2D, fall back to slow path
+ // Most common cases are perspective transform and gradient brush as pen
+ if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ QPaintEngineEx::drawStaticTextItem(staticTextItem);
+ return;
+ }
+
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(staticTextItem->fontEngine());
+ if (!fontFace) {
+ qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
+ QPaintEngineEx::drawStaticTextItem(staticTextItem);
+ return;
+ }
+
+ QVector<UINT16> glyphIndices(staticTextItem->numGlyphs);
+ QVector<FLOAT> glyphAdvances(staticTextItem->numGlyphs);
+ QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(staticTextItem->numGlyphs);
+
+ // XXX Are we generating a lot of cache misses here?
+ for (int i = 0; i < staticTextItem->numGlyphs; i++) {
+ glyphIndices[i] = UINT16(staticTextItem->glyphs[i]); // Imperfect conversion here
+
+ // This looks a little funky because the positions are precalculated
+ glyphAdvances[i] = 0;
+ glyphOffsets[i].advanceOffset = staticTextItem->glyphPositions[i].x.toReal();
+ // Qt and Direct2D seem to disagree on the direction of the ascender offset...
+ glyphOffsets[i].ascenderOffset = staticTextItem->glyphPositions[i].y.toReal() * -1;
+ }
+
+ drawGlyphRun(D2D1::Point2F(0, 0),
+ fontFace.Get(),
+ staticTextItem->font,
+ staticTextItem->numGlyphs,
+ glyphIndices.constData(),
+ glyphAdvances.constData(),
+ glyphOffsets.constData(),
+ false);
+}
+
+void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+ D2D_TAG(D2DDebugDrawTextItemTag);
+
+ if (qpen_style(d->pen.qpen) == Qt::NoPen)
+ return;
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
+ if (ti.glyphs.numGlyphs == 0)
+ return;
+
+ // If we can't support the current configuration with Direct2D, fall back to slow path
+ // Most common cases are perspective transform and gradient brush as pen
+ if ((state()->transform().isAffine() == false) || d->pen.emulate) {
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ ComPtr<IDWriteFontFace> fontFace = fontFaceFromFontEngine(ti.fontEngine);
+ if (!fontFace) {
+ qWarning("%s: Could not find font - falling back to slow text rendering path.", __FUNCTION__);
+ QPaintEngine::drawTextItem(p, textItem);
+ return;
+ }
+
+ QVector<UINT16> glyphIndices(ti.glyphs.numGlyphs);
+ QVector<FLOAT> glyphAdvances(ti.glyphs.numGlyphs);
+ QVector<DWRITE_GLYPH_OFFSET> glyphOffsets(ti.glyphs.numGlyphs);
+
+ // XXX Are we generating a lot of cache misses here?
+ for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
+ glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
+ glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
+ glyphOffsets[i].advanceOffset = ti.glyphs.offsets[i].x.toReal();
+
+ // XXX Should we negate the y value like for static text items?
+ glyphOffsets[i].ascenderOffset = ti.glyphs.offsets[i].y.toReal();
+ }
+
+ const bool rtl = (ti.flags & QTextItem::RightToLeft);
+ const QPointF offset(rtl ? ti.width.toReal() : 0, 0);
+
+ drawGlyphRun(to_d2d_point_2f(p + offset),
+ fontFace.Get(),
+ ti.font(),
+ ti.glyphs.numGlyphs,
+ glyphIndices.constData(),
+ glyphAdvances.constData(),
+ glyphOffsets.constData(),
+ rtl);
+}
+
+// Points (1/72 inches) to Microsoft's Device Independent Pixels (1/96 inches)
+inline static Q_DECL_CONSTEXPR FLOAT pointSizeToDIP(qreal pointSize)
+{
+ return pointSize + (pointSize / qreal(3.0));
+}
+
+inline static FLOAT pixelSizeToDIP(int pixelSize)
+{
+ FLOAT dpiX, dpiY;
+ factory()->GetDesktopDpi(&dpiX, &dpiY);
+
+ return FLOAT(pixelSize) / (dpiY / 96.0f);
+}
+
+inline static FLOAT fontSizeInDIP(const QFont &font)
+{
+ // Direct2d wants the font size in DIPs (Device Independent Pixels), each of which is 1/96 inches.
+ if (font.pixelSize() == -1) {
+ // font size was set as points
+ return pointSizeToDIP(font.pointSizeF());
+ } else {
+ // font size was set as pixels
+ return pixelSizeToDIP(font.pixelSize());
+ }
+}
+
+void QWindowsDirect2DPaintEngine::drawGlyphRun(const D2D1_POINT_2F &pos,
+ IDWriteFontFace *fontFace,
+ const QFont &font,
+ int numGlyphs,
+ const UINT16 *glyphIndices,
+ const FLOAT *glyphAdvances,
+ const DWRITE_GLYPH_OFFSET *glyphOffsets,
+ bool rtl)
+{
+ Q_D(QWindowsDirect2DPaintEngine);
+
+ DWRITE_GLYPH_RUN glyphRun = {
+ fontFace, // IDWriteFontFace *fontFace;
+ fontSizeInDIP(font), // FLOAT fontEmSize;
+ numGlyphs, // UINT32 glyphCount;
+ glyphIndices, // const UINT16 *glyphIndices;
+ glyphAdvances, // const FLOAT *glyphAdvances;
+ glyphOffsets, // const DWRITE_GLYPH_OFFSET *glyphOffsets;
+ FALSE, // BOOL isSideways;
+ rtl ? 1 : 0 // UINT32 bidiLevel;
+ };
+
+ const bool antiAlias = bool((state()->renderHints & QPainter::TextAntialiasing)
+ && !(font.styleStrategy() & QFont::NoAntialias));
+ d->dc()->SetTextAntialiasMode(antiAlias ? D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
+ : D2D1_TEXT_ANTIALIAS_MODE_ALIASED);
+
+ d->dc()->DrawGlyphRun(pos,
+ &glyphRun,
+ NULL,
+ d->pen.brush.Get(),
+ DWRITE_MEASURING_MODE_GDI_CLASSIC);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
new file mode 100644
index 0000000000..6c74a07e88
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPAINTENGINE_H
+#define QWINDOWSDIRECT2DPAINTENGINE_H
+
+#include <QtCore/QScopedPointer>
+#include <QtGui/private/qpaintengineex_p.h>
+
+#include <d2d1_1.h>
+#include <dwrite_1.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPaintEnginePrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPaintEngine : public QPaintEngineEx
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPaintEngine)
+
+public:
+ QWindowsDirect2DPaintEngine(QWindowsDirect2DBitmap *bitmap);
+
+ bool begin(QPaintDevice *pdev) Q_DECL_OVERRIDE;
+ bool end() Q_DECL_OVERRIDE;
+
+ Type type() const Q_DECL_OVERRIDE;
+
+ void fill(const QVectorPath &path, const QBrush &brush) Q_DECL_OVERRIDE;
+
+ void clip(const QVectorPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRect &rect, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QRegion &region, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+ void clip(const QPainterPath &path, Qt::ClipOperation op) Q_DECL_OVERRIDE;
+
+ void clipEnabledChanged() Q_DECL_OVERRIDE;
+ void penChanged() Q_DECL_OVERRIDE;
+ void brushChanged() Q_DECL_OVERRIDE;
+ void brushOriginChanged() Q_DECL_OVERRIDE;
+ void opacityChanged() Q_DECL_OVERRIDE;
+ void compositionModeChanged() Q_DECL_OVERRIDE;
+ void renderHintsChanged() Q_DECL_OVERRIDE;
+ void transformChanged() Q_DECL_OVERRIDE;
+
+ void drawImage(const QRectF &rectangle, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags = Qt::AutoColor) Q_DECL_OVERRIDE;
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) Q_DECL_OVERRIDE;
+
+ void drawStaticTextItem(QStaticTextItem *staticTextItem) Q_DECL_OVERRIDE;
+ void drawTextItem(const QPointF &p, const QTextItem &textItem) Q_DECL_OVERRIDE;
+
+private:
+ void drawGlyphRun(const D2D1_POINT_2F &pos, IDWriteFontFace *fontFace, const QFont &font,
+ int numGlyphs, const UINT16 *glyphIndices, const FLOAT *glyphAdvances,
+ const DWRITE_GLYPH_OFFSET *glyphOffsets, bool rtl);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPAINTENGINE_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
new file mode 100644
index 0000000000..072c4b3c0e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dpaintdevice.h"
+#include "qwindowsdirect2dplatformpixmap.h"
+#include "qwindowsdirect2dbitmap.h"
+#include "qwindowsdirect2dhelpers.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QImage>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QPaintEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate
+{
+public:
+ QWindowsDirect2DPlatformPixmapPrivate()
+ : bitmap(new QWindowsDirect2DBitmap)
+ , device(new QWindowsDirect2DPaintDevice(bitmap.data(), QInternal::Pixmap))
+ , devicePixelRatio(1.0)
+ {}
+
+ QScopedPointer<QWindowsDirect2DBitmap> bitmap;
+ QScopedPointer<QWindowsDirect2DPaintDevice> device;
+ qreal devicePixelRatio;
+};
+
+static int qt_d2dpixmap_serno = 0;
+
+QWindowsDirect2DPlatformPixmap::QWindowsDirect2DPlatformPixmap(PixelType pixelType)
+ : QPlatformPixmap(pixelType, Direct2DClass)
+ , d_ptr(new QWindowsDirect2DPlatformPixmapPrivate)
+{
+ setSerialNumber(qt_d2dpixmap_serno++);
+}
+
+QWindowsDirect2DPlatformPixmap::~QWindowsDirect2DPlatformPixmap()
+{
+
+}
+
+void QWindowsDirect2DPlatformPixmap::resize(int width, int height)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->resize(width, height)) {
+ qWarning("%s: Could not resize bitmap", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = width;
+ h = height;
+ this->d = 32;
+}
+
+void QWindowsDirect2DPlatformPixmap::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+
+ if (!d->bitmap->fromImage(image, flags)) {
+ qWarning("%s: Could not init from image", __FUNCTION__);
+ return;
+ }
+
+ is_null = false;
+ w = image.width();
+ h = image.height();
+ this->d = 32;
+}
+
+int QWindowsDirect2DPlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ Q_GUI_EXPORT int qt_paint_device_metric(const QPaintDevice *device, QPaintDevice::PaintDeviceMetric metric);
+ return qt_paint_device_metric(d->device.data(), metric);
+}
+
+void QWindowsDirect2DPlatformPixmap::fill(const QColor &color)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->bitmap->fill(color);
+}
+
+bool QWindowsDirect2DPlatformPixmap::hasAlphaChannel() const
+{
+ return true;
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage() const
+{
+ return toImage(QRect());
+}
+
+QImage QWindowsDirect2DPlatformPixmap::toImage(const QRect &rect) const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+
+ bool active = d->device->paintEngine()->isActive();
+
+ if (active)
+ d->device->paintEngine()->end();
+
+ QImage result = d->bitmap->toImage(rect);
+
+ if (active)
+ d->device->paintEngine()->begin(d->device.data());
+
+ return result;
+}
+
+QPaintEngine* QWindowsDirect2DPlatformPixmap::paintEngine() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->device->paintEngine();
+}
+
+qreal QWindowsDirect2DPlatformPixmap::devicePixelRatio() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->devicePixelRatio;
+}
+
+void QWindowsDirect2DPlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
+{
+ Q_D(QWindowsDirect2DPlatformPixmap);
+ d->devicePixelRatio = scaleFactor;
+}
+
+QWindowsDirect2DBitmap *QWindowsDirect2DPlatformPixmap::bitmap() const
+{
+ Q_D(const QWindowsDirect2DPlatformPixmap);
+ return d->bitmap.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
new file mode 100644
index 0000000000..e6684ea423
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+#define QWINDOWSDIRECT2DPLATFORMPIXMAP_H
+
+#include <QtGui/qpa/qplatformpixmap.h>
+#include <QtCore/QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DPlatformPixmapPrivate;
+class QWindowsDirect2DBitmap;
+
+class QWindowsDirect2DPlatformPixmap : public QPlatformPixmap
+{
+ Q_DECLARE_PRIVATE(QWindowsDirect2DPlatformPixmap)
+public:
+ QWindowsDirect2DPlatformPixmap(PixelType pixelType);
+ ~QWindowsDirect2DPlatformPixmap();
+
+ virtual void resize(int width, int height);
+ virtual void fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags);
+
+ virtual int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ virtual void fill(const QColor &color);
+
+ virtual bool hasAlphaChannel() const;
+
+ virtual QImage toImage() const;
+ virtual QImage toImage(const QRect &rect) const;
+
+ virtual QPaintEngine* paintEngine() const;
+
+ virtual qreal devicePixelRatio() const;
+ virtual void setDevicePixelRatio(qreal scaleFactor);
+
+ QWindowsDirect2DBitmap *bitmap() const;
+
+private:
+ QScopedPointer<QWindowsDirect2DPlatformPixmapPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DPLATFORMPIXMAP_H
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
new file mode 100644
index 0000000000..f75bb49fd9
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformplugin.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dintegration.h"
+
+#include <QtGui/qpa/qplatformintegrationplugin.h>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "direct2d.json")
+public:
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QPlatformIntegration *QWindowsDirect2DIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ if (system.compare(system, QStringLiteral("direct2d"), Qt::CaseInsensitive) == 0)
+ return QWindowsDirect2DIntegration::create(paramList);
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "qwindowsdirect2dplatformplugin.moc"
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
new file mode 100644
index 0000000000..bf860f982e
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsdirect2dcontext.h"
+#include "qwindowsdirect2dwindow.h"
+#include "qwindowsdirect2ddevicecontext.h"
+#include "qwindowsdirect2dhelpers.h"
+
+#include <d3d11.h>
+#include <d2d1_1.h>
+using Microsoft::WRL::ComPtr;
+
+QT_BEGIN_NAMESPACE
+
+QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data)
+ : QWindowsWindow(window, data)
+ , m_needsFullFlush(true)
+{
+ DXGI_SWAP_CHAIN_DESC1 desc = {};
+
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ desc.BufferCount = 1;
+ desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+
+ HRESULT hr = QWindowsDirect2DContext::instance()->dxgiFactory()->CreateSwapChainForHwnd(
+ QWindowsDirect2DContext::instance()->d3dDevice(), // [in] IUnknown *pDevice
+ handle(), // [in] HWND hWnd
+ &desc, // [in] const DXGI_SWAP_CHAIN_DESC1 *pDesc
+ NULL, // [in] const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc
+ NULL, // [in] IDXGIOutput *pRestrictToOutput
+ m_swapChain.ReleaseAndGetAddressOf()); // [out] IDXGISwapChain1 **ppSwapChain
+
+ if (FAILED(hr))
+ qWarning("%s: Could not create swap chain: %#x", __FUNCTION__, hr);
+
+ hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ m_deviceContext.GetAddressOf());
+ if (FAILED(hr))
+ qWarning("%s: Couldn't create Direct2D Device context: %#x", __FUNCTION__, hr);
+}
+
+QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
+{
+}
+
+void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset)
+{
+ DXGI_SWAP_CHAIN_DESC1 desc;
+ HRESULT hr = m_swapChain->GetDesc1(&desc);
+ QRect geom = geometry();
+
+ if (FAILED(hr) || (desc.Width != geom.width()) || (desc.Height != geom.height())) {
+ resizeSwapChain(geom.size());
+ m_swapChain->GetDesc1(&desc);
+ }
+
+ setupBitmap();
+ if (!m_bitmap)
+ return;
+
+ m_bitmap->deviceContext()->begin();
+
+ ID2D1DeviceContext *dc = m_bitmap->deviceContext()->get();
+ if (!m_needsFullFlush) {
+ QRegion clipped = region;
+ clipped &= QRect(0, 0, desc.Width, desc.Height);
+
+ foreach (const QRect &rect, clipped.rects()) {
+ QRectF rectF(rect);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ }
+ } else {
+ QRectF rectF(0, 0, desc.Width, desc.Height);
+ dc->DrawBitmap(bitmap->bitmap(),
+ to_d2d_rect_f(rectF),
+ 1.0,
+ D2D1_INTERPOLATION_MODE_LINEAR,
+ to_d2d_rect_f(rectF.translated(offset.x(), offset.y())));
+ m_needsFullFlush = false;
+ }
+
+ m_bitmap->deviceContext()->end();
+ m_swapChain->Present(1, 0);
+}
+
+void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
+{
+ if (!m_swapChain)
+ return;
+
+ m_bitmap.reset();
+ m_deviceContext->SetTarget(Q_NULLPTR);
+
+ HRESULT hr = m_swapChain->ResizeBuffers(0,
+ size.width(), size.height(),
+ DXGI_FORMAT_UNKNOWN,
+ 0);
+ if (FAILED(hr))
+ qWarning("%s: Could not resize swap chain: %#x", __FUNCTION__, hr);
+
+ m_needsFullFlush = true;
+}
+
+void QWindowsDirect2DWindow::setupBitmap()
+{
+ if (m_bitmap)
+ return;
+
+ if (!m_deviceContext)
+ return;
+
+ if (!m_swapChain)
+ return;
+
+ ComPtr<IDXGISurface1> backBufferSurface;
+ HRESULT hr = m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBufferSurface));
+ if (FAILED(hr)) {
+ qWarning("%s: Could not query backbuffer for DXGI Surface: %#x", __FUNCTION__, hr);
+ return;
+ }
+
+ ComPtr<ID2D1Bitmap1> backBufferBitmap;
+ hr = m_deviceContext->CreateBitmapFromDxgiSurface(backBufferSurface.Get(), NULL, backBufferBitmap.GetAddressOf());
+ if (FAILED(hr)) {
+ qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#x", __FUNCTION__, hr);
+ return;
+ }
+
+ m_bitmap.reset(new QWindowsDirect2DBitmap(backBufferBitmap.Get(), m_deviceContext.Get()));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
new file mode 100644
index 0000000000..7996904639
--- /dev/null
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSDIRECT2DWINDOW_H
+#define QWINDOWSDIRECT2DWINDOW_H
+
+#include "qwindowswindow.h"
+#include "qwindowsdirect2dbitmap.h"
+
+#include <dxgi1_2.h>
+#include <wrl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsDirect2DWindow : public QWindowsWindow
+{
+public:
+ QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data);
+ ~QWindowsDirect2DWindow();
+
+ void flush(QWindowsDirect2DBitmap *bitmap, const QRegion &region, const QPoint &offset);
+
+private:
+ void resizeSwapChain(const QSize &size);
+ void setupBitmap();
+
+private:
+ Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
+ Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
+ QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
+ bool m_needsFullFlush;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSDIRECT2DWINDOW_H
diff --git a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
index b56d75a16e..16510095db 100644
--- a/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbconvenience.cpp
@@ -281,12 +281,16 @@ QDirectFbKeyMap::QDirectFbKeyMap()
insert(DIKS_CLEAR , Qt::Key_Clear);
insert(DIKS_MENU , Qt::Key_Menu);
insert(DIKS_HELP , Qt::Key_Help);
+ insert(DIKS_INFO , Qt::Key_Info);
+ insert(DIKS_EXIT , Qt::Key_Exit);
+ insert(DIKS_SETUP , Qt::Key_Settings);
insert(DIKS_CD , Qt::Key_CD);
insert(DIKS_INTERNET , Qt::Key_HomePage);
insert(DIKS_MAIL , Qt::Key_LaunchMail);
insert(DIKS_FAVORITES , Qt::Key_Favorites);
insert(DIKS_PHONE , Qt::Key_Phone);
+ insert(DIKS_PROGRAM , Qt::Key_Guide);
insert(DIKS_TIME , Qt::Key_Time);
insert(DIKS_RED , Qt::Key_Red);
diff --git a/src/plugins/platforms/eglfs/eglfs.pri b/src/plugins/platforms/eglfs/eglfs.pri
index 390061c168..6e3ba54b97 100644
--- a/src/plugins/platforms/eglfs/eglfs.pri
+++ b/src/plugins/platforms/eglfs/eglfs.pri
@@ -1,7 +1,5 @@
QT += core-private gui-private platformsupport-private
-#DEFINES += QEGL_EXTRA_DEBUG
-
# Avoid X11 header collision
DEFINES += MESA_EGL_NO_X11_HEADERS
@@ -12,21 +10,15 @@ DEFINES += MESA_EGL_NO_X11_HEADERS
SOURCES += $$PWD/qeglfsintegration.cpp \
$$PWD/qeglfswindow.cpp \
- $$PWD/qeglfsbackingstore.cpp \
$$PWD/qeglfsscreen.cpp \
$$PWD/qeglfshooks_stub.cpp \
- $$PWD/qeglfscursor.cpp \
- $$PWD/qeglfscontext.cpp \
- $$PWD/qeglfscompositor.cpp
+ $$PWD/qeglfscontext.cpp
HEADERS += $$PWD/qeglfsintegration.h \
$$PWD/qeglfswindow.h \
- $$PWD/qeglfsbackingstore.h \
$$PWD/qeglfsscreen.h \
- $$PWD/qeglfscursor.h \
$$PWD/qeglfshooks.h \
- $$PWD/qeglfscontext.h \
- $$PWD/qeglfscompositor.h
+ $$PWD/qeglfscontext.h
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp b/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
deleted file mode 100644
index 03531916cf..0000000000
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
-#include "qeglfscursor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
-#include <QtGui/QOpenGLPaintDevice>
-#include <QtGui/QOpenGLShaderProgram>
-
-QT_BEGIN_NAMESPACE
-
-QEglFSBackingStore::QEglFSBackingStore(QWindow *window)
- : QPlatformBackingStore(window),
- m_window(static_cast<QEglFSWindow *>(window->handle())),
- m_texture(0)
-{
- m_window->setBackingStore(this);
-}
-
-QPaintDevice *QEglFSBackingStore::paintDevice()
-{
- return &m_image;
-}
-
-void QEglFSBackingStore::updateTexture()
-{
- glBindTexture(GL_TEXTURE_2D, m_texture);
-
- if (!m_dirty.isNull()) {
- QRegion fixed;
- QRect imageRect = m_image.rect();
- m_dirty |= imageRect;
-
- foreach (const QRect &rect, m_dirty.rects()) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
-
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
- }
-
- fixed |= r;
- }
-
- foreach (const QRect &rect, fixed.rects()) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
- if (rect.width() == imageRect.width()) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.copy(rect).constBits());
- }
- }
-
- m_dirty = QRegion();
- }
-}
-
-void QEglFSBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(window);
- Q_UNUSED(region);
- Q_UNUSED(offset);
-
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglBackingStore::flush %p", window);
-#endif
-
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
- return;
-
- m_window->create();
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
- updateTexture();
- QEglFSCompositor::instance()->schedule(rootWin->screen());
-}
-
-void QEglFSBackingStore::beginPaint(const QRegion &rgn)
-{
- m_dirty |= rgn;
-}
-
-void QEglFSBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- Q_UNUSED(staticContents);
-
- QEglFSWindow *rootWin = m_window->screen()->rootWindow();
- if (!rootWin || !rootWin->isRaster())
- return;
-
- m_image = QImage(size, QImage::Format_RGB32);
- m_window->create();
-
- rootWin->screen()->rootContext()->makeCurrent(rootWin->window());
- initializeOpenGLFunctions();
-
- if (m_texture)
- glDeleteTextures(1, &m_texture);
-
- glGenTextures(1, &m_texture);
- glBindTexture(GL_TEXTURE_2D, m_texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscompositor.cpp b/src/plugins/platforms/eglfs/qeglfscompositor.cpp
deleted file mode 100644
index 845bb5b3b5..0000000000
--- a/src/plugins/platforms/eglfs/qeglfscompositor.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, 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, Digia gives you certain additional
-** rights. These rights are described in the Digia 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.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglfscompositor.h"
-#include "qeglfswindow.h"
-#include "qeglfscontext.h"
-
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QOpenGLFramebufferObject>
-
-QT_BEGIN_NAMESPACE
-
-static QEglFSCompositor *compositor = 0;
-
-QEglFSCompositor::QEglFSCompositor()
- : m_screen(0),
- m_program(0),
- m_initialized(false)
-{
- Q_ASSERT(!compositor);
- m_updateTimer.setSingleShot(true);
- m_updateTimer.setInterval(0);
- connect(&m_updateTimer, SIGNAL(timeout()), SLOT(renderAll()));
-}
-
-QEglFSCompositor::~QEglFSCompositor()
-{
- Q_ASSERT(compositor == this);
- delete m_program;
- compositor = 0;
-}
-
-void QEglFSCompositor::schedule(QEglFSScreen *screen)
-{
- m_screen = screen;
- if (!m_updateTimer.isActive())
- m_updateTimer.start();
-}
-
-void QEglFSCompositor::renderAll()
-{
- QEglFSWindow *rootWin = m_screen->rootWindow();
- if (!rootWin)
- return;
-
- Q_ASSERT(rootWin->hasNativeWindow());
- QOpenGLContext *context = m_screen->rootContext();
- Q_ASSERT(context);
-
- context->makeCurrent(rootWin->window());
- if (!m_initialized) {
- initializeOpenGLFunctions();
- m_initialized = true;
- }
- ensureProgram();
- m_program->bind();
-
- QList<QEglFSWindow *> windows = m_screen->windows();
- for (int i = 0; i < windows.size(); ++i) {
- QEglFSWindow *window = windows.at(i);
- uint texture = window->texture();
- if (texture)
- render(window, texture, window->isRaster());
- }
-
- m_program->release();
- context->swapBuffers(rootWin->window());
-}
-
-void QEglFSCompositor::ensureProgram()
-{
- if (!m_program) {
- static const char *textureVertexProgram =
- "attribute highp vec2 vertexCoordEntry;\n"
- "attribute highp vec2 textureCoordEntry;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 0.0, 1.0);\n"
- "}\n";
-
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "uniform bool isRaster;\n"
- "void main() {\n"
- " lowp vec4 c = texture2D(texture, textureCoord);\n"
- " gl_FragColor = isRaster ? c.bgra : c.rgba;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
-
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->link();
-
- m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
- m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
- m_isRasterEntry = m_program->uniformLocation("isRaster");
- }
-}
-
-void QEglFSCompositor::render(QEglFSWindow *window, uint texture, bool raster)
-{
- const GLfloat textureCoordinates[] = {
- 0, 0,
- 1, 0,
- 1, 1,
- 0, 1
- };
-
- QRectF sr = window->screen()->geometry();
- QRect r = window->window()->geometry();
- QPoint tl = r.topLeft();
- QPoint br = r.bottomRight();
-
- GLfloat x1 = (tl.x() / sr.width()) * 2 - 1;
- GLfloat x2 = (br.x() / sr.width()) * 2 - 1;
- GLfloat y1 = ((sr.height() - tl.y()) / sr.height()) * 2 - 1;
- GLfloat y2 = ((sr.height() - br.y()) / sr.height()) * 2 - 1;
-
- if (!raster)
- qSwap(y1, y2);
-
- const GLfloat vertexCoordinates[] = {
- x1, y1,
- x2, y1,
- x2, y2,
- x1, y2
- };
-
- glViewport(0, 0, sr.width(), sr.height());
-
- glEnableVertexAttribArray(m_vertexCoordEntry);
- glEnableVertexAttribArray(m_textureCoordEntry);
-
- glVertexAttribPointer(m_vertexCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinates);
- glVertexAttribPointer(m_textureCoordEntry, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- m_program->setUniformValue(m_isRasterEntry, raster);
-
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- glDisableVertexAttribArray(m_vertexCoordEntry);
- glDisableVertexAttribArray(m_textureCoordEntry);
-}
-
-QEglFSCompositor *QEglFSCompositor::instance()
-{
- if (!compositor)
- compositor = new QEglFSCompositor;
- return compositor;
-}
-
-void QEglFSCompositor::destroy()
-{
- delete compositor;
- compositor = 0;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp
index 2c6846132d..86ceb0721b 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp
@@ -41,11 +41,12 @@
#include "qeglfscontext.h"
#include "qeglfswindow.h"
-#include "qeglfscursor.h"
#include "qeglfshooks.h"
#include "qeglfsintegration.h"
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtGui/QSurface>
#include <QtDebug>
@@ -54,31 +55,10 @@ QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
EGLDisplay display, EGLenum eglApi)
: QEGLPlatformContext(QEglFSHooks::hooks()->surfaceFormatFor(format), share, display,
- QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi),
- m_swapIntervalSet(false)
+ QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)), eglApi)
{
}
-bool QEglFSContext::makeCurrent(QPlatformSurface *surface)
-{
- bool success = QEGLPlatformContext::makeCurrent(surface);
-
- if (success && !m_swapIntervalSet) {
- m_swapIntervalSet = true;
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
- eglSwapInterval(eglDisplay(), swapInterval);
- }
-
- return success;
-}
-
EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
if (surface->surface()->surfaceClass() == QSurface::Window)
@@ -89,10 +69,10 @@ EGLSurface QEglFSContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface
void QEglFSContext::swapBuffers(QPlatformSurface *surface)
{
+ // draw the cursor
if (surface->surface()->surfaceClass() == QSurface::Window) {
- QEglFSWindow *window = static_cast<QEglFSWindow *>(surface);
- // draw the cursor
- if (QEglFSCursor *cursor = static_cast<QEglFSCursor *>(window->screen()->cursor()))
+ QPlatformWindow *window = static_cast<QPlatformWindow *>(surface);
+ if (QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(window->screen()->cursor()))
cursor->paintOnScreen();
}
@@ -101,4 +81,3 @@ void QEglFSContext::swapBuffers(QPlatformSurface *surface)
}
QT_END_NAMESPACE
-
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.h b/src/plugins/platforms/eglfs/qeglfscontext.h
index 8db340252c..22a7c67e46 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.h
+++ b/src/plugins/platforms/eglfs/qeglfscontext.h
@@ -42,7 +42,6 @@
#ifndef QEGLFSCONTEXT_H
#define QEGLFSCONTEXT_H
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
@@ -52,12 +51,8 @@ class QEglFSContext : public QEGLPlatformContext
public:
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLenum eglApi = EGL_OPENGL_ES_API);
- bool makeCurrent(QPlatformSurface *surface);
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
- void swapBuffers(QPlatformSurface *surface);
-
-private:
- bool m_swapIntervalSet;
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h
index 0251e27f96..67f4d1803d 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks.h
+++ b/src/plugins/platforms/eglfs/qeglfshooks.h
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSScreen;
class QEglFSHooks
@@ -73,7 +73,7 @@ public:
const QSurfaceFormat &format);
virtual void destroyNativeWindow(EGLNativeWindowType window);
virtual bool hasCapability(QPlatformIntegration::Capability cap) const;
- virtual QEglFSCursor *createCursor(QEglFSScreen *screen) const;
+ virtual QEGLPlatformCursor *createCursor(QPlatformScreen *screen) const;
virtual bool filterConfig(EGLDisplay display, EGLConfig config) const;
virtual void waitForVSync() const;
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index 4368f37e50..dfb766db32 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -40,15 +40,17 @@
****************************************************************************/
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtCore/QRegularExpression>
+#if defined(Q_OS_LINUX)
#include <fcntl.h>
#include <unistd.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
+#endif
-#include <private/qmath_p.h>
#include <private/qcore_unix_p.h>
QT_BEGIN_NAMESPACE
@@ -100,105 +102,12 @@ EGLNativeDisplayType QEglFSHooks::platformDisplay() const
QSizeF QEglFSHooks::physicalScreenSize() const
{
- static QSizeF size;
- if (size.isEmpty()) {
-
- // Note: in millimeters
- int width = qgetenv("QT_QPA_EGLFS_PHYSICAL_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_PHYSICAL_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
- int w = -1;
- int h = -1;
- QSize screenResolution;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- w = vinfo.width;
- h = vinfo.height;
- screenResolution = QSize(vinfo.xres, vinfo.yres);
- }
- } else {
- screenResolution = screenSize();
- }
-
- const int defaultPhysicalDpi = 100;
- size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
- size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
-
- if (w <= 0 || h <= 0) {
- qWarning("EGLFS: Unable to query physical screen size, defaulting to %d dpi.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH "
- "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).",
- defaultPhysicalDpi);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setWidth(height);
- }
- return size;
+ return q_physicalScreenSizeFromFb(framebuffer, screenSize());
}
QSize QEglFSHooks::screenSize() const
{
- static QSize size;
-
- if (size.isEmpty()) {
- int width = qgetenv("QT_QPA_EGLFS_WIDTH").toInt();
- int height = qgetenv("QT_QPA_EGLFS_HEIGHT").toInt();
-
- if (width && height) {
- // no need to read fb0
- size.setWidth(width);
- size.setHeight(height);
- return size;
- }
-
- struct fb_var_screeninfo vinfo;
-
- int xres = -1;
- int yres = -1;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1) {
- qWarning("EGLFS: Could not query variable screen info.");
- } else {
- xres = vinfo.xres;
- yres = vinfo.yres;
- }
- }
-
- const int defaultWidth = 800;
- const int defaultHeight = 600;
- size.setWidth(xres <= 0 ? defaultWidth : xres);
- size.setHeight(yres <= 0 ? defaultHeight : yres);
-
- if (xres <= 0 || yres <= 0) {
- qWarning("EGLFS: Unable to query screen resolution, defaulting to %dx%d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_WIDTH and QT_QPA_EGLFS_HEIGHT.",
- defaultWidth, defaultHeight);
- }
-
- // override fb0 from environment var setting
- if (width)
- size.setWidth(width);
- if (height)
- size.setHeight(height);
- }
-
- return size;
+ return q_screenSizeFromFb(framebuffer);
}
QDpi QEglFSHooks::logicalDpi() const
@@ -222,29 +131,7 @@ Qt::ScreenOrientation QEglFSHooks::orientation() const
int QEglFSHooks::screenDepth() const
{
- static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
-
- if (depth == 0) {
- struct fb_var_screeninfo vinfo;
-
- if (framebuffer != -1) {
- if (ioctl(framebuffer, FBIOGET_VSCREENINFO, &vinfo) == -1)
- qWarning("EGLFS: Could not query variable screen info.");
- else
- depth = vinfo.bits_per_pixel;
- }
-
- const int defaultDepth = 32;
-
- if (depth <= 0) {
- depth = defaultDepth;
-
- qWarning("EGLFS: Unable to query screen depth, defaulting to %d.\n"
- "EGLFS: To override, set QT_QPA_EGLFS_DEPTH.", defaultDepth);
- }
- }
-
- return depth;
+ return q_screenDepthFromFb(framebuffer);
}
QImage::Format QEglFSHooks::screenFormat() const
@@ -283,9 +170,9 @@ bool QEglFSHooks::hasCapability(QPlatformIntegration::Capability cap) const
return false;
}
-QEglFSCursor *QEglFSHooks::createCursor(QEglFSScreen *screen) const
+QEGLPlatformCursor *QEglFSHooks::createCursor(QPlatformScreen *screen) const
{
- return new QEglFSCursor(screen);
+ return new QEGLPlatformCursor(screen);
}
void QEglFSHooks::waitForVSync() const
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
index d6832493f1..2941806f17 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
@@ -42,25 +42,15 @@
#include "qeglfsintegration.h"
#include "qeglfswindow.h"
-#include "qeglfsbackingstore.h"
-#include "qeglfscompositor.h"
#include "qeglfshooks.h"
+#include "qeglfscontext.h"
#include <QtGui/private/qguiapplication_p.h>
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
#include <QtPlatformSupport/private/qeglpbuffer_p.h>
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
-#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
-#include <QtPlatformSupport/private/qevdevtouch_p.h>
-#endif
-
#include <qpa/qplatformwindow.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QOpenGLContext>
@@ -68,10 +58,6 @@
#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformcursor.h>
-#include <qpa/qplatforminputcontextfactory_p.h>
-
-#include "qeglfscontext.h"
-
#include <EGL/egl.h>
static void initResources()
@@ -82,10 +68,6 @@ static void initResources()
QT_BEGIN_NAMESPACE
QEglFSIntegration::QEglFSIntegration()
- : mFontDb(new QGenericUnixFontDatabase)
- , mServices(new QGenericUnixServices)
- , mScreen(0)
- , mInputContext(0)
{
mDisableInputHandlers = qgetenv("QT_QPA_EGLFS_DISABLE_INPUT").toInt();
@@ -94,9 +76,6 @@ QEglFSIntegration::QEglFSIntegration()
QEglFSIntegration::~QEglFSIntegration()
{
- QEglFSCompositor::destroy();
- delete mScreen;
- eglTerminate(mDisplay);
QEglFSHooks::hooks()->platformDestroy();
}
@@ -106,85 +85,46 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
if (QEglFSHooks::hooks() && QEglFSHooks::hooks()->hasCapability(cap))
return true;
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return true;
- case WindowManagement: return false;
- default: return QPlatformIntegration::hasCapability(cap);
- }
+ return QEGLPlatformIntegration::hasCapability(cap);
}
-QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
+void QEglFSIntegration::initialize()
{
- QWindowSystemInterface::flushWindowSystemEvents();
- QEglFSWindow *w = new QEglFSWindow(window);
- w->create();
- if (window->type() != Qt::ToolTip)
- w->requestActivateWindow();
- return w;
-}
+ QEglFSHooks::hooks()->platformInit();
-QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
-{
- return new QEglFSBackingStore(window);
-}
+ QEGLPlatformIntegration::initialize();
-QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
-{
- return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(context->format()), context->shareHandle(), mDisplay);
+ if (!mDisableInputHandlers)
+ createInputHandlers();
}
-QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+EGLNativeDisplayType QEglFSIntegration::nativeDisplay() const
{
- QEglFSScreen *screen = static_cast<QEglFSScreen *>(surface->screen()->handle());
- return new QEGLPbuffer(screen->display(), QEglFSHooks::hooks()->surfaceFormatFor(surface->requestedFormat()), surface);
+ return QEglFSHooks::hooks()->platformDisplay();
}
-QPlatformFontDatabase *QEglFSIntegration::fontDatabase() const
+QEGLPlatformScreen *QEglFSIntegration::createScreen() const
{
- return mFontDb.data();
+ return new QEglFSScreen(display());
}
-QAbstractEventDispatcher *QEglFSIntegration::createEventDispatcher() const
+QEGLPlatformWindow *QEglFSIntegration::createWindow(QWindow *window) const
{
- return createUnixEventDispatcher();
+ return new QEglFSWindow(window);
}
-void QEglFSIntegration::initialize()
+QEGLPlatformContext *QEglFSIntegration::createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const
{
- QEglFSHooks::hooks()->platformInit();
-
- EGLint major, minor;
-
- if (!eglBindAPI(EGL_OPENGL_ES_API)) {
- qWarning("Could not bind GL_ES API\n");
- qFatal("EGL error");
- }
-
- mDisplay = eglGetDisplay(QEglFSHooks::hooks() ? QEglFSHooks::hooks()->platformDisplay() : EGL_DEFAULT_DISPLAY);
- if (mDisplay == EGL_NO_DISPLAY) {
- qWarning("Could not open egl display\n");
- qFatal("EGL error");
- }
-
- if (!eglInitialize(mDisplay, &major, &minor)) {
- qWarning("Could not initialize egl display\n");
- qFatal("EGL error");
- }
-
- mScreen = createScreen();
- screenAdded(mScreen);
-
- mInputContext = QPlatformInputContextFactory::create();
-
- if (!mDisableInputHandlers)
- createInputHandlers();
+ return new QEglFSContext(QEglFSHooks::hooks()->surfaceFormatFor(format), shareContext, display);
}
-QEglFSScreen *QEglFSIntegration::createScreen() const
+QPlatformOffscreenSurface *QEglFSIntegration::createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const
{
- return new QEglFSScreen(mDisplay);
+ return new QEGLPbuffer(display, QEglFSHooks::hooks()->surfaceFormatFor(format), surface);
}
QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
@@ -192,115 +132,12 @@ QVariant QEglFSIntegration::styleHint(QPlatformIntegration::StyleHint hint) cons
switch (hint)
{
case QPlatformIntegration::ShowIsFullScreen:
- return mScreen->rootWindow() == 0;
+ return screen()->compositingWindow() == 0;
default:
return QPlatformIntegration::styleHint(hint);
}
}
-QPlatformServices *QEglFSIntegration::services() const
-{
- return mServices.data();
-}
-
-QPlatformNativeInterface *QEglFSIntegration::nativeInterface() const
-{
- return const_cast<QEglFSIntegration *>(this);
-}
-
-enum ResourceType {
- EglDisplay,
- EglWindow,
- EglContext
-};
-
-static int resourceType(const QByteArray &key)
-{
- static const QByteArray names[] = { // match ResourceType
- QByteArrayLiteral("egldisplay"),
- QByteArrayLiteral("eglwindow"),
- QByteArrayLiteral("eglcontext")
- };
- const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
- const QByteArray *result = std::find(names, end, key);
- if (result == end)
- result = std::find(names, end, key.toLower());
- return int(result - names);
-}
-
-void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- result = mScreen->display();
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- if (window && window->handle())
- result = static_cast<QEglFSScreen *>(window->handle()->screen())->display();
- else
- result = mScreen->display();
- break;
- case EglWindow:
- if (window && window->handle())
- result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow());
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglContext:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static void *eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
- if (!handle)
- return 0;
-
- return handle->eglContext();
-}
-
-QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context")
- return NativeResourceForContextFunction(eglContextForContext);
-
- return 0;
-}
-
EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceFormat &format)
{
class Chooser : public QEglConfigChooser {
@@ -326,13 +163,4 @@ EGLConfig QEglFSIntegration::chooseConfig(EGLDisplay display, const QSurfaceForm
return chooser.chooseConfig();
}
-void QEglFSIntegration::createInputHandlers()
-{
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
- new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
- new QEvdevTouchScreenHandlerThread(QString() /* spec */, this);
-#endif
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.h b/src/plugins/platforms/eglfs/qeglfsintegration.h
index 12c8158bd1..99dda1ea96 100644
--- a/src/plugins/platforms/eglfs/qeglfsintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsintegration.h
@@ -42,61 +42,37 @@
#ifndef QEGLFSINTEGRATION_H
#define QEGLFSINTEGRATION_H
-#include "qeglfsscreen.h"
-
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
+#include <QtPlatformSupport/private/qeglplatformintegration_p.h>
#include <qpa/qplatformscreen.h>
+#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
-class QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
+class QEglFSIntegration : public QEGLPlatformIntegration
{
public:
QEglFSIntegration();
~QEglFSIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
-
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
- QPlatformNativeInterface *nativeInterface() const;
-
- QPlatformFontDatabase *fontDatabase() const;
- QPlatformServices *services() const;
-
- QAbstractEventDispatcher *createEventDispatcher() const;
- void initialize();
-
- QVariant styleHint(QPlatformIntegration::StyleHint hint) const;
+ void initialize() Q_DECL_OVERRIDE;
- // QPlatformNativeInterface
- void *nativeResourceForIntegration(const QByteArray &resource);
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ QVariant styleHint(QPlatformIntegration::StyleHint hint) const Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- QPlatformScreen *screen() const { return mScreen; }
static EGLConfig chooseConfig(EGLDisplay display, const QSurfaceFormat &format);
- EGLDisplay display() const { return mDisplay; }
-
- QPlatformInputContext *inputContext() const { return mInputContext; }
-
protected:
- virtual QEglFSScreen *createScreen() const;
+ QEGLPlatformScreen *createScreen() const Q_DECL_OVERRIDE;
+ QEGLPlatformWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QEGLPlatformContext *createContext(const QSurfaceFormat &format,
+ QPlatformOpenGLContext *shareContext,
+ EGLDisplay display) const Q_DECL_OVERRIDE;
+ QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
+ const QSurfaceFormat &format,
+ QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
+ EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
private:
- void createInputHandlers();
-
- EGLDisplay mDisplay;
- QScopedPointer<QPlatformFontDatabase> mFontDb;
- QScopedPointer<QPlatformServices> mServices;
- QEglFSScreen *mScreen;
- QPlatformInputContext *mInputContext;
bool mDisableInputHandlers;
};
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 758b461b3f..31f6ac5be6 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -39,39 +39,21 @@
**
****************************************************************************/
-#include "qeglfscursor.h"
#include "qeglfsscreen.h"
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qdevicediscovery_p.h>
-#endif
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
QT_BEGIN_NAMESPACE
QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
- : m_dpy(dpy),
+ : QEGLPlatformScreen(dpy),
m_surface(EGL_NO_SURFACE),
m_cursor(0),
+ m_rootWindow(0),
m_rootContext(0)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglScreen %p\n", this);
-#endif
-
- QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
- bool hideCursor = false;
- if (hideCursorVal.isEmpty()) {
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- QScopedPointer<QDeviceDiscovery> dis(QDeviceDiscovery::create(QDeviceDiscovery::Device_Mouse));
- hideCursor = dis->scanConnectedDevices().isEmpty();
-#endif
- } else {
- hideCursor = hideCursorVal.toInt() != 0;
- }
- if (!hideCursor)
- m_cursor = QEglFSHooks::hooks()->createCursor(this);
+ m_cursor = QEglFSHooks::hooks()->createCursor(this);
}
QEglFSScreen::~QEglFSScreen()
@@ -124,50 +106,4 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
m_surface = surface;
}
-void QEglFSScreen::addWindow(QEglFSWindow *window)
-{
- if (!m_windows.contains(window)) {
- m_windows.append(window);
- topWindowChanged(window);
- }
-}
-
-void QEglFSScreen::removeWindow(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- if (!m_windows.isEmpty())
- topWindowChanged(m_windows.last());
-}
-
-void QEglFSScreen::moveToTop(QEglFSWindow *window)
-{
- m_windows.removeOne(window);
- m_windows.append(window);
- topWindowChanged(window);
-}
-
-void QEglFSScreen::changeWindowIndex(QEglFSWindow *window, int newIdx)
-{
- int idx = m_windows.indexOf(window);
- if (idx != -1 && idx != newIdx) {
- m_windows.move(idx, newIdx);
- if (newIdx == m_windows.size() - 1)
- topWindowChanged(m_windows.last());
- }
-}
-
-QEglFSWindow *QEglFSScreen::rootWindow()
-{
- Q_FOREACH (QEglFSWindow *window, m_windows) {
- if (window->hasNativeWindow())
- return window;
- }
- return 0;
-}
-
-void QEglFSScreen::topWindowChanged(QPlatformWindow *window)
-{
- Q_UNUSED(window);
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 11d66b7e0f..13f7cfddd8 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -42,7 +42,7 @@
#ifndef QEGLFSSCREEN_H
#define QEGLFSSCREEN_H
-#include <qpa/qplatformscreen.h>
+#include <QtPlatformSupport/private/qeglplatformscreen_p.h>
#include <QtCore/QTextStream>
@@ -50,52 +50,48 @@
QT_BEGIN_NAMESPACE
-class QEglFSCursor;
+class QEGLPlatformCursor;
class QEglFSWindow;
class QOpenGLContext;
-class QEglFSScreen : public QPlatformScreen
+class QEglFSScreen : public QEGLPlatformScreen
{
public:
QEglFSScreen(EGLDisplay display);
~QEglFSScreen();
- QRect geometry() const;
- int depth() const;
- QImage::Format format() const;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ int depth() const Q_DECL_OVERRIDE;
+ QImage::Format format() const Q_DECL_OVERRIDE;
- QSizeF physicalSize() const;
- QDpi logicalDpi() const;
- Qt::ScreenOrientation nativeOrientation() const;
- Qt::ScreenOrientation orientation() const;
+ QSizeF physicalSize() const Q_DECL_OVERRIDE;
+ QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
+ Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
- QPlatformCursor *cursor() const;
+ QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
- EGLDisplay display() const { return m_dpy; }
EGLSurface primarySurface() const { return m_surface; }
- QList<QEglFSWindow *> windows() const { return m_windows; }
- void addWindow(QEglFSWindow *window);
- void removeWindow(QEglFSWindow *window);
- void moveToTop(QEglFSWindow *window);
- void changeWindowIndex(QEglFSWindow *window, int newIdx);
- QEglFSWindow *rootWindow();
- QOpenGLContext *rootContext() { return m_rootContext; }
+ QEGLPlatformWindow *compositingWindow() Q_DECL_OVERRIDE { return m_rootWindow; }
+ QOpenGLContext *compositingContext() Q_DECL_OVERRIDE { return m_rootContext; }
+
+ void setRootWindow(QEGLPlatformWindow *window) { m_rootWindow = window; }
void setRootContext(QOpenGLContext *context) { m_rootContext = context; }
protected:
void setPrimarySurface(EGLSurface surface);
- virtual void topWindowChanged(QPlatformWindow *window);
private:
friend class QEglFSWindow;
EGLDisplay m_dpy;
EGLSurface m_surface;
- QEglFSCursor *m_cursor;
- QList<QEglFSWindow *> m_windows;
+ QEGLPlatformCursor *m_cursor;
+ QEGLPlatformWindow *m_rootWindow;
QOpenGLContext *m_rootContext;
};
QT_END_NAMESPACE
+
#endif // QEGLFSSCREEN_H
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp
index bba00da128..2d36c0b58e 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp
@@ -41,13 +41,11 @@
#include "qeglfswindow.h"
#include "qeglfshooks.h"
-#include "qeglfscursor.h"
-#include "qeglfsbackingstore.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
#include <QtGui/QOpenGLContext>
-
+#include <QtPlatformSupport/private/qeglplatformcursor_p.h>
#include <QtPlatformSupport/private/qeglconvenience_p.h>
#include <QtDebug>
@@ -55,16 +53,11 @@
QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
- : QPlatformWindow(w)
+ : QEGLPlatformWindow(w)
, m_surface(0)
, m_window(0)
- , m_wid(0)
- , m_backingStore(0)
, m_flags(0)
{
-#ifdef QEGL_EXTRA_DEBUG
- qWarning("QEglWindow %p: %p 0x%x\n", this, w, uint(m_window));
-#endif
}
QEglFSWindow::~QEglFSWindow()
@@ -72,41 +65,24 @@ QEglFSWindow::~QEglFSWindow()
destroy();
}
-static WId newWId()
-{
- static WId id = 0;
-
- if (id == std::numeric_limits<WId>::max())
- qWarning("EGLFS: Out of window IDs");
-
- return ++id;
-}
-
void QEglFSWindow::create()
{
if (m_flags.testFlag(Created))
return;
+ QEGLPlatformWindow::create();
+
m_flags = Created;
- m_wid = newWId();
- if (window()->type() == Qt::Desktop) {
- QRect rect(QPoint(), QEglFSHooks::hooks()->screenSize());
- QPlatformWindow::setGeometry(rect);
- QWindowSystemInterface::handleGeometryChange(window(), rect);
+ if (window()->type() == Qt::Desktop)
return;
- }
-
- // Save the original surface type before changing to OpenGLSurface.
- if (window()->surfaceType() == QSurface::RasterSurface)
- m_flags |= IsRaster;
// Stop if there is already a window backed by a native window and surface. Additional
// raster windows will not have their own native window, surface and context. Instead,
// they will be composited onto the root window's surface.
QEglFSScreen *screen = this->screen();
if (screen->primarySurface() != EGL_NO_SURFACE) {
- if (m_flags.testFlag(IsRaster) && screen->rootWindow()->m_flags.testFlag(IsRaster))
+ if (isRaster() && screen->compositingWindow())
return;
#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK)
@@ -118,7 +94,6 @@ void QEglFSWindow::create()
return;
}
- window()->setSurfaceType(QSurface::OpenGLSurface);
m_flags |= HasNativeWindow;
setGeometry(QRect()); // will become fullscreen
QWindowSystemInterface::handleExposeEvent(window(), geometry());
@@ -126,18 +101,20 @@ void QEglFSWindow::create()
EGLDisplay display = static_cast<QEglFSScreen *>(screen)->display();
QSurfaceFormat platformFormat = QEglFSHooks::hooks()->surfaceFormatFor(window()->requestedFormat());
m_config = QEglFSIntegration::chooseConfig(display, platformFormat);
- m_format = q_glFormatFromConfig(display, m_config);
+ m_format = q_glFormatFromConfig(display, m_config, platformFormat);
resetSurface();
screen->setPrimarySurface(m_surface);
- if (m_flags.testFlag(IsRaster)) {
+ if (isRaster()) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setFormat(window()->requestedFormat());
context->setScreen(window()->screen());
- context->create();
+ if (!context->create())
+ qFatal("EGLFS: Failed to create compositing context");
screen->setRootContext(context);
+ screen->setRootWindow(this);
}
}
@@ -145,7 +122,7 @@ void QEglFSWindow::destroy()
{
QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
- QEglFSCursor *cursor = static_cast<QEglFSCursor *>(screen->cursor());
+ QEGLPlatformCursor *cursor = static_cast<QEGLPlatformCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
@@ -188,7 +165,7 @@ void QEglFSWindow::resetSurface()
void QEglFSWindow::setVisible(bool visible)
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop) {
if (visible) {
@@ -234,11 +211,6 @@ QRect QEglFSWindow::geometry() const
return QPlatformWindow::geometry();
}
-WId QEglFSWindow::winId() const
-{
- return m_wid;
-}
-
void QEglFSWindow::requestActivateWindow()
{
if (window()->type() != Qt::Desktop)
@@ -258,7 +230,7 @@ void QEglFSWindow::raise()
void QEglFSWindow::lower()
{
- QList<QEglFSWindow *> windows = screen()->windows();
+ QList<QEGLPlatformWindow *> windows = screen()->windows();
if (window()->type() != Qt::Desktop && windows.count() > 1) {
int idx = windows.indexOf(this);
if (idx > 0) {
@@ -288,12 +260,4 @@ QEglFSScreen *QEglFSWindow::screen() const
return static_cast<QEglFSScreen *>(QPlatformWindow::screen());
}
-uint QEglFSWindow::texture() const
-{
- if (m_backingStore)
- return m_backingStore->texture();
-
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index ee3c194a7c..f93a9d54bc 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -45,42 +45,32 @@
#include "qeglfsintegration.h"
#include "qeglfsscreen.h"
-#include <qpa/qplatformwindow.h>
+#include <QtPlatformSupport/private/qeglplatformwindow_p.h>
QT_BEGIN_NAMESPACE
-class QEglFSBackingStore;
-
-class QEglFSWindow : public QPlatformWindow
+class QEglFSWindow : public QEGLPlatformWindow
{
public:
QEglFSWindow(QWindow *w);
~QEglFSWindow();
- void setGeometry(const QRect &);
- QRect geometry() const;
- WId winId() const;
- void setVisible(bool visible);
- void requestActivateWindow();
- void raise();
- void lower();
+ void create() Q_DECL_OVERRIDE;
+ void destroy();
+
+ void setGeometry(const QRect &) Q_DECL_OVERRIDE;
+ QRect geometry() const Q_DECL_OVERRIDE;
+ void setVisible(bool visible) Q_DECL_OVERRIDE;
+ void requestActivateWindow() Q_DECL_OVERRIDE;
+ void raise() Q_DECL_OVERRIDE;
+ void lower() Q_DECL_OVERRIDE;
+ QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ EGLNativeWindowType eglWindow() const Q_DECL_OVERRIDE;
EGLSurface surface() const;
- QSurfaceFormat format() const;
- EGLNativeWindowType eglWindow() const;
-
QEglFSScreen *screen() const;
- void create();
- void destroy();
-
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
- bool isRaster() const { return m_flags.testFlag(IsRaster); }
-
- QEglFSBackingStore *backingStore() { return m_backingStore; }
- void setBackingStore(QEglFSBackingStore *backingStore) { m_backingStore = backingStore; }
-
- uint texture() const;
virtual void invalidateSurface();
virtual void resetSurface();
@@ -92,13 +82,10 @@ protected:
private:
EGLConfig m_config;
QSurfaceFormat m_format;
- WId m_wid;
- QEglFSBackingStore *m_backingStore;
enum Flag {
Created = 0x01,
- IsRaster = 0x02,
- HasNativeWindow = 0x04
+ HasNativeWindow = 0x02
};
Q_DECLARE_FLAGS(Flags, Flag);
Flags m_flags;
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index 72716e6a4c..175cc3f8bd 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -36,6 +36,8 @@ HEADERS = \
qiosinputcontext.h \
qiostheme.h \
qiosglobal.h \
- qiosservices.h
+ qiosservices.h \
+ quiview.h
-#HEADERS = qiossoftwareinputhandler.h
+OTHER_FILES = \
+ quiview_textinput.mm
diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm
index 8dd690f301..2ce064582e 100644
--- a/src/plugins/platforms/ios/qiosglobal.mm
+++ b/src/plugins/platforms/ios/qiosglobal.mm
@@ -86,10 +86,10 @@ Qt::ScreenOrientation toQtScreenOrientation(UIDeviceOrientation uiDeviceOrientat
qtOrientation = Qt::InvertedPortraitOrientation;
break;
case UIDeviceOrientationLandscapeLeft:
- qtOrientation = Qt::InvertedLandscapeOrientation;
+ qtOrientation = Qt::LandscapeOrientation;
break;
case UIDeviceOrientationLandscapeRight:
- qtOrientation = Qt::LandscapeOrientation;
+ qtOrientation = Qt::InvertedLandscapeOrientation;
break;
case UIDeviceOrientationFaceUp:
case UIDeviceOrientationFaceDown:
@@ -108,10 +108,10 @@ UIDeviceOrientation fromQtScreenOrientation(Qt::ScreenOrientation qtOrientation)
UIDeviceOrientation uiOrientation;
switch (qtOrientation) {
case Qt::LandscapeOrientation:
- uiOrientation = UIDeviceOrientationLandscapeRight;
+ uiOrientation = UIDeviceOrientationLandscapeLeft;
break;
case Qt::InvertedLandscapeOrientation:
- uiOrientation = UIDeviceOrientationLandscapeLeft;
+ uiOrientation = UIDeviceOrientationLandscapeRight;
break;
case Qt::InvertedPortraitOrientation:
uiOrientation = UIDeviceOrientationPortraitUpsideDown;
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index 533ba686e1..13255ada56 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -50,6 +50,7 @@
QT_BEGIN_NAMESPACE
@class QIOSKeyboardListener;
+@class QUIView;
class QIOSInputContext : public QPlatformInputContext
{
@@ -64,14 +65,18 @@ public:
void setFocusObject(QObject *object);
void focusWindowChanged(QWindow *focusWindow);
- void scrollRootView();
+ void cursorRectangleChanged();
+ void scrollToCursor();
+ void scroll(int y);
+
+ void update(Qt::InputMethodQueries);
+ void reset();
+ void commit();
private:
QIOSKeyboardListener *m_keyboardListener;
- UIView<UIKeyInput> *m_focusView;
- QTransform m_inputItemTransform;
+ QUIView *m_focusView;
bool m_hasPendingHideRequest;
- bool m_inSetFocusObject;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 39a22f367e..d426028c46 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -42,6 +42,7 @@
#include "qiosglobal.h"
#include "qiosinputcontext.h"
#include "qioswindow.h"
+#include "quiview.h"
#include <QGuiApplication>
@interface QIOSKeyboardListener : NSObject {
@@ -49,6 +50,7 @@
QIOSInputContext *m_context;
BOOL m_keyboardVisible;
BOOL m_keyboardVisibleAndDocked;
+ BOOL m_ignoreKeyboardChanges;
QRectF m_keyboardRect;
QRectF m_keyboardEndRect;
NSTimeInterval m_duration;
@@ -66,6 +68,7 @@
m_context = context;
m_keyboardVisible = NO;
m_keyboardVisibleAndDocked = NO;
+ m_ignoreKeyboardChanges = NO;
m_duration = 0;
m_curve = UIViewAnimationCurveEaseOut;
m_viewController = 0;
@@ -128,6 +131,8 @@
- (void) keyboardDidChangeFrame:(NSNotification *)notification
{
+ if (m_ignoreKeyboardChanges)
+ return;
m_keyboardRect = [self getKeyboardRect:notification];
m_context->emitKeyboardRectChanged();
@@ -140,11 +145,13 @@
// If the keyboard was visible and docked from before, this is just a geometry
// change (normally caused by an orientation change). In that case, update scroll:
if (m_keyboardVisibleAndDocked)
- m_context->scrollRootView();
+ m_context->scrollToCursor();
}
- (void) keyboardWillShow:(NSNotification *)notification
{
+ if (m_ignoreKeyboardChanges)
+ return;
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
m_keyboardVisibleAndDocked = YES;
m_keyboardEndRect = [self getKeyboardRect:notification];
@@ -152,15 +159,17 @@
m_duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
m_curve = UIViewAnimationCurve([notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16);
}
- m_context->scrollRootView();
+ m_context->scrollToCursor();
}
- (void) keyboardWillHide:(NSNotification *)notification
{
+ if (m_ignoreKeyboardChanges)
+ return;
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
m_keyboardEndRect = [self getKeyboardRect:notification];
- m_context->scrollRootView();
+ m_context->scroll(0);
}
@end
@@ -170,10 +179,9 @@ QIOSInputContext::QIOSInputContext()
, m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_focusView(0)
, m_hasPendingHideRequest(false)
- , m_inSetFocusObject(false)
{
if (isQtApplication())
- connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::scrollRootView);
+ connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::cursorRectangleChanged);
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged);
}
@@ -216,76 +224,99 @@ bool QIOSInputContext::isInputPanelVisible() const
return m_keyboardListener->m_keyboardVisible;
}
-void QIOSInputContext::setFocusObject(QObject *)
+void QIOSInputContext::setFocusObject(QObject *focusObject)
{
- m_inputItemTransform = qApp->inputMethod()->inputItemTransform();
-
- if (!m_focusView || !m_focusView.isFirstResponder)
+ if (!focusObject || !m_focusView || !m_focusView.isFirstResponder) {
+ scroll(0);
return;
+ }
- // Since m_focusView is the first responder, it means that the keyboard is open and we
- // should update keyboard layout. But there seem to be no way to tell it to reread the
- // UITextInputTraits from m_focusView. To work around that, we quickly resign first
- // responder status just to reassign it again. To not remove the focusObject in the same
- // go, we need to call the super implementation of resignFirstResponder. Since the call
- // will cause a 'keyboardWillHide' notification to be sendt, we also block scrollRootView
- // to avoid artifacts:
- m_inSetFocusObject = true;
- SEL sel = @selector(resignFirstResponder);
- [[m_focusView superclass] instanceMethodForSelector:sel](m_focusView, sel);
- m_inSetFocusObject = false;
- [m_focusView becomeFirstResponder];
+ reset();
+
+ if (m_keyboardListener->m_keyboardVisibleAndDocked)
+ scrollToCursor();
}
void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
{
- UIView<UIKeyInput> *view = reinterpret_cast<UIView<UIKeyInput> *>(focusWindow->handle()->winId());
+ QUIView *view = focusWindow ? reinterpret_cast<QUIView *>(focusWindow->handle()->winId()) : 0;
if ([m_focusView isFirstResponder])
[view becomeFirstResponder];
[m_focusView release];
m_focusView = [view retain];
+
+ if (view.window != m_keyboardListener->m_viewController.view)
+ scroll(0);
}
-void QIOSInputContext::scrollRootView()
+void QIOSInputContext::cursorRectangleChanged()
{
- // Scroll the root view (screen) if:
- // - our backend controls the root view controller on the main screen (no hybrid app)
- // - the focus object is on the same screen as the keyboard.
- // - the first responder is a QUIView, and not some other foreign UIView.
- // - the keyboard is docked. Otherwise the user can move the keyboard instead.
- // - the inputItem has not been moved/scrolled
- if (!isQtApplication() || !m_focusView || m_inSetFocusObject)
+ if (!m_keyboardListener->m_keyboardVisibleAndDocked)
return;
- if (m_inputItemTransform != qApp->inputMethod()->inputItemTransform()) {
- // The inputItem has moved since the last scroll update. To avoid competing
- // with the application where the cursor/inputItem should be, we bail:
+ // Check if the cursor has changed position inside the input item. Since
+ // qApp->inputMethod()->cursorRectangle() will also change when the input item
+ // itself moves, we need to ask the focus object for ImCursorRectangle:
+ static QPoint prevCursor;
+ QInputMethodQueryEvent queryEvent(Qt::ImCursorRectangle);
+ QCoreApplication::sendEvent(qApp->focusObject(), &queryEvent);
+ QPoint cursor = queryEvent.value(Qt::ImCursorRectangle).toRect().topLeft();
+ if (cursor != prevCursor)
+ scrollToCursor();
+ prevCursor = cursor;
+}
+
+void QIOSInputContext::scrollToCursor()
+{
+ if (!isQtApplication() || !m_focusView)
return;
- }
UIView *view = m_keyboardListener->m_viewController.view;
- qreal scrollTo = 0;
-
- if (m_focusView.isFirstResponder
- && m_keyboardListener->m_keyboardVisibleAndDocked
- && m_focusView.window == view.window) {
- QRectF cursorRect = qGuiApp->inputMethod()->cursorRectangle();
- cursorRect.translate(m_focusView.qwindow->geometry().topLeft());
- qreal keyboardY = m_keyboardListener->m_keyboardEndRect.y();
- int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
- const int margin = 20;
-
- if (cursorRect.bottomLeft().y() > keyboardY - margin)
- scrollTo = qMin(view.bounds.size.height - keyboardY, cursorRect.y() - statusBarY - margin);
- }
+ if (view.window != m_focusView.window)
+ return;
- if (scrollTo != view.bounds.origin.y) {
- // Scroll the view the same way a UIScrollView works: by changing bounds.origin:
- CGRect newBounds = view.bounds;
- newBounds.origin.y = scrollTo;
- [UIView animateWithDuration:m_keyboardListener->m_duration delay:0
- options:m_keyboardListener->m_curve
- animations:^{ view.bounds = newBounds; }
- completion:0];
- }
+ const int margin = 20;
+ QRectF translatedCursorPos = qApp->inputMethod()->cursorRectangle();
+ translatedCursorPos.translate(m_focusView.qwindow->geometry().topLeft());
+ qreal keyboardY = m_keyboardListener->m_keyboardEndRect.y();
+ int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
+
+ scroll((translatedCursorPos.bottomLeft().y() < keyboardY - margin) ? 0
+ : qMin(view.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
}
+
+void QIOSInputContext::scroll(int y)
+{
+ // Scroll the view the same way a UIScrollView
+ // works: by changing bounds.origin:
+ UIView *view = m_keyboardListener->m_viewController.view;
+ if (y == view.bounds.origin.y)
+ return;
+
+ CGRect newBounds = view.bounds;
+ newBounds.origin.y = y;
+ [UIView animateWithDuration:m_keyboardListener->m_duration delay:0
+ options:m_keyboardListener->m_curve
+ animations:^{ view.bounds = newBounds; }
+ completion:0];
+}
+
+void QIOSInputContext::update(Qt::InputMethodQueries query)
+{
+ [m_focusView updateInputMethodWithQuery:query];
+}
+
+void QIOSInputContext::reset()
+{
+ // Since the call to reset will cause a 'keyboardWillHide'
+ // notification to be sendt, we block keyboard nofifications to avoid artifacts:
+ m_keyboardListener->m_ignoreKeyboardChanges = true;
+ [m_focusView reset];
+ m_keyboardListener->m_ignoreKeyboardChanges = false;
+}
+
+void QIOSInputContext::commit()
+{
+ [m_focusView commit];
+}
+
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index 0a6a00b753..2fe679fc20 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -44,6 +44,9 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QWindow>
#include <QtGui/QScreen>
+
+#include <QtGui/private/qwindow_p.h>
+
#include "qiosscreen.h"
#include "qiosglobal.h"
#include "qioswindow.h"
@@ -105,11 +108,10 @@
if (hiddenFromPlist)
return YES;
QWindow *focusWindow = QGuiApplication::focusWindow();
- if (!focusWindow || !focusWindow->handle())
+ if (!focusWindow)
return [UIApplication sharedApplication].statusBarHidden;
- QWindow *topLevel = static_cast<QIOSWindow *>(focusWindow->handle())->topLevelWindow();
- return topLevel->windowState() == Qt::WindowFullScreen;
+ return qt_window_private(focusWindow)->topLevelWindow()->windowState() == Qt::WindowFullScreen;
}
@end
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 8a5eb589d2..fc99543aa6 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -87,8 +87,6 @@ public:
WId winId() const { return WId(m_view); };
- QWindow *topLevelWindow() const;
-
private:
void applyGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 7a0ff055ec..7d5c507972 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -41,6 +41,7 @@
#include "qiosglobal.h"
#include "qioswindow.h"
+#include "quiview.h"
#include "qioscontext.h"
#include "qiosinputcontext.h"
#include "qiosscreen.h"
@@ -58,33 +59,19 @@
#include <QtDebug>
-@interface QUIView : UIView <UIKeyInput>
-{
-@public
- UITextAutocapitalizationType autocapitalizationType;
- UITextAutocorrectionType autocorrectionType;
- BOOL enablesReturnKeyAutomatically;
- UIKeyboardAppearance keyboardAppearance;
- UIKeyboardType keyboardType;
- UIReturnKeyType returnKeyType;
- BOOL secureTextEntry;
- QIOSWindow *m_qioswindow;
- QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
- int m_nextTouchId;
-}
-
-@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
-@property(nonatomic) UITextAutocorrectionType autocorrectionType;
-@property(nonatomic) BOOL enablesReturnKeyAutomatically;
-@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
-@property(nonatomic) UIKeyboardType keyboardType;
-@property(nonatomic) UIReturnKeyType returnKeyType;
-@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
-
-@end
+// Include category as an alternative to using -ObjC (Apple QA1490)
+#include "quiview_textinput.mm"
@implementation QUIView
+@synthesize autocapitalizationType;
+@synthesize autocorrectionType;
+@synthesize enablesReturnKeyAutomatically;
+@synthesize keyboardAppearance;
+@synthesize keyboardType;
+@synthesize returnKeyType;
+@synthesize secureTextEntry;
+
+ (Class)layerClass
{
return [CAEAGLLayer class];
@@ -112,6 +99,7 @@
self.hidden = YES;
self.multipleTouchEnabled = YES;
+ m_inSendEventToFocusObject = NO;
}
return self;
@@ -259,6 +247,14 @@
m_activeTouches[touch].id = m_nextTouchId++;
}
+ if (m_activeTouches.size() == 1) {
+ QPlatformWindow *topLevel = m_qioswindow;
+ while (QPlatformWindow *p = topLevel->parent())
+ topLevel = p;
+ if (topLevel->window() != QGuiApplication::focusWindow())
+ topLevel->requestActivateWindow();
+ }
+
[self updateTouchList:touches withState:Qt::TouchPointPressed];
[self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)];
}
@@ -271,14 +267,6 @@
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
- QWindow *window = m_qioswindow->window();
- if (window != QGuiApplication::focusWindow() && m_activeTouches.size() == 1) {
- // Activate the touched window if the last touch was released inside it:
- UITouch *touch = static_cast<UITouch *>([[touches allObjects] lastObject]);
- if (CGRectContainsPoint([self bounds], [touch locationInView:self]))
- m_qioswindow->requestActivateWindow();
- }
-
[self updateTouchList:touches withState:Qt::TouchPointReleased];
[self sendTouchEventWithTimestamp:ulong(event.timestamp * 1000)];
@@ -314,109 +302,6 @@
QWindowSystemInterface::flushWindowSystemEvents();
}
-@synthesize autocapitalizationType;
-@synthesize autocorrectionType;
-@synthesize enablesReturnKeyAutomatically;
-@synthesize keyboardAppearance;
-@synthesize keyboardType;
-@synthesize returnKeyType;
-@synthesize secureTextEntry;
-
-- (BOOL)canBecomeFirstResponder
-{
- return YES;
-}
-
-- (BOOL)becomeFirstResponder
-{
- // Note: QIOSInputContext controls our first responder status based on
- // whether or not the keyboard should be open or closed.
- [self updateTextInputTraits];
- return [super becomeFirstResponder];
-}
-
-- (BOOL)resignFirstResponder
-{
- // Resigning first responed status means that the virtual keyboard was closed, or
- // some other view became first responder. In either case we clear the focus object to
- // avoid blinking cursors in line edits etc:
- if (m_qioswindow)
- static_cast<QWindowPrivate *>(QObjectPrivate::get(m_qioswindow->window()))->clearFocusObject();
- return [super resignFirstResponder];
-}
-
-- (BOOL)hasText
-{
- return YES;
-}
-
-- (void)insertText:(NSString *)text
-{
- QString string = QString::fromUtf8([text UTF8String]);
- int key = 0;
- if ([text isEqualToString:@"\n"]) {
- key = (int)Qt::Key_Return;
- if (self.returnKeyType == UIReturnKeyDone)
- [self resignFirstResponder];
- }
-
- // Send key event to window system interface
- QWindowSystemInterface::handleKeyEvent(
- 0, QEvent::KeyPress, key, Qt::NoModifier, string, false, int(string.length()));
- QWindowSystemInterface::handleKeyEvent(
- 0, QEvent::KeyRelease, key, Qt::NoModifier, string, false, int(string.length()));
-}
-
-- (void)deleteBackward
-{
- // Send key event to window system interface
- QWindowSystemInterface::handleKeyEvent(
- 0, QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier);
- QWindowSystemInterface::handleKeyEvent(
- 0, QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier);
-}
-
-- (void)updateTextInputTraits
-{
- // Ask the current focus object what kind of input it
- // expects, and configure the keyboard appropriately:
- QObject *focusObject = QGuiApplication::focusObject();
- if (!focusObject)
- return;
- QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
- if (!QCoreApplication::sendEvent(focusObject, &queryEvent))
- return;
- if (!queryEvent.value(Qt::ImEnabled).toBool())
- return;
-
- Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
-
- self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
- self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
- self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
- UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault;
-
- if (hints & Qt::ImhUppercaseOnly)
- self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
- else if (hints & Qt::ImhNoAutoUppercase)
- self.autocapitalizationType = UITextAutocapitalizationTypeNone;
- else
- self.autocapitalizationType = UITextAutocapitalizationTypeSentences;
-
- if (hints & Qt::ImhUrlCharactersOnly)
- self.keyboardType = UIKeyboardTypeURL;
- else if (hints & Qt::ImhEmailCharactersOnly)
- self.keyboardType = UIKeyboardTypeEmailAddress;
- else if (hints & Qt::ImhDigitsOnly)
- self.keyboardType = UIKeyboardTypeNumberPad;
- else if (hints & Qt::ImhFormattedNumbersOnly)
- self.keyboardType = UIKeyboardTypeDecimalPad;
- else if (hints & Qt::ImhDialableCharactersOnly)
- self.keyboardType = UIKeyboardTypeNumberPad;
- else
- self.keyboardType = UIKeyboardTypeDefault;
-}
-
@end
@implementation UIView (QIOS)
@@ -487,7 +372,7 @@ void QIOSWindow::setVisible(bool visible)
m_view.hidden = !visible;
[m_view setNeedsDisplay];
- if (!isQtApplication())
+ if (!isQtApplication() || !window()->isTopLevel())
return;
// Since iOS doesn't do window management the way a Qt application
@@ -503,18 +388,16 @@ void QIOSWindow::setVisible(bool visible)
if (visible) {
requestActivateWindow();
-
- if (window()->isTopLevel())
- static_cast<QIOSScreen *>(screen())->updateStatusBarVisibility();
-
+ static_cast<QIOSScreen *>(screen())->updateStatusBarVisibility();
} else {
// Activate top-most visible QWindow:
NSArray *subviews = m_view.viewController.view.subviews;
for (int i = int(subviews.count) - 1; i >= 0; --i) {
UIView *view = [subviews objectAtIndex:i];
if (!view.hidden) {
- if (QWindow *window = view.qwindow) {
- static_cast<QIOSWindow *>(window->handle())->requestActivateWindow();
+ QWindow *w = view.qwindow;
+ if (w && w->isTopLevel()) {
+ static_cast<QIOSWindow *>(w->handle())->requestActivateWindow();
break;
}
}
@@ -636,23 +519,6 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow)
}
}
-QWindow *QIOSWindow::topLevelWindow() const
-{
- QWindow *window = this->window();
- while (window) {
- QWindow *parent = window->parent();
- if (!parent)
- parent = window->transientParent();
-
- if (!parent)
- break;
-
- window = parent;
- }
-
- return window;
-}
-
void QIOSWindow::requestActivateWindow()
{
// Note that several windows can be active at the same time if they exist in the same
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
new file mode 100644
index 0000000000..575dedab89
--- /dev/null
+++ b/src/plugins/platforms/ios/quiview.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#import <UIKit/UIKit.h>
+#include "qioswindow.h"
+
+@interface QUIView : UIView
+{
+@public
+ UITextAutocapitalizationType autocapitalizationType;
+ UITextAutocorrectionType autocorrectionType;
+ BOOL enablesReturnKeyAutomatically;
+ UIKeyboardAppearance keyboardAppearance;
+ UIKeyboardType keyboardType;
+ UIReturnKeyType returnKeyType;
+ BOOL secureTextEntry;
+ QIOSWindow *m_qioswindow;
+ QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
+ int m_nextTouchId;
+ QString m_markedText;
+ BOOL m_inSendEventToFocusObject;
+}
+
+@property(nonatomic, assign) id<UITextInputDelegate> inputDelegate;
+@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
+@property(nonatomic) UITextAutocorrectionType autocorrectionType;
+@property(nonatomic) UITextSpellCheckingType spellCheckingType;
+@property(nonatomic) BOOL enablesReturnKeyAutomatically;
+@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
+@property(nonatomic) UIKeyboardType keyboardType;
+@property(nonatomic) UIReturnKeyType returnKeyType;
+@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
+
+@end
+
+@interface QUIView (TextInput) <UITextInput>
+- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query;
+- (void)reset;
+- (void)commit;
+@end
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
new file mode 100644
index 0000000000..d0088d415a
--- /dev/null
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -0,0 +1,557 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qtextformat.h>
+
+class StaticVariables
+{
+public:
+ QInputMethodQueryEvent inputMethodQueryEvent;
+ QTextCharFormat markedTextFormat;
+
+ StaticVariables() : inputMethodQueryEvent(Qt::ImQueryInput)
+ {
+ // There seems to be no way to query how the preedit text
+ // should be drawn. So we need to hard-code the color.
+ QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion;
+ if (iosVersion < QSysInfo::MV_IOS_7_0)
+ markedTextFormat.setBackground(QColor(235, 239, 247));
+ else
+ markedTextFormat.setBackground(QColor(206, 221, 238));
+ }
+};
+
+Q_GLOBAL_STATIC(StaticVariables, staticVariables);
+
+// -------------------------------------------------------------------------
+
+@interface QUITextPosition : UITextPosition
+{
+}
+
+@property (nonatomic) NSUInteger index;
++ (QUITextPosition *)positionWithIndex:(NSUInteger)index;
+
+@end
+
+@implementation QUITextPosition
+
++ (QUITextPosition *)positionWithIndex:(NSUInteger)index
+{
+ QUITextPosition *pos = [[QUITextPosition alloc] init];
+ pos.index = index;
+ return [pos autorelease];
+}
+
+@end
+
+// -------------------------------------------------------------------------
+
+@interface QUITextRange : UITextRange
+{
+}
+
+@property (nonatomic) NSRange range;
++ (QUITextRange *)rangeWithNSRange:(NSRange)range;
+
+@end
+
+@implementation QUITextRange
+
++ (QUITextRange *)rangeWithNSRange:(NSRange)nsrange
+{
+ QUITextRange *range = [[QUITextRange alloc] init];
+ range.range = nsrange;
+ return [range autorelease];
+}
+
+- (UITextPosition *)start
+{
+ return [QUITextPosition positionWithIndex:self.range.location];
+}
+
+- (UITextPosition *)end
+{
+ return [QUITextPosition positionWithIndex:(self.range.location + self.range.length)];
+}
+
+- (NSRange) range
+{
+ return _range;
+}
+
+-(BOOL)isEmpty
+{
+ return (self.range.length == 0);
+}
+
+@end
+
+// -------------------------------------------------------------------------
+
+@implementation QUIView (TextInput)
+
+- (BOOL)canBecomeFirstResponder
+{
+ return YES;
+}
+
+- (BOOL)becomeFirstResponder
+{
+ // Note: QIOSInputContext controls our first responder status based on
+ // whether or not the keyboard should be open or closed.
+ [self updateTextInputTraits];
+ return [super becomeFirstResponder];
+}
+
+- (BOOL)resignFirstResponder
+{
+ // Resigning first responed status means that the virtual keyboard was closed, or
+ // some other view became first responder. In either case we clear the focus object to
+ // avoid blinking cursors in line edits etc:
+ if (m_qioswindow)
+ static_cast<QWindowPrivate *>(QObjectPrivate::get(m_qioswindow->window()))->clearFocusObject();
+ return [super resignFirstResponder];
+}
+
+- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query
+{
+ Q_UNUSED(query);
+
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return;
+
+ if (!m_inSendEventToFocusObject) {
+ if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
+ [self.inputDelegate selectionWillChange:id<UITextInput>(self)];
+ if (query & Qt::ImSurroundingText)
+ [self.inputDelegate textWillChange:id<UITextInput>(self)];
+ }
+
+ // Note that we ignore \a query, and instead update using Qt::ImQueryInput. This enables us to just
+ // store the event without copying out the result from the event each time. Besides, we seem to be
+ // called with Qt::ImQueryInput when only changing selection, and always if typing text. So there would
+ // not be any performance gain by only updating \a query.
+ staticVariables()->inputMethodQueryEvent = QInputMethodQueryEvent(Qt::ImQueryInput);
+ QCoreApplication::sendEvent(focusObject, &staticVariables()->inputMethodQueryEvent);
+
+ if (!m_inSendEventToFocusObject) {
+ if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
+ [self.inputDelegate selectionDidChange:id<UITextInput>(self)];
+ if (query & Qt::ImSurroundingText)
+ [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ }
+}
+
+- (void)sendEventToFocusObject:(QEvent &)e
+{
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return;
+
+ // While sending the event, we will receive back updateInputMethodWithQuery calls.
+ // To not confuse iOS, we cannot not call textWillChange/textDidChange at that
+ // point since it will cause spell checking etc to fail. So we use a guard.
+ m_inSendEventToFocusObject = YES;
+ QCoreApplication::sendEvent(focusObject, &e);
+ m_inSendEventToFocusObject = NO;
+}
+
+- (void)reset
+{
+ [self.inputDelegate textWillChange:id<UITextInput>(self)];
+ [self setMarkedText:@"" selectedRange:NSMakeRange(0, 0)];
+ [self updateInputMethodWithQuery:Qt::ImQueryInput];
+
+ if ([self isFirstResponder]) {
+ // There seem to be no way to inform that the keyboard needs to update (since
+ // text input traits might have changed). As a work-around, we quickly resign
+ // first responder status just to reassign it again:
+ [super resignFirstResponder];
+ [self updateTextInputTraits];
+ [super becomeFirstResponder];
+ }
+ [self.inputDelegate textDidChange:id<UITextInput>(self)];
+}
+
+- (void)commit
+{
+ [self.inputDelegate textWillChange:id<UITextInput>(self)];
+ [self unmarkText];
+ [self.inputDelegate textDidChange:id<UITextInput>(self)];
+}
+
+- (QVariant)imValue:(Qt::InputMethodQuery)query
+{
+ return staticVariables()->inputMethodQueryEvent.value(query);
+}
+
+-(id<UITextInputTokenizer>)tokenizer
+{
+ return [[[UITextInputStringTokenizer alloc] initWithTextInput:id<UITextInput>(self)] autorelease];
+}
+
+-(UITextPosition *)beginningOfDocument
+{
+ return [QUITextPosition positionWithIndex:0];
+}
+
+-(UITextPosition *)endOfDocument
+{
+ int endPosition = [self imValue:Qt::ImSurroundingText].toString().length();
+ return [QUITextPosition positionWithIndex:endPosition];
+}
+
+- (void)setSelectedTextRange:(UITextRange *)range
+{
+ QUITextRange *r = static_cast<QUITextRange *>(range);
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, r.range.location, r.range.length, 0);
+ QInputMethodEvent e(m_markedText, attrs);
+ [self sendEventToFocusObject:e];
+}
+
+- (UITextRange *)selectedTextRange {
+ int cursorPos = [self imValue:Qt::ImCursorPosition].toInt();
+ int anchorPos = [self imValue:Qt::ImAnchorPosition].toInt();
+ return [QUITextRange rangeWithNSRange:NSMakeRange(cursorPos, (anchorPos - cursorPos))];
+}
+
+- (NSString *)textInRange:(UITextRange *)range
+{
+ int s = static_cast<QUITextPosition *>([range start]).index;
+ int e = static_cast<QUITextPosition *>([range end]).index;
+ return [self imValue:Qt::ImSurroundingText].toString().mid(s, e - s).toNSString();
+}
+
+- (void)setMarkedText:(NSString *)markedText selectedRange:(NSRange)selectedRange
+{
+ Q_UNUSED(selectedRange);
+
+ m_markedText = markedText ? QString::fromNSString(markedText) : QString();
+
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, markedText.length, staticVariables()->markedTextFormat);
+ QInputMethodEvent e(m_markedText, attrs);
+ [self sendEventToFocusObject:e];
+}
+
+- (void)unmarkText
+{
+ if (m_markedText.isEmpty())
+ return;
+
+ QInputMethodEvent e;
+ e.setCommitString(m_markedText);
+ [self sendEventToFocusObject:e];
+
+ m_markedText.clear();
+}
+
+- (NSComparisonResult)comparePosition:(UITextPosition *)position toPosition:(UITextPosition *)other
+{
+ int p = static_cast<QUITextPosition *>(position).index;
+ int o = static_cast<QUITextPosition *>(other).index;
+ if (p > o)
+ return NSOrderedAscending;
+ else if (p < o)
+ return NSOrderedDescending;
+ return NSOrderedSame;
+}
+
+- (UITextRange *)markedTextRange {
+ return m_markedText.isEmpty() ? nil : [QUITextRange rangeWithNSRange:NSMakeRange(0, m_markedText.length())];
+}
+
+- (UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition
+{
+ int f = static_cast<QUITextPosition *>(fromPosition).index;
+ int t = static_cast<QUITextPosition *>(toPosition).index;
+ return [QUITextRange rangeWithNSRange:NSMakeRange(f, t - f)];
+}
+
+- (UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset
+{
+ int p = static_cast<QUITextPosition *>(position).index;
+ return [QUITextPosition positionWithIndex:p + offset];
+}
+
+- (UITextPosition *)positionFromPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset
+{
+ int p = static_cast<QUITextPosition *>(position).index;
+ return [QUITextPosition positionWithIndex:(direction == UITextLayoutDirectionRight ? p + offset : p - offset)];
+}
+
+- (UITextPosition *)positionWithinRange:(UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction
+{
+ NSRange r = static_cast<QUITextRange *>(range).range;
+ if (direction == UITextLayoutDirectionRight)
+ return [QUITextPosition positionWithIndex:r.location + r.length];
+ return [QUITextPosition positionWithIndex:r.location];
+}
+
+- (NSInteger)offsetFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition
+{
+ int f = static_cast<QUITextPosition *>(fromPosition).index;
+ int t = static_cast<QUITextPosition *>(toPosition).index;
+ return t - f;
+}
+
+- (UIView *)textInputView
+{
+ // iOS expects rects we return from other UITextInput methods
+ // to be relative to the view this method returns.
+ // Since QInputMethod returns rects relative to the top level
+ // QWindow, that is also the view we need to return.
+ QPlatformWindow *topLevel = m_qioswindow;
+ while (QPlatformWindow *p = topLevel->parent())
+ topLevel = p;
+ return reinterpret_cast<UIView *>(topLevel->winId());
+}
+
+- (CGRect)firstRectForRange:(UITextRange *)range
+{
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return CGRectZero;
+
+ // Using a work-around to get the current rect until
+ // a better API is in place:
+ if (!m_markedText.isEmpty())
+ return CGRectZero;
+
+ int cursorPos = [self imValue:Qt::ImCursorPosition].toInt();
+ int anchorPos = [self imValue:Qt::ImAnchorPosition].toInt();
+
+ NSRange r = static_cast<QUITextRange*>(range).range;
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, r.location, 0, 0);
+ QInputMethodEvent e(m_markedText, attrs);
+ [self sendEventToFocusObject:e];
+ QRectF startRect = qApp->inputMethod()->cursorRectangle();
+
+ attrs = QList<QInputMethodEvent::Attribute>();
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, r.location + r.length, 0, 0);
+ e = QInputMethodEvent(m_markedText, attrs);
+ [self sendEventToFocusObject:e];
+ QRectF endRect = qApp->inputMethod()->cursorRectangle();
+
+ if (cursorPos != int(r.location + r.length) || cursorPos != anchorPos) {
+ attrs = QList<QInputMethodEvent::Attribute>();
+ attrs << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, cursorPos, (cursorPos - anchorPos), 0);
+ e = QInputMethodEvent(m_markedText, attrs);
+ [self sendEventToFocusObject:e];
+ }
+
+ return toCGRect(startRect.united(endRect));
+}
+
+- (CGRect)caretRectForPosition:(UITextPosition *)position
+{
+ Q_UNUSED(position);
+ // Assume for now that position is always the same as
+ // cursor index until a better API is in place:
+ QRectF cursorRect = qApp->inputMethod()->cursorRectangle();
+ return toCGRect(cursorRect);
+}
+
+- (void)replaceRange:(UITextRange *)range withText:(NSString *)text
+{
+ [self setSelectedTextRange:range];
+
+ QInputMethodEvent e;
+ e.setCommitString(QString::fromNSString(text));
+ [self sendEventToFocusObject:e];
+}
+
+- (void)setBaseWritingDirection:(UITextWritingDirection)writingDirection forRange:(UITextRange *)range
+{
+ Q_UNUSED(writingDirection);
+ Q_UNUSED(range);
+ // Writing direction is handled by QLocale
+}
+
+- (UITextWritingDirection)baseWritingDirectionForPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction
+{
+ Q_UNUSED(position);
+ Q_UNUSED(direction);
+ if (QLocale::system().textDirection() == Qt::RightToLeft)
+ return UITextWritingDirectionRightToLeft;
+ return UITextWritingDirectionLeftToRight;
+}
+
+- (UITextRange *)characterRangeByExtendingPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction
+{
+ int p = static_cast<QUITextPosition *>(position).index;
+ if (direction == UITextLayoutDirectionLeft)
+ return [QUITextRange rangeWithNSRange:NSMakeRange(0, p)];
+ int l = [self imValue:Qt::ImSurroundingText].toString().length();
+ return [QUITextRange rangeWithNSRange:NSMakeRange(p, l - p)];
+}
+
+- (UITextPosition *)closestPositionToPoint:(CGPoint)point
+{
+ // No API in Qt for determining this. Use sensible default instead:
+ Q_UNUSED(point);
+ return [QUITextPosition positionWithIndex:[self imValue:Qt::ImCursorPosition].toInt()];
+}
+
+- (UITextPosition *)closestPositionToPoint:(CGPoint)point withinRange:(UITextRange *)range
+{
+ // No API in Qt for determining this. Use sensible default instead:
+ Q_UNUSED(point);
+ Q_UNUSED(range);
+ return [QUITextPosition positionWithIndex:[self imValue:Qt::ImCursorPosition].toInt()];
+}
+
+- (UITextRange *)characterRangeAtPoint:(CGPoint)point
+{
+ // No API in Qt for determining this. Use sensible default instead:
+ Q_UNUSED(point);
+ return [QUITextRange rangeWithNSRange:NSMakeRange([self imValue:Qt::ImCursorPosition].toInt(), 0)];
+}
+
+- (void)setMarkedTextStyle:(NSDictionary *)style
+{
+ Q_UNUSED(style);
+ // No-one is going to change our style. If UIKit itself did that
+ // it would be very welcome, since then we knew how to style marked
+ // text instead of just guessing...
+}
+
+- (NSDictionary *)textStylingAtPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction
+{
+ Q_UNUSED(position);
+ Q_UNUSED(direction);
+
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return [NSDictionary dictionary];
+
+ // Assume position is the same as the cursor for now. QInputMethodQueryEvent with Qt::ImFont
+ // needs to be extended to take an extra position argument before this can be fully correct.
+ QInputMethodQueryEvent e(Qt::ImFont);
+ QCoreApplication::sendEvent(focusObject, &e);
+ QFont qfont = qvariant_cast<QFont>(e.value(Qt::ImFont));
+ UIFont *uifont = [UIFont fontWithName:qfont.family().toNSString() size:qfont.pointSize()];
+ return [NSDictionary dictionaryWithObject:uifont forKey:UITextInputTextFontKey];
+}
+
+-(NSDictionary *)markedTextStyle
+{
+ return [NSDictionary dictionary];
+}
+
+- (BOOL)hasText
+{
+ return YES;
+}
+
+- (void)insertText:(NSString *)text
+{
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return;
+
+ if ([text isEqualToString:@"\n"] && self.returnKeyType == UIReturnKeyDone)
+ [self resignFirstResponder];
+
+ QInputMethodEvent e;
+ e.setCommitString(QString::fromNSString(text));
+ [self sendEventToFocusObject:e];
+}
+
+- (void)deleteBackward
+{
+ // Since we're posting im events directly to the focus object, we should do the
+ // same for key events. Otherwise they might end up in a different place or out
+ // of sync with im events.
+ QKeyEvent press(QEvent::KeyPress, (int)Qt::Key_Backspace, Qt::NoModifier);
+ QKeyEvent release(QEvent::KeyRelease, (int)Qt::Key_Backspace, Qt::NoModifier);
+ [self sendEventToFocusObject:press];
+ [self sendEventToFocusObject:release];
+}
+
+- (void)updateTextInputTraits
+{
+ // Ask the current focus object what kind of input it
+ // expects, and configure the keyboard appropriately:
+ QObject *focusObject = QGuiApplication::focusObject();
+ if (!focusObject)
+ return;
+ QInputMethodQueryEvent queryEvent(Qt::ImEnabled | Qt::ImHints);
+ if (!QCoreApplication::sendEvent(focusObject, &queryEvent))
+ return;
+ if (!queryEvent.value(Qt::ImEnabled).toBool())
+ return;
+
+ Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
+
+ self.returnKeyType = (hints & Qt::ImhMultiLine) ? UIReturnKeyDefault : UIReturnKeyDone;
+ self.secureTextEntry = BOOL(hints & Qt::ImhHiddenText);
+ self.autocorrectionType = (hints & Qt::ImhNoPredictiveText) ?
+ UITextAutocorrectionTypeNo : UITextAutocorrectionTypeDefault;
+ self.spellCheckingType = (hints & Qt::ImhNoPredictiveText) ?
+ UITextSpellCheckingTypeNo : UITextSpellCheckingTypeDefault;
+
+ if (hints & Qt::ImhUppercaseOnly)
+ self.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters;
+ else if (hints & Qt::ImhNoAutoUppercase)
+ self.autocapitalizationType = UITextAutocapitalizationTypeNone;
+ else
+ self.autocapitalizationType = UITextAutocapitalizationTypeSentences;
+
+ if (hints & Qt::ImhUrlCharactersOnly)
+ self.keyboardType = UIKeyboardTypeURL;
+ else if (hints & Qt::ImhEmailCharactersOnly)
+ self.keyboardType = UIKeyboardTypeEmailAddress;
+ else if (hints & Qt::ImhDigitsOnly)
+ self.keyboardType = UIKeyboardTypeNumberPad;
+ else if (hints & Qt::ImhFormattedNumbersOnly)
+ self.keyboardType = UIKeyboardTypeDecimalPad;
+ else if (hints & Qt::ImhDialableCharactersOnly)
+ self.keyboardType = UIKeyboardTypeNumberPad;
+ else
+ self.keyboardType = UIKeyboardTypeDefault;
+}
+
+@end
diff --git a/src/plugins/platforms/kms/kms.pro b/src/plugins/platforms/kms/kms.pro
index 612a878736..1b3678f13a 100644
--- a/src/plugins/platforms/kms/kms.pro
+++ b/src/plugins/platforms/kms/kms.pro
@@ -21,8 +21,8 @@ SOURCES = main.cpp \
qkmscursor.cpp \
qkmsdevice.cpp \
qkmsbackingstore.cpp \
- qkmsnativeinterface.cpp \
- qkmsvthandler.cpp
+ qkmsnativeinterface.cpp
+
HEADERS = qkmsintegration.h \
qkmsscreen.h \
qkmscontext.h \
@@ -30,8 +30,7 @@ HEADERS = qkmsintegration.h \
qkmscursor.h \
qkmsdevice.h \
qkmsbackingstore.h \
- qkmsnativeinterface.h \
- qkmsvthandler.h
+ qkmsnativeinterface.h
OTHER_FILES += \
kms.json
diff --git a/src/plugins/platforms/kms/qkmsintegration.cpp b/src/plugins/platforms/kms/qkmsintegration.cpp
index 80c5887a28..868886a0dd 100644
--- a/src/plugins/platforms/kms/qkmsintegration.cpp
+++ b/src/plugins/platforms/kms/qkmsintegration.cpp
@@ -46,7 +46,6 @@
#include "qkmsbackingstore.h"
#include "qkmscontext.h"
#include "qkmsnativeinterface.h"
-#include "qkmsvthandler.h"
#if !defined(QT_NO_EVDEV)
#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
@@ -56,6 +55,8 @@
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qfbvthandler_p.h>
+
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
@@ -65,10 +66,29 @@ QT_BEGIN_NAMESPACE
QKmsIntegration::QKmsIntegration()
: QPlatformIntegration(),
m_fontDatabase(new QGenericUnixFontDatabase()),
- m_nativeInterface(new QKmsNativeInterface)
+ m_nativeInterface(new QKmsNativeInterface),
+ m_vtHandler(0),
+ m_deviceDiscovery(0)
+{
+}
+
+QKmsIntegration::~QKmsIntegration()
+{
+ delete m_deviceDiscovery;
+ foreach (QKmsDevice *device, m_devices) {
+ delete device;
+ }
+ foreach (QPlatformScreen *screen, m_screens) {
+ delete screen;
+ }
+ delete m_fontDatabase;
+ delete m_vtHandler;
+}
+
+void QKmsIntegration::initialize()
{
- setenv("EGL_PLATFORM", "drm",1);
- m_vtHandler = new QKmsVTHandler;
+ qputenv("EGL_PLATFORM", "drm");
+ m_vtHandler = new QFbVtHandler;
m_deviceDiscovery = QDeviceDiscovery::create(QDeviceDiscovery::Device_DRM | QDeviceDiscovery::Device_DRM_PrimaryGPU, 0);
if (m_deviceDiscovery) {
@@ -87,19 +107,6 @@ QKmsIntegration::QKmsIntegration()
#endif
}
-QKmsIntegration::~QKmsIntegration()
-{
- delete m_deviceDiscovery;
- foreach (QKmsDevice *device, m_devices) {
- delete device;
- }
- foreach (QPlatformScreen *screen, m_screens) {
- delete screen;
- }
- delete m_fontDatabase;
- delete m_vtHandler;
-}
-
void QKmsIntegration::addDevice(const QString &deviceNode)
{
m_devices.append(new QKmsDevice(deviceNode, this));
diff --git a/src/plugins/platforms/kms/qkmsintegration.h b/src/plugins/platforms/kms/qkmsintegration.h
index 0a626e6bd2..3d3f1722e9 100644
--- a/src/plugins/platforms/kms/qkmsintegration.h
+++ b/src/plugins/platforms/kms/qkmsintegration.h
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
class QKmsScreen;
class QKmsDevice;
-class QKmsVTHandler;
+class QFbVtHandler;
class QKmsIntegration : public QObject, public QPlatformIntegration
{
@@ -60,16 +60,17 @@ public:
QKmsIntegration();
~QKmsIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const;
+ void initialize() Q_DECL_OVERRIDE;
+ bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
- QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformFontDatabase *fontDatabase() const;
- QAbstractEventDispatcher *createEventDispatcher() const;
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
- QPlatformNativeInterface *nativeInterface() const;
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
void addScreen(QKmsScreen *screen);
QObject *createDevice(const char *);
@@ -85,7 +86,7 @@ private:
QList<QKmsDevice *> m_devices;
QPlatformFontDatabase *m_fontDatabase;
QPlatformNativeInterface *m_nativeInterface;
- QKmsVTHandler *m_vtHandler;
+ QFbVtHandler *m_vtHandler;
QDeviceDiscovery *m_deviceDiscovery;
};
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 53f48d5480..b1b13e862f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -43,18 +43,22 @@
#include "qlinuxfbscreen.h"
#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtPlatformSupport/private/qgenericunixservices_p.h>
#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+
+#include <QtPlatformSupport/private/qfbvthandler_p.h>
#include <QtPlatformSupport/private/qfbbackingstore_p.h>
#include <QtPlatformSupport/private/qfbwindow_p.h>
#include <QtPlatformSupport/private/qfbcursor_p.h>
#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/private/qpixmap_raster_p.h>
+#include <qpa/qplatforminputcontextfactory_p.h>
QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
- : m_fontDb(new QGenericUnixFontDatabase())
+ : m_fontDb(new QGenericUnixFontDatabase),
+ m_services(new QGenericUnixServices)
{
m_primaryScreen = new QLinuxFbScreen(paramList);
}
@@ -70,21 +74,21 @@ void QLinuxFbIntegration::initialize()
screenAdded(m_primaryScreen);
else
qWarning("linuxfb: Failed to initialize screen");
+
+ m_inputContext = QPlatformInputContextFactory::create();
+
+ m_vtHandler.reset(new QFbVtHandler);
}
bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
case ThreadedPixmaps: return true;
+ case WindowManagement: return false;
default: return QPlatformIntegration::hasCapability(cap);
}
}
-QPlatformPixmap *QLinuxFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
-{
- return new QRasterPlatformPixmap(type);
-}
-
QPlatformBackingStore *QLinuxFbIntegration::createPlatformBackingStore(QWindow *window) const
{
return new QFbBackingStore(window);
@@ -109,7 +113,12 @@ QList<QPlatformScreen *> QLinuxFbIntegration::screens() const
QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const
{
- return m_fontDb;
+ return m_fontDb.data();
+}
+
+QPlatformServices *QLinuxFbIntegration::services() const
+{
+ return m_services.data();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index 965a6e4642..67742ecab9 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -46,9 +46,9 @@
QT_BEGIN_NAMESPACE
-class QLinuxFbIntegrationPrivate;
class QAbstractEventDispatcher;
class QLinuxFbScreen;
+class QFbVtHandler;
class QLinuxFbIntegration : public QPlatformIntegration
{
@@ -59,21 +59,25 @@ public:
void initialize() Q_DECL_OVERRIDE;
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+ QPlatformServices *services() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
QList<QPlatformScreen *> screens() const;
private:
QLinuxFbScreen *m_primaryScreen;
- QPlatformFontDatabase *m_fontDb;
-
+ QPlatformInputContext *m_inputContext;
+ QScopedPointer<QPlatformFontDatabase> m_fontDb;
+ QScopedPointer<QPlatformServices> m_services;
+ QScopedPointer<QFbVtHandler> m_vtHandler;
};
QT_END_NAMESPACE
#endif // QLINUXFBINTEGRATION_H
-
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 33a9523568..5af84918d9 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -41,6 +41,7 @@
#include "qlinuxfbscreen.h"
#include <QtPlatformSupport/private/qfbcursor_p.h>
+#include <QtCore/QRegularExpression>
#include <QtGui/QPainter>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
@@ -318,11 +319,11 @@ QLinuxFbScreen::~QLinuxFbScreen()
bool QLinuxFbScreen::initialize()
{
- QRegExp ttyRx(QLatin1String("tty=(.*)"));
- QRegExp fbRx(QLatin1String("fb=(.*)"));
- QRegExp mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
- QRegExp sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
- QRegExp offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
+ QRegularExpression ttyRx(QLatin1String("tty=(.*)"));
+ QRegularExpression fbRx(QLatin1String("fb=(.*)"));
+ QRegularExpression mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
+ QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
+ QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
QString fbDevice, ttyDevice;
QSize userMmSize;
@@ -331,18 +332,19 @@ bool QLinuxFbScreen::initialize()
// Parse arguments
foreach (const QString &arg, mArgs) {
+ QRegularExpressionMatch match;
if (arg == QLatin1String("nographicsmodeswitch"))
doSwitchToGraphicsMode = false;
- else if (mmSizeRx.indexIn(arg) != -1)
- userMmSize = QSize(mmSizeRx.cap(1).toInt(), mmSizeRx.cap(2).toInt());
- else if (sizeRx.indexIn(arg) != -1)
- userGeometry.setSize(QSize(sizeRx.cap(1).toInt(), sizeRx.cap(2).toInt()));
- else if (offsetRx.indexIn(arg) != -1)
- userGeometry.setTopLeft(QPoint(offsetRx.cap(1).toInt(), offsetRx.cap(2).toInt()));
- else if (ttyRx.indexIn(arg) != -1)
- ttyDevice = ttyRx.cap(1);
- else if (fbRx.indexIn(arg) != -1)
- fbDevice = fbRx.cap(1);
+ else if (arg.contains(mmSizeRx, &match))
+ userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
+ else if (arg.contains(sizeRx, &match))
+ userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
+ else if (arg.contains(offsetRx, &match))
+ userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt()));
+ else if (arg.contains(ttyRx, &match))
+ ttyDevice = match.captured(1);
+ else if (arg.contains(fbRx, &match))
+ fbDevice = match.captured(1);
}
if (fbDevice.isEmpty()) {
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index 76b4b5b0eb..7f5c25f239 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -41,17 +41,20 @@
#include "qminimalintegration.h"
#include "qminimalbackingstore.h"
-#ifndef Q_OS_WIN
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#else
-#include <QtCore/private/qeventdispatcher_win_p.h>
-#endif
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformfontdatabase.h>
+#if !defined(Q_OS_WIN)
+#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
+#elif defined(Q_OS_WINRT)
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_win_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
static const char debugBackingStoreEnvironmentVariable[] = "QT_DEBUG_BACKINGSTORE";
@@ -132,7 +135,11 @@ QPlatformBackingStore *QMinimalIntegration::createPlatformBackingStore(QWindow *
QAbstractEventDispatcher *QMinimalIntegration::createEventDispatcher() const
{
#ifdef Q_OS_WIN
+#ifndef Q_OS_WINRT
return new QEventDispatcherWin32;
+#else // !Q_OS_WINRT
+ return new QEventDispatcherWinRT;
+#endif // Q_OS_WINRT
#else
return createUnixEventDispatcher();
#endif
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
index ebc402550e..d26b20d364 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
@@ -101,16 +101,6 @@ QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
}
qWarning("Initialized display %d %d\n", major, minor);
-
- int swapInterval = 1;
- QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = 1;
- }
- eglSwapInterval(m_dpy, swapInterval);
}
QMinimalEglScreen::~QMinimalEglScreen()
diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
index a1da8e3a16..76881db6fc 100644
--- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
+++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp
@@ -52,7 +52,11 @@
#endif
#elif defined(Q_OS_WIN)
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+#ifndef Q_OS_WINRT
#include <QtCore/private/qeventdispatcher_win_p.h>
+#else
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+#endif
#endif
#include <QtGui/private/qpixmap_raster_p.h>
@@ -143,7 +147,11 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const
#if defined(Q_OS_UNIX)
return createUnixEventDispatcher();
#elif defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT
return new QOffscreenEventDispatcher<QEventDispatcherWin32>();
+#else // !Q_OS_WINRT
+ return new QOffscreenEventDispatcher<QEventDispatcherWinRT>();
+#endif // Q_OS_WINRT
#else
return 0;
#endif
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 377ca32e64..584efa1665 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -15,7 +15,12 @@ mac {
else: SUBDIRS += cocoa
}
-win32: SUBDIRS += windows
+win32:!winrt: SUBDIRS += windows
+winrt: SUBDIRS += winrt
+
+contains(QT_CONFIG, direct2d) {
+ SUBDIRS += direct2d
+}
qnx {
SUBDIRS += qnx
diff --git a/src/plugins/platforms/qnx/main.cpp b/src/plugins/platforms/qnx/main.cpp
index 50779d3e12..01e71b3810 100644
--- a/src/plugins/platforms/qnx/main.cpp
+++ b/src/plugins/platforms/qnx/main.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2011 - 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -41,13 +41,16 @@
#include "main.h"
#include "qqnxintegration.h"
+#include "qqnxlgmon.h"
QT_BEGIN_NAMESPACE
QPlatformIntegration *QQnxIntegrationPlugin::create(const QString& system, const QStringList& paramList)
{
- if (!system.compare(QLatin1String("qnx"), Qt::CaseInsensitive))
+ if (!system.compare(QLatin1String("qnx"), Qt::CaseInsensitive)) {
+ qqnxLgmonInit();
return new QQnxIntegration(paramList);
+ }
return 0;
}
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index bc7219de5c..2399a91c12 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -45,7 +45,8 @@ SOURCES = main.cpp \
qqnxabstractvirtualkeyboard.cpp \
qqnxservices.cpp \
qqnxcursor.cpp \
- qqnxrasterwindow.cpp
+ qqnxrasterwindow.cpp \
+ qqnxglobal.cpp
HEADERS = main.h \
qqnxbuffer.h \
@@ -62,7 +63,10 @@ HEADERS = main.h \
qqnxabstractcover.h \
qqnxservices.h \
qqnxcursor.h \
- qqnxrasterwindow.h
+ qqnxrasterwindow.h \
+ qqnxscreeneventfilter.h \
+ qqnxglobal.h \
+ qqnxlgmon.h
CONFIG(qqnx_screeneventthread) {
DEFINES += QQNX_SCREENEVENTTHREAD
@@ -142,6 +146,12 @@ CONFIG(qqnx_pps) {
}
}
+lgmon {
+ DEFINES += QQNX_LGMON
+ SOURCES += qqnxlgmon.cpp
+ LIBS += -llgmon
+}
+
OTHER_FILES += qnx.json
QMAKE_CXXFLAGS += -I./private
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
index a42f73415e..800cb96bdf 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,6 +49,7 @@ QQnxAbstractVirtualKeyboard::QQnxAbstractVirtualKeyboard(QObject *parent)
, m_visible(false)
, m_locale(QLocale::system())
, m_keyboardMode(Default)
+ , m_enterKeyType(DefaultReturn)
{
}
@@ -59,26 +60,35 @@ void QQnxAbstractVirtualKeyboard::setKeyboardMode(KeyboardMode mode)
m_keyboardMode = mode;
- applyKeyboardMode(mode);
+ if (m_visible)
+ applyKeyboardOptions();
}
-void QQnxAbstractVirtualKeyboard::setInputHintsFromObject(QObject *focusObject)
+void QQnxAbstractVirtualKeyboard::setEnterKeyType(EnterKeyType type)
{
- if (focusObject) {
- const Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(
- focusObject->property("inputMethodHints").toInt());
- if (hints & Qt::ImhEmailCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Email);
- } else if (hints & Qt::ImhDialableCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone);
- } else if (hints & Qt::ImhUrlCharactersOnly) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Web);
- } else if (hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhDigitsOnly ||
- hints & Qt::ImhDate || hints & Qt::ImhTime) {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::NumPunc);
- } else {
- setKeyboardMode(QQnxAbstractVirtualKeyboard::Default);
- }
+ if (type == m_enterKeyType)
+ return;
+
+ m_enterKeyType = type;
+
+ if (m_visible)
+ applyKeyboardOptions();
+}
+
+void QQnxAbstractVirtualKeyboard::setInputHints(int inputHints)
+{
+ if (inputHints & Qt::ImhEmailCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Email);
+ } else if (inputHints & Qt::ImhDialableCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Phone);
+ } else if (inputHints & Qt::ImhUrlCharactersOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Url);
+ } else if (inputHints & Qt::ImhFormattedNumbersOnly || inputHints & Qt::ImhDigitsOnly) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Number);
+ } else if (inputHints & Qt::ImhDate || inputHints & Qt::ImhTime) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::NumPunc); // Use NumPunc so that : is available.
+ } else if (inputHints & Qt::ImhHiddenText) {
+ setKeyboardMode(QQnxAbstractVirtualKeyboard::Password);
} else {
setKeyboardMode(QQnxAbstractVirtualKeyboard::Default);
}
diff --git a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
index 9b911e1dec..bff8c56835 100644
--- a/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
+++ b/src/plugins/platforms/qnx/qqnxabstractvirtualkeyboard.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -51,18 +51,20 @@ class QQnxAbstractVirtualKeyboard : public QObject
{
Q_OBJECT
public:
- // NOTE: Not all the following keyboard modes are currently used.
+ // Keyboard Types currently supported.
// Default - Regular Keyboard
// Url/Email - Enhanced keys for each types.
// Web - Regular keyboard with two blank keys, currently unused.
// NumPunc - Numbers & Punctionation, alternate to Symbol
+ // Number - Number pad
// Symbol - All symbols, alternate to NumPunc, currently unused.
- // Phone - Phone enhanced keyboard - currently unused as no alternate keyboard available to access a-zA-Z
- // Pin - Keyboard for entering Pins (Hex values) currently unused.
+ // Phone - Phone enhanced keyboard
+ // Pin - Keyboard for entering Pins (Hex values).
+ // Password - Keyboard with lots of extra characters for password input.
+ // Alphanumeric - Similar to password without any of the security implications.
//
- // SPECIAL NOTE: Usage of NumPunc may have to be removed, ABC button is non-functional.
- //
- enum KeyboardMode { Default, Url, Email, Web, NumPunc, Symbol, Phone, Pin };
+ enum KeyboardMode { Default, Url, Email, Web, NumPunc, Number, Symbol, Phone, Pin, Password, Alphanumeric };
+ enum EnterKeyType { DefaultReturn, Connect, Done, Go, Join, Next, Search, Send, Submit };
explicit QQnxAbstractVirtualKeyboard(QObject *parent = 0);
@@ -74,8 +76,11 @@ public:
QLocale locale() const { return m_locale; }
void setKeyboardMode(KeyboardMode mode);
- void setInputHintsFromObject(QObject *focusObject);
+ void setEnterKeyType(EnterKeyType type);
+
+ void setInputHints(int inputHints);
KeyboardMode keyboardMode() const { return m_keyboardMode; }
+ EnterKeyType enterKeyType() const { return m_enterKeyType; }
Q_SIGNALS:
void heightChanged(int height);
@@ -83,7 +88,7 @@ Q_SIGNALS:
void localeChanged(const QLocale &locale);
protected:
- virtual void applyKeyboardMode(KeyboardMode mode) = 0;
+ virtual void applyKeyboardOptions() = 0;
void setHeight(int height);
void setVisible(bool visible);
@@ -94,6 +99,7 @@ private:
bool m_visible;
QLocale m_locale;
KeyboardMode m_keyboardMode;
+ EnterKeyType m_enterKeyType;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxbuffer.cpp b/src/plugins/platforms/qnx/qqnxbuffer.cpp
index abb8a07026..e9afd5232b 100644
--- a/src/plugins/platforms/qnx/qqnxbuffer.cpp
+++ b/src/plugins/platforms/qnx/qqnxbuffer.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxbuffer.h"
#include <QtCore/QDebug>
@@ -66,34 +68,30 @@ QQnxBuffer::QQnxBuffer(screen_buffer_t buffer)
qBufferDebug() << Q_FUNC_INFO << "normal";
// Get size of buffer
- errno = 0;
int size[2];
- int result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (result != 0)
- qFatal("QQNX: failed to query buffer size, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_BUFFER_SIZE, size),
+ "Failed to query buffer size");
// Get stride of buffer
- errno = 0;
int stride;
- result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride);
- if (result != 0)
- qFatal("QQNX: failed to query buffer stride, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE, &stride),
+ "Failed to query buffer stride");
// Get access to buffer's data
errno = 0;
uchar *dataPtr = 0;
- result = screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr);
- if (result != 0)
- qFatal("QQNX: failed to query buffer pointer, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER, (void **)&dataPtr),
+ "Failed to query buffer pointer");
+
if (dataPtr == 0)
qFatal("QQNX: buffer pointer is NULL, errno=%d", errno);
// Get format of buffer
- errno = 0;
int screenFormat;
- result = screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat);
- if (result != 0)
- qFatal("QQNX: failed to query buffer format, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_FORMAT, &screenFormat),
+ "Failed to query buffer format");
// Convert screen format to QImage format
QImage::Format imageFormat = QImage::Format_Invalid;
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index 984de67d7d..3c08cc9f82 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2013 - 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -86,8 +86,9 @@ void QQnxEglWindow::createEGLSurface()
// the window's buffers before we create the EGL surface
const QSize surfaceSize = requestedBufferSize();
if (!surfaceSize.isValid()) {
- qFatal("QQNX: Trying to create 0 size EGL surface. "
+ qWarning("QQNX: Trying to create 0 size EGL surface. "
"Please set a valid window size before calling QOpenGLContext::makeCurrent()");
+ return;
}
setBufferSize(surfaceSize);
@@ -104,8 +105,8 @@ void QQnxEglWindow::createEGLSurface()
, platformOpenGLContext()->getEglConfig(),
(EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs);
if (m_eglSurface == EGL_NO_SURFACE) {
- QQnxGLContext::checkEGLError("eglCreateWindowSurface");
- qFatal("QQNX: failed to create EGL surface, err=%d", eglGetError());
+ const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface");
+ qWarning("QQNX: failed to create EGL surface, err=%d", error);
}
}
@@ -134,13 +135,14 @@ void QQnxEglWindow::swapEGLBuffers()
if (eglResult != EGL_TRUE)
qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
- if (m_cover)
- m_cover->updateCover();
+ windowPosted();
}
EGLSurface QQnxEglWindow::getSurface()
{
if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
+ const QMutexLocker locker(&m_mutex); //Set geomety must not reset the requestedBufferSize till
+ //the surface is created
if (m_eglSurface != EGL_NO_SURFACE) {
platformOpenGLContext()->doneCurrent();
destroyEGLSurface();
@@ -172,17 +174,9 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
QSize QQnxEglWindow::requestedBufferSize() const
{
- const QMutexLocker locker(&m_mutex);
return m_requestedBufferSize;
}
-void QQnxEglWindow::adjustBufferSize()
-{
- const QSize windowSize = window()->size();
- if (windowSize != bufferSize())
- setBufferSize(windowSize);
-}
-
void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
@@ -220,7 +214,6 @@ int QQnxEglWindow::pixelFormat() const
void QQnxEglWindow::resetBuffers()
{
- const QMutexLocker locker(&m_mutex);
m_requestedBufferSize = QSize();
}
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index fc53afcd7a..a6a223c58e 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -68,8 +68,6 @@ public:
// Called by QQnxGLContext::createSurface()
QSize requestedBufferSize() const;
- void adjustBufferSize();
-
protected:
int pixelFormat() const;
void resetBuffers();
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index 34e8150928..3a365be408 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -132,7 +132,7 @@ QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
}
}
- m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs());
+ m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, shareContext, contextAttrs(format));
if (m_eglContext == EGL_NO_CONTEXT) {
checkEGLError("eglCreateContext");
qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
@@ -227,7 +227,8 @@ bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext);
if (eglResult != EGL_TRUE) {
checkEGLError("eglMakeCurrent");
- qFatal("QQNX: failed to set current EGL context, err=%d", eglGetError());
+ qWarning("QQNX: failed to set current EGL context, err=%d", eglGetError());
+ return false;
}
return (eglResult == EGL_TRUE);
}
@@ -274,13 +275,13 @@ EGLDisplay QQnxGLContext::getEglDisplay() {
return ms_eglDisplay;
}
-EGLint *QQnxGLContext::contextAttrs()
+EGLint *QQnxGLContext::contextAttrs(const QSurfaceFormat &format)
{
qGLContextDebug() << Q_FUNC_INFO;
// Choose EGL settings based on OpenGL version
#if defined(QT_OPENGL_ES_2)
- static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, format.version().first, EGL_NONE };
return attrs;
#else
return 0;
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 2b12657da9..af89586bd5 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -88,7 +88,7 @@ private:
EGLContext m_eglContext;
EGLSurface m_currentEglSurface;
- static EGLint *contextAttrs();
+ static EGLint *contextAttrs(const QSurfaceFormat &format);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglobal.cpp b/src/plugins/platforms/qnx/qqnxglobal.cpp
new file mode 100644
index 0000000000..cef37af84e
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxglobal.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <errno.h>
+
+#include <QDebug>
+#include "qqnxintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical)
+{
+ if (!rc && (QQnxIntegration::options() & QQnxIntegration::AlwaysFlushScreenContext)
+ && QQnxIntegration::screenContext() != 0) {
+ rc = screen_flush_context(QQnxIntegration::screenContext(), 0);
+ }
+
+ if (rc) {
+ if (critical)
+ qCritical("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
+ else
+ qWarning("%s - Screen: %s - Error: %s (%i)", funcInfo, message, strerror(errno), errno);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglobal.h b/src/plugins/platforms/qnx/qqnxglobal.h
new file mode 100644
index 0000000000..8cfbfb084a
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxglobal.h
@@ -0,0 +1,59 @@
+/***************************************************************************
+**
+** Copyright (C) 2011 - 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXGLOBAL_H
+#define QQNXGLOBAL_H
+
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+void qScreenCheckError(int rc, const char *funcInfo, const char *message, bool critical);
+
+#define Q_SCREEN_CHECKERROR(x, message) \
+qScreenCheckError(x, Q_FUNC_INFO, message, false)
+
+#define Q_SCREEN_CRITICALERROR(x, message) \
+qScreenCheckError(x, Q_FUNC_INFO, message, true)
+
+QT_END_NAMESPACE
+
+#endif // QQNXGLOBAL_H
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
index 580553f6e2..619883e843 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,10 +40,10 @@
****************************************************************************/
#include "qqnxinputcontext_imf.h"
-#include "qqnxeventthread.h"
#include "qqnxabstractvirtualkeyboard.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
+#include "qqnxscreeneventhandler.h"
#include <QtGui/QGuiApplication>
#include <QtGui/QInputMethodEvent>
@@ -54,6 +54,8 @@
#include <QtCore/QVariant>
#include <QtCore/QVariantHash>
#include <QtCore/QWaitCondition>
+#include <QtCore/QQueue>
+#include <QtCore/QGlobalStatic>
#include <dlfcn.h>
#include "imf/imf_client.h"
@@ -62,9 +64,9 @@
#include <sys/keycodes.h>
#if defined(QQNXINPUTCONTEXT_IMF_EVENT_DEBUG)
-#define qInputContextIMFEventDebug qDebug
+#define qInputContextIMFRequestDebug qDebug
#else
-#define qInputContextIMFEventDebug QT_NO_QDEBUG_MACRO
+#define qInputContextIMFRequestDebug QT_NO_QDEBUG_MACRO
#endif
#if defined(QQNXINPUTCONTEXT_DEBUG)
@@ -73,492 +75,426 @@
#define qInputContextDebug QT_NO_QDEBUG_MACRO
#endif
-/** TODO:
- Support inputMethodHints to restrict input (needs additional features in IMF).
-*/
+static QQnxInputContext *sInputContextInstance;
+static QColor sSelectedColor(0,0xb8,0,85);
-#define STRX(x) #x
-#define STR(x) STRX(x)
-
-// Someone tell me why input_control methods are in this namespace, but the rest is not.
-using namespace InputMethodSystem;
-
-#define qs(x) QString::fromLatin1(x)
-#define iarg(name) event->mArgs[qs(#name)] = QVariant::fromValue(name)
-#define parg(name) event->mArgs[qs(#name)] = QVariant::fromValue((void*)name)
-namespace
-{
-
-spannable_string_t *toSpannableString(const QString &text);
+static const input_session_t *sSpellCheckSession = 0;
static const input_session_t *sInputSession = 0;
-bool isSessionOkay(input_session_t *ic)
+static bool isSessionOkay(input_session_t *ic)
{
return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id;
}
enum ImfEventType
{
- ImfBeginBatchEdit,
- ImfClearMetaKeyStates,
ImfCommitText,
ImfDeleteSurroundingText,
- ImfEndBatchEdit,
ImfFinishComposingText,
- ImfGetCursorCapsMode,
ImfGetCursorPosition,
- ImfGetExtractedText,
- ImfGetSelectedText,
ImfGetTextAfterCursor,
ImfGetTextBeforeCursor,
- ImfPerformEditorAction,
- ImfReportFullscreenMode,
ImfSendEvent,
- ImfSendAsyncEvent,
ImfSetComposingRegion,
ImfSetComposingText,
- ImfSetSelection
+ ImfIsTextSelected,
+ ImfIsAllTextSelected,
};
-// We use this class as a round about way to support a posting synchronous event into
-// Qt's main thread from the IMF thread.
-class ImfEventResult
-{
-public:
- ImfEventResult()
- {
- m_mutex.lock();
- }
-
- ~ImfEventResult()
- {
- m_mutex.unlock();
- }
-
- void wait()
- {
- m_wait.wait(&m_mutex);
- }
-
- void signal()
- {
- m_wait.wakeAll();
- }
-
- void setResult(const QVariant& result)
- {
- m_mutex.lock();
- m_retVal = result;
- signal();
- m_mutex.unlock();
- }
-
- QVariant result()
- {
- return m_retVal;
- }
-
-private:
- QVariant m_retVal;
- QMutex m_mutex;
- QWaitCondition m_wait;
+struct SpellCheckInfo {
+ SpellCheckInfo(void *_context, void (*_spellCheckDone)(void *, const QString &, const QList<int> &))
+ : context(_context), spellCheckDone(_spellCheckDone) {}
+ void *context;
+ void (*spellCheckDone)(void *, const QString &, const QList<int> &);
};
+Q_GLOBAL_STATIC(QQueue<SpellCheckInfo>, sSpellCheckQueue)
-class ImfEvent : public QEvent
+// IMF requests all arrive on IMF's own thread and have to be posted to the main thread to be processed.
+class QQnxImfRequest
{
- public:
- ImfEvent(input_session_t *session, ImfEventType type, ImfEventResult *result) :
- QEvent((QEvent::Type)sUserEventType),
- m_session(session),
- m_imfType(type),
- m_result(result)
- {
- }
- ~ImfEvent() { }
-
- input_session_t *m_session;
- ImfEventType m_imfType;
- QVariantHash m_args;
- ImfEventResult *m_result;
-
- static int sUserEventType;
+public:
+ QQnxImfRequest(input_session_t *_session, ImfEventType _type)
+ : session(_session), type(_type)
+ { }
+ ~QQnxImfRequest() { }
+
+ input_session_t *session;
+ ImfEventType type;
+ union {
+ struct {
+ int32_t n;
+ int32_t flags;
+ bool before;
+ spannable_string_t *result;
+ } gtac; // ic_get_text_before_cursor/ic_get_text_after_cursor
+ struct {
+ int32_t result;
+ } gcp; // ic_get_cursor_position
+ struct {
+ int32_t start;
+ int32_t end;
+ int32_t result;
+ } scr; // ic_set_composing_region
+ struct {
+ spannable_string_t* text;
+ int32_t new_cursor_position;
+ int32_t result;
+ } sct; // ic_set_composing_text
+ struct {
+ spannable_string_t* text;
+ int32_t new_cursor_position;
+ int32_t result;
+ } ct; // ic_commit_text
+ struct {
+ int32_t result;
+ } fct; // ic_finish_composing_text
+ struct {
+ int32_t left_length;
+ int32_t right_length;
+ int32_t result;
+ } dst; // ic_delete_surrounding_text
+ struct {
+ event_t *event;
+ int32_t result;
+ } sae; // ic_send_async_event/ic_send_event
+ struct {
+ int32_t *pIsSelected;
+ int32_t result;
+ } its; // ic_is_text_selected/ic_is_all_text_selected
+ };
};
-int ImfEvent::sUserEventType = QEvent::registerEventType();
-static int32_t imfBeginBatchEdit(input_session_t *ic)
+// Invoke an IMF initiated request synchronously on Qt's main thread. As describe below all
+// IMF requests are made from another thread but need to be executed on the main thread.
+static void executeIMFRequest(QQnxImfRequest *event)
+{
+ QMetaObject::invokeMethod(sInputContextInstance,
+ "processImfEvent",
+ Qt::BlockingQueuedConnection,
+ Q_ARG(QQnxImfRequest*, event));
+}
+
+// The following functions (ic_*) are callback functions called by the input system to query information
+// about the text object that currently has focus or to make changes to it. All calls are made from the
+// input system's own thread. The pattern for each callback function is to copy its parameters into
+// a QQnxImfRequest structure and call executeIMFRequest to have it passed synchronously to Qt's main thread.
+// Any return values should be pre-initialised with suitable default values as in some cases
+// (e.g. a stale session) the call will return without having executed any request specific code.
+//
+// To make the correspondence more obvious, the names of these functions match those defined in the headers.
+// They're in an anonymous namespace to avoid compiler conflicts with external functions defined with the
+// same names.
+namespace
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfBeginBatchEdit, &result);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_begin_batch_edit(input_session_t *ic)
+{
+ Q_UNUSED(ic);
- return ret;
+ // Ignore silently.
+ return 0;
}
-static int32_t imfClearMetaKeyStates(input_session_t *ic, int32_t states)
+// End composition, committing the supplied text.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfClearMetaKeyStates, &result);
- iarg(states);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+ QQnxImfRequest event(ic, ImfCommitText);
+ event.ct.text = text;
+ event.ct.new_cursor_position = new_cursor_position;
+ event.ct.result = -1;
+ executeIMFRequest(&event);
- return ret;
+ return event.ct.result;
}
-static int32_t imfCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+// Delete left_length characters before and right_length characters after the cursor.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfCommitText, &result);
- parg(text);
- iarg(new_cursor_position);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfDeleteSurroundingText);
+ event.dst.left_length = left_length;
+ event.dst.right_length = right_length;
+ event.dst.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.dst.result;
}
-static int32_t imfDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length)
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_end_batch_edit(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfDeleteSurroundingText, &result);
- iarg(left_length);
- iarg(right_length);
+ Q_UNUSED(ic);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ // Ignore silently.
+ return 0;
}
-static int32_t imfEndBatchEdit(input_session_t *ic)
+// End composition, committing what's there.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_finish_composing_text(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfEndBatchEdit, &result);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
+ QQnxImfRequest event(ic, ImfFinishComposingText);
+ event.fct.result = -1;
+ executeIMFRequest(&event);
- return ret;
+ return event.fct.result;
}
-static int32_t imfFinishComposingText(input_session_t *ic)
+// Return the position of the cursor.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_get_cursor_position(input_session_t *ic)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfFinishComposingText, &result);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetCursorPosition);
+ event.gcp.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.gcp.result;
}
-static int32_t imfGetCursorCapsMode(input_session_t *ic, int32_t req_modes)
+// Return the n characters after the cursor.
+// See comment at beginning of namespace declaration for general information
+static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetCursorCapsMode, &result);
- iarg(req_modes);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetTextAfterCursor);
+ event.gtac.n = n;
+ event.gtac.flags = flags;
+ event.gtac.result = 0;
+ executeIMFRequest(&event);
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.gtac.result;
}
-static int32_t imfGetCursorPosition(input_session_t *ic)
+// Return the n characters before the cursor.
+// See comment at beginning of namespace declaration for general information
+static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetCursorPosition, &result);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfGetTextBeforeCursor);
+ event.gtac.n = n;
+ event.gtac.flags = flags;
+ event.gtac.result = 0;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
-
- return ret;
+ return event.gtac.result;
}
-static extracted_text_t *imfGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
+// Process an event from IMF. Primarily used for reflecting back keyboard events.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_send_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic)) {
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = (spannable_string_t *)calloc(sizeof(spannable_string_t),1);
- return et;
- }
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetExtractedText, &result);
- parg(request);
- iarg(flags);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest imfEvent(ic, ImfSendEvent);
+ imfEvent.sae.event = event;
+ imfEvent.sae.result = -1;
+ executeIMFRequest(&imfEvent);
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return imfEvent.sae.result;
}
-static spannable_string_t *imfGetSelectedText(input_session_t *ic, int32_t flags)
+// Same as ic_send_event.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetSelectedText, &result);
- iarg(flags);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ // There's no difference from our point of view between ic_send_event & ic_send_async_event
+ QQnxImfRequest imfEvent(ic, ImfSendEvent);
+ imfEvent.sae.event = event;
+ imfEvent.sae.result = -1;
+ executeIMFRequest(&imfEvent);
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return imfEvent.sae.result;
}
-static spannable_string_t *imfGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags)
+// Set the range of text between start and end as the composition range.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetTextAfterCursor, &result);
- iarg(n);
- iarg(flags);
+ QQnxImfRequest event(ic, ImfSetComposingRegion);
+ event.scr.start = start;
+ event.scr.end = end;
+ event.scr.result = -1;
+ executeIMFRequest(&event);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return event.scr.result;
}
-static spannable_string_t *imfGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags)
+// Update the composition range with the supplied text. This can be called when no composition
+// range is in effect in which case one is started at the current cursor position.
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
+ QQnxImfRequest event(ic, ImfSetComposingText);
+ event.sct.text = text;
+ event.sct.new_cursor_position = new_cursor_position;
+ event.sct.result = -1;
+ executeIMFRequest(&event);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfGetTextBeforeCursor, &result);
- iarg(n);
- iarg(flags);
-
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- return result.result().value<extracted_text_t *>();
+ return event.sct.result;
}
-static int32_t imfPerformEditorAction(input_session_t *ic, int32_t editor_action)
+// Indicate if any text is selected
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfPerformEditorAction, &result);
- iarg(editor_action);
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+ QQnxImfRequest event(ic, ImfIsTextSelected);
+ event.its.pIsSelected = pIsSelected;
+ event.its.result = -1;
+ executeIMFRequest(&event);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.its.result;
}
-static int32_t imfReportFullscreenMode(input_session_t *ic, int32_t enabled)
+// Indicate if all text is selected
+// See comment at beginning of namespace declaration for general information
+static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ qInputContextIMFRequestDebug() << Q_FUNC_INFO;
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfReportFullscreenMode, &result);
- iarg(enabled);
+ QQnxImfRequest event(ic, ImfIsAllTextSelected);
+ event.its.pIsSelected = pIsSelected;
+ event.its.result = -1;
+ executeIMFRequest(&event);
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
-
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ return event.its.result;
}
-static int32_t imfSendEvent(input_session_t *ic, event_t *event)
-{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEvent *imfEvent = new ImfEvent(ic, ImfSendEvent, 0);
- imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast<void *>(event));
+// LCOV_EXCL_START - exclude from code coverage analysis
+// The following functions are defined in the IMF headers but are not currently called.
- QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent);
+// Not currently used
+static int32_t ic_perform_editor_action(input_session_t *ic, int32_t editor_action)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(editor_action);
+ qCritical() << "ic_perform_editor_action not implemented";
return 0;
}
-static int32_t imfSendAsyncEvent(input_session_t *ic, event_t *event)
+// Not currently used
+static int32_t ic_report_fullscreen_mode(input_session_t *ic, int32_t enabled)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- ImfEvent *imfEvent = new ImfEvent(ic, ImfSendAsyncEvent, 0);
- imfEvent->m_args[qs("event")] = QVariant::fromValue(static_cast<void *>(event));
-
- QCoreApplication::postEvent(QCoreApplication::instance(), imfEvent);
+ Q_UNUSED(ic);
+ Q_UNUSED(enabled);
+ qCritical() << "ic_report_fullscreen_mode not implemented";
return 0;
}
-static int32_t imfSetComposingRegion(input_session_t *ic, int32_t start, int32_t end)
+// Not currently used
+static extracted_text_t *ic_get_extracted_text(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(request);
+ Q_UNUSED(flags);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetComposingRegion, &result);
- iarg(start);
- iarg(end);
+ qCritical() << "ic_get_extracted_text not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// Not currently used
+static spannable_string_t *ic_get_selected_text(input_session_t *ic, int32_t flags)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(flags);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ qCritical() << "ic_get_selected_text not implemented";
+ return 0;
}
-static int32_t imfSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+// Not currently used
+static int32_t ic_get_cursor_caps_mode(input_session_t *ic, int32_t req_modes)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(req_modes);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetComposingText, &result);
- parg(text);
- iarg(new_cursor_position);
+ qCritical() << "ic_get_cursor_caps_mode not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// Not currently used
+static int32_t ic_clear_meta_key_states(input_session_t *ic, int32_t states)
+{
+ Q_UNUSED(ic);
+ Q_UNUSED(states);
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
+ qCritical() << "ic_clear_meta_key_states not implemented";
+ return 0;
}
-static int32_t imfSetSelection(input_session_t *ic, int32_t start, int32_t end)
+// Not currently used
+static int32_t ic_set_selection(input_session_t *ic, int32_t start, int32_t end)
{
- qInputContextIMFEventDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ Q_UNUSED(ic);
+ Q_UNUSED(start);
+ Q_UNUSED(end);
- ImfEventResult result;
- ImfEvent *event = new ImfEvent(ic, ImfSetSelection, &result);
- iarg(start);
- iarg(end);
+ qCritical() << "ic_set_selection not implemented";
+ return 0;
+}
- QCoreApplication::postEvent(QCoreApplication::instance(), event);
+// End of un-hittable code
+// LCOV_EXCL_STOP
- result.wait();
- int32_t ret = result.result().value<int32_t>();
- return ret;
-}
static connection_interface_t ic_funcs = {
- imfBeginBatchEdit,
- imfClearMetaKeyStates,
- imfCommitText,
- imfDeleteSurroundingText,
- imfEndBatchEdit,
- imfFinishComposingText,
- imfGetCursorCapsMode,
- imfGetCursorPosition,
- imfGetExtractedText,
- imfGetSelectedText,
- imfGetTextAfterCursor,
- imfGetTextBeforeCursor,
- imfPerformEditorAction,
- imfReportFullscreenMode,
- NULL, //ic_send_key_event
- imfSendEvent,
- imfSendAsyncEvent,
- imfSetComposingRegion,
- imfSetComposingText,
- imfSetSelection,
- NULL, //ic_set_candidates,
+ ic_begin_batch_edit,
+ ic_clear_meta_key_states,
+ ic_commit_text,
+ ic_delete_surrounding_text,
+ ic_end_batch_edit,
+ ic_finish_composing_text,
+ ic_get_cursor_caps_mode,
+ ic_get_cursor_position,
+ ic_get_extracted_text,
+ ic_get_selected_text,
+ ic_get_text_after_cursor,
+ ic_get_text_before_cursor,
+ ic_perform_editor_action,
+ ic_report_fullscreen_mode,
+ 0, //ic_send_key_event
+ ic_send_event,
+ ic_send_async_event,
+ ic_set_composing_region,
+ ic_set_composing_text,
+ ic_set_selection,
+ 0, //ic_set_candidates,
+ 0, //ic_get_cursor_offset,
+ 0, //ic_get_selection,
+ ic_is_text_selected,
+ ic_is_all_text_selected,
+ 0, //ic_get_max_cursor_offset_t
};
+} // namespace
+
static void
-initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId)
+initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId, int eventSize)
{
static int s_transactionId;
// Make sure structure is squeaky clean since it's not clear just what is significant.
- memset(pEvent, 0, sizeof(event_t));
+ memset(pEvent, 0, eventSize);
pEvent->event_type = eventType;
pEvent->event_id = eventId;
pEvent->pid = getpid();
@@ -566,31 +502,20 @@ initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType,
pEvent->transaction_id = ++s_transactionId;
}
-spannable_string_t *toSpannableString(const QString &text)
+static spannable_string_t *toSpannableString(const QString &text)
{
qInputContextDebug() << Q_FUNC_INFO << text;
- spannable_string_t *pString = reinterpret_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
- pString->str = (wchar_t *)malloc(sizeof(wchar_t) * text.length() + 1);
- pString->length = text.length();
+ spannable_string_t *pString = static_cast<spannable_string_t *>(malloc(sizeof(spannable_string_t)));
+ pString->str = static_cast<wchar_t *>(malloc(sizeof(wchar_t) * text.length() + 1));
+ pString->length = text.toWCharArray(pString->str);
pString->spans = 0;
pString->spans_count = 0;
-
- const QChar *pData = text.constData();
- wchar_t *pDst = pString->str;
-
- while (!pData->isNull())
- {
- *pDst = pData->unicode();
- pDst++;
- pData++;
- }
- *pDst = 0;
+ pString->str[pString->length] = 0;
return pString;
}
-} // namespace
static const input_session_t *(*p_ictrl_open_session)(connection_interface_t *) = 0;
static void (*p_ictrl_close_session)(input_session_t *) = 0;
@@ -645,27 +570,30 @@ QT_BEGIN_NAMESPACE
QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
QPlatformInputContext(),
- m_lastCaretPos(0),
+ m_caretPosition(0),
m_isComposing(false),
+ m_isUpdatingText(false),
m_inputPanelVisible(false),
m_inputPanelLocale(QLocale::c()),
+ m_focusObject(0),
m_integration(integration),
- m_virtualKeyboad(keyboard)
+ m_virtualKeyboard(keyboard)
{
qInputContextDebug() << Q_FUNC_INFO;
if (!imfAvailable())
return;
- if ( p_imf_client_init() != 0 ) {
+ // Save a pointer to ourselves so we can execute calls from IMF through executeIMFRequest
+ // In practice there will only ever be a single instance.
+ Q_ASSERT(sInputContextInstance == 0);
+ sInputContextInstance = this;
+
+ if (p_imf_client_init() != 0) {
s_imfInitFailed = true;
qCritical("imf_client_init failed - IMF services will be unavailable");
}
- QCoreApplication::instance()->installEventFilter(this);
-
- // p_vkb_init_selection_service();
-
connect(&keyboard, SIGNAL(visibilityChanged(bool)), this, SLOT(keyboardVisibilityChanged(bool)));
connect(&keyboard, SIGNAL(localeChanged(QLocale)), this, SLOT(keyboardLocaleChanged(QLocale)));
keyboardVisibilityChanged(keyboard.isVisible());
@@ -676,168 +604,75 @@ QQnxInputContext::~QQnxInputContext()
{
qInputContextDebug() << Q_FUNC_INFO;
+ Q_ASSERT(sInputContextInstance == this);
+ sInputContextInstance = 0;
+
if (!imfAvailable())
return;
- QCoreApplication::instance()->removeEventFilter(this);
p_imf_client_disconnect();
}
-#define getarg(type, name) type name = imfEvent->mArgs[qs(#name)].value<type>()
-#define getparg(type, name) type name = (type)(imfEvent->mArgs[qs(#name)].value<void*>())
-
bool QQnxInputContext::isValid() const
{
return imfAvailable();
}
-bool QQnxInputContext::eventFilter(QObject *obj, QEvent *event)
+void QQnxInputContext::processImfEvent(QQnxImfRequest *imfEvent)
{
- if (event->type() == ImfEvent::sUserEventType) {
- // Forward the event to our real handler.
- ImfEvent *imfEvent = static_cast<ImfEvent *>(event);
- switch (imfEvent->m_imfType) {
- case ImfBeginBatchEdit: {
- int32_t ret = onBeginBatchEdit(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfClearMetaKeyStates: {
- getarg(int32_t, states);
- int32_t ret = onClearMetaKeyStates(imfEvent->m_session, states);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfCommitText: {
- getparg(spannable_string_t*, text);
- getarg(int32_t, new_cursor_position);
- int32_t ret = onCommitText(imfEvent->m_session, text, new_cursor_position);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfDeleteSurroundingText: {
- getarg(int32_t, left_length);
- getarg(int32_t, right_length);
- int32_t ret = onDeleteSurroundingText(imfEvent->m_session, left_length, right_length);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfEndBatchEdit: {
- int32_t ret = onEndBatchEdit(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfFinishComposingText: {
- int32_t ret = onFinishComposingText(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetCursorCapsMode: {
- getarg(int32_t, req_modes);
- int32_t ret = onGetCursorCapsMode(imfEvent->m_session, req_modes);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetCursorPosition: {
- int32_t ret = onGetCursorPosition(imfEvent->m_session);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
-
- case ImfGetExtractedText: {
- getparg(extracted_text_request_t*, request);
- getarg(int32_t, flags);
- extracted_text_t *ret = onGetExtractedText(imfEvent->m_session, request, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ // If input session is no longer current, just bail, imfEvent should already be set with the appropriate
+ // return value. The only exception is spell check events since they're not associated with the
+ // object with focus.
+ if (imfEvent->type != ImfSendEvent || imfEvent->sae.event->event_type != EVENT_SPELL_CHECK) {
+ if (!isSessionOkay(imfEvent->session))
+ return;
+ }
- case ImfGetSelectedText: {
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetSelectedText(imfEvent->m_session, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ switch (imfEvent->type) {
+ case ImfCommitText:
+ imfEvent->ct.result = onCommitText(imfEvent->ct.text, imfEvent->ct.new_cursor_position);
+ break;
- case ImfGetTextAfterCursor: {
- getarg(int32_t, n);
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetTextAfterCursor(imfEvent->m_session, n, flags);
- imfEvent->m_result->setResult(QVariant::fromValue(static_cast<void *>(ret)));
- break;
- }
+ case ImfDeleteSurroundingText:
+ imfEvent->dst.result = onDeleteSurroundingText(imfEvent->dst.left_length, imfEvent->dst.right_length);
+ break;
- case ImfGetTextBeforeCursor: {
- getarg(int32_t, n);
- getarg(int32_t, flags);
- spannable_string_t *ret = onGetTextBeforeCursor(imfEvent->m_session, n, flags);
- imfEvent->m_result->setResult(QVariant::fromValue((void*)ret));
- break;
- }
+ case ImfFinishComposingText:
+ imfEvent->fct.result = onFinishComposingText();
+ break;
- case ImfPerformEditorAction: {
- getarg(int32_t, editor_action);
- int32_t ret = onPerformEditorAction(imfEvent->m_session, editor_action);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfGetCursorPosition:
+ imfEvent->gcp.result = onGetCursorPosition();
+ break;
- case ImfReportFullscreenMode: {
- getarg(int32_t, enabled);
- int32_t ret = onReportFullscreenMode(imfEvent->m_session, enabled);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfGetTextAfterCursor:
+ imfEvent->gtac.result = onGetTextAfterCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
+ break;
- case ImfSendEvent: {
- getparg(event_t*, event);
- onSendEvent(imfEvent->m_session, event);
- break;
- }
+ case ImfGetTextBeforeCursor:
+ imfEvent->gtac.result = onGetTextBeforeCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
+ break;
- case ImfSendAsyncEvent: {
- getparg(event_t*, event);
- onSendAsyncEvent(imfEvent->m_session, event);
- break;
- }
+ case ImfSendEvent:
+ imfEvent->sae.result = onSendEvent(imfEvent->sae.event);
+ break;
- case ImfSetComposingRegion: {
- getarg(int32_t, start);
- getarg(int32_t, end);
- int32_t ret = onSetComposingRegion(imfEvent->m_session, start, end);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfSetComposingRegion:
+ imfEvent->scr.result = onSetComposingRegion(imfEvent->scr.start, imfEvent->scr.end);
+ break;
- case ImfSetComposingText: {
- getparg(spannable_string_t*, text);
- getarg(int32_t, new_cursor_position);
- int32_t ret = onSetComposingText(imfEvent->m_session, text, new_cursor_position);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
+ case ImfSetComposingText:
+ imfEvent->sct.result = onSetComposingText(imfEvent->sct.text, imfEvent->sct.new_cursor_position);
+ break;
- case ImfSetSelection: {
- getarg(int32_t, start);
- getarg(int32_t, end);
- int32_t ret = onSetSelection(imfEvent->m_session, start, end);
- imfEvent->m_result->setResult(QVariant::fromValue(ret));
- break;
- }
- }; //switch
+ case ImfIsTextSelected:
+ imfEvent->its.result = onIsTextSelected(imfEvent->its.pIsSelected);
+ break;
- return true;
- } else {
- // standard event processing
- return QObject::eventFilter(obj, event);
- }
+ case ImfIsAllTextSelected:
+ imfEvent->its.result = onIsAllTextSelected(imfEvent->its.pIsSelected);
+ break;
+ }; //switch
}
bool QQnxInputContext::filterEvent( const QEvent *event )
@@ -845,12 +680,12 @@ bool QQnxInputContext::filterEvent( const QEvent *event )
qInputContextDebug() << Q_FUNC_INFO << event;
switch (event->type()) {
- case QEvent::CloseSoftwareInputPanel: {
+ case QEvent::CloseSoftwareInputPanel:
return dispatchCloseSoftwareInputPanel();
- }
- case QEvent::RequestSoftwareInputPanel: {
+
+ case QEvent::RequestSoftwareInputPanel:
return dispatchRequestSoftwareInputPanel();
- }
+
default:
return false;
}
@@ -869,12 +704,30 @@ void QQnxInputContext::reset()
endComposition();
}
-void QQnxInputContext::update(Qt::InputMethodQueries queries)
+void QQnxInputContext::commit()
{
qInputContextDebug() << Q_FUNC_INFO;
- reset();
+ endComposition();
+}
- QPlatformInputContext::update(queries);
+void QQnxInputContext::update(Qt::InputMethodQueries queries)
+{
+ qInputContextDebug() << Q_FUNC_INFO << queries;
+
+ if (queries & Qt::ImCursorPosition) {
+ int lastCaret = m_caretPosition;
+ updateCursorPosition();
+ // If caret position has changed we need to inform IMF unless this is just due to our own action
+ // such as committing text.
+ if (hasSession() && !m_isUpdatingText && lastCaret != m_caretPosition) {
+ caret_event_t caretEvent;
+ initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED, sizeof(caretEvent));
+ caretEvent.old_pos = lastCaret;
+ caretEvent.new_pos = m_caretPosition;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event caret changed" << lastCaret << m_caretPosition;
+ p_ictrl_dispatch_event(&caretEvent.event);
+ }
+ }
}
void QQnxInputContext::closeSession()
@@ -887,16 +740,23 @@ void QQnxInputContext::closeSession()
p_ictrl_close_session((input_session_t *)sInputSession);
sInputSession = 0;
}
+ // These are likely already in the right state but this depends on the text control
+ // having called reset or commit. So, just in case, set them to proper values.
+ m_isComposing = false;
+ m_composingText.clear();
}
-void QQnxInputContext::openSession()
+bool QQnxInputContext::openSession()
{
- qInputContextDebug() << Q_FUNC_INFO;
if (!imfAvailable())
- return;
+ return false;
closeSession();
sInputSession = p_ictrl_open_session(&ic_funcs);
+
+ qInputContextDebug() << Q_FUNC_INFO;
+
+ return sInputSession != 0;
}
bool QQnxInputContext::hasSession()
@@ -918,79 +778,89 @@ bool QQnxInputContext::hasSelectedText()
bool QQnxInputContext::dispatchRequestSoftwareInputPanel()
{
+ qInputContextDebug() << Q_FUNC_INFO << "requesting keyboard" << m_inputPanelVisible;
m_virtualKeyboard.showKeyboard();
- qInputContextDebug() << Q_FUNC_INFO << "requesting virtual keyboard";
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input || !inputMethodAccepted())
- return true;
-
- if (!hasSession())
- openSession();
- // This also means that the caret position has moved
- QInputMethodQueryEvent query(Qt::ImCursorPosition);
- QCoreApplication::sendEvent(input, &query);
- int caretPos = query.value(Qt::ImCursorPosition).toInt();
- caret_event_t caretEvent;
- memset(&caretEvent, 0, sizeof(caret_event_t));
- initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED);
- caretEvent.old_pos = m_lastCaretPos;
- m_lastCaretPos = caretEvent.new_pos = caretPos;
- p_ictrl_dispatch_event((event_t *)&caretEvent);
return true;
}
bool QQnxInputContext::dispatchCloseSoftwareInputPanel()
{
+ qInputContextDebug() << Q_FUNC_INFO << "hiding keyboard" << m_inputPanelVisible;
m_virtualKeyboard.hideKeyboard();
- qInputContextDebug() << Q_FUNC_INFO << "hiding virtual keyboard";
- // This also means we are stopping composition, but we should already have done that.
return true;
}
/**
* IMF Event Dispatchers.
*/
-bool QQnxInputContext::dispatchFocusEvent(FocusEventId id, int hints)
+bool QQnxInputContext::dispatchFocusGainEvent(int inputHints)
{
- qInputContextDebug() << Q_FUNC_INFO;
+ if (hasSession())
+ dispatchFocusLossEvent();
- if (!sInputSession) {
- qWarning() << Q_FUNC_INFO << "Attempt to dispatch a focus event with no input session.";
- return false;
- }
+ QObject *input = qGuiApp->focusObject();
- if (!imfAvailable())
+ if (!input || !openSession())
return false;
// Set the last caret position to 0 since we don't really have one and we don't
// want to have the old one.
- m_lastCaretPos = 0;
+ m_caretPosition = 0;
+
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(input, &query);
focus_event_t focusEvent;
- memset(&focusEvent, 0, sizeof(focusEvent));
- initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, id);
+ initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_GAINED, sizeof(focusEvent));
focusEvent.style = DEFAULT_STYLE;
- if (hints && Qt::ImhNoPredictiveText)
+ if (inputHints & Qt::ImhNoPredictiveText)
focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION;
- if (hints && Qt::ImhNoAutoUppercase)
+ if (inputHints & Qt::ImhNoAutoUppercase)
focusEvent.style |= NO_AUTO_TEXT;
+ // Following styles are mutually exclusive
+ if (inputHints & Qt::ImhHiddenText) {
+ focusEvent.style |= IMF_PASSWORD_TYPE;
+ } else if (inputHints & Qt::ImhDialableCharactersOnly) {
+ focusEvent.style |= IMF_PHONE_TYPE;
+ } else if (inputHints & Qt::ImhUrlCharactersOnly) {
+ focusEvent.style |= IMF_URL_TYPE;
+ } else if (inputHints & Qt::ImhEmailCharactersOnly) {
+ focusEvent.style |= IMF_EMAIL_TYPE;
+ }
+
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event focus gain style:" << focusEvent.style;
+
p_ictrl_dispatch_event((event_t *)&focusEvent);
return true;
}
-bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
+void QQnxInputContext::dispatchFocusLossEvent()
{
- if (!imfAvailable())
+ if (hasSession()) {
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_event focus lost";
+
+ focus_event_t focusEvent;
+ initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST, sizeof(focusEvent));
+ p_ictrl_dispatch_event((event_t *)&focusEvent);
+ closeSession();
+ }
+}
+
+bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId)
+{
+ Q_UNUSED(scan);
+
+ if (!hasSession())
return false;
int key = (flags & KEY_SYM_VALID) ? sym : cap;
- bool navKey = false;
- switch ( key ) {
+ bool navigationKey = false;
+ switch (key) {
case KEYCODE_RETURN:
/* In a single line edit we should end composition because enter might be used by something.
endComposition();
@@ -1007,27 +877,22 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
break;
case KEYCODE_LEFT:
key = NAVIGATE_LEFT;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_RIGHT:
key = NAVIGATE_RIGHT;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_UP:
key = NAVIGATE_UP;
- navKey = true;
+ navigationKey = true;
break;
case KEYCODE_DOWN:
key = NAVIGATE_DOWN;
- navKey = true;
+ navigationKey = true;
break;
- case KEYCODE_CAPS_LOCK:
- case KEYCODE_LEFT_SHIFT:
- case KEYCODE_RIGHT_SHIFT:
case KEYCODE_LEFT_CTRL:
case KEYCODE_RIGHT_CTRL:
- case KEYCODE_LEFT_ALT:
- case KEYCODE_RIGHT_ALT:
case KEYCODE_MENU:
case KEYCODE_LEFT_HYPER:
case KEYCODE_RIGHT_HYPER:
@@ -1041,85 +906,183 @@ bool QQnxInputContext::handleKeyboardEvent(int flags, int sym, int mod, int scan
break;
}
- if ( mod & KEYMOD_CTRL ) {
- // If CTRL is pressed, just let AIR handle it. But terminate any composition first
- //endComposition();
- return false;
- }
-
// Pass the keys we don't know about on through
if ( key == 0 )
return false;
- // IMF doesn't need key releases so just swallow them.
- if (!(flags & KEY_DOWN))
- return true;
-
- if ( navKey ) {
+ if (navigationKey) {
// Even if we're forwarding up events, we can't do this for
// navigation keys.
if ( flags & KEY_DOWN ) {
navigation_event_t navEvent;
- initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key);
+ initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key, sizeof(navEvent));
navEvent.magnitude = 1;
- qInputContextDebug() << Q_FUNC_INFO << "dispatch navigation event " << key;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even navigation" << key;
p_ictrl_dispatch_event(&navEvent.event);
}
- }
- else {
+ } else {
key_event_t keyEvent;
- initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP);
- keyEvent.key_code = key;
- keyEvent.character = 0;
- keyEvent.meta_key_state = 0;
+ initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP,
+ sizeof(keyEvent));
+ keyEvent.key_code = cap;
+ keyEvent.character = sym;
+ keyEvent.meta_key_state = mod;
+ keyEvent.sequence_id = sequenceId;
p_ictrl_dispatch_event(&keyEvent.event);
- qInputContextDebug() << Q_FUNC_INFO << "dispatch key event " << key;
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even key" << key;
}
- scan = 0;
return true;
}
-void QQnxInputContext::endComposition()
+void QQnxInputContext::updateCursorPosition()
{
- if (!m_isComposing)
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
return;
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ QInputMethodQueryEvent query(Qt::ImCursorPosition);
+ QCoreApplication::sendEvent(input, &query);
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
+
+ qInputContextDebug() << Q_FUNC_INFO << m_caretPosition;
+}
+
+void QQnxInputContext::endComposition()
+{
+ if (!m_isComposing)
return;
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_composingText);
- m_composingText = QString();
- m_isComposing = false;
- QCoreApplication::sendEvent(input, &event);
+ finishComposingText();
- action_event_t actionEvent;
- memset(&actionEvent, 0, sizeof(actionEvent));
- initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION);
- p_ictrl_dispatch_event(&actionEvent.event);
+ if (hasSession()) {
+ action_event_t actionEvent;
+ initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION, sizeof(actionEvent));
+ qInputContextDebug() << Q_FUNC_INFO << "ictrl_dispatch_even end composition";
+ p_ictrl_dispatch_event(&actionEvent.event);
+ }
}
-void QQnxInputContext::setComposingText(QString const& composingText)
+void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_cursor_position)
{
- m_composingText = composingText;
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
+ return;
+
+ if (new_cursor_position > 0)
+ new_cursor_position += text->length - 1;
+
+ m_composingText = QString::fromWCharArray(text->str, text->length);
m_isComposing = true;
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return;
+ qInputContextDebug() << Q_FUNC_INFO << m_composingText << new_cursor_position;
QList<QInputMethodEvent::Attribute> attributes;
- QTextCharFormat format;
- format.setFontUnderline(true);
- attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, composingText.length(), format));
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
+ new_cursor_position,
+ 1,
+ QVariant()));
+
+ for (unsigned int i = 0; i < text->spans_count; ++i) {
+ QColor highlightColor;
+ bool underline = false;
+
+ if ((text->spans[i].attributes_mask & COMPOSED_TEXT_ATTRIB) != 0)
+ underline = true;
+
+ if ((text->spans[i].attributes_mask & ACTIVE_REGION_ATTRIB) != 0) {
+ underline = true;
+ highlightColor = m_highlightColor[ActiveRegion];
+ } else if ((text->spans[i].attributes_mask & AUTO_CORRECTION_ATTRIB) != 0) {
+ highlightColor = m_highlightColor[AutoCorrected];
+ } else if ((text->spans[i].attributes_mask & REVERT_CORRECTION_ATTRIB) != 0) {
+ highlightColor = m_highlightColor[Reverted];
+ }
- QInputMethodEvent event(composingText, attributes);
+ if (underline || highlightColor.isValid()) {
+ QTextCharFormat format;
+ if (underline)
+ format.setFontUnderline(true);
+ if (highlightColor.isValid())
+ format.setBackground(QBrush(highlightColor));
+ qInputContextDebug() << " attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
+ text->spans[i].end - text->spans[i].start + 1, QVariant(format)));
+ }
+ }
+ QInputMethodEvent event(m_composingText, attributes);
+ m_isUpdatingText = true;
QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
+
+ updateCursorPosition();
+}
+
+void QQnxInputContext::finishComposingText()
+{
+ QObject *input = qGuiApp->focusObject();
+
+ if (input) {
+ qInputContextDebug() << Q_FUNC_INFO << m_composingText;
+
+ QInputMethodEvent event;
+ event.setCommitString(m_composingText);
+ m_isUpdatingText = true;
+ QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
+ }
+ m_composingText = QString();
+ m_isComposing = false;
+
+ updateCursorPosition();
+}
+
+// Return the index relative to a UTF-16 sequence of characters for a index that is relative to the
+// corresponding UTF-32 character string given a starting index in the UTF-16 string and a count
+// of the number of lead surrogates prior to that index. Updates the highSurrogateCount to reflect the
+// new surrogate characters encountered.
+static int adjustIndex(const QChar *text, int utf32Index, int utf16StartIndex, int *highSurrogateCount)
+{
+ int utf16Index = utf32Index + *highSurrogateCount;
+ while (utf16StartIndex < utf16Index) {
+ if (text[utf16StartIndex].isHighSurrogate()) {
+ ++utf16Index;
+ ++*highSurrogateCount;
+ }
+ ++utf16StartIndex;
+ }
+ return utf16StartIndex;
+}
+
+int QQnxInputContext::handleSpellCheck(spell_check_event_t *event)
+{
+ // These should never happen.
+ if (sSpellCheckQueue->isEmpty() || event->event.event_id != NOTIFY_SP_CHECK_MISSPELLINGS)
+ return -1;
+
+ SpellCheckInfo callerInfo = sSpellCheckQueue->dequeue();
+ spannable_string_t* spellCheckData = *event->data;
+ QString text = QString::fromWCharArray(spellCheckData->str, spellCheckData->length);
+ // Generate the list of indices indicating misspelled words in the text. We use end + 1
+ // since it's more conventional to have the end index point just past the string. We also
+ // can't use the indices directly since they are relative to UTF-32 encoded data and the
+ // conversion to Qt's UTF-16 internal format might cause lengthening.
+ QList<int> indices;
+ int adjustment = 0;
+ int index = 0;
+ for (unsigned int i = 0; i < spellCheckData->spans_count; ++i) {
+ if (spellCheckData->spans[i].attributes_mask & MISSPELLED_WORD_ATTRIB) {
+ index = adjustIndex(text.data(), spellCheckData->spans[i].start, index, &adjustment);
+ indices.push_back(index);
+ index = adjustIndex(text.data(), spellCheckData->spans[i].end + 1, index, &adjustment);
+ indices.push_back(index);
+ }
+ }
+ callerInfo.spellCheckDone(callerInfo.context, text, indices);
+
+ return 0;
}
int32_t QQnxInputContext::processEvent(event_t *event)
@@ -1128,7 +1091,7 @@ int32_t QQnxInputContext::processEvent(event_t *event)
switch (event->event_type) {
case EVENT_SPELL_CHECK: {
qInputContextDebug() << Q_FUNC_INFO << "EVENT_SPELL_CHECK";
- result = 0;
+ result = handleSpellCheck(reinterpret_cast<spell_check_event_t *>(event));
break;
}
@@ -1140,19 +1103,24 @@ int32_t QQnxInputContext::processEvent(event_t *event)
event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT :
event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0;
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
- QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
+ QQnxScreenEventHandler::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
+ QQnxScreenEventHandler::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
result = 0;
break;
}
case EVENT_KEY: {
- qInputContextDebug() << Q_FUNC_INFO << "EVENT_KEY";
- key_event_t *kevent = static_cast<key_event_t *>(event);
-
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code);
- QQnxEventThread::injectKeyboardEvent(KEY_SYM_VALID | KEY_CAP_VALID, kevent->key_code, 0, 0, kevent->key_code);
-
+ key_event_t *kevent = reinterpret_cast<key_event_t *>(event);
+ int keySym = kevent->character != 0 ? kevent->character : kevent->key_code;
+ int keyCap = kevent->key_code;
+ int modifiers = 0;
+ if (kevent->meta_key_state & META_SHIFT_ON)
+ modifiers |= KEYMOD_SHIFT;
+ int flags = KEY_SYM_VALID | KEY_CAP_VALID;
+ if (event->event_id == IMF_KEY_DOWN)
+ flags |= KEY_DOWN;
+ qInputContextDebug() << Q_FUNC_INFO << "EVENT_KEY" << flags << keySym;
+ QQnxScreenEventHandler::injectKeyboardEvent(flags, keySym, modifiers, 0, keyCap);
result = 0;
break;
}
@@ -1179,339 +1147,175 @@ int32_t QQnxInputContext::processEvent(event_t *event)
* IMF Event Handlers
*/
-int32_t QQnxInputContext::onBeginBatchEdit(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // We don't care.
- return 0;
-}
-
-int32_t QQnxInputContext::onClearMetaKeyStates(input_session_t *ic, int32_t states)
-{
- Q_UNUSED(states);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onClearMetaKeyStates is unsupported.";
- return 0;
-}
-
-int32_t QQnxInputContext::onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+int32_t QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cursor_position)
{
- Q_UNUSED(new_cursor_position); // TODO: How can we set the cursor position it's not part of the API.
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- QString commitString = QString::fromWCharArray(text->str, text->length);
-
- qInputContextDebug() << Q_FUNC_INFO << "Committing [" << commitString << "]";
-
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(commitString, 0, 0);
+ Q_UNUSED(new_cursor_position);
- QCoreApplication::sendEvent(input, &event);
- m_composingText = QString();
+ updateComposition(text, new_cursor_position);
+ finishComposingText();
return 0;
}
-int32_t QQnxInputContext::onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length)
+int32_t QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
{
qInputContextDebug() << Q_FUNC_INFO << "L:" << left_length << " R:" << right_length;
- if (!isSessionOkay(ic))
- return 0;
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- if (hasSelectedText()) {
- QQnxEventThread::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0);
- QQnxEventThread::injectKeyboardEvent(KEY_CAP_VALID, KEYCODE_DELETE, 0, 0, 0);
- reset();
+ if (!input)
return 0;
- }
int replacementLength = left_length + right_length;
int replacementStart = -left_length;
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(QLatin1String(""), replacementStart, replacementLength);
- QCoreApplication::sendEvent(input, &event);
-
- return 0;
-}
-
-int32_t QQnxInputContext::onEndBatchEdit(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- return 0;
-}
-
-int32_t QQnxInputContext::onFinishComposingText(input_session_t *ic)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
+ finishComposingText();
- // Only update the control, no need to send a message back to imf (don't call
- // end composition)
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QLatin1String(""), attributes);
- event.setCommitString(m_composingText);
- m_composingText = QString();
- m_isComposing = false;
+ QInputMethodEvent event;
+ event.setCommitString(QString(), replacementStart, replacementLength);
+ m_isUpdatingText = true;
QCoreApplication::sendEvent(input, &event);
+ m_isUpdatingText = false;
- return 0;
-}
-
-int32_t QQnxInputContext::onGetCursorCapsMode(input_session_t *ic, int32_t req_modes)
-{
- Q_UNUSED(req_modes);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onGetCursorCapsMode is unsupported.";
+ updateCursorPosition();
return 0;
}
-int32_t QQnxInputContext::onGetCursorPosition(input_session_t *ic)
+int32_t QQnxInputContext::onFinishComposingText()
{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
+ finishComposingText();
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
-
- QInputMethodQueryEvent query(Qt::ImCursorPosition);
- QCoreApplication::sendEvent(input, &query);
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
-
- return m_lastCaretPos;
-}
-
-extracted_text_t *QQnxInputContext::onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
-{
- Q_UNUSED(flags);
- Q_UNUSED(request);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic)) {
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = reinterpret_cast<spannable_string_t *>(calloc(sizeof(spannable_string_t),1));
- return et;
- }
-
- // Used to update dictionaries, but not supported right now.
- extracted_text_t *et = (extracted_text_t *)calloc(sizeof(extracted_text_t),1);
- et->text = reinterpret_cast<spannable_string_t *>(calloc(sizeof(spannable_string_t),1));
-
- return et;
+ return 0;
}
-spannable_string_t *QQnxInputContext::onGetSelectedText(input_session_t *ic, int32_t flags)
+int32_t QQnxInputContext::onGetCursorPosition()
{
- Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return 0;
- QInputMethodQueryEvent query(Qt::ImCurrentSelection);
- QCoreApplication::sendEvent(input, &query);
- QString text = query.value(Qt::ImCurrentSelection).toString();
+ updateCursorPosition();
- return toSpannableString(text);
+ return m_caretPosition;
}
-spannable_string_t *QQnxInputContext::onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags)
+spannable_string_t *QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return toSpannableString("");
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- return toSpannableString(text.mid(m_lastCaretPos+1, n));
+ return toSpannableString(text.mid(m_caretPosition, n));
}
-spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags)
+spannable_string_t *QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
{
Q_UNUSED(flags);
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return toSpannableString("");
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return toSpannableString("");
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- if (n < m_lastCaretPos)
- return toSpannableString(text.mid(m_lastCaretPos - n, n));
+ if (n < m_caretPosition)
+ return toSpannableString(text.mid(m_caretPosition - n, n));
else
- return toSpannableString(text.mid(0, m_lastCaretPos));
-}
-
-int32_t QQnxInputContext::onPerformEditorAction(input_session_t *ic, int32_t editor_action)
-{
- Q_UNUSED(editor_action);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onPerformEditorAction is unsupported.";
-
- return 0;
-}
-
-int32_t QQnxInputContext::onReportFullscreenMode(input_session_t *ic, int32_t enabled)
-{
- Q_UNUSED(enabled);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onReportFullscreenMode is unsupported.";
-
- return 0;
-}
-
-int32_t QQnxInputContext::onSendEvent(input_session_t *ic, event_t *event)
-{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- return processEvent(event);
+ return toSpannableString(text.mid(0, m_caretPosition));
}
-int32_t QQnxInputContext::onSendAsyncEvent(input_session_t *ic, event_t *event)
+int32_t QQnxInputContext::onSendEvent(event_t *event)
{
qInputContextDebug() << Q_FUNC_INFO;
- if (!isSessionOkay(ic))
- return 0;
-
return processEvent(event);
}
-int32_t QQnxInputContext::onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end)
+int32_t QQnxInputContext::onSetComposingRegion(int32_t start, int32_t end)
{
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
+ if (!input)
return 0;
QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
QCoreApplication::sendEvent(input, &query);
QString text = query.value(Qt::ImSurroundingText).toString();
- m_lastCaretPos = query.value(Qt::ImCursorPosition).toInt();
+ m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
- QString empty = QString::fromLatin1("");
- text = text.mid(start, end - start);
+ qInputContextDebug() << Q_FUNC_INFO << text;
+
+ m_isUpdatingText = true;
// Delete the current text.
+ QInputMethodEvent deleteEvent;
+ deleteEvent.setCommitString(QString(), start - m_caretPosition, end - start);
+ QCoreApplication::sendEvent(input, &deleteEvent);
+
+ m_composingText = text.mid(start, end - start);
+ m_isComposing = true;
+
QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(empty, attributes);
- event.setCommitString(empty, start - m_lastCaretPos, end - start);
- QCoreApplication::sendEvent(input, &event);
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, m_composingText.length(), format));
+
+ QInputMethodEvent setTextEvent(m_composingText, attributes);
+ QCoreApplication::sendEvent(input, &setTextEvent);
- // Move the specified text into a preedit string.
- setComposingText(text);
+ m_isUpdatingText = false;
return 0;
}
-int32_t QQnxInputContext::onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
+int32_t QQnxInputContext::onSetComposingText(spannable_string_t *text, int32_t new_cursor_position)
{
- Q_UNUSED(new_cursor_position);
- qInputContextDebug() << Q_FUNC_INFO;
-
- if (!isSessionOkay(ic))
- return 0;
-
- QObject *input = qGuiApp->focusObject();
- if (!imfAvailable() || !input)
- return 0;
+ if (text->length > 0) {
+ updateComposition(text, new_cursor_position);
+ } else {
+ // If the composing text is empty we can simply end composition, the visual effect is the same.
+ // However, sometimes one wants to display hint text in an empty text field and for this to work
+ // QQuickTextEdit.inputMethodComposing has to be false if the composition string is empty.
+ m_composingText.clear();
+ finishComposingText();
+ }
+ return 0;
+}
- m_isComposing = true;
+int32_t QQnxInputContext::onIsTextSelected(int32_t* pIsSelected)
+{
+ *pIsSelected = hasSelectedText();
- QString preeditString = QString::fromWCharArray(text->str, text->length);
- setComposingText(preeditString);
+ qInputContextDebug() << Q_FUNC_INFO << *pIsSelected;
return 0;
}
-int32_t QQnxInputContext::onSetSelection(input_session_t *ic, int32_t start, int32_t end)
+int32_t QQnxInputContext::onIsAllTextSelected(int32_t* pIsSelected)
{
- Q_UNUSED(start);
- Q_UNUSED(end);
- qInputContextDebug() << Q_FUNC_INFO;
+ QObject *input = qGuiApp->focusObject();
+ if (!input)
+ return -1;
- if (!isSessionOkay(ic))
- return 0;
+ QInputMethodQueryEvent query(Qt::ImCurrentSelection | Qt::ImSurroundingText);
+ QCoreApplication::sendEvent(input, &query);
+
+ *pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();
- // Should never get called.
- qCritical() << Q_FUNC_INFO << "onSetSelection is unsupported.";
+ qInputContextDebug() << Q_FUNC_INFO << *pIsSelected;
return 0;
}
@@ -1556,19 +1360,74 @@ void QQnxInputContext::keyboardLocaleChanged(const QLocale &locale)
}
}
+void QQnxInputContext::setHighlightColor(int index, const QColor &color)
+{
+ qInputContextDebug() << Q_FUNC_INFO << "setHighlightColor" << index << color << qGuiApp->focusObject();
+
+ if (!sInputContextInstance)
+ return;
+
+ // If the focus has changed, revert all colors to the default.
+ if (sInputContextInstance->m_focusObject != qGuiApp->focusObject()) {
+ QColor invalidColor;
+ sInputContextInstance->m_highlightColor[ActiveRegion] = sSelectedColor;
+ sInputContextInstance->m_highlightColor[AutoCorrected] = invalidColor;
+ sInputContextInstance->m_highlightColor[Reverted] = invalidColor;
+ sInputContextInstance->m_focusObject = qGuiApp->focusObject();
+ }
+ if (index >= 0 && index <= Reverted)
+ sInputContextInstance->m_highlightColor[index] = color;
+}
+
void QQnxInputContext::setFocusObject(QObject *object)
{
qInputContextDebug() << Q_FUNC_INFO << "input item=" << object;
+ // Ensure the colors are reset if we've a change in focus object
+ setHighlightColor(-1, QColor());
+
if (!inputMethodAccepted()) {
if (m_inputPanelVisible)
hideInputPanel();
+ if (hasSession())
+ dispatchFocusLossEvent();
} else {
- m_virtualKeyboard.setInputHintsFromObject(object);
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(object, &query);
+ int inputHints = query.value(Qt::ImHints).toInt();
+
+ dispatchFocusGainEvent(inputHints);
+
+ m_virtualKeyboard.setInputHints(inputHints);
if (!m_inputPanelVisible)
showInputPanel();
}
}
+bool QQnxInputContext::checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices))
+{
+ qInputContextDebug() << Q_FUNC_INFO << "text" << text;
+
+ if (!imfAvailable())
+ return false;
+
+ if (!sSpellCheckSession)
+ sSpellCheckSession = p_ictrl_open_session(&ic_funcs);
+
+ action_event_t spellEvent;
+ initEvent(&spellEvent.event, sSpellCheckSession, EVENT_ACTION, ACTION_CHECK_MISSPELLINGS, sizeof(spellEvent));
+ int len = text.length();
+ spellEvent.event_data = alloca(sizeof(wchar_t) * (len + 1));
+ spellEvent.length_data = text.toWCharArray(static_cast<wchar_t*>(spellEvent.event_data)) * sizeof(wchar_t);
+
+ int rc = p_ictrl_dispatch_event(reinterpret_cast<event_t*>(&spellEvent));
+
+ if (rc == 0) {
+ sSpellCheckQueue->enqueue(SpellCheckInfo(context, spellCheckDone));
+ return true;
+ }
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
index 1980a99ed9..5028215bbe 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_imf.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,9 +43,11 @@
#define QQNXINPUTCONTEXT_H
#include <qpa/qplatforminputcontext.h>
+#include "qqnxscreeneventfilter.h"
#include <QtCore/QLocale>
#include <QtCore/QMetaType>
+#include <QtCore/QList>
#include <qpa/qplatformintegration.h>
#include "imf/imf_client.h"
@@ -55,21 +57,30 @@ QT_BEGIN_NAMESPACE
class QQnxAbstractVirtualKeyboard;
class QQnxIntegration;
+class QQnxImfRequest;
-class QQnxInputContext : public QPlatformInputContext
+class QQnxInputContext : public QPlatformInputContext, public QQnxScreenEventFilter
{
Q_OBJECT
public:
explicit QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard);
~QQnxInputContext();
+ // Indices for selecting and setting highlight colors.
+ enum HighlightIndex {
+ ActiveRegion,
+ AutoCorrected,
+ Reverted,
+ };
+
bool isValid() const;
bool filterEvent(const QEvent *event);
QRectF keyboardRect() const;
void reset();
+ void commit();
void update(Qt::InputMethodQueries);
- bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
+ bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId);
void showInputPanel();
@@ -79,61 +90,62 @@ public:
QLocale locale() const;
void setFocusObject(QObject *object);
-protected:
- // Filters only for IMF events.
- bool eventFilter(QObject *obj, QEvent *event);
+ static void setHighlightColor(int index, const QColor &color);
+
+ static bool checkSpelling(const QString &text, void *context, void (*spellCheckDone)(void *context, const QString &text, const QList<int> &indices));
private Q_SLOTS:
void keyboardVisibilityChanged(bool visible);
void keyboardLocaleChanged(const QLocale &locale);
+ void processImfEvent(QQnxImfRequest *event);
private:
// IMF Event dispatchers
- bool dispatchFocusEvent(FocusEventId id, int hints = Qt::ImhNone);
+ bool dispatchFocusGainEvent(int inputHints);
+ void dispatchFocusLossEvent();
bool dispatchRequestSoftwareInputPanel();
bool dispatchCloseSoftwareInputPanel();
+ int handleSpellCheck(spell_check_event_t *event);
int32_t processEvent(event_t *event);
void closeSession();
- void openSession();
+ bool openSession();
bool hasSession();
+ void updateCursorPosition();
void endComposition();
- void setComposingText(QString const &composingText);
+ void finishComposingText();
bool hasSelectedText();
+ void updateComposition(spannable_string_t *text, int32_t new_cursor_position);
// IMF Event handlers - these events will come in from QCoreApplication.
- int32_t onBeginBatchEdit(input_session_t *ic);
- int32_t onClearMetaKeyStates(input_session_t *ic, int32_t states);
- int32_t onCommitText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
- int32_t onDeleteSurroundingText(input_session_t *ic, int32_t left_length, int32_t right_length);
- int32_t onEndBatchEdit(input_session_t *ic);
- int32_t onFinishComposingText(input_session_t *ic);
- int32_t onGetCursorCapsMode(input_session_t *ic, int32_t req_modes);
- int32_t onGetCursorPosition(input_session_t *ic);
- extracted_text_t *onGetExtractedText(input_session_t *ic, extracted_text_request_t *request, int32_t flags);
- spannable_string_t *onGetSelectedText(input_session_t *ic, int32_t flags);
- spannable_string_t *onGetTextAfterCursor(input_session_t *ic, int32_t n, int32_t flags);
- spannable_string_t *onGetTextBeforeCursor(input_session_t *ic, int32_t n, int32_t flags);
- int32_t onPerformEditorAction(input_session_t *ic, int32_t editor_action);
- int32_t onReportFullscreenMode(input_session_t *ic, int32_t enabled);
- int32_t onSendEvent(input_session_t *ic, event_t *event);
- int32_t onSendAsyncEvent(input_session_t *ic, event_t *event);
- int32_t onSetComposingRegion(input_session_t *ic, int32_t start, int32_t end);
- int32_t onSetComposingText(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position);
- int32_t onSetSelection(input_session_t *ic, int32_t start, int32_t end);
+ int32_t onCommitText(spannable_string_t *text, int32_t new_cursor_position);
+ int32_t onDeleteSurroundingText(int32_t left_length, int32_t right_length);
+ int32_t onGetCursorCapsMode(int32_t req_modes);
+ int32_t onFinishComposingText();
+ int32_t onGetCursorPosition();
+ spannable_string_t *onGetTextAfterCursor(int32_t n, int32_t flags);
+ spannable_string_t *onGetTextBeforeCursor(int32_t n, int32_t flags);
+ int32_t onSendEvent(event_t *event);
+ int32_t onSetComposingRegion(int32_t start, int32_t end);
+ int32_t onSetComposingText(spannable_string_t *text, int32_t new_cursor_position);
+ int32_t onIsTextSelected(int32_t* pIsSelected);
+ int32_t onIsAllTextSelected(int32_t* pIsSelected);
int32_t onForceUpdate();
- int m_lastCaretPos;
+ int m_caretPosition;
bool m_isComposing;
QString m_composingText;
+ bool m_isUpdatingText;
bool m_inputPanelVisible;
QLocale m_inputPanelLocale;
+ // The object that had focus when the last highlight color was set.
+ QObject *m_focusObject;
+ // Indexed by HighlightIndex
+ QColor m_highlightColor[3];
QQnxIntegration *m_integration;
- QQnxAbstractVirtualKeyboard &m_virtualKeyboad;
+ QQnxAbstractVirtualKeyboard &m_virtualKeyboard;
};
-Q_DECLARE_METATYPE(extracted_text_t*)
-
QT_END_NAMESPACE
#endif // QQNXINPUTCONTEXT_H
diff --git a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
index f444d34b5e..9270f1ed6b 100644
--- a/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
+++ b/src/plugins/platforms/qnx/qqnxinputcontext_noimf.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,6 +46,7 @@
#include <QtCore/QDebug>
#include <QtGui/QGuiApplication>
+#include <QtGui/QInputMethodEvent>
#if defined(QQNXINPUTCONTEXT_DEBUG)
#define qInputContextDebug qDebug
@@ -179,7 +180,11 @@ void QQnxInputContext::setFocusObject(QObject *object)
if (m_inputPanelVisible)
hideInputPanel();
} else {
- m_virtualKeyboard.setInputHintsFromObject(object);
+ QInputMethodQueryEvent query(Qt::ImHints);
+ QCoreApplication::sendEvent(object, &query);
+ int inputHints = query.value(Qt::ImHints).toInt();
+
+ m_virtualKeyboard.setInputHints(inputHints);
if (!m_inputPanelVisible)
showInputPanel();
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 52f836abbe..dd32116360 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxintegration.h"
#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
@@ -123,6 +125,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::FullScreenApplication;
}
+ if (!paramList.contains(QLatin1String("flush-screen-context"))) {
+ options |= QQnxIntegration::AlwaysFlushScreenContext;
+ }
+
// On Blackberry the first window is treated as a root window
#ifdef Q_OS_BLACKBERRY
if (!paramList.contains(QLatin1String("no-rootwindow"))) {
@@ -156,7 +162,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#else
, m_eventDispatcher(createUnixEventDispatcher())
#endif
- , m_nativeInterface(new QQnxNativeInterface())
+ , m_nativeInterface(new QQnxNativeInterface(this))
, m_screenEventHandler(new QQnxScreenEventHandler(this))
#if !defined(QT_NO_CLIPBOARD)
, m_clipboard(0)
@@ -165,14 +171,12 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#if !defined(QT_NO_DRAGANDDROP)
, m_drag(new QSimpleDrag())
#endif
- , m_options(parseOptions(paramList))
{
+ ms_options = parseOptions(paramList);
qIntegrationDebug() << Q_FUNC_INFO;
// Open connection to QNX composition manager
- errno = 0;
- int result = screen_create_context(&m_screenContext, SCREEN_APPLICATION_CONTEXT);
- if (result != 0)
- qFatal("QQnx: failed to connect to composition manager, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_create_context(&ms_screenContext, SCREEN_APPLICATION_CONTEXT),
+ "Failed to create screen context");
// Not on BlackBerry, it has specialized event dispatcher which also handles navigator events
#if !defined(Q_OS_BLACKBERRY) && defined(QQNX_PPS)
@@ -191,7 +195,7 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
// Create/start event thread
#if defined(QQNX_SCREENEVENTTHREAD)
- m_screenEventThread = new QQnxScreenEventThread(m_screenContext, m_screenEventHandler);
+ m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
m_screenEventThread->start();
#endif
@@ -251,6 +255,9 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#if defined(QQNX_PPS)
// Set up the input context
m_inputContext = new QQnxInputContext(this, *m_virtualKeyboard);
+#if defined(QQNX_IMF)
+ m_screenEventHandler->addScreenEventFilter(m_inputContext);
+#endif
#endif
}
@@ -271,17 +278,6 @@ QQnxIntegration::~QQnxIntegration()
delete m_drag;
#endif
-#if defined(QQNX_PPS)
- // Destroy the hardware button notifier
- delete m_buttonsNotifier;
-
- // Destroy input context
- delete m_inputContext;
-#endif
-
- // Destroy the keyboard class.
- delete m_virtualKeyboard;
-
#if !defined(QT_NO_CLIPBOARD)
// Delete the clipboard
delete m_clipboard;
@@ -314,13 +310,24 @@ QQnxIntegration::~QQnxIntegration()
destroyDisplays();
// Close connection to QNX composition manager
- screen_destroy_context(m_screenContext);
+ screen_destroy_context(ms_screenContext);
#if !defined(QT_NO_OPENGL)
// Cleanup global OpenGL resources
QQnxGLContext::shutdown();
#endif
+#if defined(QQNX_PPS)
+ // Destroy the hardware button notifier
+ delete m_buttonsNotifier;
+
+ // Destroy input context
+ delete m_inputContext;
+#endif
+
+ // Destroy the keyboard class.
+ delete m_virtualKeyboard;
+
// Destroy services class
delete m_services;
@@ -355,10 +362,10 @@ QPlatformWindow *QQnxIntegration::createPlatformWindow(QWindow *window) const
const bool needRootWindow = options() & RootWindow;
switch (surfaceType) {
case QSurface::RasterSurface:
- return new QQnxRasterWindow(window, m_screenContext, needRootWindow);
+ return new QQnxRasterWindow(window, ms_screenContext, needRootWindow);
#if !defined(QT_NO_OPENGL)
case QSurface::OpenGLSurface:
- return new QQnxEglWindow(window, m_screenContext, needRootWindow);
+ return new QQnxEglWindow(window, ms_screenContext, needRootWindow);
#endif
default:
qFatal("QQnxWindow: unsupported window API");
@@ -441,7 +448,7 @@ QPlatformDrag *QQnxIntegration::drag() const
QVariant QQnxIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
{
qIntegrationDebug() << Q_FUNC_INFO;
- if ((hint == ShowIsFullScreen) && (m_options & FullScreenApplication))
+ if ((hint == ShowIsFullScreen) && (ms_options & FullScreenApplication))
return true;
return QPlatformIntegration::styleHint(hint);
@@ -495,11 +502,10 @@ void QQnxIntegration::createDisplays()
{
qIntegrationDebug() << Q_FUNC_INFO;
// Query number of displays
- errno = 0;
- int displayCount;
- int result = screen_get_context_property_iv(m_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount);
- if (result != 0)
- qFatal("QQnxIntegration: failed to query display count, errno=%d", errno);
+ int displayCount = 0;
+ int result = screen_get_context_property_iv(ms_screenContext, SCREEN_PROPERTY_DISPLAY_COUNT,
+ &displayCount);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query display count");
if (displayCount < 1) {
// Never happens, even if there's no display, libscreen returns 1
@@ -507,23 +513,20 @@ void QQnxIntegration::createDisplays()
}
// Get all displays
- errno = 0;
screen_display_t *displays = (screen_display_t *)alloca(sizeof(screen_display_t) * displayCount);
- result = screen_get_context_property_pv(m_screenContext, SCREEN_PROPERTY_DISPLAYS, (void **)displays);
- if (result != 0)
- qFatal("QQnxIntegration: failed to query displays, errno=%d", errno);
+ result = screen_get_context_property_pv(ms_screenContext, SCREEN_PROPERTY_DISPLAYS,
+ (void **)displays);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query displays");
// If it's primary, we create a QScreen for it even if it's not attached
// since Qt will dereference QGuiApplication::primaryScreen()
createDisplay(displays[0], /*isPrimary=*/true);
for (int i=1; i<displayCount; i++) {
- int isAttached = 0;
- result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED, &isAttached);
- if (result != 0) {
- qWarning("QQnxIntegration: failed to query display attachment, errno=%d", errno);
- isAttached = 1; // assume attached
- }
+ int isAttached = 1;
+ result = screen_get_display_property_iv(displays[i], SCREEN_PROPERTY_ATTACHED,
+ &isAttached);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display attachment");
if (!isAttached) {
qIntegrationDebug() << Q_FUNC_INFO << "Skipping non-attached display" << i;
@@ -537,7 +540,7 @@ void QQnxIntegration::createDisplays()
void QQnxIntegration::createDisplay(screen_display_t display, bool isPrimary)
{
- QQnxScreen *screen = new QQnxScreen(m_screenContext, display, isPrimary);
+ QQnxScreen *screen = new QQnxScreen(ms_screenContext, display, isPrimary);
m_screens.append(screen);
screenAdded(screen);
screen->adjustOrientation();
@@ -584,11 +587,25 @@ QQnxScreen *QQnxIntegration::primaryDisplay() const
return m_screens.first();
}
-QQnxIntegration::Options QQnxIntegration::options() const
+QQnxIntegration::Options QQnxIntegration::options()
{
- return m_options;
+ return ms_options;
}
+screen_context_t QQnxIntegration::screenContext()
+{
+ return ms_screenContext;
+}
+
+QQnxNavigatorEventHandler *QQnxIntegration::navigatorEventHandler()
+{
+ return m_navigatorEventHandler;
+}
+
+screen_context_t QQnxIntegration::ms_screenContext = 0;
+
+QQnxIntegration::Options QQnxIntegration::ms_options = 0;
+
bool QQnxIntegration::supportsNavigatorEvents() const
{
// If QQNX_PPS or Q_OS_BLACKBERRY is defined then we have navigator
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 8b5614fe4f..70c95ae673 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -85,7 +85,8 @@ public:
enum Option { // Options to be passed on command line.
NoOptions = 0x0,
FullScreenApplication = 0x1,
- RootWindow = 0x2
+ RootWindow = 0x2,
+ AlwaysFlushScreenContext = 0x4
};
Q_DECLARE_FLAGS(Options, Option)
explicit QQnxIntegration(const QStringList &paramList);
@@ -137,7 +138,10 @@ public:
void createDisplay(screen_display_t display, bool isPrimary);
void removeDisplay(QQnxScreen *screen);
QQnxScreen *primaryDisplay() const;
- Options options() const;
+ static Options options();
+ static screen_context_t screenContext();
+
+ QQnxNavigatorEventHandler *navigatorEventHandler();
private:
void createDisplays();
@@ -146,7 +150,7 @@ private:
static void addWindow(screen_window_t qnxWindow, QWindow *window);
static void removeWindow(screen_window_t qnxWindow);
- screen_context_t m_screenContext;
+ static screen_context_t ms_screenContext;
#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
#endif
@@ -176,7 +180,7 @@ private:
static QQnxWindowMapper ms_windowMapper;
static QMutex ms_windowMapperMutex;
- const Options m_options;
+ static Options ms_options;
friend class QQnxWindow;
};
diff --git a/src/plugins/platforms/qnx/qqnxlgmon.cpp b/src/plugins/platforms/qnx/qqnxlgmon.cpp
new file mode 100644
index 0000000000..3c8d1c11a5
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxlgmon.cpp
@@ -0,0 +1,49 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqnxlgmon.h"
+
+QT_BEGIN_NAMESPACE
+
+bool qqnxLgmonFirstFrame = true;
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/qnx/qqnxlgmon.h b/src/plugins/platforms/qnx/qqnxlgmon.h
new file mode 100644
index 0000000000..e3930ce93a
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxlgmon.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXLGMON_H
+#define QQNXLGMON_H
+
+#include <qglobal.h>
+
+#if defined(QQNX_LGMON)
+#include <lgmon.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QQNX_LGMON)
+
+extern bool qqnxLgmonFirstFrame;
+
+inline void qqnxLgmonInit()
+{
+ lgmon_supported(getpid());
+}
+
+inline void qqnxLgmonFramePosted(bool isCover)
+{
+ if (qqnxLgmonFirstFrame && !isCover) {
+ qqnxLgmonFirstFrame = false;
+ lgmon_app_ready_for_user_input(getpid());
+ }
+}
+
+#else
+
+inline void qqnxLgmonInit() {}
+inline void qqnxLgmonFramePosted(bool /*isCover*/) {}
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QQNXLGMON_H
+
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index e468b051cd..b89c103a06 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -44,6 +44,11 @@
#include "qqnxglcontext.h"
#include "qqnxscreen.h"
#include "qqnxwindow.h"
+#if defined(QQNX_IMF)
+#include "qqnxinputcontext_imf.h"
+#endif
+
+#include "qqnxintegration.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
@@ -51,6 +56,11 @@
QT_BEGIN_NAMESPACE
+QQnxNativeInterface::QQnxNativeInterface(QQnxIntegration *integration)
+ : m_integration(integration)
+{
+}
+
void *QQnxNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
{
if (resource == "windowGroup" && window && window->screen()) {
@@ -75,6 +85,16 @@ void *QQnxNativeInterface::nativeResourceForScreen(const QByteArray &resource, Q
return 0;
}
+void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
+{
+#ifdef Q_OS_BLACKBERRY
+ if (resource == "navigatorEventHandler")
+ return m_integration->navigatorEventHandler();
+#endif
+
+ return 0;
+}
+
void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
if (resource == "eglcontext" && context)
@@ -85,10 +105,27 @@ void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource,
void QQnxNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
{
+ QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
+
if (name == QStringLiteral("mmRendererWindowName")) {
- QQnxWindow *qnxWindow = static_cast<QQnxWindow*>(window);
qnxWindow->setMMRendererWindowName(value.toString());
+ } else if (name == QStringLiteral("windowGroup")) {
+ if (value.isNull())
+ qnxWindow->joinWindowGroup(QByteArray());
+ else if (value.canConvert<QByteArray>())
+ qnxWindow->joinWindowGroup(value.toByteArray());
}
}
+QPlatformNativeInterface::NativeResourceForIntegrationFunction QQnxNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
+{
+#if defined(QQNX_IMF)
+ if (resource == "blackberryIMFSetHighlightColor")
+ return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::setHighlightColor);
+ if (resource == "blackberryIMFCheckSpelling")
+ return reinterpret_cast<NativeResourceForIntegrationFunction>(QQnxInputContext::checkSpelling);
+#endif
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.h b/src/plugins/platforms/qnx/qqnxnativeinterface.h
index dfd386214e..83900791f6 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.h
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.h
@@ -46,13 +46,22 @@
QT_BEGIN_NAMESPACE
+class QQnxIntegration;
+
class QQnxNativeInterface : public QPlatformNativeInterface
{
public:
+ QQnxNativeInterface(QQnxIntegration *integration);
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
+ void *nativeResourceForIntegration(const QByteArray &resource);
+
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
+ NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource);
+
+private:
+ QQnxIntegration *m_integration;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
index 30dbb330d7..76d0df4920 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.cpp
@@ -41,6 +41,9 @@
#include "qqnxnavigatoreventhandler.h"
+#include "qqnxintegration.h"
+#include "qqnxscreen.h"
+
#include <QDebug>
#include <QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
@@ -76,15 +79,8 @@ void QQnxNavigatorEventHandler::handleOrientationChange(int angle)
void QQnxNavigatorEventHandler::handleSwipeDown()
{
qNavigatorEventHandlerDebug() << Q_FUNC_INFO;
- QWindow *w = QGuiApplication::focusWindow();
-
- if (w) {
- // Get the top level window that is ancestor of the focus window
- while (QWindow *parent = w->parent())
- w = parent;
- QWindowSystemInterface::handlePlatformPanelEvent(w);
- }
+ Q_EMIT swipeDown();
}
void QQnxNavigatorEventHandler::handleExit()
diff --git a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
index cce3921a27..883d893f5e 100644
--- a/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxnavigatoreventhandler.h
@@ -65,6 +65,7 @@ Q_SIGNALS:
void windowGroupActivated(const QByteArray &id);
void windowGroupDeactivated(const QByteArray &id);
void windowGroupStateChanged(const QByteArray &id, Qt::WindowState state);
+ void swipeDown();
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
index 0d8daac0ee..eb9fac540f 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Copyright (C) 2013 - 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxrasterwindow.h"
#include "qqnxscreen.h"
@@ -108,10 +110,9 @@ void QQnxRasterWindow::post(const QRegion &dirty)
int dirtyRect[4] = { rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height() };
// Update the display with contents of render buffer
- errno = 0;
- int result = screen_post_window(nativeHandle(), currentBuffer.nativeBuffer(), 1, dirtyRect, 0);
- if (result != 0)
- qFatal("QQnxWindow: failed to post window buffer, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_post_window(nativeHandle(), currentBuffer.nativeBuffer(), 1, dirtyRect, 0),
+ "Failed to post window");
// Advance to next nender buffer
m_previousBufferIndex = m_currentBufferIndex++;
@@ -122,8 +123,7 @@ void QQnxRasterWindow::post(const QRegion &dirty)
m_previousDirty = dirty;
m_scrolled = QRegion();
- if (m_cover)
- m_cover->updateCover();
+ windowPosted();
}
}
@@ -141,28 +141,23 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
// Check if render buffer is invalid
if (m_currentBufferIndex == -1) {
// Get all buffers available for rendering
- errno = 0;
screen_buffer_t buffers[MAX_BUFFER_COUNT];
- int result = screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_RENDER_BUFFERS, (void **)buffers);
- if (result != 0)
- qFatal("QQnxRasterWindow: failed to query window buffers, errno=%d", errno);
+ const int result = screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_RENDER_BUFFERS,
+ (void **)buffers);
+ Q_SCREEN_CRITICALERROR(result, "Failed to query window buffers");
// Wrap each buffer and clear
for (int i = 0; i < MAX_BUFFER_COUNT; ++i) {
m_buffers[i] = QQnxBuffer(buffers[i]);
// Clear Buffer
- errno = 0;
int bg[] = { SCREEN_BLIT_COLOR, 0x00000000, SCREEN_BLIT_END };
- result = screen_fill(screen()->nativeContext(), buffers[i], bg);
- if (result != 0)
- qFatal("QQnxWindow: failed to clear window buffer, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_fill(screen()->nativeContext(), buffers[i], bg),
+ "Failed to clear window buffer");
}
- errno = 0;
- result = screen_flush_blits(screen()->nativeContext(), 0);
- if (result != 0)
- qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_flush_blits(screen()->nativeContext(), 0),
+ "Failed to flush blits");
// Use the first available render buffer
m_currentBufferIndex = 0;
@@ -172,11 +167,17 @@ QQnxBuffer &QQnxRasterWindow::renderBuffer()
return m_buffers[m_currentBufferIndex];
}
+void QQnxRasterWindow::setParent(const QPlatformWindow *wnd)
+{
+ QQnxWindow::setParent(wnd);
+ adjustBufferSize();
+}
+
void QQnxRasterWindow::adjustBufferSize()
{
// When having a raster window we don't need any buffers, since
// Qt will draw to the parent TLW backing store.
- const QSize windowSize = m_parentWindow ? QSize(1,1) : window()->size();
+ const QSize windowSize = window()->parent() ? QSize(1,1) : window()->size();
if (windowSize != bufferSize())
setBufferSize(windowSize);
}
@@ -226,20 +227,16 @@ void QQnxRasterWindow::blitPreviousToCurrent(const QRegion &region, int dx, int
SCREEN_BLIT_END };
// Queue blit operation
- errno = 0;
- const int result = screen_blit(m_screenContext, currentBuffer.nativeBuffer(),
- previousBuffer.nativeBuffer(), attribs);
- if (result != 0)
- qFatal("QQnxWindow: failed to blit buffers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_blit(m_screenContext, currentBuffer.nativeBuffer(),
+ previousBuffer.nativeBuffer(), attribs),
+ "Failed to blit buffers");
}
// Check if flush requested
if (flush) {
// Wait for all blits to complete
- errno = 0;
- const int result = screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE);
- if (result != 0)
- qFatal("QQnxWindow: failed to flush blits, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_flush_blits(m_screenContext, SCREEN_WAIT_IDLE),
+ "Failed to flush blits");
// Buffer was modified outside the CPU
currentBuffer.invalidateInCache();
diff --git a/src/plugins/platforms/qnx/qqnxrasterwindow.h b/src/plugins/platforms/qnx/qqnxrasterwindow.h
index ad34b3ccf2..2be5f63464 100644
--- a/src/plugins/platforms/qnx/qqnxrasterwindow.h
+++ b/src/plugins/platforms/qnx/qqnxrasterwindow.h
@@ -60,6 +60,8 @@ public:
bool hasBuffers() const { return !bufferSize().isEmpty(); }
+ void setParent(const QPlatformWindow *window);
+
void adjustBufferSize();
protected:
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index 3a0607f214..a6c69164c7 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreen.h"
#include "qqnxwindow.h"
#include "qqnxcursor.h"
@@ -75,10 +77,9 @@ QT_BEGIN_NAMESPACE
static QSize determineScreenSize(screen_display_t display, bool primaryScreen) {
int val[2];
- errno = 0;
const int result = screen_get_display_property_iv(display, SCREEN_PROPERTY_PHYSICAL_SIZE, val);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display physical size");
if (result != 0) {
- qFatal("QQnxScreen: failed to query display physical size, errno=%d", errno);
return QSize(150, 90);
}
@@ -163,19 +164,16 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
{
qScreenDebug() << Q_FUNC_INFO;
// Cache initial orientation of this display
- errno = 0;
- int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION, &m_initialRotation);
- if (result != 0)
- qFatal("QQnxScreen: failed to query display rotation, errno=%d", errno);
+ int result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_ROTATION,
+ &m_initialRotation);
+ Q_SCREEN_CHECKERROR(result, "Failed to query display rotation");
m_currentRotation = m_initialRotation;
// Cache size of this display in pixels
- errno = 0;
int val[2];
- result = screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxScreen: failed to query display size, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(screen_get_display_property_iv(m_display, SCREEN_PROPERTY_SIZE, val),
+ "Failed to query display size");
m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]);
@@ -200,6 +198,9 @@ QQnxScreen::~QQnxScreen()
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setScreen(0);
+ if (m_coverWindow)
+ m_coverWindow->setScreen(0);
+
delete m_cursor;
}
@@ -505,7 +506,6 @@ void QQnxScreen::raiseWindow(QQnxWindow *window)
if (window != m_coverWindow) {
removeWindow(window);
m_childWindows.push_back(window);
- updateHierarchy();
}
}
@@ -516,7 +516,6 @@ void QQnxScreen::lowerWindow(QQnxWindow *window)
if (window != m_coverWindow) {
removeWindow(window);
m_childWindows.push_front(window);
- updateHierarchy();
}
}
@@ -671,7 +670,7 @@ void QQnxScreen::newWindowCreated(void *window)
// Otherwise, assume that if a foreign window already has a Z-Order both negative and
// less than the default Z-Order installed by mmrender on windows it creates,
// the windows should be treated as an underlay. Otherwise, we treat it as an overlay.
- if (!windowName.isEmpty() && windowName.startsWith("BbVideoWindowControl")) {
+ if (!windowName.isEmpty() && windowName.startsWith("MmRendererVideoWindowControl")) {
addMultimediaWindow(windowName, windowHandle);
} else if (!findWindow(windowHandle)) {
if (zorder <= MAX_UNDERLAY_ZORDER)
@@ -728,8 +727,6 @@ void QQnxScreen::activateWindowGroup(const QByteArray &id)
if (m_coverWindow)
m_coverWindow->setExposed(false);
-
- QWindowSystemInterface::handleWindowActivated(window);
}
void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
@@ -744,8 +741,6 @@ void QQnxScreen::deactivateWindowGroup(const QByteArray &id)
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->setExposed(false);
-
- QWindowSystemInterface::handleWindowActivated(rootWindow()->window());
}
QQnxWindow *QQnxScreen::rootWindow() const
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 61c47e6c72..d39a210d4b 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -80,7 +80,7 @@ public:
int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; }
screen_display_t nativeDisplay() const { return m_display; }
screen_context_t nativeContext() const { return m_screenContext; }
- const char *windowGroupName() const { return rootWindow()->groupName().constData(); }
+ const char *windowGroupName() const { return m_rootWindow ? m_rootWindow->groupName().constData() : 0; }
QQnxWindow *findWindow(screen_window_t windowHandle);
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventfilter.h b/src/plugins/platforms/qnx/qqnxscreeneventfilter.h
new file mode 100644
index 0000000000..f9ecadd2a9
--- /dev/null
+++ b/src/plugins/platforms/qnx/qqnxscreeneventfilter.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+**
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQNXSCREENEVENTFILTER_H
+#define QQNXSCREENEVENTFILTER_H
+
+QT_BEGIN_NAMESPACE
+
+class QQnxScreenEventFilter
+{
+protected:
+ ~QQnxScreenEventFilter() {}
+
+public:
+ virtual bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 6f06797393..178ea121e6 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreeneventhandler.h"
#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
@@ -46,6 +48,7 @@
#include "qqnxintegration.h"
#include "qqnxkeytranslator.h"
#include "qqnxscreen.h"
+#include "qqnxscreeneventfilter.h"
#include <QDebug>
#include <QGuiApplication>
@@ -69,6 +72,7 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
#if defined(QQNX_SCREENEVENTTHREAD)
, m_eventThread(0)
#endif
+ , m_focusLostTimer(-1)
{
// Create a touch device
m_touchDevice = new QTouchDevice;
@@ -90,14 +94,22 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
}
}
+void QQnxScreenEventHandler::addScreenEventFilter(QQnxScreenEventFilter *filter)
+{
+ m_eventFilters.append(filter);
+}
+
+void QQnxScreenEventHandler::removeScreenEventFilter(QQnxScreenEventFilter *filter)
+{
+ m_eventFilters.removeOne(filter);
+}
+
bool QQnxScreenEventHandler::handleEvent(screen_event_t event)
{
// get the event type
- errno = 0;
int qnxType;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
- if (result)
- qFatal("QQNX: failed to query event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType),
+ "Failed to query event type");
return handleEvent(event, qnxType);
}
@@ -228,35 +240,44 @@ void QQnxScreenEventHandler::processEventsFromScreenThread()
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
// get flags of key event
- errno = 0;
int flags;
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
- if (result)
- qFatal("QQNX: failed to query event flags, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags),
+ "Failed to query event flags");
// get key code
- errno = 0;
int sym;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym);
- if (result)
- qFatal("QQNX: failed to query event sym, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym),
+ "Failed to query event sym");
int modifiers;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers);
- if (result)
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers),
+ "Failed to query event modifieres");
int scan;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan);
- if (result)
- qFatal("QQNX: failed to query event modifiers, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan),
+ "Failed to query event scan");
int cap;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap);
- if (result)
- qFatal("QQNX: failed to query event cap, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &cap),
+ "Failed to query event cap");
+
+ int sequenceId = 0;
+#if defined(Q_OS_BLACKBERRY)
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_SEQUENCE_ID, &sequenceId),
+ "Failed to query event seqId");
+#endif
+
+ bool inject = true;
+ Q_FOREACH (QQnxScreenEventFilter *filter, m_eventFilters) {
+ if (filter->handleKeyboardEvent(flags, sym, modifiers, scan, cap, sequenceId)) {
+ inject = false;
+ break;
+ }
+ }
- injectKeyboardEvent(flags, sym, modifiers, scan, cap);
+ if (inject)
+ injectKeyboardEvent(flags, sym, modifiers, scan, cap);
}
void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
@@ -266,35 +287,32 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
// Query the window that was clicked
screen_window_t qnxWindow;
void *handle;
- int result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result)
- qFatal("QQNX: failed to query event window, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle),
+ "Failed to query event window");
qnxWindow = static_cast<screen_window_t>(handle);
// Query the button states
int buttonState = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState);
- if (result)
- qFatal("QQNX: failed to query event button state, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttonState),
+ "Failed to query event button state");
// Query the window position
int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result)
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos),
+ "Failed to query event window position");
// Query the screen position
int pos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result)
- qFatal("QQNX: failed to query event position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos),
+ "Failed to query event position");
// Query the wheel delta
int wheelDelta = 0;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta);
- if (result)
- qFatal("QQNX: failed to query event wheel delta, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheelDelta),
+ "Failed to query event wheel delta");
// Map window handle to top-level QWindow
QWindow *w = QQnxIntegration::window(qnxWindow);
@@ -314,10 +332,6 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
}
}
- // If we don't have a navigator, we don't get activation events.
- if (buttonState && w && w != QGuiApplication::focusWindow() && !m_qnxIntegration->supportsNavigatorEvents())
- QWindowSystemInterface::handleWindowActivated(w);
-
m_lastMouseWindow = qnxWindow;
// Apply scaling to wheel delta and invert value for Qt. We'll probably want to scale
@@ -376,34 +390,36 @@ void QQnxScreenEventHandler::handlePointerEvent(screen_event_t event)
void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
{
// get display coordinates of touch
- errno = 0;
int pos[2];
- int result = screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos);
- if (result)
- qFatal("QQNX: failed to query event position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, pos),
+ "Failed to query event position");
QCursor::setPos(pos[0], pos[1]);
// get window coordinates of touch
- errno = 0;
int windowPos[2];
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos);
- if (result)
- qFatal("QQNX: failed to query event window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, windowPos),
+ "Failed to query event window position");
// determine which finger touched
- errno = 0;
int touchId;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId);
- if (result)
- qFatal("QQNX: failed to query event touch id, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touchId),
+ "Failed to query event touch id");
// determine which window was touched
- errno = 0;
void *handle;
- result = screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle);
- if (result)
- qFatal("QQNX: failed to query event window, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, &handle),
+ "Failed to query event window");
+
+ errno = 0;
+ int touchArea[2];
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SIZE, touchArea),
+ "Failed to query event touch area");
+
+ int touchPressure;
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_PRESSURE, &touchPressure),
+ "Failed to query event touch pressure");
screen_window_t qnxWindow = static_cast<screen_window_t>(handle);
@@ -439,14 +455,23 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
QPointF(static_cast<qreal>(pos[0]) / screenSize.width(),
static_cast<qreal>(pos[1]) / screenSize.height());
- m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0],
- w->geometry().top() + windowPos[1], 0.0, 0.0);
+ m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0] - (touchArea[0]>>1),
+ w->geometry().top() + windowPos[1] - (touchArea[1]>>1),
+ 0.0, 0.0);
QWindow *parent = w->parent();
while (parent) {
m_touchPoints[touchId].area.translate(parent->geometry().topLeft());
parent = parent->parent();
}
+ //Qt expects the pressure between 0 and 1. There is however no definit upper limit for
+ //the integer value of touch event pressure. The 200 was determined by experiment, it
+ //usually does not get higher than that.
+ m_touchPoints[touchId].pressure = static_cast<qreal>(touchPressure)/200.0;
+ // Can happen, because there is no upper limit for pressure
+ if (m_touchPoints[touchId].pressure > 1)
+ m_touchPoints[touchId].pressure = 1;
+
// determine event type and update state of current touch point
QEvent::Type type = QEvent::None;
switch (qnxType) {
@@ -489,8 +514,9 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
{
screen_window_t window = 0;
- if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
- qFatal("QQnx: failed to query window property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window),
+ "Failed to query window property");
Q_EMIT windowClosed(window);
@@ -503,8 +529,9 @@ void QQnxScreenEventHandler::handleCloseEvent(screen_event_t event)
void QQnxScreenEventHandler::handleCreateEvent(screen_event_t event)
{
screen_window_t window = 0;
- if (screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0)
- qFatal("QQnx: failed to query window property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_pv(event, SCREEN_PROPERTY_WINDOW, (void**)&window),
+ "Failed to query window property");
Q_EMIT newWindowCreated(window);
}
@@ -556,8 +583,9 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event)
{
errno = 0;
int objectType;
- if (screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType) != 0)
- qFatal("QQNX: failed to query object type property, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_get_event_property_iv(event, SCREEN_PROPERTY_OBJECT_TYPE, &objectType),
+ "Failed to query object type property");
if (objectType != SCREEN_OBJECT_TYPE_WINDOW)
return;
@@ -589,9 +617,28 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi
if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0)
qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno);
- QWindow *w = focus ? QQnxIntegration::window(window) : 0;
+ QWindow *focusWindow = QQnxIntegration::window(window);
+
+ if (m_focusLostTimer != -1) {
+ killTimer(m_focusLostTimer);
+ m_focusLostTimer = -1;
+ }
+
+ if (focus && focusWindow != QGuiApplication::focusWindow())
+ QWindowSystemInterface::handleWindowActivated(focusWindow);
+ else if (!focus && focusWindow == QGuiApplication::focusWindow())
+ m_focusLostTimer = startTimer(50);
+}
- QWindowSystemInterface::handleWindowActivated(w);
+void QQnxScreenEventHandler::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_focusLostTimer) {
+ killTimer(m_focusLostTimer);
+ m_focusLostTimer = -1;
+ event->accept();
+ } else {
+ QObject::timerEvent(event);
+ }
}
#include "moc_qqnxscreeneventhandler.cpp"
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 1fdb2c83cd..bab6420cb8 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2011 - 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -49,6 +49,7 @@
QT_BEGIN_NAMESPACE
class QQnxIntegration;
+class QQnxScreenEventFilter;
#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
#endif
@@ -59,6 +60,9 @@ class QQnxScreenEventHandler : public QObject
public:
explicit QQnxScreenEventHandler(QQnxIntegration *integration);
+ void addScreenEventFilter(QQnxScreenEventFilter *filter);
+ void removeScreenEventFilter(QQnxScreenEventFilter *filter);
+
bool handleEvent(screen_event_t event);
bool handleEvent(screen_event_t event, int qnxType);
@@ -72,6 +76,9 @@ Q_SIGNALS:
void newWindowCreated(void *window);
void windowClosed(void *window);
+protected:
+ void timerEvent(QTimerEvent *event);
+
#if defined(QQNX_SCREENEVENTTHREAD)
private Q_SLOTS:
void processEventsFromScreenThread();
@@ -99,9 +106,11 @@ private:
screen_window_t m_lastMouseWindow;
QTouchDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
+ QList<QQnxScreenEventFilter*> m_eventFilters;
#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_eventThread;
#endif
+ int m_focusLostTimer;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 25a597bab9..156ba8a780 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxscreeneventthread.h"
#include "qqnxscreeneventhandler.h"
@@ -92,30 +94,34 @@ void QQnxScreenEventThread::run()
{
qScreenEventThreadDebug() << Q_FUNC_INFO << "screen event thread started";
+ int errorCounter = 0;
// loop indefinitely
while (!m_quit) {
screen_event_t event;
// create screen event
- errno = 0;
- int result = screen_create_event(&event);
- if (result)
- qFatal("QQNX: failed to create screen event, errno=%d", errno);
-
+ Q_SCREEN_CHECKERROR(screen_create_event(&event), "Failed to create screen event");
// block until screen event is available
- errno = 0;
- result = screen_get_event(m_screenContext, event, -1);
- if (result)
- qFatal("QQNX: failed to get screen event, errno=%d", errno);
+ const int result = screen_get_event(m_screenContext, event, -1);
+ Q_SCREEN_CRITICALERROR(result, "Failed to get screen event");
+ // Only allow 50 consecutive errors before we exit the thread
+ if (!result) {
+ errorCounter++;
+ if (errorCounter > 50)
+ m_quit = true;
+
+ screen_destroy_event(event);
+ continue;
+ } else {
+ errorCounter = 0;
+ }
// process received event
// get the event type
- errno = 0;
int qnxType;
- result = screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType);
- if (result)
- qFatal("QQNX: failed to query screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &qnxType),
+ "Failed to query screen event type");
if (qnxType == SCREEN_EVENT_USER) {
// treat all user events as shutdown requests
@@ -145,25 +151,19 @@ void QQnxScreenEventThread::shutdown()
screen_event_t event;
// create screen event
- errno = 0;
- int result = screen_create_event(&event);
- if (result)
- qFatal("QQNX: failed to create screen event, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_create_event(&event),
+ "Failed to create screen event");
// set the event type as user
- errno = 0;
int type = SCREEN_EVENT_USER;
- result = screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type);
- if (result)
- qFatal("QQNX: failed to set screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type),
+ "Failed to set screen type");
// NOTE: ignore SCREEN_PROPERTY_USER_DATA; treat all user events as shutdown events
// post event to event loop so it will wake up and die
- errno = 0;
- result = screen_send_event(m_screenContext, event, getpid());
- if (result)
- qFatal("QQNX: failed to set screen event type, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_send_event(m_screenContext, event, getpid()),
+ "Failed to set screen event type");
// cleanup
screen_destroy_event(event);
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
index 11eb4a5082..08de94a082 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.cpp
@@ -1,6 +1,6 @@
/***************************************************************************
**
-** Copyright (C) 2012 Research In Motion
+** Copyright (C) 2013 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -46,6 +46,9 @@
#include <bps/event.h>
#include <bps/locale.h>
#include <bps/virtualkeyboard.h>
+#if defined(Q_OS_BLACKBERRY)
+#include <bbndk.h>
+#endif
#if defined(QQNXVIRTUALKEYBOARD_DEBUG)
#define qVirtualKeyboardDebug qDebug
@@ -89,7 +92,7 @@ bool QQnxVirtualKeyboardBps::showKeyboard()
// They keyboard's mode is global between applications, we have to set it each time
if ( !isVisible() )
- applyKeyboardMode(keyboardMode());
+ applyKeyboardOptions();
virtualkeyboard_show();
return true;
@@ -102,48 +105,76 @@ bool QQnxVirtualKeyboardBps::hideKeyboard()
return true;
}
-void QQnxVirtualKeyboardBps::applyKeyboardMode(KeyboardMode mode)
+void QQnxVirtualKeyboardBps::applyKeyboardOptions()
{
- virtualkeyboard_layout_t layout = VIRTUALKEYBOARD_LAYOUT_DEFAULT;
+ virtualkeyboard_layout_t layout = keyboardLayout();
+ virtualkeyboard_enter_t enter = enterKey();
- switch (mode) {
- case Url:
- layout = VIRTUALKEYBOARD_LAYOUT_URL;
- break;
+ qVirtualKeyboardDebug() << Q_FUNC_INFO << "mode=" << keyboardMode() << "enterKey=" << enterKeyType();
- case Email:
- layout = VIRTUALKEYBOARD_LAYOUT_EMAIL;
- break;
+ virtualkeyboard_change_options(layout, enter);
+}
+virtualkeyboard_layout_t QQnxVirtualKeyboardBps::keyboardLayout() const
+{
+ switch (keyboardMode()) {
+ case Url:
+ return VIRTUALKEYBOARD_LAYOUT_URL;
+ case Email:
+ return VIRTUALKEYBOARD_LAYOUT_EMAIL;
case Web:
- layout = VIRTUALKEYBOARD_LAYOUT_WEB;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_WEB;
case NumPunc:
- layout = VIRTUALKEYBOARD_LAYOUT_NUM_PUNC;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_NUM_PUNC;
+ case Number:
+ return VIRTUALKEYBOARD_LAYOUT_NUMBER;
case Symbol:
- layout = VIRTUALKEYBOARD_LAYOUT_SYMBOL;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_SYMBOL;
case Phone:
- layout = VIRTUALKEYBOARD_LAYOUT_PHONE;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_PHONE;
case Pin:
- layout = VIRTUALKEYBOARD_LAYOUT_PIN;
- break;
-
+ return VIRTUALKEYBOARD_LAYOUT_PIN;
+ case Password:
+ return VIRTUALKEYBOARD_LAYOUT_PASSWORD;
+#if defined(Q_OS_BLACKBERRY)
+#if BBNDK_VERSION_AT_LEAST(10, 2, 1)
+ case Alphanumeric:
+ return VIRTUALKEYBOARD_LAYOUT_ALPHANUMERIC;
+#endif
+#endif
case Default: // fall through
default:
- layout = VIRTUALKEYBOARD_LAYOUT_DEFAULT;
- break;
+ return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
}
- qVirtualKeyboardDebug() << Q_FUNC_INFO << "mode=" << mode;
+ return VIRTUALKEYBOARD_LAYOUT_DEFAULT;
+}
+
+virtualkeyboard_enter_t QQnxVirtualKeyboardBps::enterKey() const
+{
+ switch (enterKeyType()) {
+ case Connect:
+ return VIRTUALKEYBOARD_ENTER_CONNECT;
+ case Done:
+ return VIRTUALKEYBOARD_ENTER_DONE;
+ case Go:
+ return VIRTUALKEYBOARD_ENTER_GO;
+ case Join:
+ return VIRTUALKEYBOARD_ENTER_JOIN;
+ case Next:
+ return VIRTUALKEYBOARD_ENTER_NEXT;
+ case Search:
+ return VIRTUALKEYBOARD_ENTER_SEARCH;
+ case Send:
+ return VIRTUALKEYBOARD_ENTER_SEND;
+ case Submit:
+ return VIRTUALKEYBOARD_ENTER_SUBMIT;
+ case Default: // fall through
+ default:
+ return VIRTUALKEYBOARD_ENTER_DEFAULT;
+ }
- virtualkeyboard_change_options(layout, VIRTUALKEYBOARD_ENTER_DEFAULT);
+ return VIRTUALKEYBOARD_ENTER_DEFAULT;
}
bool QQnxVirtualKeyboardBps::handleLocaleEvent(bps_event_t *event)
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
index 43ecb4ecf8..5749deb4e0 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardbps.h
@@ -43,6 +43,7 @@
#define QQNXVIRTUALKEYBOARDBPS_H
#include "qqnxabstractvirtualkeyboard.h"
+#include <bps/virtualkeyboard.h>
struct bps_event_t;
@@ -60,11 +61,14 @@ public:
bool hideKeyboard();
protected:
- void applyKeyboardMode(KeyboardMode mode);
+ void applyKeyboardOptions();
private:
bool handleLocaleEvent(bps_event_t *event);
bool handleVirtualKeyboardEvent(bps_event_t *event);
+
+ virtualkeyboard_layout_t keyboardLayout() const;
+ virtualkeyboard_enter_t enterKey() const;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
index 20fce3da70..2b6ee3d1dc 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.cpp
@@ -67,9 +67,6 @@ QT_BEGIN_NAMESPACE
const char *QQnxVirtualKeyboardPps::ms_PPSPath = "/pps/services/input/control";
const size_t QQnxVirtualKeyboardPps::ms_bufferSize = 2048;
-// Huge hack for keyboard shadow (see QNX PR 88400). Should be removed ASAP.
-#define KEYBOARD_SHADOW_HEIGHT 8
-
QQnxVirtualKeyboardPps::QQnxVirtualKeyboardPps()
: m_encoder(0),
m_decoder(0),
@@ -91,11 +88,6 @@ void QQnxVirtualKeyboardPps::start()
return;
}
-void QQnxVirtualKeyboardPps::applyKeyboardMode(KeyboardMode mode)
-{
- applyKeyboardModeOptions(mode);
-}
-
void QQnxVirtualKeyboardPps::close()
{
delete m_readNotifier;
@@ -159,18 +151,14 @@ bool QQnxVirtualKeyboardPps::connect()
bool QQnxVirtualKeyboardPps::queryPPSInfo()
{
+ if (!prepareToSend())
+ return false;
+
// Request info, requires id to regenerate res message.
pps_encoder_add_string(m_encoder, "msg", "info");
pps_encoder_add_string(m_encoder, "id", "libWebView");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
-
- pps_encoder_reset(m_encoder);
-
- return true;
+ return writeCurrentPPSEncoder();
}
void QQnxVirtualKeyboardPps::ppsDataReady()
@@ -257,9 +245,6 @@ void QQnxVirtualKeyboardPps::handleKeyboardInfoMessage()
}
const QString countryId = QString::fromLatin1(value);
- // HUGE hack, should be removed ASAP.
- newHeight -= KEYBOARD_SHADOW_HEIGHT; // We want to ignore the 8 pixel shadow above the keyboard. (PR 88400)
-
setHeight(newHeight);
const QLocale locale = QLocale(languageId + QLatin1Char('_') + countryId);
@@ -272,13 +257,12 @@ bool QQnxVirtualKeyboardPps::showKeyboard()
{
qVirtualKeyboardDebug() << Q_FUNC_INFO;
- // Try to connect.
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return false;
// NOTE: This must be done everytime the keyboard is shown even if there is no change because
// hiding the keyboard wipes the setting.
- applyKeyboardModeOptions(keyboardMode());
+ applyKeyboardOptions();
if (isVisible())
return true;
@@ -288,140 +272,110 @@ bool QQnxVirtualKeyboardPps::showKeyboard()
// Send the show message.
pps_encoder_add_string(m_encoder, "msg", "show");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
-
- pps_encoder_reset(m_encoder);
-
- // Return true if no error occurs. Sizing response will be triggered when confirmation of
- // the change arrives.
- return true;
+ return writeCurrentPPSEncoder();
}
bool QQnxVirtualKeyboardPps::hideKeyboard()
{
qVirtualKeyboardDebug() << Q_FUNC_INFO;
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return false;
pps_encoder_add_string(m_encoder, "msg", "hide");
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
+ return writeCurrentPPSEncoder();
+}
- //Try again.
- if (connect()) {
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
- close();
- return false;
- }
- }
- else
- return false;
- }
+bool QQnxVirtualKeyboardPps::prepareToSend()
+{
+ if (m_fd == -1 && !connect())
+ return false;
pps_encoder_reset(m_encoder);
+ return true;
+}
- // Return true if no error occurs. Sizing response will be triggered when confirmation of
- // the change arrives.
+bool QQnxVirtualKeyboardPps::writeCurrentPPSEncoder()
+{
+ if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1) {
+ close();
+ return false;
+ }
return true;
}
-void QQnxVirtualKeyboardPps::applyKeyboardModeOptions(KeyboardMode mode)
+void QQnxVirtualKeyboardPps::applyKeyboardOptions()
{
- // Try to connect.
- if (m_fd == -1 && !connect())
+ if (!prepareToSend())
return;
// Send the options message.
pps_encoder_add_string(m_encoder, "msg", "options");
-
pps_encoder_start_object(m_encoder, "dat");
- switch (mode) {
+
+ pps_encoder_add_string(m_encoder, "enter", enterKeyTypeStr());
+ pps_encoder_add_string(m_encoder, "type", keyboardModeStr());
+
+ pps_encoder_end_object(m_encoder);
+
+ writeCurrentPPSEncoder();
+}
+
+const char* QQnxVirtualKeyboardPps::keyboardModeStr() const
+{
+ switch (keyboardMode()) {
case Url:
- addUrlModeOptions();
- break;
+ return "url";
case Email:
- addEmailModeOptions();
- break;
+ return "email";
case Web:
- addWebModeOptions();
- break;
+ return "web";
case NumPunc:
- addNumPuncModeOptions();
- break;
+ return "num_punc";
+ case Number:
+ return "number";
case Symbol:
- addSymbolModeOptions();
- break;
+ return "symbol";
case Phone:
- addPhoneModeOptions();
- break;
+ return "phone";
case Pin:
- addPinModeOptions();
- break;
+ return "pin";
+ case Password:
+ return "password";
+ case Alphanumeric:
+ return "alphanumeric";
case Default:
- default:
- addDefaultModeOptions();
- break;
+ return "default";
}
- pps_encoder_end_object(m_encoder);
-
- if (::write(m_fd, pps_encoder_buffer(m_encoder), pps_encoder_length(m_encoder)) == -1)
- close();
-
- pps_encoder_reset(m_encoder);
-}
-
-void QQnxVirtualKeyboardPps::addDefaultModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "default");
+ return "";
}
-void QQnxVirtualKeyboardPps::addUrlModeOptions()
+const char* QQnxVirtualKeyboardPps::enterKeyTypeStr() const
{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "url");
-}
-
-void QQnxVirtualKeyboardPps::addEmailModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "email");
-}
-
-void QQnxVirtualKeyboardPps::addWebModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "web");
-}
-
-void QQnxVirtualKeyboardPps::addNumPuncModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "numPunc");
-}
-
-void QQnxVirtualKeyboardPps::addPhoneModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "phone");
-}
-
-void QQnxVirtualKeyboardPps::addPinModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "pin");
-}
+ switch (enterKeyType()) {
+ case DefaultReturn:
+ return "enter.default";
+ case Connect:
+ return "enter.connect";
+ case Done:
+ return "enter.done";
+ case Go:
+ return "enter.go";
+ case Join:
+ return "enter.join";
+ case Next:
+ return "enter.next";
+ case Search:
+ return "enter.search";
+ case Send:
+ return "enter.send";
+ case Submit:
+ return "enter.submit";
+ }
-void QQnxVirtualKeyboardPps::addSymbolModeOptions()
-{
- pps_encoder_add_string(m_encoder, "enter", "enter.default");
- pps_encoder_add_string(m_encoder, "type", "symbol");
+ return "";
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
index 6048868b08..2b56d5afbe 100644
--- a/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
+++ b/src/plugins/platforms/qnx/qqnxvirtualkeyboardpps.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
+
class QSocketNotifier;
class QQnxVirtualKeyboardPps : public QQnxAbstractVirtualKeyboard
@@ -64,7 +65,7 @@ public Q_SLOTS:
void start();
protected:
- void applyKeyboardMode(KeyboardMode mode);
+ void applyKeyboardOptions();
private Q_SLOTS:
void ppsDataReady();
@@ -76,15 +77,11 @@ private:
bool queryPPSInfo();
void handleKeyboardInfoMessage();
- void applyKeyboardModeOptions(KeyboardMode mode);
- void addDefaultModeOptions();
- void addUrlModeOptions();
- void addEmailModeOptions();
- void addWebModeOptions();
- void addNumPuncModeOptions();
- void addSymbolModeOptions();
- void addPhoneModeOptions();
- void addPinModeOptions();
+ const char* keyboardModeStr() const;
+ const char* enterKeyTypeStr() const;
+
+ bool prepareToSend();
+ bool writeCurrentPPSEncoder();
pps_encoder_t *m_encoder;
pps_decoder_t *m_decoder;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 99071cf4f2..e57025cbc6 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -39,9 +39,12 @@
**
****************************************************************************/
+#include "qqnxglobal.h"
+
#include "qqnxwindow.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h"
+#include "qqnxlgmon.h"
#include <QUuid>
@@ -73,36 +76,45 @@ QT_BEGIN_NAMESPACE
QQnxWindow::QQnxWindow(QWindow *window, screen_context_t context, bool needRootWindow)
: QPlatformWindow(window),
m_screenContext(context),
- m_parentWindow(0),
m_window(0),
m_screen(0),
+ m_parentWindow(0),
m_visible(false),
m_exposed(true),
m_windowState(Qt::WindowNoState),
m_mmRendererWindow(0)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window << ", size =" << window->size();
- int result;
QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window->screen()->handle());
- m_isTopLevel = ( needRootWindow && !platformScreen->rootWindow())
- || (!needRootWindow && !parent())
- || window->type() == Qt::CoverWindow;
+ if (window->type() == Qt::CoverWindow) {
+ // Cover windows have to be top level to be accessible to window delegate (i.e. navigator)
+ m_isTopLevel = true;
+ } else if (parent() || (window->type() & Qt::Dialog) == Qt::Dialog) {
+ // If we have a parent we are a child window. Sometimes we have to be a child even if we
+ // don't have a parent e.g. our parent might be in a different process.
+ m_isTopLevel = false;
+ } else {
+ // We're parentless. If we're not using a root window, we'll always be a top-level window
+ // otherwise only the first window is.
+ m_isTopLevel = !needRootWindow || !platformScreen->rootWindow();
+ }
- errno = 0;
if (m_isTopLevel) {
- result = screen_create_window(&m_window, m_screenContext); // Creates an application window
+ Q_SCREEN_CRITICALERROR(screen_create_window(&m_window, m_screenContext),
+ "Could not create top level window"); // Creates an application window
if (window->type() != Qt::CoverWindow) {
if (needRootWindow)
platformScreen->setRootWindow(this);
- createWindowGroup();
}
} else {
- result = screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW);
+ Q_SCREEN_CHECKERROR(
+ screen_create_window_type(&m_window, m_screenContext, SCREEN_CHILD_WINDOW),
+ "Could not create child window");
}
- if (result != 0)
- qFatal("QQnxWindow: failed to create window, errno=%d", errno);
+
+ createWindowGroup();
}
QQnxWindow::~QQnxWindow()
@@ -130,7 +142,7 @@ void QQnxWindow::setGeometry(const QRect &rect)
if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen
newGeometry = screen()->geometry();
- const QRect oldGeometry = setGeometryHelper(newGeometry);
+ setGeometryHelper(newGeometry);
// Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
@@ -140,71 +152,34 @@ void QQnxWindow::setGeometry(const QRect &rect)
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
-
- // Now move all children.
- if (!oldGeometry.isEmpty()) {
- const QPoint offset = newGeometry.topLeft() - oldGeometry.topLeft();
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
- }
}
-QRect QQnxWindow::setGeometryHelper(const QRect &rect)
+void QQnxWindow::setGeometryHelper(const QRect &rect)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window()
<< ", (" << rect.x() << "," << rect.y()
<< "," << rect.width() << "," << rect.height() << ")";
// Call base class method
- QRect oldGeometry = QPlatformWindow::geometry();
QPlatformWindow::setGeometry(rect);
// Set window geometry equal to widget geometry
- errno = 0;
int val[2];
val[0] = rect.x();
val[1] = rect.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val),
+ "Failed to set window position");
- errno = 0;
val[0] = rect.width();
val[1] = rect.height();
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SIZE, val),
+ "Failed to set window size");
// Set viewport size equal to window size
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window source size, errno=%d", errno);
-
- return oldGeometry;
-}
-
-void QQnxWindow::setOffset(const QPoint &offset)
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
- // Move self and then children.
- QRect newGeometry = geometry();
- newGeometry.translate(offset);
-
- // Call the base class
- QPlatformWindow::setGeometry(newGeometry);
-
- int val[2];
-
- errno = 0;
- val[0] = newGeometry.x();
- val[1] = newGeometry.y();
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_POSITION, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window position, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, val),
+ "Failed to set window source size");
- Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
- childWindow->setOffset(offset);
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setVisible(bool visible)
@@ -214,6 +189,12 @@ void QQnxWindow::setVisible(bool visible)
if (m_visible == visible)
return;
+ // The first time through we join a window group if appropriate.
+ if (m_parentGroupName.isNull() && !m_isTopLevel) {
+ joinWindowGroup(parent() ? static_cast<QQnxWindow*>(parent())->groupName()
+ : QByteArray(m_screen->windowGroupName()));
+ }
+
m_visible = visible;
QQnxWindow *root = this;
@@ -222,8 +203,6 @@ void QQnxWindow::setVisible(bool visible)
root->updateVisibility(root->m_visible);
- window()->requestActivate();
-
QWindowSystemInterface::handleExposeEvent(window(), window()->geometry());
if (visible) {
@@ -238,11 +217,9 @@ void QQnxWindow::updateVisibility(bool parentVisible)
{
qWindowDebug() << Q_FUNC_INFO << "parentVisible =" << parentVisible << "window =" << window();
// Set window visibility
- errno = 0;
int val = (m_visible && parentVisible) ? 1 : 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window visibility, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_VISIBLE, &val),
+ "Failed to set window visibility");
Q_FOREACH (QQnxWindow *childWindow, m_childWindows)
childWindow->updateVisibility(m_visible && parentVisible);
@@ -252,14 +229,11 @@ void QQnxWindow::setOpacity(qreal level)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "opacity =" << level;
// Set window global alpha
- errno = 0;
int val = (int)(level * 255);
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window global alpha, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_GLOBAL_ALPHA, &val),
+ "Failed to set global alpha");
- // TODO: How to handle children of this window? If we change all the visibilities, then
- // the transparency will look wrong...
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::setExposed(bool exposed)
@@ -282,15 +256,12 @@ void QQnxWindow::setBufferSize(const QSize &size)
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
// Set window buffer size
- errno = 0;
-
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window buffer size, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
+ "Failed to set window buffer size");
// Create window buffers if they do not exist
if (m_bufferSize.isEmpty()) {
@@ -298,24 +269,18 @@ void QQnxWindow::setBufferSize(const QSize &size)
if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
return;
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window pixel format, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val),
+ "Failed to set window format");
- errno = 0;
- result = screen_create_window_buffers(m_window, MAX_BUFFER_COUNT);
- if (result != 0) {
- qWarning() << "QQnxWindow: Buffer size was" << size;
- qFatal("QQnxWindow: failed to create window buffers, errno=%d", errno);
- }
+ Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
+ "Failed to create window buffers");
// check if there are any buffers available
int bufferCount = 0;
- result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount);
-
- if (result != 0)
- qFatal("QQnxWindow: failed to query window buffer count, errno=%d", errno);
+ Q_SCREEN_CRITICALERROR(
+ screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
+ "Failed to query render buffer count");
if (bufferCount != MAX_BUFFER_COUNT) {
qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.",
@@ -338,10 +303,8 @@ void QQnxWindow::setBufferSize(const QSize &size)
val[0] = SCREEN_TRANSPARENCY_SOURCE_OVER;
}
- errno = 0;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window transparency, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_TRANSPARENCY, val),
+ "Failed to set window transparency");
// Cache new buffer size
m_bufferSize = nonEmptySize;
@@ -366,9 +329,8 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
if (m_screen) {
qWindowDebug() << Q_FUNC_INFO << "Moving window to different screen";
m_screen->removeWindow(this);
- QQnxIntegration *platformIntegration = static_cast<QQnxIntegration*>(QGuiApplicationPrivate::platformIntegration());
- if ((platformIntegration->options() & QQnxIntegration::RootWindow)) {
+ if ((QQnxIntegration::options() & QQnxIntegration::RootWindow)) {
screen_leave_window_group(m_window);
}
}
@@ -378,25 +340,12 @@ void QQnxWindow::setScreen(QQnxScreen *platformScreen)
platformScreen->addWindow(this);
}
if (m_isTopLevel) {
- // Move window to proper screen/display
- errno = 0;
+ // Move window to proper screen/display
screen_display_t display = platformScreen->nativeDisplay();
- int result = screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window display, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_pv(m_window, SCREEN_PROPERTY_DISPLAY, (void **)&display),
+ "Failed to set window display");
} else {
- errno = 0;
- int result;
- if (!parent()) {
- result = screen_join_window_group(m_window, platformScreen->windowGroupName());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- } else {
- result = screen_join_window_group(m_window, static_cast<QQnxWindow*>(parent())->groupName().constData());
- if (result != 0)
- qFatal("QQnxWindow: failed to join window group, errno=%d", errno);
- }
-
Q_FOREACH (QQnxWindow *childWindow, m_childWindows) {
// Only subwindows and tooltips need necessarily be moved to another display with the window.
if (window()->type() == Qt::SubWindow || window()->type() == Qt::ToolTip)
@@ -430,6 +379,11 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
if (newParent == m_parentWindow)
return;
+ if (screen()->rootWindow() == this) {
+ qWarning() << "Application window cannot be reparented";
+ return;
+ }
+
removeFromParent();
m_parentWindow = newParent;
@@ -439,12 +393,12 @@ void QQnxWindow::setParent(const QPlatformWindow *window)
setScreen(m_parentWindow->m_screen);
m_parentWindow->m_childWindows.push_back(this);
+ joinWindowGroup(m_parentWindow->groupName());
} else {
m_screen->addWindow(this);
+ joinWindowGroup(QByteArray());
}
- adjustBufferSize();
-
m_screen->updateHierarchy();
}
@@ -478,14 +432,59 @@ void QQnxWindow::lower()
void QQnxWindow::requestActivateWindow()
{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
+ QQnxWindow *focusWindow = 0;
+ if (QGuiApplication::focusWindow())
+ focusWindow = static_cast<QQnxWindow*>(QGuiApplication::focusWindow()->handle());
- // TODO: Tell screen to set keyboard focus to this window.
+ if (focusWindow == this)
+ return;
- // Notify that we gained focus.
- gainedFocus();
+ if (screen()->rootWindow() == this ||
+ (focusWindow && findWindow(focusWindow->nativeHandle()))) {
+ // If the focus window is a child, we can just set the focus of our own window
+ // group to our window handle
+ setFocus(nativeHandle());
+ } else {
+ // In order to receive focus the parent's window group has to give focus to the
+ // child. If we have several hierarchy layers, we have to do that several times
+ QQnxWindow *currentWindow = this;
+ QList<QQnxWindow*> windowList;
+ while (currentWindow) {
+ windowList.prepend(currentWindow);
+ // If we find the focus window, we don't have to go further
+ if (currentWindow == focusWindow)
+ break;
+
+ if (currentWindow->parent()){
+ currentWindow = static_cast<QQnxWindow*>(currentWindow->parent());
+ } else if (screen()->rootWindow() &&
+ screen()->rootWindow()->m_windowGroupName == currentWindow->m_parentGroupName) {
+ currentWindow = screen()->rootWindow();
+ } else {
+ currentWindow = 0;
+ }
+ }
+
+ // We have to apply the focus from parent to child windows
+ for (int i = 1; i < windowList.size(); ++i)
+ windowList.at(i-1)->setFocus(windowList.at(i)->nativeHandle());
+
+ windowList.last()->setFocus(windowList.last()->nativeHandle());
+ }
+
+ screen_flush_context(m_screenContext, 0);
}
+void QQnxWindow::setFocus(screen_window_t newFocusWindow)
+{
+ screen_group_t screenGroup = 0;
+ screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP,
+ reinterpret_cast<void**>(&screenGroup));
+ if (screenGroup) {
+ screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS,
+ reinterpret_cast<void**>(&newFocusWindow));
+ }
+}
void QQnxWindow::setWindowState(Qt::WindowState state)
{
@@ -507,14 +506,6 @@ void QQnxWindow::propagateSizeHints()
qWindowDebug() << Q_FUNC_INFO << ": ignored";
}
-void QQnxWindow::gainedFocus()
-{
- qWindowDebug() << Q_FUNC_INFO << "window =" << window();
-
- // Got focus
- QWindowSystemInterface::handleWindowActivated(window());
-}
-
void QQnxWindow::setMMRendererWindowName(const QString &name)
{
m_mmRendererWindowName = name;
@@ -569,43 +560,43 @@ void QQnxWindow::minimize()
void QQnxWindow::setRotation(int rotation)
{
qWindowDebug() << Q_FUNC_INFO << "angle =" << rotation;
- errno = 0;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation);
- if (result != 0)
- qFatal("QQnxRootWindow: failed to set window rotation, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ROTATION, &rotation),
+ "Failed to set window rotation");
}
void QQnxWindow::initWindow()
{
// Alpha channel is always pre-multiplied if present
- errno = 0;
int val = SCREEN_PRE_MULTIPLIED_ALPHA;
- int result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window alpha mode, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_ALPHA_MODE, &val),
+ "Failed to set alpha mode");
// Set the window swap interval
- errno = 0;
val = 1;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window swap interval, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SWAP_INTERVAL, &val),
+ "Failed to set swap interval");
if (window()->flags() & Qt::WindowDoesNotAcceptFocus) {
- errno = 0;
val = SCREEN_SENSITIVITY_NO_FOCUS;
- result = screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val);
- if (result != 0)
- qFatal("QQnxWindow: failed to set window sensitivity, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_SENSITIVITY, &val),
+ "Failed to set window sensitivity");
}
- setScreen(static_cast<QQnxScreen *>(window()->screen()->handle()));
+ QQnxScreen *platformScreen = static_cast<QQnxScreen *>(window()->screen()->handle());
+ setScreen(platformScreen);
if (window()->type() == Qt::CoverWindow) {
#if defined(Q_OS_BLACKBERRY) && !defined(Q_OS_BLACKBERRY_TABLET)
- screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
- SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
- m_cover.reset(new QQnxNavigatorCover);
+ if (platformScreen->rootWindow()) {
+ screen_set_window_property_pv(m_screen->rootWindow()->nativeHandle(),
+ SCREEN_PROPERTY_ALTERNATE_WINDOW, (void**)&m_window);
+ m_cover.reset(new QQnxNavigatorCover);
+ } else {
+ qWarning("No root window for cover window");
+ }
#endif
m_exposed = false;
}
@@ -615,6 +606,8 @@ void QQnxWindow::initWindow()
// Qt never calls these setters after creating the window, so we need to do that ourselves here
setWindowState(window()->windowState());
+ setOpacity(window()->opacity());
+
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
@@ -632,10 +625,36 @@ void QQnxWindow::createWindowGroup()
m_windowGroupName = QUuid::createUuid().toString().toLatin1();
// Create window group so child windows can be parented by container window
- errno = 0;
- int result = screen_create_window_group(m_window, m_windowGroupName.constData());
- if (result != 0)
- qFatal("QQnxRootWindow: failed to create app window group, errno=%d", errno);
+ Q_SCREEN_CHECKERROR(screen_create_window_group(m_window, m_windowGroupName.constData()),
+ "Failed to create window group");
+}
+
+void QQnxWindow::joinWindowGroup(const QByteArray &groupName)
+{
+ bool changed = false;
+
+ qWindowDebug() << Q_FUNC_INFO << "group:" << groupName;
+
+ if (!groupName.isEmpty()) {
+ if (groupName != m_parentGroupName) {
+ screen_join_window_group(m_window, groupName);
+ m_parentGroupName = groupName;
+ changed = true;
+ }
+ } else {
+ if (!m_parentGroupName.isEmpty()) {
+ screen_leave_window_group(m_window);
+ changed = true;
+ }
+ // By setting to an empty string we'll stop setVisible from trying to
+ // change our group, we want that to happen only if joinWindowGroup has
+ // never been called. This allows windows to be created that are not initially
+ // part of any group.
+ m_parentGroupName = "";
+ }
+
+ if (changed)
+ screen_flush_context(m_screenContext, 0);
}
void QQnxWindow::updateZorder(int &topZorder)
@@ -651,12 +670,9 @@ void QQnxWindow::updateZorder(int &topZorder)
void QQnxWindow::updateZorder(screen_window_t window, int &topZorder)
{
- errno = 0;
- int result = screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder);
+ Q_SCREEN_CHECKERROR(screen_set_window_property_iv(window, SCREEN_PROPERTY_ZORDER, &topZorder),
+ "Failed to set window z-order");
topZorder++;
-
- if (result != 0)
- qFatal("QQnxWindow: failed to set window z-order=%d, errno=%d, mWindow=%p", topZorder, errno, window);
}
void QQnxWindow::applyWindowState()
@@ -690,5 +706,12 @@ void QQnxWindow::applyWindowState()
}
}
+void QQnxWindow::windowPosted()
+{
+ if (m_cover)
+ m_cover->updateCover();
+
+ qqnxLgmonFramePosted(m_cover); // for performance measurements
+}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 3c8070b0be..e97e941a08 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -78,7 +78,6 @@ public:
WId winId() const { return (WId)m_window; }
screen_window_t nativeHandle() const { return m_window; }
- virtual void adjustBufferSize() = 0;
void setBufferSize(const QSize &size);
QSize bufferSize() const { return m_bufferSize; }
@@ -93,7 +92,6 @@ public:
void propagateSizeHints();
- void gainedFocus();
void setMMRendererWindowName(const QString &name);
void setMMRendererWindow(screen_window_t handle);
void clearMMRendererWindow();
@@ -112,33 +110,34 @@ public:
void setRotation(int rotation);
QByteArray groupName() const { return m_windowGroupName; }
+ void joinWindowGroup(const QByteArray &groupName);
protected:
virtual int pixelFormat() const = 0;
virtual void resetBuffers() = 0;
void initWindow();
+ void windowPosted();
screen_context_t m_screenContext;
- QScopedPointer<QQnxAbstractCover> m_cover;
-
- QQnxWindow *m_parentWindow;
private:
void createWindowGroup();
- QRect setGeometryHelper(const QRect &rect);
+ void setGeometryHelper(const QRect &rect);
void removeFromParent();
- void setOffset(const QPoint &setOffset);
void updateVisibility(bool parentVisible);
void updateZorder(int &topZorder);
void updateZorder(screen_window_t window, int &zOrder);
void applyWindowState();
+ void setFocus(screen_window_t newFocusWindow);
screen_window_t m_window;
QSize m_bufferSize;
QQnxScreen *m_screen;
+ QQnxWindow *m_parentWindow;
QList<QQnxWindow*> m_childWindows;
+ QScopedPointer<QQnxAbstractCover> m_cover;
bool m_visible;
bool m_exposed;
QRect m_unmaximizedGeometry;
@@ -146,7 +145,10 @@ private:
QString m_mmRendererWindowName;
screen_window_t m_mmRendererWindow;
+ // Group name of window group headed by this window
QByteArray m_windowGroupName;
+ // Group name that we have joined or "" if we've not joined any group.
+ QByteArray m_parentGroupName;
bool m_isTopLevel;
};
diff --git a/src/plugins/platforms/windows/accessible/accessible.pri b/src/plugins/platforms/windows/accessible/accessible.pri
index 08a37a4733..e26c6614e2 100644
--- a/src/plugins/platforms/windows/accessible/accessible.pri
+++ b/src/plugins/platforms/windows/accessible/accessible.pri
@@ -8,10 +8,10 @@ HEADERS += \
$$PWD/qwindowsaccessibility.h \
$$PWD/comutils.h
-!win32-g++*: {
+!mingw: {
SOURCES += $$PWD/iaccessible2.cpp
HEADERS += $$PWD/iaccessible2.h
include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
}
-win32-g++*: LIBS *= -luuid \ No newline at end of file
+mingw: LIBS *= -luuid \ No newline at end of file
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 66ed9d85dc..7f2ed86404 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -59,10 +59,10 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOI
{
*iface = 0;
if (id == IID_IUnknown) {
- accessibleDebug("AccessibleApplication::QI(): IID_IUnknown");
+ qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IUnknown";
*iface = (IUnknown*)this;
} else if (id == IID_IAccessibleApplication) {
- accessibleDebug("AccessibleApplication::QI(): IID_IAccessibleApplication");
+ qCDebug(lcQpaAccessibility) << "AccessibleApplication::QI(): IID_IAccessibleApplication";
*iface = static_cast<IAccessibleApplication*>(this);
}
@@ -476,7 +476,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_uniqueID(long *outUniqueID)
if (!accessible)
return E_FAIL;
- accessibleDebug("uniqueID: %08x", id);
+ qCDebug(lcQpaAccessibility) << "uniqueID: " << showbase << hex << id;
*outUniqueID = (long)id;
return int(id) < 0 ? S_OK : S_FALSE;
@@ -841,7 +841,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_cellAt( long row, long colu
*cell = QWindowsAccessibility::wrap(qtCell);
}
}
- accessibleDebug("found cell? %p", *cell);
+ qCDebug(lcQpaAccessibility) << "found cell? " << *cell;
return *cell ? S_OK : S_FALSE;
}
@@ -1574,7 +1574,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidServic
return E_POINTER;
Q_UNUSED(guidService);
*iface = 0;
- accessibleDebug("QWindowsIA2Accessible::QS(): %s", IIDToString(riid).constData());
+ qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QS(): " << IIDToString(riid);
if (guidService == IID_IAccessible) {
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
index 885bc37cff..307f2fc3bb 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -100,6 +100,25 @@ QWindowsAccessibility::QWindowsAccessibility()
{
}
+// Retrieve sound name by checking the icon property of a message box
+static inline QString messageBoxAlertSound(const QObject *messageBox)
+{
+ enum MessageBoxIcon { // Keep in sync with QMessageBox::Icon
+ Information = 1,
+ Warning = 2,
+ Critical = 3
+ };
+ switch (messageBox->property("icon").toInt()) {
+ case Information:
+ return QStringLiteral("SystemAsterisk");
+ case Warning:
+ return QStringLiteral("SystemExclamation");
+ case Critical:
+ return QStringLiteral("SystemHand");
+ }
+ return QString();
+}
+
void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
QString soundName;
@@ -113,32 +132,8 @@ void QWindowsAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
break;
case QAccessible::Alert:
- {
- /* ### FIXME
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox *mb = qobject_cast<QMessageBox*>(o);
- if (mb) {
- switch (mb->icon()) {
- case QMessageBox::Warning:
- soundName = QLatin1String("SystemExclamation");
- break;
- case QMessageBox::Critical:
- soundName = QLatin1String("SystemHand");
- break;
- case QMessageBox::Information:
- soundName = QLatin1String("SystemAsterisk");
- break;
- default:
- break;
- }
- } else
-#endif // QT_NO_MESSAGEBOX
-*/
- {
- soundName = QLatin1String("SystemAsterisk");
- }
-
- }
+ soundName = event->object()->inherits("QMessageBox") ?
+ messageBoxAlertSound(event->object()) : QStringLiteral("SystemAsterisk");
break;
default:
break;
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 7c7c33616e..bda806d102 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -185,23 +185,10 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt)
return S_OK;
}
-#ifndef QT_NO_DEBUG
-bool debug_accessibility()
-{
- static int debugging = -1;
- if (debugging == -1)
- debugging = qgetenv("QT_DEBUG_ACCESSIBILITY").toInt();
- return !!debugging;
-}
-#endif
-
#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface)
{
- QString str;
- QDebug dbg(&str);
- dbg << iface << QLatin1String(funcName);
- accessibleDebug("%s", qPrintable(str));
+ qCDebug(lcQpaAccessibility) << iface << funcName;
}
#endif
@@ -216,10 +203,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::QueryInterface(REFIID id, LPVO
QByteArray strIID = IIDToString(id);
if (!strIID.isEmpty()) {
- QString ss;
- QDebug dbg(&ss);
- dbg << accessibleInterface();
- accessibleDebug("QWindowsIA2Accessible::QI() - IID:%s, iface:%s ", strIID.constData(), qPrintable(ss));
+ qCDebug(lcQpaAccessibility) << "QWindowsIA2Accessible::QI() - IID:"
+ << strIID << ", iface:" << accessibleInterface();
}
if (id == IID_IUnknown) {
*iface = (IUnknown*)(IDispatch*)this;
@@ -1059,7 +1044,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BS
}
*pszValue = 0;
- accessibleDebug("return S_FALSE");
+ qCDebug(lcQpaAccessibility) << "return S_FALSE";
return S_FALSE;
}
@@ -1198,7 +1183,7 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetWindow(HWND *phwnd)
QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
Q_ASSERT(platform);
*phwnd = (HWND)platform->nativeResourceForWindow("handle", window);
- accessibleDebug("QWindowsAccessible::GetWindow(): %p", *phwnd);
+ qCDebug(lcQpaAccessibility) << "QWindowsAccessible::GetWindow(): " << *phwnd;
return S_OK;
}
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
index 5b8d08d3c8..43482da4be 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
@@ -59,13 +59,6 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_OUTPUT)
-bool debug_accessibility();
-# define accessibleDebug !debug_accessibility() ? (void)0 : qDebug
-#else
-# define accessibleDebug while (false) qDebug
-#endif
-
#ifndef QT_NO_DEBUG_OUTPUT
#define DEBUG_SHOW_ATCLIENT_COMMANDS
#endif
diff --git a/src/plugins/platforms/windows/main.cpp b/src/plugins/platforms/windows/main.cpp
index ffd87af193..a0057534b8 100644
--- a/src/plugins/platforms/windows/main.cpp
+++ b/src/plugins/platforms/windows/main.cpp
@@ -43,7 +43,7 @@
#include <qpa/qplatformintegrationplugin.h>
#include <QtCore/QStringList>
-#include "qwindowsintegration.h"
+#include "qwindowsgdiintegration.h"
QT_BEGIN_NAMESPACE
@@ -113,7 +113,7 @@ public:
QPlatformIntegration *QWindowsIntegrationPlugin::create(const QString& system, const QStringList& paramList, int &, char **)
{
if (system.compare(system, QStringLiteral("windows"), Qt::CaseInsensitive) == 0)
- return new QWindowsIntegration(paramList);
+ return new QWindowsGdiIntegration(paramList);
return 0;
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index 7b574b0a56..ee640224cf 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -73,6 +73,7 @@ enum WindowsEventType // Simplify event types
ExposeEvent = WindowEventFlag + 1,
ActivateWindowEvent = WindowEventFlag + 2,
DeactivateWindowEvent = WindowEventFlag + 3,
+ MouseActivateWindowEvent = WindowEventFlag + 4,
LeaveEvent = WindowEventFlag + 5,
CloseEvent = WindowEventFlag + 6,
ShowEvent = WindowEventFlag + 7,
@@ -131,6 +132,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
case WM_ACTIVATEAPP:
return (int)wParamIn ?
QtWindows::ActivateApplicationEvent : QtWindows::DeactivateApplicationEvent;
+ case WM_MOUSEACTIVATE:
+ return QtWindows::MouseActivateWindowEvent;
case WM_ACTIVATE:
return LOWORD(wParamIn) == WA_INACTIVE ?
QtWindows::DeactivateWindowEvent : QtWindows::ActivateWindowEvent;
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 55e7b85d96..f12c828d8a 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -61,14 +61,12 @@ QT_BEGIN_NAMESPACE
QWindowsBackingStore::QWindowsBackingStore(QWindow *window) :
QPlatformBackingStore(window)
{
- if (QWindowsContext::verboseBackingStore)
- qDebug() << __FUNCTION__ << this << window;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window;
}
QWindowsBackingStore::~QWindowsBackingStore()
{
- if (QWindowsContext::verboseBackingStore)
- qDebug() << __FUNCTION__ << this;
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this;
}
QPaintDevice *QWindowsBackingStore::paintDevice()
@@ -83,8 +81,8 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
Q_ASSERT(window);
const QRect br = region.boundingRect();
- if (QWindowsContext::verboseBackingStore > 1)
- qDebug() << __FUNCTION__ << window << offset << br;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaBackingStore) << __FUNCTION__ << this << window << offset << br;
QWindowsWindow *rw = QWindowsWindow::baseWindowOf(window);
#ifndef Q_OS_WINCE
@@ -117,20 +115,23 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
}
if (!BitBlt(dc, br.x(), br.y(), br.width(), br.height(),
- m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY))
- qErrnoWarning("%s: BitBlt failed", __FUNCTION__);
+ m_image->hdc(), br.x() + offset.x(), br.y() + offset.y(), SRCCOPY)) {
+ const DWORD lastError = GetLastError(); // QTBUG-35926, QTBUG-29716: may fail after lock screen.
+ if (lastError != ERROR_SUCCESS && lastError != ERROR_INVALID_HANDLE)
+ qErrnoWarning(lastError, "%s: BitBlt failed", __FUNCTION__);
+ }
rw->releaseDC();
#ifndef Q_OS_WINCE
}
#endif
// Write image for debug purposes.
- if (QWindowsContext::verboseBackingStore > 2) {
+ if (QWindowsContext::verbose > 2 && lcQpaBackingStore().isDebugEnabled()) {
static int n = 0;
const QString fileName = QString::fromLatin1("win%1_%2.png").
arg(rw->winId()).arg(n++);
m_image->image().save(fileName);
- qDebug() << "Wrote " << m_image->image().size() << fileName;
+ qCDebug(lcQpaBackingStore) << "Wrote " << m_image->image().size() << fileName;
}
}
@@ -138,16 +139,14 @@ void QWindowsBackingStore::resize(const QSize &size, const QRegion &region)
{
if (m_image.isNull() || m_image->image().size() != size) {
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseBackingStore) {
- QDebug nsp = qDebug().nospace();
- nsp << __FUNCTION__ << ' ' << rasterWindow()->window()
- << ' ' << size << ' ' << region;
- if (!m_image.isNull())
- nsp << " from: " << m_image->image().size();
+ if (QWindowsContext::verbose && lcQpaBackingStore().isDebugEnabled()) {
+ qCDebug(lcQpaBackingStore)
+ << __FUNCTION__ << ' ' << window() << ' ' << size << ' ' << region
+ << " from: " << (m_image.isNull() ? QSize() : m_image->image().size());
}
#endif
QImage::Format format = QWindowsNativeImage::systemFormat();
- if (format == QImage::Format_RGB32 && rasterWindow()->window()->format().hasAlpha())
+ if (format == QImage::Format_RGB32 && window()->format().hasAlpha())
format = QImage::Format_ARGB32_Premultiplied;
QWindowsNativeImage *oldwni = m_image.data();
@@ -185,8 +184,8 @@ bool QWindowsBackingStore::scroll(const QRegion &area, int dx, int dy)
void QWindowsBackingStore::beginPaint(const QRegion &region)
{
- if (QWindowsContext::verboseBackingStore > 1)
- qDebug() << __FUNCTION__;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaBackingStore) <<__FUNCTION__ << region;
if (m_image->image().hasAlphaChannel()) {
QPainter p(&m_image->image());
@@ -197,14 +196,6 @@ void QWindowsBackingStore::beginPaint(const QRegion &region)
}
}
-QWindowsWindow *QWindowsBackingStore::rasterWindow() const
-{
- if (const QWindow *w = window())
- if (QPlatformWindow *pw = w->handle())
- return static_cast<QWindowsWindow *>(pw);
- return 0;
-}
-
HDC QWindowsBackingStore::getDC() const
{
if (!m_image.isNull())
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index d50570dd2c..b655aca835 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -68,8 +68,6 @@ public:
HDC getDC() const;
private:
- QWindowsWindow *rasterWindow() const;
-
QScopedPointer<QWindowsNativeImage> m_image;
};
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index 51e0d0e803..5370d556fd 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -164,9 +164,7 @@ void QWindowsClipboard::registerViewer()
qClipboardViewerWndProc, WS_OVERLAPPED);
m_nextClipboardViewer = SetClipboardViewer(m_clipboardViewer);
- if (QWindowsContext::verboseOLE)
- qDebug("%s m_clipboardViewer: %p next=%p", __FUNCTION__,
- m_clipboardViewer, m_nextClipboardViewer);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "m_clipboardViewer: " << m_clipboardViewer << "next: " << m_nextClipboardViewer;
}
void QWindowsClipboard::unregisterViewer()
@@ -219,9 +217,8 @@ void QWindowsClipboard::propagateClipboardMessage(UINT message, WPARAM wParam, L
bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
{
*result = 0;
- if (QWindowsContext::verboseOLE)
- qDebug("%s HWND=%p 0x%x %s", __FUNCTION__, hwnd, message,
- QWindowsGuiEventDispatcher::windowsMessageName(message));
+ if (QWindowsContext::verbose)
+ qCDebug(lcQpaMime) << __FUNCTION__ << hwnd << message << QWindowsGuiEventDispatcher::windowsMessageName(message);
switch (message) {
case WM_CHANGECBCHAIN: {
@@ -235,8 +232,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
return true;
case WM_DRAWCLIPBOARD: {
const bool owned = ownsClipboard();
- if (QWindowsContext::verboseOLE)
- qDebug("Clipboard changed owned %d", owned);
+ qCDebug(lcQpaMime) << "Clipboard changed owned " << owned;
emitChanged(QClipboard::Clipboard);
// clean up the clipboard object if we no longer own the clipboard
if (!owned && m_data)
@@ -247,8 +243,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
case WM_DESTROY:
// Recommended shutdown
if (ownsClipboard()) {
- if (QWindowsContext::verboseOLE)
- qDebug("Clipboard owner on shutdown, releasing.");
+ qCDebug(lcQpaMime) << "Clipboard owner on shutdown, releasing.";
OleFlushClipboard();
releaseIData();
}
@@ -259,8 +254,7 @@ bool QWindowsClipboard::clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM w
QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mode;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode;
if (mode != QClipboard::Clipboard)
return 0;
if (ownsClipboard())
@@ -270,8 +264,7 @@ QMimeData *QWindowsClipboard::mimeData(QClipboard::Mode mode)
void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mode << *mimeData;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode << *mimeData;
if (mode != QClipboard::Clipboard)
return;
@@ -316,8 +309,7 @@ bool QWindowsClipboard::ownsMode(QClipboard::Mode mode) const
{
const bool result = mode == QClipboard::Clipboard ?
ownsClipboard() : false;
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d returns %d", __FUNCTION__, mode, result);
+ qCDebug(lcQpaMime) << __FUNCTION__ << mode << result;
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 77cac647ba..08f3ab4dbd 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -79,18 +79,18 @@
QT_BEGIN_NAMESPACE
-// Verbosity of components
-int QWindowsContext::verboseIntegration = 0;
-int QWindowsContext::verboseWindows = 0;
-int QWindowsContext::verboseEvents = 0;
-int QWindowsContext::verboseBackingStore = 0;
-int QWindowsContext::verboseFonts = 0;
-int QWindowsContext::verboseGL = 0;
-int QWindowsContext::verboseOLE = 0;
-int QWindowsContext::verboseInputMethods = 0;
-int QWindowsContext::verboseDialogs = 0;
-int QWindowsContext::verboseTheming = 0;
-int QWindowsContext::verboseTablet = 0;
+Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows")
+Q_LOGGING_CATEGORY(lcQpaBackingStore, "qt.qpa.backingstore")
+Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events")
+Q_LOGGING_CATEGORY(lcQpaFonts, "qt.qpa.fonts")
+Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl")
+Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime")
+Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.inputmethods")
+Q_LOGGING_CATEGORY(lcQpaDialogs, "qt.qpa.dialogs")
+Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.tabletsupport")
+Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility")
+
+int QWindowsContext::verbose = 0;
// Get verbosity of components from "foo:2,bar:3"
static inline int componentVerbose(const char *v, const char *keyWord)
@@ -318,30 +318,21 @@ QWindowsContext::QWindowsContext() :
# pragma warning( disable : 4996 )
#endif
m_instance = this;
+ // ### FIXME: Remove this once the logging system has other options of configurations.
const QByteArray bv = qgetenv("QT_QPA_VERBOSE");
- if (!bv.isEmpty()) {
- const char *v = bv.data();
- QWindowsContext::verboseIntegration = componentVerbose(v, "integration");
- QWindowsContext::verboseWindows = componentVerbose(v, "windows");
- QWindowsContext::verboseEvents = componentVerbose(v, "events");
- QWindowsContext::verboseBackingStore = componentVerbose(v, "backingstore");
- QWindowsContext::verboseFonts = componentVerbose(v, "fonts");
- QWindowsContext::verboseGL = componentVerbose(v, "gl");
- QWindowsContext::verboseOLE = componentVerbose(v, "ole");
- QWindowsContext::verboseInputMethods = componentVerbose(v, "im");
- QWindowsContext::verboseDialogs = componentVerbose(v, "dialogs");
- QWindowsContext::verboseTheming = componentVerbose(v, "theming");
- QWindowsContext::verboseTablet = componentVerbose(v, "tablet");
- }
+ if (!bv.isEmpty())
+ QLoggingCategory::setFilterRules(QString::fromLocal8Bit(bv));
#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
d->m_tabletSupport.reset(QWindowsTabletSupport::create());
- if (QWindowsContext::verboseTablet)
- qDebug() << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
+ qCDebug(lcQpaTablet) << "Tablet support: " << (d->m_tabletSupport.isNull() ? QStringLiteral("None") : d->m_tabletSupport->description());
#endif
}
QWindowsContext::~QWindowsContext()
{
+#if !defined(QT_NO_TABLETEVENT) && !defined(Q_OS_WINCE)
+ d->m_tabletSupport.reset(); // Destroy internal window before unregistering classes.
+#endif
unregisterWindowClasses();
if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE)
OleUninitialize();
@@ -407,7 +398,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w, bool isGL)
bool icon = true;
if (isGL || (flags & Qt::MSWindowsOwnDC))
style |= CS_OWNDC;
- if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
+ if (!(flags & Qt::NoDropShadowWindowHint) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)
&& (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) {
style |= CS_DROPSHADOW;
}
@@ -519,8 +510,7 @@ QString QWindowsContext::registerWindowClass(QString cname,
qPrintable(cname));
d->m_registeredWindowClassNames.insert(cname);
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << ' ' << cname
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname
<< " style=0x" << QString::number(style, 16)
<< " brush=" << brush << " icon=" << icon << " atom=" << atom;
return cname;
@@ -531,9 +521,8 @@ void QWindowsContext::unregisterWindowClasses()
const HINSTANCE appInstance = (HINSTANCE)GetModuleHandle(0);
foreach (const QString &name, d->m_registeredWindowClassNames) {
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << name;
- UnregisterClass((wchar_t*)name.utf16(), appInstance);
+ if (!UnregisterClass((wchar_t*)name.utf16(), appInstance) && QWindowsContext::verbose)
+ qErrnoWarning("UnregisterClass failed for '%s'", qPrintable(name));
}
d->m_registeredWindowClassNames.clear();
}
@@ -750,8 +739,20 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
msg.message = message; // time and pt fields ignored
msg.wParam = wParam;
msg.lParam = lParam;
- msg.pt.x = GET_X_LPARAM(lParam);
- msg.pt.y = GET_Y_LPARAM(lParam);
+ msg.pt.x = msg.pt.y = 0;
+ if (et != QtWindows::CursorEvent && (et & (QtWindows::MouseEventFlag | QtWindows::NonClientEventFlag))) {
+ msg.pt.x = GET_X_LPARAM(lParam);
+ msg.pt.y = GET_Y_LPARAM(lParam);
+ // For non-client-area messages, these are screen coordinates (as expected
+ // in the MSG structure), otherwise they are client coordinates.
+ if (!(et & QtWindows::NonClientEventFlag)) {
+ ClientToScreen(msg.hwnd, &msg.pt);
+ }
+ } else {
+#ifndef Q_OS_WINCE
+ GetCursorPos(&msg.pt);
+#endif
+ }
// Run the native event filters.
long filterResult = 0;
@@ -834,8 +835,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
// Suppress events sent during DestroyWindow() for native children.
if (platformWindow->testFlag(QWindowsWindow::WithinDestroy))
return false;
- if (QWindowsContext::verboseEvents > 1)
- qDebug().nospace() << "Event window: " << platformWindow->window();
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaEvents) << "Event window: " << platformWindow->window();
} else {
qWarning("%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
__FUNCTION__, message,
@@ -928,6 +929,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
#ifndef Q_OS_WINCE
case QtWindows::ActivateWindowEvent:
+ if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
+ *result = LRESULT(MA_NOACTIVATE);
+ return true;
+ }
#ifndef QT_NO_TABLETEVENT
if (!d->m_tabletSupport.isNull())
d->m_tabletSupport->notifyActivate();
@@ -936,6 +941,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (const QWindow *modalWindow = QGuiApplication::modalWindow())
QWindowsWindow::baseWindowOf(modalWindow)->alertWindow();
break;
+ case QtWindows::MouseActivateWindowEvent:
+ if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
+ *result = LRESULT(MA_NOACTIVATE);
+ return true;
+ }
+ break;
#endif
#ifndef QT_NO_CONTEXTMENU
case QtWindows::ContextMenu:
@@ -963,7 +974,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (lParam & ENDSESSION_LOGOFF)
fflush(NULL);
- return !sessionManager->wasCanceled();
+ *result = sessionManager->wasCanceled() ? 0 : 1;
+ return true;
}
case QtWindows::EndSessionApplicationEvent: {
QWindowsSessionManager *sessionManager = platformSessionManager();
@@ -1071,11 +1083,13 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
LRESULT result;
const QtWindows::WindowsEventType et = windowsEventType(message, wParam);
const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result);
- if (QWindowsContext::verboseEvents > 1)
- if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message))
- qDebug("EVENT: hwd=%p %s msg=0x%x et=0x%x wp=%d at %d,%d handled=%d",
- hwnd, eventName, message, et, int(wParam),
- GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), handled);
+ if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
+ if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
+ qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message
+ << "et=0x" << et << dec << "wp=" << int(wParam) << "at"
+ << GET_X_LPARAM(lParam) << GET_Y_LPARAM(lParam) << "handled=" << handled;
+ }
+ }
if (!handled)
result = DefWindowProc(hwnd, message, wParam, lParam);
return result;
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 173df58570..1fea059ed9 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -47,12 +47,24 @@
#include <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
+#include <QtCore/QLoggingCategory>
struct IBindCtx;
struct _SHSTOCKICONINFO;
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaBackingStore)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaFonts)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaGl)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaMime)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaDialogs)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaTablet)
+Q_DECLARE_LOGGING_CATEGORY(lcQpaAccessibility)
+
class QWindow;
class QPlatformScreen;
class QWindowsScreenManager;
@@ -128,17 +140,7 @@ public:
};
// Verbose flag set by environment variable QT_QPA_VERBOSE
- static int verboseIntegration;
- static int verboseWindows;
- static int verboseBackingStore;
- static int verboseEvents;
- static int verboseFonts;
- static int verboseGL;
- static int verboseOLE;
- static int verboseInputMethods;
- static int verboseDialogs;
- static int verboseTheming;
- static int verboseTablet;
+ static int verbose;
explicit QWindowsContext();
~QWindowsContext();
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 5e7944a4cf..d8fb104b3c 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -186,32 +186,6 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
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 };
- static const uchar phand_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
- 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00,
- 0x80, 0x1c, 0x00, 0x00, 0x80, 0xe4, 0x00, 0x00, 0x80, 0x24, 0x03, 0x00,
- 0x80, 0x24, 0x05, 0x00, 0xb8, 0x24, 0x09, 0x00, 0xc8, 0x00, 0x09, 0x00,
- 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0xa0, 0x00, 0x08, 0x00,
- 0x20, 0x00, 0x08, 0x00, 0x40, 0x00, 0x08, 0x00, 0x40, 0x00, 0x04, 0x00,
- 0x80, 0x00, 0x04, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00,
- 0x00, 0x01, 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
- static const uchar phandm_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
- 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00,
- 0x80, 0x1f, 0x00, 0x00, 0x80, 0xff, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00,
- 0x80, 0xff, 0x07, 0x00, 0xb8, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00,
- 0xf8, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0f, 0x00,
- 0xe0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x0f, 0x00, 0xc0, 0xff, 0x07, 0x00,
- 0x80, 0xff, 0x07, 0x00, 0x80, 0xff, 0x07, 0x00, 0x00, 0xff, 0x03, 0x00,
- 0x00, 0xff, 0x03, 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, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
static const uchar openhand_bits[] = {
0x80,0x01,0x58,0x0e,0x64,0x12,0x64,0x52,0x48,0xb2,0x48,0x92,
0x16,0x90,0x19,0x80,0x11,0x40,0x02,0x40,0x04,0x40,0x04,0x20,
@@ -229,11 +203,6 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
0xf0,0x7f,0xf8,0x7f,0xfc,0x7f,0xfc,0x3f,0xf8,0x3f,0xf0,0x1f,
0xe0,0x1f,0xe0,0x1f,0x00,0x00,0x00,0x00};
- static const uchar * const cursor_bits32[] = {
- vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
- phand_bits, phandm_bits
- };
-
wchar_t *sh = 0;
switch (c.shape()) { // map to windows cursor
case Qt::ArrowCursor:
@@ -300,23 +269,18 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
hx = hy = 8;
invb = invm = false;
- } else if (cshape != Qt::BitmapCursor) {
- int i = cshape - Qt::SplitVCursor;
- QBitmap cb = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2]);
- QBitmap cm = QBitmap::fromData(QSize(32, 32), cursor_bits32[i * 2 + 1]);
- bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
- mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
- if (cshape == Qt::PointingHandCursor) {
- hx = 7;
- hy = 0;
- } else
- hx = hy = 16;
- invb = invm = false;
- } else {
+ } else if (cshape == Qt::BitmapCursor) {
bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ } else { // Qt::SplitVCursor, Qt::SplitHCursor
+ const QBitmap cb = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplit_bits : hsplit_bits);
+ const QBitmap cm = QBitmap::fromData(QSize(32, 32), cshape == Qt::SplitVCursor ? vsplitm_bits : hsplitm_bits);
+ bbits = cb.toImage().convertToFormat(QImage::Format_Mono);
+ mbits = cm.toImage().convertToFormat(QImage::Format_Mono);
+ hx = hy = 16;
+ invb = invm = false;
}
const int n = qMax(1, bbits.width() / 8);
const int h = bbits.height();
@@ -441,9 +405,6 @@ QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
{
-
- if (QWindowsContext::verboseWindows > 1)
- qDebug() << __FUNCTION__ << cursorIn << window;
if (!window)
return;
if (!cursorIn) {
@@ -468,10 +429,24 @@ QPoint QWindowsCursor::mousePosition()
return QPoint(p.x, p.y);
}
+QWindowsCursor::CursorState QWindowsCursor::cursorState()
+{
+#ifndef Q_OS_WINCE
+ enum { cursorShowing = 0x1, cursorSuppressed = 0x2 }; // Windows 8: CURSOR_SUPPRESSED
+ CURSORINFO cursorInfo;
+ cursorInfo.cbSize = sizeof(CURSORINFO);
+ if (GetCursorInfo(&cursorInfo)) {
+ if (cursorInfo.flags & CursorShowing)
+ return CursorShowing;
+ if (cursorInfo.flags & cursorSuppressed)
+ return CursorSuppressed;
+ }
+#endif // !Q_OS_WINCE
+ return CursorHidden;
+}
+
void QWindowsCursor::setPos(const QPoint &pos)
{
- if (QWindowsContext::verboseWindows)
- qDebug("%s %d,%d", __FUNCTION__, pos.x(), pos.y());
SetCursorPos(pos.x(), pos.y());
}
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index b366d9a06a..31da4e367d 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -93,6 +93,12 @@ private:
class QWindowsCursor : public QPlatformCursor
{
public:
+ enum CursorState {
+ CursorShowing,
+ CursorHidden,
+ CursorSuppressed // Cursor suppressed by touch interaction (Windows 8).
+ };
+
QWindowsCursor() {}
virtual void changeCursor(QCursor * widgetCursor, QWindow * widget);
@@ -102,6 +108,7 @@ public:
static HCURSOR createPixmapCursor(const QPixmap &pixmap, int hotX, int hotY);
static HCURSOR createSystemCursor(const QCursor &c);
static QPoint mousePosition();
+ static CursorState cursorState();
QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
QWindowsWindowCursor pixmapWindowCursor(const QCursor &c);
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 8ebfd018d0..7307d52cf9 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -422,8 +422,7 @@ void eatMouseMove()
;
if (msg.message == WM_MOUSEMOVE)
PostMessage(msg.hwnd, msg.message, 0, msg.lParam);
- if (QWindowsContext::verboseDialogs)
- qDebug("%s triggered=%d" , __FUNCTION__, msg.message == WM_MOUSEMOVE);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "triggered=" << (msg.message == WM_MOUSEMOVE);
}
} // namespace QWindowsDialogs
@@ -503,11 +502,31 @@ template <class BaseClass>
QWindowsDialogHelperBase<BaseClass>::QWindowsDialogHelperBase() :
m_nativeDialog(0),
m_ownerWindow(0),
- m_timerId(0)
+ m_timerId(0),
+ m_thread(0)
{
}
template <class BaseClass>
+void QWindowsDialogHelperBase<BaseClass>::cleanupThread()
+{
+ if (m_thread) { // Thread may be running if the dialog failed to close.
+ if (m_thread->isRunning())
+ m_thread->wait(500);
+ if (m_thread->isRunning()) {
+ m_thread->terminate();
+ m_thread->wait(300);
+ if (m_thread->isRunning())
+ qCCritical(lcQpaDialogs) <<__FUNCTION__ << "Failed to terminate thread.";
+ else
+ qCWarning(lcQpaDialogs) << __FUNCTION__ << "Thread terminated.";
+ }
+ delete m_thread;
+ m_thread = 0;
+ }
+}
+
+template <class BaseClass>
QWindowsNativeDialogBase *QWindowsDialogHelperBase<BaseClass>::nativeDialog() const
{
if (m_nativeDialog.isNull()) {
@@ -558,12 +577,9 @@ private:
void QWindowsDialogThread::run()
{
- if (QWindowsContext::verboseDialogs)
- qDebug(">%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << '>' << __FUNCTION__;
m_dialog->exec(m_owner);
- deleteLater();
- if (QWindowsContext::verboseDialogs)
- qDebug("<%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << '<' << __FUNCTION__;
}
template <class BaseClass>
@@ -579,9 +595,9 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
} else {
m_ownerWindow = 0;
}
- if (QWindowsContext::verboseDialogs)
- qDebug("%s modal=%d modal supported? %d native=%p parent=%p" ,
- __FUNCTION__, modal, supportsNonModalDialog(parent), m_nativeDialog.data(), m_ownerWindow);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "modal=" << modal
+ << " modal supported? " << supportsNonModalDialog(parent)
+ << "native=" << m_nativeDialog.data() << "owner" << m_ownerWindow;
if (!modal && !supportsNonModalDialog(parent))
return false; // Was it changed in-between?
if (!ensureNativeDialog())
@@ -590,6 +606,7 @@ bool QWindowsDialogHelperBase<BaseClass>::show(Qt::WindowFlags,
// a subsequent call to exec() may follow. So, start an idle timer
// which will start the dialog thread. If exec() is then called, the
// timer is stopped and dialog->exec() is called directly.
+ cleanupThread();
if (modal) {
m_timerId = this->startTimer(0);
} else {
@@ -602,8 +619,9 @@ template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::startDialogThread()
{
Q_ASSERT(!m_nativeDialog.isNull());
- QWindowsDialogThread *thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow);
- thread->start();
+ Q_ASSERT(!m_thread);
+ m_thread = new QWindowsDialogThread(m_nativeDialog, m_ownerWindow);
+ m_thread->start();
stopTimer();
}
@@ -630,7 +648,7 @@ struct FindDialogContext
HWND hwnd; // contains the HWND of the window found.
};
-static BOOL CALLBACK findDialogEnumWindowsProc(HWND hwnd, LPARAM lParam)
+static BOOL QT_WIN_CALLBACK findDialogEnumWindowsProc(HWND hwnd, LPARAM lParam)
{
FindDialogContext *context = reinterpret_cast<FindDialogContext *>(lParam);
DWORD winPid = 0;
@@ -665,8 +683,7 @@ void QWindowsDialogHelperBase<BaseClass>::hide()
template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::exec()
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << __FUNCTION__;
stopTimer();
if (QWindowsNativeDialogBase *nd = nativeDialog()) {
nd->exec(m_ownerWindow);
@@ -956,8 +973,7 @@ bool QWindowsNativeFileDialogBase::init(const CLSID &clsId, const IID &iid)
qErrnoWarning("IFileDialog::Advise failed");
return false;
}
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %p %p cookie=%lu" , __FUNCTION__, m_fileDialog, m_dialogEvents, m_cookie);
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << m_fileDialog << m_dialogEvents << m_cookie;
return true;
}
@@ -1008,14 +1024,12 @@ QString QWindowsNativeFileDialogBase::directory() const
void QWindowsNativeFileDialogBase::doExec(HWND owner)
{
- if (QWindowsContext::verboseDialogs)
- qDebug(">%s on %p", __FUNCTION__, (void *)owner);
+ qCDebug(lcQpaDialogs) << '>' << __FUNCTION__;
// Show() blocks until the user closes the dialog, the dialog window
// gets a WM_CLOSE or the parent window is destroyed.
const HRESULT hr = m_fileDialog->Show(owner);
QWindowsDialogs::eatMouseMove();
- if (QWindowsContext::verboseDialogs)
- qDebug("<%s returns 0x%lx", __FUNCTION__, hr);
+ qCDebug(lcQpaDialogs) << '<' << __FUNCTION__ << " returns " << hex << hr;
if (hr == S_OK) {
emit accepted();
} else {
@@ -1045,10 +1059,8 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode, QF
flags |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT;
break;
}
- if (QWindowsContext::verboseDialogs)
- qDebug().nospace()
- << __FUNCTION__ << " mode=" << mode << " options"
- << options << " results in 0x" << flags;
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << " mode=" << mode << " options"
+ << options << " results in 0x" << flags;
if (FAILED(m_fileDialog->SetOptions(flags)))
qErrnoWarning("%s: SetOptions() failed", __FUNCTION__);
@@ -1352,8 +1364,7 @@ void QWindowsNativeFileDialogBase::close()
// IFileDialog::Close() does not work unless invoked from a callback.
// Try to find the window and send it a WM_CLOSE in addition.
const HWND hwnd = findDialogWindow(m_title);
- if (QWindowsContext::verboseDialogs)
- qDebug() << __FUNCTION__ << "closing" << hwnd;
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << "closing" << hwnd;
if (hwnd && IsWindowVisible(hwnd))
PostMessageW(hwnd, WM_CLOSE, 0, 0);
#endif // !Q_OS_WINCE
@@ -1617,8 +1628,7 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
void QWindowsFileDialogHelper::setDirectory(const QUrl &directory)
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(directory.toString()));
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << directory.toString();
m_data.setDirectory(directory);
if (hasNativeDialog())
@@ -1632,8 +1642,7 @@ QUrl QWindowsFileDialogHelper::directory() const
void QWindowsFileDialogHelper::selectFile(const QUrl &fileName)
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s %s" , __FUNCTION__, qPrintable(fileName.toString()));
+ qCDebug(lcQpaDialogs) << __FUNCTION__ << fileName.toString();
if (hasNativeDialog()) // Might be invoked from the QFileDialog constructor.
nativeFileDialog()->selectFile(fileName.toLocalFile()); // ## should use QUrl::fileName() once it exists
@@ -1646,8 +1655,7 @@ QList<QUrl> QWindowsFileDialogHelper::selectedFiles() const
void QWindowsFileDialogHelper::setFilter()
{
- if (QWindowsContext::verboseDialogs)
- qDebug("%s" , __FUNCTION__);
+ qCDebug(lcQpaDialogs) << __FUNCTION__;
}
void QWindowsFileDialogHelper::selectNameFilter(const QString &filter)
@@ -1762,7 +1770,7 @@ void QWindowsXpNativeFileDialog::doExec(HWND owner)
// Callback for QWindowsNativeXpFileDialog directory dialog.
// MFC Directory Dialog. Contrib: Steve Williams (minor parts from Scott Powers)
-static int CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+static int QT_WIN_CALLBACK xpFileDialogGetExistingDirCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
QWindowsXpNativeFileDialog *dialog = reinterpret_cast<QWindowsXpNativeFileDialog *>(lpData);
return dialog->existingDirCallback(hwnd, uMsg, lParam);
@@ -2039,8 +2047,6 @@ void QWindowsNativeColorDialog::doExec(HWND owner)
typedef BOOL (WINAPI *ChooseColorWType)(LPCHOOSECOLORW);
CHOOSECOLOR chooseColor;
- if (QWindowsContext::verboseDialogs)
- qDebug() << '>' << __FUNCTION__ << " on " << owner;
ZeroMemory(&chooseColor, sizeof(chooseColor));
chooseColor.lStructSize = sizeof(chooseColor);
chooseColor.hwndOwner = owner;
@@ -2069,8 +2075,6 @@ void QWindowsNativeColorDialog::doExec(HWND owner)
for (int c= 0; c < customColorCount; ++c)
qCustomColors[c] = COLORREFToQColor(m_customColors[c]).rgb();
emit accepted();
- if (QWindowsContext::verboseDialogs)
- qDebug() << '<' << __FUNCTION__ << *m_color;
} else {
emit rejected();
}
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
index 1501b02bd9..bcf9f544b5 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
class QFileDialog;
class QDialog;
+class QThread;
class QWindowsNativeDialogBase;
namespace QWindowsDialogs
@@ -68,6 +69,7 @@ class QWindowsDialogHelperBase : public BaseClass
Q_DISABLE_COPY(QWindowsDialogHelperBase)
public:
typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr;
+ ~QWindowsDialogHelperBase() { cleanupThread(); }
virtual void exec();
virtual bool show(Qt::WindowFlags windowFlags,
@@ -88,10 +90,12 @@ private:
inline QWindowsNativeDialogBase *ensureNativeDialog();
inline void startDialogThread();
inline void stopTimer();
+ void cleanupThread();
QWindowsNativeDialogBasePtr m_nativeDialog;
HWND m_ownerWindow;
int m_timerId;
+ QThread *m_thread;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index fedda750d9..60c3daff23 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -54,6 +54,9 @@
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
#include <QtGui/QPainter>
+#include <QtGui/QPaintDevice>
+#include <QtGui/QBackingStore>
+#include <QtGui/QWindow>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -207,6 +210,77 @@ static const char * const ignoreDragCursorXpmC[] = {
"...............XXXX....."};
/*!
+ \class QWindowsDragCursorWindow
+ \brief A toplevel window showing the drag icon in case of touch drag.
+
+ \sa QWindowsOleDropSource
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsDragCursorWindow : public QWindow
+{
+public:
+ explicit QWindowsDragCursorWindow(QWindow *parent = 0);
+
+ void setPixmap(const QPixmap &p);
+
+protected:
+ void exposeEvent(QExposeEvent *);
+
+private:
+ void render();
+
+ QBackingStore m_backingStore;
+ QPixmap m_pixmap;
+};
+
+QWindowsDragCursorWindow::QWindowsDragCursorWindow(QWindow *parent)
+ : QWindow(parent)
+ , m_backingStore(this)
+{
+ QSurfaceFormat windowFormat = format();
+ windowFormat.setAlphaBufferSize(8);
+ setFormat(windowFormat);
+ setObjectName(QStringLiteral("QWindowsDragCursorWindow"));
+ setFlags(Qt::Popup | Qt::NoDropShadowWindowHint
+ | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
+ | Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput);
+}
+
+void QWindowsDragCursorWindow::setPixmap(const QPixmap &p)
+{
+ if (p.cacheKey() == m_pixmap.cacheKey())
+ return;
+ const QSize oldSize = m_pixmap.size();
+ const QSize newSize = p.size();
+ qCDebug(lcQpaMime) << __FUNCTION__ << p.cacheKey() << newSize;
+ m_pixmap = p;
+ if (oldSize != newSize) {
+ resize(newSize);
+ m_backingStore.resize(newSize);
+ }
+ if (isVisible())
+ render();
+}
+
+void QWindowsDragCursorWindow::exposeEvent(QExposeEvent *)
+{
+ Q_ASSERT(!m_pixmap.isNull());
+ render();
+}
+
+void QWindowsDragCursorWindow::render()
+{
+ const QRect rect(QPoint(0, 0), m_pixmap.size());
+ m_backingStore.beginPaint(rect);
+ QPainter painter(m_backingStore.paintDevice());
+ painter.drawPixmap(0, 0, m_pixmap);
+ m_backingStore.endPaint();
+ m_backingStore.flush(rect);
+}
+
+/*!
\class QWindowsDropMimeData
\brief Special mime data class for data retrieval from Drag operations.
@@ -286,6 +360,11 @@ static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
class QWindowsOleDropSource : public IDropSource
{
public:
+ enum Mode {
+ MouseDrag,
+ TouchDrag // Mouse cursor suppressed, use window as cursor.
+ };
+
explicit QWindowsOleDropSource(QWindowsDrag *drag);
virtual ~QWindowsOleDropSource();
@@ -304,35 +383,65 @@ private:
class DragCursorHandle {
Q_DISABLE_COPY(DragCursorHandle)
public:
- DragCursorHandle(HCURSOR c, qint64 k) : cursor(c), cacheKey(k) {}
+ DragCursorHandle(HCURSOR c) : cursor(c) {}
~DragCursorHandle() { DestroyCursor(cursor); }
- HCURSOR cursor;
- qint64 cacheKey;
+ const HCURSOR cursor;
};
- typedef QMap <Qt::DropAction, QSharedPointer<DragCursorHandle> > ActionCursorMap;
+ typedef QSharedPointer<DragCursorHandle> DragCursorHandlePtr;
+ struct CursorEntry {
+ CursorEntry() : cacheKey(0) {}
+ CursorEntry(const QPixmap &p, qint64 cK, const DragCursorHandlePtr &c, const QPoint &h) :
+ pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
+
+ QPixmap pixmap;
+ qint64 cacheKey; // Cache key of cursor
+ DragCursorHandlePtr cursor;
+ QPoint hotSpot;
+ };
+
+ typedef QMap<Qt::DropAction, CursorEntry> ActionCursorMap;
+ typedef ActionCursorMap::Iterator ActionCursorMapIt;
+ typedef ActionCursorMap::ConstIterator ActionCursorMapConstIt;
+
+ const Mode m_mode;
QWindowsDrag *m_drag;
Qt::MouseButtons m_currentButtons;
ActionCursorMap m_cursors;
+ QWindowsDragCursorWindow *m_touchDragWindow;
ULONG m_refs;
+#ifndef QT_NO_DEBUG_OUTPUT
+ friend QDebug operator<<(QDebug, const QWindowsOleDropSource::CursorEntry &);
+#endif
};
-QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) :
- m_drag(drag), m_currentButtons(Qt::NoButton),
- m_refs(1)
+QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag)
+ : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed ? MouseDrag : TouchDrag)
+ , m_drag(drag)
+ , m_currentButtons(Qt::NoButton)
+ , m_touchDragWindow(0)
+ , m_refs(1)
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaMime) << __FUNCTION__ << m_mode;
}
QWindowsOleDropSource::~QWindowsOleDropSource()
{
m_cursors.clear();
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
+ delete m_touchDragWindow;
+ qCDebug(lcQpaMime) << __FUNCTION__;
}
+#ifndef QT_NO_DEBUG_OUTPUT
+QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
+{
+ d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey
+ << "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot;
+ return d;
+}
+#endif // !QT_NO_DEBUG_OUTPUT
+
/*!
\brief Blend custom pixmap with cursors.
*/
@@ -343,59 +452,56 @@ void QWindowsOleDropSource::createCursors()
const QPixmap pixmap = drag->pixmap();
const bool hasPixmap = !pixmap.isNull();
- QList<Qt::DropAction> actions;
- actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction;
- if (hasPixmap)
- actions << Qt::IgnoreAction;
+ Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
+ int actionCount = int(sizeof(actions) / sizeof(actions[0]));
+ if (!hasPixmap)
+ --actionCount; // No Qt::IgnoreAction unless pixmap
const QPoint hotSpot = drag->hotSpot();
- for (int cnum = 0; cnum < actions.size(); ++cnum) {
- const Qt::DropAction action = actions.at(cnum);
- QPixmap cpm = drag->dragCursor(action);
- if (cpm.isNull())
- cpm = m_drag->defaultCursor(action);
- QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action);
- if (!cursorHandler.isNull() && cpm.cacheKey() == cursorHandler->cacheKey)
+ for (int cnum = 0; cnum < actionCount; ++cnum) {
+ const Qt::DropAction action = actions[cnum];
+ QPixmap cursorPixmap = drag->dragCursor(action);
+ if (cursorPixmap.isNull())
+ cursorPixmap = m_drag->defaultCursor(action);
+ const qint64 cacheKey = cursorPixmap.cacheKey();
+ const ActionCursorMapIt it = m_cursors.find(action);
+ if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
continue;
- if (cpm.isNull()) {
+ if (cursorPixmap.isNull()) {
qWarning("%s: Unable to obtain drag cursor for %d.", __FUNCTION__, action);
continue;
}
- int w = cpm.width();
- int h = cpm.height();
+ QPoint newHotSpot(0, 0);
+ QPixmap newPixmap = cursorPixmap;
if (hasPixmap) {
const int x1 = qMin(-hotSpot.x(), 0);
- const int x2 = qMax(pixmap.width() - hotSpot.x(), cpm.width());
+ const int x2 = qMax(pixmap.width() - hotSpot.x(), cursorPixmap.width());
const int y1 = qMin(-hotSpot.y(), 0);
- const int y2 = qMax(pixmap.height() - hotSpot.y(), cpm.height());
-
- w = x2 - x1 + 1;
- h = y2 - y1 + 1;
- }
-
- const QPoint newHotSpot = hotSpot;
- QPixmap newCursor(w, h);
- if (hasPixmap) {
+ const int y2 = qMax(pixmap.height() - hotSpot.y(), cursorPixmap.height());
+ QPixmap newCursor(x2 - x1 + 1, y2 - y1 + 1);
newCursor.fill(Qt::transparent);
QPainter p(&newCursor);
const QRect srcRect = pixmap.rect();
const QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y()));
p.drawPixmap(pmDest, pixmap, srcRect);
- p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm);
- } else {
- newCursor = cpm;
+ p.drawPixmap(qMax(0, hotSpot.x()),qMax(0, hotSpot.y()), cursorPixmap);
+ newPixmap = newCursor;
+ newHotSpot = QPoint(qMax(0, hotSpot.x()), qMax(0, hotSpot.y()));
}
- const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0;
- const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0;
-
- if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) {
- m_cursors.insert(action, QSharedPointer<DragCursorHandle>(new DragCursorHandle(sysCursor, cpm.cacheKey())));
+ if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot.x(), newHotSpot.y())) {
+ const CursorEntry entry(newPixmap, cacheKey, DragCursorHandlePtr(new DragCursorHandle(sysCursor)), newHotSpot);
+ if (it == m_cursors.end())
+ m_cursors.insert(action, entry);
+ else
+ it.value() = entry;
}
}
- if (QWindowsContext::verboseOLE)
- qDebug("%s %d cursors", __FUNCTION__, m_cursors.size());
+#ifndef QT_NO_DEBUG_OUTPUT
+ if (lcQpaMime().isDebugEnabled())
+ qCDebug(lcQpaMime) << __FUNCTION__ << "pixmap" << pixmap.size() << m_cursors.size() << "cursors:\n" << m_cursors;
+#endif // !QT_NO_DEBUG_OUTPUT
}
//---------------------------------------------------------------------
@@ -468,11 +574,11 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
} while (false);
- if (QWindowsContext::verboseOLE
- && (QWindowsContext::verboseOLE > 1 || hr != S_OK))
- qDebug("%s fEscapePressed=%d, grfKeyState=%lu buttons=%d returns 0x%x",
- __FUNCTION__, fEscapePressed,grfKeyState, int(m_currentButtons),
- int(hr));
+ if (QWindowsContext::verbose > 1 || hr != S_OK) {
+ qCDebug(lcQpaMime) << __FUNCTION__ << "fEscapePressed=" << fEscapePressed
+ << "grfKeyState=" << grfKeyState << "buttons" << m_currentButtons
+ << "returns 0x" << hex <<int(hr) << dec;
+ }
return hr;
}
@@ -486,17 +592,29 @@ 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);
-
- QSharedPointer<DragCursorHandle> cursorHandler = m_cursors.value(action);
- qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
- if (cursorHandler.isNull() || currentCacheKey != cursorHandler->cacheKey)
+ const qint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey();
+ ActionCursorMapConstIt it = m_cursors.constFind(action);
+ // If a custom drag cursor is set, check its cache key to detect changes.
+ if (it == m_cursors.constEnd() || (currentCacheKey && currentCacheKey != it.value().cacheKey)) {
createCursors();
+ it = m_cursors.constFind(action);
+ }
- const ActionCursorMap::const_iterator it = m_cursors.constFind(action);
if (it != m_cursors.constEnd()) {
- SetCursor(it.value()->cursor);
+ const CursorEntry &e = it.value();
+ switch (m_mode) {
+ case MouseDrag:
+ SetCursor(e.cursor->cursor);
+ break;
+ case TouchDrag:
+ if (!m_touchDragWindow)
+ m_touchDragWindow = new QWindowsDragCursorWindow;
+ m_touchDragWindow->setPixmap(e.pixmap);
+ m_touchDragWindow->setFramePosition(QWindowsCursor::mousePosition() - e.hotSpot);
+ if (!m_touchDragWindow->isVisible())
+ m_touchDragWindow->show();
+ break;
+ }
return ResultFromScode(S_OK);
}
@@ -519,14 +637,12 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
m_refs(1), m_window(w), m_chosenEffect(0), m_lastKeyState(0)
{
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << this << w;
+ qCDebug(lcQpaMime) << __FUNCTION__ << this << w;
}
QWindowsOleDropTarget::~QWindowsOleDropTarget()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s %p", __FUNCTION__, this);
+ qCDebug(lcQpaMime) << __FUNCTION__ << this;
}
STDMETHODIMP
@@ -557,14 +673,6 @@ QWindowsOleDropTarget::Release(void)
return m_refs;
}
-QWindow *QWindowsOleDropTarget::findDragOverWindow(const POINTL &pt) const
-{
- if (QWindowsWindow *child =
- QWindowsWindow::baseWindowOf(m_window)->childAtScreenPoint(QPoint(pt.x, pt.y)))
- return child->window();
- return m_window;
-}
-
void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
const QPoint &point, LPDWORD pdwEffect)
{
@@ -588,13 +696,12 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
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;
+ qCDebug(lcQpaMime) << __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
@@ -604,8 +711,8 @@ QWindowsOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->DragEnter(reinterpret_cast<HWND>(m_window->winId()), pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect);
- if (QWindowsContext::verboseOLE)
- qDebug("%s widget=%p key=%lu, pt=%ld,%ld", __FUNCTION__, m_window, grfKeyState, pt.x, pt.y);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "widget=" << m_window << " key=" << grfKeyState
+ << "pt=" << pt.x << pt.y;
QWindowsDrag::instance()->setDropDataObject(pDataObj);
pDataObj->AddRef();
@@ -620,20 +727,18 @@ QWindowsOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->DragOver(reinterpret_cast<POINT*>(&pt), *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));
+ qCDebug(lcQpaMime) << __FUNCTION__ << "m_window" << m_window << "key=" << grfKeyState
+ << "pt=" << pt.x << pt.y;
+ const QPoint tmpPoint = QWindowsGeometryHint::mapFromGlobal(m_window, 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__);
+ qCDebug(lcQpaMime) << __FUNCTION__ << "compressed event";
return NOERROR;
}
- handleDrag(dragOverWindow, grfKeyState, tmpPoint, pdwEffect);
+ handleDrag(m_window, grfKeyState, tmpPoint, pdwEffect);
return NOERROR;
}
@@ -643,8 +748,7 @@ QWindowsOleDropTarget::DragLeave()
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->DragLeave();
- if (QWindowsContext::verboseOLE)
- qDebug().nospace() <<__FUNCTION__ << ' ' << m_window;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window;
QWindowSystemInterface::handleDrag(m_window, 0, QPoint(), Qt::IgnoreAction);
QWindowsDrag::instance()->releaseDropDataObject();
@@ -661,15 +765,10 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
if (IDropTargetHelper* dh = QWindowsDrag::instance()->dropHelper())
dh->Drop(pDataObj, reinterpret_cast<POINT*>(&pt), *pdwEffect);
- QWindow *dropWindow = findDragOverWindow(pt);
-
- if (QWindowsContext::verboseOLE)
- qDebug().nospace() << __FUNCTION__ << ' ' << m_window
- << " on " << dropWindow
- << " keys=" << grfKeyState << " pt="
- << pt.x << ',' << pt.y;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window
+ << "keys=" << grfKeyState << "pt=" << pt.x << ',' << pt.y;
- m_lastPoint = QWindowsGeometryHint::mapFromGlobal(dropWindow, QPoint(pt.x,pt.y));
+ m_lastPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y));
// grfKeyState does not all ways contain button state in the drop so if
// it doesn't then use the last known button state;
if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0)
@@ -679,7 +778,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
const QPlatformDropQtResponse response =
- QWindowSystemInterface::handleDrop(dropWindow, windowsDrag->dropData(), m_lastPoint,
+ QWindowSystemInterface::handleDrop(m_window, windowsDrag->dropData(), m_lastPoint,
translateToQDragDropActions(*pdwEffect));
if (response.isAccepted()) {
@@ -796,9 +895,8 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
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);
+ qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x"
+ << hex << int(possibleActions) << "effects=0x" << allowedEffects << dec;
const HRESULT r = DoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
if (r == DRAGDROP_S_DROP) {
@@ -819,10 +917,9 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
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), dragResult);
+ qCDebug(lcQpaMime) << '<' << __FUNCTION__ << hex << "allowedEffects=0x" << allowedEffects
+ << "reportedPerformedEffect=0x" << reportedPerformedEffect
+ << " resultEffect=0x" << resultEffect << "hr=0x" << int(r) << dec << "dropAction=" << dragResult;
return dragResult;
}
@@ -833,8 +930,7 @@ QWindowsDrag *QWindowsDrag::instance()
void QWindowsDrag::releaseDropDataObject()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s %p", __FUNCTION__, m_dropDataObject);
+ qCDebug(lcQpaMime) << __FUNCTION__ << m_dropDataObject;
if (m_dropDataObject) {
m_dropDataObject->Release();
m_dropDataObject = 0;
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index 33da4d6cc5..4f758fbf3f 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -74,7 +74,6 @@ public:
STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect);
private:
- inline QWindow *findDragOverWindow(const POINTL &pt) const;
void handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &, LPDWORD pdwEffect);
ULONG m_refs;
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index d029249eeb..e025d7e513 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -89,16 +89,14 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
Q_FUNC_INFO, eglGetError());
return 0;
}
- if (QWindowsContext::verboseGL)
- qDebug("%s: Created EGL display %p v%d.%d",
- __FUNCTION__, display, major, minor);
+
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Created EGL display" << display << 'v' <<major << '.' << minor;
return new QWindowsEGLStaticContext(display, (major << 8) | minor);
}
QWindowsEGLStaticContext::~QWindowsEGLStaticContext()
{
- if (QWindowsContext::verboseGL)
- qDebug("%s: Releasing EGL display %p", __FUNCTION__, m_display);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Releasing EGL display " << m_display;
eglTerminate(m_display);
}
@@ -137,11 +135,7 @@ QWindowsEGLContext::~QWindowsEGLContext()
bool QWindowsEGLContext::hasThreadedOpenGLCapability()
{
-#ifdef QT_OPENGL_ES_2_ANGLE
return false;
-#else
- return true;
-#endif
}
EGLSurface QWindowsEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 3a6f9f72e3..96659c505f 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -841,7 +841,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
int type)
{
// the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
+ if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
return false;
static const int SMOOTH_SCALABLE = 0xffff;
@@ -857,19 +857,20 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseFonts > 2) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << familyName << charSet
- << "TTF=" << ttf;
+ if (QWindowsContext::verbose > 2) {
+ QString message;
+ QTextStream str(&message);
+ str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
if (type & DEVICE_FONTTYPE)
- nospace << " DEVICE";
+ str << " DEVICE";
if (type & RASTER_FONTTYPE)
- nospace << " RASTER";
+ str << " RASTER";
if (type & TRUETYPE_FONTTYPE)
- nospace << " TRUETYPE";
- nospace << " scalable=" << scalable << " Size=" << size
+ str << " TRUETYPE";
+ str << " scalable=" << scalable << " Size=" << size
<< " Style=" << style << " Weight=" << weight
<< " stretch=" << stretch;
+ qCDebug(lcQpaFonts) << message;
}
#endif
@@ -932,8 +933,8 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
return true;
}
-static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
- int type, LPARAM namesSetIn)
+static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
+ int type, LPARAM namesSetIn)
{
typedef QSet<QString> StringSet;
const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName);
@@ -973,8 +974,7 @@ void QWindowsFontDatabase::populateFontDatabase()
void QWindowsFontDatabase::populate(const QString &family)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << m_families.size() << family;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family;
HDC dummy = GetDC(0);
LOGFONT lf;
@@ -1026,11 +1026,10 @@ QWindowsFontDatabase::QWindowsFontDatabase()
Q_UNUSED(hfontMetaTypeId)
Q_UNUSED(logFontMetaTypeId)
- if (QWindowsContext::verboseFonts) {
+ if (lcQpaFonts().isDebugEnabled()) {
const QWindowsFontEngineDataPtr data = sharedFontData();
- qDebug() << __FUNCTION__ << "Clear type: "
- << data->clearTypeEnabled << "gamma: "
- << data->fontSmoothingGamma;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "Clear type: "
+ << data->clearTypeEnabled << "gamma: " << data->fontSmoothingGamma;
}
}
@@ -1039,13 +1038,12 @@ QWindowsFontDatabase::~QWindowsFontDatabase()
removeApplicationFonts();
}
-QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle)
+QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
- QFontEngine *fe = QWindowsFontDatabase::createEngine(script, fontDef,
+ QFontEngine *fe = QWindowsFontDatabase::createEngine(QChar::Script_Common, fontDef,
0, QWindowsContext::instance()->defaultDPI(), false,
QStringList(), sharedFontData());
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDEF" << fontDef << script << fe << handle;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef << fe << handle;
return fe;
}
@@ -1200,8 +1198,7 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal
}
}
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine;
return fontEngine;
}
@@ -1361,17 +1358,14 @@ void QWindowsFontDatabase::removeApplicationFonts()
m_applicationFonts.clear();
}
-void QWindowsFontDatabase::releaseHandle(void *handle)
+void QWindowsFontDatabase::releaseHandle(void * /* handle */)
{
- if (handle && QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << handle;
}
QString QWindowsFontDatabase::fontDir() const
{
const QString result = QPlatformFontDatabase::fontDir();
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << result;
return result;
}
@@ -1550,7 +1544,7 @@ LOGFONT QWindowsFontDatabase::fontDefToLOGFONT(const QFontDef &request)
return lf;
}
-static QStringList extraTryFontsForFamily(const QString& family)
+QStringList QWindowsFontDatabase::extraTryFontsForFamily(const QString &family)
{
QStringList result;
QFontDatabase db;
@@ -1620,11 +1614,11 @@ QStringList QWindowsFontDatabase::fallbacksForFamily(const QString &family, QFon
result << QString::fromLatin1("Arial");
}
- result.append(extraTryFontsForFamily(family));
+ if (script == QChar::Script_Common || script == QChar::Script_Han)
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << family << style << styleHint
- << script << result << m_families.size();
+ qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families.size();
return result;
}
@@ -1752,14 +1746,6 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ
QWindowsFontEngine *few = new QWindowsFontEngine(request.family, hfont, stockFont, lf, data);
if (preferClearTypeAA)
few->glyphFormat = QFontEngineGlyphCache::Raster_RGBMask;
-
- // Also check for OpenType tables when using complex scripts
- if (!few->supportsScript(QChar::Script(script))) {
- qWarning(" OpenType support missing for script %d", int(script));
- delete few;
- return 0;
- }
-
few->initFontInfo(request, fontHdc, dpi);
fe = few;
}
@@ -1785,7 +1771,7 @@ QFontEngine *QWindowsFontDatabase::createEngine(int script, const QFontDef &requ
if ((script == QChar::Script_Common || script == QChar::Script_Han)
&& !(request.styleStrategy & QFont::NoFontMerging)) {
- QStringList extraFonts = extraTryFontsForFamily(request.family);
+ const QStringList extraFonts = QWindowsFontDatabase::extraTryFontsForFamily(request.family);
if (extraFonts.size()) {
QStringList list = family_list;
list.append(extraFonts);
@@ -1810,8 +1796,7 @@ QFont QWindowsFontDatabase::systemDefaultFont()
// "MS Shell Dlg 2" is the correct system font >= Win2k
if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << systemFont;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << systemFont;
return systemFont;
}
@@ -1825,9 +1810,9 @@ QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int vertica
qFont.setWeight(weightFromInteger(logFont.lfWeight));
const qreal logFontHeight = qAbs(logFont.lfHeight);
qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(false);
+ qFont.setUnderline(logFont.lfUnderline);
qFont.setOverline(false);
- qFont.setStrikeOut(false);
+ qFont.setStrikeOut(logFont.lfStrikeOut);
return qFont;
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
index b9e6c38eaa..1e13fc2559 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -78,7 +78,7 @@ public:
~QWindowsFontDatabase();
virtual void populateFontDatabase();
- virtual QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ virtual QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
virtual QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
@@ -103,6 +103,8 @@ public:
static qreal fontSmoothingGamma();
static LOGFONT fontDefToLOGFONT(const QFontDef &fontDef);
+ static QStringList extraTryFontsForFamily(const QString &family);
+
private:
void populate(const QString &family = QString());
void removeApplicationFonts();
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index 51f79736f2..51961014d9 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -130,7 +130,7 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
typedef QPair<QString, QStringList> FontKey;
// the "@family" fonts are just the same as "family". Ignore them.
- if (familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
+ if (familyName.isEmpty() || familyName.at(0) == QLatin1Char('@') || familyName.startsWith(QStringLiteral("WST_")))
return false;
const int separatorPos = familyName.indexOf(QStringLiteral("::"));
@@ -151,19 +151,20 @@ static bool addFontToDatabase(const QString &familyName, uchar charSet,
const QFont::Stretch stretch = QFont::Unstretched;
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseFonts > 2) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << familyName << faceName << fullName << charSet
- << "TTF=" << ttf;
+ if (QWindowsContext::verbose > 2) {
+ QString message;
+ QTextStream str(&message);
+ str << __FUNCTION__ << ' ' << familyName << ' ' << charSet << " TTF=" << ttf;
if (type & DEVICE_FONTTYPE)
- nospace << " DEVICE";
+ str << " DEVICE";
if (type & RASTER_FONTTYPE)
- nospace << " RASTER";
+ str << " RASTER";
if (type & TRUETYPE_FONTTYPE)
- nospace << " TRUETYPE";
- nospace << " scalable=" << scalable << " Size=" << size
+ str << " TRUETYPE";
+ str << " scalable=" << scalable << " Size=" << size
<< " Style=" << style << " Weight=" << weight
<< " stretch=" << stretch;
+ qCDebug(lcQpaFonts) << message;
}
#endif
@@ -335,8 +336,8 @@ static QByteArray getFntTable(HFONT hfont, uint tag)
}
#endif
-static int CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
- int type, LPARAM namesSetIn)
+static int QT_WIN_CALLBACK storeFont(ENUMLOGFONTEX* f, NEWTEXTMETRICEX *textmetric,
+ int type, LPARAM namesSetIn)
{
typedef QSet<QString> StringSet;
const QString familyName = QString::fromWCharArray(f->elfLogFont.lfFaceName)
@@ -403,8 +404,7 @@ void QWindowsFontDatabaseFT::populateFontDatabase()
void QWindowsFontDatabaseFT::populate(const QString &family)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << m_families.size() << family;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << m_families.size() << family;
HDC dummy = GetDC(0);
LOGFONT lf;
@@ -422,111 +422,22 @@ void QWindowsFontDatabaseFT::populate(const QString &family)
ReleaseDC(0, dummy);
}
-QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle)
+QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, void *handle)
{
- QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, script, handle);
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDEF" << /*fontDef <<*/ script << fe << handle;
+ QFontEngine *fe = QBasicFontDatabase::fontEngine(fontDef, handle);
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDEF" << fontDef.family << fe << handle;
return fe;
}
QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
QFontEngine *fe = QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference);
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe;
return fe;
}
-static const char *other_tryFonts[] = {
- "Arial",
- "MS UI Gothic",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *jp_tryFonts [] = {
- "MS UI Gothic",
- "Arial",
- "Gulim",
- "SimSun",
- "PMingLiU",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_CN_tryFonts [] = {
- "SimSun",
- "Arial",
- "PMingLiU",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *ch_TW_tryFonts [] = {
- "PMingLiU",
- "Arial",
- "SimSun",
- "Gulim",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char *kr_tryFonts[] = {
- "Gulim",
- "Arial",
- "PMingLiU",
- "SimSun",
- "MS UI Gothic",
- "Arial Unicode MS",
- 0
-};
-
-static const char **tryFonts = 0;
-
QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
- if (script == QChar::Script_Common || script == QChar::Script_Han) {
-// && !(request.styleStrategy & QFont::NoFontMerging)) {
- QFontDatabase db;
- if (!db.writingSystems(family).contains(QFontDatabase::Symbol)) {
- if(!tryFonts) {
- LANGID lid = GetUserDefaultLangID();
- switch( lid&0xff ) {
- case LANG_CHINESE: // Chinese (Taiwan)
- if ( lid == 0x0804 ) // Taiwan
- tryFonts = ch_TW_tryFonts;
- else
- tryFonts = ch_CN_tryFonts;
- break;
- case LANG_JAPANESE:
- tryFonts = jp_tryFonts;
- break;
- case LANG_KOREAN:
- tryFonts = kr_tryFonts;
- break;
- default:
- tryFonts = other_tryFonts;
- break;
- }
- }
- QStringList list;
- const char **tf = tryFonts;
- while(tf && *tf) {
- if(m_families.contains(QLatin1String(*tf)))
- list << QLatin1String(*tf);
- ++tf;
- }
- if (!list.isEmpty())
- return list;
- }
- }
QStringList result = QPlatformFontDatabase::fallbacksForFamily(family, style, styleHint, script);
if (!result.isEmpty())
return result;
@@ -566,51 +477,24 @@ QStringList QWindowsFontDatabaseFT::fallbacksForFamily(const QString &family, QF
}
#endif
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << family << style << styleHint
- << script << result << m_families;
+ if (script == QChar::Script_Common || script == QChar::Script_Han)
+ result.append(QWindowsFontDatabase::extraTryFontsForFamily(family));
+
+ qCDebug(lcQpaFonts) << __FUNCTION__ << family << style << styleHint
+ << script << result << m_families;
+
return result;
}
QString QWindowsFontDatabaseFT::fontDir() const
{
const QString result = QLatin1String(qgetenv("windir")) + QLatin1String("/Fonts");//QPlatformFontDatabase::fontDir();
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << result;
return result;
}
-HFONT QWindowsFontDatabaseFT::systemFont()
-{
- static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT);
- return stock_sysfont;
-}
-
-// Creation functions
-
-static inline int verticalDPI()
-{
- return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
-}
-
QFont QWindowsFontDatabaseFT::defaultFont() const
{
return QWindowsFontDatabase::systemDefaultFont();
}
-QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
-{
- if (verticalDPI_In <= 0)
- verticalDPI_In = verticalDPI();
- QFont qFont(QString::fromWCharArray(logFont.lfFaceName));
- qFont.setItalic(logFont.lfItalic);
- if (logFont.lfWeight != FW_DONTCARE)
- qFont.setWeight(weightFromInteger(logFont.lfWeight));
- const qreal logFontHeight = qAbs(logFont.lfHeight);
- qFont.setPointSizeF(logFontHeight * 72.0 / qreal(verticalDPI_In));
- qFont.setUnderline(logFont.lfUnderline);
- qFont.setOverline(false);
- qFont.setStrikeOut(logFont.lfStrikeOut);
- return qFont;
-}
-
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
index d3cbc0210a..bad6c54bf4 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
@@ -52,7 +52,7 @@ class QWindowsFontDatabaseFT : public QBasicFontDatabase
{
public:
void populateFontDatabase();
- QFontEngine *fontEngine(const QFontDef &fontDef, QChar::Script script, void *handle);
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
@@ -60,9 +60,6 @@ public:
virtual QString fontDir() const;
virtual QFont defaultFont() const;
- static HFONT systemFont();
- static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
-
private:
void populate(const QString &family = QString());
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index 6c928119b3..1676b73658 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -219,44 +219,11 @@ inline unsigned int getChar(const QChar *str, int &i, const int len)
return uc;
}
-int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs, bool mirrored) const
+int QWindowsFontEngine::getGlyphIndexes(const QChar *str, int numChars, QGlyphLayout *glyphs) const
{
int i = 0;
int glyph_pos = 0;
- if (mirrored) {
-#if defined(Q_OS_WINCE)
- {
-#else
- if (symbol) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc);
- if (!glyphs->glyphs[glyph_pos] && uc < 0x100)
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, uc + 0xf000);
- }
- } else if (ttf) {
- for (; i < numChars; ++i, ++glyph_pos) {
- unsigned int uc = getChar(str, i, numChars);
- glyphs->glyphs[glyph_pos] = getTrueTypeGlyphIndex(cmap, QChar::mirroredChar(uc));
- }
- } else {
-#endif
- wchar_t first = tm.tmFirstChar;
- wchar_t last = tm.tmLastChar;
-
- for (; i < numChars; ++i, ++glyph_pos) {
- uint ucs = QChar::mirroredChar(getChar(str, i, numChars));
- if (
-#ifdef Q_WS_WINCE
- tm.tmFirstChar > 60000 ||
-#endif
- ucs >= first && ucs <= last)
- glyphs->glyphs[glyph_pos] = ucs;
- else
- glyphs->glyphs[glyph_pos] = 0;
- }
- }
- } else {
+ {
#if defined(Q_OS_WINCE)
{
#else
@@ -325,8 +292,7 @@ QWindowsFontEngine::QWindowsFontEngine(const QString &name,
designAdvances(0),
designAdvancesSize(0)
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s: font='%s', size=%ld", __FUNCTION__, qPrintable(name), lf.lfHeight);
+ qCDebug(lcQpaFonts) << __FUNCTION__ << name << lf.lfHeight;
HDC hdc = m_fontEngineData->hdc;
SelectObject(hdc, hfont);
fontDef.pixelSize = -lf.lfHeight;
@@ -366,9 +332,7 @@ QWindowsFontEngine::~QWindowsFontEngine()
if (!DeleteObject(hfont))
qErrnoWarning("%s: QFontEngineWin: failed to delete non-stock font... failed", __FUNCTION__);
}
- if (QWindowsContext::verboseFonts)
- if (QWindowsContext::verboseFonts)
- qDebug("%s: font='%s", __FUNCTION__, qPrintable(_name));
+ qCDebug(lcQpaFonts) << __FUNCTION__ << _name;
if (!uniqueFamilyName.isEmpty()) {
QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase();
@@ -393,7 +357,7 @@ bool QWindowsFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *g
}
glyphs->numGlyphs = *nglyphs;
- *nglyphs = getGlyphIndexes(str, len, glyphs, flags & RightToLeft);
+ *nglyphs = getGlyphIndexes(str, len, glyphs);
if (!(flags & GlyphIndicesOnly))
recalcAdvances(glyphs, flags);
@@ -434,8 +398,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
calculateTTFGlyphWidth(hdc, glyph, width);
designAdvances[glyph] = QFixed(width) / designToDevice;
}
- glyphs->advances_x[i] = designAdvances[glyph];
- glyphs->advances_y[i] = 0;
+ glyphs->advances[i] = designAdvances[glyph];
}
if(oldFont)
DeleteObject(SelectObject(hdc, oldFont));
@@ -443,8 +406,6 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
for(int i = 0; i < glyphs->numGlyphs; i++) {
unsigned int glyph = glyphs->glyphs[i];
- glyphs->advances_y[i] = 0;
-
if (glyph >= widthCacheSize) {
int newSize = (glyph + 256) >> 8 << 8;
widthCache = q_check_ptr((unsigned char *)realloc(widthCache,
@@ -452,9 +413,9 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
memset(widthCache + widthCacheSize, 0, newSize - widthCacheSize);
widthCacheSize = newSize;
}
- glyphs->advances_x[i] = widthCache[glyph];
+ glyphs->advances[i] = widthCache[glyph];
// font-width cache failed
- if (glyphs->advances_x[i] == 0) {
+ if (glyphs->advances[i].value() == 0) {
int width = 0;
if (!oldFont)
oldFont = SelectObject(hdc, hfont);
@@ -473,7 +434,7 @@ void QWindowsFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::Shape
} else {
calculateTTFGlyphWidth(hdc, glyph, width);
}
- glyphs->advances_x[i] = width;
+ glyphs->advances[i] = width;
// if glyph's within cache range, store it for later
if (width > 0 && width < 0x100)
widthCache[glyph] = width;
@@ -1347,8 +1308,7 @@ QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStri
: QFontEngineMulti(fallbacks.size()+1),
fallbacks(fallbacks)
{
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
+ qCDebug(lcQpaFonts) << __FUNCTION__ << engines.size() << first << first->fontDef.family << fallbacks;
engines[0] = first;
first->ref.ref();
fontDef = engines[0]->fontDef;
@@ -1357,8 +1317,7 @@ QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStri
QWindowsMultiFontEngine::~QWindowsMultiFontEngine()
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaFonts) << __FUNCTION__;
}
void QWindowsMultiFontEngine::loadEngine(int at)
@@ -1409,9 +1368,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
fedw->ref.ref();
engines[at] = fedw;
- if (QWindowsContext::verboseFonts)
- qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
-
+ qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam;
return;
} else {
qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__);
@@ -1433,9 +1390,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, data);
engines[at]->ref.ref();
engines[at]->fontDef = fontDef;
- if (QWindowsContext::verboseFonts)
- qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam));
-
+ qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam;
// TODO: increase cost in QFontCache for the font engine loaded here
}
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index acf84d270c..e3fb3281a3 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -127,7 +127,7 @@ public:
virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0);
#endif
- int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs, bool mirrored) const;
+ int getGlyphIndexes(const QChar *ch, int numChars, QGlyphLayout *glyphs) const;
void getCMap();
bool getOutlineMetrics(glyph_t glyph, const QTransform &t, glyph_metrics_t *metrics) const;
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
index d81848fcc7..ce5ea8167f 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp
@@ -212,8 +212,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
, m_xHeight(-1)
, m_lineGap(-1)
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s %g", __FUNCTION__, pixelSize);
+ qCDebug(lcQpaFonts) << __FUNCTION__ << pixelSize;
Q_ASSERT(m_directWriteFontFace);
@@ -227,8 +226,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di
QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite()
{
- if (QWindowsContext::verboseFonts)
- qDebug("%s", __FUNCTION__);
+ qCDebug(lcQpaFonts) << __FUNCTION__;
m_fontEngineData->directWriteFactory->Release();
m_directWriteFontFace->Release();
@@ -327,13 +325,8 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly
QVarLengthArray<UINT32> codePoints(len);
int actualLength = 0;
- if (flags & QFontEngine::RightToLeft) {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = QChar::mirroredChar(getChar(str, i, len));
- } else {
- for (int i = 0; i < len; ++i)
- codePoints[actualLength++] = getChar(str, i, len);
- }
+ for (int i = 0; i < len; ++i)
+ codePoints[actualLength++] = getChar(str, i, len);
QVarLengthArray<UINT16> glyphIndices(actualLength);
HRESULT hr = m_directWriteFontFace->GetGlyphIndicesW(codePoints.data(), actualLength,
@@ -368,13 +361,11 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
glyphIndices.size(),
glyphMetrics.data());
if (SUCCEEDED(hr)) {
- for (int i=0; i<glyphs->numGlyphs; ++i) {
- glyphs->advances_x[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
- glyphs->advances_y[i] = 0;
- }
+ for (int i = 0; i < glyphs->numGlyphs; ++i)
+ glyphs->advances[i] = DESIGN_TO_LOGICAL(glyphMetrics[i].advanceWidth);
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) {
for (int i = 0; i < glyphs->numGlyphs; ++i)
- glyphs->advances_x[i] = glyphs->advances_x[i].round();
+ glyphs->advances[i] = glyphs->advances[i].round();
}
} else {
qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
index 57a6a3ba1d..399bb5f5ad 100644
--- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
+++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h
@@ -105,6 +105,8 @@ public:
static QString fontNameSubstitute(const QString &familyName);
+ IDWriteFontFace *directWriteFontFace() const { return m_directWriteFontFace; }
+
private:
QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform);
void collectMetrics();
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.cpp b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
new file mode 100644
index 0000000000..9c8b5ed620
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsgdiintegration.h"
+#include "qwindowscontext.h"
+#include "qwindowsbackingstore.h"
+#include "qwindowsgdinativeinterface.h"
+
+#include <QtCore/QDebug>
+#include <QtGui/private/qpixmap_raster_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGdiIntegrationPrivate
+{
+public:
+ QWindowsGdiNativeInterface m_nativeInterface;
+};
+
+QWindowsGdiIntegration::QWindowsGdiIntegration(const QStringList &paramList)
+ : QWindowsIntegration(paramList)
+ , d(new QWindowsGdiIntegrationPrivate)
+{}
+
+QWindowsGdiIntegration::~QWindowsGdiIntegration()
+{}
+
+QPlatformNativeInterface *QWindowsGdiIntegration::nativeInterface() const
+{
+ return &d->m_nativeInterface;
+}
+
+QPlatformPixmap *QWindowsGdiIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
+{
+ return new QRasterPlatformPixmap(type);
+}
+
+QPlatformBackingStore *QWindowsGdiIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWindowsBackingStore(window);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.h b/src/plugins/platforms/windows/qwindowsgdiintegration.h
new file mode 100644
index 0000000000..0bf44d5439
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGDIINTEGRATION_H
+#define QWINDOWSGDIINTEGRATION_H
+
+#include "qwindowsintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGdiIntegrationPrivate;
+class QWindowsGdiIntegration : public QWindowsIntegration
+{
+public:
+ explicit QWindowsGdiIntegration(const QStringList &paramList);
+ virtual ~QWindowsGdiIntegration();
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+
+private:
+ QScopedPointer<QWindowsGdiIntegrationPrivate> d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGDIINTEGRATION_H
diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
new file mode 100644
index 0000000000..c1b0c139c9
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsgdinativeinterface.h"
+#include "qwindowsbackingstore.h"
+
+#include <QtGui/QBackingStore>
+
+QT_BEGIN_NAMESPACE
+
+void *QWindowsGdiNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
+{
+ if (!bs || !bs->handle()) {
+ qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
+ if (resource == "getDC")
+ return wbs->getDC();
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.h b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
new file mode 100644
index 0000000000..3aa3a0b175
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSGDINATIVEINTERFACE_H
+#define QWINDOWSGDINATIVEINTERFACE_H
+
+#include "qwindowsnativeinterface.h"
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsGdiNativeInterface : public QWindowsNativeInterface
+{
+ Q_OBJECT
+public:
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSGDINATIVEINTERFACE_H
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 82deb0f473..9bfe4e6e26 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -223,7 +223,7 @@ static void describeFormats(HDC hdc)
PIXELFORMATDESCRIPTOR pfd;
initPixelFormatDescriptor(&pfd);
DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- qDebug() << '#' << i << '/' << pfiMax << ':' << pfd;
+ qCDebug(lcQpaGl) << '#' << i << '/' << pfiMax << ':' << pfd;
}
}
@@ -341,10 +341,8 @@ static int choosePixelFormat(HDC hdc, const QSurfaceFormat &format,
bestPfi = pfi;
*obtainedPfd = checkPfd;
}
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
- << " score=" << score << " (best " << bestPfi << '/' << bestScore
- << ") " << checkPfd;
+ qCDebug(lcQpaGl) << __FUNCTION__ << " checking " << pfi << '/' << pfiMax
+ << " score=" << score << " (best " << bestPfi << '/' << bestScore << ") " << checkPfd;
}
} // for
if (bestPfi > 0)
@@ -471,15 +469,15 @@ static int choosePixelFormat(HDC hdc,
initPixelFormatDescriptor(obtainedPfd);
DescribePixelFormat(hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), obtainedPfd);
if (!isAcceptableFormat(additional, *obtainedPfd, true)) {
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << " obtained px #" << pixelFormat
- << " not acceptable=" << *obtainedPfd;
+ qCDebug(lcQpaGl) << __FUNCTION__ << " obtained px #" << pixelFormat
+ << " not acceptable=" << *obtainedPfd;
pixelFormat = 0;
}
#ifndef QT_NO_DEBUG_OUTPUT
- if (QWindowsContext::verboseGL) {
- QDebug nsp = qDebug().nospace();
+ if (lcQpaGl().isDebugEnabled()) {
+ QString message;
+ QDebug nsp(&message);
nsp << __FUNCTION__;
if (sampleBuffersRequested)
nsp << " samples=" << iAttributes[samplesValuePosition];
@@ -488,6 +486,7 @@ static int choosePixelFormat(HDC hdc,
nsp << iAttributes[ii] << ',';
nsp << noshowbase << dec << "\n obtained px #" << pixelFormat
<< " of " << numFormats << "\n " << *obtainedPfd;
+ qCDebug(lcQpaGl) << message;
} // Debug
#endif
@@ -611,9 +610,8 @@ static HGLRC createContext(const QOpenGLStaticContext &staticContext,
break;
}
}
- if (QWindowsContext::verboseGL)
- qDebug("%s: Creating context version %d.%d with %d attributes",
- __FUNCTION__, majorVersion, minorVersion, attribIndex / 2);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Creating context version"
+ << majorVersion << '.' << minorVersion << attribIndex / 2 << "attributes";
const HGLRC result =
staticContext.wglCreateContextAttribsARB(hdc, shared, attributes);
@@ -842,8 +840,7 @@ QOpenGLStaticContext *QOpenGLStaticContext::create()
if (!wglGetCurrentContext())
temporaryContext.reset(new QOpenGLTemporaryContext);
QOpenGLStaticContext *result = new QOpenGLStaticContext;
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << *result;
+ qCDebug(lcQpaGl) << __FUNCTION__ << *result;
return result;
}
@@ -857,7 +854,7 @@ QDebug operator<<(QDebug d, const QOpenGLStaticContext &s)
if (s.hasExtensions())
nsp << ", Extension-API present";
nsp << "\nExtensions: " << (s.extensionNames.count(' ') + 1);
- if (QWindowsContext::verboseGL > 1)
+ if (QWindowsContext::verbose > 1)
nsp << s.extensionNames;
return d;
}
@@ -882,7 +879,9 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
m_staticContext(staticContext),
m_context(context),
m_renderingContext(0),
- m_pixelFormat(0), m_extensionsUsed(false)
+ m_pixelFormat(0),
+ m_extensionsUsed(false),
+ m_swapInterval(-1)
{
QSurfaceFormat format = context->format();
if (format.renderableType() == QSurfaceFormat::DefaultRenderableType)
@@ -915,7 +914,7 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
if (!hdc)
break;
- if (QWindowsContext::verboseGL > 1)
+ if (QWindowsContext::verbose > 1)
describeFormats(hdc);
// Preferably use direct rendering and ARB extensions (unless pixmap
// or explicitly turned off on command line).
@@ -979,11 +978,9 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
QWindowsOpenGLContextFormat::current().apply(&m_obtainedFormat);
- if (requestedAdditional.swapInterval != -1 && m_staticContext->wglSwapInternalExt) {
- m_staticContext->wglSwapInternalExt(requestedAdditional.swapInterval);
- if (m_staticContext->wglGetSwapInternalExt)
- obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
- }
+ if (m_staticContext->wglGetSwapInternalExt)
+ obtainedSwapInternal = m_staticContext->wglGetSwapInternalExt();
+
wglMakeCurrent(0, 0);
} while (false);
if (hdc)
@@ -991,14 +988,12 @@ QWindowsGLContext::QWindowsGLContext(const QOpenGLStaticContextPtr &staticContex
if (dummyWindow)
DestroyWindow(dummyWindow);
- if (QWindowsContext::verboseGL)
- qDebug() << __FUNCTION__ << this << (tryExtensions ? "ARB" : "GDI")
- << " requested: " << context->format()
- << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI")
- << m_obtainedFormat << "\n " << m_obtainedPixelFormatDescriptor
- << " swap interval: " << obtainedSwapInternal
- << "\n default: " << m_staticContext->defaultFormat
- << "\n HGLRC=" << m_renderingContext;
+ qCDebug(lcQpaGl) << __FUNCTION__ << this << (tryExtensions ? "ARB" : "GDI")
+ << " requested: " << context->format()
+ << "\n obtained #" << m_pixelFormat << (m_extensionsUsed ? "ARB" : "GDI") << m_obtainedFormat
+ << "\n " << m_obtainedPixelFormatDescriptor << " swap interval: " << obtainedSwapInternal
+ << "\n default: " << m_staticContext->defaultFormat
+ << "\n HGLRC=" << m_renderingContext;
}
QWindowsGLContext::~QWindowsGLContext()
@@ -1039,8 +1034,8 @@ static inline const QOpenGLContextData *
void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
{
- if (QWindowsContext::verboseGL > 1)
- qDebug() << __FUNCTION__ << surface;
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << surface;
if (const QOpenGLContextData *contextData = findByHWND(m_windowContexts, handleOf(surface))) {
SwapBuffers(contextData->hdc);
} else {
@@ -1051,8 +1046,8 @@ void QWindowsGLContext::swapBuffers(QPlatformSurface *surface)
bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
{
#ifdef DEBUG_GL
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s context=%p contexts=%d", __FUNCTION__, this, m_windowContexts.size());
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts";
#endif // DEBUG_GL
Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
@@ -1087,14 +1082,26 @@ bool QWindowsGLContext::makeCurrent(QPlatformSurface *surface)
window->setFlag(QWindowsWindow::OpenGLDoubleBuffered);
}
m_windowContexts.append(newContext);
- return wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+
+ bool success = wglMakeCurrent(newContext.hdc, newContext.renderingContext);
+
+ // Set the swap interval
+ if (m_staticContext->wglSwapInternalExt) {
+ const int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ m_staticContext->wglSwapInternalExt(interval);
+ }
+ }
+
+ return success;
}
void QWindowsGLContext::doneCurrent()
{
#ifdef DEBUG_GL
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s context=%p %d contexts", __FUNCTION__, this, m_windowContexts.size());
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << this << m_windowContexts.size() << "contexts";
#endif // DEBUG_GL
wglMakeCurrent(0, 0);
releaseDCs();
@@ -1104,10 +1111,8 @@ QWindowsGLContext::GL_Proc QWindowsGLContext::getProcAddress(const QByteArray &p
{
// TODO: Will that work with the calling conventions?
GL_Proc procAddress = reinterpret_cast<GL_Proc>(wglGetProcAddress(procName.constData()));
- if (QWindowsContext::verboseGL > 1)
- qDebug("%s('%s') with current_hglrc=%p returns %p",
- __FUNCTION__, procName.constData(),
- wglGetCurrentContext(), procAddress);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaGl) << __FUNCTION__ << procName << wglGetCurrentContext() << "returns" << procAddress;
if (!procAddress)
qWarning("%s: Unable to resolve '%s'", __FUNCTION__, procName.constData());
return procAddress;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 730e90bf70..c6b477128a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -64,11 +64,10 @@ enum QWindowsGLFormatFlags
// Additional format information for Windows.
struct QWindowsOpenGLAdditionalFormat
{
- QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0, unsigned swapIntervalIn = -1) :
- formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn), swapInterval(swapIntervalIn) {}
+ QWindowsOpenGLAdditionalFormat(unsigned formatFlagsIn = 0, unsigned pixmapDepthIn = 0) :
+ formatFlags(formatFlagsIn), pixmapDepth(pixmapDepthIn) { }
unsigned formatFlags; // QWindowsGLFormatFlags.
unsigned pixmapDepth; // for QWindowsGLRenderToPixmap
- int swapInterval;
};
// Per-window data for active OpenGL contexts.
@@ -178,6 +177,7 @@ private:
PIXELFORMATDESCRIPTOR m_obtainedPixelFormatDescriptor;
int m_pixelFormat;
bool m_extensionsUsed;
+ int m_swapInterval;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
index e7cd0bc6c8..878db7185d 100644
--- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
+++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp
@@ -75,11 +75,11 @@ QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
{
m_flags = flags;
- if (QWindowsContext::verboseEvents > 2)
- qDebug(">%s %s %d", __FUNCTION__, qPrintable(objectName()), int(flags));
+ if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
+ qCDebug(lcQpaEvents) << '>' << __FUNCTION__ << objectName() << flags;
const bool rc = QEventDispatcherWin32::processEvents(flags);
- if (QWindowsContext::verboseEvents > 2)
- qDebug("<%s %s returns %d", __FUNCTION__, qPrintable(objectName()), rc);
+ if (QWindowsContext::verbose > 2 && lcQpaEvents().isDebugEnabled())
+ qCDebug(lcQpaEvents) << '<' << __FUNCTION__ << "returns" << rc;
return rc;
}
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index a84d30de0f..2429e8a4fa 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -188,8 +188,7 @@ void QWindowsInputContext::reset()
if (!m_compositionContext.hwnd)
return;
QObject *fo = qApp->focusObject();
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__<< fo;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__<< fo;
if (!fo)
return;
if (m_compositionContext.isComposing) {
@@ -221,8 +220,7 @@ void QWindowsInputContext::cursorRectChanged()
if (!cursorRectangle.isValid())
return;
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__<< cursorRectangle;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__<< cursorRectangle;
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
if (!himc)
@@ -259,8 +257,7 @@ void QWindowsInputContext::invokeAction(QInputMethod::Action action, int cursorP
return;
}
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << cursorPosition << action;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << cursorPosition << action;
if (cursorPosition < 0 || cursorPosition > m_compositionContext.composition.size())
reset();
@@ -339,8 +336,7 @@ bool QWindowsInputContext::startComposition(HWND hwnd)
QWindow *window = qApp->focusWindow();
if (!window)
return false;
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << fo << window;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << fo << window;
if (!fo || QWindowsWindow::handleOf(window) != hwnd)
return false;
initContext(hwnd);
@@ -402,9 +398,8 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
{
QObject *fo = qApp->focusObject();
const int lParam = int(lParamIn);
- if (QWindowsContext::verboseInputMethods)
- qDebug() << '>' << __FUNCTION__ << fo << debugComposition(lParam)
- << " composing=" << m_compositionContext.isComposing;
+ qCDebug(lcQpaInputMethods) << '>' << __FUNCTION__ << fo << debugComposition(lParam)
+ << " composing=" << m_compositionContext.isComposing;
if (!fo || m_compositionContext.hwnd != hwnd || !lParam)
return false;
const HIMC himc = ImmGetContext(m_compositionContext.hwnd);
@@ -443,11 +438,9 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
endContextComposition();
}
const bool result = QCoreApplication::sendEvent(fo, event.data());
- if (QWindowsContext::verboseInputMethods)
- qDebug() << '<' << __FUNCTION__ << "sending markup="
- << event->attributes().size()
- << " commit=" << event->commitString()
- << " to " << fo << " returns " << result;
+ qCDebug(lcQpaInputMethods) << '<' << __FUNCTION__ << "sending markup="
+ << event->attributes().size() << " commit=" << event->commitString()
+ << " to " << fo << " returns " << result;
update(Qt::ImQueryAll);
ImmReleaseContext(m_compositionContext.hwnd, himc);
return result;
@@ -455,8 +448,7 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn)
bool QWindowsInputContext::endComposition(HWND hwnd)
{
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << m_endCompositionRecursionGuard << hwnd;
// Googles Pinyin Input Method likes to call endComposition again
// when we call notifyIME with CPS_CANCEL, so protect ourselves
// against that.
@@ -549,10 +541,8 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
return -1;
const DWORD memSize = sizeof(RECONVERTSTRING)
+ (surroundingText.length() + 1) * sizeof(ushort);
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << " reconv=" << reconv
- << " surroundingText=" << surroundingText
- << " size=" << memSize;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << " reconv=" << reconv
+ << " surroundingText=" << surroundingText << " size=" << memSize;
// If memory is not allocated, return the required size.
if (!reconv)
return surroundingText.isEmpty() ? -1 : int(memSize);
@@ -567,8 +557,7 @@ int QWindowsInputContext::reconvertString(RECONVERTSTRING *reconv)
const int startPos = bounds.position();
bounds.toNextBoundary();
const int endPos = bounds.position();
- if (QWindowsContext::verboseInputMethods)
- qDebug() << __FUNCTION__ << " boundary=" << startPos << endPos;
+ qCDebug(lcQpaInputMethods) << __FUNCTION__ << " boundary=" << startPos << endPos;
// Select the text, this will be overwritten by following IME events.
QList<QInputMethodEvent::Attribute> attributes;
attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, startPos, endPos-startPos, QVariant());
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index b6e75929f8..e5d9444966 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -41,15 +41,22 @@
****************************************************************************/
#include "qwindowsintegration.h"
-#include "qwindowsbackingstore.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
-#if defined(QT_OPENGL_ES_2)
+
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include "qwindowseglcontext.h"
# include <QtGui/QOpenGLContext>
-#elif !defined(QT_NO_OPENGL)
+#endif
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
# include "qwindowsglcontext.h"
#endif
+
+#if !defined(QT_NO_OPENGL)
+# include <QtGui/QOpenGLFunctions>
+#endif
+
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
#include "qwindowsservices.h"
@@ -75,8 +82,6 @@
#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
# include "qwindowssessionmanager.h"
#endif
-#include <QtGui/QBackingStore>
-#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/private/qeventdispatcher_win_p.h>
@@ -86,174 +91,6 @@
QT_BEGIN_NAMESPACE
/*!
- \class QWindowsNativeInterface
- \brief Provides access to native handles.
-
- Currently implemented keys
- \list
- \li handle (HWND)
- \li getDC (DC)
- \li releaseDC Releases the previously acquired DC and returns 0.
- \endlist
-
- \internal
- \ingroup qt-lighthouse-win
-*/
-
-class QWindowsNativeInterface : public QPlatformNativeInterface
-{
- Q_OBJECT
- Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
-public:
-#ifndef QT_NO_OPENGL
- virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
-#endif
- virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
- virtual void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs);
-
- Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
- const QString &windowName,
- void *eventProc) const;
-
- Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
-
- Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication
-
- bool asyncExpose() const;
- void setAsyncExpose(bool value);
-
- QVariantMap windowProperties(QPlatformWindow *window) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
- QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
- void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
-};
-
-void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
-{
- if (!window || !window->handle()) {
- qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
- QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
- if (resource == "handle")
- return bw->handle();
- if (window->surfaceType() == QWindow::RasterSurface) {
- if (resource == "getDC")
- return bw->getDC();
- if (resource == "releaseDC") {
- bw->releaseDC();
- return 0;
- }
- }
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-
-void *QWindowsNativeInterface::nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs)
-{
- if (!bs || !bs->handle()) {
- qWarning("%s: '%s' requested for null backingstore or backingstore without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
- QWindowsBackingStore *wbs = static_cast<QWindowsBackingStore *>(bs->handle());
- if (resource == "getDC")
- return wbs->getDC();
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-
-static const char customMarginPropertyC[] = "WindowsCustomMargins";
-
-QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
-{
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
- if (name == QLatin1String(customMarginPropertyC))
- return qVariantFromValue(platformWindow->customMargins());
- return QVariant();
-}
-
-QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
-{
- const QVariant result = windowProperty(window, name);
- return result.isValid() ? result : defaultValue;
-}
-
-void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
-{
- QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
- if (name == QLatin1String(customMarginPropertyC))
- platformWindow->setCustomMargins(qvariant_cast<QMargins>(value));
-}
-
-QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) const
-{
- QVariantMap result;
- const QString customMarginProperty = QLatin1String(customMarginPropertyC);
- result.insert(customMarginProperty, windowProperty(window, customMarginProperty));
- return result;
-}
-
-#ifndef QT_NO_OPENGL
-void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
-{
- if (!context || !context->handle()) {
- qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
- return 0;
- }
-#ifdef QT_OPENGL_ES_2
- QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("eglDisplay"))
- return windowsEglContext->eglDisplay();
- if (resource == QByteArrayLiteral("eglContext"))
- return windowsEglContext->eglContext();
- if (resource == QByteArrayLiteral("eglConfig"))
- return windowsEglContext->eglConfig();
-#else // QT_OPENGL_ES_2
- QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
- if (resource == QByteArrayLiteral("renderingContext"))
- return windowsContext->renderingContext();
-#endif // !QT_OPENGL_ES_2
-
- qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
- return 0;
-}
-#endif // !QT_NO_OPENGL
-
-/*!
- \brief Creates a non-visible window handle for filtering messages.
-*/
-
-void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
- const QString &windowName,
- void *eventProc) const
-{
- QWindowsContext *ctx = QWindowsContext::instance();
- const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
- (wchar_t*)windowName.utf16(),
- (WNDPROC)eventProc);
- return hwnd;
-}
-
-/*!
- \brief Registers a unique window class with a callback function based on \a classNameIn.
-*/
-
-QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, void *eventProc) const
-{
- return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
-}
-
-bool QWindowsNativeInterface::asyncExpose() const
-{
- return QWindowsContext::instance()->asyncExpose();
-}
-
-void QWindowsNativeInterface::setAsyncExpose(bool value)
-{
- QWindowsContext::instance()->setAsyncExpose(value);
-}
-
-/*!
\class QWindowsIntegration
\brief QPlatformIntegration implementation for Windows.
\internal
@@ -296,9 +133,10 @@ void QWindowsNativeInterface::setAsyncExpose(bool value)
struct QWindowsIntegrationPrivate
{
-#if defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
typedef QSharedPointer<QWindowsEGLStaticContext> QEGLStaticContextPtr;
-#elif !defined(QT_NO_OPENGL)
+#endif
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
#endif
@@ -308,16 +146,16 @@ struct QWindowsIntegrationPrivate
const unsigned m_options;
QWindowsContext m_context;
QPlatformFontDatabase *m_fontDatabase;
- QWindowsNativeInterface m_nativeInterface;
#ifndef QT_NO_CLIPBOARD
QWindowsClipboard m_clipboard;
# ifndef QT_NO_DRAGANDDROP
QWindowsDrag m_drag;
# endif
#endif
-#if defined(QT_OPENGL_ES_2)
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
QEGLStaticContextPtr m_staticEGLContext;
-#elif !defined(QT_NO_OPENGL)
+#endif
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
QOpenGLStaticContextPtr m_staticOpenGLContext;
#endif
QWindowsInputContext m_inputContext;
@@ -345,8 +183,10 @@ static inline unsigned parseOptions(const QStringList &paramList)
}
} else if (param == QLatin1String("gl=gdi")) {
options |= QWindowsIntegration::DisableArb;
- } else if (param == QLatin1String("mousefromtouch")) {
- options |= QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch;
+ } else if (param == QLatin1String("nomousefromtouch")) {
+ options |= QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch;
+ } else if (param.startsWith(QLatin1String("verbose="))) {
+ QWindowsContext::verbose = param.right(param.size() - 8).toInt();
}
}
return options;
@@ -375,8 +215,6 @@ QWindowsIntegration::QWindowsIntegration(const QStringList &paramList) :
QWindowsIntegration::~QWindowsIntegration()
{
- if (QWindowsContext::verboseIntegration)
- qDebug("%s", __FUNCTION__);
}
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -388,8 +226,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
case OpenGL:
return true;
case ThreadedOpenGL:
-# ifdef QT_OPENGL_ES_2
- return QWindowsEGLContext::hasThreadedOpenGLCapability();
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+ return QOpenGLFunctions::isES() ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true;
# else
return true;
# endif // QT_OPENGL_ES_2
@@ -406,14 +244,9 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
return false;
}
-QPlatformPixmap *QWindowsIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
-{
- return new QRasterPlatformPixmap(type);
-}
-
-QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
+QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
{
- QWindowsWindow::WindowData requested;
+ QWindowsWindowData requested;
requested.flags = window->flags();
requested.geometry = window->geometry();
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
@@ -421,59 +254,61 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
if (customMarginsV.isValid())
requested.customMargins = qvariant_cast<QMargins>(customMarginsV);
- const QWindowsWindow::WindowData obtained
- = QWindowsWindow::WindowData::create(window, requested, window->title());
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug().nospace()
- << __FUNCTION__ << '<' << window << '\n'
- << " Requested: " << requested.geometry << "frame incl.: "
- << QWindowsGeometryHint::positionIncludesFrame(window)
- << " Flags="
- << QWindowsWindow::debugWindowFlags(requested.flags) << '\n'
- << " Obtained : " << obtained.geometry << " Margins "
- << obtained.frame << " Flags="
- << QWindowsWindow::debugWindowFlags(obtained.flags)
- << " Handle=" << obtained.hwnd << '\n';
- if (!obtained.hwnd)
- return 0;
- if (requested.flags != obtained.flags)
- window->setFlags(obtained.flags);
- // Trigger geometry change signals of QWindow.
- if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
- QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
- return new QWindowsWindow(window, obtained);
+ const QWindowsWindowData obtained
+ = QWindowsWindowData::create(window, requested, window->title());
+ qCDebug(lcQpaWindows).nospace()
+ << __FUNCTION__ << '<' << window
+ << "\n Requested: " << requested.geometry << "frame incl.: "
+ << QWindowsGeometryHint::positionIncludesFrame(window)
+ << " Flags=" << QWindowsWindow::debugWindowFlags(requested.flags)
+ << "\n Obtained : " << obtained.geometry << " Margins "<< obtained.frame
+ << " Flags=" << QWindowsWindow::debugWindowFlags(obtained.flags)
+ << " Handle=" << obtained.hwnd << '\n';
+
+ if (obtained.hwnd) {
+ if (requested.flags != obtained.flags)
+ window->setFlags(obtained.flags);
+ // Trigger geometry change signals of QWindow.
+ if ((obtained.flags & Qt::Desktop) != Qt::Desktop && requested.geometry != obtained.geometry)
+ QWindowSystemInterface::handleGeometryChange(window, obtained.geometry);
+ }
+
+ return obtained;
}
-QPlatformBackingStore *QWindowsIntegration::createPlatformBackingStore(QWindow *window) const
+QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << window;
- return new QWindowsBackingStore(window);
+ QWindowsWindowData data = createWindowData(window);
+ return data.hwnd ? new QWindowsWindow(window, data)
+ : Q_NULLPTR;
}
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext
*QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << context->format();
-#ifdef QT_OPENGL_ES_2
- if (d->m_staticEGLContext.isNull()) {
- QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
- if (!staticContext)
- return 0;
- d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
+ qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+ if (QOpenGLFunctions::isES()){
+ if (d->m_staticEGLContext.isNull()) {
+ QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
+ if (!staticContext)
+ return 0;
+ d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
+ }
+ return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
+ }
+#endif
+#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLFunctions::isES()) {
+ if (d->m_staticOpenGLContext.isNull())
+ d->m_staticOpenGLContext =
+ QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
+ QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
+ return result->isValid() ? result.take() : 0;
}
- return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
-#else // QT_OPENGL_ES_2
- if (d->m_staticOpenGLContext.isNull())
- d->m_staticOpenGLContext =
- QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
- QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
- if (result->isValid())
- return result.take();
- return 0;
#endif // !QT_OPENGL_ES_2
+ return 0;
}
#endif // !QT_NO_OPENGL
@@ -510,9 +345,7 @@ QPlatformFontDatabase *QWindowsIntegration::fontDatabase() const
d->m_fontDatabase = new QWindowsFontDatabase;
#else
if (isQMLApplication()) {
- if (QWindowsContext::verboseIntegration) {
- qDebug() << "QML application detected, using FreeType rendering";
- }
+ qCDebug(lcQpaFonts) << "QML application detected, using FreeType rendering";
d->m_fontDatabase = new QWindowsFontDatabaseFT;
}
else
@@ -563,11 +396,9 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
#ifdef Q_OS_WINCE
// We do not want Qt to synthesize mouse events as Windows also does that.
- // Alternatively, Windows-generated touch mouse events can be identified and
- // ignored by checking GetMessageExtraInfo() for MI_WP_SIGNATURE (0xFF515700).
return false;
#else // Q_OS_WINCE
- return QVariant(!(d->m_options & PassOsMouseEventsSynthesizedFromTouch));
+ return QVariant(bool(d->m_options & DontPassOsMouseEventsSynthesizedFromTouch));
#endif // !Q_OS_WINCE
default:
break;
@@ -585,11 +416,6 @@ QList<int> QWindowsIntegration::possibleKeys(const QKeyEvent *e) const
return d->m_context.possibleKeys(e);
}
-QPlatformNativeInterface *QWindowsIntegration::nativeInterface() const
-{
- return &d->m_nativeInterface;
-}
-
#ifndef QT_NO_CLIPBOARD
QPlatformClipboard * QWindowsIntegration::clipboard() const
{
@@ -655,5 +481,3 @@ QPlatformServices *QWindowsIntegration::services() const
}
QT_END_NAMESPACE
-
-#include "qwindowsintegration.moc"
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 97916a479b..2202ebd39e 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -50,6 +50,8 @@
QT_BEGIN_NAMESPACE
struct QWindowsIntegrationPrivate;
+struct QWindowsWindowData;
+class QWindowsWindow;
class QWindowsIntegration : public QPlatformIntegration
{
@@ -60,7 +62,7 @@ public:
DisableArb = 0x4,
NoNativeDialogs = 0x8,
XpNativeDialogs = 0x10,
- PassOsMouseEventsSynthesizedFromTouch = 0x20 // Pass OS-generated mouse events from touch.
+ DontPassOsMouseEventsSynthesizedFromTouch = 0x20 // Do not pass OS-generated mouse events from touch.
};
explicit QWindowsIntegration(const QStringList &paramList);
@@ -68,9 +70,8 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const;
- virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
+ QWindowsWindowData createWindowData(QWindow *window) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
#ifndef QT_NO_OPENGL
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
#endif
@@ -85,7 +86,6 @@ public:
#ifndef QT_NO_ACCESSIBILITY
virtual QPlatformAccessibility *accessibility() const;
#endif
- virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformFontDatabase *fontDatabase() const;
virtual QStringList themeNames() const;
virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
index 5d22ea1a83..75686182cf 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.cpp
@@ -75,8 +75,7 @@ bool QWindowsInternalMimeData::hasFormat_sys(const QString &mime) const
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
const bool has = mc.converterToMime(mime, pDataObj) != 0;
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mime << has;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mime << has;
return has;
}
@@ -89,8 +88,7 @@ QStringList QWindowsInternalMimeData::formats_sys() const
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
const QStringList fmts = mc.allMimesForFormats(pDataObj);
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << fmts;
+ qCDebug(lcQpaMime) << __FUNCTION__ << fmts;
return fmts;
}
@@ -106,12 +104,10 @@ QVariant QWindowsInternalMimeData::retrieveData_sys(const QString &mimeType,
if (const QWindowsMime *converter = mc.converterToMime(mimeType, pDataObj))
result = converter->convertToMime(mimeType, pDataObj, type);
releaseDataObject(pDataObj);
- if (QWindowsContext::verboseOLE) {
- QDebug nospace = qDebug().nospace();
- nospace << __FUNCTION__ << ' ' << mimeType << ' ' << type
- << " returns " << result.type();
- if (result.type() != QVariant::ByteArray)
- nospace << ' ' << result;
+ if (QWindowsContext::verbose) {
+ qCDebug(lcQpaMime) <<__FUNCTION__ << ' ' << mimeType << ' ' << type
+ << " returns " << result.type()
+ << (result.type() != QVariant::ByteArray ? result.toString() : QStringLiteral("<data>"));
}
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 334df17026..0b257cc48f 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -653,16 +653,20 @@ void QWindowsKeyMapper::updatePossibleKeyCodes(unsigned char *kbdBuffer, quint32
::ToAscii(VK_SPACE, 0, emptyBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
::ToAscii(vk_key, scancode, kbdBuffer, reinterpret_cast<LPWORD>(&buffer), 0);
}
-
- if (QWindowsContext::verboseEvents > 1) {
- qDebug("updatePossibleKeyCodes for virtual key = 0x%02x!", vk_key);
+ if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
+ QString message;
+ QDebug debug(&message);
+ debug <<__FUNCTION__ << " for virtual key = 0x" << hex << vk_key << dec<< '\n';
for (size_t i = 0; i < NumMods; ++i) {
- qDebug(" [%d] (%d,0x%02x,'%c') %s", int(i),
- keyLayout[vk_key].qtKey[i],
- keyLayout[vk_key].qtKey[i],
- keyLayout[vk_key].qtKey[i] ? keyLayout[vk_key].qtKey[i] : 0x03,
- keyLayout[vk_key].deadkeys & (1<<i) ? "deadkey" : "");
+ const quint32 qtKey = keyLayout[vk_key].qtKey[i];
+ debug << " [" << i << "] (" << qtKey << ','
+ << hex << showbase << qtKey << noshowbase << dec
+ << ",'" << char(qtKey ? qtKey : 0x03) << "')";
+ if (keyLayout[vk_key].deadkeys & (1<<i))
+ debug << " deadkey";
+ debug << '\n';
}
+ qCDebug(lcQpaEvents) << message;
}
}
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index f62b8a6139..3af2cff9a0 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -675,8 +675,7 @@ QVariant QWindowsMimeText::convertToMime(const QString &mime, LPDATAOBJECT pData
else
ret = str.toUtf8();
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << ret;
+ qCDebug(lcQpaMime) << __FUNCTION__ << ret;
return ret;
}
@@ -1490,8 +1489,7 @@ QStringList QWindowsMimeConverter::allMimesForFormats(IDataObject *pDataObj) con
}
fmtenum->Release();
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << pDataObj << formats;
+ qCDebug(lcQpaMime) << __FUNCTION__ << pDataObj << formats;
return formats;
}
@@ -1541,9 +1539,8 @@ QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
if (converter->canConvertToMime(format, pDataObj)) {
const QVariant dataV = converter->convertToMime(format, pDataObj, preferredType);
if (dataV.isValid()) {
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << mimeTypes << "\nFormat: "
- << format << pDataObj << " returns " << dataV;
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeTypes << "\nFormat: "
+ << format << pDataObj << " returns " << dataV;
if (formatIn)
*formatIn = format;
return dataV;
@@ -1551,8 +1548,7 @@ QVariant QWindowsMimeConverter::convertToMime(const QStringList &mimeTypes,
}
}
}
- if (QWindowsContext::verboseOLE)
- qDebug() << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
+ qCDebug(lcQpaMime) << __FUNCTION__ << "fails" << mimeTypes << pDataObj << preferredType;
return QVariant();
}
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index 3dd8c5a0cd..d8c0a9e426 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -167,8 +167,12 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
if (et == QtWindows::MouseWheelEvent)
return translateMouseWheelEvent(window, hwnd, msg, result);
+ Qt::MouseEventSource source = Qt::MouseEventNotSynthesized;
+
#ifndef Q_OS_WINCE
- static const bool passSynthesizedMouseEvents = QWindowsIntegration::instance()->options() & QWindowsIntegration::PassOsMouseEventsSynthesizedFromTouch;
+ // Check for events synthesized from touch. Lower byte is touch index, 0 means pen.
+ static const bool passSynthesizedMouseEvents =
+ !(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch);
if (!passSynthesizedMouseEvents) {
// Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch.
// However, when tablet support is active, extraInfo is a packet serial number. This is not a problem
@@ -177,6 +181,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const bool fromTouch = (extraInfo & signatureMask) == miWpSignature && (extraInfo & 0x80);
if (fromTouch)
return false;
+ source = Qt::MouseEventSynthesizedBySystem;
}
#endif // !Q_OS_WINCE
@@ -187,22 +192,21 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
const Qt::MouseButtons buttons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleFrameStrutMouseEvent(window, clientPosition,
globalPosition, buttons,
- QWindowsKeyMapper::queryKeyboardModifiers());
+ QWindowsKeyMapper::queryKeyboardModifiers(),
+ source);
return false; // Allow further event processing (dragging of windows).
}
*result = 0;
if (msg.message == WM_MOUSELEAVE) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow;
+ qCDebug(lcQpaEvents) << "WM_MOUSELEAVE for " << window << " previous window under mouse = " << m_windowUnderMouse << " tracked window =" << m_trackedWindow;
// When moving out of a window, WM_MOUSEMOVE within the moved-to window is received first,
// so if m_trackedWindow is not the window here, it means the cursor has left the
// application.
if (window == m_trackedWindow) {
QWindow *leaveTarget = m_windowUnderMouse ? m_windowUnderMouse : m_trackedWindow;
- if (QWindowsContext::verboseEvents)
- qDebug() << "Generating leave event for " << leaveTarget;
+ qCDebug(lcQpaEvents) << "Generating leave event for " << leaveTarget;
QWindowSystemInterface::handleLeaveEvent(leaveTarget);
m_trackedWindow = 0;
m_windowUnderMouse = 0;
@@ -231,8 +235,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
QWindowsWindow::baseWindowOf(window)->applyCursor();
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Automatic mouse capture for missing buttondown event" << window;
+ qCDebug(lcQpaEvents) << "Automatic mouse capture for missing buttondown event" << window;
}
m_previousCaptureWindow = window;
return true;
@@ -257,8 +260,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|| msg.message == WM_RBUTTONDBLCLK || msg.message == WM_XBUTTONDBLCLK)) {
platformWindow->setMouseGrabEnabled(true);
platformWindow->setFlag(QWindowsWindow::AutoMouseCapture);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Automatic mouse capture " << window;
+ qCDebug(lcQpaEvents) << "Automatic mouse capture " << window;
// Implement "Click to focus" for native child windows (unless it is a native widget window).
if (!window->isTopLevel() && !window->inherits("QWidgetWindow") && QGuiApplication::focusWindow() != window)
window->requestActivate();
@@ -268,8 +270,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
|| msg.message == WM_RBUTTONUP || msg.message == WM_XBUTTONUP)
&& !buttons) {
platformWindow->setMouseGrabEnabled(false);
- if (QWindowsContext::verboseEvents)
- qDebug() << "Releasing automatic mouse capture " << window;
+ qCDebug(lcQpaEvents) << "Releasing automatic mouse capture " << window;
}
const bool hasCapture = platformWindow->hasMouseCapture();
@@ -301,8 +302,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
&& (!hasCapture || window == m_windowUnderMouse))
|| (hasCapture && m_previousCaptureWindow != window && m_windowUnderMouse
&& m_windowUnderMouse != window)) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Synthetic leave for " << m_windowUnderMouse;
+ qCDebug(lcQpaEvents) << "Synthetic leave for " << m_windowUnderMouse;
QWindowSystemInterface::handleLeaveEvent(m_windowUnderMouse);
if (currentNotCapturing) {
// Clear tracking if capturing and current window is not the capturing window
@@ -321,8 +321,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
&& (!hasCapture || currentWindowUnderMouse == window))
|| (m_previousCaptureWindow && window != m_previousCaptureWindow && currentWindowUnderMouse
&& currentWindowUnderMouse != m_previousCaptureWindow)) {
- if (QWindowsContext::verboseEvents)
- qDebug() << "Entering " << currentWindowUnderMouse;
+ qCDebug(lcQpaEvents) << "Entering " << currentWindowUnderMouse;
QWindowsWindow::baseWindowOf(currentWindowUnderMouse)->applyCursor();
QWindowSystemInterface::handleEnterEvent(currentWindowUnderMouse,
currentWindowUnderMouse->mapFromGlobal(globalPosition),
@@ -335,7 +334,8 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
}
QWindowSystemInterface::handleMouseEvent(window, winEventPosition, globalPosition, buttons,
- QWindowsKeyMapper::queryKeyboardModifiers());
+ QWindowsKeyMapper::queryKeyboardModifiers(),
+ source);
m_previousCaptureWindow = hasCapture ? window : 0;
return true;
}
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
new file mode 100644
index 0000000000..fb1b63084f
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsnativeinterface.h"
+#include "qwindowswindow.h"
+#include "qwindowscontext.h"
+
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+# include "qwindowseglcontext.h"
+# include <QtGui/QOpenGLContext>
+#endif
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+# include "qwindowsglcontext.h"
+#endif
+
+#if !defined(QT_NO_OPENGL)
+# include <QtGui/QOpenGLFunctions>
+#endif
+
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
+{
+ if (!window || !window->handle()) {
+ qWarning("%s: '%s' requested for null window or window without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+ QWindowsWindow *bw = static_cast<QWindowsWindow *>(window->handle());
+ if (resource == "handle")
+ return bw->handle();
+ if (window->surfaceType() == QWindow::RasterSurface) {
+ if (resource == "getDC")
+ return bw->getDC();
+ if (resource == "releaseDC") {
+ bw->releaseDC();
+ return 0;
+ }
+ }
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+
+static const char customMarginPropertyC[] = "WindowsCustomMargins";
+
+QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
+ if (name == QLatin1String(customMarginPropertyC))
+ return qVariantFromValue(platformWindow->customMargins());
+ return QVariant();
+}
+
+QVariant QWindowsNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
+{
+ const QVariant result = windowProperty(window, name);
+ return result.isValid() ? result : defaultValue;
+}
+
+void QWindowsNativeInterface::setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value)
+{
+ QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window);
+ if (name == QLatin1String(customMarginPropertyC))
+ platformWindow->setCustomMargins(qvariant_cast<QMargins>(value));
+}
+
+QVariantMap QWindowsNativeInterface::windowProperties(QPlatformWindow *window) const
+{
+ QVariantMap result;
+ const QString customMarginProperty = QLatin1String(customMarginPropertyC);
+ result.insert(customMarginProperty, windowProperty(window, customMarginProperty));
+ return result;
+}
+
+#ifndef QT_NO_OPENGL
+void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+{
+ if (!context || !context->handle()) {
+ qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
+ return 0;
+ }
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+ if (QOpenGLFunctions::isES()) {
+ QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
+ if (resource == QByteArrayLiteral("eglDisplay"))
+ return windowsEglContext->eglDisplay();
+ if (resource == QByteArrayLiteral("eglContext"))
+ return windowsEglContext->eglContext();
+ if (resource == QByteArrayLiteral("eglConfig"))
+ return windowsEglContext->eglConfig();
+ }
+#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
+#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLFunctions::isES()) {
+ QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
+ if (resource == QByteArrayLiteral("renderingContext"))
+ return windowsContext->renderingContext();
+ }
+#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
+
+ qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
+ return 0;
+}
+#endif // !QT_NO_OPENGL
+
+/*!
+ \brief Creates a non-visible window handle for filtering messages.
+*/
+
+void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTemplate,
+ const QString &windowName,
+ void *eventProc) const
+{
+ QWindowsContext *ctx = QWindowsContext::instance();
+ const HWND hwnd = ctx->createDummyWindow(classNameTemplate,
+ (wchar_t*)windowName.utf16(),
+ (WNDPROC)eventProc);
+ return hwnd;
+}
+
+/*!
+ \brief Registers a unique window class with a callback function based on \a classNameIn.
+*/
+
+QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, void *eventProc) const
+{
+ return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc);
+}
+
+bool QWindowsNativeInterface::asyncExpose() const
+{
+ return QWindowsContext::instance()->asyncExpose();
+}
+
+void QWindowsNativeInterface::setAsyncExpose(bool value)
+{
+ QWindowsContext::instance()->setAsyncExpose(value);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
new file mode 100644
index 0000000000..20100d0f49
--- /dev/null
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSNATIVEINTERFACE_H
+#define QWINDOWSNATIVEINTERFACE_H
+
+#include "qtwindows_additional.h"
+#include <QtGui/qpa/qplatformnativeinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsNativeInterface
+ \brief Provides access to native handles.
+
+ Currently implemented keys
+ \list
+ \li handle (HWND)
+ \li getDC (DC)
+ \li releaseDC Releases the previously acquired DC and returns 0.
+ \endlist
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+class QWindowsNativeInterface : public QPlatformNativeInterface
+{
+ Q_OBJECT
+ Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
+public:
+#ifndef QT_NO_OPENGL
+ virtual void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context);
+#endif
+ virtual void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
+
+ Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
+ const QString &windowName,
+ void *eventProc) const;
+
+ Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const;
+
+ Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication
+
+ bool asyncExpose() const;
+ void setAsyncExpose(bool value);
+
+ QVariantMap windowProperties(QPlatformWindow *window) const;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const;
+ void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index 0cea691f39..4f641d781d 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -80,14 +80,11 @@ QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)),
performedEffect(DROPEFFECT_NONE)
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s '%s'", __FUNCTION__, qPrintable(mimeData->formats().join(QStringLiteral(", "))));
+ qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
}
QWindowsOleDataObject::~QWindowsOleDataObject()
{
- if (QWindowsContext::verboseOLE)
- qDebug("%s", __FUNCTION__);
}
void QWindowsOleDataObject::releaseQt()
@@ -143,10 +140,10 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verboseOLE) {
+ if (QWindowsContext::verbose > 1 && lcQpaMime().isDebugEnabled()) {
wchar_t buf[256] = {0};
GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qDebug("%s CF = %d : %s", __FUNCTION__, pformatetc->cfFormat, qPrintable(QString::fromWCharArray(buf)));
+ qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << QString::fromWCharArray(buf);
}
if (data) {
@@ -156,11 +153,10 @@ QWindowsOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verboseOLE) {
+ if (QWindowsContext::verbose > 1) {
wchar_t buf[256] = {0};
GetClipboardFormatName(pformatetc->cfFormat, buf, 255);
- qDebug("%s CF = %d : %s returns 0x%x", __FUNCTION__, pformatetc->cfFormat,
- qPrintable(QString::fromWCharArray(buf)), int(hr));
+ qCDebug(lcQpaMime) <<__FUNCTION__ << "CF = " << pformatetc->cfFormat << " returns 0x" << int(hr) << dec;
}
return hr;
@@ -177,16 +173,16 @@ QWindowsOleDataObject::QueryGetData(LPFORMATETC pformatetc)
{
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (data) {
const QWindowsMimeConverter &mc = QWindowsContext::instance()->mimeConverter();
hr = mc.converterFromMime(*pformatetc, data) ?
ResultFromScode(S_OK) : ResultFromScode(S_FALSE);
}
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr);
return hr;
}
@@ -200,8 +196,8 @@ QWindowsOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetc
STDMETHODIMP
QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
HRESULT hr = ResultFromScode(E_NOTIMPL);
@@ -213,8 +209,8 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL
ReleaseStgMedium(pMedium);
hr = ResultFromScode(S_OK);
}
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s returns 0x%x", __FUNCTION__, int(hr));
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__ << " returns 0x" << hex << int(hr);
return hr;
}
@@ -222,8 +218,8 @@ QWindowsOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL
STDMETHODIMP
QWindowsOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
if (!data)
return ResultFromScode(DATA_E_FORMATETC);
@@ -285,8 +281,8 @@ QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) :
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
m_lpfmtetcs.reserve(fmtetcs.count());
for (int idx = 0; idx < fmtetcs.count(); ++idx) {
LPFORMATETC destetc = new FORMATETC();
@@ -303,8 +299,8 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) :
m_dwRefs(1), m_nIndex(0), m_isNull(false)
{
- if (QWindowsContext::verboseOLE > 1)
- qDebug("%s", __FUNCTION__);
+ if (QWindowsContext::verbose > 1)
+ qCDebug(lcQpaMime) << __FUNCTION__;
m_lpfmtetcs.reserve(lpfmtetcs.count());
for (int idx = 0; idx < lpfmtetcs.count(); ++idx) {
LPFORMATETC srcetc = lpfmtetcs.at(idx);
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 1fc1be53c7..a6e2aabaf0 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -201,8 +201,6 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat =
QPixmap QWindowsScreen::grabWindow(WId window, int x, int y, int width, int height) const
{
- if (QWindowsContext::verboseIntegration)
- qDebug() << __FUNCTION__ << window << x << y << width << height;
RECT r;
HWND hwnd = window ? (HWND)window : GetDesktopWindow();
GetClientRect(hwnd, &r);
@@ -243,8 +241,7 @@ QWindow *QWindowsScreen::findTopLevelAt(const QPoint &point, unsigned flags)
if (QPlatformWindow *bw = QWindowsContext::instance()->
findPlatformWindowAt(GetDesktopWindow(), point, flags))
result = QWindowsWindow::topLevelOf(bw->window());
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << point << flags << result;
+ qCDebug(lcQpaWindows) <<__FUNCTION__ << point << flags << result;
return result;
}
@@ -254,8 +251,7 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
if (QPlatformWindow *bw = QWindowsContext::instance()->
findPlatformWindowAt(GetDesktopWindow(), screenPoint, flags))
result = bw->window();
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << screenPoint << " returns " << result;
+ qCDebug(lcQpaWindows) <<__FUNCTION__ << screenPoint << " returns " << result;
return result;
}
@@ -366,9 +362,8 @@ bool QWindowsScreenManager::handleDisplayChange(WPARAM wParam, LPARAM lParam)
m_lastDepth = newDepth;
m_lastHorizontalResolution = newHorizontalResolution;
m_lastVerticalResolution = newVerticalResolution;
- if (QWindowsContext::verboseWindows)
- qDebug("%s: Depth=%d, resolution=%hux%hu",
- __FUNCTION__, newDepth, newHorizontalResolution, newVerticalResolution);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << "Depth=" << newDepth
+ << ", resolution " << newHorizontalResolution << 'x' << newVerticalResolution;
handleScreenChanges();
}
return false;
@@ -410,8 +405,7 @@ bool QWindowsScreenManager::handleScreenChanges()
QWindowsScreen *newScreen = new QWindowsScreen(newData);
m_screens.push_back(newScreen);
QWindowsIntegration::instance()->emitScreenAdded(newScreen);
- if (QWindowsContext::verboseWindows)
- qDebug() << "New Monitor: " << newData;
+ qCDebug(lcQpaWindows) << "New Monitor: " << newData;
} // exists
} // for new screens.
// Remove deleted ones but keep main monitors if we get only the
@@ -419,8 +413,7 @@ bool QWindowsScreenManager::handleScreenChanges()
if (!lockScreen) {
for (int i = m_screens.size() - 1; i >= 0; --i) {
if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) {
- if (QWindowsContext::verboseWindows)
- qDebug() << "Removing Monitor: " << m_screens.at(i) ->data();
+ qCDebug(lcQpaWindows) << "Removing Monitor: " << m_screens.at(i) ->data();
delete m_screens.takeAt(i);
} // not found
} // for existing screens
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.cpp b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
index 1a5c1a2e0c..8b863ec43d 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.cpp
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.cpp
@@ -182,8 +182,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
L"TabletDummyWindow",
qWindowsTabletSupportWndProc);
if (!window) {
- if (QWindowsContext::verboseTablet)
- qWarning() << __FUNCTION__ << "Unable to create window for tablet.";
+ qCWarning(lcQpaTablet) << __FUNCTION__ << "Unable to create window for tablet.";
return 0;
}
LOGCONTEXT lcMine;
@@ -199,8 +198,7 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
lcMine.lcOutExtY = -lcMine.lcInExtY;
const HCTX context = QWindowsTabletSupport::m_winTab32DLL.wTOpen(window, &lcMine, true);
if (!context) {
- if (QWindowsContext::verboseTablet)
- qWarning() << __FUNCTION__ << "Unable to open tablet.";
+ qCDebug(lcQpaTablet) << __FUNCTION__ << "Unable to open tablet.";
DestroyWindow(window);
return 0;
@@ -217,9 +215,9 @@ QWindowsTabletSupport *QWindowsTabletSupport::create()
} // cannot restore old size
} // cannot set
} // mismatch
- if (QWindowsContext::verboseTablet)
- qDebug("Opened tablet context %p on window %p, changed packet queue size %d -> %d",
- context, window, currentQueueSize, TabletPacketQSize);
+ qCDebug(lcQpaTablet) << "Opened tablet context " << context << " on window "
+ << window << "changed packet queue size " << currentQueueSize
+ << "->" << TabletPacketQSize;
return new QWindowsTabletSupport(window, context);
}
@@ -261,8 +259,7 @@ void QWindowsTabletSupport::notifyActivate()
// Cooperate with other tablet applications, but when we get focus, I want to use the tablet.
const bool result = QWindowsTabletSupport::m_winTab32DLL.wTEnable(m_context, true)
&& QWindowsTabletSupport::m_winTab32DLL.wTOverlap(m_context, true);
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << result;
+ qCDebug(lcQpaTablet) << __FUNCTION__ << result;
}
static inline int indexOfDevice(const QVector<QWindowsTabletDeviceData> &devices, qint64 uniqueId)
@@ -369,10 +366,8 @@ bool QWindowsTabletSupport::translateTabletProximityEvent(WPARAM /* wParam */, L
m_devices.push_back(tabletInit(uniqueId, cursorType));
}
m_devices[m_currentDevice].currentPointerType = pointerType(currentCursor);
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
- << " proximity for device #"
- << m_currentDevice << m_devices.at(m_currentDevice);
+ qCDebug(lcQpaTablet) << __FUNCTION__ << (enteredProximity ? "enter" : "leave")
+ << " proximity for device #" << m_currentDevice << m_devices.at(m_currentDevice);
if (enteredProximity) {
QWindowSystemInterface::handleTabletEnterProximityEvent(m_devices.at(m_currentDevice).currentDevice,
m_devices.at(m_currentDevice).currentPointerType,
@@ -410,9 +405,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
enum { absoluteRange = 20 };
const QRect virtualDesktopArea = QGuiApplication::primaryScreen()->virtualGeometry();
- if (QWindowsContext::verboseTablet)
- qDebug() << __FUNCTION__ << "processing " << packetCount
- << "target:" << QGuiApplicationPrivate::tabletPressTarget;
+ qCDebug(lcQpaTablet) << __FUNCTION__ << "processing " << packetCount
+ << "target:" << QGuiApplicationPrivate::tabletPressTarget;
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
@@ -474,8 +468,8 @@ bool QWindowsTabletSupport::translateTabletPacketEvent()
rotation = packet.pkOrientation.orTwist;
}
- if (QWindowsContext::verboseTablet > 1) {
- qDebug()
+ if (QWindowsContext::verbose > 1) {
+ qCDebug(lcQpaTablet)
<< "Packet #" << i << '/' << packetCount << "button:" << packet.pkButtons
<< globalPosF << z << "to:" << target << localPos << "(packet" << packet.pkX
<< packet.pkY << ") dev:" << currentDevice << "pointer:"
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 00a5da8f44..6349c1e355 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -354,7 +354,7 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
case UseFullScreenForPopupMenu:
return QVariant(true);
case DialogButtonBoxLayout:
- return QVariant(int(0)); // QDialogButtonBox::WinLayout
+ return QVariant(QPlatformDialogHelper::WinLayout);
case IconThemeSearchPaths:
return QVariant(iconThemeSearchPaths());
case StyleNames:
@@ -406,10 +406,6 @@ void QWindowsTheme::refreshPalettes()
m_palettes[ToolTipPalette] = new QPalette(toolTipPalette(*m_palettes[SystemPalette]));
m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette]));
m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette]);
- if (QWindowsContext::verboseTheming)
- qDebug() << __FUNCTION__ << '\n'
- << " system=" << paletteToString(*m_palettes[SystemPalette])
- << " tooltip=" << paletteToString(*m_palettes[ToolTipPalette]);
}
void QWindowsTheme::clearFonts()
@@ -449,11 +445,6 @@ void QWindowsTheme::refreshFonts()
m_fonts[DockWidgetTitleFont] = new QFont(titleFont);
m_fonts[ItemViewFont] = new QFont(iconTitleFont);
m_fonts[FixedFont] = new QFont(fixedFont);
-
- if (QWindowsContext::verboseTheming)
- qDebug() << __FUNCTION__ << '\n'
- << " menuFont=" << menuFont
- << " messageBox=" << MessageBoxFont;
#endif // !Q_OS_WINCE
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 51902385e1..a0a9e75e2d 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -48,8 +48,9 @@
# include "qwindowscursor.h"
#endif
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include "qwindowseglcontext.h"
+# include <QtGui/QOpenGLFunctions>
#endif
#include <QtGui/QGuiApplication>
@@ -358,7 +359,7 @@ static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bo
struct WindowCreationData
{
- typedef QWindowsWindow::WindowData WindowData;
+ typedef QWindowsWindowData WindowData;
enum Flags { ForceChild = 0x1, ForceTopLevel = 0x2 };
WindowCreationData() : parentHandle(0), type(Qt::Widget), style(0), exStyle(0),
@@ -534,7 +535,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
}
}
-QWindowsWindow::WindowData
+QWindowsWindowData
WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
typedef QSharedPointer<QWindowCreationContext> QWindowCreationContextPtr;
@@ -546,8 +547,7 @@ QWindowsWindow::WindowData
result.hwnd = GetDesktopWindow();
result.geometry = frameGeometry(result.hwnd, true);
result.embedded = false;
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << "Created desktop window " << w << result.hwnd;
+ qCDebug(lcQpaWindows) << "Created desktop window " << w << result.hwnd;
return result;
}
if ((flags & Qt::WindowType_Mask) == Qt::ForeignWindow) {
@@ -558,8 +558,7 @@ QWindowsWindow::WindowData
result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd));
result.frame = QWindowsGeometryHint::frame(style, exStyle);
result.embedded = false;
- if (QWindowsContext::verboseWindows)
- qDebug() << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
+ qCDebug(lcQpaWindows) << "Foreign window: " << w << result.hwnd << result.geometry << result.frame;
return result;
}
@@ -580,24 +579,21 @@ QWindowsWindow::WindowData
const QWindowCreationContextPtr context(new QWindowCreationContext(w, rect, data.customMargins, style, exStyle));
QWindowsContext::instance()->setWindowCreationContext(context);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << "CreateWindowEx: " << w << *this
- << " class=" <<windowClassName << " title=" << title
- << "\nrequested: " << rect << ": "
- << context->frameWidth << 'x' << context->frameHeight
- << '+' << context->frameX << '+' << context->frameY
- << " custom margins: " << context->customMargins;
+ qCDebug(lcQpaWindows).nospace()
+ << "CreateWindowEx: " << w << *this << " class=" <<windowClassName << " title=" << title
+ << "\nrequested: " << rect << ": "
+ << context->frameWidth << 'x' << context->frameHeight
+ << '+' << context->frameX << '+' << context->frameY
+ << " custom margins: " << context->customMargins;
result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
style,
context->frameX, context->frameY,
context->frameWidth, context->frameHeight,
parentHandle, NULL, appinst, NULL);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
- << context->obtainedGeometry << context->margins;
+ qCDebug(lcQpaWindows).nospace()
+ << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
+ << context->obtainedGeometry << context->margins;
if (!result.hwnd) {
qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
@@ -627,8 +623,7 @@ void WindowCreationData::applyWindowFlags(HWND hwnd) const
const LONG_PTR newExStyle = exStyle;
if (newExStyle != oldExStyle)
SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << hwnd << *this
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << hwnd << *this
<< "\n Style from " << debugWinStyle(oldStyle) << "\n to "
<< debugWinStyle(newStyle) << "\n ExStyle from "
<< debugWinExStyle(oldExStyle) << " to "
@@ -705,10 +700,8 @@ QMargins QWindowsGeometryHint::frame(DWORD style, DWORD exStyle)
qErrnoWarning("%s: AdjustWindowRectEx failed", __FUNCTION__);
const QMargins result(qAbs(rect.left), qAbs(rect.top),
qAbs(rect.right), qAbs(rect.bottom));
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << " style= 0x"
- << QString::number(style, 16)
- << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << " style= 0x"
+ << QString::number(style, 16) << " exStyle=0x" << QString::number(exStyle, 16) << ' ' << rect << ' ' << result;
return result;
}
@@ -727,10 +720,9 @@ bool QWindowsGeometryHint::handleCalculateSize(const QMargins &customMargins, co
ncp->rgrc[0].right -= customMargins.right();
ncp->rgrc[0].bottom -= customMargins.bottom();
result = 0;
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << oldClientArea << '+' << customMargins << "-->"
- << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2]
- << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy;
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << oldClientArea << '+' << customMargins << "-->"
+ << ncp->rgrc[0] << ' ' << ncp->rgrc[1] << ' ' << ncp->rgrc[2]
+ << ' ' << ncp->lppos->cx << ',' << ncp->lppos->cy;
return true;
#else
Q_UNUSED(customMargins)
@@ -749,11 +741,10 @@ void QWindowsGeometryHint::applyToMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) const
void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXINFO *mmi) const
{
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << '>' << __FUNCTION__ << '<' << " min="
- << minimumSize.width() << ',' << minimumSize.height()
- << " max=" << maximumSize.width() << ',' << maximumSize.height()
- << " in " << *mmi;
+ qCDebug(lcQpaWindows).nospace() << '>' << __FUNCTION__ << '<' << " min="
+ << minimumSize.width() << ',' << minimumSize.height()
+ << " max=" << maximumSize.width() << ',' << maximumSize.height()
+ << " in " << *mmi;
const QMargins margins = QWindowsGeometryHint::frame(style, exStyle);
const int frameWidth = margins.left() + margins.right() + customMargins.left() + customMargins.right();
@@ -770,10 +761,9 @@ void QWindowsGeometryHint::applyToMinMaxInfo(DWORD style, DWORD exStyle, MINMAXI
// windows with title bar have an implicit size limit of 112 pixels
if (maximumHeight < QWINDOWSIZE_MAX)
mmi->ptMaxTrackSize.y = qMax(maximumHeight + frameHeight, 112);
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << '<' << __FUNCTION__
- << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
- << " out " << *mmi;
+ qCDebug(lcQpaWindows).nospace() << '<' << __FUNCTION__
+ << " frame=" << margins << ' ' << frameWidth << ',' << frameHeight
+ << " out " << *mmi;
}
#endif // !Q_OS_WINCE
@@ -831,15 +821,13 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
}
}
- if (QWindowsContext::verboseWindows)
- qDebug().nospace()
- << __FUNCTION__ << ' ' << w << geometry
- << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
- << " frame: " << frameWidth << 'x' << frameHeight << '+'
- << frameX << '+' << frameY
- << " min" << geometryHint.minimumSize
- << " max" << geometryHint.maximumSize
- << " custom margins " << customMargins;
+ qCDebug(lcQpaWindows).nospace()
+ << __FUNCTION__ << ' ' << w << geometry
+ << " pos incl. frame" << QWindowsGeometryHint::positionIncludesFrame(w)
+ << " frame: " << frameWidth << 'x' << frameHeight << '+'
+ << frameX << '+' << frameY
+ << " min" << geometryHint.minimumSize << " max" << geometryHint.maximumSize
+ << " custom margins " << customMargins;
}
/*!
@@ -864,7 +852,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
\ingroup qt-lighthouse-win
*/
-QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
+QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) :
QPlatformWindow(aWindow),
m_data(data),
m_flags(WithinCreate),
@@ -874,7 +862,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
m_dropTarget(0),
m_savedStyle(0),
m_format(aWindow->format()),
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
m_eglSurface(0),
#endif
#ifdef Q_OS_WINCE
@@ -891,24 +879,13 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) :
return; // No further handling for Qt::Desktop
if (aWindow->surfaceType() == QWindow::OpenGLSurface) {
setFlag(OpenGLSurface);
-#ifdef QT_OPENGL_ES_2
- setFlag(OpenGL_ES2);
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
+ if (QOpenGLFunctions::isES())
+ setFlag(OpenGL_ES2);
#endif
}
- if (aWindow->isTopLevel()) {
- switch (type) {
- case Qt::Window:
- case Qt::Dialog:
- case Qt::Sheet:
- case Qt::Drawer:
- case Qt::Popup:
- case Qt::Tool:
- registerDropSite();
- break;
- default:
- break;
- }
- }
+ updateDropSite();
+
#ifndef Q_OS_WINCE
if (QWindowsContext::instance()->systemInfo() & QWindowsContext::SI_SupportsTouch) {
if (QWindowsContext::user32dll.registerTouchWindow(m_data.hwnd, 0)) {
@@ -949,8 +926,7 @@ void QWindowsWindow::fireExpose(const QRegion &region, bool force)
void QWindowsWindow::destroyWindow()
{
- if (QWindowsContext::verboseIntegration || QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.hwnd;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd;
if (m_data.hwnd) { // Stop event dispatching before Window is destroyed.
setFlag(WithinDestroy);
QWindowsContext *context = QWindowsContext::instance();
@@ -958,12 +934,10 @@ void QWindowsWindow::destroyWindow()
context->clearWindowUnderMouse();
if (hasMouseCapture())
setMouseGrabEnabled(false);
- unregisterDropSite();
-#ifdef QT_OPENGL_ES_2
+ setDropSiteEnabled(false);
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
if (m_eglSurface) {
- if (QWindowsContext::verboseGL)
- qDebug("%s: Freeing EGL surface %p, this = %p",
- __FUNCTION__, m_eglSurface, this);
+ qCDebug(lcQpaGl) << __FUNCTION__ << "Freeing EGL surface " << m_eglSurface << window();
eglDestroySurface(m_staticEglContext->display(), m_eglSurface);
m_eglSurface = 0;
}
@@ -983,31 +957,44 @@ void QWindowsWindow::destroyWindow()
}
}
-void QWindowsWindow::registerDropSite()
+void QWindowsWindow::updateDropSite()
{
-#ifndef QT_NO_CLIPBOARD
-# ifndef QT_NO_DRAGANDDROP
- if (m_data.hwnd && !m_dropTarget) {
- m_dropTarget = new QWindowsOleDropTarget(window());
- RegisterDragDrop(m_data.hwnd, m_dropTarget);
- CoLockObjectExternal(m_dropTarget, true, true);
+ bool enabled = false;
+ if (window()->isTopLevel()) {
+ switch (window()->type()) {
+ case Qt::Window:
+ case Qt::Dialog:
+ case Qt::Sheet:
+ case Qt::Drawer:
+ case Qt::Popup:
+ case Qt::Tool:
+ enabled = true;
+ break;
+ default:
+ break;
+ }
}
-# endif // !QT_NO_DRAGANDDROP
-#endif // !QT_NO_CLIPBOARD
+ setDropSiteEnabled(enabled);
}
-void QWindowsWindow::unregisterDropSite()
+void QWindowsWindow::setDropSiteEnabled(bool dropEnabled)
{
-#ifndef QT_NO_CLIPBOARD
-# ifndef QT_NO_DRAGANDDROP
- if (m_data.hwnd && m_dropTarget) {
+ if (isDropSiteEnabled() == dropEnabled)
+ return;
+ qCDebug(lcQpaMime) << __FUNCTION__ << window() << dropEnabled;
+#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_DRAGANDDROP)
+ if (dropEnabled) {
+ Q_ASSERT(m_data.hwnd);
+ m_dropTarget = new QWindowsOleDropTarget(window());
+ RegisterDragDrop(m_data.hwnd, m_dropTarget);
+ CoLockObjectExternal(m_dropTarget, true, true);
+ } else {
m_dropTarget->Release();
CoLockObjectExternal(m_dropTarget, false, true);
RevokeDragDrop(m_data.hwnd);
m_dropTarget = 0;
}
-# endif // !QT_NO_DRAGANDDROP
-#endif // !QT_NO_CLIPBOARD
+#endif // !QT_NO_CLIPBOARD && !QT_NO_DRAGANDDROP
}
// Returns topmost QWindowsWindow ancestor even if there are embedded windows in the chain.
@@ -1033,14 +1020,14 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
return w;
}
-QWindowsWindow::WindowData
- QWindowsWindow::WindowData::create(const QWindow *w,
- const WindowData &parameters,
+QWindowsWindowData
+ QWindowsWindowData::create(const QWindow *w,
+ const QWindowsWindowData &parameters,
const QString &title)
{
WindowCreationData creationData;
creationData.fromWindow(w, parameters.flags);
- WindowData result = creationData.create(w, parameters, title);
+ QWindowsWindowData result = creationData.create(w, parameters, title);
// Force WM_NCCALCSIZE (with wParam=1) via SWP_FRAMECHANGED for custom margin.
creationData.initialize(result.hwnd, !parameters.customMargins.isNull(), 1);
return result;
@@ -1048,8 +1035,7 @@ QWindowsWindow::WindowData
void QWindowsWindow::setVisible(bool visible)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.hwnd << visible;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << m_data.hwnd << visible;
if (m_data.hwnd) {
if (visible) {
show_sys();
@@ -1193,20 +1179,19 @@ void QWindowsWindow::hide_sys() const
if (flags & Qt::Popup)
ShowWindow(m_data.hwnd, SW_HIDE);
else
- SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
+ SetWindowPos(m_data.hwnd,0, 0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
}
}
void QWindowsWindow::setParent(const QPlatformWindow *newParent)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << newParent;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << newParent;
if (m_data.hwnd)
setParent_sys(newParent);
}
-void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
+void QWindowsWindow::setParent_sys(const QPlatformWindow *parent)
{
// Use GetAncestor instead of GetParent, as GetParent can return owner window for toplevels
HWND oldParentHWND = GetAncestor(m_data.hwnd, GA_PARENT);
@@ -1235,8 +1220,11 @@ void QWindowsWindow::setParent_sys(const QPlatformWindow *parent) const
// WS_CHILD/WS_POPUP must be manually set/cleared in addition
// to dialog frames, etc (see SetParent() ) if the top level state changes.
// Force toplevel state as QWindow::isTopLevel cannot be relied upon here.
- if (wasTopLevel != isTopLevel)
+ if (wasTopLevel != isTopLevel) {
+ setDropSiteEnabled(false);
setWindowFlags_sys(window()->flags(), unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
+ updateDropSite();
+ }
}
}
@@ -1252,6 +1240,28 @@ void QWindowsWindow::handleCompositionSettingsChanged()
applyBlurBehindWindow(handle());
}
+static QRect normalFrameGeometry(HWND hwnd)
+{
+#ifndef Q_OS_WINCE
+ WINDOWPLACEMENT wp;
+ wp.length = sizeof(WINDOWPLACEMENT);
+ if (GetWindowPlacement(hwnd, &wp))
+ return qrectFromRECT(wp.rcNormalPosition);
+#else
+ Q_UNUSED(hwnd)
+#endif
+ return QRect();
+}
+
+QRect QWindowsWindow::normalGeometry() const
+{
+ // Check for fake 'fullscreen' mode.
+ const bool fakeFullScreen = m_savedFrameGeometry.isValid() && window()->windowState() == Qt::WindowFullScreen;
+ const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
+ const QMargins margins = fakeFullScreen ? QWindowsGeometryHint::frame(m_savedStyle, 0) : frameMargins();
+ return frame.isValid() ? frame.marginsRemoved(margins) : frame;
+}
+
void QWindowsWindow::setGeometry(const QRect &rectIn)
{
QRect rect = rectIn;
@@ -1350,8 +1360,7 @@ void QWindowsWindow::handleGeometryChange()
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents();
- if (QWindowsContext::verboseEvents || QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << m_data.geometry;
+ qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
}
void QWindowsWindow::setGeometry_sys(const QRect &rect) const
@@ -1359,17 +1368,15 @@ void QWindowsWindow::setGeometry_sys(const QRect &rect) const
const QMargins margins = frameMargins();
const QRect frameGeometry = rect + margins;
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window()
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
<< " \n from " << geometry_sys() << " frame: "
<< margins << " to " <<rect
<< " new frame: " << frameGeometry;
const bool rc = MoveWindow(m_data.hwnd, frameGeometry.x(), frameGeometry.y(),
frameGeometry.width(), frameGeometry.height(), true);
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << this << window()
- << " \n resulting " << rc << geometry_sys();
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window()
+ << " \n resulting " << rc << geometry_sys();
}
QRect QWindowsWindow::frameGeometry_sys() const
@@ -1442,8 +1449,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
void QWindowsWindow::setWindowTitle(const QString &title)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() <<title;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() <<title;
if (m_data.hwnd) {
const QString fullTitle = formatWindowTitle(title, QStringLiteral(" - "));
SetWindowText(m_data.hwnd, (const wchar_t*)fullTitle.utf16());
@@ -1452,15 +1458,16 @@ void QWindowsWindow::setWindowTitle(const QString &title)
void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window() << "\n from: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << "\n to: " << QWindowsWindow::debugWindowFlags(flags);
const QRect oldGeometry = geometry();
if (m_data.flags != flags) {
m_data.flags = flags;
- if (m_data.hwnd)
+ if (m_data.hwnd) {
m_data = setWindowFlags_sys(flags);
+ updateDropSite();
+ }
}
// When switching to a frameless window, geometry
// may change without a WM_MOVE. Report change manually.
@@ -1470,13 +1477,12 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags)
if (oldGeometry != newGeometry)
handleGeometryChange();
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << "\n returns: "
- << QWindowsWindow::debugWindowFlags(m_data.flags)
- << " geometry " << oldGeometry << "->" << newGeometry;
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << "\n returns: "
+ << QWindowsWindow::debugWindowFlags(m_data.flags)
+ << " geometry " << oldGeometry << "->" << newGeometry;
}
-QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
+QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
unsigned flags) const
{
WindowCreationData creationData;
@@ -1484,7 +1490,7 @@ QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt
creationData.applyWindowFlags(m_data.hwnd);
creationData.initialize(m_data.hwnd, true, m_opacity);
- WindowData result = m_data;
+ QWindowsWindowData result = m_data;
result.flags = creationData.flags;
result.embedded = creationData.embedded;
setFlag(FrameDirty);
@@ -1493,8 +1499,7 @@ QWindowsWindow::WindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt
void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window()
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window()
<< "\n from " << debugWindowStates(m_windowState)
<< " to " << debugWindowStates(state);
setFlag(FrameDirty);
@@ -1577,10 +1582,8 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
const Qt::WindowState oldState = m_windowState;
if (oldState == newState)
return;
- if (QWindowsContext::verboseWindows)
- qDebug() << '>' << __FUNCTION__ << this << window()
- << " from " << debugWindowStates(oldState)
- << " to " << debugWindowStates(newState);
+ qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window()
+ << " from " << debugWindowStates(oldState) << " to " << debugWindowStates(newState);
const bool visible = isVisible();
@@ -1620,10 +1623,9 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
m_savedStyle = style();
#ifndef Q_OS_WINCE
if (oldState == Qt::WindowMinimized) {
- WINDOWPLACEMENT wp;
- wp.length = sizeof(WINDOWPLACEMENT);
- if (GetWindowPlacement(m_data.hwnd, &wp))
- m_savedFrameGeometry = qrectFromRECT(wp.rcNormalPosition);
+ const QRect nf = normalFrameGeometry(m_data.hwnd);
+ if (nf.isValid())
+ m_savedFrameGeometry = nf;
} else {
#endif
m_savedFrameGeometry = frameGeometry_sys();
@@ -1677,15 +1679,12 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
ShowWindow(m_data.hwnd, (newState == Qt::WindowMinimized) ? SW_MINIMIZE :
(newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
}
- if (QWindowsContext::verboseWindows)
- qDebug() << '<' << __FUNCTION__ << this << window()
- << debugWindowStates(newState);
+ qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << this << window() << debugWindowStates(newState);
}
void QWindowsWindow::setStyle(unsigned s) const
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << debugWinStyle(s);
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << debugWinStyle(s);
setFlag(WithinSetStyle);
setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
@@ -1694,8 +1693,7 @@ void QWindowsWindow::setStyle(unsigned s) const
void QWindowsWindow::setExStyle(unsigned s) const
{
- if (QWindowsContext::verboseWindows)
- qDebug().nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
+ qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
<< " 0x" << QByteArray::number(s, 16);
setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
@@ -1703,15 +1701,13 @@ void QWindowsWindow::setExStyle(unsigned s) const
void QWindowsWindow::raise()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
SetWindowPos(m_data.hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
void QWindowsWindow::lower()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
if (m_data.hwnd)
SetWindowPos(m_data.hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
@@ -1734,8 +1730,7 @@ void QWindowsWindow::windowEvent(QEvent *event)
void QWindowsWindow::propagateSizeHints()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
QMargins QWindowsWindow::frameMargins() const
@@ -1753,8 +1748,7 @@ QMargins QWindowsWindow::frameMargins() const
void QWindowsWindow::setOpacity(qreal level)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << level;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << level;
if (m_opacity != level) {
m_opacity = level;
if (m_data.hwnd)
@@ -1816,8 +1810,7 @@ void QWindowsWindow::setMask(const QRegion &region)
void QWindowsWindow::requestActivateWindow()
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window();
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
// 'Active' state handling is based in focus since it needs to work for
// child windows as well.
if (m_data.hwnd) {
@@ -1832,8 +1825,7 @@ bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
qWarning("%s: No handle", __FUNCTION__);
return false;
}
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << this << window() << grab;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << grab;
QWindowsContext *context = QWindowsContext::instance();
if (grab) {
@@ -1847,8 +1839,7 @@ bool QWindowsWindow::setKeyboardGrabEnabled(bool grab)
bool QWindowsWindow::setMouseGrabEnabled(bool grab)
{
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << grab;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << grab;
if (!m_data.hwnd) {
qWarning("%s: No handle", __FUNCTION__);
return false;
@@ -1930,8 +1921,7 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
}
}
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << window() << *mmi;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << *mmi;
}
bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *result) const
@@ -2031,9 +2021,8 @@ void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
#ifndef QT_NO_CURSOR
if (c.handle() != m_cursor.handle()) {
const bool apply = applyNewCursor(window());
- if (QWindowsContext::verboseWindows)
- qDebug() << window() << __FUNCTION__ << "Shape=" << c.cursor().shape()
- << " doApply=" << apply;
+ qCDebug(lcQpaWindows) <<window() << __FUNCTION__
+ << "Shape=" << c.cursor().shape() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
@@ -2120,7 +2109,7 @@ void QWindowsWindow::setEnabled(bool enabled)
setStyle(newStyle);
}
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindowsEGLStaticContextPtr &staticContext, EGLConfig config)
{
if (!m_eglSurface) {
@@ -2131,9 +2120,7 @@ EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindows
Q_FUNC_INFO, window()->metaObject()->className(),
qPrintable(window()->objectName()), eglGetError());
- if (QWindowsContext::verboseGL)
- qDebug("%s: Created EGL surface %p, this = %p",
- __FUNCTION__, m_eglSurface, this);
+ qCDebug(lcQpaGl) << __FUNCTION__<<"Created EGL surface "<< m_eglSurface <<window();
}
return m_eglSurface;
}
@@ -2244,9 +2231,8 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
newFrame.moveTo(topLeft);
setFlag(FrameDirty);
- if (QWindowsContext::verboseWindows)
- qDebug() << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
- << currentFrameGeometry << "->" << newFrame;
+ qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
+ << currentFrameGeometry << "->" << newFrame;
SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 61dc3e2dc2..ba0f22bb0a 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -50,7 +50,7 @@
#include <qpa/qplatformwindow.h>
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
# include <QtCore/QSharedPointer>
# include <EGL/egl.h>
#endif
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
class QWindowsOleDropTarget;
class QDebug;
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
class QWindowsEGLStaticContext;
#endif
@@ -111,10 +111,26 @@ struct QWindowCreationContext
int frameHeight;
};
+struct QWindowsWindowData
+{
+ QWindowsWindowData() : hwnd(0), embedded(false) {}
+
+ Qt::WindowFlags flags;
+ QRect geometry;
+ QMargins frame; // Do not use directly for windows, see FrameDirty.
+ QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
+ HWND hwnd;
+ bool embedded;
+
+ static QWindowsWindowData create(const QWindow *w,
+ const QWindowsWindowData &parameters,
+ const QString &title);
+};
+
class QWindowsWindow : public QPlatformWindow
{
public:
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
typedef QSharedPointer<QWindowsEGLStaticContext> QWindowsEGLStaticContextPtr;
#endif
@@ -140,28 +156,13 @@ public:
WithinMaximize = 0x40000
};
- struct WindowData
- {
- WindowData() : hwnd(0) {}
-
- Qt::WindowFlags flags;
- QRect geometry;
- QMargins frame; // Do not use directly for windows, see FrameDirty.
- QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
- HWND hwnd;
- bool embedded;
-
- static WindowData create(const QWindow *w,
- const WindowData &parameters,
- const QString &title);
- };
-
- QWindowsWindow(QWindow *window, const WindowData &data);
+ QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
~QWindowsWindow();
virtual QSurfaceFormat format() const { return m_format; }
virtual void setGeometry(const QRect &rect);
virtual QRect geometry() const { return m_data.geometry; }
+ QRect normalGeometry() const Q_DECL_OVERRIDE;
virtual void setVisible(bool visible);
bool isVisible() const;
@@ -205,7 +206,7 @@ public:
QMargins customMargins() const { return m_data.customMargins; }
void setCustomMargins(const QMargins &m);
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface eglSurfaceHandle() const { return m_eglSurface;}
EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config);
#endif
@@ -274,20 +275,21 @@ private:
inline void setGeometry_sys(const QRect &rect) const;
inline QRect frameGeometry_sys() const;
inline QRect geometry_sys() const;
- inline WindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const;
+ inline QWindowsWindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const;
inline bool isFullScreen_sys() const;
inline void setWindowState_sys(Qt::WindowState newState);
- inline void setParent_sys(const QPlatformWindow *parent) const;
+ inline void setParent_sys(const QPlatformWindow *parent);
inline void updateTransientParent() const;
void destroyWindow();
- void registerDropSite();
- void unregisterDropSite();
+ inline bool isDropSiteEnabled() const { return m_dropTarget != 0; }
+ void setDropSiteEnabled(bool enabled);
+ void updateDropSite();
void handleGeometryChange();
void handleWindowStateChange(Qt::WindowState state);
inline void destroyIcon();
void fireExpose(const QRegion &region, bool force=false);
- mutable WindowData m_data;
+ mutable QWindowsWindowData m_data;
mutable unsigned m_flags;
HDC m_hdc;
Qt::WindowState m_windowState;
@@ -299,7 +301,7 @@ private:
unsigned m_savedStyle;
QRect m_savedFrameGeometry;
const QSurfaceFormat m_format;
-#ifdef QT_OPENGL_ES_2
+#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
EGLSurface m_eglSurface;
QSharedPointer<QWindowsEGLStaticContext> m_staticEglContext;
#endif
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
new file mode 100644
index 0000000000..13799ba1ba
--- /dev/null
+++ b/src/plugins/platforms/windows/windows.pri
@@ -0,0 +1,184 @@
+# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
+LIBS *= -lole32
+!wince*:LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32
+
+contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):!contains(QT_CONFIG, dynamicgl): LIBS *= -lopengl32
+
+mingw: LIBS *= -luuid
+# For the dialog helpers:
+!wince*:LIBS *= -lshlwapi -lshell32
+!wince*:LIBS *= -ladvapi32
+wince*:DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\""
+
+DEFINES *= QT_NO_CAST_FROM_ASCII
+
+contains(QT_CONFIG, directwrite) {
+ LIBS *= -ldwrite
+ SOURCES += $$PWD/qwindowsfontenginedirectwrite.cpp
+ HEADERS += $$PWD/qwindowsfontenginedirectwrite.h
+} else {
+ DEFINES *= QT_NO_DIRECTWRITE
+}
+
+SOURCES += \
+ $$PWD/qwindowswindow.cpp \
+ $$PWD/qwindowsintegration.cpp \
+ $$PWD/qwindowscontext.cpp \
+ $$PWD/qwindowsscreen.cpp \
+ $$PWD/qwindowskeymapper.cpp \
+ $$PWD/qwindowsfontengine.cpp \
+ $$PWD/qwindowsfontdatabase.cpp \
+ $$PWD/qwindowsmousehandler.cpp \
+ $$PWD/qwindowsguieventdispatcher.cpp \
+ $$PWD/qwindowsole.cpp \
+ $$PWD/qwindowsmime.cpp \
+ $$PWD/qwindowsinternalmimedata.cpp \
+ $$PWD/qwindowscursor.cpp \
+ $$PWD/qwindowsinputcontext.cpp \
+ $$PWD/qwindowstheme.cpp \
+ $$PWD/qwindowsdialoghelpers.cpp \
+ $$PWD/qwindowsservices.cpp \
+ $$PWD/qwindowsnativeimage.cpp \
+ $$PWD/qwindowsnativeinterface.cpp
+
+HEADERS += \
+ $$PWD/qwindowswindow.h \
+ $$PWD/qwindowsintegration.h \
+ $$PWD/qwindowscontext.h \
+ $$PWD/qwindowsscreen.h \
+ $$PWD/qwindowskeymapper.h \
+ $$PWD/qwindowsfontengine.h \
+ $$PWD/qwindowsfontdatabase.h \
+ $$PWD/qwindowsmousehandler.h \
+ $$PWD/qwindowsguieventdispatcher.h \
+ $$PWD/qtwindowsglobal.h \
+ $$PWD/qtwindows_additional.h \
+ $$PWD/qwindowsole.h \
+ $$PWD/qwindowsmime.h \
+ $$PWD/qwindowsinternalmimedata.h \
+ $$PWD/qwindowscursor.h \
+ $$PWD/array.h \
+ $$PWD/qwindowsinputcontext.h \
+ $$PWD/qwindowstheme.h \
+ $$PWD/qwindowsdialoghelpers.h \
+ $$PWD/qwindowsservices.h \
+ $$PWD/qplatformfunctions_wince.h \
+ $$PWD/qwindowsnativeimage.h \
+ $$PWD/qwindowsnativeinterface.h
+
+INCLUDEPATH += $$PWD
+
+contains(QT_CONFIG, opengles2) {
+ SOURCES += $$PWD/qwindowseglcontext.cpp
+ HEADERS += $$PWD/qwindowseglcontext.h
+} else: contains(QT_CONFIG,opengl) {
+ SOURCES += $$PWD/qwindowsglcontext.cpp
+ HEADERS += $$PWD/qwindowsglcontext.h
+}
+
+# Dynamic GL needs both WGL and EGL
+contains(QT_CONFIG,dynamicgl) {
+ SOURCES += $$PWD/qwindowseglcontext.cpp
+ HEADERS += $$PWD/qwindowseglcontext.h
+}
+
+!contains( DEFINES, QT_NO_CLIPBOARD ) {
+ SOURCES += $$PWD/qwindowsclipboard.cpp
+ HEADERS += $$PWD/qwindowsclipboard.h
+}
+
+# drag and drop on windows only works if a clipboard is available
+!contains( DEFINES, QT_NO_DRAGANDDROP ) {
+ !win32:SOURCES += $$PWD/qwindowsdrag.cpp
+ !win32:HEADERS += $$PWD/qwindowsdrag.h
+ win32:!contains( DEFINES, QT_NO_CLIPBOARD ) {
+ HEADERS += $$PWD/qwindowsdrag.h
+ SOURCES += $$PWD/qwindowsdrag.cpp
+ }
+}
+
+!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/wintab
+ HEADERS += $$PWD/qwindowstabletsupport.h
+ SOURCES += $$PWD/qwindowstabletsupport.cpp
+}
+
+!wince*:!contains( DEFINES, QT_NO_SESSIONMANAGER ) {
+ SOURCES += $$PWD/qwindowssessionmanager.cpp
+ HEADERS += $$PWD/qwindowssessionmanager.h
+}
+
+contains(QT_CONFIG, freetype) {
+ DEFINES *= QT_NO_FONTCONFIG
+ QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
+
+ HEADERS += \
+ $$PWD/qwindowsfontdatabase_ft.h
+ SOURCES += \
+ $$PWD/qwindowsfontdatabase_ft.cpp \
+ $$QT_FREETYPE_DIR/src/base/ftbase.c \
+ $$QT_FREETYPE_DIR/src/base/ftbbox.c \
+ $$QT_FREETYPE_DIR/src/base/ftdebug.c \
+ $$QT_FREETYPE_DIR/src/base/ftglyph.c \
+ $$QT_FREETYPE_DIR/src/base/ftinit.c \
+ $$QT_FREETYPE_DIR/src/base/ftmm.c \
+ $$QT_FREETYPE_DIR/src/base/fttype1.c \
+ $$QT_FREETYPE_DIR/src/base/ftsynth.c \
+ $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
+ $$QT_FREETYPE_DIR/src/bdf/bdf.c \
+ $$QT_FREETYPE_DIR/src/cache/ftcache.c \
+ $$QT_FREETYPE_DIR/src/cff/cff.c \
+ $$QT_FREETYPE_DIR/src/cid/type1cid.c \
+ $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
+ $$QT_FREETYPE_DIR/src/pcf/pcf.c \
+ $$QT_FREETYPE_DIR/src/pfr/pfr.c \
+ $$QT_FREETYPE_DIR/src/psaux/psaux.c \
+ $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
+ $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
+ $$QT_FREETYPE_DIR/src/raster/raster.c \
+ $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
+ $$QT_FREETYPE_DIR/src/smooth/smooth.c \
+ $$QT_FREETYPE_DIR/src/truetype/truetype.c \
+ $$QT_FREETYPE_DIR/src/type1/type1.c \
+ $$QT_FREETYPE_DIR/src/type42/type42.c \
+ $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
+ $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
+ $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
+ $$QT_FREETYPE_DIR/src/autofit/afangles.c\
+ $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
+ $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
+ $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
+ $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
+ $$QT_FREETYPE_DIR/src/autofit/afhints.c\
+ $$QT_FREETYPE_DIR/src/autofit/afloader.c\
+ $$QT_FREETYPE_DIR/src/autofit/autofit.c
+
+ SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c
+
+
+ INCLUDEPATH += \
+ $$QT_FREETYPE_DIR/src \
+ $$QT_FREETYPE_DIR/include
+
+ TR_EXCLUDE += $$QT_FREETYPE_DIR/*
+
+ DEFINES += FT2_BUILD_LIBRARY
+ contains(QT_CONFIG, system-zlib) {
+ DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
+ }
+} else:contains(QT_CONFIG, system-freetype) {
+ include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri)
+ HEADERS += \
+ $$PWD/qwindowsfontdatabase_ft.h
+ SOURCES += \
+ $$PWD/qwindowsfontdatabase_ft.cpp
+}
+
+contains(QT_CONFIG, accessibility):include($$PWD/accessible/accessible.pri)
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index 0249e156d9..188bd7917c 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -8,184 +8,19 @@ QT *= core-private
QT *= gui-private
QT *= platformsupport-private
-# Note: OpenGL32 must precede Gdi32 as it overwrites some functions.
-LIBS *= -lole32
-!wince*:LIBS *= -lgdi32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32
+!wince:LIBS *= -lgdi32
-contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32
+include(windows.pri)
-win32-g++*: LIBS *= -luuid
-# For the dialog helpers:
-!wince*:LIBS *= -lshlwapi -lshell32
-!wince*:LIBS *= -ladvapi32
-wince*:DEFINES *= QT_LIBINFIX=L"\"\\\"$${QT_LIBINFIX}\\\"\""
-
-DEFINES *= QT_NO_CAST_FROM_ASCII
-
-contains(QT_CONFIG, directwrite) {
- LIBS *= -ldwrite
- SOURCES += qwindowsfontenginedirectwrite.cpp
- HEADERS += qwindowsfontenginedirectwrite.h
-} else {
- DEFINES *= QT_NO_DIRECTWRITE
-}
-
-SOURCES += \
+SOURCES += \
main.cpp \
- qwindowsnativeimage.cpp \
- qwindowswindow.cpp \
- qwindowsintegration.cpp \
- qwindowscontext.cpp \
qwindowsbackingstore.cpp \
- qwindowsscreen.cpp \
- qwindowskeymapper.cpp \
- qwindowsfontengine.cpp \
- qwindowsfontdatabase.cpp \
- qwindowsmousehandler.cpp \
- qwindowsguieventdispatcher.cpp \
- qwindowsole.cpp \
- qwindowsmime.cpp \
- qwindowsinternalmimedata.cpp \
- qwindowscursor.cpp \
- qwindowsinputcontext.cpp \
- qwindowstheme.cpp \
- qwindowsdialoghelpers.cpp \
- qwindowsservices.cpp
+ qwindowsgdiintegration.cpp \
+ qwindowsgdinativeinterface.cpp
-HEADERS += \
- qwindowsnativeimage.h \
- qwindowswindow.h \
- qwindowsintegration.h \
- qwindowscontext.h \
+HEADERS += \
qwindowsbackingstore.h \
- qwindowsscreen.h \
- qwindowskeymapper.h \
- qwindowsfontengine.h \
- qwindowsfontdatabase.h \
- qwindowsmousehandler.h \
- qwindowsguieventdispatcher.h \
- qtwindowsglobal.h \
- qtwindows_additional.h \
- qwindowsole.h \
- qwindowsmime.h \
- qwindowsinternalmimedata.h \
- qwindowscursor.h \
- array.h \
- qwindowsinputcontext.h \
- qwindowstheme.h \
- qwindowsdialoghelpers.h \
- qwindowsservices.h \
- qplatformfunctions_wince.h
-
-contains(QT_CONFIG, opengles2) {
- SOURCES += qwindowseglcontext.cpp
- HEADERS += qwindowseglcontext.h
-} else {
- contains(QT_CONFIG, opengl) {
- SOURCES += qwindowsglcontext.cpp
- HEADERS += qwindowsglcontext.h
- }
-}
-
-!contains( DEFINES, QT_NO_CLIPBOARD ) {
- SOURCES += qwindowsclipboard.cpp
- HEADERS += qwindowsclipboard.h
-}
-
-# drag and drop on windows only works if a clipboard is available
-!contains( DEFINES, QT_NO_DRAGANDDROP ) {
- !win32:SOURCES += qwindowsdrag.cpp
- !win32:HEADERS += qwindowsdrag.h
- win32:!contains( DEFINES, QT_NO_CLIPBOARD ) {
- HEADERS += qwindowsdrag.h
- SOURCES += qwindowsdrag.cpp
- }
-}
-
-!wince*:!contains( DEFINES, QT_NO_TABLETEVENT ) {
- INCLUDEPATH += ../../../3rdparty/wintab
- HEADERS += qwindowstabletsupport.h
- SOURCES += qwindowstabletsupport.cpp
-}
-
-!wince*:!contains( DEFINES, QT_NO_SESSIONMANAGER ) {
- SOURCES += qwindowssessionmanager.cpp
- HEADERS += qwindowssessionmanager.h
-}
-
-contains(QT_CONFIG, freetype) {
- DEFINES *= QT_NO_FONTCONFIG
- QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
-
- HEADERS += \
- qwindowsfontdatabase_ft.h
- SOURCES += \
- qwindowsfontdatabase_ft.cpp \
- $$QT_FREETYPE_DIR/src/base/ftbase.c \
- $$QT_FREETYPE_DIR/src/base/ftbbox.c \
- $$QT_FREETYPE_DIR/src/base/ftdebug.c \
- $$QT_FREETYPE_DIR/src/base/ftglyph.c \
- $$QT_FREETYPE_DIR/src/base/ftinit.c \
- $$QT_FREETYPE_DIR/src/base/ftmm.c \
- $$QT_FREETYPE_DIR/src/base/fttype1.c \
- $$QT_FREETYPE_DIR/src/base/ftsynth.c \
- $$QT_FREETYPE_DIR/src/base/ftbitmap.c \
- $$QT_FREETYPE_DIR/src/bdf/bdf.c \
- $$QT_FREETYPE_DIR/src/cache/ftcache.c \
- $$QT_FREETYPE_DIR/src/cff/cff.c \
- $$QT_FREETYPE_DIR/src/cid/type1cid.c \
- $$QT_FREETYPE_DIR/src/gzip/ftgzip.c \
- $$QT_FREETYPE_DIR/src/pcf/pcf.c \
- $$QT_FREETYPE_DIR/src/pfr/pfr.c \
- $$QT_FREETYPE_DIR/src/psaux/psaux.c \
- $$QT_FREETYPE_DIR/src/pshinter/pshinter.c \
- $$QT_FREETYPE_DIR/src/psnames/psmodule.c \
- $$QT_FREETYPE_DIR/src/raster/raster.c \
- $$QT_FREETYPE_DIR/src/sfnt/sfnt.c \
- $$QT_FREETYPE_DIR/src/smooth/smooth.c \
- $$QT_FREETYPE_DIR/src/truetype/truetype.c \
- $$QT_FREETYPE_DIR/src/type1/type1.c \
- $$QT_FREETYPE_DIR/src/type42/type42.c \
- $$QT_FREETYPE_DIR/src/winfonts/winfnt.c \
- $$QT_FREETYPE_DIR/src/lzw/ftlzw.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvalid.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvbase.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgdef.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvjstf.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvcommn.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgpos.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvgsub.c\
- $$QT_FREETYPE_DIR/src/otvalid/otvmod.c\
- $$QT_FREETYPE_DIR/src/autofit/afangles.c\
- $$QT_FREETYPE_DIR/src/autofit/afglobal.c\
- $$QT_FREETYPE_DIR/src/autofit/aflatin.c\
- $$QT_FREETYPE_DIR/src/autofit/afmodule.c\
- $$QT_FREETYPE_DIR/src/autofit/afdummy.c\
- $$QT_FREETYPE_DIR/src/autofit/afhints.c\
- $$QT_FREETYPE_DIR/src/autofit/afloader.c\
- $$QT_FREETYPE_DIR/src/autofit/autofit.c
-
- SOURCES += $$QT_FREETYPE_DIR/src/base/ftsystem.c
-
-
- INCLUDEPATH += \
- $$QT_FREETYPE_DIR/src \
- $$QT_FREETYPE_DIR/include
-
- TR_EXCLUDE += $$QT_FREETYPE_DIR/*
-
- DEFINES += FT2_BUILD_LIBRARY
- contains(QT_CONFIG, system-zlib) {
- DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
- }
-} else:contains(QT_CONFIG, system-freetype) {
- include($$QT_SOURCE_TREE/src/platformsupport/fontdatabases/basic/basic.pri)
- HEADERS += \
- qwindowsfontdatabase_ft.h
- SOURCES += \
- qwindowsfontdatabase_ft.cpp
-}
+ qwindowsgdiintegration.h \
+ qwindowsgdinativeinterface.h
OTHER_FILES += windows.json
-
-contains(QT_CONFIG, accessibility):include(accessible/accessible.pri)
diff --git a/src/plugins/platforms/winrt/blit.hlsl b/src/plugins/platforms/winrt/blit.hlsl
new file mode 100644
index 0000000000..170e7f40ca
--- /dev/null
+++ b/src/plugins/platforms/winrt/blit.hlsl
@@ -0,0 +1,14 @@
+uniform SamplerState Sampler : register(s0);
+uniform Texture2D Texture : register(t0);
+
+void blitvs(in float4 pos0 : TEXCOORD0, in float2 tex0 : TEXCOORD1,
+ out float4 gl_Position : SV_POSITION, out float2 coord : TEXCOORD0)
+{
+ coord = tex0;
+ gl_Position = pos0 * float4(1.0, -1.0, 1.0, 1.0);
+}
+
+float4 blitps(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0
+{
+ return Texture.Sample(Sampler, coord);
+}
diff --git a/src/plugins/platforms/winrt/main.cpp b/src/plugins/platforms/winrt/main.cpp
new file mode 100644
index 0000000000..89d560dbe3
--- /dev/null
+++ b/src/plugins/platforms/winrt/main.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+
+#include <qpa/qplatformintegrationplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTIntegrationPlugin : public QPlatformIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.2" FILE "winrt.json")
+
+public:
+ QStringList keys() const;
+ QPlatformIntegration *create(const QString&, const QStringList&);
+};
+
+QStringList QWinRTIntegrationPlugin::keys() const
+{
+ return QStringList(QStringLiteral("WinRT"));
+}
+
+QPlatformIntegration *QWinRTIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+{
+ Q_UNUSED(paramList);
+ if (!system.compare(QLatin1String("winrt"), Qt::CaseInsensitive))
+ return QWinRTIntegration::create();
+
+ return 0;
+}
+
+QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
new file mode 100644
index 0000000000..b219548788
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtbackingstore.h"
+
+#include "qwinrtscreen.h"
+#include "qwinrtwindow.h"
+#include "qwinrteglcontext.h"
+#include <QtGui/QOpenGLContext>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <dxgi.h>
+
+// Generated shader headers
+#include "blitps.h"
+#include "blitvs.h"
+
+namespace { // Utility namespace for writing out an ANGLE-compatible binary blob
+
+// Must match packaged ANGLE
+enum : quint32 {
+ AngleMajorVersion = 1,
+ AngleMinorVersion = 2,
+ AngleBuildRevision = 2446,
+ AngleVersion = ((AngleMajorVersion << 24) | (AngleMinorVersion << 16) | AngleBuildRevision),
+ AngleOptimizationLevel = (1 << 14)
+};
+
+struct ShaderString
+{
+ ShaderString(const char *data = 0) : data(data) { }
+ const char *data;
+};
+
+// ANGLE stream compatibility - when size_t is 32-bit, QDataStream::writeBytes() also works
+QDataStream &operator<<(QDataStream &stream, const ShaderString &shaderString)
+{
+ if (!shaderString.data)
+ return stream << size_t(0);
+
+ size_t len = strlen(shaderString.data);
+ stream << len;
+ stream.writeRawData(shaderString.data, int(len));
+ return stream;
+}
+
+struct Attribute
+{
+ Attribute(GLenum type = 0, const char *name = 0, quint32 index = 0)
+ : type(type), name(name), index(index) { }
+ GLenum type;
+ ShaderString name;
+ quint32 index;
+};
+
+struct Sampler
+{
+ enum TextureType { Texture2D, TextureCube };
+ Sampler(bool active = false, GLint unit = 0, TextureType type = Texture2D)
+ : active(active), unit(unit), type(type) { }
+ bool active;
+ GLint unit;
+ TextureType type;
+};
+
+struct Uniform
+{
+ Uniform() { }
+ Uniform(GLenum type, quint32 precision, const char *name, quint32 arraySize,
+ quint32 psRegisterIndex, quint32 vsRegisterIndex, quint32 registerCount)
+ : type(type), precision(precision), name(name), arraySize(arraySize)
+ , psRegisterIndex(psRegisterIndex), vsRegisterIndex(vsRegisterIndex), registerCount(registerCount) { }
+ GLenum type;
+ quint32 precision;
+ ShaderString name;
+ quint32 arraySize;
+ quint32 psRegisterIndex;
+ quint32 vsRegisterIndex;
+ quint32 registerCount;
+};
+
+struct UniformIndex
+{
+ UniformIndex(const char *name = 0, quint32 element = 0, quint32 index = 0)
+ : name(name), element(element), index(index) { }
+ ShaderString name;
+ quint32 element;
+ quint32 index;
+};
+
+static const QByteArray createAngleBinary(
+ const QVector<Attribute> &attributes,
+ const QVector<Sampler> &textureSamplers,
+ const QVector<Sampler> &vertexSamplers,
+ const QVector<Uniform> &uniforms,
+ const QVector<UniformIndex> &uniformIndex,
+ const QByteArray &pixelShader,
+ const QByteArray &vertexShader,
+ const QByteArray &geometryShader = QByteArray(),
+ bool usesPointSize = false)
+{
+ QByteArray binary;
+
+ QDataStream stream(&binary, QIODevice::WriteOnly);
+ stream.setByteOrder(QDataStream::LittleEndian);
+
+ stream << quint32(GL_PROGRAM_BINARY_ANGLE)
+ << quint32(AngleVersion)
+ << quint32(AngleOptimizationLevel);
+
+ // Vertex attributes
+ for (int i = 0; i < 16; ++i) {
+ if (i < attributes.size())
+ stream << quint32(attributes[i].type) << attributes[i].name << attributes[i].index;
+ else
+ stream << quint32(GL_NONE) << ShaderString() << qint32(-1);
+ }
+
+ // Texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < textureSamplers.size())
+ stream << textureSamplers[i].active << textureSamplers[i].unit << qint32(textureSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ // Vertex texture units
+ for (int i = 0; i < 16; ++i) {
+ if (i < vertexSamplers.size())
+ stream << vertexSamplers[i].active << vertexSamplers[i].unit << qint32(vertexSamplers[i].type);
+ else
+ stream << false << qint32(0) << qint32(Sampler::Texture2D);
+ }
+
+ stream << vertexSamplers.size()
+ << textureSamplers.size()
+ << usesPointSize;
+
+ stream << size_t(uniforms.size());
+ foreach (const Uniform &uniform, uniforms) {
+ stream << uniform.type << uniform.precision << uniform.name << uniform.arraySize
+ << uniform.psRegisterIndex << uniform.vsRegisterIndex << uniform.registerCount;
+ }
+
+ stream << size_t(uniformIndex.size());
+ foreach (const UniformIndex &index, uniformIndex)
+ stream << index.name << index.element << index.index;
+
+ stream << quint32(pixelShader.size())
+ << quint32(vertexShader.size())
+ << quint32(geometryShader.size());
+
+ // ANGLE requires that we query the adapter for its LUID. Later on, it may be useful
+ // for checking feature level support, picking the best adapter on the system, etc.
+ IDXGIFactory1 *dxgiFactory;
+ if (FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)))) {
+ qCritical("QWinRTBackingStore: failed to create DXGI factory.");
+ return QByteArray();
+ }
+ IDXGIAdapter *dxgiAdapter;
+ if (FAILED(dxgiFactory->EnumAdapters(0, &dxgiAdapter))) {
+ qCritical("QWinRTBackingStore:: failed to enumerate adapter.");
+ dxgiFactory->Release();
+ return QByteArray();
+ }
+ DXGI_ADAPTER_DESC desc;
+ dxgiAdapter->GetDesc(&desc);
+ dxgiAdapter->Release();
+ QByteArray guid(sizeof(GUID), '\0');
+ memcpy(guid.data(), &desc.AdapterLuid, sizeof(LUID));
+ stream.writeRawData(guid.constData(), guid.size());
+ stream.writeRawData(pixelShader.constData(), pixelShader.size());
+ stream.writeRawData(vertexShader.constData(), vertexShader.size());
+ if (!geometryShader.isEmpty())
+ stream.writeRawData(geometryShader.constData(), geometryShader.size());
+
+ return binary;
+}
+
+} // namespace
+
+QT_BEGIN_NAMESPACE
+
+static const GLfloat normCoords[] = { -1, 1, 1, 1, 1, -1, -1, -1 };
+static const GLfloat quadCoords[] = { 0, 0, 1, 0, 1, 1, 0, 1 };
+
+QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
+ : QPlatformBackingStore(window)
+ , m_context(new QOpenGLContext)
+ , m_shaderProgram(0)
+ , m_fbo(0)
+ , m_texture(0)
+ , m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
+{
+ window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
+
+ m_context->setFormat(window->requestedFormat());
+ m_context->setScreen(window->screen());
+ m_context->create();
+
+ m_context->makeCurrent(window);
+ glGenFramebuffers(1, &m_fbo);
+ glGenRenderbuffers(1, &m_rbo);
+ glGenTextures(1, &m_texture);
+ m_shaderProgram = glCreateProgram();
+
+#if 0 // Standard GLES passthrough shader program
+ static const char *vertexShaderSource =
+ "attribute vec4 pos0;\n"
+ "attribute vec2 tex0;\n"
+ "varying vec2 coord;\n"
+ "void main() {\n"
+ " coord = tex0;\n"
+ " gl_Position = pos0;\n"
+ "}\n";
+ static const char *fragmentShaderSource =
+ "uniform sampler2D texture;\n"
+ "varying highp vec2 coord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(texture, coord);\n"
+ "}\n";
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
+ glCompileShader(vertexShader);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
+ glCompileShader(fragmentShader);
+ glAttachShader(m_shaderProgram, vertexShader);
+ glAttachShader(m_shaderProgram, fragmentShader);
+ glLinkProgram(m_shaderProgram);
+#else // Precompiled passthrough shader
+ QVector<Attribute> attributes = QVector<Attribute>() << Attribute(GL_FLOAT_VEC4, "pos0", 0)
+ << Attribute(GL_FLOAT_VEC2, "tex0", 1);
+ QVector<Sampler> textureSamplers = QVector<Sampler>() << Sampler(true, 0, Sampler::Texture2D);
+ QVector<Sampler> vertexSamplers;
+ QVector<Uniform> uniforms = QVector<Uniform>() << Uniform(GL_SAMPLER_2D, 0, "texture", 0, 0, -1, 1);
+ QVector<UniformIndex> uniformsIndex = QVector<UniformIndex>() << UniformIndex("texture", 0, 0);
+ QByteArray pixelShader(reinterpret_cast<const char *>(q_blitps), sizeof(q_blitps));
+ QByteArray vertexShader(reinterpret_cast<const char *>(q_blitvs), sizeof(q_blitvs));
+ QByteArray binary = createAngleBinary(attributes, textureSamplers, vertexSamplers,
+ uniforms, uniformsIndex, pixelShader, vertexShader);
+ glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
+#endif
+ m_context->doneCurrent();
+ resize(window->size(), QRegion());
+}
+
+QWinRTBackingStore::~QWinRTBackingStore()
+{
+ glDeleteBuffers(1, &m_fbo);
+ glDeleteRenderbuffers(1, &m_rbo);
+ glDeleteTextures(1, &m_texture);
+ glDeleteProgram(m_shaderProgram);
+}
+
+QPaintDevice *QWinRTBackingStore::paintDevice()
+{
+ return m_paintDevice.data();
+}
+
+void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
+{
+ Q_UNUSED(offset)
+
+ const QImage *image = static_cast<QImage *>(m_paintDevice.data());
+
+ m_context->makeCurrent(window);
+
+ // Blitting the entire image width trades zero image copy/relayout for a larger texture upload.
+ // Since we're blitting the whole width anyway, the boundingRect() is used in the assumption that
+ // we don't repeat upload. This is of course dependent on the distance between update regions.
+ // Ideally, we would use the GL_EXT_unpack_subimage extension, which should be possible to implement
+ // since D3D11_MAPPED_SUBRESOURCE supports RowPitch (see below).
+ // Note that single-line blits in a loop are *very* slow, so reducing calls to glTexSubImage2D
+ // is probably a good idea anyway.
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ QRect bounds = region.boundingRect();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), m_size.width(), bounds.height(),
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()));
+ // TODO: Implement GL_EXT_unpack_subimage in ANGLE for more minimal uploads
+ //glPixelStorei(GL_UNPACK_ROW_LENGTH, image->bytesPerLine());
+ //glTexSubImage2D(GL_TEXTURE_2D, 0, bounds.x(), bounds.y(), bounds.width(), bounds.height(),
+ // GL_BGRA_EXT, GL_UNSIGNED_BYTE, image->scanLine(bounds.y()) + bounds.x() * 4);
+
+ // Bind render buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
+
+ // Bind position
+ glUseProgram(m_shaderProgram);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, normCoords);
+ glEnableVertexAttribArray(1);
+ glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, quadCoords);
+
+ // Render
+ glViewport(0, 0, m_size.width(), m_size.height());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // Unbind
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
+ glUseProgram(0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ // fast blit - TODO: perform the blit inside swap buffers instead
+ glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, 0);
+ glBlitFramebufferANGLE(0, 0, m_size.width(), m_size.height(), // TODO: blit only the changed rectangle
+ 0, 0, m_size.width(), m_size.height(),
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ m_context->swapBuffers(window);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
+{
+ Q_UNUSED(staticContents)
+ if (m_size == size)
+ return;
+
+ m_size = size;
+ m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
+
+ m_context->makeCurrent(window());
+ // Input texture
+ glBindTexture(GL_TEXTURE_2D, m_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_size.width(), m_size.height(),
+ 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, NULL);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ // Render buffer
+ glBindRenderbuffer(GL_RENDERBUFFER, m_rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_BGRA8_EXT, m_size.width(), m_size.height());
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ m_context->doneCurrent();
+}
+
+void QWinRTBackingStore::beginPaint(const QRegion &region)
+{
+ Q_UNUSED(region)
+}
+
+void QWinRTBackingStore::endPaint()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index 9af856e8e7..8be549b441 100644
--- a/src/plugins/platforms/eglfs/qeglfsbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -39,43 +39,39 @@
**
****************************************************************************/
-#ifndef QEGLFSBACKINGSTORE_H
-#define QEGLFSBACKINGSTORE_H
+#ifndef QWINRTBACKINGSTORE_H
+#define QWINRTBACKINGSTORE_H
#include <qpa/qplatformbackingstore.h>
-#include <QtGui/QOpenGLFunctions>
-
-#include <QImage>
-#include <QRegion>
+#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE
-class QOpenGLPaintDevice;
-class QEglFSWindow;
+class QWinRTScreen;
+class QOpenGLContext;
-class QEglFSBackingStore : public QPlatformBackingStore, public QOpenGLFunctions
+class QWinRTBackingStore : public QPlatformBackingStore
{
public:
- QEglFSBackingStore(QWindow *window);
-
+ explicit QWinRTBackingStore(QWindow *window);
+ ~QWinRTBackingStore();
QPaintDevice *paintDevice();
-
void beginPaint(const QRegion &);
-
+ void endPaint();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
void resize(const QSize &size, const QRegion &staticContents);
- uint texture() const { return m_texture; }
-
private:
- void updateTexture();
-
- QEglFSWindow *m_window;
- QImage m_image;
- uint m_texture;
- QRegion m_dirty;
+ QSize m_size;
+ QScopedPointer<QPaintDevice> m_paintDevice;
+ QScopedPointer<QOpenGLContext> m_context;
+ quint32 m_shaderProgram;
+ quint32 m_fbo;
+ quint32 m_rbo;
+ quint32 m_texture;
+ QWinRTScreen *m_screen;
};
QT_END_NAMESPACE
-#endif // QEGLFSBACKINGSTORE_H
+#endif // QWINRTBACKINGSTORE_H
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.cpp b/src/plugins/platforms/winrt/qwinrtcursor.cpp
new file mode 100644
index 0000000000..8241560cef
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtcursor.h"
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.foundation.h>
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::Foundation;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTCursor::QWinRTCursor(ICoreWindow *window) : m_window(window), m_cursorFactory(nullptr)
+{
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Core_CoreCursor).Get(), &m_cursorFactory);
+#endif
+}
+
+QWinRTCursor::~QWinRTCursor()
+{
+ if (m_cursorFactory)
+ m_cursorFactory->Release();
+}
+
+#ifndef QT_NO_CURSOR
+void QWinRTCursor::changeCursor(QCursor *windowCursor, QWindow *)
+{
+#ifndef Q_OS_WINPHONE
+ if (!m_cursorFactory)
+ return;
+
+ CoreCursorType type;
+ switch (windowCursor ? windowCursor->shape() : Qt::ArrowCursor) {
+ case Qt::BlankCursor:
+ m_window->put_PointerCursor(nullptr);
+ return;
+ default:
+ case Qt::OpenHandCursor:
+ case Qt::ClosedHandCursor:
+ case Qt::DragCopyCursor:
+ case Qt::DragMoveCursor:
+ case Qt::DragLinkCursor:
+ // (unavailable)
+ case Qt::ArrowCursor:
+ type = CoreCursorType_Arrow;
+ break;
+ case Qt::UpArrowCursor:
+ type = CoreCursorType_UpArrow;
+ break;
+ case Qt::CrossCursor:
+ type = CoreCursorType_Cross;
+ break;
+ case Qt::WaitCursor:
+ case Qt::BusyCursor:
+ type = CoreCursorType_Wait;
+ break;
+ case Qt::IBeamCursor:
+ type = CoreCursorType_IBeam;
+ break;
+ case Qt::SizeVerCursor:
+ case Qt::SplitVCursor:
+ type = CoreCursorType_SizeNorthSouth;
+ break;
+ case Qt::SizeHorCursor:
+ case Qt::SplitHCursor:
+ type = CoreCursorType_SizeWestEast;
+ break;
+ case Qt::SizeBDiagCursor:
+ type = CoreCursorType_SizeNortheastSouthwest;
+ break;
+ case Qt::SizeFDiagCursor:
+ type = CoreCursorType_SizeNorthwestSoutheast;
+ break;
+ case Qt::SizeAllCursor:
+ type = CoreCursorType_SizeAll;
+ break;
+ case Qt::PointingHandCursor:
+ type = CoreCursorType_Hand;
+ break;
+ case Qt::ForbiddenCursor:
+ type = CoreCursorType_UniversalNo;
+ break;
+ case Qt::WhatsThisCursor:
+ type = CoreCursorType_Help;
+ break;
+ case Qt::BitmapCursor:
+ case Qt::CustomCursor:
+ // TODO: figure out if arbitrary bitmaps can be made into resource IDs
+ // For now, we don't get enough info from QCursor to set a custom cursor
+ type = CoreCursorType_Custom;
+ break;
+ }
+
+ ICoreCursor *cursor;
+ if (SUCCEEDED(m_cursorFactory->CreateCursor(type, 0, &cursor)))
+ m_window->put_PointerCursor(cursor);
+#endif // Q_OS_WINPHONE
+}
+#endif // QT_NO_CURSOR
+
+QPoint QWinRTCursor::pos() const
+{
+#ifdef Q_OS_WINPHONE
+ return QPlatformCursor::pos();
+#else
+ Point point;
+ m_window->get_PointerPosition(&point);
+ return QPoint(point.X, point.Y);
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtcursor.h b/src/plugins/platforms/winrt/qwinrtcursor.h
new file mode 100644
index 0000000000..f7b301a98b
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtcursor.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTCURSOR_H
+#define QWINRTCURSOR_H
+
+#include <qpa/qplatformcursor.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ struct ICoreCursorFactory;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTCursor : public QPlatformCursor
+{
+public:
+ explicit QWinRTCursor(ABI::Windows::UI::Core::ICoreWindow *window);
+ ~QWinRTCursor();
+#ifndef QT_NO_CURSOR
+ void changeCursor(QCursor * windowCursor, QWindow *);
+#endif
+ QPoint pos() const;
+
+private:
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ ABI::Windows::UI::Core::ICoreCursorFactory *m_cursorFactory;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTCURSOR_H
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.cpp b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
new file mode 100644
index 0000000000..014378f896
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteglcontext.h"
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEGLContext::QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface)
+ : QEGLPlatformContext(format, share, display, EGL_OPENGL_ES_API), m_eglSurface(surface)
+{
+}
+
+EGLSurface QWinRTEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
+{
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ // All windows use the same surface
+ return m_eglSurface;
+ } else {
+ // TODO: return EGL surfaces for offscreen surfaces
+ qWarning("This plugin does not support offscreen surfaces.");
+ return EGL_NO_SURFACE;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteglcontext.h b/src/plugins/platforms/winrt/qwinrteglcontext.h
new file mode 100644
index 0000000000..c065847374
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteglcontext.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSEGLCONTEXT_H
+#define QWINDOWSEGLCONTEXT_H
+
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTEGLContext : public QEGLPlatformContext
+{
+public:
+ explicit QWinRTEGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, EGLSurface surface);
+
+protected:
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+
+private:
+ EGLSurface m_eglSurface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSEGLCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
new file mode 100644
index 0000000000..98eb83f5eb
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrteventdispatcher.h"
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <qpa/qplatformscreenpageflipper.h>
+#include <QtCore/QThread>
+#include <QtGui/QGuiApplication>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTEventDispatcher::QWinRTEventDispatcher(QObject *parent)
+ : QEventDispatcherWinRT(parent)
+{
+}
+
+bool QWinRTEventDispatcher::hasPendingEvents()
+{
+ return QEventDispatcherWinRT::hasPendingEvents() || QWindowSystemInterface::windowSystemEventsQueued();
+}
+
+bool QWinRTEventDispatcher::sendPostedEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ bool didProcess = QEventDispatcherWinRT::sendPostedEvents(flags);
+ if (!(flags & QEventLoop::ExcludeUserInputEvents))
+ didProcess |= QWindowSystemInterface::sendWindowSystemEvents(flags);
+ return didProcess;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrteventdispatcher.h b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
new file mode 100644
index 0000000000..612d5ff6e2
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrteventdispatcher.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTEVENTDISPATCHER_H
+#define QWINRTEVENTDISPATCHER_H
+
+#include <QtCore/private/qeventdispatcher_winrt_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTEventDispatcher : public QEventDispatcherWinRT
+{
+ Q_OBJECT
+public:
+ explicit QWinRTEventDispatcher(QObject *parent = 0);
+
+protected:
+ bool hasPendingEvents();
+ bool sendPostedEvents(QEventLoop::ProcessEventsFlags flags);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTEVENTDISPATCHER_H
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
new file mode 100644
index 0000000000..c7fa339fad
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtfontdatabase.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+
+QT_BEGIN_NAMESPACE
+
+QString QWinRTFontDatabase::fontDir() const
+{
+ QString fontDirectory = QBasicFontDatabase::fontDir();
+ if (!QFile::exists(fontDirectory)) {
+ // Fall back to app directory + fonts, and just app directory after that
+ const QString applicationDirPath = QCoreApplication::applicationDirPath();
+ fontDirectory = applicationDirPath + QLatin1String("/fonts");
+ if (!QFile::exists(fontDirectory)) {
+ qWarning("No fonts directory found in application package.");
+ fontDirectory = applicationDirPath;
+ }
+ }
+ return fontDirectory;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index e9251592aa..49e32470c2 100644
--- a/src/plugins/platforms/android/src/opengl/qandroidopenglplatformscreen.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -39,22 +39,19 @@
**
****************************************************************************/
-#ifndef QANDROIDOPENGLPLATFORMSCREEN_H
-#define QANDROIDOPENGLPLATFORMSCREEN_H
+#ifndef QWINRTFONTDATABASE_H
+#define QWINRTFONTDATABASE_H
-#include "qeglfsscreen.h"
+#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
QT_BEGIN_NAMESPACE
-class QAndroidOpenGLPlatformScreen : public QEglFSScreen
+class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
- QAndroidOpenGLPlatformScreen(EGLDisplay display);
-
-protected:
- void topWindowChanged(QPlatformWindow *window);
+ QString fontDir() const;
};
QT_END_NAMESPACE
-#endif // QANDROIDOPENGLPLATFORMSCREEN_H
+#endif // QWINRTFONTDATABASE_H
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.cpp b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
new file mode 100644
index 0000000000..bc15f1e448
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtinputcontext.h"
+#include <QtGui/QWindow>
+
+#include <wrl.h>
+#include <roapi.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.ui.core.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::UI::Core;
+
+#ifdef Q_OS_WINPHONE
+#include <windows.phone.ui.core.h>
+using namespace ABI::Windows::Phone::UI::Core;
+#endif
+
+typedef ITypedEventHandler<InputPane*, InputPaneVisibilityEventArgs*> InputPaneVisibilityHandler;
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWinRTInputContext
+ \brief Manages Input Method visibility
+ \internal
+ \ingroup qt-qpa-winrt
+
+ Listens to the native virtual keyboard for hide/show events and provides
+ hints to the OS for showing/hiding. On WinRT, showInputPanel()/hideInputPanel()
+ have no effect because WinRT dictates that keyboard presence is user-driven:
+ (http://msdn.microsoft.com/en-us/library/windows/apps/hh465404.aspx)
+ Windows Phone, however, supports direct hiding/showing of the keyboard.
+*/
+
+QWinRTInputContext::QWinRTInputContext(ICoreWindow *window)
+ : m_window(window)
+{
+ IInputPaneStatics *statics;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_InputPane).Get(),
+ &statics))) {
+ qWarning(Q_FUNC_INFO ": failed to retrieve input pane statics.");
+ return;
+ }
+
+ IInputPane *inputPane;
+ statics->GetForCurrentView(&inputPane);
+ statics->Release();
+ if (inputPane) {
+ EventRegistrationToken showToken, hideToken;
+ inputPane->add_Showing(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onShowing).Get(), &showToken);
+ inputPane->add_Hiding(Callback<InputPaneVisibilityHandler>(
+ this, &QWinRTInputContext::onHiding).Get(), &hideToken);
+
+ Rect rect;
+ inputPane->get_OccludedRect(&rect);
+ m_keyboardRect = QRectF(rect.X, rect.Y, rect.Width, rect.Height);
+ m_isInputPanelVisible = !m_keyboardRect.isEmpty();
+ } else {
+ qWarning(Q_FUNC_INFO ": failed to retrieve InputPane.");
+ }
+}
+
+QRectF QWinRTInputContext::keyboardRect() const
+{
+ return m_keyboardRect;
+}
+
+bool QWinRTInputContext::isInputPanelVisible() const
+{
+ return m_isInputPanelVisible;
+}
+
+HRESULT QWinRTInputContext::onShowing(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = true;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::onHiding(IInputPane *pane, IInputPaneVisibilityEventArgs *)
+{
+ m_isInputPanelVisible = false;
+ emitInputPanelVisibleChanged();
+
+ Rect rect;
+ pane->get_OccludedRect(&rect);
+ setKeyboardRect(QRectF(rect.X, rect.Y, rect.Width, rect.Height));
+
+ return S_OK;
+}
+
+void QWinRTInputContext::setKeyboardRect(const QRectF rect)
+{
+ if (m_keyboardRect == rect)
+ return;
+
+ m_keyboardRect = rect;
+ emitKeyboardRectChanged();
+}
+
+#ifdef Q_OS_WINPHONE
+
+void QWinRTInputContext::showInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(true);
+ input->Release();
+ }
+}
+
+void QWinRTInputContext::hideInputPanel()
+{
+ ICoreWindowKeyboardInput *input;
+ if (SUCCEEDED(m_window->QueryInterface(IID_PPV_ARGS(&input)))) {
+ input->put_IsKeyboardInputEnabled(false);
+ input->Release();
+ }
+}
+
+#else // Q_OS_WINPHONE
+
+// IRawElementProviderSimple
+HRESULT QWinRTInputContext::get_ProviderOptions(ProviderOptions *retVal)
+{
+ *retVal = ProviderOptions_ServerSideProvider|ProviderOptions_UseComThreading;
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetPatternProvider(PATTERNID id, IUnknown **retVal)
+{
+ switch (id) {
+ case 10002: //UIA_ValuePatternId
+ return QueryInterface(__uuidof(IValueProvider), (void**)retVal);
+ break;
+ case 10014: //UIA_TextPatternId:
+ return QueryInterface(__uuidof(ITextProvider), (void**)retVal);
+ case 10029: //UIA_TextChildPatternId:
+ *retVal = nullptr;
+ break;
+ default:
+ qWarning("Unhandled pattern ID: %d", id);
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetPropertyValue(PROPERTYID idProp, VARIANT *retVal)
+{
+ switch (idProp) {
+ case 30003: //UIA_ControlTypePropertyId
+ retVal->vt = VT_I4;
+ retVal->lVal = 50025; //UIA_CustomControlTypeId
+ break;
+ case 30008: //UIA_IsKeyboardFocusablePropertyId
+ case 30009: //UIA_HasKeyboardFocusPropertyId
+ // These are probably never actually called
+ case 30016: //UIA_IsControlElementPropertyId
+ case 30017: //UIA_IsContentElementPropertyId
+ retVal->vt = VT_BOOL;
+ retVal->boolVal = VARIANT_TRUE;
+ break;
+ case 30019: //UIA_IsPasswordPropertyId
+ retVal->vt = VT_BOOL;
+ retVal->boolVal = VARIANT_FALSE;
+ break;
+ case 30020: //UIA_NativeWindowHandlePropertyId
+ retVal->vt = VT_PTR;
+ retVal->punkVal = m_window;
+ break;
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_HostRawElementProvider(IRawElementProviderSimple **retVal)
+{
+ // Return the window's element provider
+ IInspectable *hostProvider;
+ HRESULT hr = m_window->get_AutomationHostProvider(&hostProvider);
+ if (SUCCEEDED(hr)) {
+ hr = hostProvider->QueryInterface(IID_PPV_ARGS(retVal));
+ hostProvider->Release();
+ }
+ return hr;
+}
+
+// ITextProvider
+HRESULT QWinRTInputContext::GetSelection(SAFEARRAY **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::GetVisibleRanges(SAFEARRAY **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::RangeFromPoint(UiaPoint, ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_DocumentRange(ITextRangeProvider **)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_SupportedTextSelection(SupportedTextSelection *)
+{
+ // To be useful, requires listening to the focus object for a selection change and raising an event
+ return S_OK;
+}
+
+// IValueProvider
+HRESULT QWinRTInputContext::SetValue(LPCWSTR)
+{
+ // To be useful, requires listening to the focus object for a value change and raising an event
+ // May be useful for inputPanel autocomplete, etc.
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_Value(BSTR *)
+{
+ // To be useful, requires listening to the focus object for a value change and raising an event
+ // May be useful for inputPanel autocomplete, etc.
+ return S_OK;
+}
+
+HRESULT QWinRTInputContext::get_IsReadOnly(BOOL *isReadOnly)
+{
+ // isReadOnly dictates keyboard opening behavior when view is tapped.
+ // We need to decide if the user tapped within a control which is about to receive focus...
+ // Since this isn't possible (this function gets called before we receive the touch event),
+ // the most platform-aligned option is to show the keyboard if an editable item has focus,
+ // and close the keyboard if it is already open.
+ *isReadOnly = m_isInputPanelVisible || !inputMethodAccepted();
+ return S_OK;
+}
+
+#endif // !Q_OS_WINPHONE
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtinputcontext.h b/src/plugins/platforms/winrt/qwinrtinputcontext.h
new file mode 100644
index 0000000000..0a35f9b6e1
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtinputcontext.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINPUTCONTEXT_H
+#define QWINRTINPUTCONTEXT_H
+
+#include <qpa/qplatforminputcontext.h>
+#include <QtCore/QRectF>
+
+#include <wrl.h>
+#ifndef Q_OS_WINPHONE
+# include <UIAutomationCore.h>
+#endif
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Core {
+ struct ICoreWindow;
+ }
+ namespace ViewManagement {
+ struct IInputPane;
+ struct IInputPaneVisibilityEventArgs;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTInputContext : public QPlatformInputContext
+#ifndef Q_OS_WINPHONE
+ , public Microsoft::WRL::RuntimeClass<
+ Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRtClassicComMix>,
+ IRawElementProviderSimple, ITextProvider, IValueProvider>
+#endif // !Q_OS_WINPHONE
+{
+public:
+ explicit QWinRTInputContext(ABI::Windows::UI::Core::ICoreWindow *window);
+
+ QRectF keyboardRect() const;
+
+ bool isInputPanelVisible() const;
+
+#ifdef Q_OS_WINPHONE
+ void showInputPanel();
+ void hideInputPanel();
+#else // Q_OS_WINPHONE
+ // IRawElementProviderSimple
+ HRESULT __stdcall get_ProviderOptions(ProviderOptions *retVal);
+ HRESULT __stdcall GetPatternProvider(PATTERNID, IUnknown **);
+ HRESULT __stdcall GetPropertyValue(PROPERTYID idProp, VARIANT *retVal);
+ HRESULT __stdcall get_HostRawElementProvider(IRawElementProviderSimple **retVal);
+
+ // ITextProvider
+ HRESULT __stdcall GetSelection(SAFEARRAY **);
+ HRESULT __stdcall GetVisibleRanges(SAFEARRAY **);
+ HRESULT __stdcall RangeFromChild(IRawElementProviderSimple *,ITextRangeProvider **);
+ HRESULT __stdcall RangeFromPoint(UiaPoint, ITextRangeProvider **);
+ HRESULT __stdcall get_DocumentRange(ITextRangeProvider **);
+ HRESULT __stdcall get_SupportedTextSelection(SupportedTextSelection *);
+
+ // IValueProvider
+ HRESULT __stdcall SetValue(LPCWSTR);
+ HRESULT __stdcall get_Value(BSTR *);
+ HRESULT __stdcall get_IsReadOnly(BOOL *);
+#endif // !Q_OS_WINPHONE
+
+private:
+ HRESULT onShowing(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ HRESULT onHiding(ABI::Windows::UI::ViewManagement::IInputPane *,
+ ABI::Windows::UI::ViewManagement::IInputPaneVisibilityEventArgs *);
+ void setKeyboardRect(const QRectF rect);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_window;
+ QRectF m_keyboardRect;
+ bool m_isInputPanelVisible;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINPUTCONTEXT_H
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
new file mode 100644
index 0000000000..be82390723
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtintegration.h"
+#include "qwinrtwindow.h"
+#include "qwinrteventdispatcher.h"
+#include "qwinrtbackingstore.h"
+#include "qwinrtscreen.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtservices.h"
+#include "qwinrteglcontext.h"
+#include "qwinrtfontdatabase.h"
+#include "qwinrtplatformtheme.h"
+
+#include <QtGui/QOpenGLContext>
+
+#include <wrl.h>
+#include <windows.ui.core.h>
+#include <windows.ui.viewmanagement.h>
+#include <Windows.ApplicationModel.core.h>
+
+using namespace Microsoft::WRL;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::ApplicationModel::Core;
+
+static IUISettings *getSettings()
+{
+ static IUISettings *settings = 0;
+ if (!settings) {
+ if (FAILED(RoActivateInstance(Wrappers::HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_UISettings).Get(),
+ reinterpret_cast<IInspectable **>(&settings)))) {
+ qWarning("Could not activate UISettings.");
+ }
+ }
+ return settings;
+}
+
+QT_BEGIN_NAMESPACE
+
+QWinRTIntegration::QWinRTIntegration()
+ : m_success(false)
+ , m_fontDatabase(new QWinRTFontDatabase)
+ , m_services(new QWinRTServices)
+{
+ // Obtain the WinRT Application, view, and window
+ ICoreApplication *application;
+ if (FAILED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&application))))
+ qCritical("Could not attach to the application factory.");
+
+ ICoreApplicationView *view;
+ if (FAILED(application->GetCurrentView(&view))) {
+ qCritical("Could not obtain the application view - have you started outside of WinRT?");
+ return;
+ }
+
+ // Get core window (will act as our screen)
+ ICoreWindow *window;
+ if (FAILED(view->get_CoreWindow(&window))) {
+ qCritical("Could not obtain the application window - have you started outside of WinRT?");
+ return;
+ }
+ window->Activate();
+ m_screen = new QWinRTScreen(window);
+ screenAdded(m_screen);
+
+ m_success = true;
+}
+
+QWinRTIntegration::~QWinRTIntegration()
+{
+ Windows::Foundation::Uninitialize();
+}
+
+QAbstractEventDispatcher *QWinRTIntegration::createEventDispatcher() const
+{
+ return new QWinRTEventDispatcher;
+}
+
+bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case ThreadedPixmaps:
+ case OpenGL:
+ case ApplicationState:
+ return true;
+ default:
+ return QPlatformIntegration::hasCapability(cap);
+ }
+}
+
+QVariant QWinRTIntegration::styleHint(StyleHint hint) const
+{
+ switch (hint) {
+ case CursorFlashTime:
+ if (IUISettings *settings = getSettings()) {
+ quint32 blinkRate;
+ settings->get_CaretBlinkRate(&blinkRate);
+ return blinkRate;
+ }
+ break;
+ case MouseDoubleClickInterval:
+ if (IUISettings *settings = getSettings()) {
+ quint32 doubleClickTime;
+ settings->get_DoubleClickTime(&doubleClickTime);
+ return doubleClickTime;
+ }
+ case ShowIsFullScreen:
+ return true;
+ default:
+ break;
+ }
+ return QPlatformIntegration::styleHint(hint);
+}
+
+QPlatformWindow *QWinRTIntegration::createPlatformWindow(QWindow *window) const
+{
+ return new QWinRTWindow(window);
+}
+
+QPlatformBackingStore *QWinRTIntegration::createPlatformBackingStore(QWindow *window) const
+{
+ return new QWinRTBackingStore(window);
+}
+
+QPlatformOpenGLContext *QWinRTIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
+{
+ QWinRTScreen *screen = static_cast<QWinRTScreen *>(context->screen()->handle());
+ return new QWinRTEGLContext(context->format(), context->handle(), screen->eglDisplay(), screen->eglSurface());
+}
+
+QPlatformFontDatabase *QWinRTIntegration::fontDatabase() const
+{
+ return m_fontDatabase;
+}
+
+QPlatformInputContext *QWinRTIntegration::inputContext() const
+{
+ return m_screen->inputContext();
+}
+
+QPlatformServices *QWinRTIntegration::services() const
+{
+ return m_services;
+}
+
+Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
+{
+ return m_screen->keyboardModifiers();
+}
+
+QStringList QWinRTIntegration::themeNames() const
+{
+ return QStringList(QLatin1String("winrt"));
+}
+
+QPlatformTheme *QWinRTIntegration::createPlatformTheme(const QString &
+name) const
+{
+ if (name == QLatin1String("winrt"))
+ return new QWinRTPlatformTheme();
+
+ return 0;
+}
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h
new file mode 100644
index 0000000000..983637e670
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtintegration.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTINTEGRATION_H
+#define QWINRTINTEGRATION_H
+
+#include <qpa/qplatformintegration.h>
+
+QT_BEGIN_NAMESPACE
+
+class QAbstractEventDispatcher;
+class QWinRTScreen;
+
+class QWinRTIntegration : public QPlatformIntegration
+{
+private:
+ explicit QWinRTIntegration();
+public:
+ ~QWinRTIntegration();
+
+ static QWinRTIntegration *create()
+ {
+ QWinRTIntegration *integration = new QWinRTIntegration;
+ return integration->m_success ? integration : 0;
+ }
+
+ bool hasCapability(QPlatformIntegration::Capability cap) const;
+ QVariant styleHint(StyleHint hint) const;
+
+ QPlatformWindow *createPlatformWindow(QWindow *window) const;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
+ QPlatformFontDatabase *fontDatabase() const;
+ QPlatformInputContext *inputContext() const;
+ QPlatformServices *services() const;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const;
+
+ QStringList themeNames() const;
+ QPlatformTheme *createPlatformTheme(const QString &name) const;
+private:
+ bool m_success;
+ QWinRTScreen *m_screen;
+ QPlatformFontDatabase *m_fontDatabase;
+ QPlatformServices *m_services;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTINTEGRATION_H
diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
new file mode 100644
index 0000000000..e70d06860c
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.cpp
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtplatformmessagedialoghelper.h"
+
+#include <QtGui/QGuiApplication>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformtheme.h>
+
+#include <asyncinfo.h>
+#include <windows.ui.popups.h>
+#include <windows.foundation.h>
+#include <windows.foundation.collections.h>
+#include <wrl.h>
+
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::UI::Popups;
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+
+QT_BEGIN_NAMESPACE
+
+struct QWinRTPlatformMessageDialogInfo
+{
+ ComPtr<IAsyncInfo> info;
+};
+
+QWinRTPlatformMessageDialogHelper::QWinRTPlatformMessageDialogHelper() :
+ QPlatformMessageDialogHelper(),
+ m_info(new QWinRTPlatformMessageDialogInfo),
+ m_shown(false)
+{
+}
+
+QWinRTPlatformMessageDialogHelper::~QWinRTPlatformMessageDialogHelper()
+{
+ if (m_shown)
+ hide();
+ delete m_info;
+}
+
+void QWinRTPlatformMessageDialogHelper::exec()
+{
+ if (!m_shown)
+ show(Qt::Dialog, Qt::ApplicationModal, 0);
+ m_loop.exec();
+}
+
+bool QWinRTPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent)
+{
+ Q_UNUSED(windowFlags)
+ Q_UNUSED(windowModality)
+ Q_UNUSED(parent)
+
+ QSharedPointer<QMessageDialogOptions> options = this->options();
+
+ const QString informativeText = options->informativeText();
+ const QString title = options->windowTitle();
+ const QString text = informativeText.isEmpty() ? options->text() : (options->text() + QLatin1Char('\n') + informativeText);
+
+
+ ComPtr<IMessageDialogFactory> dialogFactory;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_MessageDialog).Get(), &dialogFactory)))
+ return false;
+
+ ComPtr<IUICommandFactory> commandFactory;
+ if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Popups_UICommand).Get(), &commandFactory)))
+ return false;
+
+ HString nativeText;
+ nativeText.Set(reinterpret_cast<LPCWSTR>(text.utf16()), text.size());
+ ComPtr<IMessageDialog> dialog;
+
+ if (!title.isEmpty()) {
+ HString nativeTitle;
+ nativeTitle.Set(reinterpret_cast<LPCWSTR>(title.utf16()), title.size());
+ if (FAILED(dialogFactory->CreateWithTitle(nativeText.Get(), nativeTitle.Get(), &dialog)))
+ return false;
+ } else {
+ if (FAILED(dialogFactory->Create(nativeText.Get(), &dialog)))
+ return false;
+ }
+
+ // Add Buttons
+ ComPtr<IVector<IUICommand*> > dialogCommands;
+ if (FAILED(dialog->get_Commands(&dialogCommands)))
+ return false;
+
+ // If no button is specified we need to create one to get close notification
+ int buttons = options->standardButtons();
+ if (buttons == 0)
+ buttons = QPlatformDialogHelper::Ok;
+
+ for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
+ if (buttons & i) {
+ // Add native command
+ const QString label = QGuiApplicationPrivate::platformTheme()->standardButtonText(i);
+
+ HString hLabel;
+ hLabel.Set(reinterpret_cast<LPCWSTR>(label.utf16()), label.size());
+
+ ABI::Windows::UI::Popups::IUICommand *command;
+ if (FAILED(commandFactory->CreateWithHandler(hLabel.Get(),
+ Callback<IUICommandInvokedHandler>(this, &QWinRTPlatformMessageDialogHelper::onInvoked).Get(),
+ &command)))
+ return false;
+ dialogCommands->Append(command);
+ }
+ }
+
+ ComPtr<IAsyncOperation<IUICommand*> > op;
+ if (FAILED(dialog->ShowAsync(&op)))
+ return false;
+
+ m_shown = true;
+ if (FAILED(op.As(&m_info->info))) {
+ m_shown = false;
+ // The dialog is shown already, so we cannot return false
+ qWarning("Failed to acquire AsyncInfo for MessageDialog");
+ }
+ return true;
+}
+
+void QWinRTPlatformMessageDialogHelper::hide()
+{
+ if (!m_shown)
+ return;
+
+ m_info->info->Cancel();
+ m_shown = false;
+}
+
+HRESULT QWinRTPlatformMessageDialogHelper::onInvoked(ABI::Windows::UI::Popups::IUICommand *command)
+{
+ HSTRING hLabel;
+ UINT32 labelLength;
+ command->get_Label(&hLabel);
+ QString label = QString::fromWCharArray(::WindowsGetStringRawBuffer(hLabel, &labelLength));
+ int buttonId = -1;
+ for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
+ if ( options()->standardButtons() & i ) {
+ if (QGuiApplicationPrivate::platformTheme()->standardButtonText(i) == label) {
+ buttonId = i;
+ break;
+ }
+ }
+ }
+ if (m_loop.isRunning())
+ m_loop.exit();
+
+ m_shown = false;
+
+ if (buttonId < 0) {
+ emit reject();
+ return S_OK;
+ }
+
+ QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonId);
+ QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton);
+ emit clicked(standardButton, role);
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h
new file mode 100644
index 0000000000..fbb21ed69c
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtplatformmessagedialoghelper.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTPLATFORMMESSAGEDIALOGHELPER_H
+#define QWINRTPLATFORMMESSAGEDIALOGHELPER_H
+
+#include <qpa/qplatformdialoghelper.h>
+#include <QtCore/QEventLoop>
+#include <QtCore/qt_windows.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace UI {
+ namespace Popups {
+ struct IUICommand;
+ }
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+struct QWinRTPlatformMessageDialogInfo;
+
+class QWinRTPlatformMessageDialogHelper : public QPlatformMessageDialogHelper
+{
+ Q_OBJECT
+public:
+ explicit QWinRTPlatformMessageDialogHelper();
+ ~QWinRTPlatformMessageDialogHelper();
+
+ void exec();
+ bool show(Qt::WindowFlags windowFlags,
+ Qt::WindowModality windowModality,
+ QWindow *parent);
+ void hide();
+
+ HRESULT onInvoked(ABI::Windows::UI::Popups::IUICommand *command);
+private:
+ QWinRTPlatformMessageDialogInfo *m_info;
+ QEventLoop m_loop;
+ bool m_shown;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTPLATFORMMESSAGEDIALOGHELPER_H
diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
new file mode 100644
index 0000000000..2c8d33da84
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtplatformtheme.h"
+#include "qwinrtplatformmessagedialoghelper.h"
+
+QT_BEGIN_NAMESPACE
+
+QWinRTPlatformTheme::QWinRTPlatformTheme()
+{
+}
+
+bool QWinRTPlatformTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
+{
+#ifndef Q_OS_WINPHONE
+ if (type == QPlatformTheme::MessageDialog)
+ return true;
+#endif // Q_OS_WINPHONE
+ return false;
+}
+
+QPlatformDialogHelper *QWinRTPlatformTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const
+{
+#ifndef Q_OS_WINPHONE
+ switch (type) {
+ case QPlatformTheme::MessageDialog:
+ return new QWinRTPlatformMessageDialogHelper();
+ default:
+ return QPlatformTheme::createPlatformDialogHelper(type);
+ }
+#else
+ return QPlatformTheme::createPlatformDialogHelper(type);
+#endif // Q_OS_WINPHONE
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtplatformtheme.h b/src/plugins/platforms/winrt/qwinrtplatformtheme.h
new file mode 100644
index 0000000000..f4a61982b2
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtplatformtheme.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTPLATFORMTHEME_H
+#define QWINRTPLATFORMTHEME_H
+
+#include <qpa/qplatformtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTPlatformTheme : public QPlatformTheme
+{
+public:
+ QWinRTPlatformTheme();
+
+ bool usePlatformNativeDialog(DialogType type) const;
+ QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTPLATFORMTHEME_H
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
new file mode 100644
index 0000000000..5bbf73a945
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -0,0 +1,1003 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtscreen.h"
+
+#include "qwinrtbackingstore.h"
+#include "qwinrtinputcontext.h"
+#include "qwinrtcursor.h"
+#include "qwinrteglcontext.h"
+
+#include <QtGui/QSurfaceFormat>
+#include <QtGui/QGuiApplication>
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <qpa/qwindowsysteminterface.h>
+#include <QtCore/qt_windows.h>
+
+#include <wrl.h>
+#include <windows.system.h>
+#include <Windows.Applicationmodel.h>
+#include <Windows.ApplicationModel.core.h>
+#include <windows.devices.input.h>
+#include <windows.ui.h>
+#include <windows.ui.core.h>
+#include <windows.ui.input.h>
+#include <windows.ui.viewmanagement.h>
+#include <windows.graphics.display.h>
+#include <windows.foundation.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::System;
+using namespace ABI::Windows::UI::Core;
+using namespace ABI::Windows::UI::Input;
+using namespace ABI::Windows::UI::ViewManagement;
+using namespace ABI::Windows::Devices::Input;
+using namespace ABI::Windows::Graphics::Display;
+
+typedef IEventHandler<IInspectable*> ResumeHandler;
+typedef IEventHandler<SuspendingEventArgs*> SuspendHandler;
+typedef ITypedEventHandler<CoreWindow*, WindowActivatedEventArgs*> ActivatedHandler;
+typedef ITypedEventHandler<CoreWindow*, CoreWindowEventArgs*> ClosedHandler;
+typedef ITypedEventHandler<CoreWindow*, CharacterReceivedEventArgs*> CharacterReceivedHandler;
+typedef ITypedEventHandler<CoreWindow*, InputEnabledEventArgs*> InputEnabledHandler;
+typedef ITypedEventHandler<CoreWindow*, KeyEventArgs*> KeyHandler;
+typedef ITypedEventHandler<CoreWindow*, PointerEventArgs*> PointerHandler;
+typedef ITypedEventHandler<CoreWindow*, WindowSizeChangedEventArgs*> SizeChangedHandler;
+typedef ITypedEventHandler<CoreWindow*, VisibilityChangedEventArgs*> VisibilityChangedHandler;
+typedef ITypedEventHandler<CoreWindow*, AutomationProviderRequestedEventArgs*> AutomationProviderRequestedHandler;
+
+QT_BEGIN_NAMESPACE
+
+static inline Qt::ScreenOrientations qtOrientationsFromNative(DisplayOrientations native)
+{
+ Qt::ScreenOrientations orientations = Qt::PrimaryOrientation;
+ if (native & DisplayOrientations_Portrait)
+ orientations |= Qt::PortraitOrientation;
+ if (native & DisplayOrientations_PortraitFlipped)
+ orientations |= Qt::InvertedPortraitOrientation;
+ if (native & DisplayOrientations_Landscape)
+ orientations |= Qt::LandscapeOrientation;
+ if (native & DisplayOrientations_LandscapeFlipped)
+ orientations |= Qt::InvertedLandscapeOrientation;
+ return orientations;
+}
+
+static inline DisplayOrientations nativeOrientationsFromQt(Qt::ScreenOrientations orientation)
+{
+ DisplayOrientations native = DisplayOrientations_None;
+ if (orientation & Qt::PortraitOrientation)
+ native |= DisplayOrientations_Portrait;
+ if (orientation & Qt::InvertedPortraitOrientation)
+ native |= DisplayOrientations_PortraitFlipped;
+ if (orientation & Qt::LandscapeOrientation)
+ native |= DisplayOrientations_Landscape;
+ if (orientation & Qt::InvertedLandscapeOrientation)
+ native |= DisplayOrientations_LandscapeFlipped;
+ return native;
+}
+
+static inline bool qIsNonPrintable(quint32 keyCode)
+{
+ switch (keyCode) {
+ case '\b':
+ case '\n':
+ case '\t':
+ case '\r':
+ case '\v':
+ case '\f':
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Return Qt meta key from VirtualKey
+static inline Qt::Key qKeyFromVirtual(VirtualKey key)
+{
+ switch (key) {
+
+ default:
+ return Qt::Key_unknown;
+
+ // Non-printable characters
+ case VirtualKey_Enter:
+ return Qt::Key_Enter;
+ case VirtualKey_Tab:
+ return Qt::Key_Tab;
+ case VirtualKey_Back:
+ return Qt::Key_Backspace;
+
+ // Modifiers
+ case VirtualKey_Shift:
+ case VirtualKey_LeftShift:
+ case VirtualKey_RightShift:
+ return Qt::Key_Shift;
+ case VirtualKey_Control:
+ case VirtualKey_LeftControl:
+ case VirtualKey_RightControl:
+ return Qt::Key_Control;
+ case VirtualKey_Menu:
+ case VirtualKey_LeftMenu:
+ case VirtualKey_RightMenu:
+ return Qt::Key_Alt;
+ case VirtualKey_LeftWindows:
+ case VirtualKey_RightWindows:
+ return Qt::Key_Meta;
+
+ // Toggle keys
+ case VirtualKey_CapitalLock:
+ return Qt::Key_CapsLock;
+ case VirtualKey_NumberKeyLock:
+ return Qt::Key_NumLock;
+ case VirtualKey_Scroll:
+ return Qt::Key_ScrollLock;
+
+ // East-Asian language keys
+ case VirtualKey_Kana:
+ //case VirtualKey_Hangul: // Same enum as Kana
+ return Qt::Key_Kana_Shift;
+ case VirtualKey_Junja:
+ return Qt::Key_Hangul_Jeonja;
+ case VirtualKey_Kanji:
+ //case VirtualKey_Hanja: // Same enum as Kanji
+ return Qt::Key_Kanji;
+ case VirtualKey_ModeChange:
+ return Qt::Key_Mode_switch;
+ case VirtualKey_Convert:
+ return Qt::Key_Henkan;
+ case VirtualKey_NonConvert:
+ return Qt::Key_Muhenkan;
+
+ // Misc. keys
+ case VirtualKey_Cancel:
+ return Qt::Key_Cancel;
+ case VirtualKey_Clear:
+ return Qt::Key_Clear;
+ case VirtualKey_Application:
+ return Qt::Key_ApplicationLeft;
+ case VirtualKey_Sleep:
+ return Qt::Key_Sleep;
+ case VirtualKey_Pause:
+ return Qt::Key_Pause;
+ case VirtualKey_PageUp:
+ return Qt::Key_PageUp;
+ case VirtualKey_PageDown:
+ return Qt::Key_PageDown;
+ case VirtualKey_End:
+ return Qt::Key_End;
+ case VirtualKey_Home:
+ return Qt::Key_Home;
+ case VirtualKey_Left:
+ return Qt::Key_Left;
+ case VirtualKey_Up:
+ return Qt::Key_Up;
+ case VirtualKey_Right:
+ return Qt::Key_Right;
+ case VirtualKey_Down:
+ return Qt::Key_Down;
+ case VirtualKey_Select:
+ return Qt::Key_Select;
+ case VirtualKey_Print:
+ return Qt::Key_Print;
+ case VirtualKey_Execute:
+ return Qt::Key_Execute;
+ case VirtualKey_Insert:
+ return Qt::Key_Insert;
+ case VirtualKey_Delete:
+ return Qt::Key_Delete;
+ case VirtualKey_Help:
+ return Qt::Key_Help;
+ case VirtualKey_Snapshot:
+ return Qt::Key_Camera;
+ case VirtualKey_Escape:
+ return Qt::Key_Escape;
+
+ // Function Keys
+ case VirtualKey_F1:
+ return Qt::Key_F1;
+ case VirtualKey_F2:
+ return Qt::Key_F2;
+ case VirtualKey_F3:
+ return Qt::Key_F3;
+ case VirtualKey_F4:
+ return Qt::Key_F4;
+ case VirtualKey_F5:
+ return Qt::Key_F5;
+ case VirtualKey_F6:
+ return Qt::Key_F6;
+ case VirtualKey_F7:
+ return Qt::Key_F7;
+ case VirtualKey_F8:
+ return Qt::Key_F8;
+ case VirtualKey_F9:
+ return Qt::Key_F9;
+ case VirtualKey_F10:
+ return Qt::Key_F10;
+ case VirtualKey_F11:
+ return Qt::Key_F11;
+ case VirtualKey_F12:
+ return Qt::Key_F12;
+ case VirtualKey_F13:
+ return Qt::Key_F13;
+ case VirtualKey_F14:
+ return Qt::Key_F14;
+ case VirtualKey_F15:
+ return Qt::Key_F15;
+ case VirtualKey_F16:
+ return Qt::Key_F16;
+ case VirtualKey_F17:
+ return Qt::Key_F17;
+ case VirtualKey_F18:
+ return Qt::Key_F18;
+ case VirtualKey_F19:
+ return Qt::Key_F19;
+ case VirtualKey_F20:
+ return Qt::Key_F20;
+ case VirtualKey_F21:
+ return Qt::Key_F21;
+ case VirtualKey_F22:
+ return Qt::Key_F22;
+ case VirtualKey_F23:
+ return Qt::Key_F23;
+ case VirtualKey_F24:
+ return Qt::Key_F24;
+
+ // Character keys
+ case VirtualKey_Space:
+ return Qt::Key_Space;
+ case VirtualKey_Number0:
+ case VirtualKey_NumberPad0:
+ return Qt::Key_0;
+ case VirtualKey_Number1:
+ case VirtualKey_NumberPad1:
+ return Qt::Key_1;
+ case VirtualKey_Number2:
+ case VirtualKey_NumberPad2:
+ return Qt::Key_2;
+ case VirtualKey_Number3:
+ case VirtualKey_NumberPad3:
+ return Qt::Key_3;
+ case VirtualKey_Number4:
+ case VirtualKey_NumberPad4:
+ return Qt::Key_4;
+ case VirtualKey_Number5:
+ case VirtualKey_NumberPad5:
+ return Qt::Key_5;
+ case VirtualKey_Number6:
+ case VirtualKey_NumberPad6:
+ return Qt::Key_6;
+ case VirtualKey_Number7:
+ case VirtualKey_NumberPad7:
+ return Qt::Key_7;
+ case VirtualKey_Number8:
+ case VirtualKey_NumberPad8:
+ return Qt::Key_8;
+ case VirtualKey_Number9:
+ case VirtualKey_NumberPad9:
+ return Qt::Key_9;
+ case VirtualKey_A:
+ return Qt::Key_A;
+ case VirtualKey_B:
+ return Qt::Key_B;
+ case VirtualKey_C:
+ return Qt::Key_C;
+ case VirtualKey_D:
+ return Qt::Key_D;
+ case VirtualKey_E:
+ return Qt::Key_E;
+ case VirtualKey_F:
+ return Qt::Key_F;
+ case VirtualKey_G:
+ return Qt::Key_G;
+ case VirtualKey_H:
+ return Qt::Key_H;
+ case VirtualKey_I:
+ return Qt::Key_I;
+ case VirtualKey_J:
+ return Qt::Key_J;
+ case VirtualKey_K:
+ return Qt::Key_K;
+ case VirtualKey_L:
+ return Qt::Key_L;
+ case VirtualKey_M:
+ return Qt::Key_M;
+ case VirtualKey_N:
+ return Qt::Key_N;
+ case VirtualKey_O:
+ return Qt::Key_O;
+ case VirtualKey_P:
+ return Qt::Key_P;
+ case VirtualKey_Q:
+ return Qt::Key_Q;
+ case VirtualKey_R:
+ return Qt::Key_R;
+ case VirtualKey_S:
+ return Qt::Key_S;
+ case VirtualKey_T:
+ return Qt::Key_T;
+ case VirtualKey_U:
+ return Qt::Key_U;
+ case VirtualKey_V:
+ return Qt::Key_V;
+ case VirtualKey_W:
+ return Qt::Key_W;
+ case VirtualKey_X:
+ return Qt::Key_X;
+ case VirtualKey_Y:
+ return Qt::Key_Y;
+ case VirtualKey_Z:
+ return Qt::Key_Z;
+ case VirtualKey_Multiply:
+ return Qt::Key_9;
+ case VirtualKey_Add:
+ return Qt::Key_9;
+ case VirtualKey_Separator:
+ return Qt::Key_9;
+ case VirtualKey_Subtract:
+ return Qt::Key_9;
+ case VirtualKey_Decimal:
+ return Qt::Key_9;
+ case VirtualKey_Divide:
+ return Qt::Key_9;
+
+ /* Keys with no matching Qt enum (?)
+ case VirtualKey_None:
+ case VirtualKey_LeftButton:
+ case VirtualKey_RightButton:
+ case VirtualKey_MiddleButton:
+ case VirtualKey_XButton1:
+ case VirtualKey_XButton2:
+ case VirtualKey_Final:
+ case VirtualKey_Accept:*/
+ }
+}
+
+static inline Qt::Key qKeyFromCode(quint32 code, int mods)
+{
+ if (code >= 'a' && code <= 'z')
+ code = toupper(code);
+ if ((mods & Qt::ControlModifier) != 0) {
+ if (code >= 0 && code <= 31) // Ctrl+@..Ctrl+A..CTRL+Z..Ctrl+_
+ code += '@'; // to @..A..Z.._
+ }
+ return static_cast<Qt::Key>(code & 0xff);
+}
+
+QWinRTScreen::QWinRTScreen(ICoreWindow *window)
+ : m_coreWindow(window)
+ , m_depth(32)
+ , m_format(QImage::Format_ARGB32_Premultiplied)
+#ifdef Q_OS_WINPHONE
+ , m_inputContext(new QWinRTInputContext(m_coreWindow))
+#else
+ , m_inputContext(Make<QWinRTInputContext>(m_coreWindow).Detach())
+#endif
+ , m_cursor(new QWinRTCursor(window))
+ , m_orientation(Qt::PrimaryOrientation)
+{
+#ifdef Q_OS_WINPHONE // On phone, there can be only one touch device
+ QTouchDevice *touchDevice = new QTouchDevice;
+ touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ touchDevice->setType(QTouchDevice::TouchScreen);
+ touchDevice->setName(QStringLiteral("WinPhoneTouchScreen"));
+ Pointer pointer = { Pointer::TouchScreen, touchDevice };
+ m_pointers.insert(0, pointer);
+ QWindowSystemInterface::registerTouchDevice(touchDevice);
+#endif
+
+ Rect rect;
+ window->get_Bounds(&rect);
+ m_geometry = QRect(0, 0, rect.Width, rect.Height);
+
+ m_surfaceFormat.setAlphaBufferSize(0);
+ m_surfaceFormat.setRedBufferSize(8);
+ m_surfaceFormat.setGreenBufferSize(8);
+ m_surfaceFormat.setBlueBufferSize(8);
+
+ m_surfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
+ m_surfaceFormat.setSamples(1);
+ m_surfaceFormat.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
+ m_surfaceFormat.setDepthBufferSize(24);
+ m_surfaceFormat.setStencilBufferSize(8);
+
+ m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (m_eglDisplay == EGL_NO_DISPLAY)
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL display.");
+
+ if (!eglInitialize(m_eglDisplay, NULL, NULL))
+ qFatal("Qt WinRT platform plugin: failed to initialize EGL. This can happen if you haven't included the D3D compiler DLL in your application package.");
+
+ // TODO: move this to Window
+ m_eglSurface = eglCreateWindowSurface(m_eglDisplay, q_configFromGLFormat(m_eglDisplay, m_surfaceFormat), window, NULL);
+ if (m_eglSurface == EGL_NO_SURFACE)
+ qFatal("Could not create EGL surface, error 0x%X", eglGetError());
+
+ // Event handlers mapped to QEvents
+ m_coreWindow->add_KeyDown(Callback<KeyHandler>(this, &QWinRTScreen::onKeyDown).Get(), &m_tokens[QEvent::KeyPress]);
+ m_coreWindow->add_KeyUp(Callback<KeyHandler>(this, &QWinRTScreen::onKeyUp).Get(), &m_tokens[QEvent::KeyRelease]);
+ m_coreWindow->add_CharacterReceived(Callback<CharacterReceivedHandler>(this, &QWinRTScreen::onCharacterReceived).Get(), &m_tokens[QEvent::User]);
+ m_coreWindow->add_PointerEntered(Callback<PointerHandler>(this, &QWinRTScreen::onPointerEntered).Get(), &m_tokens[QEvent::Enter]);
+ m_coreWindow->add_PointerExited(Callback<PointerHandler>(this, &QWinRTScreen::onPointerExited).Get(), &m_tokens[QEvent::Leave]);
+ m_coreWindow->add_PointerMoved(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseMove]);
+ m_coreWindow->add_PointerPressed(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonPress]);
+ m_coreWindow->add_PointerReleased(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::MouseButtonRelease]);
+ m_coreWindow->add_PointerWheelChanged(Callback<PointerHandler>(this, &QWinRTScreen::onPointerUpdated).Get(), &m_tokens[QEvent::Wheel]);
+ m_coreWindow->add_SizeChanged(Callback<SizeChangedHandler>(this, &QWinRTScreen::onSizeChanged).Get(), &m_tokens[QEvent::Resize]);
+
+ // Window event handlers
+ m_coreWindow->add_Activated(Callback<ActivatedHandler>(this, &QWinRTScreen::onActivated).Get(), &m_tokens[QEvent::WindowActivate]);
+ m_coreWindow->add_Closed(Callback<ClosedHandler>(this, &QWinRTScreen::onClosed).Get(), &m_tokens[QEvent::WindowDeactivate]);
+ m_coreWindow->add_VisibilityChanged(Callback<VisibilityChangedHandler>(this, &QWinRTScreen::onVisibilityChanged).Get(), &m_tokens[QEvent::Show]);
+ m_coreWindow->add_AutomationProviderRequested(Callback<AutomationProviderRequestedHandler>(this, &QWinRTScreen::onAutomationProviderRequested).Get(), &m_tokens[QEvent::InputMethodQuery]);
+
+ // Orientation handling
+ if (SUCCEEDED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(),
+ &m_displayProperties))) {
+ // Set native orientation
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_NativeOrientation(&displayOrientation);
+ m_nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+
+ // Set initial orientation
+ onOrientationChanged(0);
+
+ m_displayProperties->add_OrientationChanged(Callback<IDisplayPropertiesEventHandler>(this, &QWinRTScreen::onOrientationChanged).Get(),
+ &m_tokens[QEvent::OrientationChange]);
+ }
+
+#ifndef Q_OS_WINPHONE
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_ViewManagement_ApplicationView).Get(),
+ &m_applicationView);
+#endif
+
+
+ if (SUCCEEDED(RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ IID_PPV_ARGS(&m_application)))) {
+ m_application->add_Suspending(Callback<SuspendHandler>(this, &QWinRTScreen::onSuspended).Get(), &m_suspendTokens[Qt::ApplicationSuspended]);
+ m_application->add_Resuming(Callback<ResumeHandler>(this, &QWinRTScreen::onResume).Get(), &m_suspendTokens[Qt::ApplicationHidden]);
+ }
+}
+
+QRect QWinRTScreen::geometry() const
+{
+ return m_geometry;
+}
+
+int QWinRTScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QWinRTScreen::format() const
+{
+ return m_format;
+}
+
+QSurfaceFormat QWinRTScreen::surfaceFormat() const
+{
+ return m_surfaceFormat;
+}
+
+QWinRTInputContext *QWinRTScreen::inputContext() const
+{
+ return m_inputContext;
+}
+
+QPlatformCursor *QWinRTScreen::cursor() const
+{
+ return m_cursor;
+}
+
+Qt::KeyboardModifiers QWinRTScreen::keyboardModifiers() const
+{
+ Qt::KeyboardModifiers mods;
+ CoreVirtualKeyStates mod;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Shift, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ShiftModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Menu, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::AltModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_Control, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::ControlModifier;
+ m_coreWindow->GetAsyncKeyState(VirtualKey_LeftWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down) {
+ mods |= Qt::MetaModifier;
+ } else {
+ m_coreWindow->GetAsyncKeyState(VirtualKey_RightWindows, &mod);
+ if (mod == CoreVirtualKeyStates_Down)
+ mods |= Qt::MetaModifier;
+ }
+ return mods;
+}
+
+Qt::ScreenOrientation QWinRTScreen::nativeOrientation() const
+{
+ return m_nativeOrientation;
+}
+
+Qt::ScreenOrientation QWinRTScreen::orientation() const
+{
+ return m_orientation;
+}
+
+void QWinRTScreen::setOrientationUpdateMask(Qt::ScreenOrientations mask)
+{
+ m_displayProperties->put_AutoRotationPreferences(nativeOrientationsFromQt(mask));
+}
+
+ICoreWindow *QWinRTScreen::coreWindow() const
+{
+ return m_coreWindow;
+}
+
+EGLDisplay QWinRTScreen::eglDisplay() const
+{
+ return m_eglDisplay;
+}
+
+EGLSurface QWinRTScreen::eglSurface() const
+{
+ return m_eglSurface;
+}
+
+QWindow *QWinRTScreen::topWindow() const
+{
+ return m_visibleWindows.isEmpty() ? 0 : m_visibleWindows.first();
+}
+
+void QWinRTScreen::addWindow(QWindow *window)
+{
+ if (window == topWindow())
+ return;
+ m_visibleWindows.prepend(window);
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::removeWindow(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (!m_visibleWindows.removeAll(window))
+ return;
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::raise(QWindow *window)
+{
+ m_visibleWindows.removeAll(window);
+ addWindow(window);
+}
+
+void QWinRTScreen::lower(QWindow *window)
+{
+ const bool wasTopWindow = window == topWindow();
+ if (wasTopWindow && m_visibleWindows.size() == 1)
+ return;
+ m_visibleWindows.removeAll(window);
+ m_visibleWindows.append(window);
+ if (wasTopWindow)
+ QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason);
+ handleExpose();
+}
+
+void QWinRTScreen::handleExpose()
+{
+ if (m_visibleWindows.isEmpty())
+ return;
+ QList<QWindow *>::const_iterator it = m_visibleWindows.constBegin();
+ QWindowSystemInterface::handleExposeEvent(*it, m_geometry);
+ while (++it != m_visibleWindows.constEnd())
+ QWindowSystemInterface::handleExposeEvent(*it, QRegion());
+ QWindowSystemInterface::flushWindowSystemEvents();
+}
+
+HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+{
+ Q_UNUSED(window);
+ VirtualKey virtualKey;
+ args->get_VirtualKey(&virtualKey);
+ Qt::Key key = qKeyFromVirtual(virtualKey);
+ // Defer character key presses to onCharacterReceived
+ if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis))
+ return S_OK;
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, keyboardModifiers());
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args)
+{
+ Q_UNUSED(window);
+ Qt::KeyboardModifiers mods = keyboardModifiers();
+#ifndef Q_OS_WINPHONE
+ CorePhysicalKeyStatus status; // Look for a pressed character key
+ if (SUCCEEDED(args->get_KeyStatus(&status)) && m_activeKeys.contains(status.ScanCode)) {
+ QPair<Qt::Key, QString> keyStatus = m_activeKeys.take(status.ScanCode);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
+ keyStatus.first, mods, keyStatus.second);
+ return S_OK;
+ }
+#endif // !Q_OS_WINPHONE
+ VirtualKey virtualKey;
+ args->get_VirtualKey(&virtualKey);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease,
+ qKeyFromVirtual(virtualKey), mods);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *window, ICharacterReceivedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ quint32 keyCode;
+ args->get_KeyCode(&keyCode);
+ // Don't generate character events for non-printables; the meta key stage is enough
+ if (qIsNonPrintable(keyCode))
+ return S_OK;
+
+ Qt::KeyboardModifiers mods = keyboardModifiers();
+ Qt::Key key = qKeyFromCode(keyCode, mods);
+ QString text = QChar(keyCode);
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyPress, key, mods, text);
+#ifndef Q_OS_WINPHONE
+ CorePhysicalKeyStatus status; // Defer release to onKeyUp for physical keys
+ if (SUCCEEDED(args->get_KeyStatus(&status)) && !status.IsKeyReleased) {
+ m_activeKeys.insert(status.ScanCode, qMakePair(key, text));
+ return S_OK;
+ }
+#endif // !Q_OS_WINPHONE
+ QWindowSystemInterface::handleKeyEvent(topWindow(), QEvent::KeyRelease, key, mods, text);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ IPointerPoint *pointerPoint;
+ if (SUCCEEDED(args->get_CurrentPoint(&pointerPoint))) {
+ // Assumes full-screen window
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPoint pos(point.X, point.Y);
+
+ QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
+ pointerPoint->Release();
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerExited(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+ QWindowSystemInterface::handleLeaveEvent(0);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *window, IPointerEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ IPointerPoint *pointerPoint;
+ if (FAILED(args->get_CurrentPoint(&pointerPoint)))
+ return E_INVALIDARG;
+
+ // Common traits - point, modifiers, properties
+ Point point;
+ pointerPoint->get_Position(&point);
+ QPointF pos(point.X, point.Y);
+
+ VirtualKeyModifiers modifiers;
+ args->get_KeyModifiers(&modifiers);
+ Qt::KeyboardModifiers mods;
+ if (modifiers & VirtualKeyModifiers_Control)
+ mods |= Qt::ControlModifier;
+ if (modifiers & VirtualKeyModifiers_Menu)
+ mods |= Qt::AltModifier;
+ if (modifiers & VirtualKeyModifiers_Shift)
+ mods |= Qt::ShiftModifier;
+ if (modifiers & VirtualKeyModifiers_Windows)
+ mods |= Qt::MetaModifier;
+
+ IPointerPointProperties *properties;
+ if (FAILED(pointerPoint->get_Properties(&properties)))
+ return E_INVALIDARG;
+
+#ifdef Q_OS_WINPHONE
+ quint32 pointerId = 0;
+ Pointer pointer = m_pointers.value(pointerId);
+#else
+ Pointer pointer = { Pointer::Unknown, 0 };
+ quint32 pointerId;
+ pointerPoint->get_PointerId(&pointerId);
+ if (m_pointers.contains(pointerId)) {
+ pointer = m_pointers.value(pointerId);
+ } else { // We have not yet enumerated this device. Do so now...
+ IPointerDevice *device;
+ if (SUCCEEDED(pointerPoint->get_PointerDevice(&device))) {
+ PointerDeviceType type;
+ device->get_PointerDeviceType(&type);
+ switch (type) {
+ case PointerDeviceType_Touch:
+ pointer.type = Pointer::TouchScreen;
+ pointer.device = new QTouchDevice;
+ pointer.device->setName(QStringLiteral("WinRT TouchScreen ") + QString::number(pointerId));
+ // TODO: We may want to probe the device usage flags for more accurate values for these next two
+ pointer.device->setType(QTouchDevice::TouchScreen);
+ pointer.device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure);
+ QWindowSystemInterface::registerTouchDevice(pointer.device);
+ break;
+
+ case PointerDeviceType_Pen:
+ pointer.type = Pointer::Tablet;
+ break;
+
+ case PointerDeviceType_Mouse:
+ pointer.type = Pointer::Mouse;
+ break;
+ }
+
+ m_pointers.insert(pointerId, pointer);
+ device->Release();
+ }
+ }
+#endif
+ switch (pointer.type) {
+ case Pointer::Mouse: {
+ qint32 delta;
+ properties->get_MouseWheelDelta(&delta);
+ if (delta) {
+ boolean isHorizontal;
+ properties->get_IsHorizontalMouseWheel(&isHorizontal);
+ QPoint angleDelta(isHorizontal ? delta : 0, isHorizontal ? 0 : delta);
+ QWindowSystemInterface::handleWheelEvent(topWindow(), pos, pos, QPoint(), angleDelta, mods);
+ break;
+ }
+
+ boolean isPressed;
+ Qt::MouseButtons buttons = Qt::NoButton;
+ properties->get_IsLeftButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::LeftButton;
+
+ properties->get_IsMiddleButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::MiddleButton;
+
+ properties->get_IsRightButtonPressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::RightButton;
+
+ properties->get_IsXButton1Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton1;
+
+ properties->get_IsXButton2Pressed(&isPressed);
+ if (isPressed)
+ buttons |= Qt::XButton2;
+
+ QWindowSystemInterface::handleMouseEvent(topWindow(), pos, pos, buttons, mods);
+
+ break;
+ }
+ case Pointer::TouchScreen: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ Rect area;
+ properties->get_ContactRect(&area);
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator it = m_touchPoints.find(id);
+ if (it != m_touchPoints.end()) {
+ boolean isPressed;
+#ifndef Q_OS_WINPHONE
+ pointerPoint->get_IsInContact(&isPressed);
+#else
+ properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
+#endif
+ it.value().state = isPressed ? Qt::TouchPointMoved : Qt::TouchPointReleased;
+ } else {
+ it = m_touchPoints.insert(id, QWindowSystemInterface::TouchPoint());
+ it.value().state = Qt::TouchPointPressed;
+ it.value().id = id;
+ }
+ it.value().area = QRectF(area.X, area.Y, area.Width, area.Height);
+ it.value().normalPosition = QPointF(pos.x()/m_geometry.width(), pos.y()/m_geometry.height());
+ it.value().pressure = pressure;
+
+ QWindowSystemInterface::handleTouchEvent(topWindow(), pointer.device, m_touchPoints.values(), mods);
+
+ // Remove released points, station others
+ for (QHash<quint32, QWindowSystemInterface::TouchPoint>::iterator i = m_touchPoints.begin(); i != m_touchPoints.end();) {
+ if (i.value().state == Qt::TouchPointReleased)
+ i = m_touchPoints.erase(i);
+ else
+ (i++).value().state = Qt::TouchPointStationary;
+ }
+
+ break;
+ }
+ case Pointer::Tablet: {
+ quint32 id;
+ pointerPoint->get_PointerId(&id);
+
+ boolean isPressed;
+ pointerPoint->get_IsInContact(&isPressed);
+
+ boolean isEraser;
+ properties->get_IsEraser(&isEraser);
+ int pointerType = isEraser ? 3 : 1;
+
+ float pressure;
+ properties->get_Pressure(&pressure);
+
+ float xTilt;
+ properties->get_XTilt(&xTilt);
+
+ float yTilt;
+ properties->get_YTilt(&yTilt);
+
+ float rotation;
+ properties->get_Twist(&rotation);
+
+ QWindowSystemInterface::handleTabletEvent(topWindow(), isPressed, pos, pos, pointerId,
+ pointerType, pressure, xTilt, yTilt,
+ 0, rotation, 0, id, mods);
+
+ break;
+ }
+ }
+
+ properties->Release();
+ pointerPoint->Release();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onAutomationProviderRequested(ICoreWindow *, IAutomationProviderRequestedEventArgs *args)
+{
+#ifndef Q_OS_WINPHONE
+ args->put_AutomationProvider(m_inputContext);
+#endif
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *window, IWindowSizeChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ Size size;
+ if (FAILED(args->get_Size(&size))) {
+ qWarning(Q_FUNC_INFO ": failed to get size");
+ return S_OK;
+ }
+
+ // Regardless of state, all top-level windows are viewport-sized - this might change if
+ // a more advanced compositor is written.
+ m_geometry.setSize(QSize(size.Width, size.Height));
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_geometry);
+ QPlatformScreen::resizeMaximizedWindows();
+ handleExpose();
+
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onActivated(ICoreWindow *window, IWindowActivatedEventArgs *args)
+{
+ Q_UNUSED(window);
+
+ CoreWindowActivationState activationState;
+ args->get_WindowActivationState(&activationState);
+ if (activationState == CoreWindowActivationState_Deactivated) {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ return S_OK;
+ }
+
+ // Activate topWindow
+ if (!m_visibleWindows.isEmpty()) {
+ Qt::FocusReason focusReason = activationState == CoreWindowActivationState_PointerActivated
+ ? Qt::MouseFocusReason : Qt::ActiveWindowFocusReason;
+ QWindowSystemInterface::handleWindowActivated(topWindow(), focusReason);
+ }
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
+{
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ QWindowSystemInterface::flushWindowSystemEvents();
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onResume(IInspectable *, IInspectable *)
+{
+ // First the system invokes onResume and then changes
+ // the visibility of the screen to be active.
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationHidden);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onClosed(ICoreWindow *window, ICoreWindowEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ foreach (QWindow *w, QGuiApplication::topLevelWindows())
+ QWindowSystemInterface::handleCloseEvent(w);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *window, IVisibilityChangedEventArgs *args)
+{
+ Q_UNUSED(window);
+ Q_UNUSED(args);
+
+ boolean visible;
+ args->get_Visible(&visible);
+ QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
+ return S_OK;
+}
+
+HRESULT QWinRTScreen::onOrientationChanged(IInspectable *)
+{
+ DisplayOrientations displayOrientation;
+ m_displayProperties->get_CurrentOrientation(&displayOrientation);
+ Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
+ if (m_orientation != newOrientation) {
+ m_orientation = newOrientation;
+ QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation);
+ }
+
+ return S_OK;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h
new file mode 100644
index 0000000000..3131f879b5
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtscreen.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSCREEN_H
+#define QWINRTSCREEN_H
+
+#include <qpa/qplatformscreen.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtCore/QHash>
+#include <QtGui/QSurfaceFormat>
+#include <EGL/egl.h>
+
+#include <EventToken.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace ApplicationModel {
+ struct ISuspendingEventArgs;
+ namespace Core {
+ struct ICoreApplication;
+ }
+ }
+ namespace UI {
+ namespace Core {
+ struct IAutomationProviderRequestedEventArgs;
+ struct ICharacterReceivedEventArgs;
+ struct ICoreWindow;
+ struct ICoreWindowEventArgs;
+ struct IKeyEventArgs;
+ struct IPointerEventArgs;
+ struct IVisibilityChangedEventArgs;
+ struct IWindowActivatedEventArgs;
+ struct IWindowSizeChangedEventArgs;
+ }
+ namespace ViewManagement {
+ struct IApplicationViewStatics;
+ }
+ }
+ namespace Graphics {
+ namespace Display {
+ struct IDisplayPropertiesStatics;
+ }
+ }
+ }
+}
+struct IInspectable;
+
+QT_BEGIN_NAMESPACE
+
+class QTouchDevice;
+class QWinRTEGLContext;
+class QWinRTPageFlipper;
+class QWinRTCursor;
+class QWinRTInputContext;
+
+struct Pointer {
+ enum Type { Unknown, Mouse, TouchScreen, Tablet };
+ Type type;
+ QTouchDevice *device;
+};
+
+class QWinRTScreen : public QPlatformScreen
+{
+public:
+ explicit QWinRTScreen(ABI::Windows::UI::Core::ICoreWindow *window);
+ QRect geometry() const;
+ int depth() const;
+ QImage::Format format() const;
+ QSurfaceFormat surfaceFormat() const;
+ QWinRTInputContext *inputContext() const;
+ QPlatformCursor *cursor() const;
+ Qt::KeyboardModifiers keyboardModifiers() const;
+
+ Qt::ScreenOrientation nativeOrientation() const;
+ Qt::ScreenOrientation orientation() const;
+ void setOrientationUpdateMask(Qt::ScreenOrientations mask);
+
+ QWindow *topWindow() const;
+ void addWindow(QWindow *window);
+ void removeWindow(QWindow *window);
+ void raise(QWindow *window);
+ void lower(QWindow *window);
+
+ ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
+ EGLDisplay eglDisplay() const; // To opengl context
+ EGLSurface eglSurface() const; // To window
+
+private:
+ void handleExpose();
+
+ // Event handlers
+ QHash<QEvent::Type, EventRegistrationToken> m_tokens;
+ QHash<Qt::ApplicationState, EventRegistrationToken> m_suspendTokens;
+
+ HRESULT onKeyDown(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
+ HRESULT onKeyUp(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IKeyEventArgs *args);
+ HRESULT onCharacterReceived(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::ICharacterReceivedEventArgs *args);
+ HRESULT onPointerEntered(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerExited(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onPointerUpdated(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IPointerEventArgs *args);
+ HRESULT onSizeChanged(ABI::Windows::UI::Core::ICoreWindow *window, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *args);
+
+ HRESULT onActivated(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IWindowActivatedEventArgs *args);
+ HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *);
+ HRESULT onResume(IInspectable *, IInspectable *);
+
+ HRESULT onClosed(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::ICoreWindowEventArgs *args);
+ HRESULT onVisibilityChanged(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IVisibilityChangedEventArgs *args);
+ HRESULT onAutomationProviderRequested(ABI::Windows::UI::Core::ICoreWindow *, ABI::Windows::UI::Core::IAutomationProviderRequestedEventArgs *args);
+
+ HRESULT onOrientationChanged(IInspectable *);
+
+ ABI::Windows::UI::Core::ICoreWindow *m_coreWindow;
+ ABI::Windows::UI::ViewManagement::IApplicationViewStatics *m_applicationView;
+ ABI::Windows::ApplicationModel::Core::ICoreApplication *m_application;
+ QRect m_geometry;
+ QImage::Format m_format;
+ QSurfaceFormat m_surfaceFormat;
+ int m_depth;
+ QWinRTInputContext *m_inputContext;
+ QWinRTCursor *m_cursor;
+ QList<QWindow *> m_visibleWindows;
+
+ EGLDisplay m_eglDisplay;
+ EGLSurface m_eglSurface;
+
+ ABI::Windows::Graphics::Display::IDisplayPropertiesStatics *m_displayProperties;
+ Qt::ScreenOrientation m_nativeOrientation;
+ Qt::ScreenOrientation m_orientation;
+
+#ifndef Q_OS_WINPHONE
+ QHash<quint32, QPair<Qt::Key, QString> > m_activeKeys;
+#endif
+ QHash<quint32, Pointer> m_pointers;
+ QHash<quint32, QWindowSystemInterface::TouchPoint> m_touchPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSCREEN_H
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
new file mode 100644
index 0000000000..8f0a1d55bb
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtservices.h"
+#include <QtCore/QUrl>
+#include <QtCore/QDir>
+#include <QtCore/QCoreApplication>
+
+#include <wrl.h>
+#include <windows.foundation.h>
+#include <windows.storage.h>
+#include <windows.system.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Storage;
+using namespace ABI::Windows::System;
+
+QT_BEGIN_NAMESPACE
+
+QWinRTServices::QWinRTServices()
+{
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Uri).Get(), &m_uriFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFile).Get(), &m_fileFactory);
+ GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Launcher).Get(), &m_launcher);
+}
+
+QWinRTServices::~QWinRTServices()
+{
+ if (m_uriFactory)
+ m_uriFactory->Release();
+
+ if (m_fileFactory)
+ m_fileFactory->Release();
+
+ if (m_launcher)
+ m_launcher->Release();
+}
+
+bool QWinRTServices::openUrl(const QUrl &url)
+{
+ if (!(m_uriFactory && m_launcher))
+ return QPlatformServices::openUrl(url);
+
+ IUriRuntimeClass *uri;
+ QString urlString = url.toString(); HSTRING uriString; HSTRING_HEADER header;
+ WindowsCreateStringReference((const wchar_t*)urlString.utf16(), urlString.length(), &header, &uriString);
+ m_uriFactory->CreateUri(uriString, &uri);
+ if (!uri)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchUriAsync(uri, &launchOp);
+ uri->Release();
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+bool QWinRTServices::openDocument(const QUrl &url)
+{
+ if (!(m_fileFactory && m_launcher))
+ return QPlatformServices::openDocument(url);
+
+ QString pathString = QDir::toNativeSeparators(
+ QDir::cleanPath(qApp->applicationDirPath().append(url.toString(QUrl::RemoveScheme))));
+ HSTRING_HEADER header; HSTRING path;
+ WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
+ IAsyncOperation<StorageFile*> *fileOp;
+ m_fileFactory->GetFileFromPathAsync(path, &fileOp);
+ if (!fileOp)
+ return false;
+
+ IStorageFile *file = nullptr;
+ while (fileOp->GetResults(&file) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ fileOp->Release();
+ if (!file)
+ return false;
+
+ IAsyncOperation<bool> *launchOp;
+ m_launcher->LaunchFileAsync(file, &launchOp);
+ if (!launchOp)
+ return false;
+
+ boolean result = false;
+ while (launchOp->GetResults(&result) == E_ILLEGAL_METHOD_CALL)
+ QCoreApplication::processEvents();
+ launchOp->Release();
+
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.h b/src/plugins/platforms/winrt/qwinrtservices.h
new file mode 100644
index 0000000000..9cc917030a
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtservices.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINRTSERVICES_H
+#define QWINRTSERVICES_H
+
+#include <qpa/qplatformservices.h>
+
+namespace ABI {
+ namespace Windows {
+ namespace Foundation {
+ struct IUriRuntimeClassFactory;
+ }
+ namespace Storage {
+ struct IStorageFileStatics;
+ }
+ namespace System {
+ struct ILauncherStatics;
+ }
+ }
+}
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTServices : public QPlatformServices
+{
+public:
+ explicit QWinRTServices();
+ ~QWinRTServices();
+
+ bool openUrl(const QUrl &url);
+ bool openDocument(const QUrl &url);
+
+private:
+ ABI::Windows::Foundation::IUriRuntimeClassFactory *m_uriFactory;
+ ABI::Windows::Storage::IStorageFileStatics *m_fileFactory;
+ ABI::Windows::System::ILauncherStatics *m_launcher;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINRTSERVICES_H
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
new file mode 100644
index 0000000000..88b753b463
--- /dev/null
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwinrtwindow.h"
+#include "qwinrtscreen.h"
+
+#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatformscreen.h>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+
+QT_BEGIN_NAMESPACE
+
+QWinRTWindow::QWinRTWindow(QWindow *window)
+ : QPlatformWindow(window)
+ , m_screen(static_cast<QWinRTScreen*>(screen()))
+{
+ setWindowFlags(window->flags());
+ setWindowState(window->windowState());
+ handleContentOrientationChange(window->contentOrientation());
+ setGeometry(window->geometry());
+}
+
+QWinRTWindow::~QWinRTWindow()
+{
+ m_screen->removeWindow(window());
+}
+
+QSurfaceFormat QWinRTWindow::format() const
+{
+ return m_screen->surfaceFormat();
+}
+
+bool QWinRTWindow::isActive() const
+{
+ return m_screen->topWindow() == window();
+}
+
+bool QWinRTWindow::isExposed() const
+{
+ const bool exposed = isActive();
+ return exposed;
+}
+
+void QWinRTWindow::setGeometry(const QRect &rect)
+{
+ if (window()->isTopLevel()) {
+ QPlatformWindow::setGeometry(m_screen->geometry());
+ QWindowSystemInterface::handleGeometryChange(window(), geometry());
+ } else {
+ QPlatformWindow::setGeometry(rect);
+ QWindowSystemInterface::handleGeometryChange(window(), rect);
+ }
+}
+
+void QWinRTWindow::setVisible(bool visible)
+{
+ if (!window()->isTopLevel())
+ return;
+ if (visible)
+ m_screen->addWindow(window());
+ else
+ m_screen->removeWindow(window());
+}
+
+void QWinRTWindow::raise()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->raise(window());
+}
+
+void QWinRTWindow::lower()
+{
+ if (!window()->isTopLevel())
+ return;
+ m_screen->lower(window());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h b/src/plugins/platforms/winrt/qwinrtwindow.h
index 9e3f203201..1f19b4f2d5 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformwindow.h
+++ b/src/plugins/platforms/winrt/qwinrtwindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -39,26 +39,34 @@
**
****************************************************************************/
-#ifndef ANDROIDPLATFORMWINDOW_H
-#define ANDROIDPLATFORMWINDOW_H
-#include <qobject.h>
-#include <QtPlatformSupport/private/qfbwindow_p.h>
+#ifndef QWINRTWINDOW_H
+#define QWINRTWINDOW_H
-class QAndroidPlatformWindow: public QObject, public QFbWindow
+#include <qpa/qplatformwindow.h>
+#include <qpa/qwindowsysteminterface.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWinRTScreen;
+
+class QWinRTWindow : public QPlatformWindow
{
- Q_OBJECT
public:
- explicit QAndroidPlatformWindow(QWindow *window);
+ QWinRTWindow(QWindow *window);
+ ~QWinRTWindow();
- void propagateSizeHints();
-
- void raise();
- void setWindowState(Qt::WindowState state);
+ QSurfaceFormat format() const;
+ bool isActive() const;
+ bool isExposed() const;
+ void setGeometry(const QRect &rect);
void setVisible(bool visible);
- void updateStatusBarVisibility();
+ void raise();
+ void lower();
-public slots:
- void setGeometry(const QRect &rect);
+private:
+ QWinRTScreen *m_screen;
};
-#endif // ANDROIDPLATFORMWINDOW_H
+QT_END_NAMESPACE
+
+#endif // QWINRTWINDOW_H
diff --git a/src/plugins/platforms/winrt/winrt.json b/src/plugins/platforms/winrt/winrt.json
new file mode 100644
index 0000000000..962747b697
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "winrt" ]
+}
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
new file mode 100644
index 0000000000..3bd688c069
--- /dev/null
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -0,0 +1,64 @@
+TARGET = qwinrt
+CONFIG -= precompile_header
+
+PLUGIN_TYPE = platforms
+PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
+load(qt_plugin)
+
+QT += core-private gui-private platformsupport-private
+
+DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
+
+LIBS += $$QMAKE_LIBS_CORE -ldxgi
+
+SOURCES = \
+ main.cpp \
+ qwinrtbackingstore.cpp \
+ qwinrtcursor.cpp \
+ qwinrteglcontext.cpp \
+ qwinrteventdispatcher.cpp \
+ qwinrtfontdatabase.cpp \
+ qwinrtinputcontext.cpp \
+ qwinrtintegration.cpp \
+ qwinrtplatformmessagedialoghelper.cpp \
+ qwinrtplatformtheme.cpp \
+ qwinrtscreen.cpp \
+ qwinrtservices.cpp \
+ qwinrtwindow.cpp
+
+HEADERS = \
+ qwinrtbackingstore.h \
+ qwinrtcursor.h \
+ qwinrteglcontext.h \
+ qwinrteventdispatcher.h \
+ qwinrtfontdatabase.h \
+ qwinrtinputcontext.h \
+ qwinrtintegration.h \
+ qwinrtplatformmessagedialoghelper.h \
+ qwinrtplatformtheme.h \
+ qwinrtscreen.h \
+ qwinrtservices.h \
+ qwinrtwindow.h
+
+BLIT_INPUT = $$PWD/blit.hlsl
+fxc_blitps.commands = fxc.exe /nologo /T ps_4_0_level_9_1 /E blitps /Vn q_blitps /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitps.output = $$OUT_PWD/blitps.h
+fxc_blitps.input = BLIT_INPUT
+fxc_blitps.dependency_type = TYPE_C
+fxc_blitps.variable_out = HEADERS
+fxc_blitps.CONFIG += target_predeps
+fxc_blitvs.commands = fxc.exe /nologo /T vs_4_0_level_9_1 /E blitvs /Vn q_blitvs /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+fxc_blitvs.output = $$OUT_PWD/blitvs.h
+fxc_blitvs.input = BLIT_INPUT
+fxc_blitvs.dependency_type = TYPE_C
+fxc_blitvs.variable_out = HEADERS
+fxc_blitvs.CONFIG += target_predeps
+QMAKE_EXTRA_COMPILERS += fxc_blitps fxc_blitvs
+
+winphone {
+ SOURCES -= qwinrtplatformmessagedialoghelper.cpp
+ HEADERS -= qwinrtplatformmessagedialoghelper.h
+}
+
+OTHER_FILES += winrt.json \
+ blit.hlsl
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index e504d93fba..f7abb4662b 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -167,6 +167,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_shareContext(0)
, m_format(format)
, m_isPBufferCurrent(false)
+ , m_swapInterval(-1)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -326,19 +327,50 @@ QGLXContext::~QGLXContext()
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
- Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ bool success = false;
+ Q_ASSERT(surface->surface()->supportsOpenGL());
+ Display *dpy = DISPLAY_FROM_XCB(m_screen);
+ GLXDrawable glxDrawable = 0;
QSurface::SurfaceClass surfaceClass = surface->surface()->surfaceClass();
if (surfaceClass == QSurface::Window) {
m_isPBufferCurrent = false;
QXcbWindow *window = static_cast<QXcbWindow *>(surface);
- return glXMakeCurrent(DISPLAY_FROM_XCB(m_screen), window->xcb_window(), m_context);
+ glxDrawable = window->xcb_window();
+ success = glXMakeCurrent(dpy, glxDrawable, m_context);
} else if (surfaceClass == QSurface::Offscreen) {
m_isPBufferCurrent = true;
QGLXPbuffer *pbuffer = static_cast<QGLXPbuffer *>(surface);
- return glXMakeContextCurrent(DISPLAY_FROM_XCB(m_screen), pbuffer->pbuffer(), pbuffer->pbuffer(), m_context);
+ glxDrawable = pbuffer->pbuffer();
+ success = glXMakeContextCurrent(dpy, glxDrawable, glxDrawable, m_context);
+ }
+
+ if (success) {
+ int interval = surface->format().swapInterval();
+ if (interval >= 0 && m_swapInterval != interval) {
+ m_swapInterval = interval;
+ typedef void (*qt_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
+ typedef void (*qt_glXSwapIntervalMESA)(unsigned int);
+ static qt_glXSwapIntervalEXT glXSwapIntervalEXT = 0;
+ static qt_glXSwapIntervalMESA glXSwapIntervalMESA = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ resolved = true;
+ QList<QByteArray> glxExt = QByteArray(glXQueryExtensionsString(dpy,
+ m_screen->screenNumber())).split(' ');
+ if (glxExt.contains("GLX_EXT_swap_control"))
+ glXSwapIntervalEXT = (qt_glXSwapIntervalEXT) getProcAddress("glXSwapIntervalEXT");
+ if (glxExt.contains("GLX_MESA_swap_control"))
+ glXSwapIntervalMESA = (qt_glXSwapIntervalMESA) getProcAddress("glXSwapIntervalMESA");
+ }
+ if (glXSwapIntervalEXT)
+ glXSwapIntervalEXT(dpy, glxDrawable, interval);
+ else if (glXSwapIntervalMESA)
+ glXSwapIntervalMESA(interval);
+ }
}
- return false;
+
+ return success;
}
void QGLXContext::doneCurrent()
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index dcc7fe8855..00bba94ab3 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -81,7 +81,7 @@ private:
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
-
+ int m_swapInterval;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index e93b36cb99..1579797f85 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -232,9 +232,6 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
Q_XCB_NOOP(connection());
m_dirty = m_dirty | source;
-
- xcb_flush(xcb_connection());
- Q_XCB_NOOP(connection());
}
void QXcbShmImage::preparePaint(const QRegion &region)
@@ -283,6 +280,11 @@ void QXcbBackingStore::beginPaint(const QRegion &region)
}
}
+QImage QXcbBackingStore::toImage() const
+{
+ return m_image && m_image->image() ? *m_image->image() : QImage();
+}
+
void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
if (!m_image || m_image->size().isEmpty())
@@ -314,12 +316,32 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
if (m_syncingResize) {
+ connection()->sync();
+ m_syncingResize = false;
+ platformWindow->updateSyncRequestCounter();
+ } else {
xcb_flush(xcb_connection());
+ }
+}
+
+#ifndef QT_NO_OPENGL
+void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context)
+{
+ QPlatformBackingStore::composeAndFlush(window, region, offset, textures, context);
+
+ Q_XCB_NOOP(connection());
+
+ if (m_syncingResize) {
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
connection()->sync();
m_syncingResize = false;
platformWindow->updateSyncRequestCounter();
+ } else {
+ xcb_flush(xcb_connection());
}
}
+#endif // QT_NO_OPENGL
void QXcbBackingStore::resize(const QSize &size, const QRegion &)
{
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index d2548242db..19a5ac62d0 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -60,6 +60,11 @@ public:
QPaintDevice *paintDevice();
void flush(QWindow *window, const QRegion &region, const QPoint &offset);
+#ifndef QT_NO_OPENGL
+ void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, QOpenGLContext *context);
+#endif
+ QImage toImage() const;
void resize(const QSize &size, const QRegion &staticContents);
bool scroll(const QRegion &area, int dx, int dy);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 3c4ab8d3e2..030090d98d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -326,23 +326,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRandr();
updateScreens();
- m_connectionEventListener = xcb_generate_id(m_connection);
- xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
- m_connectionEventListener, m_screens.at(0)->root(),
- 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
- m_screens.at(0)->screen()->root_visual, 0, 0);
-#ifndef QT_NO_DEBUG
- QByteArray ba("Qt xcb connection listener window");
- Q_XCB_CALL(xcb_change_property(xcb_connection(),
- XCB_PROP_MODE_REPLACE,
- m_connectionEventListener,
- atom(QXcbAtom::_NET_WM_NAME),
- atom(QXcbAtom::UTF8_STRING),
- 8,
- ba.length(),
- ba.constData()));
-#endif
-
initializeGLX();
initializeXFixes();
initializeXRender();
@@ -379,9 +362,6 @@ QXcbConnection::~QXcbConnection()
#ifndef QT_NO_DRAGANDDROP
delete m_drag;
#endif
- // 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
finalizeXInput2Maemo();
@@ -396,6 +376,10 @@ QXcbConnection::~QXcbConnection()
delete m_reader;
+ // Delete screens in reverse order to avoid crash in case of multiple screens
+ while (!m_screens.isEmpty())
+ delete m_screens.takeLast();
+
#ifdef XCB_USE_EGL
if (m_has_egl)
eglTerminate(m_egl_display);
@@ -1081,14 +1065,21 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
xcb_client_message_event_t event;
memset(&event, 0, sizeof(event));
+ const xcb_window_t eventListener = xcb_generate_id(m_connection);
+ Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT,
+ eventListener, m_screens.at(0)->root(),
+ 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
+ m_screens.at(0)->screen()->root_visual, 0, 0));
+
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
- event.window = m_connectionEventListener;
+ event.window = eventListener;
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, m_connectionEventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
@@ -1163,6 +1154,7 @@ void QXcbConnection::processXcbEvents()
xcb_generic_event_t *event = eventqueue->at(i);
if (!event)
continue;
+ QScopedPointer<xcb_generic_event_t, QScopedPointerPodDeleter> eventGuard(event);
(*eventqueue)[i] = 0;
uint response_type = event->response_type & ~0x80;
@@ -1213,8 +1205,6 @@ void QXcbConnection::processXcbEvents()
handleXcbEvent(event);
m_reader->lock();
}
-
- free(event);
}
eventqueue->clear();
@@ -1450,6 +1440,10 @@ static const char * xcb_atomnames = {
"Abs Distance\0"
"Wacom Serial IDs\0"
"INTEGER\0"
+ "Rel Horiz Wheel\0"
+ "Rel Vert Wheel\0"
+ "Rel Horiz Scroll\0"
+ "Rel Vert Scroll\0"
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
"_MEEGOTOUCH_ORIENTATION_ANGLE\0"
#endif
@@ -1731,21 +1725,23 @@ bool QXcbConnection::hasEgl() const
#endif // defined(XCB_USE_EGL)
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
-// Borrowed from libXi.
-int QXcbConnection::xi2CountBits(unsigned char *ptr, int len)
+static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number)
{
- int bits = 0;
- int i;
- unsigned char x;
-
- for (i = 0; i < len; i++) {
- x = ptr[i];
- while (x > 0) {
- bits += (x & 0x1);
- x >>= 1;
+ int offset = 0;
+ for (int i = 0; i < maskLen; i++) {
+ if (number < 8) {
+ if ((maskPtr[i] & (1 << number)) == 0)
+ return -1;
}
+ for (int j = 0; j < 8; j++) {
+ if (j == number)
+ return offset;
+ if (maskPtr[i] & (1 << j))
+ offset++;
+ }
+ number -= 8;
}
- return bits;
+ return -1;
}
bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value)
@@ -1754,13 +1750,13 @@ bool QXcbConnection::xi2GetValuatorValueIfSet(void *event, int valuatorNum, doub
unsigned char *buttonsMaskAddr = (unsigned char*)&xideviceevent[1];
unsigned char *valuatorsMaskAddr = buttonsMaskAddr + xideviceevent->buttons_len * 4;
FP3232 *valuatorsValuesAddr = (FP3232*)(valuatorsMaskAddr + xideviceevent->valuators_len * 4);
- int numValuatorValues = xi2CountBits(valuatorsMaskAddr, xideviceevent->valuators_len * 4);
- // This relies on all bit being set until a certain number i.e. it doesn't support only bit 0 and 5 being set in the mask.
- // Just like the original code, works for now.
- if (valuatorNum >= numValuatorValues)
+
+ int valuatorOffset = xi2ValuatorOffset(valuatorsMaskAddr, xideviceevent->valuators_len, valuatorNum);
+ if (valuatorOffset < 0)
return false;
- *value = valuatorsValuesAddr[valuatorNum].integral;
- *value += ((double)valuatorsValuesAddr[valuatorNum].frac / (1 << 16) / (1 << 16));
+
+ *value = valuatorsValuesAddr[valuatorOffset].integral;
+ *value += ((double)valuatorsValuesAddr[valuatorOffset].frac / (1 << 16) / (1 << 16));
return true;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index ba056a8006..71f5ce13fb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -69,9 +69,12 @@
struct XInput2MaemoData;
#elif XCB_USE_XINPUT2
#include <X11/extensions/XI2.h>
+#ifdef XIScrollClass
+#define XCB_USE_XINPUT21 // XI 2.1 adds smooth scrolling support
#ifdef XI_TouchBeginMask
#define XCB_USE_XINPUT22 // XI 2.2 adds multi-point touch support
#endif
+#endif
struct XInput2DeviceData;
#endif
struct xcb_randr_get_output_info_reply_t;
@@ -271,6 +274,10 @@ namespace QXcbAtom {
AbsDistance,
WacomSerialIDs,
INTEGER,
+ RelHorizWheel,
+ RelVertWheel,
+ RelHorizScroll,
+ RelVertScroll,
#if XCB_USE_MAEMO_WINDOW_PROPERTIES
MeegoTouchOrientationAngle,
@@ -499,10 +506,19 @@ private:
void xi2ReportTabletEvent(const TabletData &tabletData, void *event);
QVector<TabletData> m_tabletData;
#endif
+ struct ScrollingDevice {
+ ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0) { }
+ int deviceId;
+ int verticalIndex, horizontalIndex;
+ double verticalIncrement, horizontalIncrement;
+ Qt::Orientations orientations;
+ QPointF lastScrollPosition;
+ };
+ void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice);
+ QHash<int, ScrollingDevice> m_scrollingDevices;
#endif // XCB_USE_XINPUT2
#if defined(XCB_USE_XINPUT2) || defined(XCB_USE_XINPUT2_MAEMO)
- static int xi2CountBits(unsigned char *ptr, int len);
static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value);
static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode);
#endif
@@ -521,8 +537,6 @@ private:
QByteArray m_displayName;
- xcb_window_t m_connectionEventListener;
-
QXcbKeyboard *m_keyboard;
#ifndef QT_NO_CLIPBOARD
QXcbClipboard *m_clipboard;
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index a2ef8bf20f..d80b49ccbb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qxcbconnection.h"
+#include "qxcbkeyboard.h"
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
@@ -75,16 +76,20 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
m_tabletData.clear();
#endif
+ m_scrollingDevices.clear();
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
- m_xi2Minor = 0; // for tablet support 2.0 is enough
- m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
- } else {
+ m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
+ if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
+ m_xi2Minor = 0; // for tablet support 2.0 is enough
+ m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
+ } else
+ m_xi2Enabled = true;
+ } else
m_xi2Enabled = true;
- }
if (m_xi2Enabled) {
if (Q_UNLIKELY(debug_xinput_devices))
#ifdef XCB_USE_XINPUT22
@@ -103,6 +108,7 @@ void QXcbConnection::initializeXInput2()
#ifndef QT_NO_TABLETEVENT
TabletData tabletData;
#endif
+ ScrollingDevice scrollingDevice;
for (int c = 0; c < devices[i].num_classes; ++c) {
switch (devices[i].classes[c]->type) {
case XIValuatorClass: {
@@ -119,7 +125,29 @@ void QXcbConnection::initializeXInput2()
tabletData.valuatorInfo[valuatorAtom] = info;
}
#endif // QT_NO_TABLETEVENT
- } break;
+ if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
+ scrollingDevice.lastScrollPosition.setX(vci->value);
+ else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
+ scrollingDevice.lastScrollPosition.setY(vci->value);
+ break;
+ }
+#ifdef XCB_USE_XINPUT21
+ case XIScrollClass: {
+ XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(devices[i].classes[c]);
+ scrollingDevice.deviceId = devices[i].deviceid;
+ if (sci->scroll_type == XIScrollTypeVertical) {
+ scrollingDevice.orientations |= Qt::Vertical;
+ scrollingDevice.verticalIndex = sci->number;
+ scrollingDevice.verticalIncrement = sci->increment;
+ }
+ else if (sci->scroll_type == XIScrollTypeHorizontal) {
+ scrollingDevice.orientations |= Qt::Horizontal;
+ scrollingDevice.horizontalIndex = sci->number;
+ scrollingDevice.horizontalIncrement = sci->increment;
+ }
+ break;
+ }
+#endif
default:
break;
}
@@ -140,6 +168,15 @@ void QXcbConnection::initializeXInput2()
qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ if (scrollingDevice.orientations) {
+ m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " it's a scrolling device";
+ }
+#endif
+
if (!isTablet) {
XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
if (Q_UNLIKELY(debug_xinput_devices)) {
@@ -181,7 +218,7 @@ void QXcbConnection::xi2Select(xcb_window_t window)
mask.mask_len = sizeof(bitMask);
mask.mask = xiBitMask;
// Enable each touchscreen
- foreach (XInput2DeviceData *dev, m_touchDevices.values()) {
+ foreach (XInput2DeviceData *dev, m_touchDevices) {
mask.deviceid = dev->xiDeviceInfo->deviceid;
Status result = XISelectEvents(xDisplay, window, &mask, 1);
// If we have XInput >= 2.2 and successfully enable a touchscreen, then
@@ -213,6 +250,22 @@ void QXcbConnection::xi2Select(xcb_window_t window)
XISelectEvents(xDisplay, window, xiEventMask.data(), m_tabletData.count());
}
#endif // QT_NO_TABLETEVENT
+
+#ifdef XCB_USE_XINPUT21
+ // Enable each scroll device
+ if (!m_scrollingDevices.isEmpty()) {
+ QVector<XIEventMask> xiEventMask(m_scrollingDevices.size());
+ bitMask = XI_MotionMask;
+ int i=0;
+ Q_FOREACH (const ScrollingDevice& scrollingDevice, m_scrollingDevices) {
+ xiEventMask[i].deviceid = scrollingDevice.deviceId;
+ xiEventMask[i].mask_len = sizeof(bitMask);
+ xiEventMask[i].mask = xiBitMask;
+ i++;
+ }
+ XISelectEvents(xDisplay, window, xiEventMask.data(), m_scrollingDevices.size());
+ }
+#endif
}
XInput2DeviceData *QXcbConnection::deviceForId(int id)
@@ -243,7 +296,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
type = QTouchDevice::TouchScreen;
break;
}
- } break;
+ break;
+ }
#endif // XCB_USE_XINPUT22
case XIValuatorClass: {
XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo);
@@ -260,7 +314,8 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
hasRelativeCoords = true;
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vci->resolution);
}
- } break;
+ break;
+ }
}
}
if (type < 0 && caps && hasRelativeCoords) {
@@ -287,14 +342,14 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
return dev;
}
-#if defined(XCB_USE_XINPUT22) || !defined(QT_NO_TABLETEVENT)
+#if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
static qreal fixed1616ToReal(FP1616 val)
{
return (qreal(val >> 16)) + (val & 0xFF) / (qreal)0xFF;
}
-#endif
+#endif // defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT)
-#ifdef XCB_USE_XINPUT22
+#if defined(XCB_USE_XINPUT21)
static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
{
if (value > vci->max)
@@ -303,7 +358,7 @@ static qreal valuatorNormalized(double value, XIValuatorClassInfo *vci)
value = vci->min;
return (value - vci->min) / (vci->max - vci->min);
}
-#endif // XCB_USE_XINPUT22
+#endif // XCB_USE_XINPUT21
void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
{
@@ -319,6 +374,12 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
#endif // QT_NO_TABLETEVENT
+#ifdef XCB_USE_XINPUT21
+ QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->deviceid);
+ if (device != m_scrollingDevices.end())
+ xi2HandleScrollEvent(xiEvent, device.value());
+#endif // XCB_USE_XINPUT21
+
#ifdef XCB_USE_XINPUT22
if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) {
xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
@@ -463,6 +524,55 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
}
+void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice)
+{
+#ifdef XCB_USE_XINPUT21
+ xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+
+ if (xiEvent->evtype == XI_Motion) {
+ xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event);
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
+ QPoint rawDelta;
+ QPoint angleDelta;
+ double value;
+ if (scrollingDevice.orientations & Qt::Vertical) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.verticalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.y() - value;
+ scrollingDevice.lastScrollPosition.setY(value);
+ angleDelta.setY((delta / scrollingDevice.verticalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.verticalIncrement > 1)
+ rawDelta.setY(delta);
+ }
+ }
+ if (scrollingDevice.orientations & Qt::Horizontal) {
+ if (xi2GetValuatorValueIfSet(xiDeviceEvent, scrollingDevice.horizontalIndex, &value)) {
+ double delta = scrollingDevice.lastScrollPosition.x() - value;
+ scrollingDevice.lastScrollPosition.setX(value);
+ angleDelta.setX((delta / scrollingDevice.horizontalIncrement) * 120);
+ // We do not set "pixel" delta if it is only measured in ticks.
+ if (scrollingDevice.horizontalIncrement > 1)
+ rawDelta.setX(delta);
+ }
+ }
+ if (!angleDelta.isNull()) {
+ QPoint local(fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y));
+ QPoint global(fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y));
+ Qt::KeyboardModifiers modifiers = keyboard()->translateModifiers(xiDeviceEvent->mods.effective_mods);
+ if (modifiers & Qt::AltModifier) {
+ std::swap(angleDelta.rx(), angleDelta.ry());
+ std::swap(rawDelta.rx(), rawDelta.ry());
+ }
+ QWindowSystemInterface::handleWheelEvent(platformWindow->window(), xiEvent->time, local, global, rawDelta, angleDelta, modifiers);
+ }
+ }
+ }
+#else
+ Q_UNUSED(event);
+ Q_UNUSED(scrollingDevice);
+#endif // XCB_USE_XINPUT21
+}
+
#ifndef QT_NO_TABLETEVENT
bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData)
{
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 15e5bf27f1..ce9e445ba2 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -549,7 +549,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
void *dpy = connection()->xlib_display();
// special case for non-standard dnd-* cursors
cursor = loadCursor(dpy, cshape);
- if (!cursor && !m_gtkCursorThemeInitialized) {
+ if (!cursor && !m_gtkCursorThemeInitialized && m_screen->xSettings()->initialized()) {
QByteArray gtkCursorTheme = m_screen->xSettings()->setting("Gtk/CursorThemeName").toByteArray();
m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this);
if (updateCursorTheme(dpy,gtkCursorTheme)) {
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index d18693f6b8..61dfe8ac17 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -593,9 +593,9 @@ static Window findXdndAwareParent(Window window)
unsigned char *data = 0;
if (XGetWindowProperty(X11->display, window, ATOM(XdndAware), 0, 0, False,
AnyPropertyType, &type, &f,&n,&a,&data) == Success) {
- if (data)
+ if (data)
XFree(data);
- if (type) {
+ if (type) {
target = window;
break;
}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index ecbf28bab9..768a591ab5 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -145,18 +145,15 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
if (argc) {
int j = 1;
for (int i = 1; i < argc; i++) {
- char *arg = argv[i];
- if (arg) {
- if (!strcmp(arg, "-display") && i < argc - 1) {
- displayName = argv[++i];
- arg = 0;
- } else if (!strcmp(arg, "-name") && i < argc - 1) {
- m_instanceName = argv[++i];
- arg = 0;
- }
- }
- if (arg)
- argv[j++] = arg;
+ QByteArray arg(argv[i]);
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
+ if (arg == "-display" && i < argc - 1)
+ displayName = argv[++i];
+ else if (arg == "-name" && i < argc - 1)
+ m_instanceName = argv[++i];
+ else
+ argv[j++] = argv[i];
}
argc = j;
} // argc
@@ -287,6 +284,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
case MultipleWindows: return true;
case ForeignWindows: return true;
case SyncState: return true;
+ case RasterGLSurface: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 2529fb8a83..966090dbd5 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -117,7 +117,7 @@
#define XF86XK_KbdBrightnessUp 0x1008FF05
#define XF86XK_KbdBrightnessDown 0x1008FF06
#define XF86XK_Standby 0x1008FF10
-#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioLowerVolume 0x1008FF11
#define XF86XK_AudioMute 0x1008FF12
#define XF86XK_AudioRaiseVolume 0x1008FF13
#define XF86XK_AudioPlay 0x1008FF14
@@ -344,65 +344,65 @@ static const unsigned int KeyTbl[] = {
// International & multi-key character composition
XK_ISO_Level3_Shift, Qt::Key_AltGr,
- XK_Multi_key, Qt::Key_Multi_key,
- XK_Codeinput, Qt::Key_Codeinput,
- XK_SingleCandidate, Qt::Key_SingleCandidate,
- XK_MultipleCandidate, Qt::Key_MultipleCandidate,
- XK_PreviousCandidate, Qt::Key_PreviousCandidate,
+ XK_Multi_key, Qt::Key_Multi_key,
+ XK_Codeinput, Qt::Key_Codeinput,
+ XK_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_MultipleCandidate, Qt::Key_MultipleCandidate,
+ XK_PreviousCandidate, Qt::Key_PreviousCandidate,
// Misc Functions
- XK_Mode_switch, Qt::Key_Mode_switch,
- XK_script_switch, Qt::Key_Mode_switch,
+ XK_Mode_switch, Qt::Key_Mode_switch,
+ XK_script_switch, Qt::Key_Mode_switch,
// Japanese keyboard support
- XK_Kanji, Qt::Key_Kanji,
- XK_Muhenkan, Qt::Key_Muhenkan,
- //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
- XK_Henkan_Mode, Qt::Key_Henkan,
- XK_Henkan, Qt::Key_Henkan,
- XK_Romaji, Qt::Key_Romaji,
- XK_Hiragana, Qt::Key_Hiragana,
- XK_Katakana, Qt::Key_Katakana,
- XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
- XK_Zenkaku, Qt::Key_Zenkaku,
- XK_Hankaku, Qt::Key_Hankaku,
- XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
- XK_Touroku, Qt::Key_Touroku,
- XK_Massyo, Qt::Key_Massyo,
- XK_Kana_Lock, Qt::Key_Kana_Lock,
- XK_Kana_Shift, Qt::Key_Kana_Shift,
- XK_Eisu_Shift, Qt::Key_Eisu_Shift,
- XK_Eisu_toggle, Qt::Key_Eisu_toggle,
- //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
- //XK_Zen_Koho, Qt::Key_Zen_Koho,
- //XK_Mae_Koho, Qt::Key_Mae_Koho,
- XK_Kanji_Bangou, Qt::Key_Codeinput,
- XK_Zen_Koho, Qt::Key_MultipleCandidate,
- XK_Mae_Koho, Qt::Key_PreviousCandidate,
+ XK_Kanji, Qt::Key_Kanji,
+ XK_Muhenkan, Qt::Key_Muhenkan,
+ //XK_Henkan_Mode, Qt::Key_Henkan_Mode,
+ XK_Henkan_Mode, Qt::Key_Henkan,
+ XK_Henkan, Qt::Key_Henkan,
+ XK_Romaji, Qt::Key_Romaji,
+ XK_Hiragana, Qt::Key_Hiragana,
+ XK_Katakana, Qt::Key_Katakana,
+ XK_Hiragana_Katakana, Qt::Key_Hiragana_Katakana,
+ XK_Zenkaku, Qt::Key_Zenkaku,
+ XK_Hankaku, Qt::Key_Hankaku,
+ XK_Zenkaku_Hankaku, Qt::Key_Zenkaku_Hankaku,
+ XK_Touroku, Qt::Key_Touroku,
+ XK_Massyo, Qt::Key_Massyo,
+ XK_Kana_Lock, Qt::Key_Kana_Lock,
+ XK_Kana_Shift, Qt::Key_Kana_Shift,
+ XK_Eisu_Shift, Qt::Key_Eisu_Shift,
+ XK_Eisu_toggle, Qt::Key_Eisu_toggle,
+ //XK_Kanji_Bangou, Qt::Key_Kanji_Bangou,
+ //XK_Zen_Koho, Qt::Key_Zen_Koho,
+ //XK_Mae_Koho, Qt::Key_Mae_Koho,
+ XK_Kanji_Bangou, Qt::Key_Codeinput,
+ XK_Zen_Koho, Qt::Key_MultipleCandidate,
+ XK_Mae_Koho, Qt::Key_PreviousCandidate,
#ifdef XK_KOREAN
// Korean keyboard support
- XK_Hangul, Qt::Key_Hangul,
- XK_Hangul_Start, Qt::Key_Hangul_Start,
- XK_Hangul_End, Qt::Key_Hangul_End,
- XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
- XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
- XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
- //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
- XK_Hangul_Codeinput, Qt::Key_Codeinput,
- XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
- XK_Hangul_Banja, Qt::Key_Hangul_Banja,
- XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
- XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
+ XK_Hangul, Qt::Key_Hangul,
+ XK_Hangul_Start, Qt::Key_Hangul_Start,
+ XK_Hangul_End, Qt::Key_Hangul_End,
+ XK_Hangul_Hanja, Qt::Key_Hangul_Hanja,
+ XK_Hangul_Jamo, Qt::Key_Hangul_Jamo,
+ XK_Hangul_Romaja, Qt::Key_Hangul_Romaja,
+ //XK_Hangul_Codeinput, Qt::Key_Hangul_Codeinput,
+ XK_Hangul_Codeinput, Qt::Key_Codeinput,
+ XK_Hangul_Jeonja, Qt::Key_Hangul_Jeonja,
+ XK_Hangul_Banja, Qt::Key_Hangul_Banja,
+ XK_Hangul_PreHanja, Qt::Key_Hangul_PreHanja,
+ XK_Hangul_PostHanja, Qt::Key_Hangul_PostHanja,
//XK_Hangul_SingleCandidate,Qt::Key_Hangul_SingleCandidate,
//XK_Hangul_MultipleCandidate,Qt::Key_Hangul_MultipleCandidate,
//XK_Hangul_PreviousCandidate,Qt::Key_Hangul_PreviousCandidate,
- XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
+ XK_Hangul_SingleCandidate, Qt::Key_SingleCandidate,
XK_Hangul_MultipleCandidate,Qt::Key_MultipleCandidate,
XK_Hangul_PreviousCandidate,Qt::Key_PreviousCandidate,
- XK_Hangul_Special, Qt::Key_Hangul_Special,
- //XK_Hangul_switch, Qt::Key_Hangul_switch,
- XK_Hangul_switch, Qt::Key_Mode_switch,
+ XK_Hangul_Special, Qt::Key_Hangul_Special,
+ //XK_Hangul_switch, Qt::Key_Hangul_switch,
+ XK_Hangul_switch, Qt::Key_Mode_switch,
#endif // XK_KOREAN
// dead keys
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
index 9d81c8e224..0098f47e33 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp
@@ -50,6 +50,7 @@
#include <X11/SM/SMlib.h>
#include <errno.h> // ERANGE
+#include <cerrno> // ERANGE
class QSmSocketReceiver : public QObject
{
@@ -390,16 +391,6 @@ void* QXcbSessionManager::handle() const
return (void*) smcConnection;
}
-void QXcbSessionManager::setSessionId(const QString &id)
-{
- m_sessionId = id;
-}
-
-void QXcbSessionManager::setSessionKey(const QString &key)
-{
- m_sessionKey = key;
-}
-
bool QXcbSessionManager::allowsInteraction()
{
if (sm_interactionActive)
@@ -495,16 +486,6 @@ void QXcbSessionManager::requestPhase2()
sm_phase2 = true;
}
-void QXcbSessionManager::appCommitData()
-{
- QPlatformSessionManager::appCommitData();
-}
-
-void QXcbSessionManager::appSaveState()
-{
- QPlatformSessionManager::appSaveState();
-}
-
void QXcbSessionManager::exitEventLoop()
{
m_eventLoop->exit();
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h
index 28eb287097..3c7c968890 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.h
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h
@@ -66,8 +66,8 @@ public:
void *handle() const;
- void setSessionId(const QString &id);
- void setSessionKey(const QString &key);
+ void setSessionId(const QString &id) { m_sessionId = id; }
+ void setSessionKey(const QString &key) { m_sessionKey = key; }
bool allowsInteraction() Q_DECL_OVERRIDE;
bool allowsErrorInteraction() Q_DECL_OVERRIDE;
@@ -81,9 +81,6 @@ public:
bool isPhase2() const Q_DECL_OVERRIDE;
void requestPhase2() Q_DECL_OVERRIDE;
- void appCommitData() Q_DECL_OVERRIDE;
- void appSaveState() Q_DECL_OVERRIDE;
-
void exitEventLoop();
private:
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3d8f91649a..d0106984a2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -292,12 +292,10 @@ void QXcbWindow::create()
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
#if defined(XCB_USE_GLX)
XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen), m_screen->screenNumber(), &m_format);
- if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
- qFatal("Could not initialize GLX");
#elif defined(XCB_USE_EGL)
EGLDisplay eglDisplay = connection()->egl_display();
EGLConfig eglConfig = q_configFromGLFormat(eglDisplay, m_format, true);
- m_format = q_glFormatFromConfig(eglDisplay, eglConfig);
+ m_format = q_glFormatFromConfig(eglDisplay, eglConfig, m_format);
VisualID id = QXlibEglIntegration::getCompatibleVisualId(DISPLAY_FROM_XCB(this), eglDisplay, eglConfig);
@@ -308,9 +306,14 @@ void QXcbWindow::create()
XVisualInfo *visualInfo;
int matchingCount = 0;
visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
- if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
- qFatal("Could not initialize EGL");
#endif //XCB_USE_GLX
+ if (!visualInfo && window()->surfaceType() == QSurface::OpenGLSurface)
+ qFatal("Could not initialize OpenGL");
+
+ if (!visualInfo && window()->surfaceType() == QSurface::RasterGLSurface) {
+ qWarning("Could not initialize OpenGL for RasterGLSurface, reverting to RasterSurface.");
+ window()->setSurfaceType(QSurface::RasterSurface);
+ }
if (visualInfo) {
m_depth = visualInfo->depth;
m_imageFormat = imageFormatForDepth(m_depth);
@@ -672,8 +675,6 @@ void QXcbWindow::show()
m_screen->windowShown(this);
- xcb_flush(xcb_connection());
-
connection()->sync();
}
@@ -1377,6 +1378,7 @@ void QXcbWindow::requestActivateWindow()
updateNetWmUserTime(connection()->time());
if (window()->isTopLevel()
+ && !(window()->flags() & Qt::X11BypassWindowManagerHint)
&& connection()->wmSupport()->isSupportedByWM(atom(QXcbAtom::_NET_ACTIVE_WINDOW))) {
xcb_client_message_event_t event;
@@ -1392,10 +1394,10 @@ void QXcbWindow::requestActivateWindow()
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()));
}
- Q_XCB_CALL(xcb_set_input_focus(xcb_connection(), XCB_INPUT_FOCUS_PARENT, m_window, connection()->time()));
-
connection()->sync();
}
@@ -1586,6 +1588,16 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QPlatformWindow::setGeometry(rect);
QWindowSystemInterface::handleGeometryChange(window(), rect);
+ if (!m_screen->availableGeometry().intersects(rect)) {
+ Q_FOREACH (QPlatformScreen* screen, m_screen->virtualSiblings()) {
+ if (screen->availableGeometry().intersects(rect)) {
+ m_screen = static_cast<QXcbScreen*>(screen);
+ QWindowSystemInterface::handleWindowScreenChanged(window(), m_screen->QPlatformScreen::screen());
+ break;
+ }
+ }
+ }
+
m_configureNotifyPending = false;
if (m_deferredExpose) {
@@ -1695,6 +1707,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
if (isWheel) {
+#ifndef XCB_USE_XINPUT21
// Logic borrowed from qapplication_x11.cpp
int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1);
bool hor = (((event->detail == 4 || event->detail == 5)
@@ -1703,6 +1716,7 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event)
QWindowSystemInterface::handleWheelEvent(window(), event->time,
local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers);
+#endif
return;
}
@@ -1893,7 +1907,6 @@ void QXcbWindow::updateSyncRequestCounter()
{
if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
- xcb_flush(xcb_connection());
connection()->sync();
m_syncValue.lo = 0;
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 8679d502d9..141a6cc0cb 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -99,6 +99,7 @@ class QXcbXSettingsPrivate
public:
QXcbXSettingsPrivate(QXcbScreen *screen)
: screen(screen)
+ , initialized(false)
{
}
@@ -202,6 +203,7 @@ public:
QXcbScreen *screen;
xcb_window_t x_settings_window;
QMap<QByteArray, QXcbXSettingsPropertyValue> settings;
+ bool initialized;
};
@@ -217,7 +219,6 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_generic_error_t *error = 0;
xcb_intern_atom_reply_t *atom_reply = xcb_intern_atom_reply(screen->xcb_connection(),atom_cookie,&error);
if (error) {
- qWarning() << Q_FUNC_INFO << "Failed to find XSETTINGS_S atom";
free(error);
return;
}
@@ -230,7 +231,6 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_get_selection_owner_reply_t *selection_result =
xcb_get_selection_owner_reply(screen->xcb_connection(), selection_cookie, &error);
if (error) {
- qWarning() << Q_FUNC_INFO << "Failed to get selection owner for XSETTINGS_S atom";
free(error);
return;
}
@@ -246,6 +246,13 @@ QXcbXSettings::QXcbXSettings(QXcbScreen *screen)
xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask);
d_ptr->populateSettings(d_ptr->getSettings());
+ d_ptr->initialized = true;
+}
+
+bool QXcbXSettings::initialized() const
+{
+ Q_D(const QXcbXSettings);
+ return d->initialized;
}
void QXcbXSettings::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event)
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.h b/src/plugins/platforms/xcb/qxcbxsettings.h
index 16fed862bc..f6a07a6091 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.h
+++ b/src/plugins/platforms/xcb/qxcbxsettings.h
@@ -53,6 +53,7 @@ class QXcbXSettings : public QXcbWindowEventListener
Q_DECLARE_PRIVATE(QXcbXSettings)
public:
QXcbXSettings(QXcbScreen *screen);
+ bool initialized() const;
QVariant setting(const QByteArray &property) const;
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index 8968d020c4..4727262f3f 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -42,7 +42,7 @@ HEADERS = \
qxcbxsettings.h \
qxcbsystemtraytracker.h
-LIBS += -ldl
+LIBS += $$QMAKE_LIBS_DYNLOAD
# needed by GLX, Xcursor ...
contains(QT_CONFIG, xcb-xlib) {
@@ -90,7 +90,7 @@ contains(QT_CONFIG, opengl) {
DEFINES += XCB_HAS_XCB_GLX
LIBS += -lxcb-glx
}
- } else:contains(QT_CONFIG, egl) {
+ } else:contains(QT_CONFIG, egl):contains(QT_CONFIG, egl_x11) {
DEFINES += XCB_USE_EGL
CONFIG += egl
HEADERS += qxcbeglsurface.h
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 6f4bca63be..942db329ca 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
SUBDIRS *= sqldrivers
-qtHaveModule(network): SUBDIRS += bearer
+!winrt:qtHaveModule(network): SUBDIRS += bearer
qtHaveModule(gui): SUBDIRS *= imageformats platforms platforminputcontexts platformthemes generic
qtHaveModule(widgets): SUBDIRS += accessible
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index 1c86420cb2..2fecdc00e9 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -221,7 +221,7 @@ void QCupsPrintEnginePrivate::closePrintDevice()
if (copies > 1)
options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
- if (collate)
+ if (copies > 1 && collate)
options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
switch (duplex) {
diff --git a/src/printsupport/dialogs/qprintdialog_win.cpp b/src/printsupport/dialogs/qprintdialog_win.cpp
index 6f96a499e5..b5dc2d016a 100644
--- a/src/printsupport/dialogs/qprintdialog_win.cpp
+++ b/src/printsupport/dialogs/qprintdialog_win.cpp
@@ -54,8 +54,8 @@
#if !defined(PD_NOCURRENTPAGE)
#define PD_NOCURRENTPAGE 0x00800000
-#define PD_RESULT_PRINT 1
-#define PD_RESULT_APPLY 2
+#define PD_RESULT_PRINT 1
+#define PD_RESULT_APPLY 2
#define START_PAGE_GENERAL 0XFFFFFFFF
#endif
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index 4692fb5c3c..c0c8a759aa 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -65,6 +65,15 @@
#ifndef QT_NO_PRINTPREVIEWDIALOG
+static void initResources()
+{
+ static bool resourcesInitialized = false;
+ if (!resourcesInitialized) {
+ Q_INIT_RESOURCE(qprintdialog);
+ resourcesInitialized = true;
+ }
+}
+
QT_BEGIN_NAMESPACE
namespace {
@@ -217,6 +226,8 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer)
{
Q_Q(QPrintPreviewDialog);
+ initResources();
+
if (_printer) {
preview = new QPrintPreviewWidget(_printer, q);
printer = _printer;
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
index 7b3c3c1dac..6c65300462 100644
--- a/src/printsupport/kernel/qprintengine_pdf.cpp
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -147,6 +147,28 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
Q_D(QPdfPrintEngine);
switch (int(key)) {
+
+ // The following keys are properties or derived values and so cannot be set
+ case PPK_PageRect:
+ break;
+ case PPK_PaperRect:
+ break;
+ case PPK_PaperSources:
+ break;
+ case PPK_SupportsMultipleCopies:
+ break;
+ case PPK_SupportedResolutions:
+ break;
+
+ // The following keys are settings that are unsupported by the PDF PrintEngine
+ case PPK_CustomBase:
+ break;
+ case PPK_PaperName:
+ break;
+ case PPK_WindowsPageSize:
+ break;
+
+ // The following keys are properties and settings that are supported by the PDF PrintEngine
case PPK_CollateCopies:
d->collate = value.toBool();
break;
@@ -216,8 +238,7 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->pageMarginsSet = true;
break;
}
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
}
@@ -227,6 +248,20 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
QVariant ret;
switch (int(key)) {
+
+ // The following keys are settings that are unsupported by the PDF PrintEngine
+ // Return sensible default values to ensure consistent behavior across platforms
+ case PPK_CustomBase:
+ // Special case, leave null
+ break;
+ case PPK_PaperName:
+ ret = QString();
+ break;
+ case PPK_WindowsPageSize:
+ // Special case, leave null
+ break;
+
+ // The following keys are properties and settings that are supported by the PDF PrintEngine
case PPK_CollateCopies:
ret = d->collate;
break;
@@ -307,8 +342,7 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = margins;
break;
}
- default:
- break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
return ret;
}
@@ -352,7 +386,7 @@ void QPdfPrintEnginePrivate::closePrintDevice()
QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
: QPdfEnginePrivate(),
duplex(QPrinter::DuplexNone),
- collate(false),
+ collate(true),
copies(1),
pageOrder(QPrinter::FirstPageFirst),
paperSource(QPrinter::Auto),
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 6fa75338aa..74484bfc8c 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -182,7 +182,7 @@ static const struct {
int winSourceName;
QPrinter::PaperSource qtSourceName;
} sources[] = {
- { DMBIN_ONLYONE, QPrinter::OnlyOne },
+ { DMBIN_UPPER, QPrinter::Upper }, // = DBMIN_ONLYONE
{ DMBIN_LOWER, QPrinter::Lower },
{ DMBIN_MIDDLE, QPrinter::Middle },
{ DMBIN_MANUAL, QPrinter::Manual },
@@ -195,6 +195,7 @@ static const struct {
{ DMBIN_LARGECAPACITY, QPrinter::LargeCapacity },
{ DMBIN_CASSETTE, QPrinter::Cassette },
{ DMBIN_FORMSOURCE, QPrinter::FormSource },
+ { DMBIN_USER, QPrinter::CustomSource },
{ 0, (QPrinter::PaperSource) -1 }
};
@@ -234,7 +235,6 @@ QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode)
| PaintOutsidePaintEvent))
{
Q_D(QWin32PrintEngine);
- d->docName = QLatin1String("document1");
d->mode = mode;
d->queryDefault();
d->initialize();
@@ -269,7 +269,10 @@ bool QWin32PrintEngine::begin(QPaintDevice *pdev)
DOCINFO di;
memset(&di, 0, sizeof(DOCINFO));
di.cbSize = sizeof(DOCINFO);
- di.lpszDocName = reinterpret_cast<const wchar_t *>(d->docName.utf16());
+ if (d->docName.isEmpty())
+ di.lpszDocName = L"document1";
+ else
+ di.lpszDocName = reinterpret_cast<const wchar_t *>(d->docName.utf16());
if (d->printToFile && !d->fileName.isEmpty())
di.lpszOutput = reinterpret_cast<const wchar_t *>(d->fileName.utf16());
if (ok && StartDoc(d->hdc, &di) == SP_ERROR) {
@@ -1093,6 +1096,7 @@ void QWin32PrintEnginePrivate::initialize()
if (devMode) {
num_copies = devMode->dmCopies;
+ devMode->dmCollate = DMCOLLATE_TRUE;
}
initHDC();
@@ -1270,6 +1274,35 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
{
Q_D(QWin32PrintEngine);
switch (key) {
+
+ // The following keys are properties or derived values and so cannot be set
+ case PPK_PageRect:
+ break;
+ case PPK_PaperRect:
+ break;
+ case PPK_PaperSources:
+ break;
+ case PPK_SupportsMultipleCopies:
+ break;
+ case PPK_SupportedResolutions:
+ break;
+
+ // The following keys are settings that are unsupported by the Windows PrintEngine
+ case PPK_CustomBase:
+ break;
+ case PPK_Duplex:
+ // TODO Add support using DEVMODE.dmDuplex
+ break;
+ case PPK_FontEmbedding:
+ break;
+ case PPK_PageOrder:
+ break;
+ case PPK_PrinterProgram:
+ break;
+ case PPK_SelectionOption:
+ break;
+
+ // The following keys are properties and settings that are supported by the Windows PrintEngine
case PPK_CollateCopies:
{
if (!d->devMode)
@@ -1289,7 +1322,7 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
break;
case PPK_Creator:
-
+ d->m_creator = value.toString();
break;
case PPK_DocumentName:
@@ -1344,33 +1377,31 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
setDevModePaperFlags(d->devMode, d->has_custom_paper_size);
d->doReinit();
break;
+
case PPK_PaperName:
{
if (!d->devMode)
break;
- DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERNAMES, NULL, NULL);
+ const wchar_t *name = reinterpret_cast<const wchar_t*>(d->name.utf16());
+ DWORD size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
if ((int)size > 0) {
- wchar_t *paperNames = new wchar_t[size*64];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERNAMES, paperNames, NULL);
+ QScopedArrayPointer<wchar_t> paperNames(new wchar_t[size*64]);
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERNAMES, paperNames.data(), NULL))
+ break;
int paperPos = -1;
- for (int i=0;i<(int)size;i++) {
- wchar_t *copyOfPaper = paperNames + (i * 64);
+ for (int i = 0; i < (int)size; ++i) {
+ wchar_t *copyOfPaper = paperNames.data() + (i * 64);
if (value.toString() == QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64))) {
paperPos = i;
break;
}
}
- delete [] paperNames;
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERS, NULL, NULL);
+ size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
if ((int)size > 0) {
- wchar_t *papers = new wchar_t[size];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERS, papers, NULL);
+ QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
+ size = DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL);
QScopedArrayPointer<POINT> paperSizes(new POINT[size]);
- DWORD paperNameCount = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()), NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL);
+ DWORD paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL);
if (paperNameCount == size) {
const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, d->resolution);
d->paper_size = QSizeF((paperSizes[paperPos].x / 10.0) * multiplier, (paperSizes[paperPos].y / 10.0) * multiplier);
@@ -1381,8 +1412,6 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
setDevModePaperFlags(d->devMode, false);
d->doReinit();
}
-
- delete [] papers;
}
}
}
@@ -1418,15 +1447,6 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
}
break;
- case PPK_SelectionOption:
-
- break;
-
- case PPK_SupportedResolutions:
-
- break;
-
-
case PPK_WindowsPageSize:
if (!d->devMode)
break;
@@ -1470,9 +1490,9 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
d->setPageMargins(left, top, right, bottom);
break;
}
- default:
- // Do nothing
- break;
+
+ // No default so that compiler will complain if new keys added and not handled in this engine
+
}
}
@@ -1482,9 +1502,29 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
QVariant value;
switch (key) {
- case PPK_CollateCopies:
+ // The following keys are settings that are unsupported by the Windows PrintEngine
+ // Return sensible default values to ensure consistent behavior across platforms
+ case PPK_Duplex:
+ // TODO Add support using DEVMODE.dmDuplex
+ value = QPrinter::DuplexNone;
+ break;
+ case PPK_FontEmbedding:
value = false;
break;
+ case PPK_PageOrder:
+ value = QPrinter::FirstPageFirst;
+ break;
+ case PPK_PrinterProgram:
+ value = QString();
+ break;
+ case PPK_SelectionOption:
+ value = QString();
+ break;
+
+ // The following keys are properties and settings that are supported by the Windows PrintEngine
+ case PPK_CollateCopies:
+ value = d->devMode->dmCollate == DMCOLLATE_TRUE;
+ break;
case PPK_ColorMode:
{
@@ -1496,6 +1536,10 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
}
break;
+ case PPK_Creator:
+ value = d->m_creator;
+ break;
+
case PPK_DocumentName:
value = d->docName;
break;
@@ -1569,40 +1613,37 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect);
}
break;
+
case PPK_PaperName:
if (!d->devMode) {
value = QLatin1String("A4");
} else {
- DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERS, NULL, NULL);
+ const wchar_t *name = reinterpret_cast<const wchar_t*>(d->name.utf16());
+ DWORD size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
int paperSizePos = -1;
if ((int)size > 0) {
- wchar_t *papers = new wchar_t[size];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERS, papers, NULL);
+ QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL))
+ break;
for (int i=0;i<(int)size;i++) {
if (papers[i] == d->devMode->dmPaperSize) {
paperSizePos = i;
break;
}
}
- delete [] papers;
-
}
if (paperSizePos != -1) {
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERNAMES, NULL, NULL);
+ size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
if ((int)size > 0) {
- wchar_t *papers = new wchar_t[size*64];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
- NULL, DC_PAPERNAMES, papers, NULL);
- wchar_t *copyOfPaper = papers + (paperSizePos * 64);
+ QScopedArrayPointer<wchar_t> paperNames(new wchar_t[size*64]);
+ size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, paperNames.data(), NULL);
+ wchar_t *copyOfPaper = paperNames.data() + (paperSizePos * 64);
value = QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64));
- delete [] papers;
}
}
}
break;
+
case PPK_PaperSource:
if (!d->devMode) {
value = QPrinter::Auto;
@@ -1677,9 +1718,9 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
value = margins;
break;
}
- default:
- // Do nothing
- break;
+
+ // No default so that compiler will complain if new keys added and not handled in this engine
+
}
return value;
}
@@ -1705,16 +1746,14 @@ QList<QPrinter::PaperSize> QWin32PrintEngine::supportedPaperSizes(const QPrinter
if (printerInfo.isNull())
return returnList;
-
- DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t *>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERS, NULL, NULL);
+ const wchar_t *name = reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16());
+ DWORD size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
if ((int)size != -1) {
- wchar_t *papers = new wchar_t[size];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t *>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERS, papers, NULL);
+ QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL))
+ return returnList;
for (int c = 0; c < (int)size; ++c)
returnList.append(mapDevmodePaperSize(papers[c]));
- delete [] papers;
}
return returnList;
}
@@ -1724,27 +1763,22 @@ QList<QPair<QString, QSizeF> > QWin32PrintEngine::supportedSizesWithNames(const
QList<QPair<QString, QSizeF> > paperSizes;
if (printerInfo.isNull())
return paperSizes;
- DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERNAMES, NULL, NULL);
+ const wchar_t *name = reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16());
+ DWORD size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
if ((int)size > 0) {
- wchar_t *papers = new wchar_t[size*64];
- size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERNAMES, papers, NULL);
- DWORD size2 = DeviceCapabilities(reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERSIZE, NULL, NULL);
- if ((int)size2 > 0) {
- POINT *points = new POINT[size2*sizeof(POINT)];
-
- size2 = DeviceCapabilities(reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16()),
- NULL, DC_PAPERSIZE, (wchar_t *)points, NULL);
- for (int i=0;i<(int)size;i++) {
- wchar_t *paper = papers + (i * 64);
- QString str = QString::fromWCharArray(paper, qwcsnlen(paper, 64));
- paperSizes << qMakePair(str, QSizeF(points[i].x / 10.0, points[i].y / 10.0));
- }
- delete [] points;
+ QScopedArrayPointer<wchar_t> papers(new wchar_t[size*64]);
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERNAMES, papers.data(), NULL))
+ return paperSizes;
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERSIZE, NULL, NULL))
+ return paperSizes;
+ QScopedArrayPointer<POINT> points(new POINT[size*sizeof(POINT)]);
+ if (size != DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)points.data(), NULL))
+ return paperSizes;
+ for (int i = 0; i < (int)size; ++i) {
+ wchar_t *paper = papers.data() + (i * 64);
+ QString str = QString::fromWCharArray(paper, qwcsnlen(paper, 64));
+ paperSizes << qMakePair(str, QSizeF(points[i].x / 10.0, points[i].y / 10.0));
}
- delete [] papers;
}
return paperSizes;
}
diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h
index 93fe993088..040140d50f 100644
--- a/src/printsupport/kernel/qprintengine_win_p.h
+++ b/src/printsupport/kernel/qprintengine_win_p.h
@@ -210,6 +210,7 @@ public:
// Document info
QString docName;
+ QString m_creator;
QString fileName;
QPrinter::PrinterState state;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index f23708045d..496883f44b 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -226,7 +226,6 @@ void QPrinterPrivate::changeEngines(QPrinter::OutputFormat format, const QPrinte
prop = QVariant(q_ptr->copyCount());
else if (key != QPrintEngine::PPK_PrinterName)
prop = oldPrintEngine->property(key);
-
if (prop.isValid())
setProperty(key, prop);
}
@@ -516,12 +515,15 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons
\value LargeCapacity
\value LargeFormat
\value Lower
- \value MaxPageSource
+ \value MaxPageSource Deprecated, use LastPaperSource instead
\value Middle
\value Manual
\value OnlyOne
\value Tractor
\value SmallFormat
+ \value Upper
+ \value CustomSource A PaperSource defined by the printer that is unknown to Qt
+ \value LastPaperSource The highest valid PaperSource value, currently CustomSource
*/
/*!
@@ -936,11 +938,9 @@ QPrinter::Orientation QPrinter::orientation() const
The printer driver reads this setting and prints using the
specified orientation.
- On Windows, this option can be changed while printing and will
+ On Windows and Mac, this option can be changed while printing and will
take effect from the next call to newPage().
- On Mac OS X, changing the orientation during a print job has no effect.
-
\sa orientation()
*/
@@ -1824,11 +1824,17 @@ QList<QPrinter::PaperSource> QPrinter::supportedPaperSources() const
Any other value implies that the given value should be used.
- \warning This function is not available on Windows.
+ This function always returns an empty string on Windows and Mac.
- \sa setPrinterSelectionOption()
+ \sa setPrinterSelectionOption(), setPrintProgram()
*/
+QString QPrinter::printerSelectionOption() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_SelectionOption).toString();
+}
+
/*!
\fn void QPrinter::setPrinterSelectionOption(const QString &option)
@@ -1840,24 +1846,16 @@ QList<QPrinter::PaperSource> QPrinter::supportedPaperSources() const
If the printer selection option is changed while the printer is
active, the current print job may or may not be affected.
- \warning This function is not available on Windows.
+ This function has no effect on Windows or Mac.
- \sa printerSelectionOption()
+ \sa printerSelectionOption(), setPrintProgram()
*/
-#ifndef Q_OS_WIN
-QString QPrinter::printerSelectionOption() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_SelectionOption).toString();
-}
-
void QPrinter::setPrinterSelectionOption(const QString &option)
{
Q_D(QPrinter);
d->setProperty(QPrintEngine::PPK_SelectionOption, option);
}
-#endif
/*!
\since 4.1
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
index 2528157532..679f3af043 100644
--- a/src/printsupport/kernel/qprinter.h
+++ b/src/printsupport/kernel/qprinter.h
@@ -103,7 +103,10 @@ public:
LargeCapacity,
Cassette,
FormSource,
- MaxPageSource
+ MaxPageSource, // Deprecated
+ CustomSource,
+ LastPaperSource = CustomSource,
+ Upper = OnlyOne // As defined in Windows
};
enum PrinterState { Idle,
@@ -222,10 +225,8 @@ public:
QRectF paperRect(Unit) const;
QRectF pageRect(Unit) const;
-#if !defined(Q_OS_WIN) || defined(Q_QDOC)
QString printerSelectionOption() const;
void setPrinterSelectionOption(const QString &);
-#endif
bool newPage();
bool abort();
diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro
index ee4f9f72df..a92d36f7bc 100644
--- a/src/printsupport/printsupport.pro
+++ b/src/printsupport/printsupport.pro
@@ -1,6 +1,7 @@
TARGET = QtPrintSupport
QT = core-private gui-private widgets-private
+MODULE_CONFIG = needs_printsupport_plugin
DEFINES += QT_NO_USING_NAMESPACE
QMAKE_DOCS = $$PWD/doc/qtprintsupport.qdocconf
diff --git a/src/printsupport/widgets/qprintpreviewwidget.cpp b/src/printsupport/widgets/qprintpreviewwidget.cpp
index f788663041..3ef1e882fe 100644
--- a/src/printsupport/widgets/qprintpreviewwidget.cpp
+++ b/src/printsupport/widgets/qprintpreviewwidget.cpp
@@ -162,9 +162,10 @@ signals:
protected:
void resizeEvent(QResizeEvent* e)
{
- const bool blocked = verticalScrollBar()->blockSignals(true); // Don't change page, QTBUG-14517
- QGraphicsView::resizeEvent(e);
- verticalScrollBar()->blockSignals(blocked);
+ {
+ const QSignalBlocker blocker(verticalScrollBar()); // Don't change page, QTBUG-14517
+ QGraphicsView::resizeEvent(e);
+ }
emit resized();
}
diff --git a/src/sql/doc/src/sql-driver.qdoc b/src/sql/doc/src/sql-driver.qdoc
index f1fd2f6e90..9858e30ff9 100644
--- a/src/sql/doc/src/sql-driver.qdoc
+++ b/src/sql/doc/src/sql-driver.qdoc
@@ -531,8 +531,8 @@
is not necessary to have a database server. SQLite operates on a
single file, which must be set as the database name when opening
a connection. If the file does not exist, SQLite will try to
- create it. SQLite also supports in-memory databases, simply pass
- ":memory:" as the database name.
+ create it. SQLite also supports in-memory and temporary databases. Simply
+ pass respectively ":memory:" or an empty string as the database name.
SQLite has some restrictions regarding multiple users and
multiple transactions. If you try to read/write on a resource from different
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index 98da296240..fe5a3cd23a 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -1732,7 +1732,7 @@ QString QIBaseDriver::formatValue(const QSqlField &field, bool trimStrings) cons
QString::number(datetime.time().minute()) + QLatin1Char(':') +
QString::number(datetime.time().second()) + QLatin1Char('.') +
QString::number(datetime.time().msec()).rightJustified(3, QLatin1Char('0'), true) +
- QLatin1Char('\'');
+ QLatin1Char('\'');
else
return QLatin1String("NULL");
}
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index fd5990f3ee..c052e4c2e7 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -224,11 +224,12 @@ static QSqlError qMakeError(const QString& err, QSqlError::ErrorType type,
{
const char *s = PQerrorMessage(p->connection);
QString msg = p->isUtf8 ? QString::fromUtf8(s) : QString::fromLocal8Bit(s);
+ QString errorCode;
if (result) {
- const char *sCode = PQresultErrorField(result, PG_DIAG_SQLSTATE);
- msg += QString::fromLatin1("(%1)").arg(QString::fromLatin1(sCode));
+ errorCode = QString::fromLatin1(PQresultErrorField(result, PG_DIAG_SQLSTATE));
+ msg += QString::fromLatin1("(%1)").arg(errorCode);
}
- return QSqlError(QLatin1String("QPSQL: ") + err, msg, type);
+ return QSqlError(QLatin1String("QPSQL: ") + err, msg, type, errorCode);
}
bool QPSQLResultPrivate::processResults()
diff --git a/src/sql/drivers/psql/qsql_psql.pri b/src/sql/drivers/psql/qsql_psql.pri
index d0ded5e625..867be3edb8 100644
--- a/src/sql/drivers/psql/qsql_psql.pri
+++ b/src/sql/drivers/psql/qsql_psql.pri
@@ -1,7 +1,7 @@
HEADERS += $$PWD/qsql_psql_p.h
SOURCES += $$PWD/qsql_psql.cpp
-unix|win32-g++* {
+unix|mingw {
LIBS += $$QT_LFLAGS_PSQL
!contains(LIBS, .*pq.*):LIBS += -lpq
QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 0b0731399e..9e4ddab1b1 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -597,8 +597,6 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
if (isOpen())
close();
- if (db.isEmpty())
- return false;
int timeOut = 5000;
bool sharedCache = false;
diff --git a/src/sql/drivers/tds/qsql_tds.pri b/src/sql/drivers/tds/qsql_tds.pri
index 67d037aa6b..8c528c154d 100644
--- a/src/sql/drivers/tds/qsql_tds.pri
+++ b/src/sql/drivers/tds/qsql_tds.pri
@@ -1,7 +1,7 @@
HEADERS += $$PWD/qsql_tds_p.h
SOURCES += $$PWD/qsql_tds.cpp
-unix|win32-g++*: {
+unix|mingw: {
LIBS += $$QT_LFLAGS_TDS
!contains(LIBS, .*sybdb.*):LIBS += -lsybdb
QMAKE_CXXFLAGS *= $$QT_CFLAGS_TDS
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 36e886ed1f..3541841e87 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -589,7 +589,7 @@ QString QSqlDriver::formatValue(const QSqlField &field, bool trimStrings) const
r = field.value().toString();
break;
#ifndef QT_NO_DATESTRING
- case QVariant::Date:
+ case QVariant::Date:
if (field.value().toDate().isValid())
r = QLatin1Char('\'') + field.value().toDate().toString(Qt::ISODate)
+ QLatin1Char('\'');
diff --git a/src/sql/kernel/qsqlerror.cpp b/src/sql/kernel/qsqlerror.cpp
index e4b8aa0c6d..1763722e8a 100644
--- a/src/sql/kernel/qsqlerror.cpp
+++ b/src/sql/kernel/qsqlerror.cpp
@@ -47,12 +47,22 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug dbg, const QSqlError &s)
{
- dbg.nospace() << "QSqlError(" << s.number() << ", " << s.driverText() <<
+ dbg.nospace() << "QSqlError(" << s.nativeErrorCode() << ", " << s.driverText() <<
", " << s.databaseText() << ')';
return dbg.space();
}
#endif
+class QSqlErrorPrivate
+{
+public:
+ QString driverError;
+ QString databaseError;
+ QSqlError::ErrorType errorType;
+ QString errorCode;
+};
+
+
/*!
\class QSqlError
\brief The QSqlError class provides SQL database error information.
@@ -62,7 +72,7 @@ QDebug operator<<(QDebug dbg, const QSqlError &s)
A QSqlError object can provide database-specific error data,
including the driverText() and databaseText() messages (or both
- concatenated together as text()), and the error number() and
+ concatenated together as text()), and the nativeErrorCode() and
type().
\sa QSqlDatabase::lastError(), QSqlQuery::lastError()
@@ -81,25 +91,52 @@ QDebug operator<<(QDebug dbg, const QSqlError &s)
*/
/*!
+ \obsolete
+
Constructs an error containing the driver error text \a
driverText, the database-specific error text \a databaseText, the
type \a type and the optional error number \a number.
*/
+#if QT_DEPRECATED_SINCE(5, 3)
QSqlError::QSqlError(const QString& driverText, const QString& databaseText, ErrorType type,
int number)
- : driverError(driverText), databaseError(databaseText), errorType(type), errorNumber(number)
{
+ d = new QSqlErrorPrivate;
+
+ d->driverError = driverText;
+ d->databaseError = databaseText;
+ d->errorType = type;
+ d->errorCode = QString::number(number);
}
+#endif
+
+/*!
+ Constructs an error containing the driver error text \a
+ driverText, the database-specific error text \a databaseText, the
+ type \a type and the error code \a code.
+*/
+
+QSqlError::QSqlError(const QString &driverText, const QString &databaseText,
+ ErrorType type, const QString &code)
+{
+ d = new QSqlErrorPrivate;
+
+ d->driverError = driverText;
+ d->databaseError = databaseText;
+ d->errorType = type;
+ d->errorCode = code;
+}
+
/*!
Creates a copy of \a other.
*/
QSqlError::QSqlError(const QSqlError& other)
- : driverError(other.driverError), databaseError(other.databaseError),
- errorType(other.errorType),
- errorNumber(other.errorNumber)
{
+ d = new QSqlErrorPrivate;
+
+ *d = *other.d;
}
/*!
@@ -108,10 +145,7 @@ QSqlError::QSqlError(const QSqlError& other)
QSqlError& QSqlError::operator=(const QSqlError& other)
{
- driverError = other.driverError;
- databaseError = other.databaseError;
- errorType = other.errorType;
- errorNumber = other.errorNumber;
+ *d = *other.d;
return *this;
}
@@ -121,7 +155,7 @@ QSqlError& QSqlError::operator=(const QSqlError& other)
bool QSqlError::operator==(const QSqlError& other) const
{
- return (errorType == other.errorType);
+ return (d->errorType == other.d->errorType);
}
@@ -131,7 +165,7 @@ bool QSqlError::operator==(const QSqlError& other) const
bool QSqlError::operator!=(const QSqlError& other) const
{
- return (errorType != other.errorType);
+ return (d->errorType != other.d->errorType);
}
@@ -141,6 +175,7 @@ bool QSqlError::operator!=(const QSqlError& other) const
QSqlError::~QSqlError()
{
+ delete d;
}
/*!
@@ -151,7 +186,7 @@ QSqlError::~QSqlError()
*/
QString QSqlError::driverText() const
{
- return driverError;
+ return d->driverError;
}
/*!
@@ -169,7 +204,7 @@ QString QSqlError::driverText() const
#if QT_DEPRECATED_SINCE(5, 1)
void QSqlError::setDriverText(const QString& driverText)
{
- driverError = driverText;
+ d->driverError = driverText;
}
#endif
@@ -182,7 +217,7 @@ void QSqlError::setDriverText(const QString& driverText)
QString QSqlError::databaseText() const
{
- return databaseError;
+ return d->databaseError;
}
/*!
@@ -200,7 +235,7 @@ QString QSqlError::databaseText() const
#if QT_DEPRECATED_SINCE(5, 1)
void QSqlError::setDatabaseText(const QString& databaseText)
{
- databaseError = databaseText;
+ d->databaseError = databaseText;
}
#endif
@@ -210,7 +245,7 @@ void QSqlError::setDatabaseText(const QString& databaseText)
QSqlError::ErrorType QSqlError::type() const
{
- return errorType;
+ return d->errorType;
}
/*!
@@ -228,19 +263,33 @@ QSqlError::ErrorType QSqlError::type() const
#if QT_DEPRECATED_SINCE(5, 1)
void QSqlError::setType(ErrorType type)
{
- errorType = type;
+ d->errorType = type;
}
#endif
/*!
+ \fn int QSqlError::number() const
+ \obsolete
+
Returns the database-specific error number, or -1 if it cannot be
determined.
+
+ Returns 0 if the error code is not an integer.
+
+ \warning Some databases use alphanumeric error codes, which makes
+ number() unreliable if such a database is used.
+
+ Use nativeErrorCode() instead
+
+ \sa nativeErrorCode()
*/
+#if QT_DEPRECATED_SINCE(5, 3)
int QSqlError::number() const
{
- return errorNumber;
+ return d->errorCode.toInt();
}
+#endif
/*!
\fn void QSqlError::setNumber(int number)
@@ -257,11 +306,21 @@ int QSqlError::number() const
#if QT_DEPRECATED_SINCE(5, 1)
void QSqlError::setNumber(int number)
{
- errorNumber = number;
+ d->errorCode = QString::number(number);
}
#endif
/*!
+ Returns the database-specific error code, or an empty string if
+ it cannot be determined.
+*/
+
+QString QSqlError::nativeErrorCode() const
+{
+ return d->errorCode;
+}
+
+/*!
This is a convenience function that returns databaseText() and
driverText() concatenated into a single string.
@@ -270,10 +329,10 @@ void QSqlError::setNumber(int number)
QString QSqlError::text() const
{
- QString result = databaseError;
- if (!databaseError.endsWith(QLatin1String("\n")))
+ QString result = d->databaseError;
+ if (!d->databaseError.endsWith(QLatin1String("\n")))
result += QLatin1Char(' ');
- result += driverError;
+ result += d->driverError;
return result;
}
@@ -287,7 +346,7 @@ QString QSqlError::text() const
*/
bool QSqlError::isValid() const
{
- return errorType != NoError;
+ return d->errorType != NoError;
}
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqlerror.h b/src/sql/kernel/qsqlerror.h
index 39c4cda958..4e27ab03ae 100644
--- a/src/sql/kernel/qsqlerror.h
+++ b/src/sql/kernel/qsqlerror.h
@@ -47,6 +47,7 @@
QT_BEGIN_NAMESPACE
+class QSqlErrorPrivate;
class Q_SQL_EXPORT QSqlError
{
@@ -58,10 +59,16 @@ public:
TransactionError,
UnknownError
};
+#if QT_DEPRECATED_SINCE(5, 3)
QSqlError( const QString& driverText = QString(),
const QString& databaseText = QString(),
ErrorType type = NoError,
int number = -1);
+#endif
+ QSqlError(const QString &driverText,
+ const QString &databaseText,
+ ErrorType type,
+ const QString &errorCode);
QSqlError(const QSqlError& other);
QSqlError& operator=(const QSqlError& other);
bool operator==(const QSqlError& other) const;
@@ -71,7 +78,10 @@ public:
QString driverText() const;
QString databaseText() const;
ErrorType type() const;
+#if QT_DEPRECATED_SINCE(5, 3)
int number() const;
+#endif
+ QString nativeErrorCode() const;
QString text() const;
bool isValid() const;
@@ -83,10 +93,17 @@ public:
#endif
private:
- QString driverError;
- QString databaseError;
- ErrorType errorType;
- int errorNumber;
+ // ### Qt6: Keep the pointer and remove the rest.
+ QString unused1;
+ QString unused2;
+ struct Unused {
+ ErrorType unused3;
+ int unused4;
+ };
+ union {
+ QSqlErrorPrivate *d;
+ Unused unused5;
+ };
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index 661a582afe..0cfc37833d 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -309,18 +309,37 @@ QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other)
}
/*!
- Returns \c true if the query is \l{isActive()}{active} and positioned
- on a valid record and the \a field is NULL; otherwise returns
- false. Note that for some drivers, isNull() will not return accurate
- information until after an attempt is made to retrieve data.
+ Returns \c true if the query is not \l{isActive()}{active},
+ the query is not positioned on a valid record,
+ there is no such field, or the field is null; otherwise \c false.
+ Note that for some drivers, isNull() will not return accurate
+ information until after an attempt is made to retrieve data.
- \sa isActive(), isValid(), value()
+ \sa isActive(), isValid(), value()
*/
bool QSqlQuery::isNull(int field) const
{
- if (d->sqlResult->isActive() && d->sqlResult->isValid())
- return d->sqlResult->isNull(field);
+ return !d->sqlResult->isActive()
+ || !d->sqlResult->isValid()
+ || d->sqlResult->isNull(field);
+}
+
+/*!
+ \overload
+
+ Returns \c true if there is no field with this \a name; otherwise
+ returns isNull(int index) for the corresponding field index.
+
+ This overload is less efficient than \l{QSqlQuery::}{isNull()}
+*/
+
+bool QSqlQuery::isNull(const QString &name) const
+{
+ int index = d->sqlResult->record().indexOf(name);
+ if (index > -1)
+ return isNull(index);
+ qWarning("QSqlQuery::isNull: unknown field name '%s'", qPrintable(name));
return true;
}
diff --git a/src/sql/kernel/qsqlquery.h b/src/sql/kernel/qsqlquery.h
index 3719643174..ef48b91298 100644
--- a/src/sql/kernel/qsqlquery.h
+++ b/src/sql/kernel/qsqlquery.h
@@ -70,6 +70,7 @@ public:
bool isValid() const;
bool isActive() const;
bool isNull(int field) const;
+ bool isNull(const QString &name) const;
int at() const;
QString lastQuery() const;
int numRowsAffected() const;
diff --git a/src/src.pro b/src/src.pro
index b7887a6108..114ee5e424 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -14,6 +14,11 @@ src_tools_rcc.target = sub-rcc
src_tools_rcc.depends = src_tools_bootstrap
src_tools_rcc.CONFIG = host_build
+src_tools_qlalr.subdir = tools/qlalr
+src_tools_qlalr.target = sub-qlalr
+force_bootstrap: src_tools_qlalr.depends = src_tools_bootstrap
+else: src_tools_qlalr.depends = src_corelib
+
src_tools_uic.subdir = tools/uic
src_tools_uic.target = sub-uic
src_tools_uic.CONFIG = host_build
@@ -77,6 +82,7 @@ src_testlib.depends = src_corelib # src_gui & src_widgets are not build-depend
src_angle.subdir = $$PWD/angle
src_angle.target = sub-angle
+angle_d3d11: src_angle.depends = src_corelib
src_gui.subdir = $$PWD/gui
src_gui.target = sub-gui
@@ -109,8 +115,8 @@ src_plugins.depends = src_sql src_xml src_network
src_android.subdir = $$PWD/android
# this order is important
-SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_corelib
-TOOLS = src_tools_moc src_tools_rcc
+SUBDIRS += src_tools_bootstrap src_tools_moc src_tools_rcc src_corelib src_tools_qlalr
+TOOLS = src_tools_moc src_tools_rcc src_tools_qlalr
win32:SUBDIRS += src_winmain
SUBDIRS += src_network src_sql src_xml src_testlib
contains(QT_CONFIG, dbus) {
@@ -124,7 +130,7 @@ contains(QT_CONFIG, dbus) {
}
contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
!contains(QT_CONFIG, no-gui) {
- win32:contains(QT_CONFIG, angle) {
+ win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
SUBDIRS += src_angle
src_gui.depends += src_angle
}
@@ -152,8 +158,8 @@ nacl: SUBDIRS -= src_network src_testlib
android:!android-no-sdk: SUBDIRS += src_android
TR_EXCLUDE = \
- src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic \
+ src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_tools_qlalr \
src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
sub-tools.depends = $$TOOLS
-QMAKE_EXTRA_TARGETS = sub-tools \ No newline at end of file
+QMAKE_EXTRA_TARGETS = sub-tools
diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc
index bdd9769175..13654972ec 100644
--- a/src/testlib/doc/src/qttestlib-manual.qdoc
+++ b/src/testlib/doc/src/qttestlib-manual.qdoc
@@ -186,6 +186,9 @@
Outputs results as a stream of XML tags.
\li \c -xunitxml \br
Outputs results as an Xunit XML document.
+ \li \c -csv \br
+ Outputs results as comma-separated values (CSV). This mode is only suitable for
+ benchmarks, since it suppresses normal pass/fail messages.
\endlist
The first version of the \c -o option may be repeated in order to log
diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h
index c471717655..c549233ddb 100644
--- a/src/testlib/qabstracttestlogger_p.h
+++ b/src/testlib/qabstracttestlogger_p.h
@@ -94,7 +94,7 @@ public:
const char *file = 0, int line = 0) = 0;
virtual void addBenchmarkResult(const QBenchmarkResult &result) = 0;
- virtual void addMessage(MessageTypes type, const char *message,
+ virtual void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0) = 0;
void outputString(const char *msg);
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/testlib/qcsvbenchmarklogger.cpp
index 2e59c307c3..ae5c3183dc 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
+++ b/src/testlib/qcsvbenchmarklogger.cpp
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
+** Copyright (C) 2013 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtTest module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -39,56 +39,65 @@
**
****************************************************************************/
-#include "qandroidplatformscreen.h"
-#include "qandroidplatformintegration.h"
-#include "androidjnimain.h"
-#include "androidjnimenu.h"
-#include "qandroidplatformwindow.h"
+#include "qcsvbenchmarklogger_p.h"
+#include "qtestresult_p.h"
+#include "qbenchmark_p.h"
-QAndroidPlatformScreen::QAndroidPlatformScreen():QFbScreen()
+QCsvBenchmarkLogger::QCsvBenchmarkLogger(const char *filename)
+ : QAbstractTestLogger(filename)
{
- mGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
- mFormat = QImage::Format_RGB16;
- mDepth = 16;
- mPhysicalSize.setHeight(QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
- mPhysicalSize.setWidth(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth);
- initializeCompositor();
}
-void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
+QCsvBenchmarkLogger::~QCsvBenchmarkLogger()
{
- QtAndroidMenu::setActiveTopLevelWindow(w);
+}
- if (w != 0) {
- QAndroidPlatformWindow *platformWindow = static_cast<QAndroidPlatformWindow *>(w->handle());
- if (platformWindow != 0)
- platformWindow->updateStatusBarVisibility();
- }
+void QCsvBenchmarkLogger::startLogging()
+{
+ // don't print anything
}
-QRegion QAndroidPlatformScreen::doRedraw()
+void QCsvBenchmarkLogger::stopLogging()
{
- QRegion touched;
- touched = QFbScreen::doRedraw();
- if (touched.isEmpty())
- return touched;
+ // don't print anything
+}
- QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect());
- return touched;
+void QCsvBenchmarkLogger::enterTestFunction(const char *)
+{
+ // don't print anything
}
-QDpi QAndroidPlatformScreen::logicalDpi() const
+void QCsvBenchmarkLogger::leaveTestFunction()
{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
- return QDpi(lDpi, lDpi);
+ // don't print anything
}
-Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
+void QCsvBenchmarkLogger::addIncident(QAbstractTestLogger::IncidentTypes, const char *, const char *, int)
{
- return QAndroidPlatformIntegration::m_orientation;
+ // don't print anything
+}
+
+void QCsvBenchmarkLogger::addBenchmarkResult(const QBenchmarkResult &result)
+{
+ const char *fn = QTestResult::currentTestFunction() ? QTestResult::currentTestFunction()
+ : "UnknownTestFunc";
+ const char *tag = QTestResult::currentDataTag() ? QTestResult::currentDataTag() : "";
+ const char *gtag = QTestResult::currentGlobalDataTag()
+ ? QTestResult::currentGlobalDataTag()
+ : "";
+ const char *filler = (tag[0] && gtag[0]) ? ":" : "";
+
+ const char *metric = QTest::benchmarkMetricName(result.metric);
+
+ char buf[1024];
+ // "function","[globaltag:]tag","metric",value_per_iteration,total,iterations
+ qsnprintf(buf, sizeof(buf), "\"%s\",\"%s%s%s\",\"%s\",%.13g,%.13g,%u\n",
+ fn, gtag, filler, tag, metric,
+ result.value / result.iterations, result.value, result.iterations);
+ outputString(buf);
}
-Qt::ScreenOrientation QAndroidPlatformScreen::nativeOrientation() const
+void QCsvBenchmarkLogger::addMessage(QAbstractTestLogger::MessageTypes, const QString &, const char *, int)
{
- return QAndroidPlatformIntegration::m_nativeOrientation;
+ // don't print anything
}
diff --git a/src/testlib/qcsvbenchmarklogger_p.h b/src/testlib/qcsvbenchmarklogger_p.h
new file mode 100644
index 0000000000..89692de972
--- /dev/null
+++ b/src/testlib/qcsvbenchmarklogger_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtTest module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCSVBENCHMARKLOGGER_P_H
+#define QCSVBENCHMARKLOGGER_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 "qabstracttestlogger_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QCsvBenchmarkLogger : public QAbstractTestLogger
+{
+public:
+ QCsvBenchmarkLogger(const char *filename);
+ ~QCsvBenchmarkLogger();
+
+ void startLogging() Q_DECL_OVERRIDE;
+ void stopLogging() Q_DECL_OVERRIDE;
+
+ void enterTestFunction(const char *function) Q_DECL_OVERRIDE;
+ void leaveTestFunction() Q_DECL_OVERRIDE;
+
+ void addIncident(IncidentTypes type, const char *description,
+ const char *file = 0, int line = 0) Q_DECL_OVERRIDE;
+ void addBenchmarkResult(const QBenchmarkResult &result) Q_DECL_OVERRIDE;
+
+ void addMessage(MessageTypes type, const QString &message,
+ const char *file = 0, int line = 0) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCSVBENCHMARKLOGGER_P_H
diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp
index 3f65dc0a6e..39580f22d4 100644
--- a/src/testlib/qplaintestlogger.cpp
+++ b/src/testlib/qplaintestlogger.cpp
@@ -389,14 +389,14 @@ void QPlainTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
printBenchmarkResult(result);
}
-void QPlainTestLogger::addMessage(MessageTypes type, const char *message,
+void QPlainTestLogger::addMessage(MessageTypes type, const QString &message,
const char *file, int line)
{
// suppress non-fatal messages in silent mode
if (type != QAbstractTestLogger::QFatal && QTestLog::verboseLevel() < 0)
return;
- printMessage(QTest::messageType2String(type), message, file, line);
+ printMessage(QTest::messageType2String(type), qPrintable(message), file, line);
}
QT_END_NAMESPACE
diff --git a/src/testlib/qplaintestlogger_p.h b/src/testlib/qplaintestlogger_p.h
index 8aa0d745e9..69dbc89649 100644
--- a/src/testlib/qplaintestlogger_p.h
+++ b/src/testlib/qplaintestlogger_p.h
@@ -73,7 +73,7 @@ public:
const char *file = 0, int line = 0);
void addBenchmarkResult(const QBenchmarkResult &result);
- void addMessage(MessageTypes type, const char *message,
+ void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0);
private:
diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h
index ac1d6cc9ef..7c9a7b2b3f 100644
--- a/src/testlib/qtest.h
+++ b/src/testlib/qtest.h
@@ -66,14 +66,14 @@ QT_BEGIN_NAMESPACE
namespace QTest
{
-template<> inline char *toString(const QLatin1String &str)
+template<> inline char *toString(const QString &str)
{
- return qstrdup(qPrintable(QString(str)));
+ return QTest::toPrettyUnicode(reinterpret_cast<const ushort *>(str.constData()), str.length());
}
-template<> inline char *toString(const QString &str)
+template<> inline char *toString(const QLatin1String &str)
{
- return qstrdup(qPrintable(str));
+ return toString(QString(str));
}
template<> inline char *toString(const QByteArray &ba)
@@ -195,15 +195,15 @@ inline bool qCompare(QList<T> const &t1, QList<T> const &t2, const char *actual,
const int expectedSize = t2.count();
if (actualSize != expectedSize) {
qsnprintf(msg, sizeof(msg), "Compared lists have different sizes.\n"
- " Actual (%s) size: '%d'\n"
- " Expected (%s) size: '%d'", actual, actualSize, expected, expectedSize);
+ " Actual (%s) size: %d\n"
+ " Expected (%s) size: %d", actual, actualSize, expected, expectedSize);
isOk = false;
}
for (int i = 0; isOk && i < actualSize; ++i) {
if (!(t1.at(i) == t2.at(i))) {
qsnprintf(msg, sizeof(msg), "Compared lists differ at index %d.\n"
- " Actual (%s): '%s'\n"
- " Expected (%s): '%s'", i, actual, toString(t1.at(i)),
+ " Actual (%s): %s\n"
+ " Expected (%s): %s", i, actual, toString(t1.at(i)),
expected, toString(t2.at(i)));
isOk = false;
}
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index e170d2a044..6c1df8815c 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -165,6 +165,25 @@ QT_BEGIN_NAMESPACE
\sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
*/
+/*! \macro QVERIFY_EXCEPTION_THROWN(expression, exceptiontype)
+ \since 5.3
+
+ \relates QTest
+
+ The QVERIFY_EXCEPTION_THROWN macro executes an \a expression and tries
+ to catch an exception thrown from the \a expression. If the \a expression
+ throws an exception and its type is the same as \a exceptiontype
+ or \a exceptiontype is substitutable with the type of thrown exception
+ (i.e. usually the type of thrown exception is publically derived
+ from \a exceptiontype) then execution will be continued. If not-substitutable
+ type of exception is thrown or the \a expression doesn't throw an exception
+ at all, then a failure will be recorded in the test log and
+ the test won't be executed further.
+
+ \note This macro can only be used in a test function that is invoked
+ by the test framework.
+*/
+
/*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
\since 5.0
@@ -1301,6 +1320,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" Use - to output to stdout\n"
" Valid formats are:\n"
" txt : Plain text\n"
+ " csv : CSV format (suitable for benchmarks)\n"
" xunitxml : XML XUnit document\n"
" xml : XML document\n"
" lightxml : A stream of XML tags\n"
@@ -1310,6 +1330,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
" Old-style logging options:\n"
" -o filename : Write the output into file\n"
" -txt : Output results in Plain Text\n"
+ " -csv : Output results in a CSV format (suitable for benchmarks)\n"
" -xunitxml : Output results as XML XUnit document\n"
" -xml : Output results as XML document\n"
" -lightxml : Output results as stream of XML tags\n"
@@ -1389,6 +1410,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
}
} else if (strcmp(argv[i], "-txt") == 0) {
logFormat = QTestLog::Plain;
+ } else if (strcmp(argv[i], "-csv") == 0) {
+ logFormat = QTestLog::CSV;
} else if (strcmp(argv[i], "-xunitxml") == 0) {
logFormat = QTestLog::XunitXML;
} else if (strcmp(argv[i], "-xml") == 0) {
@@ -1419,6 +1442,8 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
// New-style
if (strcmp(format, "txt") == 0)
logFormat = QTestLog::Plain;
+ else if (strcmp(format, "csv") == 0)
+ logFormat = QTestLog::CSV;
else if (strcmp(format, "lightxml") == 0)
logFormat = QTestLog::LightXML;
else if (strcmp(format, "xml") == 0)
@@ -1426,7 +1451,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
else if (strcmp(format, "xunitxml") == 0)
logFormat = QTestLog::XunitXML;
else {
- fprintf(stderr, "output format must be one of txt, lightxml, xml or xunitxml\n");
+ fprintf(stderr, "output format must be one of txt, csv, lightxml, xml or xunitxml\n");
exit(1);
}
if (strcmp(filename, "-") == 0 && QTestLog::loggerUsingStdout()) {
@@ -1540,6 +1565,10 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
} else if (strcmp(argv[i], "-vb") == 0) {
QBenchmarkGlobalData::current->verboseOutput = true;
+#ifdef Q_OS_WINRT
+ } else if (strncmp(argv[i], "-ServerName:", 12) == 0) {
+ continue;
+#endif
} else if (argv[i][0] == '-') {
fprintf(stderr, "Unknown option: '%s'\n\n%s", argv[i], testOptions);
if (qml) {
@@ -1865,6 +1894,12 @@ void *fetchData(QTestData *data, const char *tagName, int typeId)
return data->data(idx);
}
+static char toHex(ushort value)
+{
+ static const char hexdigits[] = "0123456789ABCDEF";
+ return hexdigits[value & 0xF];
+}
+
/*!
\fn char* QTest::toHexRepresentation(const char *ba, int length)
@@ -1908,16 +1943,15 @@ char *toHexRepresentation(const char *ba, int length)
result[size - 1] = '\0';
}
- const char toHex[] = "0123456789ABCDEF";
int i = 0;
int o = 0;
while (true) {
const char at = ba[i];
- result[o] = toHex[(at >> 4) & 0x0F];
+ result[o] = toHex(at >> 4);
++o;
- result[o] = toHex[at & 0x0F];
+ result[o] = toHex(at);
++i;
++o;
@@ -1932,6 +1966,61 @@ char *toHexRepresentation(const char *ba, int length)
return result;
}
+/*!
+ \internal
+ Returns the same QString but with only the ASCII characters still shown;
+ everything else is replaced with \c {\uXXXX}.
+*/
+char *toPrettyUnicode(const ushort *p, int length)
+{
+ // keep it simple for the vast majority of cases
+ QScopedArrayPointer<char> buffer(new char[length * 6 + 3]);
+ const ushort *end = p + length;
+ char *dst = buffer.data();
+
+ *dst++ = '"';
+ for ( ; p != end; ++p) {
+ if (*p < 0x7f && *p >= 0x20 && *p != '\\') {
+ *dst++ = *p;
+ continue;
+ }
+
+ // write as an escape sequence
+ *dst++ = '\\';
+ switch (*p) {
+ case 0x22:
+ case 0x5c:
+ *dst++ = uchar(*p);
+ break;
+ case 0x8:
+ *dst++ = 'b';
+ break;
+ case 0xc:
+ *dst++ = 'f';
+ break;
+ case 0xa:
+ *dst++ = 'n';
+ break;
+ case 0xd:
+ *dst++ = 'r';
+ break;
+ case 0x9:
+ *dst++ = 't';
+ break;
+ default:
+ *dst++ = 'u';
+ *dst++ = toHex(*p >> 12);
+ *dst++ = toHex(*p >> 8);
+ *dst++ = toHex(*p >> 4);
+ *dst++ = toHex(*p);
+ }
+ }
+
+ *dst++ = '"';
+ *dst++ = '\0';
+ return buffer.take();
+}
+
static void qInvokeTestMethods(QObject *testObject)
{
const QMetaObject *metaObject = testObject->metaObject();
@@ -2170,13 +2259,15 @@ int QTest::qExec(QObject *testObject, int argc, char **argv)
qtest_qParseArgs(argc, argv, false);
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
if (!noCrashHandler) {
# ifndef Q_CC_MINGW
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
# endif
+# ifndef Q_OS_WINRT
SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter(windowsFaultHandler);
+# endif
} // !noCrashHandler
#endif // Q_OS_WIN) && !Q_OS_WINCE && !Q_OS_WINRT
@@ -2325,6 +2416,27 @@ void QTest::ignoreMessage(QtMsgType type, const char *message)
QTestLog::ignoreMessage(type, message);
}
+/*!
+ \overload
+
+ Ignores messages created by qDebug() or qWarning(). If the \a message
+ matching \a messagePattern
+ with the corresponding \a type is outputted, it will be removed from the
+ test log. If the test finished and the \a message was not outputted,
+ a test failure is appended to the test log.
+
+ \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.
+
+ \since 5.3
+*/
+
+void QTest::ignoreMessage(QtMsgType type, const QRegularExpression &messagePattern)
+{
+ QTestLog::ignoreMessage(type, messagePattern);
+}
+
/*! \internal
*/
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index ba727b5afe..b715d83383 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -51,8 +51,14 @@
#include <string.h>
+#ifndef QT_NO_EXCEPTIONS
+# include <exception>
+#endif // QT_NO_EXCEPTIONS
+
+
QT_BEGIN_NAMESPACE
+class QRegularExpression;
#define QVERIFY(statement) \
do {\
@@ -83,34 +89,84 @@ do {\
return;\
} while (0)
-// Will try to wait for the expression to become true while allowing event processing
-#define QTRY_VERIFY_WITH_TIMEOUT(__expr, __timeout) \
-do { \
- const int __step = 50; \
- const int __timeoutValue = __timeout; \
+
+#ifndef QT_NO_EXCEPTIONS
+
+# define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
+ do {\
+ QT_TRY {\
+ QT_TRY {\
+ expression;\
+ QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
+ " but no exception caught", __FILE__, __LINE__);\
+ return;\
+ } QT_CATCH (const exceptiontype &) {\
+ }\
+ } QT_CATCH (const std::exception &e) {\
+ QByteArray msg = QByteArray() + "Expected exception of type " #exceptiontype \
+ " to be thrown but std::exception caught with message: " + e.what(); \
+ QTest::qFail(msg.constData(), __FILE__, __LINE__);\
+ return;\
+ } QT_CATCH (...) {\
+ QTest::qFail("Expected exception of type " #exceptiontype " to be thrown" \
+ " but unknown exception caught", __FILE__, __LINE__);\
+ return;\
+ }\
+ } while (0)
+
+#else // QT_NO_EXCEPTIONS
+
+/*
+ * The expression passed to the macro should throw an exception and we can't
+ * catch it because Qt has been compiled without exception support. We can't
+ * skip the expression because it may have side effects and must be executed.
+ * So, users must use Qt with exception support enabled if they use exceptions
+ * in their code.
+ */
+# define QVERIFY_EXCEPTION_THROWN(expression, exceptiontype) \
+ Q_STATIC_ASSERT_X(false, "Support of exceptions is disabled")
+
+#endif // !QT_NO_EXCEPTIONS
+
+
+#define QTRY_LOOP_IMPL(__expr, __timeoutValue, __step) \
if (!(__expr)) { \
QTest::qWait(0); \
} \
- for (int __i = 0; __i < __timeoutValue && !(__expr); __i+=__step) { \
+ int __i = 0; \
+ for (; __i < __timeoutValue && !(__expr); __i += __step) { \
QTest::qWait(__step); \
- } \
+ }
+
+#define QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\
+ if (!(__expr)) { \
+ QTRY_LOOP_IMPL(__expr, (2 * __timeoutValue), __step);\
+ if (__expr) { \
+ QString msg = QString::fromUtf8("QTestLib: This test case check (\"%1\") failed because the requested timeout (%2 ms) was too short, %3 ms would have been sufficient this time."); \
+ msg = msg.arg(QString::fromUtf8(#__expr)).arg(__timeoutValue).arg(__timeoutValue + __i); \
+ QFAIL(qPrintable(msg)); \
+ } \
+ }
+
+#define QTRY_IMPL(__expr, __timeout)\
+ const int __step = 50; \
+ const int __timeoutValue = __timeout; \
+ QTRY_LOOP_IMPL(__expr, __timeoutValue, __step); \
+ QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\
+
+// Will try to wait for the expression to become true while allowing event processing
+#define QTRY_VERIFY_WITH_TIMEOUT(__expr, __timeout) \
+do { \
+ QTRY_IMPL(__expr, __timeout);\
QVERIFY(__expr); \
} while (0)
#define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT(__expr, 5000)
// Will try to wait for the comparison to become successful while allowing event processing
-
#define QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, __timeout) \
do { \
- const int __step = 50; \
- const int __timeoutValue = __timeout; \
- if ((__expr) != (__expected)) { \
- QTest::qWait(0); \
- } \
- for (int __i = 0; __i < __timeoutValue && ((__expr) != (__expected)); __i+=__step) { \
- QTest::qWait(__step); \
- } \
+ QTRY_IMPL(((__expr) == (__expected)), __timeout);\
QCOMPARE(__expr, __expected); \
} while (0)
@@ -177,6 +233,7 @@ namespace QTest
Q_TESTLIB_EXPORT char *toHexRepresentation(const char *ba, int length);
+ Q_TESTLIB_EXPORT char *toPrettyUnicode(const ushort *unicode, int length);
Q_TESTLIB_EXPORT char *toString(const char *);
Q_TESTLIB_EXPORT char *toString(const void *);
@@ -191,6 +248,7 @@ namespace QTest
const char *file, int line);
Q_TESTLIB_EXPORT void qWarn(const char *message, const char *file = 0, int line = 0);
Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const char *message);
+ Q_TESTLIB_EXPORT void ignoreMessage(QtMsgType type, const QRegularExpression &messagePattern);
Q_TESTLIB_EXPORT QString qFindTestData(const char* basepath, const char* file = 0, int line = 0, const char* builddir = 0);
Q_TESTLIB_EXPORT QString qFindTestData(const QString& basepath, const char* file = 0, int line = 0, const char* builddir = 0);
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp
index bbca5b94e5..8cca892a4d 100644
--- a/src/testlib/qtestlog.cpp
+++ b/src/testlib/qtestlog.cpp
@@ -45,10 +45,13 @@
#include <QtTest/private/qtestresult_p.h>
#include <QtTest/private/qabstracttestlogger_p.h>
#include <QtTest/private/qplaintestlogger_p.h>
+#include <QtTest/private/qcsvbenchmarklogger_p.h>
#include <QtTest/private/qxunittestlogger_p.h>
#include <QtTest/private/qxmltestlogger_p.h>
#include <QtCore/qatomic.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/QVariant>
+#include <QtCore/QRegularExpression>
#include <stdlib.h>
#include <string.h>
@@ -86,11 +89,8 @@ namespace QTest {
struct IgnoreResultList
{
- inline IgnoreResultList(QtMsgType tp, const char *message)
- : type(tp), next(0)
- { msg = qstrdup(message); }
- inline ~IgnoreResultList()
- { delete [] msg; }
+ inline IgnoreResultList(QtMsgType tp, const QVariant &patternIn)
+ : type(tp), pattern(patternIn), next(0) {}
static inline void clearList(IgnoreResultList *&list)
{
@@ -101,8 +101,43 @@ namespace QTest {
}
}
+ static void append(IgnoreResultList *&list, QtMsgType type, const QVariant &patternIn)
+ {
+ QTest::IgnoreResultList *item = new QTest::IgnoreResultList(type, patternIn);
+
+ if (!list) {
+ list = item;
+ return;
+ }
+ IgnoreResultList *last = list;
+ for ( ; last->next; last = last->next) ;
+ last->next = item;
+ }
+
+ static bool stringsMatch(const QString &expected, const QString &actual)
+ {
+ if (expected == actual)
+ return true;
+
+ // ignore an optional whitespace at the end of str
+ // (the space was added automatically by ~QDebug() until Qt 5.3,
+ // so autotests still might expect it)
+ if (expected.endsWith(QLatin1Char(' ')))
+ return actual == expected.leftRef(expected.length() - 1);
+
+ return false;
+ }
+
+ inline bool matches(QtMsgType tp, const QString &message) const
+ {
+ return tp == type
+ && (pattern.type() == QVariant::String ?
+ stringsMatch(pattern.toString(), message) :
+ pattern.toRegularExpression().match(message).hasMatch());
+ }
+
QtMsgType type;
- char *msg;
+ QVariant pattern;
IgnoreResultList *next;
};
@@ -175,7 +210,7 @@ namespace QTest {
FOREACH_LOGGER(logger->addBenchmarkResult(result));
}
- static void addMessage(QAbstractTestLogger::MessageTypes type, const char *message,
+ static void addMessage(QAbstractTestLogger::MessageTypes type, const QString &message,
const char *file = 0, int line = 0)
{
FOREACH_LOGGER(logger->addMessage(type, message, file, line));
@@ -208,12 +243,14 @@ namespace QTest {
static QtMessageHandler oldMessageHandler;
- static bool handleIgnoredMessage(QtMsgType type, const char *msg)
+ static bool handleIgnoredMessage(QtMsgType type, const QString &message)
{
+ if (!ignoreResultList)
+ return false;
IgnoreResultList *last = 0;
IgnoreResultList *list = ignoreResultList;
while (list) {
- if (list->type == type && strcmp(msg, list->msg) == 0) {
+ if (list->matches(type, message)) {
// remove the item from the list
if (last)
last->next = list->next;
@@ -242,12 +279,11 @@ namespace QTest {
QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0);
}
- QByteArray msg = message.toLocal8Bit();
- if (handleIgnoredMessage(type, msg))
+ if (handleIgnoredMessage(type, message))
// the message is expected, so just swallow it.
return;
- msg = qMessageFormatString(type, context, message).toLocal8Bit();
+ QString msg = qMessageFormatString(type, context, message);
msg.chop(1); // remove trailing newline
if (type != QtFatalMsg) {
@@ -256,7 +292,7 @@ namespace QTest {
if (!counter.deref()) {
QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem,
- "Maximum amount of warnings exceeded. Use -maxwarnings to override.");
+ QStringLiteral("Maximum amount of warnings exceeded. Use -maxwarnings to override."));
return;
}
}
@@ -317,11 +353,15 @@ void QTestLog::leaveTestFunction()
void QTestLog::printUnhandledIgnoreMessages()
{
- char msg[1024];
+ QString message;
QTest::IgnoreResultList *list = QTest::ignoreResultList;
while (list) {
- qsnprintf(msg, 1024, "Did not receive message: \"%s\"", list->msg);
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, msg);
+ if (list->pattern.type() == QVariant::String) {
+ message = QStringLiteral("Did not receive message: \"") + list->pattern.toString() + QLatin1Char('"');
+ } else {
+ message = QStringLiteral("Did not receive any message matching: \"") + list->pattern.toRegularExpression().pattern() + QLatin1Char('"');
+ }
+ QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, message);
list = list->next;
}
@@ -378,7 +418,7 @@ void QTestLog::addSkip(const char *msg, const char *file, int line)
++QTest::skips;
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Skip, msg, file, line);
+ QTest::TestLoggers::addMessage(QAbstractTestLogger::Skip, QString::fromUtf8(msg), file, line);
}
void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
@@ -413,6 +453,9 @@ void QTestLog::addLogger(LogMode mode, const char *filename)
case QTestLog::Plain:
logger = new QPlainTestLogger(filename);
break;
+ case QTestLog::CSV:
+ logger = new QCsvBenchmarkLogger(filename);
+ break;
case QTestLog::XML:
logger = new QXmlTestLogger(QXmlTestLogger::Complete, filename);
break;
@@ -442,14 +485,14 @@ void QTestLog::warn(const char *msg, const char *file, int line)
QTEST_ASSERT(msg);
if (QTest::TestLoggers::loggerCount() > 0)
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Warn, msg, file, line);
+ QTest::TestLoggers::addMessage(QAbstractTestLogger::Warn, QString::fromUtf8(msg), file, line);
}
void QTestLog::info(const char *msg, const char *file, int line)
{
QTEST_ASSERT(msg);
- QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, msg, file, line);
+ QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, QString::fromUtf8(msg), file, line);
}
void QTestLog::setVerboseLevel(int level)
@@ -466,16 +509,14 @@ void QTestLog::ignoreMessage(QtMsgType type, const char *msg)
{
QTEST_ASSERT(msg);
- QTest::IgnoreResultList *item = new QTest::IgnoreResultList(type, msg);
+ QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QString::fromLocal8Bit(msg));
+}
+
+void QTestLog::ignoreMessage(QtMsgType type, const QRegularExpression &expression)
+{
+ QTEST_ASSERT(expression.isValid());
- QTest::IgnoreResultList *list = QTest::ignoreResultList;
- if (!list) {
- QTest::ignoreResultList = item;
- return;
- }
- while (list->next)
- list = list->next;
- list->next = item;
+ QTest::IgnoreResultList::append(QTest::ignoreResultList, type, QVariant(expression));
}
void QTestLog::setMaxWarnings(int m)
diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h
index df3e2ab5d4..a987c45806 100644
--- a/src/testlib/qtestlog_p.h
+++ b/src/testlib/qtestlog_p.h
@@ -58,11 +58,12 @@
QT_BEGIN_NAMESPACE
class QBenchmarkResult;
+class QRegularExpression;
class Q_TESTLIB_EXPORT QTestLog
{
public:
- enum LogMode { Plain = 0, XML, LightXML, XunitXML };
+ enum LogMode { Plain = 0, XML, LightXML, XunitXML, CSV };
static void enterTestFunction(const char* function);
static void leaveTestFunction();
@@ -75,6 +76,7 @@ public:
static void addBenchmarkResult(const QBenchmarkResult &result);
static void ignoreMessage(QtMsgType type, const char *msg);
+ static void ignoreMessage(QtMsgType type, const QRegularExpression &expression);
static int unhandledIgnoreMessages();
static void printUnhandledIgnoreMessages();
static void clearIgnoreMessages();
diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp
index 3f77f152b5..3fff753c5c 100644
--- a/src/testlib/qxmltestlogger.cpp
+++ b/src/testlib/qxmltestlogger.cpp
@@ -121,10 +121,16 @@ void QXmlTestLogger::startLogging()
" <QTestVersion>" QTEST_VERSION_STR "</QTestVersion>\n"
"</Environment>\n", qVersion());
outputString(buf.constData());
+ m_totalTime.start();
}
void QXmlTestLogger::stopLogging()
{
+ QTestCharBuffer buf;
+ QTest::qt_asprintf(&buf,
+ "<Duration msecs=\"%f\"/>\n",
+ m_totalTime.nsecsElapsed() / 1000000.);
+ outputString(buf.constData());
if (xmlmode == QXmlTestLogger::Complete) {
outputString("</TestCase>\n");
}
@@ -139,11 +145,19 @@ void QXmlTestLogger::enterTestFunction(const char *function)
xmlQuote(&quotedFunction, function);
QTest::qt_asprintf(&buf, "<TestFunction name=\"%s\">\n", quotedFunction.constData());
outputString(buf.constData());
+
+ m_functionTime.start();
}
void QXmlTestLogger::leaveTestFunction()
{
- outputString("</TestFunction>\n");
+ QTestCharBuffer buf;
+ QTest::qt_asprintf(&buf,
+ " <Duration msecs=\"%f\"/>\n"
+ "</TestFunction>\n",
+ m_functionTime.nsecsElapsed() / 1000000.);
+
+ outputString(buf.constData());
}
namespace QTest
@@ -257,7 +271,7 @@ void QXmlTestLogger::addBenchmarkResult(const QBenchmarkResult &result)
outputString(buf.constData());
}
-void QXmlTestLogger::addMessage(MessageTypes type, const char *message,
+void QXmlTestLogger::addMessage(MessageTypes type, const QString &message,
const char *file, int line)
{
QTestCharBuffer buf;
@@ -274,10 +288,10 @@ void QXmlTestLogger::addMessage(MessageTypes type, const char *message,
xmlQuote(&quotedFile, file);
xmlCdata(&cdataGtag, gtag);
xmlCdata(&cdataTag, tag);
- xmlCdata(&cdataDescription, message);
+ xmlCdata(&cdataDescription, message.toUtf8().constData());
QTest::qt_asprintf(&buf,
- QTest::messageFormatString(QTest::isEmpty(message), notag),
+ QTest::messageFormatString(message.isEmpty(), notag),
QTest::xmlMessageType2String(type),
quotedFile.constData(), line,
cdataGtag.constData(),
diff --git a/src/testlib/qxmltestlogger_p.h b/src/testlib/qxmltestlogger_p.h
index ba0185a2b3..8ca15e47e2 100644
--- a/src/testlib/qxmltestlogger_p.h
+++ b/src/testlib/qxmltestlogger_p.h
@@ -55,6 +55,7 @@
#include <QtTest/private/qabstracttestlogger_p.h>
+#include <QtCore/qelapsedtimer.h>
QT_BEGIN_NAMESPACE
@@ -76,7 +77,7 @@ public:
const char *file = 0, int line = 0);
void addBenchmarkResult(const QBenchmarkResult &result);
- void addMessage(MessageTypes type, const char *message,
+ void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0);
static int xmlCdata(QTestCharBuffer *dest, char const* src);
@@ -86,6 +87,8 @@ public:
private:
XmlMode xmlmode;
+ QElapsedTimer m_functionTime;
+ QElapsedTimer m_totalTime;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qxunittestlogger.cpp b/src/testlib/qxunittestlogger.cpp
index 0a1a5fb6f9..a47f77ae49 100644
--- a/src/testlib/qxunittestlogger.cpp
+++ b/src/testlib/qxunittestlogger.cpp
@@ -220,7 +220,7 @@ void QXunitTestLogger::addIncident(IncidentTypes type, const char *description,
have some information about the expected failure.
*/
if (type == QAbstractTestLogger::XFail) {
- QXunitTestLogger::addMessage(QAbstractTestLogger::Info, description, file, line);
+ QXunitTestLogger::addMessage(QAbstractTestLogger::Info, QString::fromUtf8(description), file, line);
}
}
@@ -263,7 +263,7 @@ void QXunitTestLogger::addTag(QTestElement* element)
element->addAttribute(QTest::AI_Tag, buf.constData());
}
-void QXunitTestLogger::addMessage(MessageTypes type, const char *message, const char *file, int line)
+void QXunitTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line)
{
QTestElement *errorElement = new QTestElement(QTest::LET_Error);
const char *typeBuf = 0;
@@ -296,7 +296,7 @@ void QXunitTestLogger::addMessage(MessageTypes type, const char *message, const
}
errorElement->addAttribute(QTest::AI_Type, typeBuf);
- errorElement->addAttribute(QTest::AI_Description, message);
+ errorElement->addAttribute(QTest::AI_Description, message.toUtf8().constData());
addTag(errorElement);
if (file)
@@ -314,7 +314,7 @@ void QXunitTestLogger::addMessage(MessageTypes type, const char *message, const
// Also add the message to the system error log (i.e. stderr), if one exists
if (errorLogElement) {
QTestElement *systemErrorElement = new QTestElement(QTest::LET_Error);
- systemErrorElement->addAttribute(QTest::AI_Description, message);
+ systemErrorElement->addAttribute(QTest::AI_Description, message.toUtf8().constData());
errorLogElement->addLogElement(systemErrorElement);
}
}
diff --git a/src/testlib/qxunittestlogger_p.h b/src/testlib/qxunittestlogger_p.h
index 2c39fa952c..754462473a 100644
--- a/src/testlib/qxunittestlogger_p.h
+++ b/src/testlib/qxunittestlogger_p.h
@@ -77,7 +77,7 @@ class QXunitTestLogger : public QAbstractTestLogger
void addBenchmarkResult(const QBenchmarkResult &result);
void addTag(QTestElement* element);
- void addMessage(MessageTypes type, const char *message,
+ void addMessage(MessageTypes type, const QString &message,
const char *file = 0, int line = 0);
private:
diff --git a/src/testlib/testlib.pro b/src/testlib/testlib.pro
index 571e3b2fca..1fb6d6df18 100644
--- a/src/testlib/testlib.pro
+++ b/src/testlib/testlib.pro
@@ -33,7 +33,7 @@ HEADERS = qbenchmark.h \
qtestmouse.h \
qtestspontaneevent.h \
qtestsystem.h \
- qtesttouch.h \
+ qtesttouch.h
SOURCES = qtestcase.cpp \
qtestlog.cpp \
@@ -51,6 +51,7 @@ SOURCES = qtestcase.cpp \
qbenchmarkevent.cpp \
qbenchmarkperfevents.cpp \
qbenchmarkmetric.cpp \
+ qcsvbenchmarklogger.cpp \
qtestelement.cpp \
qtestelementattribute.cpp \
qtestxunitstreamer.cpp \
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index dd5189758d..fea4e2519f 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -5,7 +5,7 @@ QT =
CONFIG += internal_module force_bootstrap
# otherwise mingw headers do not declare common functions like putenv
-win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
+mingw:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
MODULE_DEFINES = \
QT_BOOTSTRAPPED \
@@ -74,6 +74,8 @@ SOURCES += \
../../corelib/io/qtemporaryfile.cpp \
../../corelib/io/qtextstream.cpp \
../../corelib/io/qstandardpaths.cpp \
+ ../../corelib/io/qloggingcategory.cpp \
+ ../../corelib/io/qloggingregistry.cpp \
../../corelib/kernel/qcoreapplication.cpp \
../../corelib/kernel/qcoreglobaldata.cpp \
../../corelib/kernel/qmetatype.cpp \
@@ -100,6 +102,7 @@ SOURCES += \
../../corelib/tools/qsize.cpp \
../../corelib/tools/qline.cpp \
../../corelib/tools/qstring.cpp \
+ ../../corelib/tools/qstring_compat.cpp \
../../corelib/tools/qstringlist.cpp \
../../corelib/tools/qvector.cpp \
../../corelib/tools/qvsnprintf.cpp \
@@ -147,7 +150,7 @@ macx {
if(contains(QT_CONFIG, zlib)|cross_compile):include(../../3rdparty/zlib.pri)
else:include(../../3rdparty/zlib_dependency.pri)
-win32:LIBS += -luser32 -lole32 -ladvapi32
+win32:LIBS += -luser32 -lole32 -ladvapi32 -lshell32
lib.CONFIG = dummy_install
INSTALLS += lib
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index b39a3b5e9f..d831edfef0 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -87,8 +87,9 @@ QT_FOR_EACH_STATIC_TYPE(RETURN_METATYPENAME_STRING)
return 0;
}
-Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QSet<QByteArray> &knownQObjectClasses, FILE *outfile)
+Generator::Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile)
: out(outfile), cdef(classDef), metaTypes(metaTypes), knownQObjectClasses(knownQObjectClasses)
+ , knownGadgets(knownGadgets)
{
if (cdef->superclassList.size())
purestSuperClass = cdef->superclassList.first().first;
@@ -243,7 +244,7 @@ void Generator::generateCode()
int len = 0;
for (int i = 0; i < strings.size(); ++i)
len += strings.at(i).length() + 1;
- fprintf(out, " char stringdata[%d];\n", len + 1);
+ fprintf(out, " char stringdata[%d];\n", len);
}
fprintf(out, "};\n");
@@ -254,8 +255,8 @@ void Generator::generateCode()
// QByteArrayData::data() implementation returning simply "this + offset".
fprintf(out, "#define QT_MOC_LITERAL(idx, ofs, len) \\\n"
" Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\\n"
- " offsetof(qt_meta_stringdata_%s_t, stringdata) + ofs \\\n"
- " - idx * sizeof(QByteArrayData) \\\n"
+ " qptrdiff(offsetof(qt_meta_stringdata_%s_t, stringdata) + ofs \\\n"
+ " - idx * sizeof(QByteArrayData)) \\\n"
" )\n",
qualifiedClassNameIdentifier.constData());
@@ -315,7 +316,8 @@ void Generator::generateCode()
col += spanLen;
}
- fputs("\\0", out);
+ if (i != strings.size() - 1) // skip the last \0 the c++ will add it for us
+ fputs("\\0", out);
col += len + 2;
}
@@ -436,17 +438,46 @@ void Generator::generateCode()
// Build extra array
//
QList<QByteArray> extraList;
+ QHash<QByteArray, QByteArray> knownExtraMetaObject = knownGadgets;
+ knownExtraMetaObject.unite(knownQObjectClasses);
+
for (int i = 0; i < cdef->propertyList.count(); ++i) {
const PropertyDef &p = cdef->propertyList.at(i);
- if (!isBuiltinType(p.type) && !metaTypes.contains(p.type) && !p.type.contains('*') &&
- !p.type.contains('<') && !p.type.contains('>')) {
- int s = p.type.lastIndexOf("::");
- if (s > 0) {
- QByteArray scope = p.type.left(s);
- if (scope != "Qt" && !qualifiedNameEquals(cdef->qualified, scope) && !extraList.contains(scope))
- extraList += scope;
- }
- }
+ if (isBuiltinType(p.type))
+ continue;
+
+ if (p.type.contains('*') || p.type.contains('<') || p.type.contains('>'))
+ continue;
+
+ int s = p.type.lastIndexOf("::");
+ if (s <= 0)
+ continue;
+
+ QByteArray unqualifiedScope = p.type.left(s);
+
+ // The scope may be a namespace for example, so it's only safe to include scopes that are known QObjects (QTBUG-2151)
+ QHash<QByteArray, QByteArray>::ConstIterator scopeIt;
+
+ QByteArray thisScope = cdef->qualified;
+ do {
+ int s = thisScope.lastIndexOf("::");
+ thisScope = thisScope.left(s);
+ QByteArray currentScope = thisScope.isEmpty() ? unqualifiedScope : thisScope + "::" + unqualifiedScope;
+ scopeIt = knownExtraMetaObject.constFind(currentScope);
+ } while (!thisScope.isEmpty() && scopeIt == knownExtraMetaObject.constEnd());
+
+ if (scopeIt == knownExtraMetaObject.constEnd())
+ continue;
+
+ const QByteArray &scope = *scopeIt;
+
+ if (scope == "Qt")
+ continue;
+ if (qualifiedNameEquals(cdef->qualified, scope))
+ continue;
+
+ if (!extraList.contains(scope))
+ extraList += scope;
}
// QTBUG-20639 - Accept non-local enums for QML signal/slot parameters.
@@ -464,7 +495,7 @@ void Generator::generateCode()
}
if (!extraList.isEmpty()) {
- fprintf(out, "static const QMetaObject *qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
+ fprintf(out, "static const QMetaObject * const qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData());
for (int i = 0; i < extraList.count(); ++i) {
fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData());
}
@@ -610,31 +641,38 @@ void Generator::generateFunctions(const QList<FunctionDef>& list, const char *fu
for (int i = 0; i < list.count(); ++i) {
const FunctionDef &f = list.at(i);
+ QByteArray comment;
unsigned char flags = type;
- if (f.access == FunctionDef::Private)
+ if (f.access == FunctionDef::Private) {
flags |= AccessPrivate;
- else if (f.access == FunctionDef::Public)
+ comment.append(QByteArrayLiteral("Private"));
+ } else if (f.access == FunctionDef::Public) {
flags |= AccessPublic;
- else if (f.access == FunctionDef::Protected)
+ comment.append(QByteArrayLiteral("Public"));
+ } else if (f.access == FunctionDef::Protected) {
flags |= AccessProtected;
- if (f.access == FunctionDef::Private)
- flags |= AccessPrivate;
- else if (f.access == FunctionDef::Public)
- flags |= AccessPublic;
- else if (f.access == FunctionDef::Protected)
- flags |= AccessProtected;
- if (f.isCompat)
+ comment.append(QByteArrayLiteral("Protected"));
+ }
+ if (f.isCompat) {
flags |= MethodCompatibility;
- if (f.wasCloned)
+ comment.append(QByteArrayLiteral(" | MethodCompatibility"));
+ }
+ if (f.wasCloned) {
flags |= MethodCloned;
- if (f.isScriptable)
+ comment.append(QByteArrayLiteral(" | MethodCloned"));
+ }
+ if (f.isScriptable) {
flags |= MethodScriptable;
- if (f.revision > 0)
+ comment.append(QByteArrayLiteral(" | isScriptable"));
+ }
+ if (f.revision > 0) {
flags |= MethodRevisioned;
+ comment.append(QByteArrayLiteral(" | MethodRevisioned"));
+ }
int argc = f.arguments.count();
- fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x,\n",
- stridx(f.name), argc, paramsIndex, stridx(f.tag), flags);
+ fprintf(out, " %4d, %4d, %4d, %4d, 0x%02x /* %s */,\n",
+ stridx(f.name), argc, paramsIndex, stridx(f.tag), flags, comment.constData());
paramsIndex += 1 + argc * 2;
}
diff --git a/src/tools/moc/generator.h b/src/tools/moc/generator.h
index 203c856b7c..a01ec5860b 100644
--- a/src/tools/moc/generator.h
+++ b/src/tools/moc/generator.h
@@ -52,7 +52,7 @@ class Generator
ClassDef *cdef;
QVector<uint> meta_data;
public:
- Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QSet<QByteArray> &knownQObjectClasses, FILE *outfile = 0);
+ Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, const QHash<QByteArray, QByteArray> &knownQObjectClasses, const QHash<QByteArray, QByteArray> &knownGadgets, FILE *outfile = 0);
void generateCode();
private:
bool registerableMetaType(const QByteArray &propertyType);
@@ -79,7 +79,8 @@ private:
QList<QByteArray> strings;
QByteArray purestSuperClass;
QList<QByteArray> metaTypes;
- QSet<QByteArray> knownQObjectClasses;
+ QHash<QByteArray, QByteArray> knownQObjectClasses;
+ QHash<QByteArray, QByteArray> knownGadgets;
};
QT_END_NAMESPACE
diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp
index 9f5bd46ef4..bdeb5477a7 100644
--- a/src/tools/moc/main.cpp
+++ b/src/tools/moc/main.cpp
@@ -295,7 +295,7 @@ int runMoc(int argc, char **argv)
const QStringList files = parser.positionalArguments();
if (files.count() > 1) {
- error("Too many input files specified");
+ error(qPrintable(QStringLiteral("Too many input files specified: '") + files.join(QStringLiteral("' '")) + QLatin1Char('\'')));
parser.showHelp(1);
} else if (!files.isEmpty()) {
filename = files.first();
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index b26fac5dcf..ea4838c8f2 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -605,21 +605,27 @@ void Moc::parse()
continue;
while (inClass(&def) && hasNext()) {
- if (next() == Q_OBJECT_TOKEN) {
+ switch (next()) {
+ case Q_OBJECT_TOKEN:
def.hasQObject = true;
break;
+ case Q_GADGET_TOKEN:
+ def.hasQGadget = true;
+ break;
+ default: break;
}
}
- if (!def.hasQObject)
+ if (!def.hasQObject && !def.hasQGadget)
continue;
for (int i = namespaceList.size() - 1; i >= 0; --i)
if (inNamespace(&namespaceList.at(i)))
def.qualified.prepend(namespaceList.at(i).name + "::");
- knownQObjectClasses.insert(def.classname);
- knownQObjectClasses.insert(def.qualified);
+ QHash<QByteArray, QByteArray> &classHash = def.hasQObject ? knownQObjectClasses : knownGadgets;
+ classHash.insert(def.classname, def.qualified);
+ classHash.insert(def.qualified, def.qualified);
continue; }
default: break;
@@ -792,8 +798,9 @@ void Moc::parse()
checkProperties(&def);
classList += def;
- knownQObjectClasses.insert(def.classname);
- knownQObjectClasses.insert(def.qualified);
+ QHash<QByteArray, QByteArray> &classHash = def.hasQObject ? knownQObjectClasses : knownGadgets;
+ classHash.insert(def.classname, def.qualified);
+ classHash.insert(def.qualified, def.qualified);
}
}
}
@@ -893,7 +900,7 @@ void Moc::generate(FILE *out)
fprintf(out, "QT_BEGIN_MOC_NAMESPACE\n");
for (i = 0; i < classList.size(); ++i) {
- Generator generator(&classList[i], metaTypes, knownQObjectClasses, out);
+ Generator generator(&classList[i], metaTypes, knownQObjectClasses, knownGadgets, out);
generator.generateCode();
}
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index 2e22435653..e8da24b2bf 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -215,7 +215,9 @@ public:
QList<ClassDef> classList;
QMap<QByteArray, QByteArray> interface2IdMap;
QList<QByteArray> metaTypes;
- QSet<QByteArray> knownQObjectClasses;
+ // map from class name to fully qualified name
+ QHash<QByteArray, QByteArray> knownQObjectClasses;
+ QHash<QByteArray, QByteArray> knownGadgets;
QMap<QString, QJsonArray> metaArgs;
void parse();
diff --git a/src/tools/qlalr/compress.cpp b/src/tools/qlalr/compress.cpp
new file mode 100644
index 0000000000..4ae0716047
--- /dev/null
+++ b/src/tools/qlalr/compress.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "compress.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qlist.h>
+
+#include <algorithm>
+#include <iterator>
+#include <iostream>
+
+#define QLALR_NO_CHECK_SORTED_TABLE
+
+struct _Fit: public std::binary_function<int, int, bool>
+{
+ inline bool operator () (int a, int b) const
+ {
+ return a == 0 || b == 0 || a == b;
+ }
+};
+
+struct _PerfectMatch: public std::binary_function<int, int, bool>
+{
+ inline bool operator () (int a, int b) const
+ { return a == b; }
+};
+
+struct _GenerateCheck
+{
+ QVector<int>::const_iterator iterator;
+ int initial;
+
+ _GenerateCheck (QVector<int>::const_iterator it, int i):
+ iterator (it),
+ initial (i) {}
+
+ inline int operator () ()
+ {
+ int check = initial++;
+ return *iterator++ ? check : -1;
+ }
+};
+
+class UncompressedRow
+{
+public:
+ typedef const int *const_iterator;
+ typedef const int *iterator;
+
+public:
+ inline UncompressedRow ():
+ _M_index (0),
+ _M_begin (0),
+ _M_end (0),
+ _M_beginNonZeros (0),
+ _M_endNonZeros (0) {}
+
+ inline UncompressedRow (int index, const_iterator begin, const_iterator end)
+ { assign (index, begin, end); }
+
+ inline int index () const { return _M_index; }
+ inline const_iterator begin () const { return _M_begin; }
+ inline const_iterator end () const { return _M_end; }
+
+ inline void assign (int index, const_iterator begin, const_iterator end)
+ {
+ _M_index = index;
+ _M_begin = begin;
+ _M_end = end;
+
+ _M_beginNonZeros = _M_begin;
+ _M_endNonZeros = _M_end;
+
+ for (_M_beginNonZeros = _M_begin; _M_beginNonZeros != _M_end && ! _M_beginNonZeros [0]; ++_M_beginNonZeros)
+ /*continue*/ ;
+
+#if 0
+ for (_M_endNonZeros = _M_end; _M_endNonZeros != _M_beginNonZeros && ! _M_endNonZeros [-1]; --_M_endNonZeros)
+ /*continue*/ ;
+#endif
+ }
+
+ inline int at (int index) const
+ { return _M_begin [index]; }
+
+ inline bool isEmpty () const
+ { return _M_begin == _M_end; }
+
+ inline int size () const
+ { return _M_end - _M_begin; }
+
+ inline int nonZeroElements () const
+ { return _M_endNonZeros - _M_beginNonZeros; }
+
+ inline int count (int value) const
+ { return std::count (begin (), end (), value); }
+
+ inline const_iterator beginNonZeros () const
+ { return _M_beginNonZeros; }
+
+ inline const_iterator endNonZeros () const
+ { return _M_endNonZeros; }
+
+private:
+ int _M_index;
+ const_iterator _M_begin;
+ const_iterator _M_end;
+ const_iterator _M_beginNonZeros;
+ const_iterator _M_endNonZeros;
+};
+
+struct _SortUncompressedRow: public std::binary_function<UncompressedRow, UncompressedRow, bool>
+{
+ inline bool operator () (const UncompressedRow &a, const UncompressedRow &b) const
+ { return a.count (0) > b.count (0); }
+};
+
+Compress::Compress ()
+{
+}
+
+void Compress::operator () (int *table, int row_count, int column_count)
+{
+ index.clear ();
+ info.clear ();
+ check.clear ();
+
+ QVector<UncompressedRow> sortedTable (row_count);
+
+ for (int i = 0; i < row_count; ++i)
+ {
+ int *begin = &table [i * column_count];
+ int *end = begin + column_count;
+
+ sortedTable [i].assign (i, begin, end);
+ }
+
+ std::sort (sortedTable.begin (), sortedTable.end (), _SortUncompressedRow ());
+
+#ifndef QLALR_NO_CHECK_SORTED_TABLE
+ int previous_zeros = INT_MAX;
+
+ foreach (UncompressedRow row, sortedTable)
+ {
+ int zeros = row.count (0);
+
+ Q_ASSERT (zeros <= previous_zeros);
+ zeros = previous_zeros;
+ qDebug () << "OK!";
+ }
+#endif
+
+ index.fill (-999999, row_count);
+
+ foreach (UncompressedRow row, sortedTable)
+ {
+ int first_token = std::distance (row.begin (), row.beginNonZeros ());
+ QVector<int>::iterator pos = info.begin ();
+
+ while (pos != info.end ())
+ {
+ if (pos == info.begin ())
+ {
+ // try to find a perfect match
+ QVector<int>::iterator pm = std::search (pos, info.end (), row.beginNonZeros (), row.endNonZeros (), _PerfectMatch ());
+
+ if (pm != info.end ())
+ {
+ pos = pm;
+ break;
+ }
+ }
+
+ pos = std::search (pos, info.end (), row.beginNonZeros (), row.endNonZeros (), _Fit ());
+
+ if (pos == info.end ())
+ break;
+
+ int idx = std::distance (info.begin (), pos) - first_token;
+ bool conflict = false;
+
+ for (int j = 0; ! conflict && j < row.size (); ++j)
+ {
+ if (row.at (j) == 0)
+ conflict |= idx + j >= 0 && check [idx + j] == j;
+
+ else
+ conflict |= check [idx + j] == j;
+ }
+
+ if (! conflict)
+ break;
+
+ ++pos;
+ }
+
+ if (pos == info.end ())
+ {
+ int size = info.size ();
+
+ info.resize (info.size () + row.nonZeroElements ());
+ check.resize (info.size ());
+
+ std::fill (check.begin () + size, check.end (), -1);
+ pos = info.begin () + size;
+ }
+
+ int offset = std::distance (info.begin (), pos);
+ index [row.index ()] = offset - first_token;
+
+ for (const int *it = row.beginNonZeros (); it != row.endNonZeros (); ++it, ++pos)
+ {
+ if (*it)
+ *pos = *it;
+ }
+
+ int i = row.index ();
+
+ for (int j = 0; j < row.size (); ++j)
+ {
+ if (row.at (j) == 0)
+ continue;
+
+ check [index [i] + j] = j;
+ }
+ }
+
+#if 0
+ foreach (UncompressedRow row, sortedTable)
+ {
+ int i = row.index ();
+ Q_ASSERT (i < sortedTable.size ());
+
+ for (int j = 0; j < row.size (); ++j)
+ {
+ if (row.at (j) == 0)
+ {
+ Q_ASSERT (index [i] + j < 0 || check [index [i] + j] != j);
+ continue;
+ }
+
+ Q_ASSERT ( info [index [i] + j] == row.at (j));
+ Q_ASSERT (check [index [i] + j] == j);
+ }
+ }
+#endif
+}
diff --git a/src/tools/qlalr/compress.h b/src/tools/qlalr/compress.h
new file mode 100644
index 0000000000..72f1d1db83
--- /dev/null
+++ b/src/tools/qlalr/compress.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COMPRESS_H
+#define COMPRESS_H
+
+#include <QtCore/qvector.h>
+
+class Compress
+{
+public:
+ Compress ();
+
+ void operator () (int *table, int row_count, int column_count);
+
+public:
+ QVector<int> index;
+ QVector<int> info;
+ QVector<int> check;
+};
+
+#endif // COMPRESS_H
diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp
new file mode 100644
index 0000000000..d48c059397
--- /dev/null
+++ b/src/tools/qlalr/cppgenerator.cpp
@@ -0,0 +1,750 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cppgenerator.h"
+
+#include "lalr.h"
+#include "recognizer.h"
+
+#include <QtCore/qbitarray.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qmap.h>
+
+
+QString CppGenerator::copyrightHeader() const
+{
+ return QLatin1String(
+ "/****************************************************************************\n"
+ "**\n"
+ "** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
+ "** Contact: http://www.qt-project.org/legal\n"
+ "**\n"
+ "** This file is part of the Qt Toolkit.\n"
+ "**\n"
+ "** $QT_BEGIN_LICENSE:LGPL$\n"
+ "** Commercial License Usage\n"
+ "** Licensees holding valid commercial Qt licenses may use this file in\n"
+ "** accordance with the commercial license agreement provided with the\n"
+ "** Software or, alternatively, in accordance with the terms contained in\n"
+ "** a written agreement between you and Digia. For licensing terms and\n"
+ "** conditions see http://qt.digia.com/licensing. For further information\n"
+ "** use the contact form at http://qt.digia.com/contact-us.\n"
+ "**\n"
+ "** GNU Lesser General Public License Usage\n"
+ "** Alternatively, this file may be used under the terms of the GNU Lesser\n"
+ "** General Public License version 2.1 as published by the Free Software\n"
+ "** Foundation and appearing in the file LICENSE.LGPL included in the\n"
+ "** packaging of this file. Please review the following information to\n"
+ "** ensure the GNU Lesser General Public License version 2.1 requirements\n"
+ "** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.\n"
+ "**\n"
+ "** In addition, as a special exception, Digia gives you certain additional\n"
+ "** rights. These rights are described in the Digia Qt LGPL Exception\n"
+ "** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.\n"
+ "**\n"
+ "** GNU General Public License Usage\n"
+ "** Alternatively, this file may be used under the terms of the GNU\n"
+ "** General Public License version 3.0 as published by the Free Software\n"
+ "** Foundation and appearing in the file LICENSE.GPL included in the\n"
+ "** packaging of this file. Please review the following information to\n"
+ "** ensure the GNU General Public License version 3.0 requirements will be\n"
+ "** met: http://www.gnu.org/copyleft/gpl.html.\n"
+ "**\n"
+ "**\n"
+ "** $QT_END_LICENSE$\n"
+ "**\n"
+ "****************************************************************************/\n"
+ "\n");
+}
+
+QString CppGenerator::privateCopyrightHeader() const
+{
+ return QLatin1String(
+ "//\n"
+ "// W A R N I N G\n"
+ "// -------------\n"
+ "//\n"
+ "// This file is not part of the Qt API. It exists for the convenience\n"
+ "// of other Qt classes. This header file may change from version to\n"
+ "// version without notice, or even be removed.\n"
+ "//\n"
+ "// We mean it.\n"
+ "//\n");
+}
+
+QString CppGenerator::startIncludeGuard(const QString &fileName)
+{
+ const QString normalized(QString(fileName).replace(QLatin1Char('.'), QLatin1Char('_')).toUpper());
+
+ return QString::fromLatin1("#ifndef %1\n"
+ "#define %2\n").arg(normalized, normalized);
+}
+
+QString CppGenerator::endIncludeGuard(const QString &fileName)
+{
+ const QString normalized(QString(fileName).replace(QLatin1Char('.'), QLatin1Char('_')).toUpper());
+
+ return QString::fromLatin1("#endif // %1\n").arg(normalized);
+}
+
+void CppGenerator::operator () ()
+{
+ // action table...
+ state_count = aut.states.size ();
+ terminal_count = grammar.terminals.size ();
+ non_terminal_count = grammar.non_terminals.size ();
+
+#define ACTION(i, j) table [(i) * terminal_count + (j)]
+#define GOTO(i, j) pgoto [(i) * non_terminal_count + (j)]
+
+ int *table = new int [state_count * terminal_count];
+ ::memset (table, 0, state_count * terminal_count * sizeof (int));
+
+ int *pgoto = new int [state_count * non_terminal_count];
+ ::memset (pgoto, 0, state_count * non_terminal_count * sizeof (int));
+
+ accept_state = -1;
+ int shift_reduce_conflict_count = 0;
+ int reduce_reduce_conflict_count = 0;
+
+ for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state)
+ {
+ int q = aut.id (state);
+
+ for (Bundle::iterator a = state->bundle.begin (); a != state->bundle.end (); ++a)
+ {
+ int symbol = aut.id (a.key ());
+ int r = aut.id (a.value ());
+
+ Q_ASSERT (r < state_count);
+
+ if (grammar.isNonTerminal (a.key ()))
+ {
+ Q_ASSERT (symbol >= terminal_count && symbol < grammar.names.size ());
+ GOTO (q, symbol - terminal_count) = r;
+ }
+
+ else
+ ACTION (q, symbol) = r;
+ }
+
+ for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item)
+ {
+ if (item->dot != item->end_rhs ())
+ continue;
+
+ int r = aut.id (item->rule);
+
+ NameSet lookaheads = aut.lookaheads.value (item);
+
+ if (item->rule == grammar.goal)
+ accept_state = q;
+
+ foreach (Name s, lookaheads)
+ {
+ int &u = ACTION (q, aut.id (s));
+
+ if (u == 0)
+ u = - r;
+
+ else if (u < 0)
+ {
+ if (verbose)
+ qout << "*** Warning. Found a reduce/reduce conflict in state " << q << " on token ``" << s << "'' between rule "
+ << r << " and " << -u << endl;
+
+ ++reduce_reduce_conflict_count;
+
+ u = qMax (u, -r);
+
+ if (verbose)
+ qout << "\tresolved using rule " << -u << endl;
+ }
+
+ else if (u > 0)
+ {
+ if (item->rule->prec != grammar.names.end() && grammar.token_info.contains (s))
+ {
+ Grammar::TokenInfo info_r = grammar.token_info.value (item->rule->prec);
+ Grammar::TokenInfo info_s = grammar.token_info.value (s);
+
+ if (info_r.prec > info_s.prec)
+ u = -r;
+ else if (info_r.prec == info_s.prec)
+ {
+ switch (info_r.assoc) {
+ case Grammar::Left:
+ u = -r;
+ break;
+ case Grammar::Right:
+ // shift... nothing to do
+ break;
+ case Grammar::NonAssoc:
+ u = 0;
+ break;
+ } // switch
+ }
+ }
+
+ else
+ {
+ ++shift_reduce_conflict_count;
+
+ if (verbose)
+ qout << "*** Warning. Found a shift/reduce conflict in state " << q << " on token ``" << s << "'' with rule " << r << endl;
+ }
+ }
+ }
+ }
+ }
+
+ if (shift_reduce_conflict_count || reduce_reduce_conflict_count)
+ {
+ if (shift_reduce_conflict_count != grammar.expected_shift_reduce
+ || reduce_reduce_conflict_count != grammar.expected_reduce_reduce)
+ qerr << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << endl;
+
+ if (verbose)
+ qout << endl << "*** Conflicts: " << shift_reduce_conflict_count << " shift/reduce, " << reduce_reduce_conflict_count << " reduce/reduce" << endl
+ << endl;
+ }
+
+ QBitArray used_rules (grammar.rules.count ());
+
+ int q = 0;
+ for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state, ++q)
+ {
+ for (int j = 0; j < terminal_count; ++j)
+ {
+ int &u = ACTION (q, j);
+
+ if (u < 0)
+ used_rules.setBit (-u - 1);
+ }
+ }
+
+ for (int i = 0; i < used_rules.count (); ++i)
+ {
+ if (! used_rules.testBit (i))
+ {
+ RulePointer rule = grammar.rules.begin () + i;
+
+ if (rule != grammar.goal)
+ qerr << "*** Warning: Rule ``" << *rule << "'' is useless!" << endl;
+ }
+ }
+
+ q = 0;
+ for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state, ++q)
+ {
+ for (int j = 0; j < terminal_count; ++j)
+ {
+ int &u = ACTION (q, j);
+
+ if (u >= 0)
+ continue;
+
+ RulePointer rule = grammar.rules.begin () + (- u - 1);
+
+ if (state->defaultReduce == rule)
+ u = 0;
+ }
+ }
+
+ // ... compress the goto table
+ defgoto.resize (non_terminal_count);
+ for (int j = 0; j < non_terminal_count; ++j)
+ {
+ count.fill (0, state_count);
+
+ int &mx = defgoto [j];
+
+ for (int i = 0; i < state_count; ++i)
+ {
+ int r = GOTO (i, j);
+
+ if (! r)
+ continue;
+
+ ++count [r];
+
+ if (count [r] > count [mx])
+ mx = r;
+ }
+ }
+
+ for (int i = 0; i < state_count; ++i)
+ {
+ for (int j = 0; j < non_terminal_count; ++j)
+ {
+ int &r = GOTO (i, j);
+
+ if (r == defgoto [j])
+ r = 0;
+ }
+ }
+
+ compressed_action (table, state_count, terminal_count);
+ compressed_goto (pgoto, state_count, non_terminal_count);
+
+ delete[] table;
+ table = 0;
+
+ delete[] pgoto;
+ pgoto = 0;
+
+#undef ACTION
+#undef GOTO
+
+ if (! grammar.merged_output.isEmpty())
+ {
+ QFile f(grammar.merged_output);
+ if (! f.open (QFile::WriteOnly))
+ {
+ fprintf (stderr, "*** cannot create %s\n", qPrintable(grammar.merged_output));
+ return;
+ }
+
+ QTextStream out (&f);
+
+ // copyright headers must come first, otherwise the headers tests will fail
+ if (copyright)
+ {
+ out << copyrightHeader()
+ << privateCopyrightHeader()
+ << endl;
+ }
+
+ out << "// This file was generated by qlalr - DO NOT EDIT!\n";
+
+ out << startIncludeGuard(grammar.merged_output) << endl;
+
+ if (copyright) {
+ out << "#if defined(ERROR)" << endl
+ << "# undef ERROR" << endl
+ << "#endif" << endl << endl;
+ }
+
+ generateDecl (out);
+ generateImpl (out);
+ out << p.decls();
+ out << p.impls();
+ out << endl;
+
+ out << endIncludeGuard(grammar.merged_output) << endl;
+
+ return;
+ }
+
+ // default behaviour
+ QString declFileName = grammar.table_name.toLower () + QLatin1String("_p.h");
+ QString bitsFileName = grammar.table_name.toLower () + QLatin1String(".cpp");
+
+ { // decls...
+ QFile f (declFileName);
+ f.open (QFile::WriteOnly);
+ QTextStream out (&f);
+
+ QString prot = declFileName.toUpper ().replace (QLatin1Char ('.'), QLatin1Char ('_'));
+
+ // copyright headers must come first, otherwise the headers tests will fail
+ if (copyright)
+ {
+ out << copyrightHeader()
+ << privateCopyrightHeader()
+ << endl;
+ }
+
+ out << "// This file was generated by qlalr - DO NOT EDIT!\n";
+
+ out << "#ifndef " << prot << endl
+ << "#define " << prot << endl
+ << endl;
+
+ if (copyright) {
+ out << "#include <QtCore/qglobal.h>" << endl << endl;
+ out << "QT_BEGIN_NAMESPACE" << endl << endl;
+ }
+ generateDecl (out);
+ if (copyright)
+ out << "QT_END_NAMESPACE" << endl;
+
+ out << "#endif // " << prot << endl << endl;
+ } // end decls
+
+ { // bits...
+ QFile f (bitsFileName);
+ f.open (QFile::WriteOnly);
+ QTextStream out (&f);
+
+ // copyright headers must come first, otherwise the headers tests will fail
+ if (copyright)
+ out << copyrightHeader();
+
+ out << "// This file was generated by qlalr - DO NOT EDIT!\n";
+
+ out << "#include \"" << declFileName << "\"" << endl << endl;
+ if (copyright)
+ out << "QT_BEGIN_NAMESPACE" << endl << endl;
+ generateImpl(out);
+ if (copyright)
+ out << "QT_END_NAMESPACE" << endl;
+
+ } // end bits
+
+ if (! grammar.decl_file_name.isEmpty ())
+ {
+ QFile f (grammar.decl_file_name);
+ f.open (QFile::WriteOnly);
+ QTextStream out (&f);
+ out << p.decls();
+ }
+
+ if (! grammar.impl_file_name.isEmpty ())
+ {
+ QFile f (grammar.impl_file_name);
+ f.open (QFile::WriteOnly);
+ QTextStream out (&f);
+ out << p.impls();
+ }
+}
+
+QString CppGenerator::debugInfoProt() const
+{
+ QString prot = QLatin1String("QLALR_NO_");
+ prot += grammar.table_name.toUpper();
+ prot += QLatin1String("_DEBUG_INFO");
+ return prot;
+}
+
+void CppGenerator::generateDecl (QTextStream &out)
+{
+ out << "class " << grammar.table_name << endl
+ << "{" << endl
+ << "public:" << endl
+ << " enum VariousConstants {" << endl;
+
+ foreach (Name t, grammar.terminals)
+ {
+ QString name = *t;
+ int value = std::distance (grammar.names.begin (), t);
+
+ if (name == QLatin1String ("$end"))
+ name = QLatin1String ("EOF_SYMBOL");
+
+ else if (name == QLatin1String ("$accept"))
+ name = QLatin1String ("ACCEPT_SYMBOL");
+
+ else
+ name.prepend (grammar.token_prefix);
+
+ out << " " << name << " = " << value << "," << endl;
+ }
+
+ out << endl
+ << " ACCEPT_STATE = " << accept_state << "," << endl
+ << " RULE_COUNT = " << grammar.rules.size () << "," << endl
+ << " STATE_COUNT = " << state_count << "," << endl
+ << " TERMINAL_COUNT = " << terminal_count << "," << endl
+ << " NON_TERMINAL_COUNT = " << non_terminal_count << "," << endl
+ << endl
+ << " GOTO_INDEX_OFFSET = " << compressed_action.index.size () << "," << endl
+ << " GOTO_INFO_OFFSET = " << compressed_action.info.size () << "," << endl
+ << " GOTO_CHECK_OFFSET = " << compressed_action.check.size () << endl
+ << " };" << endl
+ << endl
+ << " static const char *const spell [];" << endl
+ << " static const short lhs [];" << endl
+ << " static const short rhs [];" << endl;
+
+ if (debug_info)
+ {
+ QString prot = debugInfoProt();
+
+ out << endl << "#ifndef " << prot << endl
+ << " static const int rule_index [];" << endl
+ << " static const int rule_info [];" << endl
+ << "#endif // " << prot << endl << endl;
+ }
+
+ out << " static const short goto_default [];" << endl
+ << " static const short action_default [];" << endl
+ << " static const short action_index [];" << endl
+ << " static const short action_info [];" << endl
+ << " static const short action_check [];" << endl
+ << endl
+ << " static inline int nt_action (int state, int nt)" << endl
+ << " {" << endl
+ << " const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;" << endl
+ << " if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)" << endl
+ << " return goto_default [nt];" << endl
+ << endl
+ << " return action_info [GOTO_INFO_OFFSET + yyn];" << endl
+ << " }" << endl
+ << endl
+ << " static inline int t_action (int state, int token)" << endl
+ << " {" << endl
+ << " const int yyn = action_index [state] + token;" << endl
+ << endl
+ << " if (yyn < 0 || action_check [yyn] != token)" << endl
+ << " return - action_default [state];" << endl
+ << endl
+ << " return action_info [yyn];" << endl
+ << " }" << endl
+ << "};" << endl
+ << endl
+ << endl;
+}
+
+void CppGenerator::generateImpl (QTextStream &out)
+{
+ int idx = 0;
+
+ out << "const char *const " << grammar.table_name << "::spell [] = {";
+ idx = 0;
+
+ QMap<Name, int> name_ids;
+ bool first_nt = true;
+
+ for (Name t = grammar.names.begin (); t != grammar.names.end (); ++t, ++idx)
+ {
+ bool terminal = grammar.isTerminal (t);
+
+ if (! (debug_info || terminal))
+ break;
+
+ name_ids.insert (t, idx);
+
+ if (idx)
+ out << ", ";
+
+ if (! (idx % 10))
+ out << endl << " ";
+
+ if (terminal)
+ {
+ QString spell = grammar.spells.value (t);
+
+ if (spell.isEmpty ())
+ out << "0";
+ else
+ out << "\"" << spell << "\"";
+ }
+ else
+ {
+ if (first_nt)
+ {
+ first_nt = false;
+ QString prot = debugInfoProt();
+ out << endl << "#ifndef " << prot << endl;
+ }
+ out << "\"" << *t << "\"";
+ }
+ }
+
+ if (debug_info)
+ out << endl << "#endif // " << debugInfoProt() << endl;
+
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::lhs [] = {";
+ idx = 0;
+ for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
+ {
+ if (idx)
+ out << ", ";
+
+ if (! (idx % 10))
+ out << endl << " ";
+
+ out << aut.id (rule->lhs);
+ }
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::rhs [] = {";
+ idx = 0;
+ for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
+ {
+ if (idx)
+ out << ", ";
+
+ if (! (idx % 10))
+ out << endl << " ";
+
+ out << rule->rhs.size ();
+ }
+ out << "};" << endl << endl;
+
+ if (debug_info)
+ {
+ QString prot = debugInfoProt();
+
+ out << endl << "#ifndef " << prot << endl;
+ out << "const int " << grammar.table_name << "::rule_info [] = {";
+ idx = 0;
+ for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
+ {
+ out << endl << " ";
+
+ if (idx)
+ out << ", ";
+ else
+ out << " ";
+
+ out << name_ids.value(rule->lhs);
+
+ foreach (Name n, rule->rhs)
+ out << ", " << name_ids.value (n);
+ }
+ out << "};" << endl << endl;
+
+ out << "const int " << grammar.table_name << "::rule_index [] = {";
+ idx = 0;
+ int offset = 0;
+ for (RulePointer rule = grammar.rules.begin (); rule != grammar.rules.end (); ++rule, ++idx)
+ {
+ if (idx)
+ out << ", ";
+
+ if (! (idx % 10))
+ out << endl << " ";
+
+ out << offset;
+ offset += rule->rhs.size () + 1;
+ }
+ out << "};" << endl
+ << "#endif // " << prot << endl << endl;
+ }
+
+ out << "const short " << grammar.table_name << "::action_default [] = {";
+ idx = 0;
+ for (StatePointer state = aut.states.begin (); state != aut.states.end (); ++state, ++idx)
+ {
+ if (state != aut.states.begin ())
+ out << ", ";
+
+ if (! (idx % 10))
+ out << endl << " ";
+
+ if (state->defaultReduce != grammar.rules.end ())
+ out << aut.id (state->defaultReduce);
+ else
+ out << "0";
+ }
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::goto_default [] = {";
+ for (int i = 0; i < defgoto.size (); ++i)
+ {
+ if (i)
+ out << ", ";
+
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << defgoto [i];
+ }
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::action_index [] = {";
+ for (int i = 0; i < compressed_action.index.size (); ++i)
+ {
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_action.index [i] << ", ";
+ }
+ out << endl;
+ for (int i = 0; i < compressed_goto.index.size (); ++i)
+ {
+ if (i)
+ out << ", ";
+
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_goto.index [i];
+ }
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::action_info [] = {";
+ for (int i = 0; i < compressed_action.info.size (); ++i)
+ {
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_action.info [i] << ", ";
+ }
+ out << endl;
+ for (int i = 0; i < compressed_goto.info.size (); ++i)
+ {
+ if (i)
+ out << ", ";
+
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_goto.info [i];
+ }
+ out << "};" << endl << endl;
+
+ out << "const short " << grammar.table_name << "::action_check [] = {";
+ for (int i = 0; i < compressed_action.check.size (); ++i)
+ {
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_action.check [i] << ", ";
+ }
+ out << endl;
+ for (int i = 0; i < compressed_goto.check.size (); ++i)
+ {
+ if (i)
+ out << ", ";
+
+ if (! (i % 10))
+ out << endl << " ";
+
+ out << compressed_goto.check [i];
+ }
+ out << "};" << endl << endl;
+}
diff --git a/src/tools/qlalr/cppgenerator.h b/src/tools/qlalr/cppgenerator.h
new file mode 100644
index 0000000000..3ee5dc91e3
--- /dev/null
+++ b/src/tools/qlalr/cppgenerator.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CPPGENERATOR_H
+#define CPPGENERATOR_H
+
+#include "lalr.h"
+#include "compress.h"
+
+class Grammar;
+class Automaton;
+class Recognizer;
+
+class CppGenerator
+{
+public:
+ CppGenerator(const Recognizer &p, Grammar &grammar, Automaton &aut, bool verbose):
+ p (p),
+ grammar (grammar),
+ aut (aut),
+ verbose (verbose),
+ debug_info (false),
+ copyright (false) {}
+
+ void operator () ();
+
+ bool debugInfo () const { return debug_info; }
+ void setDebugInfo (bool d) { debug_info = d; }
+
+ void setCopyright (bool t) { copyright = t; }
+
+private:
+ void generateDecl (QTextStream &out);
+ void generateImpl (QTextStream &out);
+
+ QString debugInfoProt() const;
+ QString copyrightHeader() const;
+ QString privateCopyrightHeader() const;
+
+private:
+ static QString startIncludeGuard(const QString &fileName);
+ static QString endIncludeGuard(const QString &fileName);
+
+ const Recognizer &p;
+ Grammar &grammar;
+ Automaton &aut;
+ bool verbose;
+ int accept_state;
+ int state_count;
+ int terminal_count;
+ int non_terminal_count;
+ bool debug_info;
+ bool copyright;
+ Compress compressed_action;
+ Compress compressed_goto;
+ QVector<int> count;
+ QVector<int> defgoto;
+};
+
+#endif // CPPGENERATOR_H
diff --git a/src/tools/qlalr/doc/qlalr.qdocconf b/src/tools/qlalr/doc/qlalr.qdocconf
new file mode 100644
index 0000000000..434393a727
--- /dev/null
+++ b/src/tools/qlalr/doc/qlalr.qdocconf
@@ -0,0 +1,64 @@
+# Run qdoc from the directory that contains this file.
+
+project = qlalr
+description = qlalr Reference Documentation
+url = http://qt.nokia.com/doc/
+
+language = Cpp
+
+# sourcedirs = $PWD/src
+sourcedirs = src
+sources.fileextensions = "*.qdoc"
+
+exampledirs = ../examples
+
+imagedirs = src/images
+outputdir = html
+codeindent = 1
+extraimages.HTML = qt-logo
+
+macro.key = "\\b"
+macro.menu = "\\b"
+macro.gui = "\\b"
+macro.reg.HTML = "<sup>&reg;</sup>"
+macro.raisedaster.HTML = "<sup>*</sup>"
+macro.BR.HTML = "<br />"
+macro.br.HTML = "<br />"
+macro.QD = "\\e{Qt Designer}"
+macro.QA = "\\e{Qt Assistant}"
+macro.eacute.HTML = "&eacute;"
+macro.aring.HTML = "&aring;"
+macro.oslash.HTML = "&oslash;"
+macro.ouml.HTML = "&ouml;"
+macro.Auml.HTML = "&Auml;"
+macro.uuml.HTML = "&uuml;"
+
+HTML.stylesheets = src/classic.css
+HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \
+ "<tr>\n" \
+ "<td align=\"left\" valign=\"top\" width=\"32\">" \
+ "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" width=\"32\" height=\"32\" border=\"0\" /></a>" \
+ "</td>\n" \
+ "<td width=\"1\">&nbsp;&nbsp;</td>" \
+ "<td class=\"postheader\" valign=\"center\">" \
+ "<a href=\"index.html\">" \
+ "<font color=\"#004faf\">Home</font></a>&nbsp;&middot;" \
+ " <a href=\"classes.html\">" \
+ "<font color=\"#004faf\">All&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"mainclasses.html\">" \
+ "<font color=\"#004faf\">Main&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"groups.html\">" \
+ "<font color=\"#004faf\">Grouped&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"modules.html\">" \
+ "<font color=\"#004faf\">Modules</font></a>&nbsp;&middot;" \
+ " <a href=\"functions.html\">" \
+ "<font color=\"#004faf\">Functions</font></a>" \
+ "</td>\n" \
+ "<td align=\"right\" valign=\"top\" width=\"230\"><a href=\"http://qt.nokia.com\"><img src=\"images/qt-logo.png\" align=\"right\" width=\"203\" height=\"32\" border=\"0\" /></a></td></tr></table>"
+
+HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
+ "<td width=\"30%\" align=\"left\">Copyright &copy; 2012 Digia Plc and/or its subsidiary(-ies)</td>\n" \
+ "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
+ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \
+ "</tr></table></div></address>"
diff --git a/src/tools/qlalr/doc/src/classic.css b/src/tools/qlalr/doc/src/classic.css
new file mode 100644
index 0000000000..afc66d548a
--- /dev/null
+++ b/src/tools/qlalr/doc/src/classic.css
@@ -0,0 +1,97 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated {
+ border-spacing: 0px;
+}
+
+table.annotated th {
+ font-weight: bold;
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
diff --git a/src/tools/qlalr/doc/src/images/qt-logo.png b/src/tools/qlalr/doc/src/images/qt-logo.png
new file mode 100644
index 0000000000..2dc67161c1
--- /dev/null
+++ b/src/tools/qlalr/doc/src/images/qt-logo.png
Binary files differ
diff --git a/src/tools/qlalr/doc/src/qlalr.qdoc b/src/tools/qlalr/doc/src/qlalr.qdoc
new file mode 100644
index 0000000000..36cf27b3d9
--- /dev/null
+++ b/src/tools/qlalr/doc/src/qlalr.qdoc
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qlalr.html
+ \title qlalr
+ \nextpage qlalr - Writing Grammars
+
+ \section1 Table of Contents
+
+ \list
+ \li \l{qlalr - Writing Grammars}
+ \tableofcontents{1 qlalr - Writing Grammars}
+ \li \l{qlalr - Generating Code from Grammar Specifications}
+ \tableofcontents{1 qlalr - Generating Code from Grammar Specifications}
+ \li \l{qlalr - qlalr Grammar Specification}
+ \tableofcontents{1 qlalr - qlalr Grammar Specification}
+ \li \l{qlalr - Handling Conflicts}
+ \tableofcontents{1 qlalr - Handling Conflicts}
+ \li \l{qlalr - Error Handling and Recovery}
+ \tableofcontents{1 qlalr - Error Handling and Recovery}
+ \li \l{qlalr - References to External Information}
+ \tableofcontents{1 qlalr - References to External Information}
+ \endlist
+
+*/
+
+/*!
+ \page qlalr-files.html
+ \title qlalr - Writing Grammars
+
+ \contentspage qlalr
+ \previouspage qlalr
+ \nextpage qlalr - Generating Code from Grammar Specifications
+
+*/
+
+/*!
+ \page qlalr-generating.html
+ \title qlalr - Generating Code from Grammar Specifications
+
+ \contentspage qlalr
+ \previouspage qlalr - Writing Grammars
+ \nextpage qlalr - qlalr Grammar Specification
+*/
+
+/*!
+ \page qlalr-grammar-specification.html
+ \title qlalr - qlalr Grammar Specification
+
+ \contentspage qlalr
+ \previouspage qlalr - Generating Code from Grammar Specifications
+ \nextpage qlalr - Handling Conflicts
+
+*/
+
+/*!
+ \page qlalr-handling-conflicts.html
+ \title qlalr - Handling Conflicts
+
+ \contentspage qlalr
+ \previouspage qlalr - qlalr Grammar Specification
+ \nextpage qlalr - Error Handling and Recovery
+*/
+
+/*!
+ \page qlalr-handling-errors.html
+ \title qlalr - Error Handling and Recovery
+
+ \contentspage qlalr
+ \previouspage qlalr - Handling Conflicts
+ \nextpage qlalr - References to External Information
+*/
+
+/*!
+ \page qlalr-external-references.html
+ \title qlalr - References to External Information
+
+ \contentspage qlalr
+ \previouspage qlalr - Error Handling and Recovery
+*/
+
diff --git a/src/tools/qlalr/dotgraph.cpp b/src/tools/qlalr/dotgraph.cpp
new file mode 100644
index 0000000000..60ec82ae84
--- /dev/null
+++ b/src/tools/qlalr/dotgraph.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "dotgraph.h"
+
+#include "lalr.h"
+
+#include <QtCore/qtextstream.h>
+
+DotGraph::DotGraph(QTextStream &o):
+ out (o)
+{
+}
+
+void DotGraph::operator () (Automaton *aut)
+{
+ Grammar *g = aut->_M_grammar;
+
+ out << "digraph {" << endl << endl;
+
+ out << "subgraph Includes {" << endl;
+ for (Automaton::IncludesGraph::iterator incl = Automaton::IncludesGraph::begin_nodes ();
+ incl != Automaton::IncludesGraph::end_nodes (); ++incl)
+ {
+ for (Automaton::IncludesGraph::edge_iterator edge = incl->begin (); edge != incl->end (); ++edge)
+ {
+ out << "\t\"(" << aut->id (incl->data.state) << ", " << incl->data.nt << ")\"";
+ out << "\t->\t";
+ out << "\"(" << aut->id ((*edge)->data.state) << ", " << (*edge)->data.nt << ")\"\t";
+ out << "[label=\"" << incl->data.state->follows [incl->data.nt] << "\"]";
+ out << endl;
+ }
+ }
+ out << "}" << endl << endl;
+
+
+ out << "subgraph LRA {" << endl;
+ //out << "node [shape=record];" << endl << endl;
+
+ for (StatePointer q = aut->states.begin (); q != aut->states.end (); ++q)
+ {
+ int state = aut->id (q);
+
+ out << "\t" << state << "\t[shape=record,label=\"{";
+
+ out << "<0> State " << state;
+
+ int index = 1;
+ for (ItemPointer item = q->kernel.begin (); item != q->kernel.end (); ++item)
+ out << "| <" << index++ << "> " << *item;
+
+ out << "}\"]" << endl;
+
+ for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
+ {
+ const char *clr = g->isTerminal (a.key ()) ? "blue" : "red";
+ out << "\t" << state << "\t->\t" << aut->id (*a) << "\t[color=\"" << clr << "\",label=\"" << a.key () << "\"]" << endl;
+ }
+ out << endl;
+ }
+
+ out << "}" << endl;
+ out << endl << endl << "}" << endl;
+}
diff --git a/src/tools/qlalr/dotgraph.h b/src/tools/qlalr/dotgraph.h
new file mode 100644
index 0000000000..1d21db060a
--- /dev/null
+++ b/src/tools/qlalr/dotgraph.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DOTGRAPH_H
+#define DOTGRAPH_H
+
+#include <QtCore/qglobal.h>
+
+QT_FORWARD_DECLARE_CLASS(QTextStream);
+class Automaton;
+
+class DotGraph
+{
+public:
+ DotGraph (QTextStream &out);
+
+ void operator () (Automaton *a);
+
+private:
+ QTextStream &out;
+};
+
+#endif // DOTGRAPH_H
diff --git a/src/tools/qlalr/examples/dummy-xml/dummy-xml.pro b/src/tools/qlalr/examples/dummy-xml/dummy-xml.pro
new file mode 100644
index 0000000000..e54512d6c9
--- /dev/null
+++ b/src/tools/qlalr/examples/dummy-xml/dummy-xml.pro
@@ -0,0 +1,2 @@
+HEADERS += xmltable_p.h
+SOURCES += xmlreader.cpp xmltable.cpp
diff --git a/src/tools/qlalr/examples/dummy-xml/ll/dummy-xml-ll.cpp b/src/tools/qlalr/examples/dummy-xml/ll/dummy-xml-ll.cpp
new file mode 100644
index 0000000000..3d2a09c845
--- /dev/null
+++ b/src/tools/qlalr/examples/dummy-xml/ll/dummy-xml-ll.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <cstdlib>
+#include <cstdio>
+
+enum Token {
+ EOF_SYMBOL,
+ LEFT_ANGLE,
+ RIGHT_ANGLE,
+ ANY,
+};
+
+static int current_char;
+static int yytoken;
+static bool in_tag = false;
+
+bool parseXmlStream();
+bool parseTagOrWord();
+bool parseTagName();
+
+inline int nextToken()
+{
+ current_char = fgetc(stdin);
+ if (current_char == EOF) {
+ return (yytoken = EOF_SYMBOL);
+ } else if (current_char == '<') {
+ in_tag = true;
+ return (yytoken = LEFT_ANGLE);
+ } else if (in_tag && current_char == '>') {
+ in_tag = false;
+ return (yytoken = RIGHT_ANGLE);
+ }
+ return (yytoken = ANY);
+}
+
+bool parse()
+{
+ nextToken();
+ return parseXmlStream();
+}
+
+bool parseXmlStream()
+{
+ while (parseTagOrWord())
+ ;
+
+ return true;
+}
+
+bool parseTagOrWord()
+{
+ if (yytoken == LEFT_ANGLE) {
+ nextToken();
+ if (! parseTagName())
+ return false;
+ if (yytoken != RIGHT_ANGLE)
+ return false;
+ nextToken();
+
+ fprintf (stderr, "*** found a tag\n");
+
+ } else if (yytoken == ANY) {
+ nextToken();
+ } else {
+ return false;
+ }
+ return true;
+}
+
+bool parseTagName()
+{
+ while (yytoken == ANY)
+ nextToken();
+
+ return true;
+}
+
+int main()
+{
+ if (parse())
+ printf("OK\n");
+ else
+ printf("KO\n");
+}
diff --git a/src/tools/qlalr/examples/dummy-xml/xml.g b/src/tools/qlalr/examples/dummy-xml/xml.g
new file mode 100644
index 0000000000..a5d6b6e978
--- /dev/null
+++ b/src/tools/qlalr/examples/dummy-xml/xml.g
@@ -0,0 +1,242 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+-- Contact: http://www.qt-project.org/legal
+--
+-- This file is part of the QtCore module of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, 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, Digia gives you certain additional
+-- rights. These rights are described in the Digia 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.
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+%parser XMLTable
+
+%impl xmlreader.cpp
+
+%token LEFT_ANGLE
+%token RIGHT_ANGLE
+%token ANY
+
+%start XmlStream
+
+/.
+#ifndef XMLREADER_H
+#define XMLREADER_H
+
+#include <QtCore>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include "$header"
+
+class XMLReader: protected $table
+{
+public:
+ XMLReader(const QByteArray &bytes);
+ ~XMLReader();
+
+ bool parse();
+
+ inline int nextToken()
+ {
+ switch (*bufptr++) {
+ case '\0':
+ return EOF_SYMBOL;
+
+ case '<':
+ in_tag = true;
+ return LEFT_ANGLE;
+
+ case '>':
+ if (! in_tag)
+ break;
+ in_tag = false;
+ return RIGHT_ANGLE;
+ break;
+
+ } // switch
+
+ return ANY;
+ }
+
+protected:
+ inline void reallocateStack();
+
+ inline int &sym(int index)
+ { return stack [tos + index - 1].ival; }
+
+protected:
+ int tos;
+ int stack_size;
+
+ struct StackItem {
+ int state;
+ int ival;
+ };
+
+ QVarLengthArray<StackItem> stack;
+ unsigned in_tag: 1;
+ QByteArray bytes;
+ const char *bufptr;
+};
+
+inline void XMLReader::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ stack.resize (stack_size);
+}
+
+#endif // XMLREADER_H
+
+XMLReader::XMLReader(const QByteArray &bytes):
+ tos(0),
+ stack_size(0),
+ bytes(bytes)
+{
+ bufptr = bytes.constData();
+}
+
+XMLReader::~XMLReader()
+{
+}
+
+bool XMLReader::parse()
+{
+ const int INITIAL_STATE = 0;
+
+ in_tag = 0;
+ bufptr = bytes.constData();
+
+ int yytoken = -1;
+ reallocateStack();
+
+ tos = 0;
+ stack [++tos].state = INITIAL_STATE;
+
+ while (true)
+ {
+ const int state = stack [tos].state;
+
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
+ yytoken = nextToken();
+
+ int act = t_action (state, yytoken);
+
+ if (act == ACCEPT_STATE)
+ return true;
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ stack [tos].ival = *bufptr; // ### save the token value here
+ stack [tos].state = act;
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = stack [tos++].state;
+
+ switch (r) {
+./
+
+
+
+
+XmlStream: TagOrWord ;
+XmlStream: XmlStream TagOrWord ;
+
+TagOrWord: Tag ;
+TagOrWord: ANY ;
+
+Tag: LEFT_ANGLE TagName RIGHT_ANGLE ;
+/.
+ case $rule_number: {
+ fprintf (stderr, "*** found a tag\n");
+ } break;
+./
+
+TagName: ANY ;
+TagName: TagName ANY ;
+
+
+/.
+ } // switch
+
+ stack [tos].state = nt_action (act, lhs [r] - TERMINAL_COUNT);
+ }
+
+ else
+ {
+ // ### ERROR RECOVERY HERE
+ break;
+ }
+ }
+
+ return false;
+}
+
+
+
+/////////////////////////////
+// entry point
+/////////////////////////////
+int main(int, char *argv[])
+{
+ QFile f (argv[1]);
+
+ if (f.open(QFile::ReadOnly)) {
+ QByteArray contents = f.readAll();
+ XMLReader parser (contents);
+
+ if (parser.parse())
+ printf ("OK\n");
+ else
+ printf ("KO\n");
+ }
+}
+
+
+
+
+./
+
diff --git a/src/tools/qlalr/examples/glsl/build.sh b/src/tools/qlalr/examples/glsl/build.sh
new file mode 100644
index 0000000000..122431ba4e
--- /dev/null
+++ b/src/tools/qlalr/examples/glsl/build.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#############################################################################
+##
+## Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+## Contact: http://www.qt-project.org/legal
+##
+## This file is the build configuration utility of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and Digia. For licensing terms and
+## conditions see http://qt.digia.com/licensing. For further information
+## use the contact form at http://qt.digia.com/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, 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, Digia gives you certain additional
+## rights. These rights are described in the Digia 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.
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+${FLEX-flex} -oglsl-lex.incl glsl-lex.l
+${QLALR-qlalr} glsl.g
+
+qmake
+make
diff --git a/src/tools/qlalr/examples/glsl/glsl b/src/tools/qlalr/examples/glsl/glsl
new file mode 100755
index 0000000000..c19018f985
--- /dev/null
+++ b/src/tools/qlalr/examples/glsl/glsl
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+me=$(dirname $0)
+${CPP-cpp} -nostdinc $* | $me/glsl.bin
diff --git a/src/tools/qlalr/examples/glsl/glsl-lex.l b/src/tools/qlalr/examples/glsl/glsl-lex.l
new file mode 100644
index 0000000000..16ff333b79
--- /dev/null
+++ b/src/tools/qlalr/examples/glsl/glsl-lex.l
@@ -0,0 +1,245 @@
+
+%{
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR tool of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <cassert>
+#define YY_DECL int GLSLParser::nextToken()
+%}
+
+%option noyywrap
+
+hex [0-9a-fA-F]
+dec [1-9][0-9]*
+oct [0-7]
+digit [0-9]
+
+fract {digit}*\.{digit}+|{digit}+\.
+exp [eE][+-]?{digit}+
+
+hexfract {hex}*\.{hex}+|{hex}+\.
+binexp [pP][+-]?{digit}+
+
+icst ({dec}|0{oct}*|0[xX]{hex}+)
+
+%%
+
+[\n] { ++context.line; }
+[ \t\r]+ { /* skip */ }
+
+"+=" { return ADD_ASSIGN; }
+"&" { return AMPERSAND; }
+"&=" { return AND_ASSIGN; }
+"&&" { return AND_OP; }
+"attribute" { return ATTRIBUTE; }
+"!" { return BANG; }
+"bool" { return BOOL; }
+"true" { return BOOLCONSTANT; }
+"false" { return BOOLCONSTANT; }
+"break" { return BREAK; }
+"bvec2" { return BVEC2; }
+"bvec3" { return BVEC3; }
+"bvec4" { return BVEC4; }
+":" { return COLON; }
+"," { return COMMA; }
+"const" { return CONST; }
+"continue" { return CONTINUE; }
+"-" { return DASH; }
+"--" { return DEC_OP; }
+"discard" { return DISCARD; }
+"/=" { return DIV_ASSIGN; }
+"do" { return DO; }
+"." { return DOT; }
+"else" { return ELSE; }
+"=" { return EQUAL; }
+"==" { return EQ_OP; }
+"float" { return FLOAT; }
+"for" { return FOR; }
+">=" { return GE_OP; }
+"if" { return IF; }
+"in" { return IN; }
+"++" { return INC_OP; }
+"inout" { return INOUT; }
+"int" { return INT; }
+"ivec2" { return IVEC2; }
+"ivec3" { return IVEC3; }
+"ivec4" { return IVEC4; }
+"<" { return LEFT_ANGLE; }
+"<<=" { return LEFT_ASSIGN; }
+"{" { return LEFT_BRACE; }
+"[" { return LEFT_BRACKET; }
+"<<" { return LEFT_OP; }
+"(" { return LEFT_PAREN; }
+"<=" { return LE_OP; }
+"mat2" { return MAT2; }
+"mat3" { return MAT3; }
+"mat4" { return MAT4; }
+"%=" { return MOD_ASSIGN; }
+"*=" { return MUL_ASSIGN; }
+"!=" { return NE_OP; }
+"|=" { return OR_ASSIGN; }
+"||" { return OR_OP; }
+"out" { return OUT; }
+"%" { return PERCENT; }
+"+" { return PLUS; }
+"?" { return QUESTION; }
+"return" { return RETURN; }
+">" { return RIGHT_ANGLE; }
+">>=" { return RIGHT_ASSIGN; }
+"}" { return RIGHT_BRACE; }
+"]" { return RIGHT_BRACKET; }
+">>" { return RIGHT_OP; }
+")" { return RIGHT_PAREN; }
+"sampler1D" { return SAMPLER1D; }
+"sampler1DShadow" { return SAMPLER1DSHADOW; }
+"sampler2D" { return SAMPLER2D; }
+"sampler2DShadow" { return SAMPLER2DSHADOW; }
+"sampler3D" { return SAMPLER3D; }
+"samplerCube" { return SAMPLERCUBE; }
+";" { return SEMICOLON; }
+"/" { return SLASH; }
+"*" { return STAR; }
+"struct" { return STRUCT; }
+"-=" { return SUB_ASSIGN; }
+"~" { return TILDE; }
+"uniform" { return UNIFORM; }
+"varying" { return VARYING; }
+"vec2" { return VEC2; }
+"vec3" { return VEC3; }
+"vec4" { return VEC4; }
+"|" { return VERTICAL_BAR; }
+"void" { return VOID; }
+"while" { return WHILE; }
+"^=" { return XOR_ASSIGN; }
+"^" { return XOR_OP; }
+"highp" { return HIGH_PRECISION; }
+"mediump" { return MEDIUM_PRECISION; }
+"lowp" { return LOW_PRECISION; }
+
+#[ \t]+[0-9]+.* {
+ char *eptr = 0;
+ context.line = (int) strtod(&yytext[1], &eptr);
+ QString fn = QString::fromUtf8(eptr).trimmed();
+ if (fn.length() > 2)
+ context.fileName = fn.mid(1, fn.length()-2);
+}
+
+#.* {
+ /* skip */
+}
+
+[_a-zA-Z][_a-zA-Z0-9]* {
+ yylval.s = intern (yytext);
+
+ if (isTypename (yylval.s))
+ return TYPE_NAME;
+
+ return IDENTIFIER;
+}
+
+{icst} {
+ yylval.i = (int) strtol (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}[uU] {
+ yylval.u = (unsigned) strtoul (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}[uU][lL] {
+ yylval.ul = strtoul (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}[lL][uU] {
+ yylval.ul = strtoul (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}[lL] {
+ yylval.l = strtol (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}[uU](ll|LL) {
+ yylval.l = strtoull (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}(ll|LL) {
+ yylval.l = strtoll (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{icst}(ll|LL)[uU] {
+ yylval.l = strtoull (yytext, 0, 0);
+ return INTCONSTANT;
+}
+
+{fract}{exp}?[flFL]? {
+ yylval.f = strtof (yytext, 0);
+ return FLOATCONSTANT;
+}
+
+{digit}+{exp}[flFL]? {
+ yylval.f = strtof (yytext, 0);
+ return FLOATCONSTANT;
+}
+
+0[xX]{hexfract}{binexp}[flFL]? {
+ yylval.f = strtof (yytext, 0);
+ return FLOATCONSTANT;
+}
+
+0[xX]{hex}+{binexp}[flFL]? {
+ yylval.f = strtof (yytext, 0);
+ return FLOATCONSTANT;
+}
+
+. {
+ fprintf (stderr, "invalid char: %d\n", yytext [0]);
+ return ERROR;
+}
+
+
+%%
+
diff --git a/src/tools/qlalr/examples/glsl/glsl.g b/src/tools/qlalr/examples/glsl/glsl.g
new file mode 100644
index 0000000000..64b1b0b1e5
--- /dev/null
+++ b/src/tools/qlalr/examples/glsl/glsl.g
@@ -0,0 +1,671 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+-- Contact: http://www.qt-project.org/legal
+--
+-- This file is part of the QtCore module of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, 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, Digia gives you certain additional
+-- rights. These rights are described in the Digia 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.
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+%parser GLSLParserTable
+%merged_output glsl.cpp
+
+%token ADD_ASSIGN
+%token AMPERSAND
+%token AND_ASSIGN
+%token AND_OP
+%token ATTRIBUTE
+%token BANG
+%token BOOL
+%token BOOLCONSTANT
+%token BREAK
+%token BVEC2
+%token BVEC3
+%token BVEC4
+%token CARET
+%token COLON
+%token COMMA
+%token CONST
+%token CONTINUE
+%token DASH
+%token DEC_OP
+%token DISCARD
+%token DIV_ASSIGN
+%token DO
+%token DOT
+%token ELSE
+%token EQUAL
+%token EQ_OP
+%token FLOAT
+%token FLOATCONSTANT
+%token FOR
+%token GE_OP
+%token IDENTIFIER
+%token IF
+%token IN
+%token INC_OP
+%token INOUT
+%token INT
+%token INTCONSTANT
+%token IVEC2
+%token IVEC3
+%token IVEC4
+%token LEFT_ANGLE
+%token LEFT_ASSIGN
+%token LEFT_BRACE
+%token LEFT_BRACKET
+%token LEFT_OP
+%token LEFT_PAREN
+%token LE_OP
+%token MAT2
+%token MAT3
+%token MAT4
+%token MOD_ASSIGN
+%token MUL_ASSIGN
+%token NE_OP
+%token OR_ASSIGN
+%token OR_OP
+%token OUT
+%token PERCENT
+%token PLUS
+%token QUESTION
+%token RETURN
+%token RIGHT_ANGLE
+%token RIGHT_ASSIGN
+%token RIGHT_BRACE
+%token RIGHT_BRACKET
+%token RIGHT_OP
+%token RIGHT_PAREN
+%token SAMPLER1D
+%token SAMPLER1DSHADOW
+%token SAMPLER2D
+%token SAMPLER2DSHADOW
+%token SAMPLER3D
+%token SAMPLERCUBE
+%token SEMICOLON
+%token SLASH
+%token STAR
+%token STRUCT
+%token SUB_ASSIGN
+%token TILDE
+%token TYPE_NAME
+%token UNIFORM
+%token VARYING
+%token VEC2
+%token VEC3
+%token VEC4
+%token VERTICAL_BAR
+%token VOID
+%token WHILE
+%token XOR_ASSIGN
+%token XOR_OP
+%token ERROR
+%token HIGH_PRECISION
+%token MEDIUM_PRECISION
+%token LOW_PRECISION
+%start translation_unit
+
+
+/:
+
+#include <QtCore>
+
+class GLSLParser: protected $table
+{
+public:
+ union Value {
+ int i;
+ unsigned u;
+ unsigned long ul;
+ unsigned long long ull;
+ long l;
+ double d;
+ float f;
+ const QString *s;
+ // ### more...
+ };
+
+public:
+ GLSLParser();
+ ~GLSLParser();
+
+ bool parse();
+
+protected:
+ inline void reallocateStack();
+
+ inline Value &sym(int index)
+ { return sym_stack [tos + index - 1]; }
+
+ int nextToken();
+
+ bool isTypename(const QString *s) const
+ {
+ return types.contains(s);
+ }
+
+ inline const QString *intern(const QString &s)
+ { return &*string_repository.insert(s); }
+
+protected:
+ int tos;
+ int stack_size;
+ Value *sym_stack;
+ int *state_stack;
+ Value yylval;
+ QSet<QString> string_repository;
+ QSet<const QString*> types;
+
+ struct /*Context*/ {
+ int line;
+ const QString *function_name;
+ QString fileName;
+
+ void init()
+ {
+ line = 1;
+ function_name = 0;
+ fileName.clear();
+ }
+ } context;
+};
+
+inline void GLSLParser::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
+ state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
+}
+
+:/
+
+
+/.
+
+GLSLParser::GLSLParser():
+ tos(0),
+ stack_size(0),
+ sym_stack(0),
+ state_stack(0)
+{
+}
+
+GLSLParser::~GLSLParser()
+{
+ if (stack_size) {
+ free(sym_stack);
+ free(state_stack);
+ }
+}
+
+bool GLSLParser::parse()
+{
+ const int INITIAL_STATE = 0;
+
+ int yytoken = -1;
+
+ reallocateStack();
+
+ context.init();
+ tos = 0;
+ state_stack[++tos] = INITIAL_STATE;
+
+ while (true)
+ {
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state_stack [tos]])
+ yytoken = nextToken();
+
+ int act = t_action (state_stack [tos], yytoken);
+
+ if (act == ACCEPT_STATE) {
+ return true;
+ }
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos] = yylval;
+ state_stack [tos] = act;
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ int ridx = rule_index [r];
+ printf ("*** reduce using rule %d %s ::=", r + 1, spell[rule_info [ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs [r]; ++i)
+ {
+ int symbol = rule_info [i];
+ if (const char *name = spell [symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+
+ switch (r) {
+./
+
+
+translation_unit ::= external_declaration ;
+translation_unit ::= translation_unit external_declaration ;
+
+variable_identifier ::= IDENTIFIER ;
+
+primary_expression ::= variable_identifier ;
+primary_expression ::= INTCONSTANT ;
+primary_expression ::= FLOATCONSTANT ;
+primary_expression ::= BOOLCONSTANT ;
+primary_expression ::= LEFT_PAREN expression RIGHT_PAREN ;
+
+
+postfix_expression ::= primary_expression ;
+postfix_expression ::= postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET ;
+postfix_expression ::= function_call ;
+postfix_expression ::= postfix_expression DOT IDENTIFIER ;
+postfix_expression ::= postfix_expression DOT TYPE_NAME ;
+postfix_expression ::= postfix_expression INC_OP ;
+postfix_expression ::= postfix_expression DEC_OP ;
+
+
+integer_expression ::= expression ;
+
+function_call ::= function_call_generic ;
+
+function_call_generic ::= function_call_header_with_parameters RIGHT_PAREN ;
+function_call_generic ::= function_call_header_no_parameters RIGHT_PAREN ;
+
+function_call_header_no_parameters ::= function_call_header VOID ;
+function_call_header_no_parameters ::= function_call_header ;
+
+
+function_call_header_with_parameters ::= function_call_header assignment_expression ;
+function_call_header_with_parameters ::= function_call_header_with_parameters COMMA assignment_expression ;
+
+function_call_header ::= function_identifier LEFT_PAREN ;
+
+function_identifier ::= constructor_identifier ;
+function_identifier ::= IDENTIFIER ;
+
+
+constructor_identifier ::= FLOAT ;
+constructor_identifier ::= INT ;
+constructor_identifier ::= BOOL ;
+constructor_identifier ::= VEC2 ;
+constructor_identifier ::= VEC3 ;
+constructor_identifier ::= VEC4 ;
+constructor_identifier ::= BVEC2 ;
+constructor_identifier ::= BVEC3 ;
+constructor_identifier ::= BVEC4 ;
+constructor_identifier ::= IVEC2 ;
+constructor_identifier ::= IVEC3 ;
+constructor_identifier ::= IVEC4 ;
+constructor_identifier ::= MAT2 ;
+constructor_identifier ::= MAT3 ;
+constructor_identifier ::= MAT4 ;
+constructor_identifier ::= TYPE_NAME ;
+
+unary_expression ::= postfix_expression ;
+unary_expression ::= INC_OP unary_expression ;
+unary_expression ::= DEC_OP unary_expression ;
+unary_expression ::= unary_operator unary_expression ;
+
+-- Grammar Note: No traditional style type casts.
+
+unary_operator ::= PLUS ;
+unary_operator ::= DASH ;
+unary_operator ::= BANG ;
+unary_operator ::= TILDE ; -- reserved
+
+-- Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
+
+multiplicative_expression ::= unary_expression ;
+multiplicative_expression ::= multiplicative_expression STAR unary_expression ;
+multiplicative_expression ::= multiplicative_expression SLASH unary_expression ;
+multiplicative_expression ::= multiplicative_expression PERCENT unary_expression ; -- reserved
+
+
+additive_expression ::= multiplicative_expression ;
+additive_expression ::= additive_expression PLUS multiplicative_expression ;
+additive_expression ::= additive_expression DASH multiplicative_expression ;
+
+shift_expression ::= additive_expression ;
+shift_expression ::= shift_expression LEFT_OP additive_expression ; -- reserved
+shift_expression ::= shift_expression RIGHT_OP additive_expression ; -- reserved
+
+relational_expression ::= shift_expression ;
+relational_expression ::= relational_expression LEFT_ANGLE shift_expression ;
+relational_expression ::= relational_expression RIGHT_ANGLE shift_expression ;
+relational_expression ::= relational_expression LE_OP shift_expression ;
+relational_expression ::= relational_expression GE_OP shift_expression ;
+
+equality_expression ::= relational_expression ;
+equality_expression ::= equality_expression EQ_OP relational_expression ;
+equality_expression ::= equality_expression NE_OP relational_expression ;
+
+and_expression ::= equality_expression ;
+and_expression ::= and_expression AMPERSAND equality_expression ; -- reserved
+
+exclusive_or_expression ::= and_expression ;
+exclusive_or_expression ::= exclusive_or_expression CARET and_expression ; -- reserved
+
+inclusive_or_expression ::= exclusive_or_expression ;
+inclusive_or_expression ::= inclusive_or_expression VERTICAL_BAR exclusive_or_expression ; -- reserved
+
+logical_and_expression ::= inclusive_or_expression ;
+logical_and_expression ::= logical_and_expression AND_OP inclusive_or_expression ;
+
+logical_xor_expression ::= logical_and_expression ;
+logical_xor_expression ::= logical_xor_expression XOR_OP logical_and_expression ;
+
+logical_or_expression ::= logical_xor_expression ;
+logical_or_expression ::= logical_or_expression OR_OP logical_xor_expression ;
+
+conditional_expression ::= logical_or_expression ;
+conditional_expression ::= logical_or_expression QUESTION expression COLON conditional_expression ;
+
+assignment_expression ::= conditional_expression ;
+assignment_expression ::= unary_expression assignment_operator assignment_expression ;
+
+assignment_operator ::= EQUAL ;
+assignment_operator ::= MUL_ASSIGN ;
+assignment_operator ::= DIV_ASSIGN ;
+assignment_operator ::= MOD_ASSIGN ; -- reserved
+assignment_operator ::= ADD_ASSIGN ;
+assignment_operator ::= SUB_ASSIGN ;
+assignment_operator ::= LEFT_ASSIGN ; -- reserved
+assignment_operator ::= RIGHT_ASSIGN ; -- reserved
+assignment_operator ::= AND_ASSIGN ; -- reserved
+assignment_operator ::= XOR_ASSIGN ; -- reserved
+assignment_operator ::= OR_ASSIGN ; -- reserved
+
+expression ::= assignment_expression ;
+expression ::= expression COMMA assignment_expression ;
+
+constant_expression ::= conditional_expression ;
+
+declaration ::= function_prototype SEMICOLON ;
+declaration ::= init_declarator_list SEMICOLON ;
+
+function_prototype ::= function_declarator RIGHT_PAREN ;
+
+function_declarator ::= function_header ;
+function_declarator ::= function_header_with_parameters ;
+
+function_header_with_parameters ::= function_header parameter_declaration ;
+function_header_with_parameters ::= function_header_with_parameters COMMA parameter_declaration ;
+
+function_header ::= fully_specified_type IDENTIFIER LEFT_PAREN ;
+/.
+case $rule_number: {
+ context.function_name = sym(2).s;
+} break;
+./
+
+parameter_declarator ::= type_specifier IDENTIFIER ;
+parameter_declarator ::= type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
+
+parameter_declaration ::= type_qualifier parameter_qualifier parameter_declarator ;
+parameter_declaration ::= parameter_qualifier parameter_declarator ;
+parameter_declaration ::= type_qualifier parameter_qualifier parameter_type_specifier ;
+parameter_declaration ::= parameter_qualifier parameter_type_specifier ;
+
+parameter_qualifier ::= ;
+parameter_qualifier ::= IN ;
+parameter_qualifier ::= OUT ;
+parameter_qualifier ::= INOUT ;
+
+parameter_type_specifier ::= type_specifier ;
+parameter_type_specifier ::= type_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET ;
+
+init_declarator_list ::= single_declaration ;
+init_declarator_list ::= init_declarator_list COMMA IDENTIFIER ;
+init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
+init_declarator_list ::= init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression ;
+init_declarator_list ::= RIGHT_BRACKET ;
+init_declarator_list ::= init_declarator_list COMMA IDENTIFIER EQUAL initializer ;
+
+single_declaration ::= fully_specified_type ;
+single_declaration ::= fully_specified_type IDENTIFIER ;
+single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET ;
+single_declaration ::= fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
+single_declaration ::= fully_specified_type IDENTIFIER EQUAL initializer ;
+
+-- Grammar Note: No 'enum', or 'typedef'.
+
+--fully_specified_type ::= type_specifier ;
+--fully_specified_type ::= type_qualifier type_specifier ;
+
+fully_specified_type ::= type_specifier ;
+fully_specified_type ::= type_qualifier ;
+fully_specified_type ::= fully_specified_type type_specifier ;
+fully_specified_type ::= fully_specified_type type_qualifier ;
+
+type_qualifier ::= CONST ;
+type_qualifier ::= ATTRIBUTE ; -- Vertex only.
+type_qualifier ::= VARYING ;
+type_qualifier ::= UNIFORM ;
+
+type_specifier ::= type_specifier_no_prec ;
+type_specifier ::= precision_qualifier type_specifier_no_prec ;
+
+type_specifier_no_prec ::= VOID ;
+type_specifier_no_prec ::= FLOAT ;
+type_specifier_no_prec ::= INT ;
+type_specifier_no_prec ::= BOOL ;
+type_specifier_no_prec ::= VEC2 ;
+type_specifier_no_prec ::= VEC3 ;
+type_specifier_no_prec ::= VEC4 ;
+type_specifier_no_prec ::= BVEC2 ;
+type_specifier_no_prec ::= BVEC3 ;
+type_specifier_no_prec ::= BVEC4 ;
+type_specifier_no_prec ::= IVEC2 ;
+type_specifier_no_prec ::= IVEC3 ;
+type_specifier_no_prec ::= IVEC4 ;
+type_specifier_no_prec ::= MAT2 ;
+type_specifier_no_prec ::= MAT3 ;
+type_specifier_no_prec ::= MAT4 ;
+type_specifier_no_prec ::= SAMPLER1D ;
+type_specifier_no_prec ::= SAMPLER2D ;
+type_specifier_no_prec ::= SAMPLER3D ;
+type_specifier_no_prec ::= SAMPLERCUBE ;
+type_specifier_no_prec ::= SAMPLER1DSHADOW ;
+type_specifier_no_prec ::= SAMPLER2DSHADOW ;
+type_specifier_no_prec ::= struct_specifier ;
+type_specifier_no_prec ::= TYPE_NAME ;
+
+precision_qualifier ::= HIGH_PRECISION ;
+precision_qualifier ::= MEDIUM_PRECISION ;
+precision_qualifier ::= LOW_PRECISION ;
+
+struct_specifier ::= STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
+/.
+case $rule_number: {
+ types.insert(sym(2).s);
+} break;
+./
+
+struct_specifier ::= STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE ;
+
+struct_declaration_list ::= struct_declaration ;
+struct_declaration_list ::= struct_declaration_list struct_declaration ;
+
+struct_declaration ::= type_specifier struct_declarator_list SEMICOLON ;
+
+struct_declarator_list ::= struct_declarator ;
+struct_declarator_list ::= struct_declarator_list COMMA struct_declarator ;
+
+struct_declarator ::= IDENTIFIER ;
+struct_declarator ::= IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET ;
+
+initializer ::= assignment_expression ;
+
+declaration_statement ::= declaration ;
+
+statement ::= compound_statement ;
+statement ::= simple_statement ;
+
+-- Grammar Note: No labeled statements; 'goto' is not supported.
+
+simple_statement ::= declaration_statement ;
+simple_statement ::= expression_statement ;
+simple_statement ::= selection_statement ;
+simple_statement ::= iteration_statement ;
+simple_statement ::= jump_statement ;
+
+compound_statement ::= LEFT_BRACE RIGHT_BRACE ;
+compound_statement ::= LEFT_BRACE statement_list RIGHT_BRACE ;
+
+statement_no_new_scope ::= compound_statement_no_new_scope ;
+statement_no_new_scope ::= simple_statement ;
+
+compound_statement_no_new_scope ::= LEFT_BRACE RIGHT_BRACE ;
+compound_statement_no_new_scope ::= LEFT_BRACE statement_list RIGHT_BRACE ;
+
+statement_list ::= statement ;
+statement_list ::= statement_list statement ;
+
+expression_statement ::= SEMICOLON ;
+expression_statement ::= expression SEMICOLON ;
+
+selection_statement ::= IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement ;
+selection_statement ::= IF LEFT_PAREN expression RIGHT_PAREN statement ;
+
+-- Grammar Note: No 'switch'. Switch statements not supported.
+
+condition ::= expression ;
+condition ::= fully_specified_type IDENTIFIER EQUAL initializer ;
+
+iteration_statement ::= WHILE LEFT_PAREN condition RIGHT_PAREN statement_no_new_scope ;
+iteration_statement ::= DO statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON ;
+iteration_statement ::= FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope ;
+
+for_init_statement ::= expression_statement ;
+for_init_statement ::= declaration_statement ;
+
+conditionopt ::= ;
+conditionopt ::= condition ;
+
+for_rest_statement ::= conditionopt SEMICOLON ;
+for_rest_statement ::= conditionopt SEMICOLON expression ;
+
+jump_statement ::= CONTINUE SEMICOLON ;
+jump_statement ::= BREAK SEMICOLON ;
+jump_statement ::= RETURN SEMICOLON ;
+jump_statement ::= RETURN expression SEMICOLON ;
+jump_statement ::= DISCARD SEMICOLON ; -- Fragment shader only.
+
+-- Grammar Note: No 'goto'. Gotos are not supported.
+
+external_declaration ::= function_definition ;
+external_declaration ::= declaration ;
+
+function_definition ::= function_prototype compound_statement_no_new_scope ;
+/.
+ case $rule_number: { // $rule_name
+ qDebug() << "--> function" << *context.function_name;
+ } break;
+./
+
+
+
+
+
+/.
+ } // switch
+
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+ }
+
+ else
+ {
+ // ### ERROR RECOVERY HERE
+ break;
+ }
+ }
+
+ fprintf (stderr, "%s:%d: Syntax Error\n", qPrintable(context.fileName), context.line);
+
+ return false;
+}
+
+#include "glsl-lex.incl"
+
+
+/////////////////////////////
+// entry point
+/////////////////////////////
+int main()
+{
+#if 0 // dump the GLSL grammar
+ for (int r = 0; r < GLSLParserTable::RULE_COUNT; ++r)
+ {
+ int ridx = GLSLParserTable::rule_index [r];
+ int rhs = GLSLParserTable::rhs [r];
+ printf ("%3d) %s ::=", r + 1, GLSLParserTable::spell[GLSLParserTable::rule_info [ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs; ++i)
+ {
+ int symbol = GLSLParserTable::rule_info [i];
+ if (const char *name = GLSLParserTable::spell [symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+ }
+#endif
+
+ GLSLParser parser;
+
+ if (parser.parse())
+ qDebug() << "OK";
+ else
+ qDebug() << "KO";
+}
+
+./
diff --git a/src/tools/qlalr/examples/glsl/glsl.pro b/src/tools/qlalr/examples/glsl/glsl.pro
new file mode 100644
index 0000000000..8ac775f21d
--- /dev/null
+++ b/src/tools/qlalr/examples/glsl/glsl.pro
@@ -0,0 +1,4 @@
+QT = core
+TARGET = glsl.bin
+SOURCES += glsl.cpp
+
diff --git a/src/tools/qlalr/examples/lambda/COMPILE b/src/tools/qlalr/examples/lambda/COMPILE
new file mode 100644
index 0000000000..3226ec95fa
--- /dev/null
+++ b/src/tools/qlalr/examples/lambda/COMPILE
@@ -0,0 +1,3 @@
+qlalr lambda.g
+qmake
+make
diff --git a/src/tools/qlalr/examples/lambda/lambda.g b/src/tools/qlalr/examples/lambda/lambda.g
new file mode 100644
index 0000000000..2d9ddd8ed4
--- /dev/null
+++ b/src/tools/qlalr/examples/lambda/lambda.g
@@ -0,0 +1,81 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+-- Contact: http://www.qt-project.org/legal
+--
+-- This file is part of the QtCore module of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, 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, Digia gives you certain additional
+-- rights. These rights are described in the Digia 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.
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+-- lambda calculus
+
+%decl lambda.h
+
+%token LPAREN
+%token RPAREN
+%token ID
+%token FUN
+%token DOT
+
+%nonassoc SHIFT_THERE
+%nonassoc LPAREN RPAREN ID FUN DOT
+%nonassoc REDUCE_HERE
+
+%start Expr
+
+/:
+enum {
+:/
+
+
+Expr ::= ID %prec SHIFT_THERE ;
+/: Symbol = $rule_number,
+:/
+
+Expr ::= LPAREN Expr RPAREN %prec SHIFT_THERE ;
+/: SubExpression = $rule_number,
+:/
+
+Expr ::= Expr Expr %prec REDUCE_HERE ;
+/: Appl = $rule_number,
+:/
+
+Expr ::= FUN ID DOT Expr %prec SHIFT_THERE ;
+/: Abstr = $rule_number,
+:/
+
+/:};
+:/
+
diff --git a/src/tools/qlalr/examples/lambda/lambda.pro b/src/tools/qlalr/examples/lambda/lambda.pro
new file mode 100644
index 0000000000..dfe4824027
--- /dev/null
+++ b/src/tools/qlalr/examples/lambda/lambda.pro
@@ -0,0 +1,3 @@
+HEADERS += lambda.h parser_table_p.h
+SOURCES += main.cpp parser_table.cpp
+QT = core
diff --git a/src/tools/qlalr/examples/lambda/main.cpp b/src/tools/qlalr/examples/lambda/main.cpp
new file mode 100644
index 0000000000..6c45d48e69
--- /dev/null
+++ b/src/tools/qlalr/examples/lambda/main.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lambda.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include "parser_table_p.h"
+
+class Parser: protected parser_table
+{
+public:
+ union Value {
+ int ival;
+ // ### more...
+ };
+
+public:
+ Parser();
+ ~Parser();
+
+ bool parse();
+
+protected:
+ inline void reallocateStack();
+
+ inline Value &sym(int index)
+ { return sym_stack [tos + index - 1]; }
+
+ int nextToken();
+ void consumeRule(int ruleno);
+
+protected:
+ int tos;
+ int stack_size;
+ Value *sym_stack;
+ int *state_stack;
+ int current_char;
+ unsigned in_tag: 1;
+};
+
+inline void Parser::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack = reinterpret_cast<Value*> (::realloc(sym_stack, stack_size * sizeof(Value)));
+ state_stack = reinterpret_cast<int*> (::realloc(state_stack, stack_size * sizeof(int)));
+}
+
+Parser::Parser():
+ tos(0),
+ stack_size(0),
+ sym_stack(0),
+ state_stack(0)
+{
+}
+
+Parser::~Parser()
+{
+ if (stack_size) {
+ ::free(sym_stack);
+ ::free(state_stack);
+ }
+}
+
+bool Parser::parse()
+{
+ const int INITIAL_STATE = 0;
+
+ current_char = 0;
+ in_tag = 0;
+
+ int yytoken = -1;
+ reallocateStack();
+
+ tos = 0;
+ state_stack[++tos] = INITIAL_STATE;
+
+ while (true)
+ {
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state_stack [tos]])
+ yytoken = nextToken();
+
+ int act = t_action (state_stack [tos], yytoken);
+
+ if (act == ACCEPT_STATE) {
+ return true;
+ }
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos].ival = current_char; // ### save the token value here
+ state_stack [tos] = act;
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+ consumeRule (r);
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+ }
+
+ else
+ break;
+ }
+
+ return false;
+}
+
+
+int Parser::nextToken()
+{
+ static int tokens[] = { ID, ID, ID, EOF_SYMBOL };
+ static int *tk = tokens;
+
+ return *tk++;
+}
+
+void Parser::consumeRule(int ruleno)
+{
+ switch (ruleno) {
+ case Symbol:
+ printf("symbol\n");
+ break;
+ case SubExpression:
+ printf("sub-expr\n");
+ break;
+ case Appl:
+ printf("appl\n");
+ break;
+ case Abstr:
+ printf("abstr\n");
+ break;
+ }
+}
+
+/////////////////////////////
+// entry point
+/////////////////////////////
+int main()
+{
+ Parser parser;
+
+ if (parser.parse())
+ printf ("OK\n");
+ else
+ printf ("KO\n");
+}
+
+
diff --git a/src/tools/qlalr/examples/qparser/COMPILE b/src/tools/qlalr/examples/qparser/COMPILE
new file mode 100644
index 0000000000..4aad300a9f
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/COMPILE
@@ -0,0 +1,3 @@
+qlalr calc.g
+qmake
+make
diff --git a/src/tools/qlalr/examples/qparser/calc.g b/src/tools/qlalr/examples/qparser/calc.g
new file mode 100644
index 0000000000..394b89c964
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/calc.g
@@ -0,0 +1,133 @@
+----------------------------------------------------------------------------
+--
+-- Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+-- Contact: http://www.qt-project.org/legal
+--
+-- This file is part of the QtCore module of the Qt Toolkit.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, 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, Digia gives you certain additional
+-- rights. These rights are described in the Digia 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.
+--
+--
+-- $QT_END_LICENSE$
+--
+----------------------------------------------------------------------------
+
+%parser calc_grammar
+%decl calc_parser.h
+%impl calc_parser.cpp
+
+%token_prefix Token_
+%token number
+%token lparen
+%token rparen
+%token plus
+%token minus
+
+%start Goal
+
+/:
+#ifndef CALC_PARSER_H
+#define CALC_PARSER_H
+
+#include "qparser.h"
+#include "calc_grammar_p.h"
+
+class CalcParser: public QParser<CalcParser, $table>
+{
+public:
+ int nextToken();
+ void consumeRule(int ruleno);
+};
+
+#endif // CALC_PARSER_H
+:/
+
+
+
+
+
+/.
+#include "calc_parser.h"
+
+#include <QtDebug>
+#include <cstdlib>
+
+void CalcParser::consumeRule(int ruleno)
+ {
+ switch (ruleno) {
+./
+
+Goal: Expression ;
+/.
+case $rule_number:
+ qDebug() << "value:" << sym(1);
+ break;
+./
+
+PrimaryExpression: number ;
+PrimaryExpression: lparen Expression rparen ;
+/.
+case $rule_number:
+ sym(1) = sym (2);
+ break;
+./
+
+Expression: PrimaryExpression ;
+
+Expression: Expression plus PrimaryExpression;
+/.
+case $rule_number:
+ sym(1) += sym (3);
+ break;
+./
+
+Expression: Expression minus PrimaryExpression;
+/.
+case $rule_number:
+ sym(1) -= sym (3);
+ break;
+./
+
+
+
+/.
+ } // switch
+}
+
+#include <cstdio>
+
+int main()
+{
+ CalcParser p;
+
+ if (p.parse())
+ printf("ok\n");
+}
+./
diff --git a/src/tools/qlalr/examples/qparser/calc.l b/src/tools/qlalr/examples/qparser/calc.l
new file mode 100644
index 0000000000..eb666f1f7e
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/calc.l
@@ -0,0 +1,61 @@
+
+%option noyywrap
+
+%{
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR tool of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "calc_parser.h"
+#include <cstdlib>
+
+#define YY_DECL int CalcParser::nextToken()
+%}
+
+%%
+
+[ \t\n] { /* eat me */ }
+[0-9]+ { sym(1) = atoi (yytext); return Token_number; }
+"(" { return Token_lparen; }
+")" { return Token_rparen; }
+"+" { return Token_plus; }
+"-" { return Token_minus; }
+
+%%
diff --git a/src/tools/qlalr/examples/qparser/qparser.cpp b/src/tools/qlalr/examples/qparser/qparser.cpp
new file mode 100644
index 0000000000..d749467fe8
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/qparser.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qparser.h"
+
diff --git a/src/tools/qlalr/examples/qparser/qparser.h b/src/tools/qlalr/examples/qparser/qparser.h
new file mode 100644
index 0000000000..a5678d0c33
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/qparser.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPARSER_H
+#define QPARSER_H
+
+#include <QtCore/QSharedDataPointer>
+#include <QtCore/QVarLengthArray>
+
+template <typename _Parser, typename _Table, typename _Value = int>
+class QParser: protected _Table
+{
+public:
+ QParser();
+ ~QParser();
+
+ bool parse();
+
+ inline _Value &sym(int index);
+
+private:
+ inline int nextToken()
+ {
+ return static_cast<_Parser*> (this)->nextToken();
+ }
+
+ inline void consumeRule(int rule)
+ {
+ static_cast<_Parser*> (this)->consumeRule(rule);
+ }
+
+ enum { DefaultStackSize = 128 };
+
+ struct Data: public QSharedData
+ {
+ Data(): stackSize (DefaultStackSize), tos (0) {}
+
+ QVarLengthArray<int, DefaultStackSize> stateStack;
+ QVarLengthArray<_Value, DefaultStackSize> parseStack;
+ int stackSize;
+ int tos;
+
+ void reallocateStack() {
+ stackSize <<= 1;
+ stateStack.resize(stackSize);
+ parseStack.resize(stackSize);
+ }
+ };
+
+ QSharedDataPointer<Data> d;
+};
+
+template <typename _Parser, typename _Table, typename _Value>
+inline _Value &QParser<_Parser, _Table, _Value>::sym(int n)
+{
+ return d->parseStack [d->tos + n - 1];
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+QParser<_Parser, _Table, _Value>::QParser():
+ d(new Data())
+{
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+QParser<_Parser, _Table, _Value>::~QParser()
+{
+}
+
+template <typename _Parser, typename _Table, typename _Value>
+bool QParser<_Parser, _Table, _Value>::parse()
+{
+ const int INITIAL_STATE = 0;
+
+ d->tos = 0;
+ d->reallocateStack();
+
+ int act = d->stateStack[++d->tos] = INITIAL_STATE;
+ int token = -1;
+
+ forever {
+ if (token == -1 && - _Table::TERMINAL_COUNT != _Table::action_index[act])
+ token = nextToken();
+
+ act = _Table::t_action(act, token);
+
+ if (d->stateStack[d->tos] == _Table::ACCEPT_STATE)
+ return true;
+
+ else if (act > 0) {
+ if (++d->tos == d->stackSize)
+ d->reallocateStack();
+
+ d->parseStack[d->tos] = d->parseStack[d->tos - 1];
+ d->stateStack[d->tos] = act;
+ token = -1;
+ }
+
+ else if (act < 0) {
+ int r = - act - 1;
+ d->tos -= _Table::rhs[r];
+ act = d->stateStack[d->tos++];
+ consumeRule(r);
+ act = d->stateStack[d->tos] = _Table::nt_action(act, _Table::lhs[r] - _Table::TERMINAL_COUNT);
+ }
+
+ else break;
+ }
+
+ return false;
+}
+
+
+#endif // QPARSER_H
diff --git a/src/tools/qlalr/examples/qparser/qparser.pro b/src/tools/qlalr/examples/qparser/qparser.pro
new file mode 100644
index 0000000000..938e336939
--- /dev/null
+++ b/src/tools/qlalr/examples/qparser/qparser.pro
@@ -0,0 +1,4 @@
+QT = core
+HEADERS += calc_grammar_p.h calc_parser.h qparser.h
+SOURCES += calc_grammar.cpp calc_parser.cpp qparser.cpp
+LEXSOURCES += calc.l
diff --git a/src/tools/qlalr/grammar.cpp b/src/tools/qlalr/grammar.cpp
new file mode 100644
index 0000000000..f1c32adb2d
--- /dev/null
+++ b/src/tools/qlalr/grammar.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This file was generated by qlalr - DO NOT EDIT!
+#include "grammar_p.h"
+
+QT_BEGIN_NAMESPACE
+
+const char *const grammar::spell [] = {
+ "end of file", "identifier", "string literal", "%decl", "%expect", "%expect-lr", "%impl", "%left", "%merged_output", "%nonassoc",
+ "%parser", "%prec", "%right", "%start", "%token", "%token_prefix", ":", "|", ";", 0,
+ 0, 0};
+
+const short grammar::lhs [] = {
+ 22, 23, 23, 29, 25, 28, 28, 28, 28, 28,
+ 28, 28, 24, 24, 31, 32, 32, 33, 33, 34,
+ 34, 34, 31, 35, 35, 36, 37, 37, 38, 38,
+ 30, 30, 26, 26, 40, 39, 41, 41, 44, 43,
+ 43, 42, 42, 27, 45};
+
+const short grammar::rhs [] = {
+ 4, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 2, 2, 1, 2, 2, 2, 1,
+ 1, 1, 2, 1, 2, 1, 1, 1, 1, 2,
+ 0, 1, 1, 2, 2, 4, 3, 6, 0, 0,
+ 2, 1, 2, 0, 2};
+
+const short grammar::action_default [] = {
+ 44, 2, 44, 0, 0, 0, 0, 13, 0, 0,
+ 3, 0, 0, 0, 8, 10, 11, 9, 7, 6,
+ 12, 20, 22, 0, 21, 0, 44, 31, 0, 14,
+ 26, 24, 23, 25, 4, 33, 1, 0, 34, 44,
+ 35, 42, 39, 40, 0, 31, 44, 40, 43, 0,
+ 31, 41, 29, 27, 28, 32, 38, 30, 36, 31,
+ 37, 5, 44, 16, 15, 18, 19, 17, 45};
+
+const short grammar::goto_default [] = {
+ 3, 2, 13, 26, 36, 41, 10, 27, 61, 29,
+ 64, 63, 23, 32, 31, 52, 55, 38, 39, 42,
+ 43, 59, 44, 0};
+
+const short grammar::action_index [] = {
+ -22, -22, 54, 1, 5, 15, 20, -22, -1, 6,
+ -22, 3, 2, 35, -22, -22, -22, -22, -22, -22,
+ -22, -22, -22, 10, -22, 7, -22, 14, 9, -22,
+ -22, -22, 8, -22, -22, -22, 11, -2, -22, -22,
+ -22, -22, -3, 16, 13, 14, -22, 17, -22, 4,
+ 14, -22, -22, -22, -22, 14, -22, -22, -22, 14,
+ -22, -22, 0, -22, 12, -22, -22, -22, -22,
+
+ 2, -24, -2, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -4, -24, -24, -24,
+ -24, -24, -14, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, 0, -16, -15, -24, -24,
+ 15, -24, -24, -24, -24, -10, -24, -24, -24, 1,
+ -24, -24, -3, -24, -1, -24, -24, -24, -24};
+
+const short grammar::action_info [] = {
+ 17, 68, 66, 20, 19, 51, 14, 18, 34, 30,
+ 62, 30, 37, 62, 40, 45, 15, 48, 48, 0,
+ 0, 16, 0, 0, 0, 0, 0, 49, 49, 0,
+ 46, 0, 0, 53, 54, 0, 0, 0, 0, 0,
+ 0, 0, 21, 0, 22, 0, 0, 24, 25, 28,
+ 0, 0, 0, 0, 0, 0, 0, 4, 5, 6,
+ 8, 0, 9, 0, 11, 0, 0, 0, 0, 12,
+ 0, 0, 0, 0, 0, 0,
+
+ 33, 35, 65, 7, 47, 57, 50, 1, 58, 60,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 56, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+const short grammar::action_check [] = {
+ 1, 0, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 16, 18, 1, 1, 1, -1,
+ -1, 1, -1, -1, -1, -1, -1, 11, 11, -1,
+ 17, -1, -1, 19, 20, -1, -1, -1, -1, -1,
+ -1, -1, 7, -1, 9, -1, -1, 12, 13, 14,
+ -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ 6, -1, 8, -1, 10, -1, -1, -1, -1, 15,
+ -1, -1, -1, -1, -1, -1,
+
+ 14, 5, 5, 5, 20, 15, 21, 5, 8, 8,
+ 11, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 8, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1};
+
+QT_END_NAMESPACE
diff --git a/src/tools/qlalr/grammar_p.h b/src/tools/qlalr/grammar_p.h
new file mode 100644
index 0000000000..e2f294ea00
--- /dev/null
+++ b/src/tools/qlalr/grammar_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+// This file was generated by qlalr - DO NOT EDIT!
+#ifndef GRAMMAR_P_H
+#define GRAMMAR_P_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class grammar
+{
+public:
+ enum VariousConstants {
+ EOF_SYMBOL = 0,
+ COLON = 16,
+ DECL = 19,
+ DECL_FILE = 3,
+ ERROR = 21,
+ EXPECT = 4,
+ EXPECT_RR = 5,
+ ID = 1,
+ IMPL = 20,
+ IMPL_FILE = 6,
+ LEFT = 7,
+ MERGED_OUTPUT = 8,
+ NONASSOC = 9,
+ OR = 17,
+ PARSER = 10,
+ PREC = 11,
+ RIGHT = 12,
+ SEMICOLON = 18,
+ START = 13,
+ STRING_LITERAL = 2,
+ TOKEN = 14,
+ TOKEN_PREFIX = 15,
+
+ ACCEPT_STATE = 68,
+ RULE_COUNT = 45,
+ STATE_COUNT = 69,
+ TERMINAL_COUNT = 22,
+ NON_TERMINAL_COUNT = 24,
+
+ GOTO_INDEX_OFFSET = 69,
+ GOTO_INFO_OFFSET = 76,
+ GOTO_CHECK_OFFSET = 76
+ };
+
+ static const char *const spell [];
+ static const short lhs [];
+ static const short rhs [];
+ static const short goto_default [];
+ static const short action_default [];
+ static const short action_index [];
+ static const short action_info [];
+ static const short action_check [];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
+ if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
+ return goto_default [nt];
+
+ return action_info [GOTO_INFO_OFFSET + yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
+};
+
+
+QT_END_NAMESPACE
+#endif // GRAMMAR_P_H
+
diff --git a/src/tools/qlalr/lalr.cpp b/src/tools/qlalr/lalr.cpp
new file mode 100644
index 0000000000..c68076477f
--- /dev/null
+++ b/src/tools/qlalr/lalr.cpp
@@ -0,0 +1,781 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lalr.h"
+
+#include <limits.h>
+
+#include <algorithm>
+
+#define QLALR_NO_DEBUG_NULLABLES
+#define QLALR_NO_DEBUG_LOOKBACKS
+#define QLALR_NO_DEBUG_DIRECT_READS
+#define QLALR_NO_DEBUG_READS
+#define QLALR_NO_DEBUG_INCLUDES
+#define QLALR_NO_DEBUG_LOOKAHEADS
+
+QT_BEGIN_NAMESPACE
+QTextStream qerr (stderr, QIODevice::WriteOnly);
+QTextStream qout (stdout, QIODevice::WriteOnly);
+
+bool operator < (Name a, Name b)
+{
+ return *a < *b;
+}
+
+bool operator < (ItemPointer a, ItemPointer b)
+{
+ return &*a < &*b;
+}
+
+bool operator < (StatePointer a, StatePointer b)
+{
+ return &*a < &*b;
+}
+QT_END_NAMESPACE
+
+bool Read::operator < (const Read &other) const
+{
+ if (state == other.state)
+ return nt < other.nt;
+
+ return state < other.state;
+}
+
+bool Include::operator < (const Include &other) const
+{
+ if (state == other.state)
+ return nt < other.nt;
+
+ return state < other.state;
+}
+
+bool Lookback::operator < (const Lookback &other) const
+{
+ if (state == other.state)
+ return nt < other.nt;
+
+ return state < other.state;
+}
+
+QTextStream &operator << (QTextStream &out, const Name &n)
+{
+ return out << *n;
+}
+
+QTextStream &operator << (QTextStream &out, const Rule &r)
+{
+ out << *r.lhs << " ::=";
+
+ for (NameList::const_iterator name = r.rhs.begin (); name != r.rhs.end (); ++name)
+ out << " " << **name;
+
+ return out;
+}
+
+QTextStream &operator << (QTextStream &out, const NameSet &ns)
+{
+ out << "{";
+
+ for (NameSet::const_iterator n = ns.begin (); n != ns.end (); ++n)
+ {
+ if (n != ns.begin ())
+ out << ", ";
+
+ out << *n;
+ }
+
+ return out << "}";
+}
+
+Item Item::next () const
+{
+ Q_ASSERT (! isReduceItem ());
+
+ Item n;
+ n.rule = rule;
+ n.dot = dot;
+ ++n.dot;
+
+ return n;
+}
+
+QTextStream &operator << (QTextStream &out, const Item &item)
+{
+ RulePointer r = item.rule;
+
+ out << *r->lhs << ":";
+ for (NameList::iterator name = r->rhs.begin (); name != r->rhs.end (); ++name)
+ {
+ out << " ";
+
+ if (item.dot == name)
+ out << ". ";
+
+ out << **name;
+ }
+
+ if (item.isReduceItem ())
+ out << " .";
+
+ return out;
+}
+
+State::State (Grammar *g):
+ defaultReduce (g->rules.end ())
+{
+}
+
+QPair<ItemPointer, bool> State::insert (const Item &item)
+{
+ ItemPointer it = std::find (kernel.begin (), kernel.end (), item);
+
+ if (it != kernel.end ())
+ return qMakePair (it, false);
+
+ return qMakePair (kernel.insert (it, item), true);
+}
+
+QPair<ItemPointer, bool> State::insertClosure (const Item &item)
+{
+ ItemPointer it = std::find (closure.begin (), closure.end (), item);
+
+ if (it != closure.end ())
+ return qMakePair (it, false);
+
+ return qMakePair (closure.insert (it, item), true);
+}
+
+
+/////////////////////////////////////////////////////////////
+// Grammar
+/////////////////////////////////////////////////////////////
+Grammar::Grammar ():
+ start (names.end ())
+{
+ expected_shift_reduce = 0;
+ expected_reduce_reduce = 0;
+ current_prec = 0;
+ current_assoc = NonAssoc;
+
+ table_name = QLatin1String ("parser_table");
+
+ tk_end = intern ("$end");
+ terminals.insert (tk_end);
+ spells.insert (tk_end, "end of file");
+
+ /*tk_error= terminals.insert (intern ("error"))*/;
+}
+
+Name Grammar::intern (const QString &id)
+{
+ Name name = std::find (names.begin (), names.end (), id);
+
+ if (name == names.end ())
+ name = names.insert (names.end (), id);
+
+ return name;
+}
+
+void Grammar::buildRuleMap ()
+{
+ NameSet undefined;
+ for (RulePointer rule = rules.begin (); rule != rules.end (); ++rule)
+ {
+ for (NameList::iterator it = rule->rhs.begin (); it != rule->rhs.end (); ++it)
+ {
+ Name name = *it;
+ if (isTerminal (name) || declared_lhs.find (name) != declared_lhs.end ()
+ || undefined.find (name) != undefined.end ())
+ continue;
+
+ undefined.insert(name);
+ fprintf (stderr, "*** Warning. Symbol `%s' is not defined\n", qPrintable (*name));
+ }
+
+ rule_map.insert (rule->lhs, rule);
+ }
+}
+
+void Grammar::buildExtendedGrammar ()
+{
+ accept_symbol = intern ("$accept");
+ goal = rules.insert (rules.end (), Rule ());
+ goal->lhs = accept_symbol;
+ goal->rhs.push_back (start);
+ goal->rhs.push_back (tk_end);
+
+ non_terminals.insert (accept_symbol);
+}
+
+struct _Nullable: public std::unary_function<Name, bool>
+{
+ Automaton *_M_automaton;
+
+ _Nullable (Automaton *aut):
+ _M_automaton (aut) {}
+
+ bool operator () (Name name) const
+ { return _M_automaton->nullables.find (name) != _M_automaton->nullables.end (); }
+};
+
+Automaton::Automaton (Grammar *g):
+ _M_grammar (g),
+ start (states.end ())
+{
+}
+
+int Automaton::id (RulePointer rule)
+{
+ return 1 + std::distance (_M_grammar->rules.begin (), rule);
+}
+
+int Automaton::id (Name name)
+{
+ return std::distance (_M_grammar->names.begin (), name);
+}
+
+int Automaton::id (StatePointer state)
+{
+ return std::distance (states.begin (), state);
+}
+
+void Automaton::build ()
+{
+ Item item;
+ item.rule = _M_grammar->goal;
+ item.dot = _M_grammar->goal->rhs.begin ();
+
+ State tmp (_M_grammar);
+ tmp.insert (item);
+ start = internState (tmp).first;
+
+ closure (start);
+
+ buildNullables ();
+ buildLookbackSets ();
+ buildReads ();
+ buildIncludesAndFollows ();
+ buildLookaheads ();
+ buildDefaultReduceActions ();
+}
+
+void Automaton::buildNullables ()
+{
+ bool changed = true;
+
+ while (changed)
+ {
+ changed = false;
+
+ for (RulePointer rule = _M_grammar->rules.begin (); rule != _M_grammar->rules.end (); ++rule)
+ {
+ NameList::iterator nn = std::find_if (rule->rhs.begin (), rule->rhs.end (), std::not1 (_Nullable (this)));
+
+ if (nn == rule->rhs.end ())
+ changed |= nullables.insert (rule->lhs).second;
+ }
+ }
+
+#ifndef QLALR_NO_DEBUG_NULLABLES
+ qerr << "nullables = {" << nullables << endl;
+#endif
+}
+
+QPair<StatePointer, bool> Automaton::internState (const State &state)
+{
+ StatePointer it = std::find (states.begin (), states.end (), state);
+
+ if (it != states.end ())
+ return qMakePair (it, false);
+
+ return qMakePair (states.insert (it, state), true);
+}
+
+struct _Bucket
+{
+ QLinkedList<ItemPointer> items;
+
+ void insert (ItemPointer item)
+ { items.push_back (item); }
+
+ State toState (Automaton *aut)
+ {
+ State st (aut->_M_grammar);
+
+ for (QLinkedList<ItemPointer>::iterator item = items.begin (); item != items.end (); ++item)
+ st.insert ((*item)->next ());
+
+ return st;
+ }
+};
+
+void Automaton::closure (StatePointer state)
+{
+ if (! state->closure.empty ()) // ### not true.
+ return;
+
+ typedef QMap<Name, _Bucket> bucket_map_type;
+
+ bucket_map_type buckets;
+ QStack<ItemPointer> working_list;
+
+ for (ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item)
+ working_list.push (item);
+
+ state->closure = state->kernel;
+
+ while (! working_list.empty ())
+ {
+ ItemPointer item = working_list.top ();
+ working_list.pop ();
+
+ if (item->isReduceItem ())
+ continue;
+
+ buckets [*item->dot].insert (item);
+
+ if (_M_grammar->isNonTerminal (*item->dot))
+ {
+ foreach (RulePointer rule, _M_grammar->rule_map.values (*item->dot))
+ {
+ Item ii;
+ ii.rule = rule;
+ ii.dot = rule->rhs.begin ();
+
+ QPair<ItemPointer, bool> r = state->insertClosure (ii);
+
+ if (r.second)
+ working_list.push (r.first);
+ }
+ }
+ }
+
+ QList<StatePointer> todo;
+
+ for (bucket_map_type::iterator bucket = buckets.begin (); bucket != buckets.end (); ++bucket)
+ {
+ QPair<StatePointer, bool> r = internState (bucket->toState (this));
+
+ StatePointer target = r.first;
+
+ if (r.second)
+ todo.push_back (target);
+
+ state->bundle.insert (bucket.key(), target);
+ }
+
+ while (! todo.empty ())
+ {
+ closure (todo.front ());
+ todo.pop_front ();
+ }
+}
+
+void Automaton::buildLookbackSets ()
+{
+ for (StatePointer p = states.begin (); p != states.end (); ++p)
+ {
+ for (Bundle::iterator a = p->bundle.begin (); a != p->bundle.end (); ++a)
+ {
+ Name A = a.key ();
+
+ if (! _M_grammar->isNonTerminal (A))
+ continue;
+
+ foreach (RulePointer rule, _M_grammar->rule_map.values (A))
+ {
+ StatePointer q = p;
+
+ for (NameList::iterator dot = rule->rhs.begin (); dot != rule->rhs.end (); ++dot)
+ q = q->bundle.value (*dot, states.end ());
+
+ Q_ASSERT (q != states.end ());
+
+ ItemPointer item = q->closure.begin ();
+
+ for (; item != q->closure.end (); ++item)
+ {
+ if (item->rule == rule && item->dot == item->end_rhs ())
+ break;
+ }
+
+ if (item == q->closure.end ())
+ {
+ Q_ASSERT (q == p);
+ Q_ASSERT (rule->rhs.begin () == rule->rhs.end ());
+
+ for (item = q->closure.begin (); item != q->closure.end (); ++item)
+ {
+ if (item->rule == rule && item->dot == item->end_rhs ())
+ break;
+ }
+ }
+
+ Q_ASSERT (item != q->closure.end ());
+
+ lookbacks.insert (item, Lookback (p, A));
+
+#ifndef QLALR_NO_DEBUG_LOOKBACKS
+ qerr << "*** (" << id (q) << ", " << *rule << ") lookback (" << id (p) << ", " << *A << ")" << endl;
+#endif
+ }
+ }
+ }
+}
+
+void Automaton::buildDirectReads ()
+{
+ for (StatePointer q = states.begin (); q != states.end (); ++q)
+ {
+ for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
+ {
+ if (! _M_grammar->isNonTerminal (a.key ()))
+ continue;
+
+ StatePointer r = a.value ();
+
+ for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
+ {
+ Name sym = z.key ();
+
+ if (! _M_grammar->isTerminal (sym))
+ continue;
+
+ q->reads [a.key ()].insert (sym);
+ }
+ }
+
+#ifndef QLALR_NO_DEBUG_DIRECT_READS
+ for (QMap<Name, NameSet>::iterator dr = q->reads.begin (); dr != q->reads.end (); ++dr)
+ qerr << "*** DR(" << id (q) << ", " << dr.key () << ") = " << dr.value () << endl;
+#endif
+ }
+}
+
+void Automaton::buildReadsDigraph ()
+{
+ for (StatePointer q = states.begin (); q != states.end (); ++q)
+ {
+ for (Bundle::iterator a = q->bundle.begin (); a != q->bundle.end (); ++a)
+ {
+ if (! _M_grammar->isNonTerminal (a.key ()))
+ continue;
+
+ StatePointer r = a.value ();
+
+ for (Bundle::iterator z = r->bundle.begin (); z != r->bundle.end (); ++z)
+ {
+ Name sym = z.key ();
+
+ if (! _M_grammar->isNonTerminal(sym) || nullables.find (sym) == nullables.end ())
+ continue;
+
+ ReadsGraph::iterator source = ReadsGraph::get (Read (q, a.key ()));
+ ReadsGraph::iterator target = ReadsGraph::get (Read (r, sym));
+
+ source->insertEdge (target);
+
+#ifndef QLALR_NO_DEBUG_READS
+ qerr << "*** ";
+ dump (qerr, source);
+ qerr << " reads ";
+ dump (qerr, target);
+ qerr << endl;
+#endif
+ }
+ }
+ }
+}
+
+void Automaton::buildReads ()
+{
+ buildDirectReads ();
+ buildReadsDigraph ();
+
+ _M_reads_dfn = 0;
+
+ for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
+ {
+ if (! node->root)
+ continue;
+
+ visitReadNode (node);
+ }
+
+ for (ReadsGraph::iterator node = ReadsGraph::begin_nodes (); node != ReadsGraph::end_nodes (); ++node)
+ visitReadNode (node);
+}
+
+void Automaton::visitReadNode (ReadNode node)
+{
+ if (node->dfn != 0)
+ return; // nothing to do
+
+ int N = node->dfn = ++_M_reads_dfn;
+ _M_reads_stack.push (node);
+
+#ifndef QLALR_NO_DEBUG_INCLUDES
+ // qerr << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << endl;
+#endif
+
+ for (ReadsGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
+ {
+ ReadsGraph::iterator r = *edge;
+
+ visitReadNode (r);
+
+ node->dfn = qMin (N, r->dfn);
+
+ NameSet &dst = node->data.state->reads [node->data.nt];
+ NameSet &src = r->data.state->reads [r->data.nt];
+ dst.insert (src.begin (), src.end ());
+ }
+
+ if (node->dfn == N)
+ {
+ ReadsGraph::iterator tos = _M_reads_stack.top ();
+
+ do {
+ tos = _M_reads_stack.top ();
+ _M_reads_stack.pop ();
+ tos->dfn = INT_MAX;
+ } while (tos != node);
+ }
+}
+
+void Automaton::buildIncludesAndFollows ()
+{
+ for (StatePointer p = states.begin (); p != states.end (); ++p)
+ p->follows = p->reads;
+
+ buildIncludesDigraph ();
+
+ _M_includes_dfn = 0;
+
+ for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
+ {
+ if (! node->root)
+ continue;
+
+ visitIncludeNode (node);
+ }
+
+ for (IncludesGraph::iterator node = IncludesGraph::begin_nodes (); node != IncludesGraph::end_nodes (); ++node)
+ visitIncludeNode (node);
+}
+
+void Automaton::buildIncludesDigraph ()
+{
+ for (StatePointer pp = states.begin (); pp != states.end (); ++pp)
+ {
+ for (Bundle::iterator a = pp->bundle.begin (); a != pp->bundle.end (); ++a)
+ {
+ Name name = a.key ();
+
+ if (! _M_grammar->isNonTerminal (name))
+ continue;
+
+ foreach (RulePointer rule, _M_grammar->rule_map.values (name))
+ {
+ StatePointer p = pp;
+
+ for (NameList::iterator A = rule->rhs.begin (); A != rule->rhs.end (); ++A)
+ {
+ NameList::iterator dot = A;
+ ++dot;
+
+ if (_M_grammar->isNonTerminal (*A) && dot == rule->rhs.end ())
+ {
+ // found an include edge.
+ IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
+ IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
+
+ source->insertEdge (target);
+
+#ifndef QLALR_NO_DEBUG_INCLUDES
+ qerr << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << endl;
+#endif // QLALR_NO_DEBUG_INCLUDES
+
+ continue;
+ }
+
+ p = p->bundle.value (*A);
+
+ if (! _M_grammar->isNonTerminal (*A))
+ continue;
+
+ NameList::iterator first_not_nullable = std::find_if (dot, rule->rhs.end (), std::not1 (_Nullable (this)));
+ if (first_not_nullable != rule->rhs.end ())
+ continue;
+
+ // found an include edge.
+ IncludesGraph::iterator target = IncludesGraph::get (Include (pp, name));
+ IncludesGraph::iterator source = IncludesGraph::get (Include (p, *A));
+
+ source->insertEdge (target);
+
+#ifndef QLALR_NO_DEBUG_INCLUDES
+ qerr << "*** (" << id (p) << ", " << *A << ") includes (" << id (pp) << ", " << *name << ")" << endl;
+#endif // QLALR_NO_DEBUG_INCLUDES
+ }
+ }
+ }
+ }
+}
+
+void Automaton::visitIncludeNode (IncludeNode node)
+{
+ if (node->dfn != 0)
+ return; // nothing to do
+
+ int N = node->dfn = ++_M_includes_dfn;
+ _M_includes_stack.push (node);
+
+#ifndef QLALR_NO_DEBUG_INCLUDES
+ // qerr << "*** Debug. visit node (" << id (node->data.state) << ", " << node->data.nt << ") N = " << N << endl;
+#endif
+
+ for (IncludesGraph::edge_iterator edge = node->begin (); edge != node->end (); ++edge)
+ {
+ IncludesGraph::iterator r = *edge;
+
+ visitIncludeNode (r);
+
+ node->dfn = qMin (N, r->dfn);
+
+#ifndef QLALR_NO_DEBUG_INCLUDES
+ qerr << "*** Merge. follows";
+ dump (qerr, node);
+ qerr << " += follows";
+ dump (qerr, r);
+ qerr << endl;
+#endif
+
+ NameSet &dst = node->data.state->follows [node->data.nt];
+ NameSet &src = r->data.state->follows [r->data.nt];
+
+ dst.insert (src.begin (), src.end ());
+ }
+
+ if (node->dfn == N)
+ {
+ IncludesGraph::iterator tos = _M_includes_stack.top ();
+
+ do {
+ tos = _M_includes_stack.top ();
+ _M_includes_stack.pop ();
+ tos->dfn = INT_MAX;
+ } while (tos != node);
+ }
+}
+
+void Automaton::buildLookaheads ()
+{
+ for (StatePointer p = states.begin (); p != states.end (); ++p)
+ {
+ for (ItemPointer item = p->closure.begin (); item != p->closure.end (); ++item)
+ {
+ foreach (Lookback lookback, lookbacks.values (item))
+ {
+ StatePointer q = lookback.state;
+
+#ifndef QLALR_NO_DEBUG_LOOKAHEADS
+ qerr << "(" << id (p) << ", " << *item->rule << ") lookbacks ";
+ dump (qerr, lookback);
+ qerr << " with follows (" << id (q) << ", " << lookback.nt << ") = " << q->follows [lookback.nt] << endl;
+#endif
+
+ lookaheads [item].insert (q->follows [lookback.nt].begin (), q->follows [lookback.nt].end ());
+ }
+ }
+
+ // propagate the lookahead in the kernel
+ ItemPointer k = p->kernel.begin ();
+ ItemPointer c = p->closure.begin ();
+
+ for (; k != p->kernel.end (); ++k, ++c)
+ lookaheads [k] = lookaheads [c];
+ }
+}
+
+void Automaton::buildDefaultReduceActions ()
+{
+ for (StatePointer state = states.begin (); state != states.end (); ++state)
+ {
+ ItemPointer def = state->closure.end ();
+ int size = -1;
+
+ for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item)
+ {
+ if (item->dot != item->end_rhs ())
+ continue;
+
+ int la = lookaheads.value (item).size ();
+ if (def == state->closure.end () || la > size)
+ {
+ def = item;
+ size = la;
+ }
+ }
+
+ if (def != state->closure.end ())
+ {
+ Q_ASSERT (size >= 0);
+ state->defaultReduce = def->rule;
+ }
+ }
+}
+
+void Automaton::dump (QTextStream &out, IncludeNode incl)
+{
+ out << "(" << id (incl->data.state) << ", " << incl->data.nt << ")";
+}
+
+void Automaton::dump (QTextStream &out, ReadNode rd)
+{
+ out << "(" << id (rd->data.state) << ", " << rd->data.nt << ")";
+}
+
+void Automaton::dump (QTextStream &out, const Lookback &lp)
+{
+ out << "(" << id (lp.state) << ", " << lp.nt << ")";
+}
diff --git a/src/tools/qlalr/lalr.g b/src/tools/qlalr/lalr.g
new file mode 100644
index 0000000000..e060eea6f1
--- /dev/null
+++ b/src/tools/qlalr/lalr.g
@@ -0,0 +1,802 @@
+-----------------------------------------------------------------------------
+--
+-- Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+-- Contact: http://www.qt-project.org/legal
+--
+-- This file is part of the QLALR project on Qt Labs.
+--
+-- $QT_BEGIN_LICENSE:LGPL$
+-- Commercial License Usage
+-- Licensees holding valid commercial Qt licenses may use this file in
+-- accordance with the commercial license agreement provided with the
+-- Software or, alternatively, in accordance with the terms contained in
+-- a written agreement between you and Digia. For licensing terms and
+-- conditions see http://qt.digia.com/licensing. For further information
+-- use the contact form at http://qt.digia.com/contact-us.
+--
+-- GNU Lesser General Public License Usage
+-- Alternatively, 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, Digia gives you certain additional
+-- rights. These rights are described in the Digia 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.
+--
+--
+-- $QT_END_LICENSE$
+--
+-----------------------------------------------------------------------------
+
+
+%parser grammar
+
+%decl recognizer.h
+%impl recognizer.cpp
+
+%token ID "identifier"
+%token STRING_LITERAL "string literal"
+
+%token DECL_FILE "%decl"
+%token EXPECT "%expect"
+%token EXPECT_RR "%expect-lr"
+%token IMPL_FILE "%impl"
+%token LEFT "%left"
+%token MERGED_OUTPUT "%merged_output"
+%token NONASSOC "%nonassoc"
+%token PARSER "%parser"
+%token PREC "%prec"
+%token RIGHT "%right"
+%token START "%start"
+%token TOKEN "%token"
+%token TOKEN_PREFIX "%token_prefix"
+
+%token COLON ":"
+%token OR "|"
+%token SEMICOLON ";"
+
+%token DECL
+%token IMPL
+
+%token ERROR
+
+%start Specification
+
+
+/:
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR project on Qt Labs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "$header"
+
+#include "lalr.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qtextstream.h>
+
+#include <cstdlib>
+
+class Recognizer: protected $table
+{
+public:
+ Recognizer (Grammar *grammar, bool no_lines);
+ ~Recognizer();
+
+ bool parse (const QString &input_file = QString ());
+
+ inline QString decls () const { return _M_decls; }
+ inline QString impls () const { return _M_impls; }
+
+protected:
+ inline void reallocateStack ();
+
+ inline QString &sym (int index)
+ { return sym_stack [tos + index - 1]; }
+
+protected: // scanner
+ int nextToken();
+
+ inline void inp ()
+ {
+ if (_M_currentChar != _M_lastChar)
+ {
+ ch = *_M_currentChar++;
+
+ if (ch == QLatin1Char('\n'))
+ ++_M_line;
+ }
+ else
+ ch = QChar();
+ }
+
+ QString expand (const QString &text) const;
+
+protected:
+ // recognizer
+ int tos;
+ int stack_size;
+ QVector<QString> sym_stack;
+ int *state_stack;
+
+ QString _M_contents;
+ QString::const_iterator _M_firstChar;
+ QString::const_iterator _M_lastChar;
+ QString::const_iterator _M_currentChar;
+
+ // scanner
+ QChar ch;
+ int _M_line;
+ int _M_action_line;
+ Grammar *_M_grammar;
+ RulePointer _M_current_rule;
+ QString _M_input_file;
+
+ QString _M_decls;
+ QString _M_impls;
+ QString _M_current_value;
+ bool _M_no_lines;
+};
+:/
+
+/.
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR project on Qt Labs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "recognizer.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <cctype>
+
+Recognizer::Recognizer (Grammar *grammar, bool no_lines):
+ tos(0),
+ stack_size(0),
+ state_stack(0),
+ _M_line(1),
+ _M_action_line(0),
+ _M_grammar(grammar),
+ _M_no_lines(no_lines)
+{
+}
+
+Recognizer::~Recognizer()
+{
+ if (stack_size)
+ ::free(state_stack);
+}
+
+inline void Recognizer::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack.resize (stack_size);
+
+ if (! state_stack)
+ state_stack = reinterpret_cast<int*> (::malloc(stack_size * sizeof(int)));
+ else
+ state_stack = reinterpret_cast<int*> (::realloc(state_stack, stack_size * sizeof(int)));
+}
+
+int Recognizer::nextToken()
+{
+ QString text;
+
+ Lagain:
+ while (ch.isSpace ())
+ inp ();
+
+ if (ch.isNull ())
+ return EOF_SYMBOL;
+
+ int token = ch.unicode ();
+
+ if (token == '"')
+ {
+ inp(); // skip "
+ text.clear ();
+ while (! ch.isNull () && ch != QLatin1Char ('"'))
+ {
+ if (ch == QLatin1Char ('\\'))
+ {
+ text += ch;
+ inp();
+ }
+ text += ch;
+ inp ();
+ }
+
+ if (ch == QLatin1Char ('"'))
+ inp ();
+ else
+ qerr << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << endl;
+
+ _M_current_value = text;
+ return (token = STRING_LITERAL);
+ }
+
+ else if (ch.isLetterOrNumber () || ch == QLatin1Char ('_'))
+ {
+ text.clear ();
+ do { text += ch; inp (); }
+ while (ch.isLetterOrNumber () || ch == QLatin1Char ('_') || ch == QLatin1Char ('.'));
+ _M_current_value = text;
+ return (token = ID);
+ }
+
+ else if (token == '%')
+ {
+ text.clear ();
+
+ do { inp (); }
+ while (ch.isSpace ());
+
+ do { text += ch; inp (); }
+ while (ch.isLetterOrNumber () || ch == QLatin1Char ('_') || ch == QLatin1Char ('-'));
+
+ if (text == QLatin1String("token_prefix"))
+ return (token = TOKEN_PREFIX);
+ else if (text == QLatin1String("merged_output"))
+ return (token = MERGED_OUTPUT);
+ else if (text == QLatin1String("token"))
+ return (token = TOKEN);
+ else if (text == QLatin1String("start"))
+ return (token = START);
+ else if (text == QLatin1String("parser"))
+ return (token = PARSER);
+ else if (text == QLatin1String("decl"))
+ return (token = DECL_FILE);
+ else if (text == QLatin1String("impl"))
+ return (token = IMPL_FILE);
+ else if (text == QLatin1String("expect"))
+ return (token = EXPECT);
+ else if (text == QLatin1String("expect-rr"))
+ return (token = EXPECT_RR);
+ else if (text == QLatin1String("left"))
+ return (token = LEFT);
+ else if (text == QLatin1String("right"))
+ return (token = RIGHT);
+ else if (text == QLatin1String("nonassoc"))
+ return (token = NONASSOC);
+ else if (text == QLatin1String("prec"))
+ return (token = PREC);
+ else
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << endl;
+ exit (EXIT_FAILURE);
+ return (token = ERROR);
+ }
+ }
+
+ inp ();
+
+ if (token == '-' && ch == QLatin1Char ('-'))
+ {
+ do { inp (); }
+ while (! ch.isNull () && ch != QLatin1Char ('\n'));
+ goto Lagain;
+ }
+
+ else if (token == ':' && ch == QLatin1Char (':'))
+ {
+ inp ();
+ if (ch != QLatin1Char ('='))
+ return (token = ERROR);
+ inp ();
+ return (token = COLON);
+ }
+
+ else if (token == '/' && ch == QLatin1Char (':'))
+ {
+ _M_action_line = _M_line;
+
+ text.clear ();
+ if (! _M_no_lines)
+ text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+ inp (); // skip ':'
+
+ forever
+ {
+ while (! ch.isNull ())
+ {
+ token = ch.unicode ();
+ inp ();
+
+ if (token == ':' && ch == QLatin1Char ('/'))
+ break;
+
+ text += QLatin1Char (token);
+ }
+
+ if (ch != QLatin1Char ('/'))
+ return (token = ERROR);
+
+ inp ();
+
+ if (ch.isNull () || ch.isSpace ())
+ {
+ _M_current_value = text;
+ return (token = DECL);
+ }
+ else
+ text += QLatin1String (":/");
+ }
+ }
+
+ else if (token == '/' && ch == QLatin1Char ('.'))
+ {
+ _M_action_line = _M_line;
+
+ text.clear ();
+ if (! _M_no_lines)
+ text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+
+ inp (); // skip ':'
+
+ forever
+ {
+ while (! ch.isNull ())
+ {
+ token = ch.unicode ();
+ inp ();
+
+ if (token == '.' && ch == QLatin1Char ('/'))
+ break;
+
+ text += QLatin1Char (token);
+ }
+
+ if (ch != QLatin1Char ('/'))
+ return (token = ERROR);
+
+ inp ();
+
+ if (ch.isNull () || ch.isSpace ())
+ {
+ _M_current_value = text;
+ return (token = IMPL);
+ }
+ else
+ text += QLatin1String ("./");
+ }
+ }
+
+ switch (token) {
+ case ':':
+ return (token = COLON);
+
+ case ';':
+ return (token = SEMICOLON);
+
+ case '|':
+ return (token = OR);
+
+ default:
+ break;
+ }
+
+ return token;
+}
+
+bool Recognizer::parse (const QString &input_file)
+{
+ _M_input_file = input_file;
+
+ QFile file(_M_input_file);
+ if (! file.open(QFile::ReadOnly))
+ {
+ qerr << "qlalr: no input file\n";
+ return false;
+ }
+
+ QString _M_contents = QTextStream(&file).readAll();
+ _M_firstChar = _M_contents.constBegin();
+ _M_lastChar = _M_contents.constEnd();
+ _M_currentChar = _M_firstChar;
+ _M_line = 1;
+
+ int yytoken = -1;
+ inp ();
+
+ reallocateStack();
+
+ _M_current_rule = _M_grammar->rules.end ();
+ _M_decls.clear ();
+ _M_impls.clear ();
+
+ tos = 0;
+ state_stack[++tos] = 0;
+
+ while (true)
+ {
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state_stack [tos]])
+ yytoken = nextToken();
+
+ int act = t_action (state_stack [tos], yytoken);
+
+ if (act == ACCEPT_STATE)
+ return true;
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos] = _M_current_value;
+ state_stack [tos] = act;
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+
+ switch (r) {
+./
+
+----------------------------------------------------------- SPECS
+Specification ::= Options Tokens Start Rules ;
+
+Options ::= Empty ;
+Options ::= Options Option ;
+
+StartHeader ::= START ID ;
+/.
+case $rule_number: {
+ Name name = _M_grammar->intern (sym(2));
+ _M_grammar->start = name;
+ _M_grammar->non_terminals.insert (name);
+} break;
+./
+
+Start ::= StartHeader UserActionOpt ;
+
+----------------------------------------------------------- OPTIONS
+Option ::= PARSER ID ;
+/.
+case $rule_number: {
+ _M_grammar->table_name = sym(2);
+} break;
+./
+
+Option ::= MERGED_OUTPUT ID ;
+/.
+case $rule_number: {
+ _M_grammar->merged_output = sym(2);
+} break;
+./
+
+Option ::= DECL_FILE ID ;
+/.
+case $rule_number: {
+ _M_grammar->decl_file_name = sym(2);
+} break;
+./
+
+
+Option ::= IMPL_FILE ID ;
+/.
+case $rule_number: {
+ _M_grammar->impl_file_name = sym(2);
+} break;
+./
+
+Option ::= EXPECT ID ;
+/.
+case $rule_number: {
+ _M_grammar->expected_shift_reduce = sym(2).toInt();
+} break;
+./
+
+Option ::= EXPECT_RR ID ;
+/.
+case $rule_number: {
+ _M_grammar->expected_reduce_reduce = sym(2).toInt();
+} break;
+./
+
+
+Option ::= TOKEN_PREFIX ID ;
+/.
+case $rule_number: {
+ _M_grammar->token_prefix = sym(2);
+} break;
+./
+
+
+----------------------------------------------------------- TOKENS
+Tokens ::= Empty ;
+Tokens ::= Tokens Token ;
+
+Token ::= TOKEN TerminalList ;
+
+TerminalList ::= Terminal ;
+
+TerminalList ::= TerminalList Terminal ;
+
+Terminal ::= ID Empty ;
+/.case $rule_number:./
+
+Terminal ::= ID STRING_LITERAL ;
+/.case $rule_number: {
+ Name name = _M_grammar->intern (sym(1));
+ _M_grammar->terminals.insert (name);
+ _M_grammar->spells.insert (name, sym(2));
+} break;
+./
+
+PrecHeader: LEFT ;
+/.
+case $rule_number: {
+ _M_grammar->current_assoc = Grammar::Left;
+ ++_M_grammar->current_prec;
+} break;
+./
+
+PrecHeader: RIGHT ;
+/.
+case $rule_number: {
+ _M_grammar->current_assoc = Grammar::Right;
+ ++_M_grammar->current_prec;
+} break;
+./
+
+PrecHeader: NONASSOC ;
+/.
+case $rule_number: {
+ _M_grammar->current_assoc = Grammar::NonAssoc;
+ ++_M_grammar->current_prec;
+} break;
+./
+
+Token ::= PrecHeader TokenList ;
+
+TokenList ::= TokenId ;
+TokenList ::= TokenList TokenId ;
+
+TokenId ::= ID ;
+/.
+case $rule_number: {
+ Name name = _M_grammar->intern (sym(1));
+ _M_grammar->terminals.insert (name);
+
+ Grammar::TokenInfo info;
+ info.prec = _M_grammar->current_prec;
+ info.assoc = _M_grammar->current_assoc;
+ _M_grammar->token_info.insert (name, info);
+} break;
+./
+
+----------------------------------------------------------- Code
+Code ::= DECL ;
+/.
+case $rule_number: {
+ _M_decls += expand (sym(1));
+} break;
+./
+
+
+Code ::= IMPL ;
+/.
+case $rule_number: {
+ _M_impls += expand (sym(1));
+} break;
+./
+
+UserAction ::= Code ;
+UserAction ::= UserAction Code ;
+
+UserActionOpt ::= ;
+UserActionOpt ::= UserAction ;
+
+----------------------------------------------------------- RULES
+Rules ::= Empty ;
+Rules ::= Rules Rule ;
+
+RuleHeader ::= ID COLON ;
+/.
+case $rule_number: {
+ _M_current_rule = _M_grammar->rules.insert (_M_grammar->rules.end (), Rule ());
+ _M_current_rule->lhs = _M_grammar->intern (sym(1));
+ _M_grammar->declared_lhs.insert (_M_current_rule->lhs);
+
+ if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ return false;
+ }
+
+ _M_grammar->non_terminals.insert (_M_current_rule->lhs);
+} break;
+./
+
+
+Rule ::= RuleHeader RuleDefinition SEMICOLON UserActionOpt ;
+
+RuleDefinition ::= Symbols PrecOpt UserActionOpt ;
+RuleDefinition ::= RuleDefinition NewRule OR Symbols PrecOpt UserActionOpt ;
+
+NewRule ::= ;
+/.
+case $rule_number: {
+ Name lhs = _M_current_rule->lhs;
+ _M_current_rule = _M_grammar->rules.insert (_M_grammar->rules.end (), Rule ());
+ _M_current_rule->lhs = lhs;
+ _M_grammar->declared_lhs.insert (_M_current_rule->lhs);
+
+ if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ return false;
+ }
+
+ _M_grammar->non_terminals.insert (_M_current_rule->lhs);
+} break;
+./
+
+PrecOpt ::= ;
+/.
+case $rule_number: {
+ _M_current_rule->prec = _M_grammar->names.end ();
+
+ for (NameList::iterator it = _M_current_rule->rhs.begin (); it != _M_current_rule->rhs.end (); ++it)
+ {
+ if (! _M_grammar->isTerminal (*it))
+ continue;
+
+ _M_current_rule->prec = *it;
+ }
+} break;
+./
+
+PrecOpt ::= PREC ID ;
+/.
+case $rule_number: {
+ Name tok = _M_grammar->intern (sym(2));
+ if (! _M_grammar->isTerminal (tok))
+ {
+ qerr << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << endl;
+ _M_current_rule->prec = _M_grammar->names.end ();
+ }
+ else
+ _M_current_rule->prec = tok;
+} break;
+./
+
+----------------------------------------------------------- SYMBOLS
+Symbols ::= Empty ;
+Symbols ::= Symbols ID ;
+/.
+case $rule_number: {
+ Name name = _M_grammar->intern (sym(2));
+
+ if (_M_grammar->terminals.find (name) == _M_grammar->terminals.end ())
+ _M_grammar->non_terminals.insert (name);
+
+ _M_current_rule->rhs.push_back (name);
+} break;
+./
+
+----------------------------------------------------------- HELPERS
+Empty ::= ;
+/.
+case $rule_number: {
+ sym(1) = QString();
+} break;
+./
+
+
+
+
+----------------------------------------------------------- END
+/.
+ } // switch
+
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+ }
+
+ else
+ {
+ break;
+ }
+ }
+
+ qerr << _M_input_file << ":" << _M_line << ": Syntax error" << endl;
+ return false;
+}
+
+./
diff --git a/src/tools/qlalr/lalr.h b/src/tools/qlalr/lalr.h
new file mode 100644
index 0000000000..85c5b51e38
--- /dev/null
+++ b/src/tools/qlalr/lalr.h
@@ -0,0 +1,503 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LALR_H
+#define LALR_H
+
+#include <QtCore/qset.h>
+#include <QtCore/qstack.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qlinkedlist.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtextstream.h>
+#include <QtCore/qpair.h>
+
+#include <algorithm>
+#include <functional>
+
+class Rule;
+class State;
+class Grammar;
+class Item;
+class State;
+class Arrow;
+class Automaton;
+
+template <typename _Tp >
+class OrderedSet : protected QMap<_Tp, bool>
+{
+ typedef QMap<_Tp, bool> _Base;
+
+public:
+ class const_iterator
+ {
+ typename _Base::const_iterator _M_iterator;
+
+ public:
+ const_iterator () {}
+
+ const_iterator (const typename _Base::const_iterator &it):
+ _M_iterator (it) {}
+
+ const _Tp &operator * () const
+ { return _M_iterator.key (); }
+
+ const _Tp *operator -> () const
+ { return &_M_iterator.key (); }
+
+ const_iterator &operator ++ ()
+ { ++_M_iterator; return *this; }
+
+ const_iterator operator ++ (int) const
+ {
+ const_iterator me (*this);
+ ++_M_iterator;
+ return me;
+ }
+
+ bool operator == (const const_iterator &other) const
+ { return _M_iterator == other._M_iterator; }
+
+ bool operator != (const const_iterator &other) const
+ { return _M_iterator != other._M_iterator; }
+ };
+
+ typedef const_iterator iterator;
+
+public:
+ OrderedSet () {}
+
+ const_iterator begin () const
+ { return const_iterator (_Base::begin ()); }
+
+ const_iterator end () const
+ { return const_iterator (_Base::end ()); }
+
+ bool isEmpty () const
+ { return _Base::isEmpty (); }
+
+ int size () const
+ { return _Base::size (); }
+
+ const_iterator find (const _Tp &elt) const
+ { return const_iterator (_Base::find (elt)); }
+
+ QPair<const_iterator, bool> insert (const _Tp &elt)
+ {
+ int elts = _Base::size ();
+ const_iterator it (_Base::insert (typename _Base::key_type (elt), true));
+ return qMakePair (it, elts != _Base::size ());
+ }
+
+ QPair<const_iterator, bool> insert (const_iterator, const _Tp &elt)
+ {
+ int elts = _Base::size ();
+ const_iterator it (_Base::insert (typename _Base::key_type (elt), true));
+ return qMakePair (it, elts != _Base::size ());
+ }
+
+ const _Tp &operator [] (const _Tp &elt)
+ { return *insert (elt)->first; }
+
+ template <typename _InputIterator>
+ void insert (_InputIterator first, _InputIterator last)
+ {
+ for (; first != last; ++first)
+ insert (*first);
+ }
+};
+
+// names
+typedef QLinkedList<QString>::iterator Name;
+typedef QLinkedList<Name> NameList;
+typedef OrderedSet<Name> NameSet;
+
+// items
+typedef QLinkedList<Item> ItemList;
+typedef ItemList::iterator ItemPointer;
+
+// rules
+typedef QLinkedList<Rule> debug_infot;
+typedef debug_infot::iterator RulePointer;
+typedef QMultiMap<Name, RulePointer> RuleMap;
+
+// states
+typedef QLinkedList<State> StateList;
+typedef StateList::iterator StatePointer;
+
+// arrows
+typedef QMap<Name, StatePointer> Bundle;
+
+class Rule
+{
+public:
+ void clear ()
+ {
+ lhs = Name ();
+ rhs.clear ();
+ prec = Name ();
+ }
+
+public:
+ Name lhs;
+ NameList rhs;
+ Name prec;
+};
+
+class Lookback
+{
+public:
+ Lookback (StatePointer s, Name n):
+ state (s), nt (n) {}
+
+ inline bool operator == (const Lookback &other) const
+ { return state == other.state && nt == other.nt; }
+
+ inline bool operator != (const Lookback &other) const
+ { return state != other.state || nt != other.nt; }
+
+ bool operator < (const Lookback &other) const;
+
+public:
+ StatePointer state;
+ Name nt;
+};
+
+class Item
+{
+public:
+ inline NameList::iterator begin_rhs () const
+ { return rule->rhs.begin (); }
+
+ inline NameList::iterator end_rhs () const
+ { return rule->rhs.end (); }
+
+ inline bool operator == (const Item &other) const
+ { return rule == other.rule && dot == other.dot; }
+
+ inline bool operator != (const Item &other) const
+ { return rule != other.rule || dot != other.dot; }
+
+ inline bool isReduceItem () const
+ { return dot == rule->rhs.end (); }
+
+ Item next () const;
+
+public:
+ RulePointer rule;
+ NameList::iterator dot;
+};
+
+class State
+{
+public:
+ State (Grammar *grammar);
+
+ inline bool operator == (const State &other) const
+ { return kernel == other.kernel; }
+
+ inline bool operator != (const State &other) const
+ { return kernel != other.kernel; }
+
+ QPair<ItemPointer, bool> insert (const Item &item);
+ QPair<ItemPointer, bool> insertClosure (const Item &item);
+
+public: // attributes
+ ItemList kernel;
+ ItemList closure;
+ Bundle bundle;
+ QMap<Name, NameSet> reads;
+ QMap<Name, NameSet> follows;
+ RulePointer defaultReduce;
+};
+
+/////////////////////////////////////////////////////////////
+// digraph
+/////////////////////////////////////////////////////////////
+template <typename _Tp>
+class Node
+{
+public:
+ typedef OrderedSet<Node<_Tp> > Repository;
+ typedef typename Repository::iterator iterator;
+ typedef typename QLinkedList<iterator>::iterator edge_iterator;
+
+public:
+ static iterator get (_Tp data);
+
+ QPair<edge_iterator, bool> insertEdge (iterator other) const;
+
+ inline edge_iterator begin () const
+ { return outs.begin (); }
+
+ inline edge_iterator end () const
+ { return outs.end (); }
+
+ inline bool operator == (const Node<_Tp> &other) const
+ { return data == other.data; }
+
+ inline bool operator != (const Node<_Tp> &other) const
+ { return data != other.data; }
+
+ inline bool operator < (const Node<_Tp> &other) const
+ { return data < other.data; }
+
+ static inline iterator begin_nodes ()
+ { return repository ().begin (); }
+
+ static inline iterator end_nodes ()
+ { return repository ().end (); }
+
+ static Repository &repository ()
+ {
+ static Repository r;
+ return r;
+ }
+
+public: // attributes
+ mutable bool root;
+ mutable int dfn;
+ mutable _Tp data;
+ mutable QLinkedList<iterator> outs;
+
+protected:
+ inline Node () {}
+
+ inline Node (_Tp d):
+ root (true), dfn (0), data (d) {}
+};
+
+template <typename _Tp>
+typename Node<_Tp>::iterator Node<_Tp>::get (_Tp data)
+{
+ Node<_Tp> tmp (data);
+ iterator it = repository ().find (tmp);
+
+ if (it != repository ().end ())
+ return it;
+
+ return repository ().insert (tmp).first;
+}
+
+template <typename _Tp>
+QPair<typename QLinkedList<typename Node<_Tp>::iterator>::iterator, bool> Node<_Tp>::insertEdge (typename Node<_Tp>::iterator other) const
+{
+ edge_iterator it = std::find (outs.begin (), outs.end (), other);
+
+ if (it != outs.end ())
+ return qMakePair (it, false);
+
+ other->root = false;
+ return qMakePair (outs.insert (outs.end (), other), true);
+}
+
+/////////////////////////////////////////////////////////////
+// Grammar
+/////////////////////////////////////////////////////////////
+class Grammar
+{
+public:
+ Grammar ();
+
+ Name intern (const QString &id);
+
+ inline bool isTerminal (Name name) const
+ { return terminals.find (name) != terminals.end (); }
+
+ inline bool isNonTerminal (Name name) const
+ { return non_terminals.find (name) != non_terminals.end (); }
+
+ void buildRuleMap ();
+ void buildExtendedGrammar ();
+
+public:
+ QString merged_output;
+ QString table_name;
+ QString decl_file_name;
+ QString impl_file_name;
+ QString token_prefix;
+ QLinkedList<QString> names;
+ Name start;
+ NameSet terminals;
+ NameSet non_terminals;
+ QMap<Name, QString> spells;
+ debug_infot rules;
+ RuleMap rule_map;
+ RulePointer goal;
+ Name tk_end;
+ Name accept_symbol;
+ NameSet declared_lhs;
+ int expected_shift_reduce;
+ int expected_reduce_reduce;
+
+ enum Assoc {
+ NonAssoc,
+ Left,
+ Right
+ };
+
+ struct TokenInfo {
+ Assoc assoc;
+ int prec;
+ };
+
+ QMap<Name, TokenInfo> token_info;
+ Assoc current_assoc;
+ int current_prec;
+};
+
+class Read
+{
+public:
+ inline Read () {}
+
+ inline Read (StatePointer s, Name n):
+ state (s), nt (n) {}
+
+ inline bool operator == (const Read &other) const
+ { return state == other.state && nt == other.nt; }
+
+ inline bool operator != (const Read &other) const
+ { return state != other.state || nt != other.nt; }
+
+ bool operator < (const Read &other) const;
+
+public:
+ StatePointer state;
+ Name nt;
+};
+
+class Include
+{
+public:
+ inline Include () {}
+
+ inline Include (StatePointer s, Name n):
+ state (s), nt (n) {}
+
+ inline bool operator == (const Include &other) const
+ { return state == other.state && nt == other.nt; }
+
+ inline bool operator != (const Include &other) const
+ { return state != other.state || nt != other.nt; }
+
+ bool operator < (const Include &other) const;
+
+public:
+ StatePointer state;
+ Name nt;
+};
+
+class Automaton
+{
+public:
+ Automaton (Grammar *g);
+
+ QPair<StatePointer, bool> internState (const State &state);
+
+ typedef Node<Read> ReadsGraph;
+ typedef ReadsGraph::iterator ReadNode;
+
+ typedef Node<Include> IncludesGraph;
+ typedef IncludesGraph::iterator IncludeNode;
+
+ void build ();
+ void buildNullables ();
+
+ void buildLookbackSets ();
+
+ void buildDirectReads ();
+ void buildReadsDigraph ();
+ void buildReads ();
+ void visitReadNode (ReadNode node);
+
+ void buildIncludesAndFollows ();
+ void buildIncludesDigraph ();
+ void visitIncludeNode (IncludeNode node);
+
+ void buildLookaheads ();
+
+ void buildDefaultReduceActions ();
+
+ void closure (StatePointer state);
+
+ int id (RulePointer rule);
+ int id (StatePointer state);
+ int id (Name name);
+
+ void dump (QTextStream &out, IncludeNode incl);
+ void dump (QTextStream &out, ReadNode rd);
+ void dump (QTextStream &out, const Lookback &lp);
+
+public: // ### private
+ Grammar *_M_grammar;
+ StateList states;
+ StatePointer start;
+ NameSet nullables;
+ QMultiMap<ItemPointer, Lookback> lookbacks;
+ QMap<ItemPointer, NameSet> lookaheads;
+
+private:
+ QStack<ReadsGraph::iterator> _M_reads_stack;
+ int _M_reads_dfn;
+
+ QStack<IncludesGraph::iterator> _M_includes_stack;
+ int _M_includes_dfn;
+};
+
+QT_BEGIN_NAMESPACE
+bool operator < (Name a, Name b);
+bool operator < (StatePointer a, StatePointer b);
+bool operator < (ItemPointer a, ItemPointer b);
+QT_END_NAMESPACE
+
+QTextStream &operator << (QTextStream &out, const Name &n);
+QTextStream &operator << (QTextStream &out, const Rule &r);
+QTextStream &operator << (QTextStream &out, const Item &item);
+QTextStream &operator << (QTextStream &out, const NameSet &ns);
+
+QT_BEGIN_NAMESPACE
+// ... hmm
+extern QTextStream qerr;
+extern QTextStream qout;
+QT_END_NAMESPACE
+
+#endif // LALR_H
diff --git a/src/tools/qlalr/main.cpp b/src/tools/qlalr/main.cpp
new file mode 100644
index 0000000000..1e4f030122
--- /dev/null
+++ b/src/tools/qlalr/main.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lalr.h"
+#include "dotgraph.h"
+#include "parsetable.h"
+#include "cppgenerator.h"
+#include "recognizer.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qdebug.h>
+
+#include <cstdlib>
+
+#define QLALR_NO_DEBUG_TABLE
+#define QLALR_NO_DEBUG_DOT
+
+static void help_me ()
+{
+ qerr << "Usage: qlalr [options] [input file name]" << endl
+ << endl
+ << " --help, -h\t\tdisplay this help and exit" << endl
+ << " --verbose, -v\t\tverbose output" << endl
+ << " --no-debug\t\tno debug information" << endl
+ << " --no-lines\t\tno #line directives" << endl
+ << " --dot\t\t\tgenerate a graph" << endl
+ << " --qt\t\tadd the Qt copyright header and Qt-specific types and macros" << endl
+ << endl;
+ exit (0);
+}
+
+int main (int argc, char *argv[])
+{
+ QCoreApplication app (argc, argv);
+
+ bool generate_dot = false;
+ bool generate_report = false;
+ bool no_lines = false;
+ bool debug_info = true;
+ bool qt_copyright = false;
+ QString file_name = 0;
+
+ QStringList args = app.arguments ();
+ args.removeFirst ();
+
+ foreach (QString arg, args)
+ {
+ if (arg == QLatin1String ("-h") || arg == QLatin1String ("--help"))
+ help_me ();
+
+ else if (arg == QLatin1String ("-v") || arg == QLatin1String ("--verbose"))
+ generate_report = true;
+
+ else if (arg == QLatin1String ("--dot"))
+ generate_dot = true;
+
+ else if (arg == QLatin1String ("--no-lines"))
+ no_lines = true;
+
+ else if (arg == QLatin1String ("--no-debug"))
+ debug_info = false;
+
+ else if (arg == QLatin1String ("--qt"))
+ qt_copyright = true;
+
+ else if (file_name.isEmpty ())
+ file_name = arg;
+
+ else
+ qerr << "*** Warning. Ignore argument `" << arg << "'" << endl;
+ }
+
+ if (file_name.isEmpty ())
+ {
+ help_me ();
+ exit (EXIT_SUCCESS);
+ }
+
+ Grammar grammar;
+ Recognizer p (&grammar, no_lines);
+
+ if (! p.parse (file_name))
+ exit (EXIT_FAILURE);
+
+ if (grammar.rules.isEmpty ())
+ {
+ qerr << "*** Fatal. No rules!" << endl;
+ exit (EXIT_FAILURE);
+ }
+
+ else if (grammar.start == grammar.names.end ())
+ {
+ qerr << "*** Fatal. No start symbol!" << endl;
+ exit (EXIT_FAILURE);
+ }
+
+ grammar.buildExtendedGrammar ();
+ grammar.buildRuleMap ();
+
+ Automaton aut (&grammar);
+ aut.build ();
+
+ CppGenerator gen (p, grammar, aut, generate_report);
+ gen.setDebugInfo (debug_info);
+ gen.setCopyright (qt_copyright);
+ gen ();
+
+ if (generate_dot)
+ {
+ DotGraph genDotFile (qout);
+ genDotFile (&aut);
+ }
+
+ else if (generate_report)
+ {
+ ParseTable genParseTable (qout);
+ genParseTable(&aut);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+QString Recognizer::expand (const QString &text) const
+{
+ QString code = text;
+
+ if (_M_grammar->start != _M_grammar->names.end ())
+ {
+ code = code.replace (QLatin1String("$start_id"), QString::number (std::distance (_M_grammar->names.begin (), _M_grammar->start)));
+ code = code.replace (QLatin1String("$start"), *_M_grammar->start);
+ }
+
+ code = code.replace (QLatin1String("$header"), _M_grammar->table_name.toLower () + QLatin1String("_p.h"));
+
+ code = code.replace (QLatin1String("$table"), _M_grammar->table_name);
+ code = code.replace (QLatin1String("$parser"), _M_grammar->table_name);
+
+ if (_M_current_rule != _M_grammar->rules.end ())
+ {
+ code = code.replace (QLatin1String("$rule_number"), QString::number (std::distance (_M_grammar->rules.begin (), _M_current_rule)));
+ code = code.replace (QLatin1String("$rule"), *_M_current_rule->lhs);
+ }
+
+ return code;
+}
diff --git a/src/tools/qlalr/parsetable.cpp b/src/tools/qlalr/parsetable.cpp
new file mode 100644
index 0000000000..6877af7a00
--- /dev/null
+++ b/src/tools/qlalr/parsetable.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "parsetable.h"
+
+#include "lalr.h"
+
+#include <QtCore/qtextstream.h>
+
+ParseTable::ParseTable (QTextStream &o):
+ out (o)
+{
+}
+
+void ParseTable::operator () (Automaton *aut)
+{
+ Grammar *g = aut->_M_grammar;
+
+ int rindex = 1;
+ for (RulePointer rule = g->rules.begin (); rule != g->rules.end (); ++rule)
+ out << rindex++ << ")\t" << *rule << endl;
+ out << endl << endl;
+
+ int index = 0;
+ for (StatePointer state = aut->states.begin (); state != aut->states.end (); ++state)
+ {
+ out << "state " << index++ << endl << endl;
+
+ for (ItemPointer item = state->kernel.begin (); item != state->kernel.end (); ++item)
+ {
+ out << " * " << *item;
+
+ if (item->dot == item->end_rhs ())
+ out << " " << aut->lookaheads [item];
+
+ out << endl;
+ }
+
+ bool first = true;
+ for (Bundle::iterator arrow = state->bundle.begin (); arrow != state->bundle.end (); ++arrow)
+ {
+ if (! g->isTerminal (arrow.key ()))
+ continue;
+
+ if (first)
+ out << endl;
+
+ first = false;
+
+ out << " " << *arrow.key () << " shift, and go to state " << std::distance (aut->states.begin (), *arrow) << endl;
+ }
+
+ first = true;
+ for (ItemPointer item = state->closure.begin (); item != state->closure.end (); ++item)
+ {
+ if (item->dot != item->end_rhs () || item->rule == state->defaultReduce)
+ continue;
+
+ if (first)
+ out << endl;
+
+ first = false;
+
+ foreach (Name la, aut->lookaheads.value (item))
+ out << " " << *la << " reduce using rule " << aut->id (item->rule) << " (" << *item->rule->lhs << ")" << endl;
+ }
+
+ first = true;
+ for (Bundle::iterator arrow = state->bundle.begin (); arrow != state->bundle.end (); ++arrow)
+ {
+ if (! g->isNonTerminal (arrow.key ()))
+ continue;
+
+ if (first)
+ out << endl;
+
+ first = false;
+
+ out << " " << *arrow.key () << " go to state " << std::distance (aut->states.begin (), *arrow) << endl;
+ }
+
+ if (state->defaultReduce != g->rules.end ())
+ {
+ out << endl
+ << " $default reduce using rule " << aut->id (state->defaultReduce) << " (" << *state->defaultReduce->lhs << ")" << endl;
+ }
+
+ out << endl;
+ }
+}
diff --git a/src/tools/qlalr/parsetable.h b/src/tools/qlalr/parsetable.h
new file mode 100644
index 0000000000..d0fe78be81
--- /dev/null
+++ b/src/tools/qlalr/parsetable.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the utils of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PARSETABLE_H
+#define PARSETABLE_H
+
+#include <QtCore/qglobal.h>
+
+QT_FORWARD_DECLARE_CLASS(QTextStream);
+class Automaton;
+
+class ParseTable
+{
+public:
+ ParseTable (QTextStream &out);
+
+ void operator () (Automaton *a);
+
+private:
+ QTextStream &out;
+};
+
+#endif // PARSETABLE_H
diff --git a/src/tools/qlalr/qlalr.pro b/src/tools/qlalr/qlalr.pro
new file mode 100644
index 0000000000..08cf6a1591
--- /dev/null
+++ b/src/tools/qlalr/qlalr.pro
@@ -0,0 +1,25 @@
+option(host_build)
+
+SOURCES += \
+ compress.cpp \
+ cppgenerator.cpp \
+ dotgraph.cpp \
+ lalr.cpp \
+ main.cpp \
+ parsetable.cpp \
+ recognizer.cpp \
+ grammar.cpp
+
+HEADERS += \
+ compress.h \
+ cppgenerator.h \
+ dotgraph.h \
+ lalr.h \
+ parsetable.h \
+ recognizer.h \
+ grammar_p.h
+
+OTHER_FILES += \
+ lalr.g
+
+load(qt_tool)
diff --git a/src/tools/qlalr/recognizer.cpp b/src/tools/qlalr/recognizer.cpp
new file mode 100644
index 0000000000..6808f3f66b
--- /dev/null
+++ b/src/tools/qlalr/recognizer.cpp
@@ -0,0 +1,490 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR project on Qt Labs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "recognizer.h"
+
+#include <cstdlib>
+#include <cstring>
+#include <cctype>
+
+Recognizer::Recognizer (Grammar *grammar, bool no_lines):
+ tos(0),
+ stack_size(0),
+ state_stack(0),
+ _M_line(1),
+ _M_action_line(0),
+ _M_grammar(grammar),
+ _M_no_lines(no_lines)
+{
+}
+
+Recognizer::~Recognizer()
+{
+ if (stack_size)
+ ::free(state_stack);
+}
+
+inline void Recognizer::reallocateStack()
+{
+ if (! stack_size)
+ stack_size = 128;
+ else
+ stack_size <<= 1;
+
+ sym_stack.resize (stack_size);
+
+ if (! state_stack)
+ state_stack = reinterpret_cast<int*> (::malloc(stack_size * sizeof(int)));
+ else
+ state_stack = reinterpret_cast<int*> (::realloc(state_stack, stack_size * sizeof(int)));
+}
+
+int Recognizer::nextToken()
+{
+ QString text;
+
+ Lagain:
+ while (ch.isSpace ())
+ inp ();
+
+ if (ch.isNull ())
+ return EOF_SYMBOL;
+
+ int token = ch.unicode ();
+
+ if (token == '"')
+ {
+ inp(); // skip "
+ text.clear ();
+ while (! ch.isNull () && ch != QLatin1Char ('"'))
+ {
+ if (ch == QLatin1Char ('\\'))
+ {
+ text += ch;
+ inp();
+ }
+ text += ch;
+ inp ();
+ }
+
+ if (ch == QLatin1Char ('"'))
+ inp ();
+ else
+ qerr << _M_input_file << ":" << _M_line << ": Warning. Expected `\"'" << endl;
+
+ _M_current_value = text;
+ return (token = STRING_LITERAL);
+ }
+
+ else if (ch.isLetterOrNumber () || ch == QLatin1Char ('_'))
+ {
+ text.clear ();
+ do { text += ch; inp (); }
+ while (ch.isLetterOrNumber () || ch == QLatin1Char ('_') || ch == QLatin1Char ('.'));
+ _M_current_value = text;
+ return (token = ID);
+ }
+
+ else if (token == '%')
+ {
+ text.clear ();
+
+ do { inp (); }
+ while (ch.isSpace ());
+
+ do { text += ch; inp (); }
+ while (ch.isLetterOrNumber () || ch == QLatin1Char ('_') || ch == QLatin1Char ('-'));
+
+ if (text == QLatin1String("token_prefix"))
+ return (token = TOKEN_PREFIX);
+ else if (text == QLatin1String("merged_output"))
+ return (token = MERGED_OUTPUT);
+ else if (text == QLatin1String("token"))
+ return (token = TOKEN);
+ else if (text == QLatin1String("start"))
+ return (token = START);
+ else if (text == QLatin1String("parser"))
+ return (token = PARSER);
+ else if (text == QLatin1String("decl"))
+ return (token = DECL_FILE);
+ else if (text == QLatin1String("impl"))
+ return (token = IMPL_FILE);
+ else if (text == QLatin1String("expect"))
+ return (token = EXPECT);
+ else if (text == QLatin1String("expect-rr"))
+ return (token = EXPECT_RR);
+ else if (text == QLatin1String("left"))
+ return (token = LEFT);
+ else if (text == QLatin1String("right"))
+ return (token = RIGHT);
+ else if (text == QLatin1String("nonassoc"))
+ return (token = NONASSOC);
+ else if (text == QLatin1String("prec"))
+ return (token = PREC);
+ else
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Unknown keyword `" << text << "'" << endl;
+ exit (EXIT_FAILURE);
+ return (token = ERROR);
+ }
+ }
+
+ inp ();
+
+ if (token == '-' && ch == QLatin1Char ('-'))
+ {
+ do { inp (); }
+ while (! ch.isNull () && ch != QLatin1Char ('\n'));
+ goto Lagain;
+ }
+
+ else if (token == ':' && ch == QLatin1Char (':'))
+ {
+ inp ();
+ if (ch != QLatin1Char ('='))
+ return (token = ERROR);
+ inp ();
+ return (token = COLON);
+ }
+
+ else if (token == '/' && ch == QLatin1Char (':'))
+ {
+ _M_action_line = _M_line;
+
+ text.clear ();
+ if (! _M_no_lines)
+ text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+ inp (); // skip ':'
+
+ forever
+ {
+ while (! ch.isNull ())
+ {
+ token = ch.unicode ();
+ inp ();
+
+ if (token == ':' && ch == QLatin1Char ('/'))
+ break;
+
+ text += QLatin1Char (token);
+ }
+
+ if (ch != QLatin1Char ('/'))
+ return (token = ERROR);
+
+ inp ();
+
+ if (ch.isNull () || ch.isSpace ())
+ {
+ _M_current_value = text;
+ return (token = DECL);
+ }
+ else
+ text += QLatin1String (":/");
+ }
+ }
+
+ else if (token == '/' && ch == QLatin1Char ('.'))
+ {
+ _M_action_line = _M_line;
+
+ text.clear ();
+ if (! _M_no_lines)
+ text += QLatin1String ("\n#line ") + QString::number (_M_action_line) + " \"" + _M_input_file + "\"\n";
+
+ inp (); // skip ':'
+
+ forever
+ {
+ while (! ch.isNull ())
+ {
+ token = ch.unicode ();
+ inp ();
+
+ if (token == '.' && ch == QLatin1Char ('/'))
+ break;
+
+ text += QLatin1Char (token);
+ }
+
+ if (ch != QLatin1Char ('/'))
+ return (token = ERROR);
+
+ inp ();
+
+ if (ch.isNull () || ch.isSpace ())
+ {
+ _M_current_value = text;
+ return (token = IMPL);
+ }
+ else
+ text += QLatin1String ("");
+ }
+ }
+
+ switch (token) {
+ case ':':
+ return (token = COLON);
+
+ case ';':
+ return (token = SEMICOLON);
+
+ case '|':
+ return (token = OR);
+
+ default:
+ break;
+ }
+
+ return token;
+}
+
+bool Recognizer::parse (const QString &input_file)
+{
+ _M_input_file = input_file;
+
+ QFile file(_M_input_file);
+ if (! file.open(QFile::ReadOnly))
+ {
+ qerr << "qlalr: no input file\n";
+ return false;
+ }
+
+ QString _M_contents = QTextStream(&file).readAll();
+ _M_firstChar = _M_contents.constBegin();
+ _M_lastChar = _M_contents.constEnd();
+ _M_currentChar = _M_firstChar;
+ _M_line = 1;
+
+ int yytoken = -1;
+ inp ();
+
+ reallocateStack();
+
+ _M_current_rule = _M_grammar->rules.end ();
+ _M_decls.clear ();
+ _M_impls.clear ();
+
+ tos = 0;
+ state_stack[++tos] = 0;
+
+ while (true)
+ {
+ if (yytoken == -1 && - TERMINAL_COUNT != action_index [state_stack [tos]])
+ yytoken = nextToken();
+
+ int act = t_action (state_stack [tos], yytoken);
+
+ if (act == ACCEPT_STATE)
+ return true;
+
+ else if (act > 0)
+ {
+ if (++tos == stack_size)
+ reallocateStack();
+
+ sym_stack [tos] = _M_current_value;
+ state_stack [tos] = act;
+ yytoken = -1;
+ }
+
+ else if (act < 0)
+ {
+ int r = - act - 1;
+
+ tos -= rhs [r];
+ act = state_stack [tos++];
+
+ switch (r) {
+
+case 3: {
+ Name name = _M_grammar->intern (sym(2));
+ _M_grammar->start = name;
+ _M_grammar->non_terminals.insert (name);
+} break;
+
+case 5: {
+ _M_grammar->table_name = sym(2);
+} break;
+
+case 6: {
+ _M_grammar->merged_output = sym(2);
+} break;
+
+case 7: {
+ _M_grammar->decl_file_name = sym(2);
+} break;
+
+case 8: {
+ _M_grammar->impl_file_name = sym(2);
+} break;
+
+case 9: {
+ _M_grammar->expected_shift_reduce = sym(2).toInt();
+} break;
+
+case 10: {
+ _M_grammar->expected_reduce_reduce = sym(2).toInt();
+} break;
+
+case 11: {
+ _M_grammar->token_prefix = sym(2);
+} break;
+case 17:case 18: {
+ Name name = _M_grammar->intern (sym(1));
+ _M_grammar->terminals.insert (name);
+ _M_grammar->spells.insert (name, sym(2));
+} break;
+
+case 19: {
+ _M_grammar->current_assoc = Grammar::Left;
+ ++_M_grammar->current_prec;
+} break;
+
+case 20: {
+ _M_grammar->current_assoc = Grammar::Right;
+ ++_M_grammar->current_prec;
+} break;
+
+case 21: {
+ _M_grammar->current_assoc = Grammar::NonAssoc;
+ ++_M_grammar->current_prec;
+} break;
+
+case 25: {
+ Name name = _M_grammar->intern (sym(1));
+ _M_grammar->terminals.insert (name);
+
+ Grammar::TokenInfo info;
+ info.prec = _M_grammar->current_prec;
+ info.assoc = _M_grammar->current_assoc;
+ _M_grammar->token_info.insert (name, info);
+} break;
+
+case 26: {
+ _M_decls += expand (sym(1));
+} break;
+
+case 27: {
+ _M_impls += expand (sym(1));
+} break;
+
+case 34: {
+ _M_current_rule = _M_grammar->rules.insert (_M_grammar->rules.end (), Rule ());
+ _M_current_rule->lhs = _M_grammar->intern (sym(1));
+ _M_grammar->declared_lhs.insert (_M_current_rule->lhs);
+
+ if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ return false;
+ }
+
+ _M_grammar->non_terminals.insert (_M_current_rule->lhs);
+} break;
+
+case 38: {
+ Name lhs = _M_current_rule->lhs;
+ _M_current_rule = _M_grammar->rules.insert (_M_grammar->rules.end (), Rule ());
+ _M_current_rule->lhs = lhs;
+ _M_grammar->declared_lhs.insert (_M_current_rule->lhs);
+
+ if (_M_grammar->terminals.find (_M_current_rule->lhs) != _M_grammar->terminals.end ())
+ {
+ qerr << _M_input_file << ":" << _M_line << ": Invalid non terminal `" << *_M_current_rule->lhs << "'" << endl;
+ return false;
+ }
+
+ _M_grammar->non_terminals.insert (_M_current_rule->lhs);
+} break;
+
+case 39: {
+ _M_current_rule->prec = _M_grammar->names.end ();
+
+ for (NameList::iterator it = _M_current_rule->rhs.begin (); it != _M_current_rule->rhs.end (); ++it)
+ {
+ if (! _M_grammar->isTerminal (*it))
+ continue;
+
+ _M_current_rule->prec = *it;
+ }
+} break;
+
+case 40: {
+ Name tok = _M_grammar->intern (sym(2));
+ if (! _M_grammar->isTerminal (tok))
+ {
+ qerr << _M_input_file << ":" << _M_line << ": `" << *tok << " is not a terminal symbol" << endl;
+ _M_current_rule->prec = _M_grammar->names.end ();
+ }
+ else
+ _M_current_rule->prec = tok;
+} break;
+
+case 42: {
+ Name name = _M_grammar->intern (sym(2));
+
+ if (_M_grammar->terminals.find (name) == _M_grammar->terminals.end ())
+ _M_grammar->non_terminals.insert (name);
+
+ _M_current_rule->rhs.push_back (name);
+} break;
+
+case 43: {
+ sym(1) = QString();
+} break;
+
+ } // switch
+
+ state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
+ }
+
+ else
+ {
+ break;
+ }
+ }
+
+ qerr << _M_input_file << ":" << _M_line << ": Syntax error" << endl;
+ return false;
+}
+
diff --git a/src/tools/qlalr/recognizer.h b/src/tools/qlalr/recognizer.h
new file mode 100644
index 0000000000..8eb089eb8d
--- /dev/null
+++ b/src/tools/qlalr/recognizer.h
@@ -0,0 +1,113 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QLALR project on Qt Labs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "grammar_p.h"
+
+#include "lalr.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qtextstream.h>
+
+#include <cstdlib>
+
+class Recognizer: protected grammar
+{
+public:
+ Recognizer (Grammar *grammar, bool no_lines);
+ ~Recognizer();
+
+ bool parse (const QString &input_file = QString ());
+
+ inline QString decls () const { return _M_decls; }
+ inline QString impls () const { return _M_impls; }
+
+protected:
+ inline void reallocateStack ();
+
+ inline QString &sym (int index)
+ { return sym_stack [tos + index - 1]; }
+
+protected: // scanner
+ int nextToken();
+
+ inline void inp ()
+ {
+ if (_M_currentChar != _M_lastChar)
+ {
+ ch = *_M_currentChar++;
+
+ if (ch == QLatin1Char('\n'))
+ ++_M_line;
+ }
+ else
+ ch = QChar();
+ }
+
+ QString expand (const QString &text) const;
+
+protected:
+ // recognizer
+ int tos;
+ int stack_size;
+ QVector<QString> sym_stack;
+ int *state_stack;
+
+ QString _M_contents;
+ QString::const_iterator _M_firstChar;
+ QString::const_iterator _M_lastChar;
+ QString::const_iterator _M_currentChar;
+
+ // scanner
+ QChar ch;
+ int _M_line;
+ int _M_action_line;
+ Grammar *_M_grammar;
+ RulePointer _M_current_rule;
+ QString _M_input_file;
+
+ QString _M_decls;
+ QString _M_impls;
+ QString _M_current_value;
+ bool _M_no_lines;
+};
diff --git a/src/tools/uic/cpp/cppwriteincludes.cpp b/src/tools/uic/cpp/cppwriteincludes.cpp
index c473566e3a..5b7403bf06 100644
--- a/src/tools/uic/cpp/cppwriteincludes.cpp
+++ b/src/tools/uic/cpp/cppwriteincludes.cpp
@@ -127,6 +127,9 @@ void WriteIncludes::acceptUI(DomUI *node)
TreeWalker::acceptUI(node);
+ if (!m_uic->option().includeFile.isEmpty())
+ m_globalIncludes.insert(m_uic->option().includeFile, true);
+
writeHeaders(m_globalIncludes, true);
writeHeaders(m_localIncludes, false);
diff --git a/src/tools/uic/main.cpp b/src/tools/uic/main.cpp
index c29292a99b..cb2bd430ff 100644
--- a/src/tools/uic/main.cpp
+++ b/src/tools/uic/main.cpp
@@ -95,6 +95,11 @@ int runUic(int argc, char *argv[])
translateOption.setValueName(QStringLiteral("function"));
parser.addOption(translateOption);
+ QCommandLineOption includeOption(QStringList() << QStringLiteral("include"));
+ includeOption.setDescription(QStringLiteral("Add #include <include-file> to <file>."));
+ includeOption.setValueName(QStringLiteral("include-file"));
+ parser.addOption(includeOption);
+
QCommandLineOption generatorOption(QStringList() << QStringLiteral("g") << QStringLiteral("generator"));
generatorOption.setDescription(QStringLiteral("Select generator."));
generatorOption.setValueName(QStringLiteral("java|cpp"));
@@ -110,6 +115,7 @@ int runUic(int argc, char *argv[])
driver.option().implicitIncludes = !parser.isSet(noImplicitIncludesOption);
driver.option().postfix = parser.value(postfixOption);
driver.option().translateFunction = parser.value(translateOption);
+ driver.option().includeFile = parser.value(includeOption);
driver.option().generator = (parser.value(generatorOption).toLower() == QLatin1String("java")) ? Option::JavaGenerator : Option::CppGenerator;
QString inputFile;
diff --git a/src/tools/uic/option.h b/src/tools/uic/option.h
index 14ed422d63..52dc731057 100644
--- a/src/tools/uic/option.h
+++ b/src/tools/uic/option.h
@@ -73,6 +73,7 @@ struct Option
QString prefix;
QString postfix;
QString translateFunction;
+ QString includeFile;
#ifdef QT_UIC_JAVA_GENERATOR
QString javaPackage;
QString javaOutputDirectory;
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 2e6518dd17..8866a3e97e 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -66,6 +66,8 @@
#include "qscreen.h"
#include "qcursor.h"
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
//////////// QWellArray BEGIN
@@ -758,13 +760,9 @@ void QColorLuminancePicker::paintEvent(QPaintEvent *)
int y;
uint *pixel = (uint *) img.scanLine(0);
for (y = 0; y < hi; y++) {
- const uint *end = pixel + wi;
- while (pixel < end) {
- QColor c;
- c.setHsv(hue, sat, y2val(y+coff));
- *pixel = c.rgb();
- ++pixel;
- }
+ uint *end = pixel + wi;
+ std::fill(pixel, end, QColor::fromHsv(hue, sat, y2val(y + coff)).rgb());
+ pixel = end;
}
pix = new QPixmap(QPixmap::fromImage(img));
}
@@ -907,10 +905,8 @@ public:
QColSpinBox(QWidget *parent)
: QSpinBox(parent) { setRange(0, 255); }
void setValue(int i) {
- bool block = signalsBlocked();
- blockSignals(true);
+ const QSignalBlocker blocker(this);
QSpinBox::setValue(i);
- blockSignals(block);
}
};
@@ -1393,7 +1389,7 @@ void QColorShower::setRgb(QRgb rgb)
void QColorShower::setHsv(int h, int s, int v)
{
if (h < -1 || (uint)s > 255 || (uint)v > 255)
- return;
+ return;
rgbOriginal = false;
hue = h; val = v; sat = s;
@@ -1794,6 +1790,21 @@ void QColorDialogPrivate::retranslateStrings()
cs->retranslateStrings();
}
+bool QColorDialogPrivate::canBeNativeDialog() const
+{
+ Q_Q(const QColorDialog);
+ if (nativeDialogInUse)
+ return true;
+ if (q->testAttribute(Qt::WA_DontShowOnScreen))
+ return false;
+ if (q->options() & QColorDialog::DontUseNativeDialog)
+ return false;
+
+ QLatin1String staticName(QColorDialog::staticMetaObject.className());
+ QLatin1String dynamicName(q->metaObject()->className());
+ return (staticName == dynamicName);
+}
+
static const Qt::WindowFlags DefaultWindowFlags =
Qt::Dialog | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint
| Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
@@ -2196,13 +2207,13 @@ bool QColorDialogPrivate::handleColorPickingKeyPress(QKeyEvent *e)
void QColorDialog::done(int result)
{
Q_D(QColorDialog);
- QDialog::done(result);
if (result == Accepted) {
d->selectedQColor = d->currentQColor();
emit colorSelected(d->selectedQColor);
} else {
d->selectedQColor = QColor();
}
+ QDialog::done(result);
if (d->receiverToDisconnectOnClose) {
disconnect(this, SIGNAL(colorSelected(QColor)),
d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose);
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index f58a9200db..72c3b0e3cd 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -110,6 +110,8 @@ public:
bool handleColorPickingMouseButtonRelease(QMouseEvent *e);
bool handleColorPickingKeyPress(QKeyEvent *e);
+ bool canBeNativeDialog() const;
+
QWellArray *custom;
QWellArray *standard;
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 998866c039..1c580ce143 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -1729,7 +1729,7 @@ int QFileDialogPrivate::maxNameLength(const QString &path)
{
#if defined(Q_OS_UNIX)
return ::pathconf(QFile::encodeName(path).data(), _PC_NAME_MAX);
-#elif defined(Q_OS_WINCE)
+#elif defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
Q_UNUSED(path);
return MAX_PATH;
#elif defined(Q_OS_WIN)
@@ -2627,9 +2627,8 @@ void QFileDialog::accept()
// special case for ".."
if (lineEditText == QLatin1String("..")) {
d->_q_navigateToParent();
- bool block = d->qFileDialogUi->fileNameEdit->blockSignals(true);
+ const QSignalBlocker blocker(d->qFileDialogUi->fileNameEdit);
d->lineEdit()->selectAll();
- d->qFileDialogUi->fileNameEdit->blockSignals(block);
return;
}
diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp
index c06ef0c474..b08cc798e5 100644
--- a/src/widgets/dialogs/qfileinfogatherer.cpp
+++ b/src/widgets/dialogs/qfileinfogatherer.cpp
@@ -315,7 +315,7 @@ void QFileInfoGatherer::getFileInfos(const QString &path, const QStringList &fil
dirIt.next();
fileInfo = dirIt.fileInfo();
allFiles.append(fileInfo.fileName());
- fetch(fileInfo, base, firstTime, updatedFiles, path);
+ fetch(fileInfo, base, firstTime, updatedFiles, path);
}
if (!allFiles.isEmpty())
emit newListOfFiles(path, allFiles);
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index fa6306005b..bda448bde3 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -1715,7 +1715,7 @@ QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFile
#ifndef QT_NO_FILESYSTEMWATCHER
node->populate(info);
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//The parentNode is "" so we are listing the drives
if (parentNode->fileName.isEmpty()) {
wchar_t name[MAX_PATH + 1];
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index d908a683a9..94e96a52c5 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -632,12 +632,11 @@ void QFontDialogPrivate::updateSizes()
}
sizeList->setCurrentItem(current);
- sizeEdit->blockSignals(true);
+ const QSignalBlocker blocker(sizeEdit);
sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText()));
if (q->style()->styleHint(QStyle::SH_FontDialog_SelectAssociatedText, 0, q)
&& sizeList->hasFocus())
sizeEdit->selectAll();
- sizeEdit->blockSignals(false);
} else {
sizeEdit->clear();
}
@@ -750,9 +749,8 @@ void QFontDialogPrivate::_q_sizeChanged(const QString &s)
if (sizeList->text(i).toInt() >= this->size)
break;
}
- sizeList->blockSignals(true);
+ const QSignalBlocker blocker(sizeList);
sizeList->setCurrentItem(i);
- sizeList->blockSignals(false);
}
_q_updateSample();
}
diff --git a/src/widgets/dialogs/qinputdialog.cpp b/src/widgets/dialogs/qinputdialog.cpp
index 4eec2eb3e2..10d693b4a3 100644
--- a/src/widgets/dialogs/qinputdialog.cpp
+++ b/src/widgets/dialogs/qinputdialog.cpp
@@ -771,10 +771,11 @@ void QInputDialog::setComboBoxItems(const QStringList &items)
Q_D(QInputDialog);
d->ensureComboBox();
- d->comboBox->blockSignals(true);
- d->comboBox->clear();
- d->comboBox->addItems(items);
- d->comboBox->blockSignals(false);
+ {
+ const QSignalBlocker blocker(d->comboBox);
+ d->comboBox->clear();
+ d->comboBox->addItems(items);
+ }
if (inputMode() == TextInput)
d->chooseRightTextInputWidget();
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index ee2ef409d8..3080d5f1e8 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -73,7 +73,7 @@
QT_BEGIN_NAMESPACE
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
HMENU qt_getWindowsSystemMenu(const QWidget *w)
{
if (QWindow *window = QApplicationPrivate::windowForWidget(w))
@@ -209,7 +209,7 @@ public:
void init(const QString &title = QString(), const QString &text = QString());
void setupLayout();
void _q_buttonClicked(QAbstractButton *);
- void _q_clicked(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole role);
+ void _q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role);
QAbstractButton *findButton(int button0, int button1, int button2, int flags);
void addOldButtons(int button0, int button1, int button2);
@@ -524,7 +524,7 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
}
}
-void QMessageBoxPrivate::_q_clicked(QMessageDialogOptions::StandardButton button, QMessageDialogOptions::ButtonRole role)
+void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
{
Q_UNUSED(role);
Q_Q(QMessageBox);
@@ -1620,7 +1620,7 @@ void QMessageBox::showEvent(QShowEvent *e)
QAccessibleEvent event(this, QAccessible::Alert);
QAccessible::updateAccessibility(&event);
#endif
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (const HMENU systemMenu = qt_getWindowsSystemMenu(this)) {
EnableMenuItem(systemMenu, SC_CLOSE, d->detectedEscapeButton ?
MF_BYCOMMAND|MF_ENABLED : MF_BYCOMMAND|MF_GRAYED);
@@ -2697,8 +2697,8 @@ QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb
void QMessageBoxPrivate::initHelper(QPlatformDialogHelper *h)
{
Q_Q(QMessageBox);
- QObject::connect(h, SIGNAL(clicked(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)),
- q, SLOT(_q_clicked(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole)));
+ QObject::connect(h, SIGNAL(clicked(QPlatformDialogHelper::StandardButton, QPlatformDialogHelper::ButtonRole)),
+ q, SLOT(_q_clicked(QPlatformDialogHelper::StandardButton, QPlatformDialogHelper::ButtonRole)));
static_cast<QPlatformMessageDialogHelper *>(h)->setOptions(options);
}
@@ -2719,9 +2719,9 @@ static QMessageDialogOptions::Icon helperIcon(QMessageBox::Icon i)
return QMessageDialogOptions::NoIcon;
}
-static QMessageDialogOptions::StandardButtons helperStandardButtons(QMessageBox * q)
+static QPlatformDialogHelper::StandardButtons helperStandardButtons(QMessageBox * q)
{
- QMessageDialogOptions::StandardButtons buttons(int(q->standardButtons()));
+ QPlatformDialogHelper::StandardButtons buttons(int(q->standardButtons()));
return buttons;
}
diff --git a/src/widgets/dialogs/qmessagebox.h b/src/widgets/dialogs/qmessagebox.h
index c5598a8f1d..5fae174fe1 100644
--- a/src/widgets/dialogs/qmessagebox.h
+++ b/src/widgets/dialogs/qmessagebox.h
@@ -72,6 +72,7 @@ class Q_WIDGETS_EXPORT QMessageBox : public QDialog
public:
enum Icon {
+ // keep this in sync with QMessageDialogOptions::Icon
NoIcon = 0,
Information = 1,
Warning = 2,
@@ -80,7 +81,7 @@ public:
};
enum ButtonRole {
- // keep this in sync with QDialogButtonBox::ButtonRole
+ // keep this in sync with QDialogButtonBox::ButtonRole and QPlatformDialogHelper::ButtonRole
InvalidRole = -1,
AcceptRole,
RejectRole,
@@ -96,7 +97,7 @@ public:
};
enum StandardButton {
- // keep this in sync with QDialogButtonBox::StandardButton and QMessageDialogOptions::StandardButton
+ // keep this in sync with QDialogButtonBox::StandardButton and QPlatformDialogHelper::StandardButton
NoButton = 0x00000000,
Ok = 0x00000400,
Save = 0x00000800,
@@ -309,7 +310,7 @@ protected:
private:
Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked(QAbstractButton *))
- Q_PRIVATE_SLOT(d_func(), void _q_clicked(QMessageDialogOptions::StandardButton, QMessageDialogOptions::ButtonRole))
+ Q_PRIVATE_SLOT(d_func(), void _q_clicked(QPlatformDialogHelper::StandardButton, QPlatformDialogHelper::ButtonRole))
Q_DISABLE_COPY(QMessageBox)
Q_DECLARE_PRIVATE(QMessageBox)
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index a667f299e8..b294e98c30 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -76,6 +76,7 @@ extern bool qt_wince_is_mobile(); //defined in qguifunctions_wce.cpp
#endif
#include <string.h> // for memset()
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -129,22 +130,41 @@ static bool objectInheritsXAndXIsCloserThanY(const QObject *object, const QByteA
return false;
}
-const int NFallbackDefaultProperties = 7;
-
const struct {
- const char *className;
- const char *property;
- const char *changedSignal;
-} fallbackProperties[NFallbackDefaultProperties] = {
+ const char className[16];
+ const char property[13];
+} fallbackProperties[] = {
// If you modify this list, make sure to update the documentation (and the auto test)
- { "QAbstractButton", "checked", SIGNAL(toggled(bool)) },
- { "QAbstractSlider", "value", SIGNAL(valueChanged(int)) },
- { "QComboBox", "currentIndex", SIGNAL(currentIndexChanged(int)) },
- { "QDateTimeEdit", "dateTime", SIGNAL(dateTimeChanged(QDateTime)) },
- { "QLineEdit", "text", SIGNAL(textChanged(QString)) },
- { "QListWidget", "currentRow", SIGNAL(currentRowChanged(int)) },
- { "QSpinBox", "value", SIGNAL(valueChanged(int)) }
+ { "QAbstractButton", "checked" },
+ { "QAbstractSlider", "value" },
+ { "QComboBox", "currentIndex" },
+ { "QDateTimeEdit", "dateTime" },
+ { "QLineEdit", "text" },
+ { "QListWidget", "currentRow" },
+ { "QSpinBox", "value" },
};
+const size_t NFallbackDefaultProperties = sizeof fallbackProperties / sizeof *fallbackProperties;
+
+static const char *changed_signal(int which)
+{
+ // since it might expand to a runtime function call (to
+ // qFlagLocations()), we cannot store the result of SIGNAL() in a
+ // character array and expect it to be statically initialized. To
+ // avoid the relocations caused by a char pointer table, use a
+ // switch statement:
+ switch (which) {
+ case 0: return SIGNAL(toggled(bool));
+ case 1: return SIGNAL(valueChanged(int));
+ case 2: return SIGNAL(currentIndexChanged(int));
+ case 3: return SIGNAL(dateTimeChanged(QDateTime));
+ case 4: return SIGNAL(textChanged(QString));
+ case 5: return SIGNAL(currentRowChanged(int));
+ case 6: return SIGNAL(valueChanged(int));
+ };
+ Q_STATIC_ASSERT(7 == NFallbackDefaultProperties);
+ Q_UNREACHABLE();
+ return 0;
+}
class QWizardDefaultProperty
{
@@ -542,6 +562,7 @@ public:
, canContinue(false)
, canFinish(false)
, disableUpdatesCount(0)
+ , wizStyle(QWizard::ClassicStyle)
, opts(0)
, buttonsHaveCustomLayout(false)
, titleFmt(Qt::AutoText)
@@ -551,10 +572,12 @@ public:
, headerWidget(0)
, watermarkLabel(0)
, sideWidget(0)
+ , pageFrame(0)
, titleLabel(0)
, subTitleLabel(0)
, bottomRuler(0)
#if !defined(QT_NO_STYLE_WINDOWSVISTA)
+ , vistaHelper(0)
, vistaInitPending(false)
, vistaState(QVistaHelper::Dirty)
, vistaStateChanged(false)
@@ -565,8 +588,7 @@ public:
, maximumWidth(QWIDGETSIZE_MAX)
, maximumHeight(QWIDGETSIZE_MAX)
{
- for (int i = 0; i < QWizard::NButtons; ++i)
- btns[i] = 0;
+ std::fill(btns, btns + QWizard::NButtons, static_cast<QAbstractButton *>(0));
#if !defined(QT_NO_STYLE_WINDOWSVISTA)
if (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
@@ -737,10 +759,10 @@ void QWizardPrivate::init()
updateButtonLayout();
- for (int i = 0; i < NFallbackDefaultProperties; ++i)
+ for (uint i = 0; i < NFallbackDefaultProperties; ++i)
defaultPropertyTable.append(QWizardDefaultProperty(fallbackProperties[i].className,
fallbackProperties[i].property,
- fallbackProperties[i].changedSignal));
+ changed_signal(i)));
}
void QWizardPrivate::reset()
@@ -887,9 +909,28 @@ void QWizardPrivate::switchToPage(int newId, Direction direction)
}
// keep in sync with QWizard::WizardButton
-static const char * const buttonSlots[QWizard::NStandardButtons] = {
- SLOT(back()), SLOT(next()), SLOT(next()), SLOT(accept()), SLOT(reject()),
- SIGNAL(helpRequested())
+static const char * buttonSlots(QWizard::WizardButton which)
+{
+ switch (which) {
+ case QWizard::BackButton:
+ return SLOT(back());
+ case QWizard::NextButton:
+ case QWizard::CommitButton:
+ return SLOT(next());
+ case QWizard::FinishButton:
+ return SLOT(accept());
+ case QWizard::CancelButton:
+ return SLOT(reject());
+ case QWizard::HelpButton:
+ return SIGNAL(helpRequested());
+ case QWizard::CustomButton1:
+ case QWizard::CustomButton2:
+ case QWizard::CustomButton3:
+ case QWizard::Stretch:
+ case QWizard::NoButton:
+ Q_UNREACHABLE();
+ };
+ return 0;
};
QWizardLayoutInfo QWizardPrivate::layoutInfoForCurrentPage()
@@ -1405,7 +1446,7 @@ void QWizardPrivate::connectButton(QWizard::WizardButton which) const
{
Q_Q(const QWizard);
if (which < QWizard::NStandardButtons) {
- QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots[which]);
+ QObject::connect(btns[which], SIGNAL(clicked()), q, buttonSlots(which));
} else {
QObject::connect(btns[which], SIGNAL(clicked()), q, SLOT(_q_emitCustomButtonClicked()));
}
@@ -1424,6 +1465,11 @@ void QWizardPrivate::updateButtonTexts()
btns[i]->setText(buttonDefaultText(wizStyle, i, this));
}
}
+ // Vista: Add shortcut for 'next'. Note: native dialogs use ALT-Right
+ // even in RTL mode, so do the same, even if it might be counter-intuitive.
+ // The shortcut for 'back' is set in class QVistaBackButton.
+ if (btns[QWizard::NextButton])
+ btns[QWizard::NextButton]->setShortcut(isVistaThemeEnabled() ? QKeySequence(Qt::ALT | Qt::Key_Right) : QKeySequence());
}
void QWizardPrivate::updateButtonLayout()
@@ -1576,7 +1622,7 @@ bool QWizardPrivate::handleAeroStyleChange()
if (isWindow)
vistaHelper->setTitleBarIconAndCaptionVisible(false);
QObject::connect(
- vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots[QWizard::BackButton]);
+ vistaHelper->backButton(), SIGNAL(clicked()), q, buttonSlots(QWizard::BackButton));
vistaHelper->backButton()->show();
} else {
q->setMouseTracking(true); // ### original value possibly different
@@ -1666,6 +1712,10 @@ void QWizardPrivate::_q_updateButtonStates()
btn.finish->setVisible(buttonLayoutContains(QWizard::FinishButton)
&& (canFinish || (opts & QWizard::HaveFinishButtonOnEarlyPages)));
+ if (!(opts & QWizard::NoCancelButton))
+ btn.cancel->setVisible(buttonLayoutContains(QWizard::CancelButton)
+ && (canContinue || !(opts & QWizard::NoCancelButtonOnLastPage)));
+
bool useDefault = !(opts & QWizard::NoDefaultButton);
if (QPushButton *nextPush = qobject_cast<QPushButton *>(btn.next))
nextPush->setDefault(canContinue && useDefault && !commitPage);
@@ -2150,6 +2200,7 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)
\value HaveCustomButton1 Show the first user-defined button (CustomButton1).
\value HaveCustomButton2 Show the second user-defined button (CustomButton2).
\value HaveCustomButton3 Show the third user-defined button (CustomButton3).
+ \value NoCancelButtonOnLastPage Don't show the \uicontrol Cancel button on the last page.
\sa setOptions(), setOption(), testOption()
*/
@@ -2604,7 +2655,7 @@ void QWizard::setOptions(WizardOptions options)
d->updateButtonLayout();
} else if (changed & (NoBackButtonOnStartPage | NoBackButtonOnLastPage
| HaveNextButtonOnLastPage | HaveFinishButtonOnEarlyPages
- | DisabledBackButtonOnLastPage)) {
+ | DisabledBackButtonOnLastPage | NoCancelButtonOnLastPage)) {
d->_q_updateButtonStates();
}
diff --git a/src/widgets/dialogs/qwizard.h b/src/widgets/dialogs/qwizard.h
index 9dea9a8e6f..51b18e0e8f 100644
--- a/src/widgets/dialogs/qwizard.h
+++ b/src/widgets/dialogs/qwizard.h
@@ -115,7 +115,8 @@ public:
HelpButtonOnRight = 0x00001000,
HaveCustomButton1 = 0x00002000,
HaveCustomButton2 = 0x00004000,
- HaveCustomButton3 = 0x00008000
+ HaveCustomButton3 = 0x00008000,
+ NoCancelButtonOnLastPage = 0x00010000
};
Q_DECLARE_FLAGS(WizardOptions, WizardOption)
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index b57614c018..747115984d 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -117,16 +117,16 @@ enum WIZ_WINDOWTHEMEATTRIBUTETYPE {
#define WIZ_DT_NOPREFIX 0x00000800
enum WIZ_NAVIGATIONPARTS { //NAVIGATIONPARTS
- WIZ_NAV_BACKBUTTON = 1,
- WIZ_NAV_FORWARDBUTTON = 2,
- WIZ_NAV_MENUBUTTON = 3,
+ WIZ_NAV_BACKBUTTON = 1,
+ WIZ_NAV_FORWARDBUTTON = 2,
+ WIZ_NAV_MENUBUTTON = 3,
};
enum WIZ_NAV_BACKBUTTONSTATES { //NAV_BACKBUTTONSTATES
- WIZ_NAV_BB_NORMAL = 1,
- WIZ_NAV_BB_HOT = 2,
- WIZ_NAV_BB_PRESSED = 3,
- WIZ_NAV_BB_DISABLED = 4,
+ WIZ_NAV_BB_NORMAL = 1,
+ WIZ_NAV_BB_HOT = 2,
+ WIZ_NAV_BB_PRESSED = 3,
+ WIZ_NAV_BB_DISABLED = 4,
};
#define WIZ_TMT_CAPTIONFONT (801) //TMT_CAPTIONFONT
@@ -183,6 +183,8 @@ QVistaBackButton::QVistaBackButton(QWidget *widget)
: QAbstractButton(widget)
{
setFocusPolicy(Qt::NoFocus);
+ // Native dialogs use ALT-Left even in RTL mode, so do the same, even if it might be counter-intuitive.
+ setShortcut(QKeySequence(Qt::ALT | Qt::Key_Left));
}
QSize QVistaBackButton::sizeHint() const
@@ -278,8 +280,6 @@ QVistaHelper::~QVistaHelper()
void QVistaHelper::updateCustomMargins(bool vistaMargins)
{
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS8)
- return; // Negative margins are not supported on Windows 8.
if (QWindow *window = wizard->windowHandle()) {
// Reduce top frame to zero since we paint it ourselves.
const QMargins customMargins = vistaMargins ?
@@ -768,6 +768,33 @@ bool QVistaHelper::drawBlackRect(const QRect &rect, HDC hdc)
return value;
}
+#if !defined(_MSC_VER) || _MSC_VER < 1700
+static inline int getWindowBottomMargin()
+{
+ return GetSystemMetrics(SM_CYSIZEFRAME);
+}
+#else // !_MSC_VER || _MSC_VER < 1700
+// QTBUG-36192, GetSystemMetrics(SM_CYSIZEFRAME) returns bogus values
+// for MSVC2012 which leads to the custom margin having no effect since
+// that only works when removing the entire margin.
+static inline int getWindowBottomMargin()
+{
+ RECT rect = {0, 0, 0, 0};
+ AdjustWindowRectEx(&rect, WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_THICKFRAME | WS_DLGFRAME, FALSE, 0);
+ return qAbs(rect.bottom);
+}
+#endif // _MSC_VER >= 1700
+
+int QVistaHelper::frameSize()
+{
+ return getWindowBottomMargin();
+}
+
+int QVistaHelper::captionSize()
+{
+ return GetSystemMetrics(SM_CYCAPTION);
+}
+
bool QVistaHelper::resolveSymbols()
{
static bool tried = false;
@@ -826,10 +853,7 @@ int QVistaHelper::topOffset()
static const int aeroOffset =
QSysInfo::WindowsVersion == QSysInfo::WV_WINDOWS7 ?
QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
- int result = aeroOffset;
- if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8)
- result += titleBarSize();
- return result;
+ return aeroOffset + titleBarSize();
}
QT_END_NAMESPACE
diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h
index a7713d889b..81514a8950 100644
--- a/src/widgets/dialogs/qwizard_win_p.h
+++ b/src/widgets/dialogs/qwizard_win_p.h
@@ -117,8 +117,8 @@ private:
bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc);
static bool drawBlackRect(const QRect &rect, HDC hdc);
- static int frameSize() { return GetSystemMetrics(SM_CYSIZEFRAME); }
- static int captionSize() { return GetSystemMetrics(SM_CYCAPTION); }
+ static int frameSize();
+ static int captionSize();
static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); }
static int iconSize() { return 16; } // Standard Aero
diff --git a/src/widgets/doc/snippets/code/doc_src_layout.cpp b/src/widgets/doc/snippets/code/doc_src_layout.cpp
index 6bad8558c1..5ea8ce5a5f 100644
--- a/src/widgets/doc/snippets/code/doc_src_layout.cpp
+++ b/src/widgets/doc/snippets/code/doc_src_layout.cpp
@@ -75,7 +75,7 @@ private:
//! [2]
int CardLayout::count() const
{
- // QList::size() returns the number of QLayoutItems in the list
+ // QList::size() returns the number of QLayoutItems in the list
return list.size();
}
//! [2]
diff --git a/src/widgets/doc/snippets/customstyle/customstyle.cpp b/src/widgets/doc/snippets/customstyle/customstyle.cpp
index 9d00745e6a..b5d44ebecd 100644
--- a/src/widgets/doc/snippets/customstyle/customstyle.cpp
+++ b/src/widgets/doc/snippets/customstyle/customstyle.cpp
@@ -57,32 +57,32 @@ void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *op
QPainter *painter, const QWidget *widget) const
{
if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
- QPolygon points(3);
- int x = option->rect.x();
- int y = option->rect.y();
- int w = option->rect.width() / 2;
- int h = option->rect.height() / 2;
- x += (option->rect.width() - w) / 2;
- y += (option->rect.height() - h) / 2;
+ QPolygon points(3);
+ int x = option->rect.x();
+ int y = option->rect.y();
+ int w = option->rect.width() / 2;
+ int h = option->rect.height() / 2;
+ x += (option->rect.width() - w) / 2;
+ y += (option->rect.height() - h) / 2;
- if (element == PE_IndicatorSpinUp) {
- points[0] = QPoint(x, y + h);
- points[1] = QPoint(x + w, y + h);
- points[2] = QPoint(x + w / 2, y);
- } else { // PE_SpinBoxDown
- points[0] = QPoint(x, y);
- points[1] = QPoint(x + w, y);
- points[2] = QPoint(x + w / 2, y + h);
- }
+ if (element == PE_IndicatorSpinUp) {
+ points[0] = QPoint(x, y + h);
+ points[1] = QPoint(x + w, y + h);
+ points[2] = QPoint(x + w / 2, y);
+ } else { // PE_SpinBoxDown
+ points[0] = QPoint(x, y);
+ points[1] = QPoint(x + w, y);
+ points[2] = QPoint(x + w / 2, y + h);
+ }
- if (option->state & State_Enabled) {
- painter->setPen(option->palette.mid().color());
- painter->setBrush(option->palette.buttonText());
- } else {
- painter->setPen(option->palette.buttonText().color());
- painter->setBrush(option->palette.mid());
- }
- painter->drawPolygon(points);
+ if (option->state & State_Enabled) {
+ painter->setPen(option->palette.mid().color());
+ painter->setBrush(option->palette.buttonText());
+ } else {
+ painter->setPen(option->palette.buttonText().color());
+ painter->setBrush(option->palette.mid());
+ }
+ painter->drawPolygon(points);
} else {
QProxyStyle::drawPrimitive(element, option, painter, widget);
//! [2] //! [3]
diff --git a/src/widgets/doc/snippets/mainwindowsnippet.cpp b/src/widgets/doc/snippets/mainwindowsnippet.cpp
index a9a9012d46..e27e00e848 100644
--- a/src/widgets/doc/snippets/mainwindowsnippet.cpp
+++ b/src/widgets/doc/snippets/mainwindowsnippet.cpp
@@ -85,7 +85,7 @@ void MainWindow::createDockWidgets()
//! [0]
QDockWidget *dockWidget = new QDockWidget(tr("Dock Widget"), this);
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
- Qt::RightDockWidgetArea);
+ Qt::RightDockWidgetArea);
dockWidget->setWidget(dockWidgetContents);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
//! [0]
diff --git a/src/widgets/doc/snippets/mdiareasnippets.cpp b/src/widgets/doc/snippets/mdiareasnippets.cpp
index 42902b4cd7..9c0b693e80 100644
--- a/src/widgets/doc/snippets/mdiareasnippets.cpp
+++ b/src/widgets/doc/snippets/mdiareasnippets.cpp
@@ -66,7 +66,7 @@ void addingSubWindowsExample()
mdiArea.addSubWindow(subWindow1);
QMdiSubWindow *subWindow2 =
- mdiArea.addSubWindow(internalWidget2);
+ mdiArea.addSubWindow(internalWidget2);
//! [1]
subWindow1->show();
diff --git a/src/widgets/doc/snippets/textdocument-imagedrop/textedit.cpp b/src/widgets/doc/snippets/textdocument-imagedrop/textedit.cpp
index 619333d98e..b11abbe604 100644
--- a/src/widgets/doc/snippets/textdocument-imagedrop/textedit.cpp
+++ b/src/widgets/doc/snippets/textdocument-imagedrop/textedit.cpp
@@ -42,7 +42,7 @@
#include <QtGui>
TextEdit::TextEdit(QWidget *parent)
- : QTextEdit(parent)
+ : QTextEdit(parent)
{
}
diff --git a/src/widgets/doc/snippets/timeline/main.cpp b/src/widgets/doc/snippets/timeline/main.cpp
index 9e4d218a88..8c74ee0615 100644
--- a/src/widgets/doc/snippets/timeline/main.cpp
+++ b/src/widgets/doc/snippets/timeline/main.cpp
@@ -56,7 +56,7 @@ int main(int argv, char *args[])
animation->setTimeLine(timer);
for (int i = 0; i < 200; ++i)
- animation->setPosAt(i / 200.0, QPointF(i, i));
+ animation->setPosAt(i / 200.0, QPointF(i, i));
QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 250, 250);
diff --git a/src/widgets/graphicsview/graphicsview.pri b/src/widgets/graphicsview/graphicsview.pri
index a0fc4bc8d3..b81f736ef4 100644
--- a/src/widgets/graphicsview/graphicsview.pri
+++ b/src/widgets/graphicsview/graphicsview.pri
@@ -23,7 +23,8 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \
graphicsview/qgraphicsview_p.h \
graphicsview/qgraphicswidget.h \
graphicsview/qgraphicswidget_p.h \
- graphicsview/qgridlayoutengine_p.h \
+ graphicsview/qgraphicslayoutstyleinfo_p.h \
+ graphicsview/qgraphicsgridlayoutengine_p.h \
graphicsview/qgraph_p.h \
graphicsview/qsimplex_p.h \
graphicsview/qgraphicsanchorlayout_p.h \
@@ -47,7 +48,8 @@ SOURCES += graphicsview/qgraphicsgridlayout.cpp \
graphicsview/qgraphicsview.cpp \
graphicsview/qgraphicswidget.cpp \
graphicsview/qgraphicswidget_p.cpp \
- graphicsview/qgridlayoutengine.cpp \
+ graphicsview/qgraphicslayoutstyleinfo.cpp \
+ graphicsview/qgraphicsgridlayoutengine.cpp \
graphicsview/qsimplex_p.cpp \
graphicsview/qgraphicsanchorlayout_p.cpp \
graphicsview/qgraphicsanchorlayout.cpp
diff --git a/src/widgets/graphicsview/qgraphicsgridlayout.cpp b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
index 6d9dd98839..0ecb4af6bd 100644
--- a/src/widgets/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicsgridlayout.cpp
@@ -89,30 +89,35 @@
#include "qgraphicslayoutitem.h"
#include "qgraphicsgridlayout.h"
#include "qgraphicswidget.h"
-#include "qgridlayoutengine_p.h"
-#include <QtCore/qdebug.h>
+#include "qgraphicsgridlayoutengine_p.h"
+#include "qgraphicslayoutstyleinfo_p.h"
+#ifdef QT_DEBUG
+# include <QtCore/qdebug.h>
+#endif
QT_BEGIN_NAMESPACE
class QGraphicsGridLayoutPrivate : public QGraphicsLayoutPrivate
{
public:
- QGraphicsGridLayoutPrivate() { }
- QLayoutStyleInfo styleInfo() const;
+ QGraphicsGridLayoutPrivate(): m_styleInfo(0) { }
+ QGraphicsLayoutStyleInfo *styleInfo() const;
- QGridLayoutEngine engine;
-#ifdef QT_DEBUG
+ mutable QGraphicsLayoutStyleInfo *m_styleInfo;
+ QGraphicsGridLayoutEngine engine;
+
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void dump(int indent) const;
#endif
};
-Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget);
-QLayoutStyleInfo QGraphicsGridLayoutPrivate::styleInfo() const
+QGraphicsLayoutStyleInfo *QGraphicsGridLayoutPrivate::styleInfo() const
{
- QGraphicsItem *item = parentItem();
- QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
- return QLayoutStyleInfo(style, globalStyleInfoWidget());
+ if (!m_styleInfo)
+ m_styleInfo = new QGraphicsLayoutStyleInfo(this);
+ m_styleInfo->updateChanged(QAbstractLayoutStyleInfo::Unknown);
+ return m_styleInfo;
}
/*!
@@ -172,7 +177,8 @@ void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column
d->addChildLayoutItem(item);
- new QGridLayoutItem(&d->engine, item, row, column, rowSpan, columnSpan, alignment);
+ QGraphicsGridLayoutEngineItem *gridEngineItem = new QGraphicsGridLayoutEngineItem(item, row, column, rowSpan, columnSpan, alignment);
+ d->engine.insertItem(gridEngineItem, -1);
invalidate();
}
@@ -199,7 +205,7 @@ void QGraphicsGridLayout::setHorizontalSpacing(qreal spacing)
qreal QGraphicsGridLayout::horizontalSpacing() const
{
Q_D(const QGraphicsGridLayout);
- return d->engine.spacing(d->styleInfo(), Qt::Horizontal);
+ return d->engine.spacing(Qt::Horizontal, d->styleInfo());
}
/*!
@@ -218,7 +224,7 @@ void QGraphicsGridLayout::setVerticalSpacing(qreal spacing)
qreal QGraphicsGridLayout::verticalSpacing() const
{
Q_D(const QGraphicsGridLayout);
- return d->engine.spacing(d->styleInfo(), Qt::Vertical);
+ return d->engine.spacing(Qt::Vertical, d->styleInfo());
}
/*!
@@ -535,8 +541,8 @@ QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int row, int column) const
qWarning("QGraphicsGridLayout::itemAt: invalid row, column %d, %d", row, column);
return 0;
}
- if (QGridLayoutItem *item = d->engine.itemAt(row, column))
- return item->layoutItem();
+ if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(row, column)))
+ return engineItem->layoutItem();
return 0;
}
@@ -561,8 +567,8 @@ QGraphicsLayoutItem *QGraphicsGridLayout::itemAt(int index) const
return 0;
}
QGraphicsLayoutItem *item = 0;
- if (QGridLayoutItem *gridItem = d->engine.itemAt(index))
- item = gridItem->layoutItem();
+ if (QGraphicsGridLayoutEngineItem *engineItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index)))
+ item = engineItem->layoutItem();
return item;
}
@@ -579,7 +585,8 @@ void QGraphicsGridLayout::removeAt(int index)
qWarning("QGraphicsGridLayout::removeAt: invalid index %d", index);
return;
}
- if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) {
+
+ if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) {
if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem())
layoutItem->setParentLayoutItem(0);
d->engine.removeItem(gridItem);
@@ -619,10 +626,12 @@ void QGraphicsGridLayout::invalidate()
{
Q_D(QGraphicsGridLayout);
d->engine.invalidate();
+ if (d->m_styleInfo)
+ d->m_styleInfo->invalidate();
QGraphicsLayout::invalidate();
}
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
void QGraphicsGridLayoutPrivate::dump(int indent) const
{
if (qt_graphicsLayoutDebug()) {
@@ -646,8 +655,8 @@ void QGraphicsGridLayout::setGeometry(const QRectF &rect)
if (visualDir == Qt::RightToLeft)
qSwap(left, right);
effectiveRect.adjust(+left, +top, -right, -bottom);
- d->engine.setGeometries(d->styleInfo(), effectiveRect);
-#ifdef QT_DEBUG
+ d->engine.setGeometries(effectiveRect, d->styleInfo());
+#ifdef QGRIDLAYOUTENGINE_DEBUG
if (qt_graphicsLayoutDebug()) {
static int counter = 0;
qDebug("==== BEGIN DUMP OF QGraphicsGridLayout (%d)====", counter++);
@@ -666,7 +675,7 @@ QSizeF QGraphicsGridLayout::sizeHint(Qt::SizeHint which, const QSizeF &constrain
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
const QSizeF extraMargins(left + right, top + bottom);
- return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins;
+ return d->engine.sizeHint(which , constraint - extraMargins, d->styleInfo()) + extraMargins;
}
diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp
new file mode 100644
index 0000000000..605411bd6d
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgraphicsgridlayoutengine_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicslayoutitem_p.h"
+#include "qgraphicslayout_p.h"
+#include "qgraphicswidget.h"
+
+QT_BEGIN_NAMESPACE
+
+/*
+ returns \c true if the size policy returns \c true for either hasHeightForWidth()
+ or hasWidthForHeight()
+ */
+bool QGraphicsGridLayoutEngineItem::hasDynamicConstraint() const
+{
+ return QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth()
+ || QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight();
+}
+
+Qt::Orientation QGraphicsGridLayoutEngineItem::dynamicConstraintOrientation() const
+{
+ if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasHeightForWidth())
+ return Qt::Vertical;
+ else //if (QGraphicsLayoutItemPrivate::get(q_layoutItem)->hasWidthForHeight())
+ return Qt::Horizontal;
+}
+
+
+void QGraphicsGridLayoutEngine::setAlignment(QGraphicsLayoutItem *graphicsLayoutItem, Qt::Alignment alignment)
+{
+ if (QGraphicsGridLayoutEngineItem *gridEngineItem = findLayoutItem(graphicsLayoutItem)) {
+ gridEngineItem->setAlignment(alignment);
+ invalidate();
+ }
+}
+
+Qt::Alignment QGraphicsGridLayoutEngine::alignment(QGraphicsLayoutItem *graphicsLayoutItem) const
+{
+ if (QGraphicsGridLayoutEngineItem *gridEngineItem = findLayoutItem(graphicsLayoutItem))
+ return gridEngineItem->alignment();
+ return 0;
+}
+
+
+void QGraphicsGridLayoutEngine::setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch,
+ Qt::Orientation orientation)
+{
+ Q_ASSERT(stretch >= 0);
+
+ if (QGraphicsGridLayoutEngineItem *item = findLayoutItem(layoutItem))
+ item->setStretchFactor(stretch, orientation);
+}
+
+int QGraphicsGridLayoutEngine::stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const
+{
+ if (QGraphicsGridLayoutEngineItem *item = findLayoutItem(layoutItem))
+ return item->stretchFactor(orientation);
+ return 0;
+}
+
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h
new file mode 100644
index 0000000000..1338114d96
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicsgridlayoutengine_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSGRIDLAYOUTENGINE_P_H
+#define QGRAPHICSGRIDLAYOUTENGINE_P_H
+
+#include <QtGui/private/qgridlayoutengine_p.h>
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include <QtWidgets/qsizepolicy.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qstyleoption.h>
+#include "qgraphicslayoutitem.h"
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsLayoutPrivate;
+
+class QGraphicsGridLayoutEngineItem : public QGridLayoutItem {
+public:
+ QGraphicsGridLayoutEngineItem(QGraphicsLayoutItem *item, int row, int columns, int rowSpan = 1, int columnSpan = 1,
+ Qt::Alignment alignment = 0)
+ : QGridLayoutItem(row, columns, rowSpan, columnSpan, alignment), q_layoutItem(item) {}
+
+ virtual QLayoutPolicy::Policy sizePolicy(Qt::Orientation orientation) const Q_DECL_OVERRIDE
+ {
+ QSizePolicy sizePolicy(q_layoutItem->sizePolicy());
+ return (QLayoutPolicy::Policy)((orientation == Qt::Horizontal) ? sizePolicy.horizontalPolicy()
+ : sizePolicy.verticalPolicy());
+ }
+
+ virtual QLayoutPolicy::ControlTypes controlTypes(LayoutSide) const Q_DECL_OVERRIDE
+ {
+ const QSizePolicy::ControlType ct = q_layoutItem->sizePolicy().controlType();
+ return (QLayoutPolicy::ControlTypes)ct;
+ }
+
+ virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const Q_DECL_OVERRIDE
+ {
+ return q_layoutItem->effectiveSizeHint(which, constraint);
+ }
+
+ virtual void setGeometry(const QRectF &rect) Q_DECL_OVERRIDE
+ {
+ q_layoutItem->setGeometry(rect);
+ }
+
+ virtual bool hasDynamicConstraint() const Q_DECL_OVERRIDE;
+ virtual Qt::Orientation dynamicConstraintOrientation() const Q_DECL_OVERRIDE;
+
+ QGraphicsLayoutItem *layoutItem() const { return q_layoutItem; }
+
+protected:
+ QGraphicsLayoutItem *q_layoutItem;
+};
+
+
+class QGraphicsGridLayoutEngine : public QGridLayoutEngine
+{
+public:
+ QGraphicsGridLayoutEngineItem *findLayoutItem(QGraphicsLayoutItem *layoutItem) const
+ {
+ const int index = indexOf(layoutItem);
+ if (index < 0)
+ return 0;
+ return static_cast<QGraphicsGridLayoutEngineItem*>(q_items.at(index));
+ }
+
+ int indexOf(QGraphicsLayoutItem *item) const
+ {
+ for (int i = 0; i < q_items.count(); ++i) {
+ if (item == static_cast<QGraphicsGridLayoutEngineItem*>(q_items.at(i))->layoutItem())
+ return i;
+ }
+ return -1;
+ }
+
+ void setAlignment(QGraphicsLayoutItem *graphicsLayoutItem, Qt::Alignment alignment);
+ Qt::Alignment alignment(QGraphicsLayoutItem *graphicsLayoutItem) const;
+
+ void setStretchFactor(QGraphicsLayoutItem *layoutItem, int stretch, Qt::Orientation orientation);
+ int stretchFactor(QGraphicsLayoutItem *layoutItem, Qt::Orientation orientation) const;
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif // QGRAPHICSGRIDLAYOUTENGINE_P_H
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 2d07e545c8..ae2423400a 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -10316,7 +10316,7 @@ QVariant QGraphicsTextItem::inputMethodQuery(Qt::InputMethodQuery query) const
if (query == Qt::ImHints)
v = int(inputMethodHints());
else if (dd->control)
- v = dd->control->inputMethodQuery(query);
+ v = dd->control->inputMethodQuery(query, QVariant());
if (v.type() == QVariant::RectF)
v = v.toRectF().translated(-dd->controlOffset());
else if (v.type() == QVariant::PointF)
diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
new file mode 100644
index 0000000000..d60fd6059e
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgraphicslayoutstyleinfo_p.h"
+
+#ifndef QT_NO_GRAPHICSVIEW
+
+#include "qgraphicslayout_p.h"
+#include "qgraphicswidget.h"
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qwidget.h>
+#include <QtWidgets/qapplication.h>
+
+QT_BEGIN_NAMESPACE
+
+QGraphicsLayoutStyleInfo::QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout)
+ : m_layout(layout), m_style(0)
+{
+ m_widget = new QWidget; // pixelMetric might need a widget ptr
+ if (m_widget)
+ m_styleOption.initFrom(m_widget);
+ m_isWindow = m_styleOption.state & QStyle::State_Window;
+}
+
+QGraphicsLayoutStyleInfo::~QGraphicsLayoutStyleInfo()
+{
+ delete m_widget;
+}
+
+qreal QGraphicsLayoutStyleInfo::combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1,
+ QLayoutPolicy::ControlTypes controls2,
+ Qt::Orientation orientation) const
+{
+ Q_ASSERT(style());
+ return style()->combinedLayoutSpacing(QSizePolicy::ControlTypes(int(controls1)), QSizePolicy::ControlTypes(int(controls2)),
+ orientation, const_cast<QStyleOption*>(&m_styleOption), widget());
+}
+
+qreal QGraphicsLayoutStyleInfo::perItemSpacing(QLayoutPolicy::ControlType control1,
+ QLayoutPolicy::ControlType control2,
+ Qt::Orientation orientation) const
+{
+ Q_ASSERT(style());
+ return style()->layoutSpacing(QSizePolicy::ControlType(control1), QSizePolicy::ControlType(control2),
+ orientation, const_cast<QStyleOption*>(&m_styleOption), widget());
+}
+
+qreal QGraphicsLayoutStyleInfo::spacing(Qt::Orientation orientation) const
+{
+ Q_ASSERT(style());
+ return style()->pixelMetric(orientation == Qt::Horizontal ? QStyle::PM_LayoutHorizontalSpacing : QStyle::PM_LayoutVerticalSpacing);
+}
+
+qreal QGraphicsLayoutStyleInfo::windowMargin(Qt::Orientation orientation) const
+{
+ return style()->pixelMetric(orientation == Qt::Vertical
+ ? QStyle::PM_LayoutBottomMargin
+ : QStyle::PM_LayoutRightMargin,
+ const_cast<QStyleOption*>(&m_styleOption), widget());
+}
+
+QWidget *QGraphicsLayoutStyleInfo::widget() const { return m_widget; }
+
+QStyle *QGraphicsLayoutStyleInfo::style() const
+{
+ if (!m_style) {
+ Q_ASSERT(m_layout);
+ QGraphicsItem *item = m_layout->parentItem();
+ m_style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
+ }
+ return m_style;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
diff --git a/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h
new file mode 100644
index 0000000000..275ebab6a1
--- /dev/null
+++ b/src/widgets/graphicsview/qgraphicslayoutstyleinfo_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QGRAPHICSLAYOUTSTYLEINFO_P_H
+#define QGRAPHICSLAYOUTSTYLEINFO_P_H
+
+#include <QtGui/private/qabstractlayoutstyleinfo_p.h>
+#include <QtWidgets/qstyleoption.h>
+
+QT_BEGIN_NAMESPACE
+
+class QStyle;
+class QWidget;
+class QGraphicsLayoutPrivate;
+
+class QGraphicsLayoutStyleInfo : public QAbstractLayoutStyleInfo
+{
+public:
+ QGraphicsLayoutStyleInfo(const QGraphicsLayoutPrivate *layout);
+ ~QGraphicsLayoutStyleInfo();
+
+ virtual qreal combinedLayoutSpacing(QLayoutPolicy::ControlTypes controls1,
+ QLayoutPolicy::ControlTypes controls2,
+ Qt::Orientation orientation) const Q_DECL_OVERRIDE;
+
+ virtual qreal perItemSpacing(QLayoutPolicy::ControlType control1,
+ QLayoutPolicy::ControlType control2,
+ Qt::Orientation orientation) const Q_DECL_OVERRIDE;
+
+ virtual qreal spacing(Qt::Orientation orientation) const Q_DECL_OVERRIDE;
+
+ virtual qreal windowMargin(Qt::Orientation orientation) const Q_DECL_OVERRIDE;
+
+ virtual void invalidate() Q_DECL_OVERRIDE
+ {
+ m_style = 0;
+ QAbstractLayoutStyleInfo::invalidate();
+ }
+
+ virtual bool hasChangedCore() const Q_DECL_OVERRIDE
+ {
+ QStyle *s = m_style;
+ // Note that style() will change m_style
+ return s != style();
+ }
+
+ QWidget *widget() const;
+ QStyle *style() const;
+
+private:
+ const QGraphicsLayoutPrivate *m_layout;
+ mutable QStyle *m_style;
+ QStyleOption m_styleOption;
+ QWidget *m_widget;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGRAPHICSLAYOUTSTYLEINFO_P_H \ No newline at end of file
diff --git a/src/widgets/graphicsview/qgraphicslinearlayout.cpp b/src/widgets/graphicsview/qgraphicslinearlayout.cpp
index 00076502ea..294905b986 100644
--- a/src/widgets/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/widgets/graphicsview/qgraphicslinearlayout.cpp
@@ -63,9 +63,9 @@
layout. The layout takes ownership of the items. In some cases when the layout
item also inherits from QGraphicsItem (such as QGraphicsWidget) there will be a
ambiguity in ownership because the layout item belongs to two ownership hierarchies.
- See the documentation of QGraphicsLayoutItem::setOwnedByLayout() how to handle
- this.
- You can access each item in the layout by calling count() and itemAt(). Calling
+ See the documentation of QGraphicsLayoutItem::setOwnedByLayout() how to handle
+ this.
+ You can access each item in the layout by calling count() and itemAt(). Calling
removeAt() or removeItem() will remove an item from the layout, without
destroying it.
@@ -122,7 +122,8 @@
#include "qgraphicslayoutitem.h"
#include "qgraphicslinearlayout.h"
#include "qgraphicswidget.h"
-#include "qgridlayoutengine_p.h"
+#include "qgraphicsgridlayoutengine_p.h"
+#include "qgraphicslayoutstyleinfo_p.h"
#ifdef QT_DEBUG
#include <QtCore/qdebug.h>
#endif
@@ -132,16 +133,20 @@ QT_BEGIN_NAMESPACE
class QGraphicsLinearLayoutPrivate : public QGraphicsLayoutPrivate
{
public:
- QGraphicsLinearLayoutPrivate(Qt::Orientation orientation) : orientation(orientation) { }
+ QGraphicsLinearLayoutPrivate(Qt::Orientation orientation)
+ : orientation(orientation),
+ m_styleInfo(0)
+ { }
void removeGridItem(QGridLayoutItem *gridItem);
- QLayoutStyleInfo styleInfo() const;
+ QGraphicsLayoutStyleInfo *styleInfo() const;
void fixIndex(int *index) const;
int gridRow(int index) const;
int gridColumn(int index) const;
Qt::Orientation orientation;
- QGridLayoutEngine engine;
+ mutable QGraphicsLayoutStyleInfo *m_styleInfo;
+ QGraphicsGridLayoutEngine engine;
};
void QGraphicsLinearLayoutPrivate::removeGridItem(QGridLayoutItem *gridItem)
@@ -172,13 +177,12 @@ int QGraphicsLinearLayoutPrivate::gridColumn(int index) const
return int(qMin(uint(index), uint(engine.columnCount())));
}
-Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget)
-
-QLayoutStyleInfo QGraphicsLinearLayoutPrivate::styleInfo() const
+QGraphicsLayoutStyleInfo *QGraphicsLinearLayoutPrivate::styleInfo() const
{
- QGraphicsItem *item = parentItem();
- QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
- return QLayoutStyleInfo(style, globalStyleInfoWidget());
+ if (!m_styleInfo)
+ m_styleInfo = new QGraphicsLayoutStyleInfo(this);
+ m_styleInfo->updateChanged(QAbstractLayoutStyleInfo::Unknown);
+ return m_styleInfo;
}
/*!
@@ -281,7 +285,8 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item)
Q_ASSERT(item);
d->fixIndex(&index);
d->engine.insertRow(index, d->orientation);
- new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index);
+ QGraphicsGridLayoutEngineItem *gridEngineItem = new QGraphicsGridLayoutEngineItem(item, d->gridRow(index), d->gridColumn(index), 1, 1, 0);
+ d->engine.insertItem(gridEngineItem, index);
invalidate();
}
@@ -309,7 +314,7 @@ void QGraphicsLinearLayout::insertStretch(int index, int stretch)
void QGraphicsLinearLayout::removeItem(QGraphicsLayoutItem *item)
{
Q_D(QGraphicsLinearLayout);
- if (QGridLayoutItem *gridItem = d->engine.findLayoutItem(item)) {
+ if (QGraphicsGridLayoutEngineItem *gridItem = d->engine.findLayoutItem(item)) {
item->setParentLayoutItem(0);
d->removeGridItem(gridItem);
delete gridItem;
@@ -330,7 +335,8 @@ void QGraphicsLinearLayout::removeAt(int index)
qWarning("QGraphicsLinearLayout::removeAt: invalid index %d", index);
return;
}
- if (QGridLayoutItem *gridItem = d->engine.itemAt(index)) {
+
+ if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem*>(d->engine.itemAt(index))) {
if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem())
layoutItem->setParentLayoutItem(0);
d->removeGridItem(gridItem);
@@ -365,7 +371,7 @@ void QGraphicsLinearLayout::setSpacing(qreal spacing)
qreal QGraphicsLinearLayout::spacing() const
{
Q_D(const QGraphicsLinearLayout);
- return d->engine.spacing(d->styleInfo(), d->orientation);
+ return d->engine.spacing(d->orientation, d->styleInfo());
}
/*!
@@ -485,7 +491,7 @@ QGraphicsLayoutItem *QGraphicsLinearLayout::itemAt(int index) const
return 0;
}
QGraphicsLayoutItem *item = 0;
- if (QGridLayoutItem *gridItem = d->engine.itemAt(index))
+ if (QGraphicsGridLayoutEngineItem *gridItem = static_cast<QGraphicsGridLayoutEngineItem *>(d->engine.itemAt(index)))
item = gridItem->layoutItem();
return item;
}
@@ -505,15 +511,15 @@ void QGraphicsLinearLayout::setGeometry(const QRectF &rect)
if (visualDir == Qt::RightToLeft)
qSwap(left, right);
effectiveRect.adjust(+left, +top, -right, -bottom);
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
if (qt_graphicsLayoutDebug()) {
static int counter = 0;
qDebug() << counter++ << "QGraphicsLinearLayout::setGeometry - " << rect;
dump(1);
}
#endif
- d->engine.setGeometries(d->styleInfo(), effectiveRect);
-#ifdef QT_DEBUG
+ d->engine.setGeometries(effectiveRect, d->styleInfo());
+#ifdef QGRIDLAYOUTENGINE_DEBUG
if (qt_graphicsLayoutDebug()) {
qDebug() << "post dump";
dump(1);
@@ -530,7 +536,7 @@ QSizeF QGraphicsLinearLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra
qreal left, top, right, bottom;
getContentsMargins(&left, &top, &right, &bottom);
const QSizeF extraMargins(left + right, top + bottom);
- return d->engine.sizeHint(d->styleInfo(), which , constraint - extraMargins) + extraMargins;
+ return d->engine.sizeHint(which , constraint - extraMargins, d->styleInfo()) + extraMargins;
}
/*!
@@ -540,6 +546,8 @@ void QGraphicsLinearLayout::invalidate()
{
Q_D(QGraphicsLinearLayout);
d->engine.invalidate();
+ if (d->m_styleInfo)
+ d->m_styleInfo->invalidate();
QGraphicsLayout::invalidate();
}
@@ -548,7 +556,7 @@ void QGraphicsLinearLayout::invalidate()
*/
void QGraphicsLinearLayout::dump(int indent) const
{
-#ifdef QT_DEBUG
+#ifdef QGRIDLAYOUTENGINE_DEBUG
if (qt_graphicsLayoutDebug()) {
Q_D(const QGraphicsLinearLayout);
qDebug("%*s%s layout", indent, "",
diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
index 0ed0b0ec3f..68944817f6 100644
--- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp
@@ -348,7 +348,7 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
// Run around the focus chain until we find a widget that can take tab focus.
if (!child) {
- child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
+ child = next ? (QWidget *)widget : widget->d_func()->focus_prev;
} else {
child = next ? child->d_func()->focus_next : child->d_func()->focus_prev;
if ((next && child == widget) || (!next && child == widget->d_func()->focus_prev)) {
@@ -363,7 +363,7 @@ QWidget *QGraphicsProxyWidgetPrivate::findFocusChild(QWidget *child, bool next)
uint focus_flag = qt_tab_all_widgets() ? Qt::TabFocus : Qt::StrongFocus;
do {
if (child->isEnabled()
- && child->isVisibleTo(widget)
+ && child->isVisibleTo(widget)
&& ((child->focusPolicy() & focus_flag) == focus_flag)
&& !(child->d_func()->extra && child->d_func()->extra->focus_proxy)) {
return child;
@@ -1324,17 +1324,17 @@ void QGraphicsProxyWidget::focusInEvent(QFocusEvent *event)
switch (event->reason()) {
case Qt::TabFocusReason: {
- if (QWidget *focusChild = d->findFocusChild(0, true))
+ if (QWidget *focusChild = d->findFocusChild(0, true))
focusChild->setFocus(event->reason());
break;
}
case Qt::BacktabFocusReason:
- if (QWidget *focusChild = d->findFocusChild(0, false))
+ if (QWidget *focusChild = d->findFocusChild(0, false))
focusChild->setFocus(event->reason());
break;
default:
- if (d->widget && d->widget->focusWidget()) {
- d->widget->focusWidget()->setFocus(event->reason());
+ if (d->widget && d->widget->focusWidget()) {
+ d->widget->focusWidget()->setFocus(event->reason());
}
break;
}
@@ -1371,8 +1371,8 @@ bool QGraphicsProxyWidget::focusNextPrevChild(bool next)
Qt::FocusReason reason = next ? Qt::TabFocusReason : Qt::BacktabFocusReason;
QWidget *lastFocusChild = d->widget->focusWidget();
if (QWidget *newFocusChild = d->findFocusChild(lastFocusChild, next)) {
- newFocusChild->setFocus(reason);
- return true;
+ newFocusChild->setFocus(reason);
+ return true;
}
return QGraphicsWidget::focusNextPrevChild(next);
diff --git a/src/widgets/graphicsview/qgraphicssceneindex.cpp b/src/widgets/graphicsview/qgraphicssceneindex.cpp
index 398e72e4c3..40f63937f4 100644
--- a/src/widgets/graphicsview/qgraphicssceneindex.cpp
+++ b/src/widgets/graphicsview/qgraphicssceneindex.cpp
@@ -67,12 +67,13 @@
QT_BEGIN_NAMESPACE
-class QGraphicsSceneIndexRectIntersector : public QGraphicsSceneIndexIntersector
-{
-public:
- bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
- const QTransform &deviceTransform) const
+namespace QtPrivate { // just to keep indentation of the following functions at the same level
+
+ static bool intersect_rect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform, const void *intersectData)
{
+ const QRectF sceneRect = *static_cast<const QRectF *>(intersectData);
+
QRectF brect = item->boundingRect();
_q_adjustRect(&brect);
@@ -117,15 +118,11 @@ public:
return keep;
}
- QRectF sceneRect;
-};
-
-class QGraphicsSceneIndexPointIntersector : public QGraphicsSceneIndexIntersector
-{
-public:
- bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
- const QTransform &deviceTransform) const
+ static bool intersect_point(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform, const void *intersectData)
{
+ const QPointF scenePoint = *static_cast<const QPointF *>(intersectData);
+
QRectF brect = item->boundingRect();
_q_adjustRect(&brect);
@@ -163,15 +160,11 @@ public:
return keep;
}
- QPointF scenePoint;
-};
-
-class QGraphicsSceneIndexPathIntersector : public QGraphicsSceneIndexIntersector
-{
-public:
- bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
- const QTransform &deviceTransform) const
+ static bool intersect_path(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform, const void *intersectData)
{
+ const QPainterPath scenePath = *static_cast<const QPainterPath *>(intersectData);
+
QRectF brect = item->boundingRect();
_q_adjustRect(&brect);
@@ -211,17 +204,13 @@ public:
return keep;
}
- QPainterPath scenePath;
-};
+} // namespace QtPrivate
/*!
Constructs a private scene index.
*/
QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) : scene(scene)
{
- pointIntersector = new QGraphicsSceneIndexPointIntersector;
- rectIntersector = new QGraphicsSceneIndexRectIntersector;
- pathIntersector = new QGraphicsSceneIndexPathIntersector;
}
/*!
@@ -229,9 +218,6 @@ QGraphicsSceneIndexPrivate::QGraphicsSceneIndexPrivate(QGraphicsScene *scene) :
*/
QGraphicsSceneIndexPrivate::~QGraphicsSceneIndexPrivate()
{
- delete pointIntersector;
- delete rectIntersector;
- delete pathIntersector;
}
/*!
@@ -268,11 +254,11 @@ bool QGraphicsSceneIndexPrivate::itemCollidesWithPath(const QGraphicsItem *item,
This function returns the items in ascending order.
*/
void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
- QGraphicsSceneIndexIntersector *intersector,
+ QGraphicsSceneIndexIntersector intersect,
QList<QGraphicsItem *> *items,
const QTransform &viewTransform,
Qt::ItemSelectionMode mode,
- qreal parentOpacity) const
+ qreal parentOpacity, const void *intersectData) const
{
Q_ASSERT(item);
if (!item->d_ptr->visible)
@@ -295,7 +281,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape);
bool processItem = !itemIsFullyTransparent;
if (processItem) {
- processItem = intersector->intersect(item, exposeRect, mode, viewTransform);
+ processItem = intersect(item, exposeRect, mode, viewTransform, intersectData);
if (!processItem && (!itemHasChildren || itemClipsChildrenToShape)) {
if (wasDirtyParentSceneTransform)
item->d_ptr->invalidateChildrenSceneTransform();
@@ -326,8 +312,8 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
break;
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
- recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
- mode, opacity);
+ recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
+ mode, opacity, intersectData);
}
}
@@ -343,8 +329,8 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe
child->d_ptr->dirtySceneTransform = 1;
if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity))
continue;
- recursive_items_helper(child, exposeRect, intersector, items, viewTransform,
- mode, opacity);
+ recursive_items_helper(child, exposeRect, intersect, items, viewTransform,
+ mode, opacity, intersectData);
}
}
}
@@ -419,8 +405,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPointF &pos, Qt::ItemSe
Q_D(const QGraphicsSceneIndex);
QList<QGraphicsItem *> itemList;
- d->pointIntersector->scenePoint = pos;
- d->items_helper(QRectF(pos, QSizeF(1, 1)), d->pointIntersector, &itemList, deviceTransform, mode, order);
+ d->items_helper(QRectF(pos, QSizeF(1, 1)), &QtPrivate::intersect_point, &itemList, deviceTransform, mode, order, &pos);
return itemList;
}
@@ -453,8 +438,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QRectF &rect, Qt::ItemSe
QRectF exposeRect = rect;
_q_adjustRect(&exposeRect);
QList<QGraphicsItem *> itemList;
- d->rectIntersector->sceneRect = rect;
- d->items_helper(exposeRect, d->rectIntersector, &itemList, deviceTransform, mode, order);
+ d->items_helper(exposeRect, &QtPrivate::intersect_rect, &itemList, deviceTransform, mode, order, &rect);
return itemList;
}
@@ -489,8 +473,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPolygonF &polygon, Qt::
_q_adjustRect(&exposeRect);
QPainterPath path;
path.addPolygon(polygon);
- d->pathIntersector->scenePath = path;
- d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order);
+ d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
return itemList;
}
@@ -523,8 +506,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::items(const QPainterPath &path, Qt::
QList<QGraphicsItem *> itemList;
QRectF exposeRect = path.controlPointRect();
_q_adjustRect(&exposeRect);
- d->pathIntersector->scenePath = path;
- d->items_helper(exposeRect, d->pathIntersector, &itemList, deviceTransform, mode, order);
+ d->items_helper(exposeRect, &QtPrivate::intersect_path, &itemList, deviceTransform, mode, order, &path);
return itemList;
}
diff --git a/src/widgets/graphicsview/qgraphicssceneindex_p.h b/src/widgets/graphicsview/qgraphicssceneindex_p.h
index 29b321fb1d..215fefe9b7 100644
--- a/src/widgets/graphicsview/qgraphicssceneindex_p.h
+++ b/src/widgets/graphicsview/qgraphicssceneindex_p.h
@@ -66,15 +66,14 @@ QT_BEGIN_NAMESPACE
#if !defined(QT_NO_GRAPHICSVIEW)
-class QGraphicsSceneIndexIntersector;
-class QGraphicsSceneIndexPointIntersector;
-class QGraphicsSceneIndexRectIntersector;
-class QGraphicsSceneIndexPathIntersector;
class QGraphicsSceneIndexPrivate;
class QPointF;
class QRectF;
template<typename T> class QList;
+typedef bool (*QGraphicsSceneIndexIntersector)(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
+ const QTransform &deviceTransform, const void *data);
+
class Q_AUTOTEST_EXPORT QGraphicsSceneIndex : public QObject
{
Q_OBJECT
@@ -133,27 +132,24 @@ public:
static bool itemCollidesWithPath(const QGraphicsItem *item, const QPainterPath &path, Qt::ItemSelectionMode mode);
void recursive_items_helper(QGraphicsItem *item, QRectF exposeRect,
- QGraphicsSceneIndexIntersector *intersector, QList<QGraphicsItem *> *items,
+ QGraphicsSceneIndexIntersector intersect, QList<QGraphicsItem *> *items,
const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, qreal parentOpacity = 1.0) const;
- inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector,
+ Qt::ItemSelectionMode mode, qreal parentOpacity, const void *intersectData) const;
+ inline void items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector intersect,
QList<QGraphicsItem *> *items, const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order) const;
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, const void *intersectData) const;
QGraphicsScene *scene;
- QGraphicsSceneIndexPointIntersector *pointIntersector;
- QGraphicsSceneIndexRectIntersector *rectIntersector;
- QGraphicsSceneIndexPathIntersector *pathIntersector;
};
-inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector *intersector,
+inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphicsSceneIndexIntersector intersect,
QList<QGraphicsItem *> *items, const QTransform &viewTransform,
- Qt::ItemSelectionMode mode, Qt::SortOrder order) const
+ Qt::ItemSelectionMode mode, Qt::SortOrder order, const void *intersectData) const
{
Q_Q(const QGraphicsSceneIndex);
const QList<QGraphicsItem *> tli = q->estimateTopLevelItems(rect, Qt::AscendingOrder);
for (int i = 0; i < tli.size(); ++i)
- recursive_items_helper(tli.at(i), rect, intersector, items, viewTransform, mode);
+ recursive_items_helper(tli.at(i), rect, intersect, items, viewTransform, mode, 1.0, intersectData);
if (order == Qt::DescendingOrder) {
const int n = items->size();
for (int i = 0; i < n / 2; ++i)
@@ -161,15 +157,6 @@ inline void QGraphicsSceneIndexPrivate::items_helper(const QRectF &rect, QGraphi
}
}
-class QGraphicsSceneIndexIntersector
-{
-public:
- QGraphicsSceneIndexIntersector() { }
- virtual ~QGraphicsSceneIndexIntersector() { }
- virtual bool intersect(const QGraphicsItem *item, const QRectF &exposeRect, Qt::ItemSelectionMode mode,
- const QTransform &deviceTransform) const = 0;
-};
-
#endif // QT_NO_GRAPHICSVIEW
QT_END_NAMESPACE
diff --git a/src/widgets/graphicsview/qsimplex_p.cpp b/src/widgets/graphicsview/qsimplex_p.cpp
index a2437d8ab1..cf023dc8f1 100644
--- a/src/widgets/graphicsview/qsimplex_p.cpp
+++ b/src/widgets/graphicsview/qsimplex_p.cpp
@@ -509,7 +509,7 @@ bool QSimplex::iterate()
Both solveMin and solveMax are interfaces to this method.
- The enum solverFactor admits 2 values: Minimum (-1) and Maximum (+1).
+ The enum SolverFactor admits 2 values: Minimum (-1) and Maximum (+1).
This method sets the original objective and runs the second phase
Simplex to obtain the optimal solution for the problem. As the internal
@@ -517,7 +517,7 @@ bool QSimplex::iterate()
minimization case by inverting the original objective and then
maximizing it.
*/
-qreal QSimplex::solver(solverFactor factor)
+qreal QSimplex::solver(SolverFactor factor)
{
// Remove old objective
clearRow(0);
diff --git a/src/widgets/graphicsview/qsimplex_p.h b/src/widgets/graphicsview/qsimplex_p.h
index 842044fa7f..8cb295e7ef 100644
--- a/src/widgets/graphicsview/qsimplex_p.h
+++ b/src/widgets/graphicsview/qsimplex_p.h
@@ -149,9 +149,10 @@ struct QSimplexConstraint
class QSimplex
{
+ Q_DISABLE_COPY(QSimplex)
public:
QSimplex();
- virtual ~QSimplex();
+ ~QSimplex();
qreal solveMin();
qreal solveMax();
@@ -163,8 +164,8 @@ public:
private:
// Matrix handling
- qreal valueAt(int row, int column);
- void setValueAt(int row, int column, qreal value);
+ inline qreal valueAt(int row, int column);
+ inline void setValueAt(int row, int column, qreal value);
void clearRow(int rowIndex);
void clearColumns(int first, int last);
void combineRows(int toIndex, int fromIndex, qreal factor);
@@ -179,8 +180,8 @@ private:
// Helpers
void clearDataStructures();
void solveMaxHelper();
- enum solverFactor { Minimum = -1, Maximum = 1 };
- qreal solver(solverFactor factor);
+ enum SolverFactor { Minimum = -1, Maximum = 1 };
+ qreal solver(SolverFactor factor);
void collectResults();
QList<QSimplexConstraint *> constraints;
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 7edad74f54..771753b7da 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -2939,14 +2939,13 @@ void QAbstractItemView::keyboardSearch(const QString &search)
}
// search from start with wraparound
- const QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
QModelIndex current = start;
QModelIndexList match;
QModelIndex firstMatch;
QModelIndex startMatch;
QModelIndexList previous;
do {
- match = d->model->match(current, Qt::DisplayRole, searchString);
+ match = d->model->match(current, Qt::DisplayRole, d->keyboardInput);
if (match == previous)
break;
firstMatch = match.value(0);
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 71697ddc40..b12ab736f4 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -53,8 +53,10 @@
#if defined(Q_OS_WIN)
# include <qt_windows.h>
-# include <commctrl.h>
-# include <objbase.h>
+# ifndef Q_OS_WINRT
+# include <commctrl.h>
+# include <objbase.h>
+# endif
#endif
#if defined(Q_OS_UNIX) && !defined(QT_NO_STYLE_GTK)
@@ -313,7 +315,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const
return retIcon;
if (info.isRoot())
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
{
UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16());
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 75a513fb67..f1bdfc8709 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -724,6 +724,22 @@ int QHeaderView::sectionViewportPosition(int logicalIndex) const
\sa sectionPosition()
*/
+template<typename Container>
+static void qMoveRange(Container& c,
+ typename Container::size_type rangeStart,
+ typename Container::size_type rangeEnd,
+ typename Container::size_type targetPosition)
+{
+ Q_ASSERT(targetPosition <= c.size());
+ Q_ASSERT(targetPosition < rangeStart || targetPosition >= rangeEnd);
+
+ const bool forwardMove = targetPosition > rangeStart;
+ typename Container::size_type first = std::min(rangeStart, targetPosition);
+ typename Container::size_type mid = forwardMove ? rangeEnd : rangeStart;
+ typename Container::size_type last = forwardMove ? targetPosition + 1 : rangeEnd;
+ std::rotate(c.begin() + first, c.begin() + mid, c.begin() + last);
+}
+
/*!
Moves the section at visual index \a from to occupy visual index \a to.
@@ -748,71 +764,32 @@ void QHeaderView::moveSection(int from, int to)
if (stretchLastSection() && to == d->lastVisibleVisualIndex())
d->lastSectionSize = sectionSize(from);
- //int oldHeaderLength = length(); // ### for debugging; remove later
d->initializeIndexMapping();
- QBitArray sectionHidden = d->sectionHidden;
int *visualIndices = d->visualIndices.data();
int *logicalIndices = d->logicalIndices.data();
int logical = logicalIndices[from];
int visual = from;
- int affected_count = qAbs(to - from) + 1;
- QVarLengthArray<int> sizes(affected_count);
- QVarLengthArray<ResizeMode> modes(affected_count);
-
- // move sections and indices
if (to > from) {
- sizes[to - from] = d->headerSectionSize(from);
- modes[to - from] = d->headerSectionResizeMode(from);
while (visual < to) {
- sizes[visual - from] = d->headerSectionSize(visual + 1);
- modes[visual - from] = d->headerSectionResizeMode(visual + 1);
- if (!sectionHidden.isEmpty())
- sectionHidden.setBit(visual, sectionHidden.testBit(visual + 1));
visualIndices[logicalIndices[visual + 1]] = visual;
logicalIndices[visual] = logicalIndices[visual + 1];
++visual;
}
} else {
- sizes[0] = d->headerSectionSize(from);
- modes[0] = d->headerSectionResizeMode(from);
while (visual > to) {
- sizes[visual - to] = d->headerSectionSize(visual - 1);
- modes[visual - to] = d->headerSectionResizeMode(visual - 1);
- if (!sectionHidden.isEmpty())
- sectionHidden.setBit(visual, sectionHidden.testBit(visual - 1));
visualIndices[logicalIndices[visual - 1]] = visual;
logicalIndices[visual] = logicalIndices[visual - 1];
--visual;
}
}
- if (!sectionHidden.isEmpty()) {
- sectionHidden.setBit(to, d->sectionHidden.testBit(from));
- d->sectionHidden = sectionHidden;
- }
visualIndices[logical] = to;
logicalIndices[to] = logical;
- //Q_ASSERT(oldHeaderLength == length());
- // move sizes
- // ### check for items of section sizes here
- if (to > from) {
- for (visual = from; visual <= to; ++visual) {
- int size = sizes[visual - from];
- ResizeMode mode = modes[visual - from];
- d->createSectionItems(visual, visual, size, mode);
- }
- } else {
- for (visual = to; visual <= from; ++visual) {
- int size = sizes[visual - to];
- ResizeMode mode = modes[visual - to];
- d->createSectionItems(visual, visual, size, mode);
- }
- }
- //Q_ASSERT(d->headerLength() == length());
- //Q_ASSERT(oldHeaderLength == length());
- //Q_ASSERT(d->logicalIndices.count() == d->sectionCount);
+ qMoveRange(d->sectionItems, from, from + 1, to);
+
+ d->sectionStartposRecalc = true;
if (d->hasAutoResizeSections())
d->doDelayedResizeSections();
@@ -860,11 +837,11 @@ void QHeaderView::swapSections(int first, int second)
d->visualIndices[secondLogical] = first;
d->logicalIndices[first] = secondLogical;
- if (!d->sectionHidden.isEmpty()) {
- bool firstHidden = d->sectionHidden.testBit(first);
- bool secondHidden = d->sectionHidden.testBit(second);
- d->sectionHidden.setBit(first, secondHidden);
- d->sectionHidden.setBit(second, firstHidden);
+ if (!d->hiddenSectionSize.isEmpty()) {
+ bool firstHidden = d->isVisualIndexHidden(first);
+ bool secondHidden = d->isVisualIndexHidden(second);
+ d->setVisualIndexHidden(first, secondHidden);
+ d->setVisualIndexHidden(second, firstHidden);
}
d->viewport->update();
@@ -992,11 +969,11 @@ bool QHeaderView::isSectionHidden(int logicalIndex) const
{
Q_D(const QHeaderView);
d->executePostedLayout();
- if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount())
+ if (d->hiddenSectionSize.isEmpty() || logicalIndex < 0 || logicalIndex >= d->sectionCount())
return false;
int visual = visualIndex(logicalIndex);
Q_ASSERT(visual != -1);
- return d->sectionHidden.testBit(visual);
+ return d->isVisualIndexHidden(visual);
}
/*!
@@ -1035,20 +1012,13 @@ void QHeaderView::setSectionHidden(int logicalIndex, bool hide)
if (!d->hasAutoResizeSections())
resizeSection(logicalIndex, 0);
d->hiddenSectionSize.insert(logicalIndex, size);
- if (d->sectionHidden.count() < count())
- d->sectionHidden.resize(count());
- d->sectionHidden.setBit(visual, true);
+ d->setVisualIndexHidden(visual, true);
if (d->hasAutoResizeSections())
d->doDelayedResizeSections();
} else {
int size = d->hiddenSectionSize.value(logicalIndex, d->defaultSectionSize);
d->hiddenSectionSize.remove(logicalIndex);
- if (d->hiddenSectionSize.isEmpty()) {
- d->sectionHidden.clear();
- } else {
- Q_ASSERT(visual <= d->sectionHidden.count());
- d->sectionHidden.setBit(visual, false);
- }
+ d->setVisualIndexHidden(visual, false);
resizeSection(logicalIndex, size);
}
}
@@ -1901,17 +1871,6 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
}
}
- // insert sections into sectionsHidden
- if (!d->sectionHidden.isEmpty()) {
- QBitArray sectionHidden(d->sectionHidden);
- sectionHidden.resize(sectionHidden.count() + insertCount);
- sectionHidden.fill(false, logicalFirst, logicalLast + 1);
- for (int j = logicalLast + 1; j < sectionHidden.count(); ++j)
- //here we simply copy the old sectionHidden
- sectionHidden.setBit(j, d->sectionHidden.testBit(j - insertCount));
- d->sectionHidden = sectionHidden;
- }
-
// insert sections into hiddenSectionSize
QHash<int, int> newHiddenSectionSize; // from logical index to section size
for (int i = 0; i < logicalFirst; ++i)
@@ -1960,19 +1919,6 @@ void QHeaderViewPrivate::updateHiddenSections(int logicalFirst, int logicalLast)
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());
- QBitArray newSectionHidden(newsize);
- for (int j = 0, k = 0; j < sectionHidden.size(); ++j) {
- const int logical = logicalIndex(j);
- if (logical < logicalFirst || logical > logicalLast) {
- newSectionHidden[k++] = sectionHidden[j];
- }
- }
- sectionHidden = newSectionHidden;
- }
}
void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
@@ -2061,8 +2007,11 @@ void QHeaderViewPrivate::_q_layoutAboutToBeChanged()
|| model->columnCount(root) == 0)
return;
- for (int i = 0; i < sectionHidden.count(); ++i)
- if (sectionHidden.testBit(i)) // ### note that we are using column or row 0
+ if (hiddenSectionSize.count() == 0)
+ return;
+
+ for (int i = 0; i < sectionItems.count(); ++i)
+ if (isVisualIndexHidden(i)) // ### note that we are using column or row 0
persistentHiddenSections.append(orientation == Qt::Horizontal
? model->index(0, logicalIndex(i), root)
: model->index(logicalIndex(i), 0, root));
@@ -2079,7 +2028,8 @@ void QHeaderViewPrivate::_q_layoutChanged()
return;
}
- QBitArray oldSectionHidden = sectionHidden;
+ QBitArray oldSectionHidden = sectionsHiddenToBitVector();
+ oldSectionHidden.resize(sectionItems.size());
bool sectionCountChanged = false;
for (int i = 0; i < persistentHiddenSections.count(); ++i) {
@@ -2193,8 +2143,6 @@ void QHeaderView::initializeSections(int start, int end)
d->stretchSections = newSectionCount;
else if (d->globalResizeMode == ResizeToContents)
d->contentsSections = newSectionCount;
- if (!d->sectionHidden.isEmpty())
- d->sectionHidden.resize(newSectionCount);
if (newSectionCount > oldCount)
d->createSectionItems(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode);
@@ -3385,7 +3333,6 @@ void QHeaderViewPrivate::clear()
visualIndices.clear();
logicalIndices.clear();
sectionSelected.clear();
- sectionHidden.clear();
hiddenSectionSize.clear();
sectionItems.clear();
invalidateCachedSizeHint();
@@ -3526,7 +3473,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
preventCursorChangeInSetOffset = true;
for (int i = 0; i < sectionItems.count(); ++i) {
QHeaderViewPrivate::SectionItem &section = sectionItems[i];
- if (sectionHidden.isEmpty() || !sectionHidden.testBit(i)) { // resize on not hidden.
+ if (hiddenSectionSize.isEmpty() || !isVisualIndexHidden(i)) { // resize on not hidden.
const int newSize = size;
if (newSize != section.size) {
length += newSize - section.size; //the whole length is changed
@@ -3629,11 +3576,11 @@ int QHeaderViewPrivate::viewSectionSizeHint(int logical) const
int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
{
- if (!sectionHidden.isEmpty()) {
+ if (!hiddenSectionSize.isEmpty()) {
int adjustedVisualIndex = visualIndex;
int currentVisualIndex = 0;
for (int i = 0; i < sectionItems.count(); ++i) {
- if (sectionHidden.testBit(i))
+ if (isVisualIndexHidden(i))
++adjustedVisualIndex;
else
++currentVisualIndex;
@@ -3669,7 +3616,7 @@ void QHeaderViewPrivate::write(QDataStream &out) const
out << visualIndices;
out << logicalIndices;
- out << sectionHidden;
+ out << sectionsHiddenToBitVector();
out << hiddenSectionSize;
out << length;
@@ -3706,6 +3653,7 @@ bool QHeaderViewPrivate::read(QDataStream &in)
in >> visualIndices;
in >> logicalIndices;
+ QBitArray sectionHidden;
in >> sectionHidden;
in >> hiddenSectionSize;
@@ -3739,6 +3687,7 @@ bool QHeaderViewPrivate::read(QDataStream &in)
newSectionItems.append(sectionItems[u]);
}
sectionItems = newSectionItems;
+ setHiddenSectionsFromBitVector(sectionHidden);
recalcSectionStartPos();
int tmpint;
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index b2af821e9b..81f1b176ee 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -171,11 +171,11 @@ public:
}
inline bool isVisualIndexHidden(int visual) const {
- return !sectionHidden.isEmpty() && sectionHidden.at(visual);
+ return sectionItems.at(visual).isHidden;
}
inline void setVisualIndexHidden(int visual, bool hidden) {
- if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden);
+ sectionItems[visual].isHidden = hidden;
}
inline bool hasAutoResizeSections() const {
@@ -258,7 +258,6 @@ public:
mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model
mutable QBitArray sectionSelected; // from logical index to bit
- mutable QBitArray sectionHidden; // from visual index to bit
mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
mutable QSize cachedSizeHint;
@@ -301,7 +300,7 @@ public:
struct SectionItem {
uint size : 20;
- uint reservedForIsHidden : 1;
+ uint isHidden : 1;
uint resizeMode : 5; // (holding QHeaderView::ResizeMode)
uint currentlyUnusedPadding : 6;
@@ -311,9 +310,9 @@ public:
int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
}; // to ensure that calculated_startpos will be calculated afterwards.
- inline SectionItem() : size(0), resizeMode(QHeaderView::Interactive) {}
+ inline SectionItem() : size(0), isHidden(0), resizeMode(QHeaderView::Interactive) {}
inline SectionItem(int length, QHeaderView::ResizeMode mode)
- : size(length), resizeMode(mode), calculated_startpos(-1) {}
+ : size(length), isHidden(0), resizeMode(mode), calculated_startpos(-1) {}
inline int sectionSize() const { return size; }
inline int calculatedEndPos() const { return calculated_startpos + size; }
#ifndef QT_NO_DATASTREAM
@@ -339,6 +338,23 @@ public:
return len;
}
+ QBitArray sectionsHiddenToBitVector() const
+ {
+ QBitArray sectionHidden;
+ if (!hiddenSectionSize.isEmpty()) {
+ sectionHidden.resize(sectionItems.size());
+ for (int u = 0; u < sectionItems.size(); ++u)
+ sectionHidden[u] = sectionItems.at(u).isHidden;
+ }
+ return sectionHidden;
+ }
+
+ void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden) {
+ SectionItem *sectionData = sectionItems.data();
+ for (int i = 0; i < sectionHidden.count(); ++i)
+ sectionData[i].isHidden = sectionHidden.at(i);
+ }
+
int headerSectionSize(int visual) const;
int headerSectionPosition(int visual) const;
int headerVisualIndexAt(int position) const;
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index b3ef21e3e5..b4e155c087 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -428,8 +428,8 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
/*!
\class QItemEditorCreator
\brief The QItemEditorCreator class makes it possible to create
- item editor creator bases without subclassing
- QItemEditorCreatorBase.
+ item editor creator bases without subclassing
+ QItemEditorCreatorBase.
\since 4.2
\ingroup model-view
@@ -450,7 +450,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
property, you should use QStandardItemEditorCreator instead.
\sa QItemEditorCreatorBase, QStandardItemEditorCreator,
- QItemEditorFactory, {Color Editor Factory Example}
+ QItemEditorFactory, {Color Editor Factory Example}
*/
/*!
@@ -506,7 +506,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
\snippet code/src_gui_itemviews_qitemeditorfactory.cpp 3
\sa QItemEditorCreatorBase, QItemEditorCreator,
- QItemEditorFactory, QItemDelegate, {Color Editor Factory Example}
+ QItemEditorFactory, QItemDelegate, {Color Editor Factory Example}
*/
/*!
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 43c1ea9cae..dd430435f3 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1353,8 +1353,8 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos)
Q_Q(QTreeView);
// we want to handle mousePress in EditingState (persistent editors)
if ((state != QAbstractItemView::NoState
- && state != QAbstractItemView::EditingState)
- || !viewport->rect().contains(pos))
+ && state != QAbstractItemView::EditingState)
+ || !viewport->rect().contains(pos))
return true;
int i = itemDecorationAt(pos);
@@ -1771,14 +1771,14 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
int x = 0;
if (!option.showDecorationSelected)
x = header->sectionPosition(0) + d->indentationForItem(d->current);
- QRect focusRect(x - header->offset(), y, header->length() - x, height);
+ QRect focusRect(x - header->offset(), y, header->length() - x, height);
o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), focusRect);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
// if we show focus on all columns and the first section is moved,
// we have to split the focus rect into two rects
if (allColumnsShowFocus && !option.showDecorationSelected
&& header->sectionsMoved() && (header->visualIndex(0) != 0)) {
- QRect sectionRect(0, y, header->sectionPosition(0), height);
+ QRect sectionRect(0, y, header->sectionPosition(0), height);
o.rect = style()->visualRect(layoutDirection(), d->viewport->rect(), sectionRect);
style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter);
}
@@ -1891,11 +1891,11 @@ void QTreeView::drawBranches(QPainter *painter, const QRect &rect,
*/
void QTreeView::mousePressEvent(QMouseEvent *event)
{
- Q_D(QTreeView);
+ Q_D(QTreeView);
bool handled = false;
if (style()->styleHint(QStyle::SH_ListViewExpand_SelectMouseType, 0, this) == QEvent::MouseButtonPress)
handled = d->expandOrCollapseItemAtPos(event->pos());
- if (!handled && d->itemDecorationAt(event->pos()) == -1)
+ if (!handled && d->itemDecorationAt(event->pos()) == -1)
QAbstractItemView::mousePressEvent(event);
}
@@ -2598,7 +2598,7 @@ void QTreeView::columnCountChanged(int oldCount, int newCount)
if (isVisible())
updateGeometries();
- viewport()->update();
+ viewport()->update();
}
/*!
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index e75f602e90..cd57b5828a 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -493,8 +493,7 @@ bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) {
beginRemoveRows(parent, row, row + count - 1);
- bool blockSignal = signalsBlocked();
- blockSignals(true);
+ QSignalBlocker blocker(this);
QTreeWidgetItem *itm = item(parent);
for (int i = row + count - 1; i >= row; --i) {
@@ -504,7 +503,7 @@ bool QTreeModel::removeRows(int row, int count, const QModelIndex &parent) {
delete child;
child = 0;
}
- blockSignals(blockSignal);
+ blocker.unblock();
endRemoveRows();
return true;
@@ -2824,7 +2823,7 @@ void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column)
\sa currentItem()
*/
void QTreeWidget::setCurrentItem(QTreeWidgetItem *item, int column,
- QItemSelectionModel::SelectionFlags command)
+ QItemSelectionModel::SelectionFlags command)
{
Q_D(QTreeWidget);
d->selectionModel->setCurrentIndex(d->index(item, column), command);
@@ -2860,7 +2859,7 @@ QRect QTreeWidget::visualItemRect(const QTreeWidgetItem *item) const
{
Q_D(const QTreeWidget);
//the visual rect for an item is across all columns. So we need to determine
- //what is the first and last column and get their visual index rects
+ //what is the first and last column and get their visual index rects
QModelIndex base = d->index(item);
const int firstVisiblesection = header()->logicalIndexAt(- header()->offset());
const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1);
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index 444b9b687f..857fe4ac91 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -79,3 +79,8 @@ wince*: {
SOURCES += \
kernel/qwidgetsfunctions_wince.cpp
}
+
+contains(QT_CONFIG, opengl) {
+ HEADERS += kernel/qopenglwidget_p.h
+ SOURCES += kernel/qopenglwidget.cpp
+}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index c9d6593662..9bc1576dc6 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -377,7 +377,6 @@ QPalette *QApplicationPrivate::set_pal = 0; // default palette set by pro
QFont *QApplicationPrivate::sys_font = 0; // default system font
QFont *QApplicationPrivate::set_font = 0; // default font set by programmer
-QIcon *QApplicationPrivate::app_icon = 0;
QWidget *QApplicationPrivate::main_widget = 0; // main application widget
QWidget *QApplicationPrivate::focus_widget = 0; // has keyboard input focus
QWidget *QApplicationPrivate::hidden_focus_widget = 0; // will get keyboard input focus after show()
@@ -446,7 +445,8 @@ void QApplicationPrivate::process_cmdline()
continue;
}
QByteArray arg = argv[i];
- arg = arg;
+ if (arg.startsWith("--"))
+ arg.remove(0, 1);
QString s;
if (arg == "-qdevel" || arg == "-qdebug") {
// obsolete argument
@@ -729,8 +729,6 @@ QApplication::~QApplication()
delete QApplicationPrivate::app_style;
QApplicationPrivate::app_style = 0;
- delete QApplicationPrivate::app_icon;
- QApplicationPrivate::app_icon = 0;
#ifndef QT_NO_DRAGANDDROP
if (qt_is_gui_used)
@@ -1560,6 +1558,7 @@ QString QApplicationPrivate::desktopStyleKey()
return QString();
}
+#if QT_VERSION < 0x060000 // remove these forwarders in Qt 6
/*!
\property QApplication::windowIcon
\brief the default window icon
@@ -1568,23 +1567,32 @@ QString QApplicationPrivate::desktopStyleKey()
*/
QIcon QApplication::windowIcon()
{
- return QApplicationPrivate::app_icon ? *QApplicationPrivate::app_icon : QIcon();
+ return QGuiApplication::windowIcon();
}
void QApplication::setWindowIcon(const QIcon &icon)
{
- if (!QApplicationPrivate::app_icon)
- QApplicationPrivate::app_icon = new QIcon();
- *QApplicationPrivate::app_icon = icon;
- if (QApplicationPrivate::is_app_running && !QApplicationPrivate::is_app_closing) {
- QEvent e(QEvent::ApplicationWindowIconChange);
- QWidgetList all = QApplication::allWidgets();
- for (QWidgetList::ConstIterator it = all.constBegin(); it != all.constEnd(); ++it) {
- QWidget *w = *it;
- if (w->isWindow())
- sendEvent(w, &e);
- }
+ QGuiApplication::setWindowIcon(icon);
+}
+#endif
+
+void QApplicationPrivate::notifyWindowIconChanged()
+{
+ QEvent ev(QEvent::ApplicationWindowIconChange);
+ const QWidgetList list = QApplication::topLevelWidgets();
+ QWindowList windowList = QGuiApplication::topLevelWindows();
+
+ // send to all top-level QWidgets
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ windowList.removeOne(w->windowHandle());
+ QCoreApplication::sendEvent(w, &ev);
}
+
+ // in case there are any plain QWindows in this QApplication-using
+ // application, also send the notification to them
+ for (int i = 0; i < windowList.size(); ++i)
+ QCoreApplication::sendEvent(windowList.at(i), &ev);
}
/*!
@@ -1725,6 +1733,41 @@ QFontMetrics QApplication::fontMetrics()
return desktop()->fontMetrics();
}
+bool QApplicationPrivate::tryCloseAllWidgetWindows(QWindowList *processedWindows)
+{
+ Q_ASSERT(processedWindows);
+ while (QWidget *w = QApplication::activeModalWidget()) {
+ if (!w->isVisible() || w->data->is_closing)
+ break;
+ QWindow *window = w->windowHandle();
+ if (!w->close()) // Qt::WA_DeleteOnClose may cause deletion.
+ return false;
+ if (window)
+ processedWindows->append(window);
+ }
+
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (w->isVisible() && w->windowType() != Qt::Desktop && !w->data->is_closing) {
+ QWindow *window = w->windowHandle();
+ if (!w->close()) // Qt::WA_DeleteOnClose may cause deletion.
+ return false;
+ if (window)
+ processedWindows->append(window);
+ list = QApplication::topLevelWidgets();
+ i = -1;
+ }
+ }
+ return true;
+}
+
+bool QApplicationPrivate::tryCloseAllWindows()
+{
+ QWindowList processedWindows;
+ return QApplicationPrivate::tryCloseAllWidgetWindows(&processedWindows)
+ && QGuiApplicationPrivate::tryCloseRemainingWindows(processedWindows);
+}
/*!
Closes all top-level windows.
@@ -1746,24 +1789,8 @@ QFontMetrics QApplication::fontMetrics()
*/
void QApplication::closeAllWindows()
{
- bool did_close = true;
- QWidget *w;
- while ((w = activeModalWidget()) && did_close) {
- if (!w->isVisible() || w->data->is_closing)
- break;
- did_close = w->close();
- }
- QWidgetList list = QApplication::topLevelWidgets();
- for (int i = 0; did_close && i < list.size(); ++i) {
- w = list.at(i);
- if (w->isVisible()
- && w->windowType() != Qt::Desktop
- && !w->data->is_closing) {
- did_close = w->close();
- list = QApplication::topLevelWidgets();
- i = -1;
- }
- }
+ QWindowList processedWindows;
+ QApplicationPrivate::tryCloseAllWidgetWindows(&processedWindows);
}
/*!
@@ -2611,7 +2638,7 @@ QDesktopWidget *QApplication::desktop()
void QApplication::setStartDragTime(int ms)
{
- Q_UNUSED(ms)
+ QGuiApplication::styleHints()->setStartDragTime(ms);
}
/*!
@@ -2644,7 +2671,7 @@ int QApplication::startDragTime()
void QApplication::setStartDragDistance(int l)
{
- Q_UNUSED(l);
+ QGuiApplication::styleHints()->setStartDragDistance(l);
}
/*!
@@ -2716,9 +2743,11 @@ bool QApplicationPrivate::shouldQuit()
QWindowList processedWindows;
for (int i = 0; i < list.size(); ++i) {
QWidget *w = list.at(i);
- processedWindows.push_back(w->windowHandle());
- if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose))
- return false;
+ if (QWindow *window = w->windowHandle()) { // Menus, popup widgets may not have a QWindow
+ processedWindows.push_back(window);
+ if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose))
+ return false;
+ }
}
return QGuiApplicationPrivate::shouldQuitInternal(processedWindows);
}
@@ -2767,6 +2796,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QApplicationPrivate::mouse_buttons |= me->button();
break;
}
+ case QEvent::MouseButtonDblClick:
+ {
+ QMouseEvent *me = static_cast<QMouseEvent*>(e);
+ QApplicationPrivate::modifier_buttons = me->modifiers();
+ QApplicationPrivate::mouse_buttons |= me->button();
+ break;
+ }
case QEvent::MouseButtonRelease:
{
QMouseEvent *me = static_cast<QMouseEvent*>(e);
@@ -2995,6 +3031,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
mouse->modifiers());
me.spont = mouse->spontaneous();
me.setTimestamp(mouse->timestamp());
+ QGuiApplicationPrivate::setMouseEventFlags(&me, mouse->flags());
// throw away any mouse-tracking-only mouse events
if (!w->hasMouseTracking()
&& mouse->type() == QEvent::MouseMove && mouse->buttons() == 0) {
@@ -3611,7 +3648,7 @@ bool QApplication::keypadNavigationEnabled()
*/
void QApplication::setCursorFlashTime(int msecs)
{
- Q_UNUSED(msecs);
+ QGuiApplication::styleHints()->setCursorFlashTime(msecs);
}
int QApplication::cursorFlashTime()
@@ -3626,12 +3663,10 @@ int QApplication::cursorFlashTime()
The default value on X11 is 400 milliseconds. On Windows and Mac OS, the
operating system's value is used.
-
- Setting the interval is not supported anymore in Qt 5.
*/
void QApplication::setDoubleClickInterval(int ms)
{
- Q_UNUSED(ms);
+ QGuiApplication::styleHints()->setMouseDoubleClickInterval(ms);
}
int QApplication::doubleClickInterval()
@@ -3659,7 +3694,7 @@ int QApplication::doubleClickInterval()
*/
void QApplication::setKeyboardInputInterval(int ms)
{
- Q_UNUSED(ms);
+ QGuiApplication::styleHints()->setKeyboardInputInterval(ms);
}
int QApplication::keyboardInputInterval()
@@ -3750,6 +3785,7 @@ void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEven
switch (event->type()) {
case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
case QEvent::TouchBegin:
if (setFocusOnRelease)
return;
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index 83673eef4e..9cd18d5cd9 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -126,10 +126,10 @@ public:
static void setFont(const QFont &, const char* className = 0);
static QFontMetrics fontMetrics();
+#if QT_VERSION < 0x060000 // remove these forwarders in Qt 6
static void setWindowIcon(const QIcon &icon);
static QIcon windowIcon();
-
-
+#endif
static QWidgetList allWidgets();
static QWidgetList topLevelWidgets();
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 29c6902c78..93c9ffe002 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -120,6 +120,7 @@ public:
virtual void notifyActiveWindowChange(QWindow *);
virtual bool shouldQuit();
+ bool tryCloseAllWindows() Q_DECL_OVERRIDE;
#if defined(Q_WS_X11)
#ifndef QT_NO_SETTINGS
@@ -137,6 +138,8 @@ public:
void createEventDispatcher();
static void dispatchEnterLeave(QWidget *enter, QWidget *leave, const QPointF &globalPosF);
+ void notifyWindowIconChanged() Q_DECL_OVERRIDE;
+
//modality
bool isWindowBlocked(QWindow *window, QWindow **blockingWindow = 0) const Q_DECL_OVERRIDE;
static bool isBlockedByModal(QWidget *widget);
@@ -144,7 +147,7 @@ public:
static bool tryModalHelper(QWidget *widget, QWidget **rettop = 0);
#ifdef Q_WS_MAC
static QWidget *tryModalHelper_sys(QWidget *top);
- bool canQuit();
+ bool canQuit();
#endif
bool notify_helper(QObject *receiver, QEvent * e);
@@ -198,7 +201,6 @@ public:
static QWidget *focus_widget;
static QWidget *hidden_focus_widget;
static QWidget *active_window;
- static QIcon *app_icon;
#ifndef QT_NO_WHEELEVENT
static int wheel_scroll_lines;
#endif
@@ -293,6 +295,7 @@ public:
QPixmap applyQIconStyleHelper(QIcon::Mode mode, const QPixmap& base) const;
private:
static QApplicationPrivate *self;
+ static bool tryCloseAllWidgetWindows(QWindowList *processedWindows);
static void giveFocusAccordingToFocusPolicy(QWidget *w, QEvent *event, QPoint localPos);
static bool shouldSetFocus(QWidget *w, Qt::FocusPolicy policy);
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 1f8e950d00..7977ae3528 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -451,7 +451,7 @@ void qt_init(QApplicationPrivate *priv, int type)
QApplicationPrivate::initializeWidgetFontHash();
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// #fixme: Remove.
static HDC displayDC = 0; // display device context
@@ -470,7 +470,7 @@ void qt_cleanup()
QColormap::cleanup();
QApplicationPrivate::active_window = 0; //### this should not be necessary
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
if (displayDC) {
ReleaseDC(0, displayDC);
displayDC = 0;
diff --git a/src/widgets/kernel/qformlayout.h b/src/widgets/kernel/qformlayout.h
index a1356c734f..0b8fd65a3f 100644
--- a/src/widgets/kernel/qformlayout.h
+++ b/src/widgets/kernel/qformlayout.h
@@ -143,7 +143,7 @@ public:
int rowCount() const;
#if 0
- void dump() const;
+ void dump() const;
#endif
private:
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
new file mode 100644
index 0000000000..a5f81a9df8
--- /dev/null
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopenglwidget_p.h"
+#include <QOpenGLContext>
+#include <QtWidgets/private/qwidget_p.h>
+
+#include <QOpenGLFramebufferObject>
+#include <QWindow>
+#include <qpa/qplatformwindow.h>
+#include <QDebug>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLWidgetPrivate : public QWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(QOpenGLWidget)
+public:
+ QOpenGLWidgetPrivate()
+ : fbo(0), uninitialized(true)
+ {
+ setRenderToTexture();
+ }
+ GLuint textureId() const { return fbo ? fbo->texture() : 0; }
+
+ const QSurface *surface() const { return q_func()->window()->windowHandle(); }
+ QSurface *surface() { return q_func()->window()->windowHandle(); }
+ void initialize();
+
+ QOpenGLContext context;
+ QOpenGLFramebufferObject *fbo;
+ bool uninitialized;
+
+ int w,h;
+};
+
+void QOpenGLWidgetPrivate::initialize()
+{
+ Q_Q(QOpenGLWidget);
+ if (!uninitialized)
+ return;
+ context.setShareContext(get(q->window())->shareContext());
+ context.setFormat(surface()->format());
+ context.create();
+ context.makeCurrent(surface());
+ q->initializeGL();
+ uninitialized = false;
+}
+
+QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)
+ : QWidget(*(new QOpenGLWidgetPrivate), parent, f)
+{
+}
+
+QOpenGLWidget::~QOpenGLWidget()
+{
+}
+
+bool QOpenGLWidget::isValid() const
+{
+ Q_D(const QOpenGLWidget);
+ return d->context.isValid();
+}
+
+void QOpenGLWidget::makeCurrent()
+{
+ Q_D(QOpenGLWidget);
+ d->context.makeCurrent(d->surface());
+ d->fbo->bind();
+}
+
+void QOpenGLWidget::doneCurrent()
+{
+ Q_D(QOpenGLWidget);
+ d->context.doneCurrent();
+}
+
+QSurfaceFormat QOpenGLWidget::format() const
+{
+ Q_D(const QOpenGLWidget);
+ return d->surface()->format();
+}
+
+GLuint QOpenGLWidget::defaultFramebufferObject() const
+{
+ Q_D(const QOpenGLWidget);
+ return d->fbo ? d->fbo->handle() : 0;
+}
+
+void QOpenGLWidget::initializeGL()
+{
+
+}
+
+void QOpenGLWidget::resizeGL(int w, int h)
+{
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+}
+
+void QOpenGLWidget::paintGL()
+{
+}
+
+void QOpenGLWidget::updateGL()
+{
+ makeCurrent();
+ paintGL();
+ glFlush();
+ doneCurrent();
+ update();
+}
+
+
+void QOpenGLWidget::resizeEvent(QResizeEvent *)
+{
+ Q_D(QOpenGLWidget);
+ d->w = width();
+ d->h = height();
+ d->initialize();
+
+ d->context.makeCurrent(d->surface());
+ delete d->fbo; // recreate when resized
+ d->fbo = new QOpenGLFramebufferObject(size());
+ d->fbo->bind();
+ glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ resizeGL(width(), height());
+ paintGL();
+ glFlush();
+}
+
+void QOpenGLWidget::paintEvent(QPaintEvent *)
+{
+ qWarning("QOpenGLWidget does not support paintEvent() yet.");
+ return;
+}
+
+QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qopenglwidget_p.h b/src/widgets/kernel/qopenglwidget_p.h
new file mode 100644
index 0000000000..1c7f0bfeec
--- /dev/null
+++ b/src/widgets/kernel/qopenglwidget_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWidgets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+#ifndef QOPENGLWIDGET_H
+#define QOPENGLWIDGET_H
+
+#include <QWidget>
+#include <QSurfaceFormat>
+
+#include <QtGui/qopengl.h>
+
+QT_BEGIN_NAMESPACE
+
+class QOpenGLWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QOpenGLWidget : public QWidget
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QOpenGLWidget)
+
+public:
+ explicit QOpenGLWidget(QWidget* parent=0,
+ Qt::WindowFlags f=0);
+
+// This API is not finalized yet. The commented-out functions below are
+// QGLWidget functions that have not been implemented for QOpenGLWidget.
+// Some of them may not end up in the final version (which is planned for a
+// future release of Qt).
+
+// explicit QOpenGLWidget(const QSurfaceFormat& format, QWidget* parent=0,
+// Qt::WindowFlags f=0);
+ ~QOpenGLWidget();
+
+// void qglClearColor(const QColor& c) const;
+
+ bool isValid() const;
+// bool isSharing() const;
+
+ void makeCurrent();
+ void doneCurrent();
+
+// void swapBuffers();
+
+ QSurfaceFormat format() const;
+ GLuint defaultFramebufferObject() const;
+
+// QPixmap renderPixmap(int w = 0, int h = 0, bool useContext = false);
+ QImage grabFrameBuffer(bool withAlpha = false);
+
+// static QImage convertToGLFormat(const QImage& img);
+
+// QPaintEngine *paintEngine() const;
+
+// void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
+// void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D);
+
+public Q_SLOTS:
+ void updateGL();
+
+protected:
+// bool event(QEvent *);
+ virtual void initializeGL();
+ virtual void resizeGL(int w, int h);
+ virtual void paintGL();
+
+// void setAutoBufferSwap(bool on);
+// bool autoBufferSwap() const;
+
+ void paintEvent(QPaintEvent*);
+ void resizeEvent(QResizeEvent*);
+
+// virtual void glInit();
+// virtual void glDraw();
+
+// QOpenGLWidget(QOpenGLWidgetPrivate &dd,
+// const QGLFormat &format = QGLFormat(),
+// QWidget *parent = 0,
+// const QOpenGLWidget* shareWidget = 0,
+// Qt::WindowFlags f = 0);
+private:
+ Q_DISABLE_COPY(QOpenGLWidget)
+
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QOPENGLWIDGET_H
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index ee7f779a3a..46aa93fe48 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -78,6 +78,7 @@
#include "private/qstyle_p.h"
#include "qfileinfo.h"
#include <QtGui/qinputmethod.h>
+#include <QtGui/qopenglcontext.h>
#include <private/qgraphicseffect_p.h>
#include <qbackingstore.h>
@@ -270,6 +271,8 @@ QWidgetPrivate::QWidgetPrivate(int version)
, isMoved(0)
, usesDoubleBufferedGLContext(0)
, mustHaveWindowHandle(0)
+ , renderToTexture(0)
+ , textureChildSeen(0)
#ifndef QT_NO_IM
, inheritsInputMethodHints(0)
#endif
@@ -353,10 +356,10 @@ void QWidgetPrivate::scrollChildren(int dx, int dy)
}
}
-void QWidgetPrivate::updateWidgetTransform()
+void QWidgetPrivate::updateWidgetTransform(QEvent *event)
{
Q_Q(QWidget);
- if (q == qGuiApp->focusObject()) {
+ if (q == qGuiApp->focusObject() || event->type() == QEvent::FocusIn) {
QTransform t;
QPoint p = q->mapTo(q->topLevelWidget(), QPoint(0,0));
t.translate(p.x(), p.y());
@@ -1188,7 +1191,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (++QWidgetPrivate::instanceCounter > QWidgetPrivate::maxInstances)
QWidgetPrivate::maxInstances = QWidgetPrivate::instanceCounter;
- if (QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation))
+ if (QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation)) // ### fixme: Qt 6: Remove AA_ImmediateWidgetCreation.
q->create();
QEvent e(QEvent::Create);
@@ -1558,6 +1561,7 @@ void QWidgetPrivate::createTLExtra()
x->inRepaint = false;
x->embedded = 0;
x->window = 0;
+ x->shareContext = 0;
x->screenIndex = 0;
#ifdef Q_WS_MAC
x->wasMaximized = false;
@@ -4178,7 +4182,7 @@ const QPalette &QWidget::palette() const
if (!isEnabled()) {
data->pal.setCurrentColorGroup(QPalette::Disabled);
} else if ((!isVisible() || isActiveWindow())
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
&& !QApplicationPrivate::isBlockedByModal(const_cast<QWidget *>(this))
#endif
) {
@@ -5133,9 +5137,17 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
<< "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
#endif
- //actually send the paint event
- QPaintEvent e(toBePainted);
- QCoreApplication::sendSpontaneousEvent(q, &e);
+ if (renderToTexture) {
+ // This widget renders into a texture which is composed later. We just need to
+ // punch a hole in the backingstore, so the texture will be visible.
+ QPainter p(q);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.fillRect(q->rect(), Qt::transparent);
+ } else {
+ //actually send the paint event
+ QPaintEvent e(toBePainted);
+ QCoreApplication::sendSpontaneousEvent(q, &e);
+ }
// Native widgets need to be marked dirty on screen so painting will be done in correct context
if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow()))
@@ -6747,12 +6759,25 @@ bool QWidget::restoreGeometry(const QByteArray &geometry)
if (maximized || fullScreen) {
// set geometry before setting the window state to make
// sure the window is maximized to the right screen.
- // Skip on windows: the window is restored into a broken
- // half-maximized state.
+ Qt::WindowStates ws = windowState();
#ifndef Q_OS_WIN
setGeometry(restoredNormalGeometry);
-#endif
- Qt::WindowStates ws = windowState();
+#else
+ if (ws & Qt::WindowFullScreen) {
+ // Full screen is not a real window state on Windows.
+ move(availableGeometry.topLeft());
+ } else if (ws & Qt::WindowMaximized) {
+ // Setting a geometry on an already maximized window causes this to be
+ // restored into a broken, half-maximized state, non-resizable state (QTBUG-4397).
+ // Move the window in normal state if needed.
+ if (restoredScreenNumber != desktop->screenNumber(this)) {
+ setWindowState(Qt::WindowNoState);
+ setGeometry(restoredNormalGeometry);
+ }
+ } else {
+ setGeometry(restoredNormalGeometry);
+ }
+#endif // Q_OS_WIN
if (maximized)
ws |= Qt::WindowMaximized;
if (fullScreen)
@@ -8058,7 +8083,7 @@ bool QWidget::event(QEvent *event)
break;
case QEvent::FocusIn:
focusInEvent((QFocusEvent*)event);
- d->updateWidgetTransform();
+ d->updateWidgetTransform(event);
break;
case QEvent::FocusOut:
@@ -8100,12 +8125,12 @@ bool QWidget::event(QEvent *event)
case QEvent::Move:
moveEvent((QMoveEvent*)event);
- d->updateWidgetTransform();
+ d->updateWidgetTransform(event);
break;
case QEvent::Resize:
resizeEvent((QResizeEvent*)event);
- d->updateWidgetTransform();
+ d->updateWidgetTransform(event);
break;
case QEvent::Close:
@@ -9479,27 +9504,36 @@ void QWidget::updateGeometry()
*/
void QWidget::setWindowFlags(Qt::WindowFlags flags)
{
- if (data->window_flags == flags)
- return;
-
Q_D(QWidget);
+ d->setWindowFlags(flags);
+}
+
+/*! \internal
+
+ Implemented in QWidgetPrivate so that QMdiSubWindowPrivate can reimplement it.
+*/
+void QWidgetPrivate::setWindowFlags(Qt::WindowFlags flags)
+{
+ Q_Q(QWidget);
+ if (q->data->window_flags == flags)
+ return;
- if ((data->window_flags | flags) & Qt::Window) {
+ if ((q->data->window_flags | flags) & Qt::Window) {
// the old type was a window and/or the new type is a window
- QPoint oldPos = pos();
- bool visible = isVisible();
- setParent(parentWidget(), flags);
+ QPoint oldPos = q->pos();
+ bool visible = q->isVisible();
+ q->setParent(q->parentWidget(), flags);
// if both types are windows or neither of them are, we restore
// the old position
- if (!((data->window_flags ^ flags) & Qt::Window)
- && (visible || testAttribute(Qt::WA_Moved))) {
- move(oldPos);
+ if (!((q->data->window_flags ^ flags) & Qt::Window)
+ && (visible || q->testAttribute(Qt::WA_Moved))) {
+ q->move(oldPos);
}
// for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
- d->adjustQuitOnCloseAttribute();
+ adjustQuitOnCloseAttribute();
} else {
- data->window_flags = flags;
+ q->data->window_flags = flags;
}
}
@@ -9615,6 +9649,13 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
if (desktopWidget)
parent = 0;
+#ifndef QT_NO_OPENGL
+ if (d->textureChildSeen && parent) {
+ // set the textureChildSeen flag up the whole parent chain
+ QWidgetPrivate::get(parent)->setTextureChildSeen();
+ }
+#endif
+
if (QWidgetBackingStore *oldBs = oldtlw->d_func()->maybeBackingStore()) {
if (newParent)
oldBs->removeDirtyWidget(this);
@@ -9623,6 +9664,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
oldBs->moveStaticWidgets(this);
}
+ // ### fixme: Qt 6: Remove AA_ImmediateWidgetCreation.
if (QApplicationPrivate::testAttribute(Qt::AA_ImmediateWidgetCreation) && !testAttribute(Qt::WA_WState_Created))
create();
@@ -11085,7 +11127,25 @@ void QWidgetPrivate::adjustQuitOnCloseAttribute()
}
}
-
+QOpenGLContext *QWidgetPrivate::shareContext() const
+{
+#ifdef QT_NO_OPENGL
+ return 0;
+#else
+ if (!extra || !extra->topextra || !extra->topextra->window) {
+ qWarning() << "Asking for share context for widget that does not have a window handle";
+ return 0;
+ }
+ QWidgetPrivate *that = const_cast<QWidgetPrivate *>(this);
+ if (!extra->topextra->shareContext) {
+ QOpenGLContext *ctx = new QOpenGLContext();
+ ctx->setFormat(extra->topextra->window->format());
+ ctx->create();
+ that->extra->topextra->shareContext = ctx;
+ }
+ return that->extra->topextra->shareContext;
+#endif // QT_NO_OPENGL
+}
Q_WIDGETS_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget)
{
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 943b7057b5..bdfc57f7c3 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -60,6 +60,7 @@
#include "QtCore/qset.h"
#include "QtGui/qregion.h"
#include "QtGui/qinputmethod.h"
+#include "QtGui/qopengl.h"
#include "QtWidgets/qsizepolicy.h"
#include "QtWidgets/qstyle.h"
#include "QtWidgets/qapplication.h"
@@ -80,6 +81,7 @@ class QPixmap;
class QWidgetBackingStore;
class QGraphicsProxyWidget;
class QWidgetItemV2;
+class QOpenGLContext;
class QStyle;
@@ -216,6 +218,7 @@ struct QTLWExtra {
bool wasMaximized;
#endif
QWidgetWindow *window;
+ QOpenGLContext *shareContext;
quint32 screenIndex; // index in qplatformscreenlist
};
@@ -324,6 +327,8 @@ public:
explicit QWidgetPrivate(int version = QObjectPrivateVersion);
~QWidgetPrivate();
+ static QWidgetPrivate *get(QWidget *w) { return w->d_func(); }
+
QWExtra *extraData() const;
QTLWExtra *topData() const;
QTLWExtra *maybeTopData() const;
@@ -438,7 +443,7 @@ public:
void syncBackingStore(const QRegion &region);
// tells the input method about the widgets transform
- void updateWidgetTransform();
+ void updateWidgetTransform(QEvent *event);
void reparentFocusWidgets(QWidget *oldtlw);
@@ -489,6 +494,7 @@ public:
void setWindowTitle_helper(const QString &cap);
void setWindowFilePath_helper(const QString &filePath);
void setWindowModified_helper();
+ virtual void setWindowFlags(Qt::WindowFlags windowFlags);
bool setMinimumSize_helper(int &minw, int &minh);
bool setMaximumSize_helper(int &maxw, int &maxh);
@@ -537,6 +543,8 @@ public:
}
}
}
+#else
+ Q_UNUSED(widget);
#endif
return screen;
}
@@ -615,6 +623,27 @@ public:
inline QRect mapFromWS(const QRect &r) const
{ QRect rr(r); rr.translate(data.wrect.topLeft()); return rr; }
+ QOpenGLContext *shareContext() const;
+
+#ifndef QT_NO_OPENGL
+ virtual GLuint textureId() const { return 0; }
+
+ void setRenderToTexture() { renderToTexture = true; textureChildSeen = true; }
+ void setTextureChildSeen()
+ {
+ Q_Q(QWidget);
+ if (textureChildSeen)
+ return;
+ textureChildSeen = 1;
+
+ if (!q->isWindow()) {
+ QWidget *parent = q->parentWidget();
+ if (parent)
+ get(parent)->setTextureChildSeen();
+ }
+ }
+#endif
+
// Variables.
// Regular pointers (keep them together to avoid gaps on 64 bit architectures).
QWExtra *extra;
@@ -695,6 +724,8 @@ public:
uint isMoved : 1;
uint usesDoubleBufferedGLContext : 1;
uint mustHaveWindowHandle : 1;
+ uint renderToTexture : 1;
+ uint textureChildSeen : 1;
#ifndef QT_NO_IM
uint inheritsInputMethodHints : 1;
#endif
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index 0a4bc990e6..c2260b6e7d 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -49,6 +49,7 @@
#include "QtWidgets/qdesktopwidget.h"
#include <qpa/qplatformwindow.h>
#include "QtGui/qsurfaceformat.h"
+#include <QtGui/qopenglcontext.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
#include "QtGui/private/qwindow_p.h"
@@ -953,6 +954,10 @@ void QWidgetPrivate::deleteTLSysExtra()
delete extra->topextra->backingStore;
extra->topextra->backingStore = 0;
+#ifndef QT_NO_OPENGL
+ delete extra->topextra->shareContext;
+ extra->topextra->shareContext = 0;
+#endif
}
}
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 4a94cd6cb8..dc918657b4 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -57,6 +57,8 @@
#include <private/qpaintengine_raster_p.h>
#include <private/qgraphicseffect_p.h>
+#include <qpa/qplatformbackingstore.h>
+
#if defined(Q_OS_WIN) && !defined(QT_NO_PAINT_DEBUG)
# include <QtCore/qt_windows.h>
# include <qpa/qplatformnativeinterface.h>
@@ -72,10 +74,15 @@ extern QRegion qt_dirtyRegion(QWidget *);
* \a region is the region to be updated in \a widget coordinates.
*/
static inline void qt_flush(QWidget *widget, const QRegion &region, QBackingStore *backingStore,
- QWidget *tlw, const QPoint &tlwOffset)
+ QWidget *tlw, const QPoint &tlwOffset, QPlatformTextureList *widgetTextures = 0,
+ QOpenGLContext *context = 0)
{
+#ifdef QT_NO_OPENGL
+ Q_UNUSED(widgetTextures);
+ Q_UNUSED(context);
+#endif
Q_ASSERT(widget);
- Q_ASSERT(!region.isEmpty());
+ Q_ASSERT(!region.isEmpty() || (context && widgetTextures && widgetTextures->count()));
Q_ASSERT(backingStore);
Q_ASSERT(tlw);
@@ -104,14 +111,20 @@ static inline void qt_flush(QWidget *widget, const QRegion &region, QBackingStor
if (tlw->testAttribute(Qt::WA_DontShowOnScreen) || widget->testAttribute(Qt::WA_DontShowOnScreen))
return;
+ QPoint offset = tlwOffset;
if (widget != tlw)
- backingStore->flush(region, widget->windowHandle(), tlwOffset + widget->mapTo(tlw, QPoint()));
+ offset += widget->mapTo(tlw, QPoint());
+
+#ifndef QT_NO_OPENGL
+ if (widgetTextures)
+ backingStore->handle()->composeAndFlush(widget->windowHandle(), region, offset, widgetTextures, context);
else
- backingStore->flush(region, widget->windowHandle(), tlwOffset);
+#endif
+ backingStore->flush(region, widget->windowHandle(), offset);
}
#ifndef QT_NO_PAINT_DEBUG
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec)
{
@@ -151,7 +164,7 @@ static void showYellowThing_win(QWidget *widget, const QRegion &region, int msec
QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("releaseDC"), nativeWindow);
::Sleep(msec);
}
-#endif // Q_OS_WIN
+#endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePainted, int msec, bool unclipped)
{
@@ -166,7 +179,7 @@ void QWidgetBackingStore::showYellowThing(QWidget *widget, const QRegion &toBePa
widget = nativeParent;
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
Q_UNUSED(unclipped);
showYellowThing_win(widget, paintRegion, msec);
#else
@@ -430,7 +443,7 @@ QRegion QWidgetBackingStore::staticContents(QWidget *parent, const QRect &within
return region;
}
-static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
+void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, bool updateImmediately)
{
if (!widget)
return;
@@ -439,6 +452,7 @@ static inline void sendUpdateRequest(QWidget *widget, bool updateImmediately)
QEvent event(QEvent::UpdateRequest);
QApplication::sendEvent(widget, &event);
} else {
+ updateRequestSent = true;
QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
}
}
@@ -488,6 +502,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
return;
}
+ //### FIXME fullUpdatePending seems to be always false????
if (fullUpdatePending) {
if (updateImmediately)
sendUpdateRequest(tlw, updateImmediately);
@@ -495,6 +510,13 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
}
const QPoint offset = widget->mapTo(tlw, QPoint());
+
+ if (QWidgetPrivate::get(widget)->renderToTexture) {
+ if (!updateRequestSent || updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
const QRect widgetRect = widget->d_func()->effectiveRectFor(widget->rect());
if (qt_region_strictContains(dirty, widgetRect.translated(offset))) {
if (updateImmediately)
@@ -503,7 +525,7 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, bool up
}
if (invalidateBuffer) {
- const bool eventAlreadyPosted = !dirty.isEmpty();
+ const bool eventAlreadyPosted = !dirty.isEmpty() || updateRequestSent;
#ifndef QT_NO_GRAPHICSEFFECT
if (widget->d_func()->graphicsEffect)
dirty += widget->d_func()->effectiveRectFor(rgn.boundingRect()).translated(offset);
@@ -583,6 +605,13 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, bool upd
return;
}
+ if (QWidgetPrivate::get(widget)->renderToTexture) {
+ if (!updateRequestSent || updateImmediately)
+ sendUpdateRequest(tlw, updateImmediately);
+ return;
+ }
+
+
const QRect widgetRect = widget->d_func()->effectiveRectFor(rect);
const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint())));
if (qt_region_strictContains(dirty, translatedRect)) {
@@ -703,7 +732,12 @@ void QWidgetBackingStore::updateLists(QWidget *cur)
}
QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
- : tlw(topLevel), dirtyOnScreenWidgets(0), fullUpdatePending(0)
+ : tlw(topLevel),
+ dirtyOnScreenWidgets(0),
+ widgetTextures(0),
+ fullUpdatePending(0),
+ updateRequestSent(0),
+ textureListWatcher(0)
{
store = tlw->backingStore();
Q_ASSERT(store);
@@ -892,17 +926,17 @@ static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedRegion)
{
QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
- if (discardSyncRequest(tlw, tlwExtra) || tlwExtra->inTopLevelResize)
+ if (!tlw->isVisible() || !tlwExtra || tlwExtra->inTopLevelResize)
return;
- if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible()
+ if (!exposedWidget || !exposedWidget->internalWinId() || !exposedWidget->isVisible() || !exposedWidget->testAttribute(Qt::WA_Mapped)
|| !exposedWidget->updatesEnabled() || exposedRegion.isEmpty()) {
return;
}
// Nothing to repaint.
if (!isDirty()) {
- qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset);
+ qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTextures, tlw->d_func()->shareContext());
return;
}
@@ -910,7 +944,42 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint()));
else
markDirtyOnScreen(exposedRegion, exposedWidget, QPoint());
- sync();
+
+ doSync();
+}
+
+#ifndef QT_NO_OPENGL
+static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatformTextureList *widgetTextures)
+{
+ QWidgetPrivate *wd = QWidgetPrivate::get(widget);
+ if (wd->renderToTexture)
+ widgetTextures->appendTexture(wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()));
+
+ for (int i = 0; i < wd->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(wd->children.at(i));
+ if (w && !w->isWindow() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
+ findTextureWidgetsRecursively(tlw, w, widgetTextures);
+ }
+}
+#endif
+
+QPlatformTextureListWatcher::QPlatformTextureListWatcher(QWidgetBackingStore *backingStore)
+ : m_locked(false),
+ m_backingStore(backingStore)
+{
+}
+
+void QPlatformTextureListWatcher::watch(QPlatformTextureList *textureList)
+{
+ connect(textureList, SIGNAL(locked(bool)), SLOT(onLockStatusChanged(bool)));
+ m_locked = textureList->isLocked();
+}
+
+void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
+{
+ m_locked = locked;
+ if (!locked)
+ m_backingStore->sync();
}
/*!
@@ -918,6 +987,7 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
*/
void QWidgetBackingStore::sync()
{
+ updateRequestSent = false;
QTLWExtra *tlwExtra = tlw->d_func()->maybeTopData();
if (discardSyncRequest(tlw, tlwExtra)) {
// If the top-level is minimized, it's not visible on the screen so we can delay the
@@ -935,10 +1005,26 @@ void QWidgetBackingStore::sync()
return;
}
+ if (textureListWatcher && !textureListWatcher->isLocked()) {
+ textureListWatcher->deleteLater();
+ textureListWatcher = 0;
+ } else if (widgetTextures && widgetTextures->isLocked()) {
+ if (!textureListWatcher)
+ textureListWatcher = new QPlatformTextureListWatcher(this);
+ if (!textureListWatcher->isLocked())
+ textureListWatcher->watch(widgetTextures);
+ return;
+ }
+
+ doSync();
+}
+
+void QWidgetBackingStore::doSync()
+{
const bool updatesDisabled = !tlw->updatesEnabled();
bool repaintAllWidgets = false;
- const bool inTopLevelResize = tlwExtra->inTopLevelResize;
+ const bool inTopLevelResize = tlw->d_func()->maybeTopData()->inTopLevelResize;
const QRect tlwRect(topLevelRect());
const QRect surfaceGeometry(tlwRect.topLeft(), store->size());
if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
@@ -1018,7 +1104,15 @@ void QWidgetBackingStore::sync()
}
dirtyWidgets.clear();
+#ifndef QT_NO_OPENGL
+ delete widgetTextures;
+ widgetTextures = 0;
+ if (tlw->d_func()->textureChildSeen) {
+ widgetTextures = new QPlatformTextureList;
+ findTextureWidgetsRecursively(tlw, tlw, widgetTextures);
+ }
fullUpdatePending = false;
+#endif
if (toClean.isEmpty()) {
// Nothing to repaint. However, we might have newly exposed areas on the
@@ -1032,6 +1126,7 @@ void QWidgetBackingStore::sync()
if (tlw->d_func()->extra->proxyWidget) {
updateStaticContentsSize();
dirty = QRegion();
+ updateRequestSent = false;
const QVector<QRect> rects(toClean.rects());
for (int i = 0; i < rects.size(); ++i)
tlw->d_func()->extra->proxyWidget->update(rects.at(i));
@@ -1045,6 +1140,7 @@ void QWidgetBackingStore::sync()
for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i)
resetWidget(opaqueNonOverlappedWidgets[i]);
dirty = QRegion();
+ updateRequestSent = false;
return;
}
@@ -1053,6 +1149,7 @@ void QWidgetBackingStore::sync()
updateStaticContentsSize();
const QRegion dirtyCopy(dirty);
dirty = QRegion();
+ updateRequestSent = false;
// Paint opaque non overlapped widgets.
for (int i = 0; i < opaqueNonOverlappedWidgets.size(); ++i) {
@@ -1093,12 +1190,19 @@ void QWidgetBackingStore::flush(QWidget *widget)
{
if (!dirtyOnScreen.isEmpty()) {
QWidget *target = widget ? widget : tlw;
- qt_flush(target, dirtyOnScreen, store, tlw, tlwOffset);
+ qt_flush(target, dirtyOnScreen, store, tlw, tlwOffset, widgetTextures, tlw->d_func()->shareContext());
dirtyOnScreen = QRegion();
}
- if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty())
+ if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty()) {
+#ifndef QT_NO_OPENGL
+ if (widgetTextures && widgetTextures->count()) {
+ QWidget *target = widget ? widget : tlw;
+ qt_flush(target, QRegion(), store, tlw, tlwOffset, widgetTextures, tlw->d_func()->shareContext());
+ }
+#endif
return;
+ }
for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
QWidget *w = dirtyOnScreenWidgets->at(i);
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index b6c3e13cb0..2fe58fa4a7 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -60,6 +60,9 @@
QT_BEGIN_NAMESPACE
+class QPlatformTextureList;
+class QWidgetBackingStore;
+
struct BeginPaintInfo {
inline BeginPaintInfo() : wasFlushed(0), nothingToPaint(0), backingStoreRecreated(0) {}
uint wasFlushed : 1;
@@ -67,6 +70,23 @@ struct BeginPaintInfo {
uint backingStoreRecreated : 1;
};
+class QPlatformTextureListWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ QPlatformTextureListWatcher(QWidgetBackingStore *backingStore);
+ void watch(QPlatformTextureList *textureList);
+ bool isLocked() const { return m_locked; }
+
+private slots:
+ void onLockStatusChanged(bool locked);
+
+private:
+ bool m_locked;
+ QWidgetBackingStore *m_backingStore;
+};
+
class Q_AUTOTEST_EXPORT QWidgetBackingStore
{
public:
@@ -102,14 +122,21 @@ private:
QVector<QWidget *> dirtyWidgets;
QVector<QWidget *> *dirtyOnScreenWidgets;
QList<QWidget *> staticWidgets;
+ QPlatformTextureList *widgetTextures;
QBackingStore *store;
uint fullUpdatePending : 1;
+ uint updateRequestSent : 1;
QPoint tlwOffset;
+ QPlatformTextureListWatcher *textureListWatcher;
+
+ void sendUpdateRequest(QWidget *widget, bool updateImmediately);
+
static bool flushPaint(QWidget *widget, const QRegion &rgn);
static void unflushPaint(QWidget *widget, const QRegion &rgn);
+ void doSync();
bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);
void releaseBuffer();
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 167102c633..0e40dd866f 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -50,6 +50,7 @@
#include <private/qwidgetbackingstore_p.h>
#include <qpa/qwindowsysteminterface_p.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformwindow.h>
#include <private/qgesturemanager_p.h>
QT_BEGIN_NAMESPACE
@@ -91,6 +92,12 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
, m_widget(widget)
{
updateObjectName();
+ // Enable QOpenGLWidget/QQuickWidget children if the platform plugin supports it,
+ // and the application developer has not explicitly disabled it.
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::RasterGLSurface)
+ && !QApplication::testAttribute(Qt::AA_ForceRasterWidgets)) {
+ setSurfaceType(QSurface::RasterGLSurface);
+ }
connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName);
}
@@ -473,7 +480,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!widget)
widget = m_widget;
- if (event->type() == QEvent::MouseButtonPress)
+ if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
qt_button_down = widget;
QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
@@ -484,12 +491,17 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
QApplicationPrivate::mouse_buttons &= ~event->button();
return;
}
-
- QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers());
- translated.setTimestamp(event->timestamp());
- QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget, &qt_button_down,
- qt_last_mouse_receiver);
-
+ if ((event->type() != QEvent::MouseButtonPress)
+ || !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {
+
+ // The preceding statement excludes MouseButtonPress events which caused
+ // creation of a MouseButtonDblClick event. QTBUG-25831
+ QMouseEvent translated(event->type(), mapped, event->windowPos(), event->screenPos(),
+ event->button(), event->buttons(), event->modifiers());
+ translated.setTimestamp(event->timestamp());
+ QApplicationPrivate::sendMouseEvent(receiver, &translated, widget, m_widget,
+ &qt_button_down, qt_last_mouse_receiver);
+ }
#ifndef QT_NO_CONTEXTMENU
if (event->type() == contextMenuTrigger && event->button() == Qt::RightButton) {
QContextMenuEvent e(QContextMenuEvent::Mouse, mapped, event->globalPos(), event->modifiers());
@@ -542,6 +554,24 @@ void QWidgetWindow::updateGeometry()
m_widget->data->fstrut_dirty = false;
}
+Qt::WindowState effectiveState(Qt::WindowStates state);
+
+// Store normal geometry used for saving application settings.
+void QWidgetWindow::updateNormalGeometry()
+{
+ QTLWExtra *tle = m_widget->d_func()->maybeTopData();
+ if (!tle)
+ return;
+ // Ask platform window, default to widget geometry.
+ QRect normalGeometry;
+ if (const QPlatformWindow *pw = handle())
+ normalGeometry = pw->normalGeometry();
+ if (!normalGeometry.isValid() && effectiveState(m_widget->windowState()) == Qt::WindowNoState)
+ normalGeometry = m_widget->geometry();
+ if (normalGeometry.isValid())
+ tle->normalGeometry = normalGeometry;
+}
+
void QWidgetWindow::handleMoveEvent(QMoveEvent *event)
{
updateGeometry();
@@ -654,6 +684,11 @@ void QWidgetWindow::handleDragLeaveEvent(QDragLeaveEvent *event)
void QWidgetWindow::handleDropEvent(QDropEvent *event)
{
+ if (m_dragTarget.isNull()) {
+ qWarning() << Q_FUNC_INFO << m_widget << ": No drag target set.";
+ event->ignore();
+ return;
+ }
const QPoint mapped = m_dragTarget.data()->mapFromGlobal(m_widget->mapToGlobal(event->pos()));
QDropEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers());
QGuiApplication::sendSpontaneousEvent(m_dragTarget.data(), &translated);
@@ -682,8 +717,6 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event)
}
}
-Qt::WindowState effectiveState(Qt::WindowStates state);
-
void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event)
{
// QWindow does currently not know 'active'.
@@ -702,16 +735,12 @@ void QWidgetWindow::handleWindowStateChangedEvent(QWindowStateChangeEvent *event
widgetState |= Qt::WindowMinimized;
break;
case Qt::WindowMaximized:
- if (effectiveState(widgetState) == Qt::WindowNoState)
- if (QTLWExtra *tle = m_widget->d_func()->maybeTopData())
- tle->normalGeometry = m_widget->geometry();
+ updateNormalGeometry();
widgetState |= Qt::WindowMaximized;
widgetState &= ~(Qt::WindowMinimized | Qt::WindowFullScreen);
break;
case Qt::WindowFullScreen:
- if (effectiveState(widgetState) == Qt::WindowNoState)
- if (QTLWExtra *tle = m_widget->d_func()->maybeTopData())
- tle->normalGeometry = m_widget->geometry();
+ updateNormalGeometry();
widgetState |= Qt::WindowFullScreen;
widgetState &= ~(Qt::WindowMinimized);
break;
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
index ffde44dd27..8d6f14a669 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -104,6 +104,7 @@ private slots:
private:
void updateGeometry();
+ void updateNormalGeometry();
enum FocusWidgets {
FirstFocusWidget,
diff --git a/src/widgets/kernel/win.pri b/src/widgets/kernel/win.pri
index d5cba740d1..76bb709e2b 100644
--- a/src/widgets/kernel/win.pri
+++ b/src/widgets/kernel/win.pri
@@ -2,6 +2,6 @@
# --------------------------------------------------------------------
INCLUDEPATH += ../3rdparty/wintab
-!wince* {
+!wince*:!winrt {
LIBS_PRIVATE *= -lshell32
}
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 79a52c00cb..d8530bca1e 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -143,8 +143,6 @@ const int QMacStylePrivate::SmallButtonH = 30;
const int QMacStylePrivate::BevelButtonW = 50;
const int QMacStylePrivate::BevelButtonH = 22;
const int QMacStylePrivate::PushButtonContentPadding = 6;
-const qreal QMacStylePrivate::ScrollBarFadeOutDuration = 200.0;
-const qreal QMacStylePrivate::ScrollBarFadeOutDelay = 450.0;
QSet<QPointer<QObject> > QMacStylePrivate::scrollBars;
@@ -5049,24 +5047,23 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
styleObject->setProperty("_q_stylestate", static_cast<int>(slider->state));
styleObject->setProperty("_q_stylecontrols", static_cast<uint>(slider->activeSubControls));
- QScrollbarAnimation *anim = qobject_cast<QScrollbarAnimation *>(d->animation(styleObject));
+ QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
if (transient) {
if (!anim) {
- anim = new QScrollbarAnimation(styleObject);
- anim->setFadingOut();
+ anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Deactivating, styleObject);
d->startAnimation(anim);
- } else if (anim->isFadingOut()) {
+ } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) {
// the scrollbar was already fading out while the
// state changed -> restart the fade out animation
anim->setCurrentTime(0);
}
- } else if (anim && anim->isFadingOut()) {
+ } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
d->stopAnimation(styleObject);
}
}
- QScrollbarAnimation *anim = qobject_cast<QScrollbarAnimation *>(d->animation(styleObject));
- if (anim && anim->isFadingOut()) {
+ QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
+ if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
// once a scrollbar was active (hovered/pressed), it retains
// the active look even if it's no longer active while fading out
if (oldActiveControls)
@@ -5080,11 +5077,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
if (shouldExpand) {
if (!anim && !oldActiveControls) {
// Start expand animation only once and when entering
- anim = new QScrollbarAnimation(styleObject);
- anim->setExpanding();
+ anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Activating, styleObject);
d->startAnimation(anim);
}
- if (anim && !anim->isFadingOut()) {
+ if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) {
expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue();
expandOffset = 5.5 * anim->currentValue() - 1;
} else {
diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h
index efeaa66e39..6f42f0ea79 100644
--- a/src/widgets/styles/qmacstyle_mac_p_p.h
+++ b/src/widgets/styles/qmacstyle_mac_p_p.h
@@ -156,8 +156,6 @@ public:
static const int BevelButtonW;
static const int BevelButtonH;
static const int PushButtonContentPadding;
- static const qreal ScrollBarFadeOutDuration;
- static const qreal ScrollBarFadeOutDelay;
enum Animates { AquaPushButton, AquaProgressBar, AquaListViewItemOpen, AquaScrollBar };
static ThemeDrawState getDrawState(QStyle::State flags);
@@ -216,49 +214,6 @@ public:
void *indicatorBranchButtonCell;
};
-class QScrollbarAnimation : public QNumberStyleAnimation
-{
- Q_OBJECT
-
-public:
- QScrollbarAnimation(QObject *target) : QNumberStyleAnimation(target), _active(false)
- { }
-
- bool wasActive() const { return _active; }
- void setActive(bool active) { _active = active; }
-
- bool isFadingOut() const { return _isFadingOut; }
-
- void setFadingOut()
- {
- _isFadingOut = true;
- setDuration(QMacStylePrivate::ScrollBarFadeOutDelay + QMacStylePrivate::ScrollBarFadeOutDuration);
- setDelay(QMacStylePrivate::ScrollBarFadeOutDelay);
- setStartValue(1.0);
- setEndValue(0.0);
- }
-
- void setExpanding()
- {
- _isFadingOut = false;
- setDuration(QMacStylePrivate::ScrollBarFadeOutDuration);
- setStartValue(0.0);
- setEndValue(1.0);
- }
-
-private slots:
- void updateCurrentTime(int time)
- {
- QNumberStyleAnimation::updateCurrentTime(time);
- if (_isFadingOut && qFuzzyIsNull(currentValue()))
- target()->setProperty("visible", false);
- }
-
-private:
- bool _active;
- bool _isFadingOut;
-};
-
QT_END_NAMESPACE
#endif // QMACSTYLE_MAC_P_P_H
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index bbb216bf92..04112169ca 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -685,7 +685,7 @@ public:
SH_Menu_FadeOutOnHide,
SH_SpinBox_ClickAutoRepeatThreshold,
SH_ItemView_PaintAlternatingRowColorsForEmptyArea,
- SH_FormLayoutWrapPolicy,
+ SH_FormLayoutWrapPolicy,
SH_TabWidget_DefaultTabPosition,
SH_ToolBar_Movable,
SH_FormLayoutFieldGrowthPolicy,
diff --git a/src/widgets/styles/qstyleanimation.cpp b/src/widgets/styles/qstyleanimation.cpp
index 90fb371982..85dc357ab5 100644
--- a/src/widgets/styles/qstyleanimation.cpp
+++ b/src/widgets/styles/qstyleanimation.cpp
@@ -46,6 +46,9 @@
QT_BEGIN_NAMESPACE
+static const qreal ScrollBarFadeOutDuration = 200.0;
+static const qreal ScrollBarFadeOutDelay = 450.0;
+
QStyleAnimation::QStyleAnimation(QObject *target) : QAbstractAnimation(target),
_delay(0), _duration(-1), _startTime(QTime::currentTime())
{
@@ -301,4 +304,43 @@ void QBlendStyleAnimation::updateCurrentTime(int time)
_current = blendedImage(_start, _end, alpha);
}
+QScrollbarStyleAnimation::QScrollbarStyleAnimation(Mode mode, QObject *target) : QNumberStyleAnimation(target), _mode(mode), _active(false)
+{
+ switch (mode) {
+ case Activating:
+ setDuration(ScrollBarFadeOutDuration);
+ setStartValue(0.0);
+ setEndValue(1.0);
+ break;
+ case Deactivating:
+ setDuration(ScrollBarFadeOutDelay + ScrollBarFadeOutDuration);
+ setDelay(ScrollBarFadeOutDelay);
+ setStartValue(1.0);
+ setEndValue(0.0);
+ break;
+ }
+}
+
+QScrollbarStyleAnimation::Mode QScrollbarStyleAnimation::mode() const
+{
+ return _mode;
+}
+
+bool QScrollbarStyleAnimation::wasActive() const
+{
+ return _active;
+}
+
+void QScrollbarStyleAnimation::setActive(bool active)
+{
+ _active = active;
+}
+
+void QScrollbarStyleAnimation::updateCurrentTime(int time)
+{
+ QNumberStyleAnimation::updateCurrentTime(time);
+ if (_mode == Deactivating && qFuzzyIsNull(currentValue()))
+ target()->setProperty("visible", false);
+}
+
QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstyleanimation_p.h b/src/widgets/styles/qstyleanimation_p.h
index 77962bedac..c344858812 100644
--- a/src/widgets/styles/qstyleanimation_p.h
+++ b/src/widgets/styles/qstyleanimation_p.h
@@ -162,6 +162,28 @@ private:
QImage _current;
};
+class QScrollbarStyleAnimation : public QNumberStyleAnimation
+{
+ Q_OBJECT
+
+public:
+ enum Mode { Activating, Deactivating };
+
+ QScrollbarStyleAnimation(Mode mode, QObject *target);
+
+ Mode mode() const;
+
+ bool wasActive() const;
+ void setActive(bool active);
+
+private slots:
+ void updateCurrentTime(int time);
+
+private:
+ Mode _mode;
+ bool _active;
+};
+
QT_END_NAMESPACE
#endif // QSTYLEANIMATION_P_H
diff --git a/src/widgets/styles/qwindowscestyle.cpp b/src/widgets/styles/qwindowscestyle.cpp
index 564e84b35b..576dd4165e 100644
--- a/src/widgets/styles/qwindowscestyle.cpp
+++ b/src/widgets/styles/qwindowscestyle.cpp
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
static const int windowsItemFrame = 2; // menu item frame width
static const int windowsItemHMargin = 3; // menu item hor text margin
static const int windowsItemVMargin = 2; // menu item ver text margin
-static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
static const int windowsRightBorder = 15; // right border on windows
static const int windowsCheckMarkWidth = 14; // checkmarks width on windows
diff --git a/src/widgets/styles/qwindowsmobilestyle.cpp b/src/widgets/styles/qwindowsmobilestyle.cpp
index 36c5d7e1bb..5e6a53ed78 100644
--- a/src/widgets/styles/qwindowsmobilestyle.cpp
+++ b/src/widgets/styles/qwindowsmobilestyle.cpp
@@ -97,8 +97,8 @@ static const int PE_IndicatorArrowRightBig = 0xf000104;
/* XPM */
static const char *const radiobutton_xpm[] = {
"30 30 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ........ ",
" .............. ",
" .... .... ",
@@ -133,8 +133,8 @@ static const char *const radiobutton_xpm[] = {
/* XPM */
static const char * const radiobutton_low_xpm[] = {
"15 15 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ..... ",
" .. .. ",
" . . ",
@@ -216,8 +216,8 @@ static const char *const vertlines_xpm[] = {
/* XPM */
static const char *const radiochecked_xpm[] = {
"18 18 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ...... ",
" .......... ",
" .............. ",
@@ -240,8 +240,8 @@ static const char *const radiochecked_xpm[] = {
/* XPM */
static const char * const radiochecked_low_xpm[] = {
"9 9 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ... ",
" ....... ",
" ....... ",
@@ -254,8 +254,8 @@ static const char * const radiochecked_low_xpm[] = {
static const char *const arrowdown_xpm[] = {
"15 8 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
"...............",
" ............. ",
" ........... ",
@@ -268,8 +268,8 @@ static const char *const arrowdown_xpm[] = {
static const char *const arrowdown_big_xpm[] = {
"17 9 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
".................",
" ............... ",
" ............. ",
@@ -284,8 +284,8 @@ static const char *const arrowdown_big_xpm[] = {
/* XPM */
static const char *const checkedlight_xpm[] = {
"24 24 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ",
" ",
" ",
@@ -315,8 +315,8 @@ static const char *const checkedlight_xpm[] = {
/* XPM */
static const char *const checkedbold_xpm[] = {
"26 26 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" ",
" ",
" ",
@@ -347,8 +347,8 @@ static const char *const checkedbold_xpm[] = {
/* XPM */
static const char * const checkedbold_low_xpm[] = {
"9 8 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" .",
" ..",
". ...",
@@ -361,8 +361,8 @@ static const char * const checkedbold_low_xpm[] = {
/* XPM */
static const char * const checkedlight_low_xpm[] = {
"8 8 2 1",
- " c None",
- ". c #000000",
+ " c None",
+ ". c #000000",
" .",
" ..",
" ...",
@@ -375,9 +375,9 @@ static const char * const checkedlight_low_xpm[] = {
/* XPM */
static const char * const highlightedradiobutton_xpm[] = {
"30 30 3 1",
- " c None",
- ". c #000000",
- "+ c #0078CC",
+ " c None",
+ ". c #000000",
+ "+ c #0078CC",
" ........ ",
" .............. ",
" ....++++++++.... ",
@@ -412,9 +412,9 @@ static const char * const highlightedradiobutton_xpm[] = {
/* XPM */
static const char * const highlightedradiobutton_low_xpm[] = {
"15 15 3 1",
- " c None",
- ". c #000000",
- "+ c #3192D6",
+ " c None",
+ ". c #000000",
+ "+ c #3192D6",
" ..... ",
" ..+++++.. ",
" .++ ++. ",
@@ -434,10 +434,10 @@ static const char * const highlightedradiobutton_low_xpm[] = {
/* XPM */
static const char * const cross_big_xpm[] = {
"28 28 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FDFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
" ",
" ",
" ++++++++++++++++++++++++ ",
@@ -470,10 +470,10 @@ static const char * const cross_big_xpm[] = {
/* XPM */
static const char * const cross_small_xpm[] = {
"14 14 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FCFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
" ",
" ++++++++++++ ",
" +..........+ ",
@@ -492,10 +492,10 @@ static const char * const cross_small_xpm[] = {
/* XPM */
static const char * const max_big_xpm[] = {
"28 28 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FDFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
" ",
" ",
" ++++++++++++++++++++++++ ",
@@ -528,10 +528,10 @@ static const char * const max_big_xpm[] = {
/* XPM */
static const char * const max_small_xpm[] = {
"14 14 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FCFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
" ",
" ++++++++++++ ",
" +..........+ ",
@@ -550,10 +550,10 @@ static const char * const max_small_xpm[] = {
/* XPM */
static const char * const normal_big_xpm[] = {
"28 28 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FDFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
" ",
" ",
" ++++++++++++++++++++++++ ",
@@ -586,10 +586,10 @@ static const char * const normal_big_xpm[] = {
/* XPM */
static const char * const normal_small_xpm[] = {
"14 14 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FCFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
" ",
" ++++++++++++ ",
" +..........+ ",
@@ -609,10 +609,10 @@ static const char * const normal_small_xpm[] = {
/* XPM */
static const char * const min_big_xpm[] = {
"28 28 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FDFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FDFFFC",
" ",
" ",
" ++++++++++++++++++++++++ ",
@@ -645,10 +645,10 @@ static const char * const min_big_xpm[] = {
/* XPM */
static const char * const min_small_xpm[] = {
"14 14 4 1",
-" c #09454A",
-". c #218C98",
-"+ c #47D8E5",
-"@ c #FCFFFC",
+" c #09454A",
+". c #218C98",
+"+ c #47D8E5",
+"@ c #FCFFFC",
" ",
" ++++++++++++ ",
" +..........+ ",
@@ -668,51 +668,51 @@ static const char * const min_small_xpm[] = {
static char * sbhandleup_xpm[] = {
"26 41 45 1",
-" c None",
-". c #000000",
-"+ c #E7E7E7",
-"@ c #D6D7D6",
-"# c #949294",
-"$ c #737573",
-"% c #636563",
-"& c #636163",
-"* c #5A5D5A",
-"= c #5A595A",
-"- c #525552",
-"; c #525152",
-"> c #4A4D4A",
-", c #7B797B",
-"' c #CECFCE",
-") c #CED3CE",
-"! c #6B6D6B",
-"~ c #6B696B",
-"{ c #737173",
-"] c #7B7D7B",
-"^ c #848684",
-"/ c #848284",
-"( c #8C8A8C",
-"_ c #8C8E8C",
-": c #B5B2B5",
-"< c #FFFFFF",
-"[ c #949694",
-"} c #B5B6B5",
-"| c #9C9A9C",
-"1 c #ADAEAD",
-"2 c #9C9E9C",
-"3 c #BDBABD",
-"4 c #BDBEBD",
-"5 c #F7F3F7",
-"6 c #C6C3C6",
-"7 c #C6C7C6",
-"8 c #A5A2A5",
-"9 c #CECBCE",
-"0 c #FFFBFF",
-"a c #ADAAAD",
-"b c #A5A6A5",
-"c c #D6D3D6",
-"d c #B5BAB5",
-"e c #DEDFDE",
-"f c #DEDBDE",
+" c None",
+". c #000000",
+"+ c #E7E7E7",
+"@ c #D6D7D6",
+"# c #949294",
+"$ c #737573",
+"% c #636563",
+"& c #636163",
+"* c #5A5D5A",
+"= c #5A595A",
+"- c #525552",
+"; c #525152",
+"> c #4A4D4A",
+", c #7B797B",
+"' c #CECFCE",
+") c #CED3CE",
+"! c #6B6D6B",
+"~ c #6B696B",
+"{ c #737173",
+"] c #7B7D7B",
+"^ c #848684",
+"/ c #848284",
+"( c #8C8A8C",
+"_ c #8C8E8C",
+": c #B5B2B5",
+"< c #FFFFFF",
+"[ c #949694",
+"} c #B5B6B5",
+"| c #9C9A9C",
+"1 c #ADAEAD",
+"2 c #9C9E9C",
+"3 c #BDBABD",
+"4 c #BDBEBD",
+"5 c #F7F3F7",
+"6 c #C6C3C6",
+"7 c #C6C7C6",
+"8 c #A5A2A5",
+"9 c #CECBCE",
+"0 c #FFFBFF",
+"a c #ADAAAD",
+"b c #A5A6A5",
+"c c #D6D3D6",
+"d c #B5BAB5",
+"e c #DEDFDE",
+"f c #DEDBDE",
"..........................",
"+@#$%%&&&**===---;;;;>=,'+",
"+@#$%%&&&**===---;;;;>=$'+",
@@ -757,52 +757,52 @@ static char * sbhandleup_xpm[] = {
static char * sbhandledown_xpm[] = {
"26 40 46 1",
-" c None",
-". c #E7E7E7",
-"+ c #DEDFDE",
-"@ c #BDBEBD",
-"# c #B5B2B5",
-"$ c #ADAAAD",
-"% c #A5A6A5",
-"& c #A5A2A5",
-"* c #9C9E9C",
-"= c #9C9A9C",
-"- c #949694",
-"; c #949294",
-"> c #D6D7D6",
-", c #DEDBDE",
-"' c #D6DBD6",
-") c #ADAEAD",
-"! c #8C8E8C",
-"~ c #8C8A8C",
-"{ c #BDBABD",
-"] c #848684",
-"^ c #B5BAB5",
-"/ c #848284",
-"( c #848A84",
-"_ c #7B7D7B",
-": c #7B797B",
-"< c #C6C3C6",
-"[ c #D6D3D6",
-"} c #FFFBFF",
-"| c #CECFCE",
-"1 c #FFFFFF",
-"2 c #737573",
-"3 c #F7F3F7",
-"4 c #CECBCE",
-"5 c #737173",
-"6 c #C6C7C6",
-"7 c #6B6D6B",
-"8 c #B5B6B5",
-"9 c #6B696B",
-"0 c #636563",
-"a c #636163",
-"b c #5A5D5A",
-"c c #5A595A",
-"d c #525552",
-"e c #525152",
-"f c #4A4D4A",
-"g c #C6CBC6",
+" c None",
+". c #E7E7E7",
+"+ c #DEDFDE",
+"@ c #BDBEBD",
+"# c #B5B2B5",
+"$ c #ADAAAD",
+"% c #A5A6A5",
+"& c #A5A2A5",
+"* c #9C9E9C",
+"= c #9C9A9C",
+"- c #949694",
+"; c #949294",
+"> c #D6D7D6",
+", c #DEDBDE",
+"' c #D6DBD6",
+") c #ADAEAD",
+"! c #8C8E8C",
+"~ c #8C8A8C",
+"{ c #BDBABD",
+"] c #848684",
+"^ c #B5BAB5",
+"/ c #848284",
+"( c #848A84",
+"_ c #7B7D7B",
+": c #7B797B",
+"< c #C6C3C6",
+"[ c #D6D3D6",
+"} c #FFFBFF",
+"| c #CECFCE",
+"1 c #FFFFFF",
+"2 c #737573",
+"3 c #F7F3F7",
+"4 c #CECBCE",
+"5 c #737173",
+"6 c #C6C7C6",
+"7 c #6B6D6B",
+"8 c #B5B6B5",
+"9 c #6B696B",
+"0 c #636563",
+"a c #636163",
+"b c #5A5D5A",
+"c c #5A595A",
+"d c #525552",
+"e c #525152",
+"f c #4A4D4A",
+"g c #C6CBC6",
".+@#$$$%%%%&&&**==---;-%>.",
".+@#$$$%%%%&&&**==---;-%,.",
"')$$$%%%%&&&&**==--;;!!~~>",
@@ -846,45 +846,45 @@ static char * sbhandledown_xpm[] = {
static char * sbgripdown_xpm[] = {
"26 34 39 1",
-" c None",
-". c #949294",
-"+ c #9C9E9C",
-"@ c #9C9A9C",
-"# c #949694",
-"$ c #8C8E8C",
-"% c #8C8A8C",
-"& c #848684",
-"* c #848284",
-"= c #7B7D7B",
-"- c #7B797B",
-"; c #6B696B",
-"> c #636563",
-", c #737573",
-"' c #636163",
-") c #737173",
-"! c #5A5D5A",
-"~ c #6B6D6B",
-"{ c #5A595A",
-"] c #B5B6B5",
-"^ c #BDBEBD",
-"/ c #ADAEAD",
-"( c #BDBABD",
-"_ c #525552",
-": c #313031",
-"< c #525152",
-"[ c #ADAAAD",
-"} c #BDBAB5",
-"| c #4A4D4A",
-"1 c #4A494A",
-"2 c #C6C3C6",
-"3 c #C6CBC6",
-"4 c #E7E7E7",
-"5 c #DEDFDE",
-"6 c #E7E3E7",
-"7 c #DEE3DE",
-"8 c #CECBCE",
-"9 c #8C928C",
-"0 c #CECFCE",
+" c None",
+". c #949294",
+"+ c #9C9E9C",
+"@ c #9C9A9C",
+"# c #949694",
+"$ c #8C8E8C",
+"% c #8C8A8C",
+"& c #848684",
+"* c #848284",
+"= c #7B7D7B",
+"- c #7B797B",
+"; c #6B696B",
+"> c #636563",
+", c #737573",
+"' c #636163",
+") c #737173",
+"! c #5A5D5A",
+"~ c #6B6D6B",
+"{ c #5A595A",
+"] c #B5B6B5",
+"^ c #BDBEBD",
+"/ c #ADAEAD",
+"( c #BDBABD",
+"_ c #525552",
+": c #313031",
+"< c #525152",
+"[ c #ADAAAD",
+"} c #BDBAB5",
+"| c #4A4D4A",
+"1 c #4A494A",
+"2 c #C6C3C6",
+"3 c #C6CBC6",
+"4 c #E7E7E7",
+"5 c #DEDFDE",
+"6 c #E7E3E7",
+"7 c #DEE3DE",
+"8 c #CECBCE",
+"9 c #8C928C",
+"0 c #CECFCE",
"..+++@@@###...$$%&&**==-;>",
"$.++@@@@##...$$%%&**==-->>",
"$$+@@@@###..$$%%&&*==--,>>",
@@ -922,44 +922,44 @@ static char * sbgripdown_xpm[] = {
static char * sbgripup_xpm[] = {
"26 34 38 1",
-" c None",
-". c #E7E7E7",
-"+ c #D6DBD6",
-"@ c #C6C7C6",
-"# c #B5B6B5",
-"$ c #ADAEAD",
-"% c #ADAAAD",
-"& c #A5A6A5",
-"* c #A5A2A5",
-"= c #BDBEBD",
-"- c #DEDFDE",
-"; c #C6CBC6",
-"> c #9C9E9C",
-", c #E7E3E7",
-"' c #BDBABD",
-") c #B5B2B5",
-"! c #9C9A9C",
-"~ c #DEE3DE",
-"{ c #949694",
-"] c #D6D7D6",
-"^ c #949294",
-"/ c #DEDBDE",
-"( c #8C8E8C",
-"_ c #8C8A8C",
-": c #848684",
-"< c #D6D3CE",
-"[ c #CECBCE",
-"} c #D6D3D6",
-"| c #848284",
-"1 c #313031",
-"2 c #7B7D7B",
-"3 c #CECFCE",
-"4 c #CECBC6",
-"5 c #7B797B",
-"6 c #737573",
-"7 c #737173",
-"8 c #6B6D6B",
-"9 c #6B696B",
+" c None",
+". c #E7E7E7",
+"+ c #D6DBD6",
+"@ c #C6C7C6",
+"# c #B5B6B5",
+"$ c #ADAEAD",
+"% c #ADAAAD",
+"& c #A5A6A5",
+"* c #A5A2A5",
+"= c #BDBEBD",
+"- c #DEDFDE",
+"; c #C6CBC6",
+"> c #9C9E9C",
+", c #E7E3E7",
+"' c #BDBABD",
+") c #B5B2B5",
+"! c #9C9A9C",
+"~ c #DEE3DE",
+"{ c #949694",
+"] c #D6D7D6",
+"^ c #949294",
+"/ c #DEDBDE",
+"( c #8C8E8C",
+"_ c #8C8A8C",
+": c #848684",
+"< c #D6D3CE",
+"[ c #CECBCE",
+"} c #D6D3D6",
+"| c #848284",
+"1 c #313031",
+"2 c #7B7D7B",
+"3 c #CECFCE",
+"4 c #CECBC6",
+"5 c #7B797B",
+"6 c #737573",
+"7 c #737173",
+"8 c #6B6D6B",
+"9 c #6B696B",
"....+@#$$%%%%&&&***$=-....",
"...;$$$$$%%%&&&&**>>>>@...",
".,'$$)#'#####)))$$$%*!!$~.",
@@ -997,221 +997,221 @@ static char * sbgripup_xpm[] = {
static char * sbgripmiddle_xpm[] = {
"26 2 12 1",
-" c None",
-". c #949294",
-"+ c #A5A2A5",
-"@ c #9C9E9C",
-"# c #9C9A9C",
-"$ c #949694",
-"% c #8C8E8C",
-"& c #8C8A8C",
-"* c #848684",
-"= c #848284",
-"- c #7B7D7B",
-"; c #6B696B",
+" c None",
+". c #949294",
+"+ c #A5A2A5",
+"@ c #9C9E9C",
+"# c #9C9A9C",
+"$ c #949694",
+"% c #8C8E8C",
+"& c #8C8A8C",
+"* c #848684",
+"= c #848284",
+"- c #7B7D7B",
+"; c #6B696B",
"..++@@@###$$$..%%&&*==--;;",
"..++@@@###$$$..%%&&*==--;;"};
static char * listviewhighmiddle_xpm[] = {
"8 46 197 2",
-" c None",
-". c #66759E",
-"+ c #6C789D",
-"@ c #6A789E",
-"# c #6B789E",
-"$ c #6A779D",
-"% c #6C789C",
-"& c #6F7D9B",
-"* c #6F7D9A",
-"= c #9DB6EE",
-"- c #9DB6ED",
-"; c #9CB6ED",
-"> c #A1B6EF",
-", c #A2B6F0",
-"' c #93AAE9",
-") c #95ABEA",
-"! c #94ABEA",
-"~ c #94A9E8",
-"{ c #8BA8EA",
-"] c #8BA7EA",
-"^ c #8AA7EA",
-"/ c #8EAAE8",
-"( c #8FAAE8",
-"_ c #88A2E7",
-": c #8CA3E8",
-"< c #8BA3E7",
-"[ c #8BA3E8",
-"} c #8BA2E7",
-"| c #8CA2E7",
-"1 c #8DA2E7",
-"2 c #87A1E8",
-"3 c #87A1E9",
-"4 c #86A0E8",
-"5 c #86A1E7",
-"6 c #87A2E7",
-"7 c #859EE9",
-"8 c #849DE9",
-"9 c #869EE9",
-"0 c #869FE9",
-"a c #7C9BEA",
-"b c #7C9CEA",
-"c c #7B9CEA",
-"d c #7C9BE9",
-"e c #7E9CE9",
-"f c #7B9AEA",
-"g c #7C99E9",
-"h c #7C9AEA",
-"i c #7B9AE8",
-"j c #7A9AEA",
-"k c #7996E1",
-"l c #7C96E4",
-"m c #7B96E3",
-"n c #7B95E3",
-"o c #7E95E5",
-"p c #7E95E6",
-"q c #7292E1",
-"r c #7490DF",
-"s c #7591E0",
-"t c #7590DF",
-"u c #7392E1",
-"v c #6D8CDE",
-"w c #6F8EDD",
-"x c #6E8DDD",
-"y c #6E8DDE",
-"z c #6F8EDE",
-"A c #6E8EDE",
-"B c #718EDD",
-"C c #728EDD",
-"D c #6B89E0",
-"E c #6C89DF",
-"F c #6D89E0",
-"G c #6D89DF",
-"H c #6C88DF",
-"I c #6D88DF",
-"J c #6D86DD",
-"K c #6086E0",
-"L c #6686E0",
-"M c #6586E0",
-"N c #6486E0",
-"O c #6485E0",
-"P c #6786DF",
-"Q c #5F85E0",
-"R c #6583DE",
-"S c #6683DE",
-"T c #6682DD",
-"U c #6086DF",
-"V c #5F86E0",
-"W c #567ED7",
-"X c #567ED8",
-"Y c #557DD7",
-"Z c #5A7FD8",
-"` c #6281DA",
-" . c #5379D9",
-".. c #5278D9",
-"+. c #547BD8",
-"@. c #4C73D7",
-"#. c #4B72D2",
-"$. c #4C73D4",
-"%. c #4C73D3",
-"&. c #4B72D4",
-"*. c #4F75D3",
-"=. c #5074D2",
-"-. c #4971D0",
-";. c #4871D0",
-">. c #335ECF",
-",. c #325ECB",
-"'. c #335ECD",
-"). c #335ECE",
-"!. c #325DCD",
-"~. c #2E59C9",
-"{. c #3059C9",
-"]. c #2F59C9",
-"^. c #2F59C8",
-"/. c #2B59CA",
-"(. c #3355C6",
-"_. c #3354C5",
-":. c #3156C7",
-"<. c #3056C7",
-"[. c #3355C7",
-"}. c #3355C5",
-"|. c #254EBF",
-"1. c #1F51C1",
-"2. c #234FC0",
-"3. c #234FBF",
-"4. c #2350C0",
-"5. c #1E50BE",
-"6. c #1D50C0",
-"7. c #264DBE",
-"8. c #264CBD",
-"9. c #254DBE",
-"0. c #244EBF",
-"a. c #254DBF",
-"b. c #234CBF",
-"c. c #244CC0",
-"d. c #244BC0",
-"e. c #234BC0",
-"f. c #234BBF",
-"g. c #234CBE",
-"h. c #2049B7",
-"i. c #2A49B5",
-"j. c #2749B5",
-"k. c #2749B6",
-"l. c #2D49B4",
-"m. c #2649B6",
-"n. c #2946B5",
-"o. c #2A48B6",
-"p. c #2947B5",
-"q. c #2946B6",
-"r. c #2848B6",
-"s. c #2549B5",
-"t. c #2648B6",
-"u. c #2744B5",
-"v. c #2744B4",
-"w. c #2744AF",
-"x. c #2543B4",
-"y. c #2543B2",
-"z. c #2442B2",
-"A. c #2442B3",
-"B. c #2442B5",
-"C. c #2543B3",
-"D. c #1F40B1",
-"E. c #1E40B1",
-"F. c #243EAE",
-"G. c #273BAC",
-"H. c #263DAC",
-"I. c #253CAB",
-"J. c #273CAB",
-"K. c #273CAC",
-"L. c #263BAA",
-"M. c #253CAE",
-"N. c #263BA6",
-"O. c #253BA5",
-"P. c #253AA5",
-"Q. c #253BA6",
-"R. c #253CA7",
-"S. c #263AA6",
-"T. c #243CA6",
-"U. c #253CA5",
-"V. c #273BA8",
-"W. c #2F4DA4",
-"X. c #2F4DA3",
-"Y. c #1B2F85",
-"Z. c #B5B5B6",
-"`. c #B5B5B5",
-" + c #B5B6B6",
-".+ c #B5B4B6",
-"++ c #C2C3C5",
-"@+ c #C0C3C3",
-"#+ c #C1C3C4",
-"$+ c #E3E3E3",
-"%+ c #E3E3E4",
-"&+ c #E4E3E4",
-"*+ c #E2E3E4",
-"=+ c #ECEEEB",
-"-+ c #EBEDEA",
-";+ c #EEF0ED",
-">+ c #EFF0EE",
+" c None",
+". c #66759E",
+"+ c #6C789D",
+"@ c #6A789E",
+"# c #6B789E",
+"$ c #6A779D",
+"% c #6C789C",
+"& c #6F7D9B",
+"* c #6F7D9A",
+"= c #9DB6EE",
+"- c #9DB6ED",
+"; c #9CB6ED",
+"> c #A1B6EF",
+", c #A2B6F0",
+"' c #93AAE9",
+") c #95ABEA",
+"! c #94ABEA",
+"~ c #94A9E8",
+"{ c #8BA8EA",
+"] c #8BA7EA",
+"^ c #8AA7EA",
+"/ c #8EAAE8",
+"( c #8FAAE8",
+"_ c #88A2E7",
+": c #8CA3E8",
+"< c #8BA3E7",
+"[ c #8BA3E8",
+"} c #8BA2E7",
+"| c #8CA2E7",
+"1 c #8DA2E7",
+"2 c #87A1E8",
+"3 c #87A1E9",
+"4 c #86A0E8",
+"5 c #86A1E7",
+"6 c #87A2E7",
+"7 c #859EE9",
+"8 c #849DE9",
+"9 c #869EE9",
+"0 c #869FE9",
+"a c #7C9BEA",
+"b c #7C9CEA",
+"c c #7B9CEA",
+"d c #7C9BE9",
+"e c #7E9CE9",
+"f c #7B9AEA",
+"g c #7C99E9",
+"h c #7C9AEA",
+"i c #7B9AE8",
+"j c #7A9AEA",
+"k c #7996E1",
+"l c #7C96E4",
+"m c #7B96E3",
+"n c #7B95E3",
+"o c #7E95E5",
+"p c #7E95E6",
+"q c #7292E1",
+"r c #7490DF",
+"s c #7591E0",
+"t c #7590DF",
+"u c #7392E1",
+"v c #6D8CDE",
+"w c #6F8EDD",
+"x c #6E8DDD",
+"y c #6E8DDE",
+"z c #6F8EDE",
+"A c #6E8EDE",
+"B c #718EDD",
+"C c #728EDD",
+"D c #6B89E0",
+"E c #6C89DF",
+"F c #6D89E0",
+"G c #6D89DF",
+"H c #6C88DF",
+"I c #6D88DF",
+"J c #6D86DD",
+"K c #6086E0",
+"L c #6686E0",
+"M c #6586E0",
+"N c #6486E0",
+"O c #6485E0",
+"P c #6786DF",
+"Q c #5F85E0",
+"R c #6583DE",
+"S c #6683DE",
+"T c #6682DD",
+"U c #6086DF",
+"V c #5F86E0",
+"W c #567ED7",
+"X c #567ED8",
+"Y c #557DD7",
+"Z c #5A7FD8",
+"` c #6281DA",
+" . c #5379D9",
+".. c #5278D9",
+"+. c #547BD8",
+"@. c #4C73D7",
+"#. c #4B72D2",
+"$. c #4C73D4",
+"%. c #4C73D3",
+"&. c #4B72D4",
+"*. c #4F75D3",
+"=. c #5074D2",
+"-. c #4971D0",
+";. c #4871D0",
+">. c #335ECF",
+",. c #325ECB",
+"'. c #335ECD",
+"). c #335ECE",
+"!. c #325DCD",
+"~. c #2E59C9",
+"{. c #3059C9",
+"]. c #2F59C9",
+"^. c #2F59C8",
+"/. c #2B59CA",
+"(. c #3355C6",
+"_. c #3354C5",
+":. c #3156C7",
+"<. c #3056C7",
+"[. c #3355C7",
+"}. c #3355C5",
+"|. c #254EBF",
+"1. c #1F51C1",
+"2. c #234FC0",
+"3. c #234FBF",
+"4. c #2350C0",
+"5. c #1E50BE",
+"6. c #1D50C0",
+"7. c #264DBE",
+"8. c #264CBD",
+"9. c #254DBE",
+"0. c #244EBF",
+"a. c #254DBF",
+"b. c #234CBF",
+"c. c #244CC0",
+"d. c #244BC0",
+"e. c #234BC0",
+"f. c #234BBF",
+"g. c #234CBE",
+"h. c #2049B7",
+"i. c #2A49B5",
+"j. c #2749B5",
+"k. c #2749B6",
+"l. c #2D49B4",
+"m. c #2649B6",
+"n. c #2946B5",
+"o. c #2A48B6",
+"p. c #2947B5",
+"q. c #2946B6",
+"r. c #2848B6",
+"s. c #2549B5",
+"t. c #2648B6",
+"u. c #2744B5",
+"v. c #2744B4",
+"w. c #2744AF",
+"x. c #2543B4",
+"y. c #2543B2",
+"z. c #2442B2",
+"A. c #2442B3",
+"B. c #2442B5",
+"C. c #2543B3",
+"D. c #1F40B1",
+"E. c #1E40B1",
+"F. c #243EAE",
+"G. c #273BAC",
+"H. c #263DAC",
+"I. c #253CAB",
+"J. c #273CAB",
+"K. c #273CAC",
+"L. c #263BAA",
+"M. c #253CAE",
+"N. c #263BA6",
+"O. c #253BA5",
+"P. c #253AA5",
+"Q. c #253BA6",
+"R. c #253CA7",
+"S. c #263AA6",
+"T. c #243CA6",
+"U. c #253CA5",
+"V. c #273BA8",
+"W. c #2F4DA4",
+"X. c #2F4DA3",
+"Y. c #1B2F85",
+"Z. c #B5B5B6",
+"`. c #B5B5B5",
+" + c #B5B6B6",
+".+ c #B5B4B6",
+"++ c #C2C3C5",
+"@+ c #C0C3C3",
+"#+ c #C1C3C4",
+"$+ c #E3E3E3",
+"%+ c #E3E3E4",
+"&+ c #E4E3E4",
+"*+ c #E2E3E4",
+"=+ c #ECEEEB",
+"-+ c #EBEDEA",
+";+ c #EEF0ED",
+">+ c #EFF0EE",
". + @ @ # # $ % ",
"& & * & & & & & ",
"= = - = = ; > , ",
@@ -1263,1481 +1263,1481 @@ static char * listviewhighmiddle_xpm[] = {
static char * listviewhighcornerleft_xpm[] = {
"100 46 1475 2",
-" c None",
-". c #FBFBFC",
-"+ c #E8EAE7",
-"@ c #758DC3",
-"# c #42599E",
-"$ c #28418A",
-"% c #19418F",
-"& c #3F5695",
-"* c #415896",
-"= c #435A98",
-"- c #445C99",
-"; c #465E9B",
-"> c #48609B",
-", c #49629C",
-"' c #4A639D",
-") c #49639D",
-"! c #4A629D",
-"~ c #4B639D",
-"{ c #4B649D",
-"] c #4C659D",
-"^ c #4D669D",
-"/ c #4E689D",
-"( c #506A9D",
-"_ c #516A9D",
-": c #536B9C",
-"< c #546C9C",
-"[ c #566D9B",
-"} c #576D9B",
-"| c #586E9C",
-"1 c #5B6F9D",
-"2 c #61739D",
-"3 c #63749E",
-"4 c #64749E",
-"5 c #68769E",
-"6 c #6A779E",
-"7 c #6B789E",
-"8 c #66759E",
-"9 c #6C789D",
-"0 c #EEF0ED",
-"a c #D0D3DC",
-"b c #3E51A3",
-"c c #28428B",
-"d c #29428C",
-"e c #425996",
-"f c #455C99",
-"g c #485F9C",
-"h c #49619E",
-"i c #4A63A0",
-"j c #4B64A1",
-"k c #4B65A1",
-"l c #4C66A2",
-"m c #4D67A2",
-"n c #4F69A1",
-"o c #516AA1",
-"p c #536CA0",
-"q c #556DA1",
-"r c #576EA0",
-"s c #586F9F",
-"t c #586E9F",
-"u c #596F9E",
-"v c #5A6F9E",
-"w c #5C709E",
-"x c #5E719E",
-"y c #5F729F",
-"z c #62739F",
-"A c #63739E",
-"B c #64749D",
-"C c #65749E",
-"D c #69769D",
-"E c #6C799E",
-"F c #6D799F",
-"G c #707D9F",
-"H c #717F9E",
-"I c #6E7AA1",
-"J c #6C789E",
-"K c #6F7C9C",
-"L c #6F7D9B",
-"M c #2A4AA0",
-"N c #4971D0",
-"O c #4C72D8",
-"P c #5472C0",
-"Q c #5573BF",
-"R c #5774BF",
-"S c #5875BF",
-"T c #5976C1",
-"U c #5A76C1",
-"V c #5C78C2",
-"W c #5E7AC2",
-"X c #607CC3",
-"Y c #627EC3",
-"Z c #637FC4",
-"` c #6581C5",
-" . c #6682C6",
-".. c #6783C7",
-"+. c #6984C8",
-"@. c #6B85C9",
-"#. c #6D87CA",
-"$. c #6F89CB",
-"%. c #718CCD",
-"&. c #748ECF",
-"*. c #7690D0",
-"=. c #7992D2",
-"-. c #7A93D3",
-";. c #7C95D5",
-">. c #7F98D7",
-",. c #8099D8",
-"'. c #859CDB",
-"). c #8AA0DD",
-"!. c #8DA3DF",
-"~. c #8FA5E0",
-"{. c #90A5E0",
-"]. c #91A6E1",
-"^. c #91A5E1",
-"/. c #90A4E0",
-"(. c #8EA3DE",
-"_. c #92A6E2",
-":. c #8FA4DF",
-"<. c #90A5DE",
-"[. c #90A5DC",
-"}. c #90A6DB",
-"|. c #91A6E0",
-"1. c #93A7E2",
-"2. c #95AAE6",
-"3. c #99AEEA",
-"4. c #9AB2EA",
-"5. c #99B1E9",
-"6. c #99B1E7",
-"7. c #98AFE6",
-"8. c #93A8E2",
-"9. c #97ACE7",
-"0. c #9AB3EB",
-"a. c #9DB5ED",
-"b. c #9DB6EE",
-"c. c #375095",
-"d. c #4056AD",
-"e. c #506DCD",
-"f. c #4360CC",
-"g. c #345ED6",
-"h. c #335ECF",
-"i. c #355ED6",
-"j. c #355FD6",
-"k. c #365FD6",
-"l. c #355FD0",
-"m. c #3760D5",
-"n. c #3A63D4",
-"o. c #3C63D1",
-"p. c #3B63CD",
-"q. c #3B63C9",
-"r. c #3B62C9",
-"s. c #3D63C8",
-"t. c #4065C5",
-"u. c #4567C5",
-"v. c #496BC5",
-"w. c #4F70C7",
-"x. c #5273C8",
-"y. c #5475CA",
-"z. c #5777CB",
-"A. c #5879CD",
-"B. c #5A7BCE",
-"C. c #5D7DCF",
-"D. c #5F7ECF",
-"E. c #617FD0",
-"F. c #6381D1",
-"G. c #6583D2",
-"H. c #6785D2",
-"I. c #6886D3",
-"J. c #6A88D4",
-"K. c #6C89D5",
-"L. c #6E8BD6",
-"M. c #708CD7",
-"N. c #718DD8",
-"O. c #738EDA",
-"P. c #748FDB",
-"Q. c #7691DC",
-"R. c #7893DD",
-"S. c #7994DD",
-"T. c #7A96DE",
-"U. c #7B97DF",
-"V. c #7C98E0",
-"W. c #7E9AE2",
-"X. c #7F9BE3",
-"Y. c #829DE4",
-"Z. c #849FE5",
-"`. c #87A0E6",
-" + c #88A1E7",
-".+ c #89A2E6",
-"++ c #8CA3E7",
-"@+ c #8EA5E9",
-"#+ c #8EA6E9",
-"$+ c #8FA7E9",
-"%+ c #8FA8E8",
-"&+ c #8FA9E8",
-"*+ c #91A9E8",
-"=+ c #90A7E8",
-"-+ c #8FA8EA",
-";+ c #90AAEA",
-">+ c #93ABEA",
-",+ c #95ABEA",
-"'+ c #93ABE9",
-")+ c #94ABEA",
-"!+ c #90A9EA",
-"~+ c #93AAE9",
-"{+ c #273E7E",
-"]+ c #345ED5",
-"^+ c #3D60CE",
-"/+ c #3D60CF",
-"(+ c #345ECF",
-"_+ c #335ED0",
-":+ c #355FD3",
-"<+ c #3A60CE",
-"[+ c #3A5FCB",
-"}+ c #385FC9",
-"|+ c #3B60C8",
-"1+ c #3C63CB",
-"2+ c #3E64CB",
-"3+ c #4166CA",
-"4+ c #4568C9",
-"5+ c #4A6CC7",
-"6+ c #4F71C8",
-"7+ c #5172CA",
-"8+ c #5475CE",
-"9+ c #5678D3",
-"0+ c #597CD6",
-"a+ c #5C7ED7",
-"b+ c #5E7FD8",
-"c+ c #6181D9",
-"d+ c #6383DA",
-"e+ c #6585DA",
-"f+ c #6786DB",
-"g+ c #6988DC",
-"h+ c #6B8ADD",
-"i+ c #6D8BDE",
-"j+ c #6F8DDE",
-"k+ c #718EDF",
-"l+ c #728FE0",
-"m+ c #7390E1",
-"n+ c #7390E2",
-"o+ c #7491E3",
-"p+ c #7592E4",
-"q+ c #7693E4",
-"r+ c #7794E5",
-"s+ c #7894E5",
-"t+ c #7995E6",
-"u+ c #7B96E6",
-"v+ c #7C97E7",
-"w+ c #7D9AE8",
-"x+ c #7F9CE9",
-"y+ c #829DE9",
-"z+ c #849EE9",
-"A+ c #859EE9",
-"B+ c #87A0E7",
-"C+ c #8AA2E7",
-"D+ c #8BA3E8",
-"E+ c #89A2E7",
-"F+ c #8CA6EA",
-"G+ c #8BA6EA",
-"H+ c #8BA7EA",
-"I+ c #8CA3E8",
-"J+ c #8BA8EA",
-"K+ c #8CA7EA",
-"L+ c #8CA8EA",
-"M+ c #4659C7",
-"N+ c #355ECF",
-"O+ c #3660CF",
-"P+ c #3860CE",
-"Q+ c #3961CD",
-"R+ c #3B61CB",
-"S+ c #3B61CA",
-"T+ c #3D62CA",
-"U+ c #3D63CA",
-"V+ c #4165CB",
-"W+ c #456ACB",
-"X+ c #4B6FCD",
-"Y+ c #5174CE",
-"Z+ c #5275D1",
-"`+ c #5477D4",
-" @ c #5678D9",
-".@ c #587ADB",
-"+@ c #597BDB",
-"@@ c #5B7DDC",
-"#@ c #5E7FDC",
-"$@ c #6081DD",
-"%@ c #6283DE",
-"&@ c #6484DF",
-"*@ c #6787E0",
-"=@ c #6989E1",
-"-@ c #6B8BE1",
-";@ c #6D8DE2",
-">@ c #6F8EE3",
-",@ c #718FE4",
-"'@ c #7290E4",
-")@ c #7491E5",
-"!@ c #7692E6",
-"~@ c #7793E5",
-"{@ c #7894E6",
-"]@ c #7895E7",
-"^@ c #7996E8",
-"/@ c #7A97E8",
-"(@ c #7B98E9",
-"_@ c #7D99E8",
-":@ c #7F9AE8",
-"<@ c #7F9BE9",
-"[@ c #7F9CEA",
-"}@ c #859EE8",
-"|@ c #859FE8",
-"1@ c #85A0E9",
-"2@ c #869FE9",
-"3@ c #86A1E7",
-"4@ c #86A0E9",
-"5@ c #87A1E7",
-"6@ c #88A2E7",
-"7@ c #87A1E9",
-"8@ c #5A6FCA",
-"9@ c #365FCF",
-"0@ c #345ED0",
-"a@ c #385FCC",
-"b@ c #385FCE",
-"c@ c #3A61CC",
-"d@ c #3B62CD",
-"e@ c #3E64CD",
-"f@ c #4167CF",
-"g@ c #4469CF",
-"h@ c #486CD1",
-"i@ c #4D71D2",
-"j@ c #5175D4",
-"k@ c #5376D6",
-"l@ c #5578DA",
-"m@ c #5679DC",
-"n@ c #587BDD",
-"o@ c #5A7DDE",
-"p@ c #5D80DE",
-"q@ c #5F82DF",
-"r@ c #6284DF",
-"s@ c #6585E0",
-"t@ c #6787E1",
-"u@ c #6988E2",
-"v@ c #6B8AE2",
-"w@ c #6D8CE3",
-"x@ c #6E8DE3",
-"y@ c #708EE4",
-"z@ c #718FE3",
-"A@ c #7391E4",
-"B@ c #7592E5",
-"C@ c #7895E5",
-"D@ c #7996E6",
-"E@ c #7A97E6",
-"F@ c #7B98E7",
-"G@ c #7A98E8",
-"H@ c #7B99E9",
-"I@ c #7E9AE9",
-"J@ c #7D9AE9",
-"K@ c #7E9AEA",
-"L@ c #809CE9",
-"M@ c #819DE8",
-"N@ c #7F9BEA",
-"O@ c #819DE9",
-"P@ c #819CE9",
-"Q@ c #839EE9",
-"R@ c #839EE8",
-"S@ c #839DEA",
-"T@ c #859FE9",
-"U@ c #87A0E8",
-"V@ c #86A0E8",
-"W@ c #87A1E8",
-"X@ c #3760CF",
-"Y@ c #3A61CE",
-"Z@ c #3A62CD",
-"`@ c #3F66CE",
-" # c #4368D0",
-".# c #466CD2",
-"+# c #496DD5",
-"@# c #4E72D6",
-"## c #5175D8",
-"$# c #5276DA",
-"%# c #5578DC",
-"&# c #577ADC",
-"*# c #597CDD",
-"=# c #5B7DDD",
-"-# c #5D7FDE",
-";# c #5E81DE",
-"># c #6183DF",
-",# c #6386DF",
-"'# c #6687E0",
-")# c #6888E0",
-"!# c #6A89E1",
-"~# c #6C8AE1",
-"{# c #6E8CE2",
-"]# c #6F8DE2",
-"^# c #7390E4",
-"/# c #7390E3",
-"(# c #7491E4",
-"_# c #7693E5",
-":# c #7895E6",
-"<# c #7896E6",
-"[# c #7997E7",
-"}# c #7B97E7",
-"|# c #7B98E8",
-"1# c #7C98E8",
-"2# c #7E9BE9",
-"3# c #809CEA",
-"4# c #819CEA",
-"5# c #839DE9",
-"6# c #365FD0",
-"7# c #3660D0",
-"8# c #3961CF",
-"9# c #3B63CF",
-"0# c #3D64D0",
-"a# c #4067D0",
-"b# c #4469D2",
-"c# c #466BD3",
-"d# c #496ED5",
-"e# c #4C71D6",
-"f# c #4E72D8",
-"g# c #5074D9",
-"h# c #5376DB",
-"i# c #5578DB",
-"j# c #587ADC",
-"k# c #5B7CDC",
-"l# c #5D7EDD",
-"m# c #5F80DD",
-"n# c #6081DE",
-"o# c #6383DE",
-"p# c #6686DF",
-"q# c #6887E0",
-"r# c #6988E0",
-"s# c #6B89E1",
-"t# c #6C8AE0",
-"u# c #6E8CE1",
-"v# c #708EE2",
-"w# c #718FE2",
-"x# c #7290E3",
-"y# c #7391E2",
-"z# c #7492E1",
-"A# c #7592E2",
-"B# c #7691E3",
-"C# c #7591E3",
-"D# c #7692E3",
-"E# c #7693E3",
-"F# c #7793E4",
-"G# c #7893E4",
-"H# c #7994E5",
-"I# c #7D97E8",
-"J# c #7E98E8",
-"K# c #7D98E8",
-"L# c #7D99E9",
-"M# c #7D9BEA",
-"N# c #7D9CEA",
-"O# c #7E99E8",
-"P# c #7D9AEA",
-"Q# c #7C9BEA",
-"R# c #7C9CEA",
-"S# c #355FCF",
-"T# c #3860D0",
-"U# c #3A62D0",
-"V# c #3C64D1",
-"W# c #4167D1",
-"X# c #4369D3",
-"Y# c #466BD4",
-"Z# c #486DD5",
-"`# c #4A6ED7",
-" $ c #4C70D8",
-".$ c #5478D9",
-"+$ c #577BDA",
-"@$ c #597DDB",
-"#$ c #5B7EDB",
-"$$ c #5D7FDC",
-"%$ c #6182DE",
-"&$ c #6284DE",
-"*$ c #6485DF",
-"=$ c #6586DF",
-"-$ c #6787DF",
-";$ c #6888DF",
-">$ c #6A8ADF",
-",$ c #6C8BE0",
-"'$ c #6D8CE0",
-")$ c #6E8DE1",
-"!$ c #6F8DE1",
-"~$ c #708EE1",
-"{$ c #718FE0",
-"]$ c #728FE1",
-"^$ c #7390E0",
-"/$ c #738FE0",
-"($ c #7490E1",
-"_$ c #7590E1",
-":$ c #7591E1",
-"<$ c #7592E1",
-"[$ c #7692E2",
-"}$ c #7794E2",
-"|$ c #7894E3",
-"1$ c #7996E3",
-"2$ c #7A96E5",
-"3$ c #7B98E6",
-"4$ c #7B9AE8",
-"5$ c #7C99E8",
-"6$ c #7C96E5",
-"7$ c #7D97E7",
-"8$ c #7C99E9",
-"9$ c #7B9AE9",
-"0$ c #7B9AEA",
-"a$ c #5B6DCF",
-"b$ c #305EC8",
-"c$ c #335ECE",
-"d$ c #305ECA",
-"e$ c #345FCF",
-"f$ c #3761D0",
-"g$ c #3A62D1",
-"h$ c #3C64D2",
-"i$ c #4066D3",
-"j$ c #466BD5",
-"k$ c #486ED6",
-"l$ c #4A6ED6",
-"m$ c #4D71D8",
-"n$ c #4F72D9",
-"o$ c #5073D9",
-"p$ c #4F72D8",
-"q$ c #5074D8",
-"r$ c #5276D9",
-"s$ c #587ADA",
-"t$ c #5B7CDB",
-"u$ c #5D7EDC",
-"v$ c #5F7FDD",
-"w$ c #6081DC",
-"x$ c #6182DD",
-"y$ c #6283DD",
-"z$ c #6484DE",
-"A$ c #6585DD",
-"B$ c #6787DE",
-"C$ c #6988DF",
-"D$ c #6A89DE",
-"E$ c #6C8ADF",
-"F$ c #6D8BDF",
-"G$ c #6E8CE0",
-"H$ c #6F8DE0",
-"I$ c #718EE0",
-"J$ c #728FDF",
-"K$ c #728FDE",
-"L$ c #7290E0",
-"M$ c #7190E0",
-"N$ c #7291E0",
-"O$ c #7191E0",
-"P$ c #7392E1",
-"Q$ c #7493E1",
-"R$ c #7594E1",
-"S$ c #7594E2",
-"T$ c #7694E2",
-"U$ c #7695E2",
-"V$ c #7A96E4",
-"W$ c #7895E2",
-"X$ c #7A96E2",
-"Y$ c #7A96E3",
-"Z$ c #7B96E3",
-"`$ c #7996E1",
-" % c #7C96E4",
-".% c #305EC9",
-"+% c #315ECC",
-"@% c #325ECE",
-"#% c #3760D0",
-"$% c #3962D1",
-"%% c #3E66D3",
-"&% c #4268D4",
-"*% c #446BD5",
-"=% c #476CD6",
-"-% c #496ED7",
-";% c #4B6FD7",
-">% c #4C70D7",
-",% c #4E71D7",
-"'% c #5074D7",
-")% c #5276D8",
-"!% c #5376D8",
-"~% c #5779DA",
-"{% c #597ADA",
-"]% c #5A7BDB",
-"^% c #5B7CDA",
-"/% c #5D7EDB",
-"(% c #5E7FDB",
-"_% c #6182DB",
-":% c #6384DC",
-"<% c #6586DD",
-"[% c #6686DC",
-"}% c #6887DD",
-"|% c #6988DD",
-"1% c #6A8ADE",
-"2% c #6B8BDE",
-"3% c #6C8CDE",
-"4% c #6E8DDF",
-"5% c #6E8CDF",
-"6% c #6D8DDF",
-"7% c #6C8BDF",
-"8% c #6F8DDF",
-"9% c #718FDF",
-"0% c #7290DF",
-"a% c #7391E0",
-"b% c #7491E0",
-"c% c #7292E1",
-"d% c #3959C5",
-"e% c #345BC5",
-"f% c #315EC8",
-"g% c #355BC5",
-"h% c #325EC8",
-"i% c #315ECB",
-"j% c #345DCC",
-"k% c #335ECD",
-"l% c #345ECD",
-"m% c #355FCE",
-"n% c #3862D0",
-"o% c #3E66D2",
-"p% c #456BD5",
-"q% c #476CD5",
-"r% c #4B6ED7",
-"s% c #4B6FD6",
-"t% c #4B6FD5",
-"u% c #4D71D6",
-"v% c #5073D7",
-"w% c #5174D7",
-"x% c #5275D8",
-"y% c #5577D8",
-"z% c #5678D8",
-"A% c #5779D9",
-"B% c #587AD8",
-"C% c #597CD9",
-"D% c #5B7DD9",
-"E% c #5D7FDA",
-"F% c #5F80DB",
-"G% c #6182DC",
-"H% c #6484DC",
-"I% c #6585DC",
-"J% c #6787DD",
-"K% c #6988DE",
-"L% c #6B8ADE",
-"M% c #6B8ADF",
-"N% c #6989DE",
-"O% c #6B89DE",
-"P% c #6E8BDF",
-"Q% c #708CDE",
-"R% c #708DDF",
-"S% c #708FDF",
-"T% c #728EDF",
-"U% c #6F8EDD",
-"V% c #728EDD",
-"W% c #7390DF",
-"X% c #7490DF",
-"Y% c #335DC8",
-"Z% c #3759C5",
-"`% c #3859C5",
-" & c #335EC8",
-".& c #325DCA",
-"+& c #345CCB",
-"@& c #335DCC",
-"#& c #345DCD",
-"$& c #355FCD",
-"%& c #3861D0",
-"&& c #3B64D1",
-"*& c #3E65D2",
-"=& c #4168D3",
-"-& c #456AD5",
-";& c #4B6ED5",
-">& c #4C6FD4",
-",& c #4D70D5",
-"'& c #4F72D6",
-")& c #5173D6",
-"!& c #5375D7",
-"~& c #5476D8",
-"{& c #5577D7",
-"]& c #5477D8",
-"^& c #5677D8",
-"/& c #5879D9",
-"(& c #597AD9",
-"_& c #5C7DDA",
-":& c #6080DC",
-"<& c #6080DB",
-"[& c #6181DC",
-"}& c #6282DC",
-"|& c #6383DD",
-"1& c #6484DD",
-"2& c #6686DE",
-"3& c #6685DE",
-"4& c #6786DE",
-"5& c #6687DE",
-"6& c #6887DE",
-"7& c #6987DE",
-"8& c #6788DF",
-"9& c #6785DF",
-"0& c #6B89DF",
-"a& c #6C89DF",
-"b& c #6F8DDD",
-"c& c #6D8CDE",
-"d& c #445BBB",
-"e& c #3759BE",
-"f& c #375AC6",
-"g& c #355CC8",
-"h& c #345CCA",
-"i& c #355ECC",
-"j& c #365FCD",
-"k& c #3761CE",
-"l& c #3A63D0",
-"m& c #3D65D1",
-"n& c #466AD4",
-"o& c #476BD4",
-"p& c #486CD3",
-"q& c #4A6ED4",
-"r& c #4B6ED4",
-"s& c #4E71D6",
-"t& c #4F71D5",
-"u& c #5072D6",
-"v& c #5274D7",
-"w& c #5273D7",
-"x& c #5274D6",
-"y& c #5476D7",
-"z& c #5779D8",
-"A& c #587AD9",
-"B& c #5A7CDA",
-"C& c #5C7DDB",
-"D& c #5D7EDA",
-"E& c #6081DA",
-"F& c #6181DB",
-"G& c #6283DC",
-"H& c #6483DD",
-"I& c #6483DE",
-"J& c #6585DE",
-"K& c #6786DF",
-"L& c #6886DE",
-"M& c #6887DF",
-"N& c #6987DF",
-"O& c #6A88DF",
-"P& c #6786E0",
-"Q& c #6A86DE",
-"R& c #6B89E0",
-"S& c #365BC8",
-"T& c #365CC8",
-"U& c #375DCA",
-"V& c #375FCB",
-"W& c #3860CD",
-"X& c #3C63D0",
-"Y& c #4167D2",
-"Z& c #4268D2",
-"`& c #4368D2",
-" * c #4367D2",
-".* c #4568D2",
-"+* c #466AD2",
-"@* c #496CD3",
-"#* c #4A6DD3",
-"$* c #4A6DD4",
-"%* c #4D70D4",
-"&* c #4F72D5",
-"** c #4C70D4",
-"=* c #4E72D5",
-"-* c #5173D5",
-";* c #5375D6",
-">* c #597BDA",
-",* c #5B7DDA",
-"'* c #5C7EDB",
-")* c #5D7FDB",
-"!* c #5E80DB",
-"~* c #5E81DA",
-"{* c #5F81DB",
-"]* c #5F82DB",
-"^* c #6384DD",
-"/* c #6384DE",
-"(* c #6585DF",
-"_* c #6486E0",
-":* c #6583DD",
-"<* c #6386E0",
-"[* c #6686E0",
-"}* c #6B86DD",
-"|* c #6D86DD",
-"1* c #6086E0",
-"2* c #5573CD",
-"3* c #3959C3",
-"4* c #3959C4",
-"5* c #3759C0",
-"6* c #375BC7",
-"7* c #365CC7",
-"8* c #395FCC",
-"9* c #3B62CE",
-"0* c #3E64D0",
-"a* c #4066D1",
-"b* c #4166D1",
-"c* c #4064CF",
-"d* c #4065CF",
-"e* c #4266D0",
-"f* c #4468D1",
-"g* c #4569D1",
-"h* c #476BD2",
-"i* c #466AD1",
-"j* c #476AD2",
-"k* c #456AD1",
-"l* c #496DD2",
-"m* c #4A6FD3",
-"n* c #496ED2",
-"o* c #4B70D4",
-"p* c #4D71D4",
-"q* c #4E72D4",
-"r* c #5073D4",
-"s* c #5174D5",
-"t* c #5175D5",
-"u* c #5276D6",
-"v* c #5377D6",
-"w* c #5478D7",
-"x* c #5579D7",
-"y* c #567AD8",
-"z* c #577BD9",
-"A* c #597CD8",
-"B* c #5A7DD9",
-"C* c #5A7ED9",
-"D* c #5B7FDA",
-"E* c #5C80DA",
-"F* c #5D80DA",
-"G* c #5E81DB",
-"H* c #5D80DB",
-"I* c #6082DC",
-"J* c #6183DD",
-"K* c #6183DE",
-"L* c #6082DB",
-"M* c #6282DE",
-"N* c #6682DE",
-"O* c #6583DE",
-"P* c #3759BF",
-"Q* c #375AC2",
-"R* c #375AC1",
-"S* c #375AC4",
-"T* c #395DCA",
-"U* c #3A5ECA",
-"V* c #3C60CC",
-"W* c #3D61CD",
-"X* c #3D61CC",
-"Y* c #3C61CD",
-"Z* c #3E62CD",
-"`* c #3F64CE",
-" = c #4266CF",
-".= c #4468D0",
-"+= c #4267CF",
-"@= c #4166CE",
-"#= c #4065CE",
-"$= c #4166CD",
-"%= c #4267CE",
-"&= c #456AD0",
-"*= c #4368CE",
-"== c #4468CF",
-"-= c #4569D0",
-";= c #486BD1",
-">= c #4B6FD3",
-",= c #4C70D3",
-"'= c #4F73D4",
-")= c #5275D5",
-"!= c #5477D6",
-"~= c #577BD7",
-"{= c #587CD8",
-"]= c #577CD8",
-"^= c #597DD9",
-"/= c #5A7DDA",
-"(= c #597DDA",
-"_= c #587CDA",
-":= c #5A7EDA",
-"<= c #567BD8",
-"[= c #557AD9",
-"}= c #567BD9",
-"|= c #577CD9",
-"1= c #587DD9",
-"2= c #587ED9",
-"3= c #577ED8",
-"4= c #587DD8",
-"5= c #587ED8",
-"6= c #567ED7",
-"7= c #526ABD",
-"8= c #3759C1",
-"9= c #385BC7",
-"0= c #395CC8",
-"a= c #3B5DC9",
-"b= c #3B5ECA",
-"c= c #3A5FCA",
-"d= c #3B60CC",
-"e= c #3C61CC",
-"f= c #3D62CD",
-"g= c #3E63CD",
-"h= c #3C61CB",
-"i= c #3C61CA",
-"j= c #3D62CB",
-"k= c #3F64CC",
-"l= c #4065CD",
-"m= c #4669D0",
-"n= c #476AD0",
-"o= c #496BD1",
-"p= c #4A6DD2",
-"q= c #4B6ED2",
-"r= c #4D71D3",
-"s= c #4E73D4",
-"t= c #4F74D4",
-"u= c #5075D5",
-"v= c #5276D5",
-"w= c #5377D7",
-"x= c #5278D7",
-"y= c #5277D6",
-"z= c #5378D7",
-"A= c #5379D8",
-"B= c #5379D9",
-"C= c #5278D8",
-"D= c #5178D7",
-"E= c #3355C0",
-"F= c #3556C1",
-"G= c #395AC6",
-"H= c #385AC7",
-"I= c #395BC7",
-"J= c #395EC9",
-"K= c #395FCA",
-"L= c #3B60CA",
-"M= c #3B60CB",
-"N= c #375DC7",
-"O= c #385EC8",
-"P= c #395FC9",
-"Q= c #3A60CA",
-"R= c #3D63CC",
-"S= c #4367CF",
-"T= c #476BD1",
-"U= c #4A6ED2",
-"V= c #4B6FD2",
-"W= c #4C6FD2",
-"X= c #4D70D1",
-"Y= c #4E71D2",
-"Z= c #4E72D2",
-"`= c #4E74D4",
-" - c #4E75D5",
-".- c #4E75D4",
-"+- c #4F75D3",
-"@- c #5075D2",
-"#- c #5075D3",
-"$- c #5177D7",
-"%- c #5178D8",
-"&- c #4F75D5",
-"*- c #5076D5",
-"=- c #4F76D6",
-"-- c #5279D9",
-";- c #3C52B1",
-">- c #3656C3",
-",- c #3757C5",
-"'- c #3758C6",
-")- c #3759C6",
-"!- c #375BC6",
-"~- c #385CC7",
-"{- c #385DC8",
-"]- c #365CC6",
-"^- c #355BC6",
-"/- c #355CC6",
-"(- c #365DC7",
-"_- c #375EC8",
-":- c #375CC6",
-"<- c #385EC6",
-"[- c #3A5FC7",
-"}- c #3C60C8",
-"|- c #3D61C9",
-"1- c #3E62CA",
-"2- c #4063CC",
-"3- c #4165CE",
-"4- c #4268D0",
-"5- c #4269D1",
-"6- c #436AD2",
-"7- c #446AD2",
-"8- c #456BD2",
-"9- c #496CD1",
-"0- c #4C6CD0",
-"a- c #4D6CCF",
-"b- c #4E6DD0",
-"c- c #4F6ECF",
-"d- c #4E6FCF",
-"e- c #4C70CF",
-"f- c #4A71D0",
-"g- c #4F6FCF",
-"h- c #4B71D0",
-"i- c #4A72D1",
-"j- c #4B73D4",
-"k- c #4F70D0",
-"l- c #4C73D3",
-"m- c #4C73D6",
-"n- c #4B72D2",
-"o- c #4B71D1",
-"p- c #4C73D7",
-"q- c #3354C0",
-"r- c #3152BE",
-"s- c #3052BE",
-"t- c #3051BF",
-"u- c #2E4FBF",
-"v- c #2E4FBE",
-"w- c #2E50BF",
-"x- c #2F50BF",
-"y- c #3156C4",
-"z- c #2F56C5",
-"A- c #2E57C5",
-"B- c #2F57C5",
-"C- c #3057C6",
-"D- c #3258C6",
-"E- c #3459C7",
-"F- c #365AC7",
-"G- c #385BC8",
-"H- c #3B5DCA",
-"I- c #3B5DCB",
-"J- c #3C5ECC",
-"K- c #3C60CD",
-"L- c #3C62CE",
-"M- c #3D65D0",
-"N- c #3D66D1",
-"O- c #4166D2",
-"P- c #4667D2",
-"Q- c #4A67D1",
-"R- c #4C68D0",
-"S- c #4C69CF",
-"T- c #4D6BCE",
-"U- c #4E6DCD",
-"V- c #4E6ECE",
-"W- c #4E6DCE",
-"X- c #4970D0",
-"Y- c #4770D0",
-"Z- c #4B6BCE",
-"`- c #4A6CCE",
-" ; c #496DCF",
-".; c #476FD0",
-"+; c #4870D0",
-"@; c #486DCF",
-"#; c #242F79",
-"$; c #2F41AC",
-"%; c #2040B8",
-"&; c #2041B8",
-"*; c #2243B3",
-"=; c #2243B8",
-"-; c #2343B8",
-";; c #2444B8",
-">; c #2445B8",
-",; c #2445B6",
-"'; c #2445B7",
-"); c #2444B9",
-"!; c #2949BE",
-"~; c #2649BF",
-"{; c #234BBF",
-"]; c #224CBF",
-"^; c #224AC0",
-"/; c #244CC0",
-"(; c #254DC0",
-"_; c #254DC1",
-":; c #264DC2",
-"<; c #274EC3",
-"[; c #274CC3",
-"}; c #274DC4",
-"|; c #254DC5",
-"1; c #214EC5",
-"2; c #204FC6",
-"3; c #1F50C8",
-"4; c #2151C9",
-"5; c #2B53C8",
-"6; c #3154C7",
-"7; c #3255C6",
-"8; c #2F57C7",
-"9; c #2C58C9",
-"0; c #2D59CA",
-"a; c #2D58C9",
-"b; c #2E5BCC",
-"c; c #325ECC",
-"d; c #325ECB",
-"e; c #1F40B1",
-"f; c #1F40B2",
-"g; c #1F40B3",
-"h; c #2A44BD",
-"i; c #2845BE",
-"j; c #2745BE",
-"k; c #2646BF",
-"l; c #2546BE",
-"m; c #2347BF",
-"n; c #2147BF",
-"o; c #2048C0",
-"p; c #1D48C0",
-"q; c #1C48C0",
-"r; c #1B47C0",
-"s; c #1C48BF",
-"t; c #1E49BE",
-"u; c #214ABD",
-"v; c #244CBD",
-"w; c #264DBE",
-"x; c #254EC0",
-"y; c #214FC2",
-"z; c #1B51C5",
-"A; c #1C51C7",
-"B; c #2250C8",
-"C; c #2A52C8",
-"D; c #3254C6",
-"E; c #3355C5",
-"F; c #3154C8",
-"G; c #3355C6",
-"H; c #2F57C8",
-"I; c #2E58C9",
-"J; c #2E59C9",
-"K; c #3059C9",
-"L; c #2040B6",
-"M; c #2743BB",
-"N; c #2844BC",
-"O; c #2743BD",
-"P; c #2844BE",
-"Q; c #2844BD",
-"R; c #2346BE",
-"S; c #2047BF",
-"T; c #1E48C0",
-"U; c #1D47C0",
-"V; c #1D49BF",
-"W; c #1F49BF",
-"X; c #204ABE",
-"Y; c #254DBF",
-"Z; c #234EC0",
-"`; c #2050C1",
-" > c #1C51C3",
-".> c #1F51C6",
-"+> c #2651C8",
-"@> c #2D53C7",
-"#> c #3155C6",
-"$> c #3155C7",
-"%> c #3355C7",
-"&> c #3254C7",
-"*> c #1E40B1",
-"=> c #2141B8",
-"-> c #2442B9",
-";> c #2744BB",
-">> c #2945BB",
-",> c #2A45BB",
-"'> c #2944BA",
-")> c #2745BB",
-"!> c #2545BC",
-"~> c #2246BD",
-"{> c #2047BE",
-"]> c #1F47BD",
-"^> c #1D48BE",
-"/> c #1E49C0",
-"(> c #1F4AC0",
-"_> c #214BBF",
-":> c #244CBE",
-"<> c #254DBE",
-"[> c #244DBE",
-"}> c #224FBF",
-"|> c #2051C1",
-"1> c #2151C3",
-"2> c #2252C5",
-"3> c #2151C1",
-"4> c #2851C6",
-"5> c #2A50C6",
-"6> c #2E54C6",
-"7> c #1F51C2",
-"8> c #1D52C5",
-"9> c #2651C9",
-"0> c #2950C7",
-"a> c #2D40A5",
-"b> c #2040B0",
-"c> c #1F40B0",
-"d> c #223CAE",
-"e> c #233CAE",
-"f> c #253BAC",
-"g> c #253BAD",
-"h> c #233CB0",
-"i> c #213EB2",
-"j> c #1F3FB4",
-"k> c #1E40B6",
-"l> c #1F3FB7",
-"m> c #1E3EB8",
-"n> c #1F3FB8",
-"o> c #2040B7",
-"p> c #2141B6",
-"q> c #2140B7",
-"r> c #2241B6",
-"s> c #2342B5",
-"t> c #2442B6",
-"u> c #2543B5",
-"v> c #2643B4",
-"w> c #2544B6",
-"x> c #2346B8",
-"y> c #2247B9",
-"z> c #2048BC",
-"A> c #1F48BF",
-"B> c #2049C0",
-"C> c #214AC0",
-"D> c #224BBF",
-"E> c #234CBE",
-"F> c #244DBF",
-"G> c #234CBF",
-"H> c #264DC0",
-"I> c #274EBF",
-"J> c #264DBF",
-"K> c #254EBF",
-"L> c #2050C0",
-"M> c #1F51C1",
-"N> c #1E42A4",
-"O> c #263BA6",
-"P> c #253BA7",
-"Q> c #253CA7",
-"R> c #1E41A5",
-"S> c #1F40AF",
-"T> c #273AAC",
-"U> c #1E40B0",
-"V> c #1F40B5",
-"W> c #1F40B6",
-"X> c #1F40B8",
-"Y> c #1E40B8",
-"Z> c #1F3EB8",
-"`> c #203FB7",
-" , c #2240B6",
-"., c #2341B7",
-"+, c #2345B9",
-"@, c #2147BB",
-"#, c #2148BA",
-"$, c #2049BB",
-"%, c #2049BD",
-"&, c #2049BF",
-"*, c #224BBE",
-"=, c #244DBD",
-"-, c #244CBF",
-";, c #182969",
-">, c #273BAD",
-",, c #2739AB",
-"', c #263AAC",
-"), c #243CAE",
-"!, c #233DAE",
-"~, c #213EAF",
-"{, c #1F3FB0",
-"], c #2040B4",
-"^, c #1F3FB6",
-"/, c #1E3EB7",
-"(, c #2240B7",
-"_, c #2341B6",
-":, c #2543B4",
-"<, c #2644B3",
-"[, c #2544B5",
-"}, c #2545B5",
-"|, c #2547B6",
-"1, c #2548B7",
-"2, c #2349BA",
-"3, c #1F49BE",
-"4, c #2149BD",
-"5, c #2049BE",
-"6, c #214BBE",
-"7, c #2249BE",
-"8, c #234CBD",
-"9, c #2149BE",
-"0, c #1E49BF",
-"a, c #253BA9",
-"b, c #253BAB",
-"c, c #263AAB",
-"d, c #213DAF",
-"e, c #203EAF",
-"f, c #1D40AF",
-"g, c #1D40B0",
-"h, c #1E40B4",
-"i, c #2241B7",
-"j, c #2643B6",
-"k, c #2744B5",
-"l, c #2643B5",
-"m, c #2346B6",
-"n, c #2147B7",
-"o, c #2644B6",
-"p, c #2247B7",
-"q, c #2248B8",
-"r, c #2647B7",
-"s, c #2549B7",
-"t, c #2645B7",
-"u, c #2148B8",
-"v, c #2847B6",
-"w, c #2549B6",
-"x, c #2849B6",
-"y, c #2049B7",
-"z, c #2A49B5",
-"A, c #243BA4",
-"B, c #253BA5",
-"C, c #253BA6",
-"D, c #263AA7",
-"E, c #263AA8",
-"F, c #2739AA",
-"G, c #243CAD",
-"H, c #223DAE",
-"I, c #1F3EAF",
-"J, c #1E3FB0",
-"K, c #1D40B1",
-"L, c #1E3FB1",
-"M, c #1F3FB3",
-"N, c #1F3FB5",
-"O, c #2140B6",
-"P, c #2140B8",
-"Q, c #2744B4",
-"R, c #2746B6",
-"S, c #2947B6",
-"T, c #2946B5",
-"U, c #2A48B6",
-"V, c #3551A8",
-"W, c #1F399C",
-"X, c #143D9F",
-"Y, c #263BA5",
-"Z, c #273BA8",
-"`, c #273BAA",
-" ' c #263AAD",
-".' c #233CAD",
-"+' c #213DAE",
-"@' c #203FB2",
-"#' c #2342B6",
-"$' c #2443B6",
-"%' c #2543B6",
-"&' c #2644B5",
-"*' c #133D9E",
-"=' c #263BA7",
-"-' c #263BA9",
-";' c #273BA9",
-">' c #263AAA",
-",' c #2539AB",
-"'' c #2639AB",
-")' c #253AAC",
-"!' c #243BAD",
-"~' c #223DAF",
-"{' c #203FB0",
-"]' c #2040B1",
-"^' c #2140B3",
-"/' c #2543B1",
-"(' c #2744AF",
-"_' c #1A3CA0",
-":' c #1D3BA2",
-"<' c #233BA4",
-"[' c #263AA5",
-"}' c #253AA5",
-"|' c #263AA6",
-"1' c #263BA4",
-"2' c #243BA5",
-"3' c #263BA8",
-"4' c #223EAF",
-"5' c #3B4CA5",
-"6' c #1D379A",
-"7' c #1E389C",
-"8' c #1E399F",
-"9' c #1F3BA2",
-"0' c #1F3BA3",
-"a' c #213BA4",
-"b' c #233AA3",
-"c' c #243AA3",
-"d' c #2539A4",
-"e' c #253AA6",
-"f' c #243BA7",
-"g' c #253CAA",
-"h' c #253CAC",
-"i' c #253CAD",
-"j' c #253CAE",
-"k' c #243DAE",
-"l' c #213FAF",
-"m' c #223FAF",
-"n' c #2040AF",
-"o' c #253D93",
-"p' c #1D3894",
-"q' c #1F379A",
-"r' c #1E389B",
-"s' c #1D399C",
-"t' c #1C3A9D",
-"u' c #1B3A9D",
-"v' c #183B9E",
-"w' c #163C9E",
-"x' c #153C9E",
-"y' c #163B9D",
-"z' c #173B9D",
-"A' c #193A9D",
-"B' c #1C3A9E",
-"C' c #1F3AA1",
-"D' c #223AA4",
-"E' c #253BA8",
-"F' c #273BA7",
-"G' c #263CAB",
-"H' c #263CAC",
-"I' c #243EAE",
-"J' c #273BAC",
-"K' c #2A3795",
-"L' c #1F389B",
-"M' c #1D389B",
-"N' c #1C399C",
-"O' c #1B399C",
-"P' c #1A3A9D",
-"Q' c #1D399B",
-"R' c #1B399B",
-"S' c #1A3A9C",
-"T' c #1B3A9F",
-"U' c #1D3AA0",
-"V' c #203BA2",
-"W' c #203BA3",
-"X' c #2639A6",
-"Y' c #1B3692",
-"Z' c #1C3794",
-"`' c #1D3796",
-" ) c #1E3898",
-".) c #1E389A",
-"+) c #1F399B",
-"@) c #1A399C",
-"#) c #193A9E",
-"$) c #1A3BA0",
-"%) c #1C3BA2",
-"&) c #1D3CA3",
-"*) c #203CA4",
-"=) c #223BA5",
-"-) c #3C4699",
-";) c #2B4595",
-">) c #1C3793",
-",) c #1D3895",
-"') c #1E3897",
-")) c #1F3998",
-"!) c #1F3999",
-"~) c #1F399A",
-"{) c #1E399C",
-"]) c #1C3B9E",
-"^) c #1D3BA0",
-"/) c #1E3CA2",
-"() c #223CA5",
-"_) c #243CA6",
-":) c #596FA9",
-"<) c #3B4894",
-"[) c #314993",
-"}) c #29499F",
-"|) c #28489E",
-"1) c #2B4BA1",
-"2) c #2C4BA1",
-"3) c #2D4CA2",
-"4) c #2E4CA3",
-"5) c #2F4CA4",
-"6) c #2E4CA4",
-"7) c #2F4DA3",
-"8) c #2F4DA4",
-"9) c #D3D5D2",
-"0) c #3B4794",
-"a) c #314791",
-"b) c #304892",
-"c) c #304893",
-"d) c #2F4995",
-"e) c #2F4997",
-"f) c #2D4A9A",
-"g) c #2A4A9D",
-"h) c #294A9F",
-"i) c #284AA0",
-"j) c #294AA0",
-"k) c #2B4AA1",
-"l) c #2D4CA3",
-"m) c #C9CAC9",
-"n) c #455D9B",
-"o) c #242F78",
-"p) c #1B2F85",
-"q) c #C6C3C8",
-"r) c #B5B2B6",
-"s) c #B5B7B4",
-"t) c #B5B7B3",
-"u) c #B5B2B5",
-"v) c #B5B3B4",
-"w) c #B5B5B4",
-"x) c #B5B6B3",
-"y) c #B5B4B4",
-"z) c #B5B3B5",
-"A) c #B5B4B5",
-"B) c #B5B5B5",
-"C) c #B5B5B3",
-"D) c #B5B5B6",
-"E) c #BAC3BE",
-"F) c #B9C3BD",
-"G) c #C1C3C4",
-"H) c #BFC3C2",
-"I) c #B9C3BE",
-"J) c #BBC3BF",
-"K) c #BDC3C1",
-"L) c #C0C3C3",
-"M) c #BEC3C1",
-"N) c #C2C3C5",
-"O) c #E6E3E8",
-"P) c #E0E2DF",
-"Q) c #E1E1E1",
-"R) c #E2E1E3",
-"S) c #E4E1E6",
-"T) c #E4E2E7",
-"U) c #E4E2E6",
-"V) c #E3E3E4",
-"W) c #E2E3E3",
-"X) c #E1E3E2",
-"Y) c #E3E3E3",
-"Z) c #E3E3E2",
-"`) c #EBEDEA",
-" ! c #EAECE9",
-".! c #E9EBE8",
-"+! c #ECEEEB",
+" c None",
+". c #FBFBFC",
+"+ c #E8EAE7",
+"@ c #758DC3",
+"# c #42599E",
+"$ c #28418A",
+"% c #19418F",
+"& c #3F5695",
+"* c #415896",
+"= c #435A98",
+"- c #445C99",
+"; c #465E9B",
+"> c #48609B",
+", c #49629C",
+"' c #4A639D",
+") c #49639D",
+"! c #4A629D",
+"~ c #4B639D",
+"{ c #4B649D",
+"] c #4C659D",
+"^ c #4D669D",
+"/ c #4E689D",
+"( c #506A9D",
+"_ c #516A9D",
+": c #536B9C",
+"< c #546C9C",
+"[ c #566D9B",
+"} c #576D9B",
+"| c #586E9C",
+"1 c #5B6F9D",
+"2 c #61739D",
+"3 c #63749E",
+"4 c #64749E",
+"5 c #68769E",
+"6 c #6A779E",
+"7 c #6B789E",
+"8 c #66759E",
+"9 c #6C789D",
+"0 c #EEF0ED",
+"a c #D0D3DC",
+"b c #3E51A3",
+"c c #28428B",
+"d c #29428C",
+"e c #425996",
+"f c #455C99",
+"g c #485F9C",
+"h c #49619E",
+"i c #4A63A0",
+"j c #4B64A1",
+"k c #4B65A1",
+"l c #4C66A2",
+"m c #4D67A2",
+"n c #4F69A1",
+"o c #516AA1",
+"p c #536CA0",
+"q c #556DA1",
+"r c #576EA0",
+"s c #586F9F",
+"t c #586E9F",
+"u c #596F9E",
+"v c #5A6F9E",
+"w c #5C709E",
+"x c #5E719E",
+"y c #5F729F",
+"z c #62739F",
+"A c #63739E",
+"B c #64749D",
+"C c #65749E",
+"D c #69769D",
+"E c #6C799E",
+"F c #6D799F",
+"G c #707D9F",
+"H c #717F9E",
+"I c #6E7AA1",
+"J c #6C789E",
+"K c #6F7C9C",
+"L c #6F7D9B",
+"M c #2A4AA0",
+"N c #4971D0",
+"O c #4C72D8",
+"P c #5472C0",
+"Q c #5573BF",
+"R c #5774BF",
+"S c #5875BF",
+"T c #5976C1",
+"U c #5A76C1",
+"V c #5C78C2",
+"W c #5E7AC2",
+"X c #607CC3",
+"Y c #627EC3",
+"Z c #637FC4",
+"` c #6581C5",
+" . c #6682C6",
+".. c #6783C7",
+"+. c #6984C8",
+"@. c #6B85C9",
+"#. c #6D87CA",
+"$. c #6F89CB",
+"%. c #718CCD",
+"&. c #748ECF",
+"*. c #7690D0",
+"=. c #7992D2",
+"-. c #7A93D3",
+";. c #7C95D5",
+">. c #7F98D7",
+",. c #8099D8",
+"'. c #859CDB",
+"). c #8AA0DD",
+"!. c #8DA3DF",
+"~. c #8FA5E0",
+"{. c #90A5E0",
+"]. c #91A6E1",
+"^. c #91A5E1",
+"/. c #90A4E0",
+"(. c #8EA3DE",
+"_. c #92A6E2",
+":. c #8FA4DF",
+"<. c #90A5DE",
+"[. c #90A5DC",
+"}. c #90A6DB",
+"|. c #91A6E0",
+"1. c #93A7E2",
+"2. c #95AAE6",
+"3. c #99AEEA",
+"4. c #9AB2EA",
+"5. c #99B1E9",
+"6. c #99B1E7",
+"7. c #98AFE6",
+"8. c #93A8E2",
+"9. c #97ACE7",
+"0. c #9AB3EB",
+"a. c #9DB5ED",
+"b. c #9DB6EE",
+"c. c #375095",
+"d. c #4056AD",
+"e. c #506DCD",
+"f. c #4360CC",
+"g. c #345ED6",
+"h. c #335ECF",
+"i. c #355ED6",
+"j. c #355FD6",
+"k. c #365FD6",
+"l. c #355FD0",
+"m. c #3760D5",
+"n. c #3A63D4",
+"o. c #3C63D1",
+"p. c #3B63CD",
+"q. c #3B63C9",
+"r. c #3B62C9",
+"s. c #3D63C8",
+"t. c #4065C5",
+"u. c #4567C5",
+"v. c #496BC5",
+"w. c #4F70C7",
+"x. c #5273C8",
+"y. c #5475CA",
+"z. c #5777CB",
+"A. c #5879CD",
+"B. c #5A7BCE",
+"C. c #5D7DCF",
+"D. c #5F7ECF",
+"E. c #617FD0",
+"F. c #6381D1",
+"G. c #6583D2",
+"H. c #6785D2",
+"I. c #6886D3",
+"J. c #6A88D4",
+"K. c #6C89D5",
+"L. c #6E8BD6",
+"M. c #708CD7",
+"N. c #718DD8",
+"O. c #738EDA",
+"P. c #748FDB",
+"Q. c #7691DC",
+"R. c #7893DD",
+"S. c #7994DD",
+"T. c #7A96DE",
+"U. c #7B97DF",
+"V. c #7C98E0",
+"W. c #7E9AE2",
+"X. c #7F9BE3",
+"Y. c #829DE4",
+"Z. c #849FE5",
+"`. c #87A0E6",
+" + c #88A1E7",
+".+ c #89A2E6",
+"++ c #8CA3E7",
+"@+ c #8EA5E9",
+"#+ c #8EA6E9",
+"$+ c #8FA7E9",
+"%+ c #8FA8E8",
+"&+ c #8FA9E8",
+"*+ c #91A9E8",
+"=+ c #90A7E8",
+"-+ c #8FA8EA",
+";+ c #90AAEA",
+">+ c #93ABEA",
+",+ c #95ABEA",
+"'+ c #93ABE9",
+")+ c #94ABEA",
+"!+ c #90A9EA",
+"~+ c #93AAE9",
+"{+ c #273E7E",
+"]+ c #345ED5",
+"^+ c #3D60CE",
+"/+ c #3D60CF",
+"(+ c #345ECF",
+"_+ c #335ED0",
+":+ c #355FD3",
+"<+ c #3A60CE",
+"[+ c #3A5FCB",
+"}+ c #385FC9",
+"|+ c #3B60C8",
+"1+ c #3C63CB",
+"2+ c #3E64CB",
+"3+ c #4166CA",
+"4+ c #4568C9",
+"5+ c #4A6CC7",
+"6+ c #4F71C8",
+"7+ c #5172CA",
+"8+ c #5475CE",
+"9+ c #5678D3",
+"0+ c #597CD6",
+"a+ c #5C7ED7",
+"b+ c #5E7FD8",
+"c+ c #6181D9",
+"d+ c #6383DA",
+"e+ c #6585DA",
+"f+ c #6786DB",
+"g+ c #6988DC",
+"h+ c #6B8ADD",
+"i+ c #6D8BDE",
+"j+ c #6F8DDE",
+"k+ c #718EDF",
+"l+ c #728FE0",
+"m+ c #7390E1",
+"n+ c #7390E2",
+"o+ c #7491E3",
+"p+ c #7592E4",
+"q+ c #7693E4",
+"r+ c #7794E5",
+"s+ c #7894E5",
+"t+ c #7995E6",
+"u+ c #7B96E6",
+"v+ c #7C97E7",
+"w+ c #7D9AE8",
+"x+ c #7F9CE9",
+"y+ c #829DE9",
+"z+ c #849EE9",
+"A+ c #859EE9",
+"B+ c #87A0E7",
+"C+ c #8AA2E7",
+"D+ c #8BA3E8",
+"E+ c #89A2E7",
+"F+ c #8CA6EA",
+"G+ c #8BA6EA",
+"H+ c #8BA7EA",
+"I+ c #8CA3E8",
+"J+ c #8BA8EA",
+"K+ c #8CA7EA",
+"L+ c #8CA8EA",
+"M+ c #4659C7",
+"N+ c #355ECF",
+"O+ c #3660CF",
+"P+ c #3860CE",
+"Q+ c #3961CD",
+"R+ c #3B61CB",
+"S+ c #3B61CA",
+"T+ c #3D62CA",
+"U+ c #3D63CA",
+"V+ c #4165CB",
+"W+ c #456ACB",
+"X+ c #4B6FCD",
+"Y+ c #5174CE",
+"Z+ c #5275D1",
+"`+ c #5477D4",
+" @ c #5678D9",
+".@ c #587ADB",
+"+@ c #597BDB",
+"@@ c #5B7DDC",
+"#@ c #5E7FDC",
+"$@ c #6081DD",
+"%@ c #6283DE",
+"&@ c #6484DF",
+"*@ c #6787E0",
+"=@ c #6989E1",
+"-@ c #6B8BE1",
+";@ c #6D8DE2",
+">@ c #6F8EE3",
+",@ c #718FE4",
+"'@ c #7290E4",
+")@ c #7491E5",
+"!@ c #7692E6",
+"~@ c #7793E5",
+"{@ c #7894E6",
+"]@ c #7895E7",
+"^@ c #7996E8",
+"/@ c #7A97E8",
+"(@ c #7B98E9",
+"_@ c #7D99E8",
+":@ c #7F9AE8",
+"<@ c #7F9BE9",
+"[@ c #7F9CEA",
+"}@ c #859EE8",
+"|@ c #859FE8",
+"1@ c #85A0E9",
+"2@ c #869FE9",
+"3@ c #86A1E7",
+"4@ c #86A0E9",
+"5@ c #87A1E7",
+"6@ c #88A2E7",
+"7@ c #87A1E9",
+"8@ c #5A6FCA",
+"9@ c #365FCF",
+"0@ c #345ED0",
+"a@ c #385FCC",
+"b@ c #385FCE",
+"c@ c #3A61CC",
+"d@ c #3B62CD",
+"e@ c #3E64CD",
+"f@ c #4167CF",
+"g@ c #4469CF",
+"h@ c #486CD1",
+"i@ c #4D71D2",
+"j@ c #5175D4",
+"k@ c #5376D6",
+"l@ c #5578DA",
+"m@ c #5679DC",
+"n@ c #587BDD",
+"o@ c #5A7DDE",
+"p@ c #5D80DE",
+"q@ c #5F82DF",
+"r@ c #6284DF",
+"s@ c #6585E0",
+"t@ c #6787E1",
+"u@ c #6988E2",
+"v@ c #6B8AE2",
+"w@ c #6D8CE3",
+"x@ c #6E8DE3",
+"y@ c #708EE4",
+"z@ c #718FE3",
+"A@ c #7391E4",
+"B@ c #7592E5",
+"C@ c #7895E5",
+"D@ c #7996E6",
+"E@ c #7A97E6",
+"F@ c #7B98E7",
+"G@ c #7A98E8",
+"H@ c #7B99E9",
+"I@ c #7E9AE9",
+"J@ c #7D9AE9",
+"K@ c #7E9AEA",
+"L@ c #809CE9",
+"M@ c #819DE8",
+"N@ c #7F9BEA",
+"O@ c #819DE9",
+"P@ c #819CE9",
+"Q@ c #839EE9",
+"R@ c #839EE8",
+"S@ c #839DEA",
+"T@ c #859FE9",
+"U@ c #87A0E8",
+"V@ c #86A0E8",
+"W@ c #87A1E8",
+"X@ c #3760CF",
+"Y@ c #3A61CE",
+"Z@ c #3A62CD",
+"`@ c #3F66CE",
+" # c #4368D0",
+".# c #466CD2",
+"+# c #496DD5",
+"@# c #4E72D6",
+"## c #5175D8",
+"$# c #5276DA",
+"%# c #5578DC",
+"&# c #577ADC",
+"*# c #597CDD",
+"=# c #5B7DDD",
+"-# c #5D7FDE",
+";# c #5E81DE",
+"># c #6183DF",
+",# c #6386DF",
+"'# c #6687E0",
+")# c #6888E0",
+"!# c #6A89E1",
+"~# c #6C8AE1",
+"{# c #6E8CE2",
+"]# c #6F8DE2",
+"^# c #7390E4",
+"/# c #7390E3",
+"(# c #7491E4",
+"_# c #7693E5",
+":# c #7895E6",
+"<# c #7896E6",
+"[# c #7997E7",
+"}# c #7B97E7",
+"|# c #7B98E8",
+"1# c #7C98E8",
+"2# c #7E9BE9",
+"3# c #809CEA",
+"4# c #819CEA",
+"5# c #839DE9",
+"6# c #365FD0",
+"7# c #3660D0",
+"8# c #3961CF",
+"9# c #3B63CF",
+"0# c #3D64D0",
+"a# c #4067D0",
+"b# c #4469D2",
+"c# c #466BD3",
+"d# c #496ED5",
+"e# c #4C71D6",
+"f# c #4E72D8",
+"g# c #5074D9",
+"h# c #5376DB",
+"i# c #5578DB",
+"j# c #587ADC",
+"k# c #5B7CDC",
+"l# c #5D7EDD",
+"m# c #5F80DD",
+"n# c #6081DE",
+"o# c #6383DE",
+"p# c #6686DF",
+"q# c #6887E0",
+"r# c #6988E0",
+"s# c #6B89E1",
+"t# c #6C8AE0",
+"u# c #6E8CE1",
+"v# c #708EE2",
+"w# c #718FE2",
+"x# c #7290E3",
+"y# c #7391E2",
+"z# c #7492E1",
+"A# c #7592E2",
+"B# c #7691E3",
+"C# c #7591E3",
+"D# c #7692E3",
+"E# c #7693E3",
+"F# c #7793E4",
+"G# c #7893E4",
+"H# c #7994E5",
+"I# c #7D97E8",
+"J# c #7E98E8",
+"K# c #7D98E8",
+"L# c #7D99E9",
+"M# c #7D9BEA",
+"N# c #7D9CEA",
+"O# c #7E99E8",
+"P# c #7D9AEA",
+"Q# c #7C9BEA",
+"R# c #7C9CEA",
+"S# c #355FCF",
+"T# c #3860D0",
+"U# c #3A62D0",
+"V# c #3C64D1",
+"W# c #4167D1",
+"X# c #4369D3",
+"Y# c #466BD4",
+"Z# c #486DD5",
+"`# c #4A6ED7",
+" $ c #4C70D8",
+".$ c #5478D9",
+"+$ c #577BDA",
+"@$ c #597DDB",
+"#$ c #5B7EDB",
+"$$ c #5D7FDC",
+"%$ c #6182DE",
+"&$ c #6284DE",
+"*$ c #6485DF",
+"=$ c #6586DF",
+"-$ c #6787DF",
+";$ c #6888DF",
+">$ c #6A8ADF",
+",$ c #6C8BE0",
+"'$ c #6D8CE0",
+")$ c #6E8DE1",
+"!$ c #6F8DE1",
+"~$ c #708EE1",
+"{$ c #718FE0",
+"]$ c #728FE1",
+"^$ c #7390E0",
+"/$ c #738FE0",
+"($ c #7490E1",
+"_$ c #7590E1",
+":$ c #7591E1",
+"<$ c #7592E1",
+"[$ c #7692E2",
+"}$ c #7794E2",
+"|$ c #7894E3",
+"1$ c #7996E3",
+"2$ c #7A96E5",
+"3$ c #7B98E6",
+"4$ c #7B9AE8",
+"5$ c #7C99E8",
+"6$ c #7C96E5",
+"7$ c #7D97E7",
+"8$ c #7C99E9",
+"9$ c #7B9AE9",
+"0$ c #7B9AEA",
+"a$ c #5B6DCF",
+"b$ c #305EC8",
+"c$ c #335ECE",
+"d$ c #305ECA",
+"e$ c #345FCF",
+"f$ c #3761D0",
+"g$ c #3A62D1",
+"h$ c #3C64D2",
+"i$ c #4066D3",
+"j$ c #466BD5",
+"k$ c #486ED6",
+"l$ c #4A6ED6",
+"m$ c #4D71D8",
+"n$ c #4F72D9",
+"o$ c #5073D9",
+"p$ c #4F72D8",
+"q$ c #5074D8",
+"r$ c #5276D9",
+"s$ c #587ADA",
+"t$ c #5B7CDB",
+"u$ c #5D7EDC",
+"v$ c #5F7FDD",
+"w$ c #6081DC",
+"x$ c #6182DD",
+"y$ c #6283DD",
+"z$ c #6484DE",
+"A$ c #6585DD",
+"B$ c #6787DE",
+"C$ c #6988DF",
+"D$ c #6A89DE",
+"E$ c #6C8ADF",
+"F$ c #6D8BDF",
+"G$ c #6E8CE0",
+"H$ c #6F8DE0",
+"I$ c #718EE0",
+"J$ c #728FDF",
+"K$ c #728FDE",
+"L$ c #7290E0",
+"M$ c #7190E0",
+"N$ c #7291E0",
+"O$ c #7191E0",
+"P$ c #7392E1",
+"Q$ c #7493E1",
+"R$ c #7594E1",
+"S$ c #7594E2",
+"T$ c #7694E2",
+"U$ c #7695E2",
+"V$ c #7A96E4",
+"W$ c #7895E2",
+"X$ c #7A96E2",
+"Y$ c #7A96E3",
+"Z$ c #7B96E3",
+"`$ c #7996E1",
+" % c #7C96E4",
+".% c #305EC9",
+"+% c #315ECC",
+"@% c #325ECE",
+"#% c #3760D0",
+"$% c #3962D1",
+"%% c #3E66D3",
+"&% c #4268D4",
+"*% c #446BD5",
+"=% c #476CD6",
+"-% c #496ED7",
+";% c #4B6FD7",
+">% c #4C70D7",
+",% c #4E71D7",
+"'% c #5074D7",
+")% c #5276D8",
+"!% c #5376D8",
+"~% c #5779DA",
+"{% c #597ADA",
+"]% c #5A7BDB",
+"^% c #5B7CDA",
+"/% c #5D7EDB",
+"(% c #5E7FDB",
+"_% c #6182DB",
+":% c #6384DC",
+"<% c #6586DD",
+"[% c #6686DC",
+"}% c #6887DD",
+"|% c #6988DD",
+"1% c #6A8ADE",
+"2% c #6B8BDE",
+"3% c #6C8CDE",
+"4% c #6E8DDF",
+"5% c #6E8CDF",
+"6% c #6D8DDF",
+"7% c #6C8BDF",
+"8% c #6F8DDF",
+"9% c #718FDF",
+"0% c #7290DF",
+"a% c #7391E0",
+"b% c #7491E0",
+"c% c #7292E1",
+"d% c #3959C5",
+"e% c #345BC5",
+"f% c #315EC8",
+"g% c #355BC5",
+"h% c #325EC8",
+"i% c #315ECB",
+"j% c #345DCC",
+"k% c #335ECD",
+"l% c #345ECD",
+"m% c #355FCE",
+"n% c #3862D0",
+"o% c #3E66D2",
+"p% c #456BD5",
+"q% c #476CD5",
+"r% c #4B6ED7",
+"s% c #4B6FD6",
+"t% c #4B6FD5",
+"u% c #4D71D6",
+"v% c #5073D7",
+"w% c #5174D7",
+"x% c #5275D8",
+"y% c #5577D8",
+"z% c #5678D8",
+"A% c #5779D9",
+"B% c #587AD8",
+"C% c #597CD9",
+"D% c #5B7DD9",
+"E% c #5D7FDA",
+"F% c #5F80DB",
+"G% c #6182DC",
+"H% c #6484DC",
+"I% c #6585DC",
+"J% c #6787DD",
+"K% c #6988DE",
+"L% c #6B8ADE",
+"M% c #6B8ADF",
+"N% c #6989DE",
+"O% c #6B89DE",
+"P% c #6E8BDF",
+"Q% c #708CDE",
+"R% c #708DDF",
+"S% c #708FDF",
+"T% c #728EDF",
+"U% c #6F8EDD",
+"V% c #728EDD",
+"W% c #7390DF",
+"X% c #7490DF",
+"Y% c #335DC8",
+"Z% c #3759C5",
+"`% c #3859C5",
+" & c #335EC8",
+".& c #325DCA",
+"+& c #345CCB",
+"@& c #335DCC",
+"#& c #345DCD",
+"$& c #355FCD",
+"%& c #3861D0",
+"&& c #3B64D1",
+"*& c #3E65D2",
+"=& c #4168D3",
+"-& c #456AD5",
+";& c #4B6ED5",
+">& c #4C6FD4",
+",& c #4D70D5",
+"'& c #4F72D6",
+")& c #5173D6",
+"!& c #5375D7",
+"~& c #5476D8",
+"{& c #5577D7",
+"]& c #5477D8",
+"^& c #5677D8",
+"/& c #5879D9",
+"(& c #597AD9",
+"_& c #5C7DDA",
+":& c #6080DC",
+"<& c #6080DB",
+"[& c #6181DC",
+"}& c #6282DC",
+"|& c #6383DD",
+"1& c #6484DD",
+"2& c #6686DE",
+"3& c #6685DE",
+"4& c #6786DE",
+"5& c #6687DE",
+"6& c #6887DE",
+"7& c #6987DE",
+"8& c #6788DF",
+"9& c #6785DF",
+"0& c #6B89DF",
+"a& c #6C89DF",
+"b& c #6F8DDD",
+"c& c #6D8CDE",
+"d& c #445BBB",
+"e& c #3759BE",
+"f& c #375AC6",
+"g& c #355CC8",
+"h& c #345CCA",
+"i& c #355ECC",
+"j& c #365FCD",
+"k& c #3761CE",
+"l& c #3A63D0",
+"m& c #3D65D1",
+"n& c #466AD4",
+"o& c #476BD4",
+"p& c #486CD3",
+"q& c #4A6ED4",
+"r& c #4B6ED4",
+"s& c #4E71D6",
+"t& c #4F71D5",
+"u& c #5072D6",
+"v& c #5274D7",
+"w& c #5273D7",
+"x& c #5274D6",
+"y& c #5476D7",
+"z& c #5779D8",
+"A& c #587AD9",
+"B& c #5A7CDA",
+"C& c #5C7DDB",
+"D& c #5D7EDA",
+"E& c #6081DA",
+"F& c #6181DB",
+"G& c #6283DC",
+"H& c #6483DD",
+"I& c #6483DE",
+"J& c #6585DE",
+"K& c #6786DF",
+"L& c #6886DE",
+"M& c #6887DF",
+"N& c #6987DF",
+"O& c #6A88DF",
+"P& c #6786E0",
+"Q& c #6A86DE",
+"R& c #6B89E0",
+"S& c #365BC8",
+"T& c #365CC8",
+"U& c #375DCA",
+"V& c #375FCB",
+"W& c #3860CD",
+"X& c #3C63D0",
+"Y& c #4167D2",
+"Z& c #4268D2",
+"`& c #4368D2",
+" * c #4367D2",
+".* c #4568D2",
+"+* c #466AD2",
+"@* c #496CD3",
+"#* c #4A6DD3",
+"$* c #4A6DD4",
+"%* c #4D70D4",
+"&* c #4F72D5",
+"** c #4C70D4",
+"=* c #4E72D5",
+"-* c #5173D5",
+";* c #5375D6",
+">* c #597BDA",
+",* c #5B7DDA",
+"'* c #5C7EDB",
+")* c #5D7FDB",
+"!* c #5E80DB",
+"~* c #5E81DA",
+"{* c #5F81DB",
+"]* c #5F82DB",
+"^* c #6384DD",
+"/* c #6384DE",
+"(* c #6585DF",
+"_* c #6486E0",
+":* c #6583DD",
+"<* c #6386E0",
+"[* c #6686E0",
+"}* c #6B86DD",
+"|* c #6D86DD",
+"1* c #6086E0",
+"2* c #5573CD",
+"3* c #3959C3",
+"4* c #3959C4",
+"5* c #3759C0",
+"6* c #375BC7",
+"7* c #365CC7",
+"8* c #395FCC",
+"9* c #3B62CE",
+"0* c #3E64D0",
+"a* c #4066D1",
+"b* c #4166D1",
+"c* c #4064CF",
+"d* c #4065CF",
+"e* c #4266D0",
+"f* c #4468D1",
+"g* c #4569D1",
+"h* c #476BD2",
+"i* c #466AD1",
+"j* c #476AD2",
+"k* c #456AD1",
+"l* c #496DD2",
+"m* c #4A6FD3",
+"n* c #496ED2",
+"o* c #4B70D4",
+"p* c #4D71D4",
+"q* c #4E72D4",
+"r* c #5073D4",
+"s* c #5174D5",
+"t* c #5175D5",
+"u* c #5276D6",
+"v* c #5377D6",
+"w* c #5478D7",
+"x* c #5579D7",
+"y* c #567AD8",
+"z* c #577BD9",
+"A* c #597CD8",
+"B* c #5A7DD9",
+"C* c #5A7ED9",
+"D* c #5B7FDA",
+"E* c #5C80DA",
+"F* c #5D80DA",
+"G* c #5E81DB",
+"H* c #5D80DB",
+"I* c #6082DC",
+"J* c #6183DD",
+"K* c #6183DE",
+"L* c #6082DB",
+"M* c #6282DE",
+"N* c #6682DE",
+"O* c #6583DE",
+"P* c #3759BF",
+"Q* c #375AC2",
+"R* c #375AC1",
+"S* c #375AC4",
+"T* c #395DCA",
+"U* c #3A5ECA",
+"V* c #3C60CC",
+"W* c #3D61CD",
+"X* c #3D61CC",
+"Y* c #3C61CD",
+"Z* c #3E62CD",
+"`* c #3F64CE",
+" = c #4266CF",
+".= c #4468D0",
+"+= c #4267CF",
+"@= c #4166CE",
+"#= c #4065CE",
+"$= c #4166CD",
+"%= c #4267CE",
+"&= c #456AD0",
+"*= c #4368CE",
+"== c #4468CF",
+"-= c #4569D0",
+";= c #486BD1",
+">= c #4B6FD3",
+",= c #4C70D3",
+"'= c #4F73D4",
+")= c #5275D5",
+"!= c #5477D6",
+"~= c #577BD7",
+"{= c #587CD8",
+"]= c #577CD8",
+"^= c #597DD9",
+"/= c #5A7DDA",
+"(= c #597DDA",
+"_= c #587CDA",
+":= c #5A7EDA",
+"<= c #567BD8",
+"[= c #557AD9",
+"}= c #567BD9",
+"|= c #577CD9",
+"1= c #587DD9",
+"2= c #587ED9",
+"3= c #577ED8",
+"4= c #587DD8",
+"5= c #587ED8",
+"6= c #567ED7",
+"7= c #526ABD",
+"8= c #3759C1",
+"9= c #385BC7",
+"0= c #395CC8",
+"a= c #3B5DC9",
+"b= c #3B5ECA",
+"c= c #3A5FCA",
+"d= c #3B60CC",
+"e= c #3C61CC",
+"f= c #3D62CD",
+"g= c #3E63CD",
+"h= c #3C61CB",
+"i= c #3C61CA",
+"j= c #3D62CB",
+"k= c #3F64CC",
+"l= c #4065CD",
+"m= c #4669D0",
+"n= c #476AD0",
+"o= c #496BD1",
+"p= c #4A6DD2",
+"q= c #4B6ED2",
+"r= c #4D71D3",
+"s= c #4E73D4",
+"t= c #4F74D4",
+"u= c #5075D5",
+"v= c #5276D5",
+"w= c #5377D7",
+"x= c #5278D7",
+"y= c #5277D6",
+"z= c #5378D7",
+"A= c #5379D8",
+"B= c #5379D9",
+"C= c #5278D8",
+"D= c #5178D7",
+"E= c #3355C0",
+"F= c #3556C1",
+"G= c #395AC6",
+"H= c #385AC7",
+"I= c #395BC7",
+"J= c #395EC9",
+"K= c #395FCA",
+"L= c #3B60CA",
+"M= c #3B60CB",
+"N= c #375DC7",
+"O= c #385EC8",
+"P= c #395FC9",
+"Q= c #3A60CA",
+"R= c #3D63CC",
+"S= c #4367CF",
+"T= c #476BD1",
+"U= c #4A6ED2",
+"V= c #4B6FD2",
+"W= c #4C6FD2",
+"X= c #4D70D1",
+"Y= c #4E71D2",
+"Z= c #4E72D2",
+"`= c #4E74D4",
+" - c #4E75D5",
+".- c #4E75D4",
+"+- c #4F75D3",
+"@- c #5075D2",
+"#- c #5075D3",
+"$- c #5177D7",
+"%- c #5178D8",
+"&- c #4F75D5",
+"*- c #5076D5",
+"=- c #4F76D6",
+"-- c #5279D9",
+";- c #3C52B1",
+">- c #3656C3",
+",- c #3757C5",
+"'- c #3758C6",
+")- c #3759C6",
+"!- c #375BC6",
+"~- c #385CC7",
+"{- c #385DC8",
+"]- c #365CC6",
+"^- c #355BC6",
+"/- c #355CC6",
+"(- c #365DC7",
+"_- c #375EC8",
+":- c #375CC6",
+"<- c #385EC6",
+"[- c #3A5FC7",
+"}- c #3C60C8",
+"|- c #3D61C9",
+"1- c #3E62CA",
+"2- c #4063CC",
+"3- c #4165CE",
+"4- c #4268D0",
+"5- c #4269D1",
+"6- c #436AD2",
+"7- c #446AD2",
+"8- c #456BD2",
+"9- c #496CD1",
+"0- c #4C6CD0",
+"a- c #4D6CCF",
+"b- c #4E6DD0",
+"c- c #4F6ECF",
+"d- c #4E6FCF",
+"e- c #4C70CF",
+"f- c #4A71D0",
+"g- c #4F6FCF",
+"h- c #4B71D0",
+"i- c #4A72D1",
+"j- c #4B73D4",
+"k- c #4F70D0",
+"l- c #4C73D3",
+"m- c #4C73D6",
+"n- c #4B72D2",
+"o- c #4B71D1",
+"p- c #4C73D7",
+"q- c #3354C0",
+"r- c #3152BE",
+"s- c #3052BE",
+"t- c #3051BF",
+"u- c #2E4FBF",
+"v- c #2E4FBE",
+"w- c #2E50BF",
+"x- c #2F50BF",
+"y- c #3156C4",
+"z- c #2F56C5",
+"A- c #2E57C5",
+"B- c #2F57C5",
+"C- c #3057C6",
+"D- c #3258C6",
+"E- c #3459C7",
+"F- c #365AC7",
+"G- c #385BC8",
+"H- c #3B5DCA",
+"I- c #3B5DCB",
+"J- c #3C5ECC",
+"K- c #3C60CD",
+"L- c #3C62CE",
+"M- c #3D65D0",
+"N- c #3D66D1",
+"O- c #4166D2",
+"P- c #4667D2",
+"Q- c #4A67D1",
+"R- c #4C68D0",
+"S- c #4C69CF",
+"T- c #4D6BCE",
+"U- c #4E6DCD",
+"V- c #4E6ECE",
+"W- c #4E6DCE",
+"X- c #4970D0",
+"Y- c #4770D0",
+"Z- c #4B6BCE",
+"`- c #4A6CCE",
+" ; c #496DCF",
+".; c #476FD0",
+"+; c #4870D0",
+"@; c #486DCF",
+"#; c #242F79",
+"$; c #2F41AC",
+"%; c #2040B8",
+"&; c #2041B8",
+"*; c #2243B3",
+"=; c #2243B8",
+"-; c #2343B8",
+";; c #2444B8",
+">; c #2445B8",
+",; c #2445B6",
+"'; c #2445B7",
+"); c #2444B9",
+"!; c #2949BE",
+"~; c #2649BF",
+"{; c #234BBF",
+"]; c #224CBF",
+"^; c #224AC0",
+"/; c #244CC0",
+"(; c #254DC0",
+"_; c #254DC1",
+":; c #264DC2",
+"<; c #274EC3",
+"[; c #274CC3",
+"}; c #274DC4",
+"|; c #254DC5",
+"1; c #214EC5",
+"2; c #204FC6",
+"3; c #1F50C8",
+"4; c #2151C9",
+"5; c #2B53C8",
+"6; c #3154C7",
+"7; c #3255C6",
+"8; c #2F57C7",
+"9; c #2C58C9",
+"0; c #2D59CA",
+"a; c #2D58C9",
+"b; c #2E5BCC",
+"c; c #325ECC",
+"d; c #325ECB",
+"e; c #1F40B1",
+"f; c #1F40B2",
+"g; c #1F40B3",
+"h; c #2A44BD",
+"i; c #2845BE",
+"j; c #2745BE",
+"k; c #2646BF",
+"l; c #2546BE",
+"m; c #2347BF",
+"n; c #2147BF",
+"o; c #2048C0",
+"p; c #1D48C0",
+"q; c #1C48C0",
+"r; c #1B47C0",
+"s; c #1C48BF",
+"t; c #1E49BE",
+"u; c #214ABD",
+"v; c #244CBD",
+"w; c #264DBE",
+"x; c #254EC0",
+"y; c #214FC2",
+"z; c #1B51C5",
+"A; c #1C51C7",
+"B; c #2250C8",
+"C; c #2A52C8",
+"D; c #3254C6",
+"E; c #3355C5",
+"F; c #3154C8",
+"G; c #3355C6",
+"H; c #2F57C8",
+"I; c #2E58C9",
+"J; c #2E59C9",
+"K; c #3059C9",
+"L; c #2040B6",
+"M; c #2743BB",
+"N; c #2844BC",
+"O; c #2743BD",
+"P; c #2844BE",
+"Q; c #2844BD",
+"R; c #2346BE",
+"S; c #2047BF",
+"T; c #1E48C0",
+"U; c #1D47C0",
+"V; c #1D49BF",
+"W; c #1F49BF",
+"X; c #204ABE",
+"Y; c #254DBF",
+"Z; c #234EC0",
+"`; c #2050C1",
+" > c #1C51C3",
+".> c #1F51C6",
+"+> c #2651C8",
+"@> c #2D53C7",
+"#> c #3155C6",
+"$> c #3155C7",
+"%> c #3355C7",
+"&> c #3254C7",
+"*> c #1E40B1",
+"=> c #2141B8",
+"-> c #2442B9",
+";> c #2744BB",
+">> c #2945BB",
+",> c #2A45BB",
+"'> c #2944BA",
+")> c #2745BB",
+"!> c #2545BC",
+"~> c #2246BD",
+"{> c #2047BE",
+"]> c #1F47BD",
+"^> c #1D48BE",
+"/> c #1E49C0",
+"(> c #1F4AC0",
+"_> c #214BBF",
+":> c #244CBE",
+"<> c #254DBE",
+"[> c #244DBE",
+"}> c #224FBF",
+"|> c #2051C1",
+"1> c #2151C3",
+"2> c #2252C5",
+"3> c #2151C1",
+"4> c #2851C6",
+"5> c #2A50C6",
+"6> c #2E54C6",
+"7> c #1F51C2",
+"8> c #1D52C5",
+"9> c #2651C9",
+"0> c #2950C7",
+"a> c #2D40A5",
+"b> c #2040B0",
+"c> c #1F40B0",
+"d> c #223CAE",
+"e> c #233CAE",
+"f> c #253BAC",
+"g> c #253BAD",
+"h> c #233CB0",
+"i> c #213EB2",
+"j> c #1F3FB4",
+"k> c #1E40B6",
+"l> c #1F3FB7",
+"m> c #1E3EB8",
+"n> c #1F3FB8",
+"o> c #2040B7",
+"p> c #2141B6",
+"q> c #2140B7",
+"r> c #2241B6",
+"s> c #2342B5",
+"t> c #2442B6",
+"u> c #2543B5",
+"v> c #2643B4",
+"w> c #2544B6",
+"x> c #2346B8",
+"y> c #2247B9",
+"z> c #2048BC",
+"A> c #1F48BF",
+"B> c #2049C0",
+"C> c #214AC0",
+"D> c #224BBF",
+"E> c #234CBE",
+"F> c #244DBF",
+"G> c #234CBF",
+"H> c #264DC0",
+"I> c #274EBF",
+"J> c #264DBF",
+"K> c #254EBF",
+"L> c #2050C0",
+"M> c #1F51C1",
+"N> c #1E42A4",
+"O> c #263BA6",
+"P> c #253BA7",
+"Q> c #253CA7",
+"R> c #1E41A5",
+"S> c #1F40AF",
+"T> c #273AAC",
+"U> c #1E40B0",
+"V> c #1F40B5",
+"W> c #1F40B6",
+"X> c #1F40B8",
+"Y> c #1E40B8",
+"Z> c #1F3EB8",
+"`> c #203FB7",
+" , c #2240B6",
+"., c #2341B7",
+"+, c #2345B9",
+"@, c #2147BB",
+"#, c #2148BA",
+"$, c #2049BB",
+"%, c #2049BD",
+"&, c #2049BF",
+"*, c #224BBE",
+"=, c #244DBD",
+"-, c #244CBF",
+";, c #182969",
+">, c #273BAD",
+",, c #2739AB",
+"', c #263AAC",
+"), c #243CAE",
+"!, c #233DAE",
+"~, c #213EAF",
+"{, c #1F3FB0",
+"], c #2040B4",
+"^, c #1F3FB6",
+"/, c #1E3EB7",
+"(, c #2240B7",
+"_, c #2341B6",
+":, c #2543B4",
+"<, c #2644B3",
+"[, c #2544B5",
+"}, c #2545B5",
+"|, c #2547B6",
+"1, c #2548B7",
+"2, c #2349BA",
+"3, c #1F49BE",
+"4, c #2149BD",
+"5, c #2049BE",
+"6, c #214BBE",
+"7, c #2249BE",
+"8, c #234CBD",
+"9, c #2149BE",
+"0, c #1E49BF",
+"a, c #253BA9",
+"b, c #253BAB",
+"c, c #263AAB",
+"d, c #213DAF",
+"e, c #203EAF",
+"f, c #1D40AF",
+"g, c #1D40B0",
+"h, c #1E40B4",
+"i, c #2241B7",
+"j, c #2643B6",
+"k, c #2744B5",
+"l, c #2643B5",
+"m, c #2346B6",
+"n, c #2147B7",
+"o, c #2644B6",
+"p, c #2247B7",
+"q, c #2248B8",
+"r, c #2647B7",
+"s, c #2549B7",
+"t, c #2645B7",
+"u, c #2148B8",
+"v, c #2847B6",
+"w, c #2549B6",
+"x, c #2849B6",
+"y, c #2049B7",
+"z, c #2A49B5",
+"A, c #243BA4",
+"B, c #253BA5",
+"C, c #253BA6",
+"D, c #263AA7",
+"E, c #263AA8",
+"F, c #2739AA",
+"G, c #243CAD",
+"H, c #223DAE",
+"I, c #1F3EAF",
+"J, c #1E3FB0",
+"K, c #1D40B1",
+"L, c #1E3FB1",
+"M, c #1F3FB3",
+"N, c #1F3FB5",
+"O, c #2140B6",
+"P, c #2140B8",
+"Q, c #2744B4",
+"R, c #2746B6",
+"S, c #2947B6",
+"T, c #2946B5",
+"U, c #2A48B6",
+"V, c #3551A8",
+"W, c #1F399C",
+"X, c #143D9F",
+"Y, c #263BA5",
+"Z, c #273BA8",
+"`, c #273BAA",
+" ' c #263AAD",
+".' c #233CAD",
+"+' c #213DAE",
+"@' c #203FB2",
+"#' c #2342B6",
+"$' c #2443B6",
+"%' c #2543B6",
+"&' c #2644B5",
+"*' c #133D9E",
+"=' c #263BA7",
+"-' c #263BA9",
+";' c #273BA9",
+">' c #263AAA",
+",' c #2539AB",
+"'' c #2639AB",
+")' c #253AAC",
+"!' c #243BAD",
+"~' c #223DAF",
+"{' c #203FB0",
+"]' c #2040B1",
+"^' c #2140B3",
+"/' c #2543B1",
+"(' c #2744AF",
+"_' c #1A3CA0",
+":' c #1D3BA2",
+"<' c #233BA4",
+"[' c #263AA5",
+"}' c #253AA5",
+"|' c #263AA6",
+"1' c #263BA4",
+"2' c #243BA5",
+"3' c #263BA8",
+"4' c #223EAF",
+"5' c #3B4CA5",
+"6' c #1D379A",
+"7' c #1E389C",
+"8' c #1E399F",
+"9' c #1F3BA2",
+"0' c #1F3BA3",
+"a' c #213BA4",
+"b' c #233AA3",
+"c' c #243AA3",
+"d' c #2539A4",
+"e' c #253AA6",
+"f' c #243BA7",
+"g' c #253CAA",
+"h' c #253CAC",
+"i' c #253CAD",
+"j' c #253CAE",
+"k' c #243DAE",
+"l' c #213FAF",
+"m' c #223FAF",
+"n' c #2040AF",
+"o' c #253D93",
+"p' c #1D3894",
+"q' c #1F379A",
+"r' c #1E389B",
+"s' c #1D399C",
+"t' c #1C3A9D",
+"u' c #1B3A9D",
+"v' c #183B9E",
+"w' c #163C9E",
+"x' c #153C9E",
+"y' c #163B9D",
+"z' c #173B9D",
+"A' c #193A9D",
+"B' c #1C3A9E",
+"C' c #1F3AA1",
+"D' c #223AA4",
+"E' c #253BA8",
+"F' c #273BA7",
+"G' c #263CAB",
+"H' c #263CAC",
+"I' c #243EAE",
+"J' c #273BAC",
+"K' c #2A3795",
+"L' c #1F389B",
+"M' c #1D389B",
+"N' c #1C399C",
+"O' c #1B399C",
+"P' c #1A3A9D",
+"Q' c #1D399B",
+"R' c #1B399B",
+"S' c #1A3A9C",
+"T' c #1B3A9F",
+"U' c #1D3AA0",
+"V' c #203BA2",
+"W' c #203BA3",
+"X' c #2639A6",
+"Y' c #1B3692",
+"Z' c #1C3794",
+"`' c #1D3796",
+" ) c #1E3898",
+".) c #1E389A",
+"+) c #1F399B",
+"@) c #1A399C",
+"#) c #193A9E",
+"$) c #1A3BA0",
+"%) c #1C3BA2",
+"&) c #1D3CA3",
+"*) c #203CA4",
+"=) c #223BA5",
+"-) c #3C4699",
+";) c #2B4595",
+">) c #1C3793",
+",) c #1D3895",
+"') c #1E3897",
+")) c #1F3998",
+"!) c #1F3999",
+"~) c #1F399A",
+"{) c #1E399C",
+"]) c #1C3B9E",
+"^) c #1D3BA0",
+"/) c #1E3CA2",
+"() c #223CA5",
+"_) c #243CA6",
+":) c #596FA9",
+"<) c #3B4894",
+"[) c #314993",
+"}) c #29499F",
+"|) c #28489E",
+"1) c #2B4BA1",
+"2) c #2C4BA1",
+"3) c #2D4CA2",
+"4) c #2E4CA3",
+"5) c #2F4CA4",
+"6) c #2E4CA4",
+"7) c #2F4DA3",
+"8) c #2F4DA4",
+"9) c #D3D5D2",
+"0) c #3B4794",
+"a) c #314791",
+"b) c #304892",
+"c) c #304893",
+"d) c #2F4995",
+"e) c #2F4997",
+"f) c #2D4A9A",
+"g) c #2A4A9D",
+"h) c #294A9F",
+"i) c #284AA0",
+"j) c #294AA0",
+"k) c #2B4AA1",
+"l) c #2D4CA3",
+"m) c #C9CAC9",
+"n) c #455D9B",
+"o) c #242F78",
+"p) c #1B2F85",
+"q) c #C6C3C8",
+"r) c #B5B2B6",
+"s) c #B5B7B4",
+"t) c #B5B7B3",
+"u) c #B5B2B5",
+"v) c #B5B3B4",
+"w) c #B5B5B4",
+"x) c #B5B6B3",
+"y) c #B5B4B4",
+"z) c #B5B3B5",
+"A) c #B5B4B5",
+"B) c #B5B5B5",
+"C) c #B5B5B3",
+"D) c #B5B5B6",
+"E) c #BAC3BE",
+"F) c #B9C3BD",
+"G) c #C1C3C4",
+"H) c #BFC3C2",
+"I) c #B9C3BE",
+"J) c #BBC3BF",
+"K) c #BDC3C1",
+"L) c #C0C3C3",
+"M) c #BEC3C1",
+"N) c #C2C3C5",
+"O) c #E6E3E8",
+"P) c #E0E2DF",
+"Q) c #E1E1E1",
+"R) c #E2E1E3",
+"S) c #E4E1E6",
+"T) c #E4E2E7",
+"U) c #E4E2E6",
+"V) c #E3E3E4",
+"W) c #E2E3E3",
+"X) c #E1E3E2",
+"Y) c #E3E3E3",
+"Z) c #E3E3E2",
+"`) c #EBEDEA",
+" ! c #EAECE9",
+".! c #E9EBE8",
+"+! c #ECEEEB",
". . + @ # $ $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ % $ $ $ $ $ % $ $ $ $ $ $ $ $ $ % $ $ & * = - ; > , , ' ) ! ! ~ { ] ^ / ( _ : < [ } | | 1 2 3 3 4 4 4 4 4 4 4 5 6 4 4 4 5 6 7 8 9 4 5 6 7 8 9 6 7 8 9 ",
"0 a b % $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ c d d d d $ $ $ $ $ c d e f g h i i i i j k l m n o p q r s t u v w x y z 4 A B C D 9 9 E 9 E F G H I F J K L L L L J K L L L L L L L L ",
"@ % M N O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O O P Q R S T U V W X Y Z ` ...+.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.b.b.b.b.b.",
@@ -2788,786 +2788,786 @@ static char * listviewhighcornerleft_xpm[] = {
static char * listviewhighcornerright_xpm[] = {
"100 46 780 2",
-" c None",
-". c #6A779D",
-"+ c #6C789C",
-"@ c #6C789D",
-"# c #6B789D",
-"$ c #6A779E",
-"% c #66759E",
-"& c #64749E",
-"* c #63749E",
-"= c #61739D",
-"- c #576D9B",
-"; c #556C9C",
-"> c #4D679D",
-", c #4A649D",
-"' c #49629D",
-") c #465E9C",
-"! c #40579C",
-"~ c #3B5394",
-"{ c #2C4E97",
-"] c #314993",
-"^ c #2B4595",
-"/ c #1B4296",
-"( c #253D93",
-"_ c #19418F",
-": c #0F3C96",
-"< c #42599E",
-"[ c #758DC3",
-"} c #E8EAE7",
-"| c #EEF0ED",
-"1 c #FBFBFC",
-"2 c #6F7D9B",
-"3 c #6F7D9A",
-"4 c #6E7B9C",
-"5 c #67759E",
-"6 c #63739E",
-"7 c #62739D",
-"8 c #596F9C",
-"9 c #4A639D",
-"0 c #47609C",
-"a c #445B9F",
-"b c #3E5697",
-"c c #2E509A",
-"d c #2D509A",
-"e c #2D4F99",
-"f c #2D4F98",
-"g c #28418A",
-"h c #3E51A3",
-"i c #D0D3DC",
-"j c #A1B6EF",
-"k c #A2B6F0",
-"l c #A1B6F0",
-"m c #A3B6F0",
-"n c #A0B6EF",
-"o c #9DB6EE",
-"p c #9CB5EF",
-"q c #9CB2F0",
-"r c #9FB5EE",
-"s c #9CB4EB",
-"t c #9AB3EC",
-"u c #9AB0EC",
-"v c #9DB3EB",
-"w c #9BB4EC",
-"x c #9BB4EE",
-"y c #9BB1EF",
-"z c #9BB0F0",
-"A c #90ACF0",
-"B c #93ABEE",
-"C c #91A8EB",
-"D c #8BA3E8",
-"E c #88A1E7",
-"F c #809DE9",
-"G c #7A99E8",
-"H c #7491E5",
-"I c #698AE4",
-"J c #6184E3",
-"K c #507EDC",
-"L c #4E7CDB",
-"M c #4F7DDC",
-"N c #5479DA",
-"O c #567BDC",
-"P c #577CDD",
-"Q c #5074DA",
-"R c #5174DB",
-"S c #5175DC",
-"T c #5276DD",
-"U c #4D71DE",
-"V c #4C72D8",
-"W c #3A6CE0",
-"X c #2B49A6",
-"Y c #E0E2DF",
-"Z c #93AAE9",
-"` c #94A9E8",
-" . c #94AAE9",
-".. c #93A9E9",
-"+. c #92AAE9",
-"@. c #8DA9E8",
-"#. c #8CA7E9",
-"$. c #92ABE9",
-"%. c #8EAAE9",
-"&. c #8EA9E9",
-"*. c #8FAAE9",
-"=. c #8CA8E9",
-"-. c #8CA2E7",
-";. c #86A1E6",
-">. c #839EE9",
-",. c #7F9CE9",
-"'. c #7A97E8",
-"). c #7693E7",
-"!. c #6E8EE8",
-"~. c #678AE9",
-"{. c #5D84E3",
-"]. c #577CDF",
-"^. c #4E77DF",
-"/. c #4A70DB",
-"(. c #4870DB",
-"_. c #4870DC",
-":. c #4770E3",
-"<. c #496FDC",
-"[. c #486EDB",
-"}. c #466FE4",
-"|. c #466EE3",
-"1. c #4167D9",
-"2. c #4066D8",
-"3. c #3F66D8",
-"4. c #3D64D7",
-"5. c #3960DA",
-"6. c #476DD9",
-"7. c #446EE5",
-"8. c #305EC8",
-"9. c #8EAAE8",
-"0. c #8FAAE8",
-"a. c #91AAE9",
-"b. c #8FA9E8",
-"c. c #8BA8E8",
-"d. c #8AA7E9",
-"e. c #8BA5EA",
-"f. c #8AA7E8",
-"g. c #87A2E6",
-"h. c #859FE8",
-"i. c #7F9DE8",
-"j. c #7C9AE8",
-"k. c #7B95E7",
-"l. c #7090E8",
-"m. c #6B8BE9",
-"n. c #6386E6",
-"o. c #5881E1",
-"p. c #5479DE",
-"q. c #4D74DE",
-"r. c #476EDB",
-"s. c #446EE1",
-"t. c #446EE0",
-"u. c #446EDF",
-"v. c #446DE0",
-"w. c #426ADF",
-"x. c #3C64DA",
-"y. c #4360CC",
-"z. c #D3D5D2",
-"A. c #E6E3E8",
-"B. c #8DA2E7",
-"C. c #8CA6EA",
-"D. c #8DA3E9",
-"E. c #88A2E7",
-"F. c #87A1E7",
-"G. c #8AA1E7",
-"H. c #849EE9",
-"I. c #7D9AE9",
-"J. c #7B98E8",
-"K. c #7796E5",
-"L. c #7191E7",
-"M. c #688CE9",
-"N. c #6687E5",
-"O. c #5C83E1",
-"P. c #557BDE",
-"Q. c #4F76DE",
-"R. c #4C72DE",
-"S. c #456EDF",
-"T. c #426AD9",
-"U. c #4269D9",
-"V. c #4269D8",
-"W. c #3D64D9",
-"X. c #3A61DA",
-"Y. c #345ED6",
-"Z. c #335ECF",
-"`. c #C6C3C8",
-" + c #86A1E7",
-".+ c #87A2E7",
-"++ c #87A0E7",
-"@+ c #859EE8",
-"#+ c #849DE9",
-"$+ c #7E9BE9",
-"%+ c #7A99E9",
-"&+ c #7A95E5",
-"*+ c #7593E7",
-"=+ c #6F8EE9",
-"-+ c #668AE5",
-";+ c #6386E0",
-">+ c #5B82DF",
-",+ c #5379DE",
-"'+ c #5075DE",
-")+ c #4B6FDC",
-"!+ c #446AD7",
-"~+ c #4269D6",
-"{+ c #4269D5",
-"]+ c #3E65D7",
-"^+ c #C9CAC9",
-"/+ c #869EE9",
-"(+ c #859FE9",
-"_+ c #849FE9",
-":+ c #829DE8",
-"<+ c #819DE8",
-"[+ c #7B9AE9",
-"}+ c #7A96E6",
-"|+ c #7290E8",
-"1+ c #698CE6",
-"2+ c #6689E0",
-"3+ c #5D84E0",
-"4+ c #587FDF",
-"5+ c #5377DD",
-"6+ c #4B74DE",
-"7+ c #496BD8",
-"8+ c #7C9BE9",
-"9+ c #7E9CE9",
-"0+ c #7D9AEA",
-"a+ c #7D9BEA",
-"b+ c #7D98E8",
-"c+ c #7C98E8",
-"d+ c #7796E4",
-"e+ c #7592E6",
-"f+ c #7390E1",
-"g+ c #698DE0",
-"h+ c #6588DE",
-"i+ c #5E84E0",
-"j+ c #5880DF",
-"k+ c #5479DC",
-"l+ c #4F75DE",
-"m+ c #4A6FDB",
-"n+ c #436AD7",
-"o+ c #3F65D7",
-"p+ c #BAC3BE",
-"q+ c #7B9AE8",
-"r+ c #7B9AEA",
-"s+ c #7A9AEA",
-"t+ c #7B99E9",
-"u+ c #7D97E7",
-"v+ c #7D95E6",
-"w+ c #7D95E5",
-"x+ c #7C95E6",
-"y+ c #7493E3",
-"z+ c #7290DF",
-"A+ c #6C8DDE",
-"B+ c #6B89E1",
-"C+ c #6486DF",
-"D+ c #5D81DF",
-"E+ c #567DDE",
-"F+ c #4F73DE",
-"G+ c #496EDA",
-"H+ c #355ED6",
-"I+ c #345ED5",
-"J+ c #7E95E5",
-"K+ c #7C97E8",
-"L+ c #7C97E7",
-"M+ c #7B94E6",
-"N+ c #7A95E4",
-"O+ c #7695E5",
-"P+ c #7694E4",
-"Q+ c #7994E6",
-"R+ c #7995E4",
-"S+ c #7594E4",
-"T+ c #7391E2",
-"U+ c #6E8EDE",
-"V+ c #6B8ADE",
-"W+ c #6688DF",
-"X+ c #5F84E0",
-"Y+ c #5980E0",
-"Z+ c #4D72DD",
-"`+ c #456BD7",
-" @ c #4168D6",
-".@ c #3C64D7",
-"+@ c #335ED0",
-"@@ c #4659C7",
-"#@ c #7292E1",
-"$@ c #7392E1",
-"%@ c #7492E1",
-"&@ c #718FDF",
-"*@ c #6F8EDE",
-"=@ c #6D8BDE",
-"-@ c #6B88DF",
-";@ c #597FDF",
-">@ c #557ADD",
-",@ c #5176DC",
-"'@ c #4D74DD",
-")@ c #496DDA",
-"!@ c #3860D8",
-"~@ c #7391E0",
-"{@ c #7290DE",
-"]@ c #6D8EDD",
-"^@ c #6D8DDD",
-"/@ c #7190E0",
-"(@ c #6C8DDD",
-"_@ c #6B89DF",
-":@ c #6487E0",
-"<@ c #6085DF",
-"[@ c #5F81DE",
-"}@ c #567EDE",
-"|@ c #4F74D9",
-"1@ c #466BD7",
-"2@ c #4067D5",
-"3@ c #3C63D7",
-"4@ c #335ED3",
-"5@ c #335ED1",
-"6@ c #718EDD",
-"7@ c #728EDD",
-"8@ c #748EDD",
-"9@ c #708EDD",
-"0@ c #6F8DDD",
-"a@ c #6E8DDD",
-"b@ c #6C8ADE",
-"c@ c #6C89DF",
-"d@ c #6988DF",
-"e@ c #6387DF",
-"f@ c #6282DE",
-"g@ c #5681E0",
-"h@ c #577BDD",
-"i@ c #5277DB",
-"j@ c #4D73D8",
-"k@ c #4A70D8",
-"l@ c #436AD5",
-"m@ c #3F66D6",
-"n@ c #3C63D8",
-"o@ c #3960D8",
-"p@ c #3860D7",
-"q@ c #335ED2",
-"r@ c #345ED4",
-"s@ c #6C88DF",
-"t@ c #6D88DF",
-"u@ c #6B89DE",
-"v@ c #6888DF",
-"w@ c #6587E0",
-"x@ c #6989DF",
-"y@ c #6687E0",
-"z@ c #6287E0",
-"A@ c #6281DD",
-"B@ c #5881E0",
-"C@ c #557ADB",
-"D@ c #5176D9",
-"E@ c #4E75D7",
-"F@ c #4A6FD8",
-"G@ c #476BD6",
-"H@ c #4067D6",
-"I@ c #3C62D7",
-"J@ c #3C60D4",
-"K@ c #365ED1",
-"L@ c #345ED3",
-"M@ c #6786DF",
-"N@ c #5F85E0",
-"O@ c #5F86E0",
-"P@ c #6186DF",
-"Q@ c #6286E0",
-"R@ c #6284DF",
-"S@ c #6384DF",
-"T@ c #5B7FDE",
-"U@ c #577DDC",
-"V@ c #557BDA",
-"W@ c #5278D8",
-"X@ c #4E76D6",
-"Y@ c #4C72D7",
-"Z@ c #486DD8",
-"`@ c #4469D6",
-" # c #3F62D2",
-".# c #3C60CF",
-"+# c #345ECF",
-"@# c #6086DF",
-"## c #6085E0",
-"$# c #6285DF",
-"%# c #6383DD",
-"&# c #6481DC",
-"*# c #6380DD",
-"=# c #6183DE",
-"-# c #6083DD",
-";# c #6081DC",
-"># c #6080DD",
-",# c #6083DE",
-"'# c #6181DC",
-")# c #6280DD",
-"!# c #577EDB",
-"~# c #557CD7",
-"{# c #4F76D6",
-"]# c #4E74D7",
-"^# c #466CD7",
-"/# c #3B64D6",
-"(# c #4261CD",
-"_# c #375FCE",
-":# c #5A7FD8",
-"<# c #6281DA",
-"[# c #5F81D8",
-"}# c #5C80D8",
-"|# c #557DD7",
-"1# c #577ED8",
-"2# c #567ED7",
-"3# c #587DD8",
-"4# c #577DD8",
-"5# c #587ED8",
-"6# c #567DD8",
-"7# c #5379D9",
-"8# c #5177D7",
-"9# c #4D74D5",
-"0# c #486ED9",
-"a# c #4068D4",
-"b# c #3D65D2",
-"c# c #4361CC",
-"d# c #345ECE",
-"e# c #325DCF",
-"f# c #2C5AD1",
-"g# c #3959C5",
-"h# c #547BD8",
-"i# c #567DD7",
-"j# c #557BD8",
-"k# c #5279D9",
-"l# c #5278D9",
-"m# c #4D74D6",
-"n# c #4B71D8",
-"o# c #496CD8",
-"p# c #4669D7",
-"q# c #3D66D3",
-"r# c #3F62CF",
-"s# c #4260CC",
-"t# c #5379D8",
-"u# c #4E75D4",
-"v# c #4C73D7",
-"w# c #476CD7",
-"x# c #4869D0",
-"y# c #4067D2",
-"z# c #3D64D1",
-"A# c #4261CC",
-"B# c #395FCE",
-"C# c #4F75D3",
-"D# c #5074D2",
-"E# c #5174D1",
-"F# c #5175D1",
-"G# c #4F74D3",
-"H# c #4C73D5",
-"I# c #4C73D4",
-"J# c #4A72D1",
-"K# c #4B70CF",
-"L# c #506CCC",
-"M# c #4D6BCE",
-"N# c #4167D0",
-"O# c #3D65D1",
-"P# c #3F63CF",
-"Q# c #3B5FCD",
-"R# c #3159CD",
-"S# c #4971D0",
-"T# c #4870CF",
-"U# c #4C6FCF",
-"V# c #4E6CCE",
-"W# c #4E6BCE",
-"X# c #4769CF",
-"Y# c #3D66D0",
-"Z# c #3C65D1",
-"`# c #4062CE",
-" $ c #3D5FCD",
-".$ c #365FCF",
-"+$ c #325DCD",
-"@$ c #2D5AD0",
-"#$ c #3859C5",
-"$$ c #355FCF",
-"%$ c #355ECF",
-"&$ c #335ECE",
-"*$ c #305CCD",
-"=$ c #2B5ACE",
-"-$ c #3056C9",
-";$ c #2553C6",
-">$ c #2153C8",
-",$ c #1F4FC7",
-"'$ c #274CC5",
-")$ c #214AC7",
-"!$ c #1C48C8",
-"~$ c #1244C9",
-"{$ c #1043C9",
-"]$ c #1144C9",
-"^$ c #2A45BE",
-"/$ c #2744B5",
-"($ c #1D49C0",
-"_$ c #2B58DE",
-":$ c #002D94",
-"<$ c #2B59CA",
-"[$ c #2A59CA",
-"}$ c #2E57C8",
-"|$ c #3255C6",
-"1$ c #3355C5",
-"2$ c #1C52C8",
-"3$ c #1D50C7",
-"4$ c #234FC6",
-"5$ c #264CC5",
-"6$ c #1D48C7",
-"7$ c #1245C8",
-"8$ c #1F44C2",
-"9$ c #2945BE",
-"0$ c #2A45BD",
-"a$ c #2040BF",
-"b$ c #3156C7",
-"c$ c #3056C7",
-"d$ c #3354C5",
-"e$ c #3355C6",
-"f$ c #3255C5",
-"g$ c #3254C5",
-"h$ c #1952C7",
-"i$ c #1951C8",
-"j$ c #2050C7",
-"k$ c #274CC4",
-"l$ c #244CC6",
-"m$ c #1F49C7",
-"n$ c #1E47C5",
-"o$ c #2045C3",
-"p$ c #1C44BF",
-"q$ c #2045BE",
-"r$ c #2040B8",
-"s$ c #3254C6",
-"t$ c #3055C6",
-"u$ c #2A54C6",
-"v$ c #2353C7",
-"w$ c #3054C5",
-"x$ c #2F55C5",
-"y$ c #2A54C5",
-"z$ c #2553C5",
-"A$ c #2F54C5",
-"B$ c #3155C6",
-"C$ c #2A54C7",
-"D$ c #1A52C8",
-"E$ c #204FC2",
-"F$ c #264DC6",
-"G$ c #234BC5",
-"H$ c #1D48C1",
-"I$ c #1E48BF",
-"J$ c #2646BE",
-"K$ c #2B45BD",
-"L$ c #1E43BE",
-"M$ c #2643BF",
-"N$ c #2243BF",
-"O$ c #3049BC",
-"P$ c #1E50BE",
-"Q$ c #1D50C0",
-"R$ c #1D50BF",
-"S$ c #1852C1",
-"T$ c #1E51C0",
-"U$ c #214FBF",
-"V$ c #2050C0",
-"W$ c #244EBF",
-"X$ c #2151C0",
-"Y$ c #234FBF",
-"Z$ c #2350C0",
-"`$ c #2351C0",
-" % c #244FBF",
-".% c #2250C0",
-"+% c #2051C0",
-"@% c #1E50C0",
-"#% c #244DBE",
-"$% c #274DBF",
-"%% c #244CBF",
-"&% c #1C48C0",
-"*% c #2247BF",
-"=% c #2C44BD",
-"-% c #1C44BE",
-";% c #1444BF",
-">% c #1841BF",
-",% c #1F40BF",
-"'% c #254DBE",
-")% c #224FBE",
-"!% c #224FBF",
-"~% c #234EBF",
-"{% c #254CBD",
-"]% c #244DBD",
-"^% c #244CBD",
-"/% c #264DBE",
-"(% c #264DBD",
-"_% c #214BC0",
-":% c #1D48C0",
-"<% c #2347BF",
-"[% c #2B44BD",
-"}% c #2444BE",
-"|% c #0F42BF",
-"1% c #0641BF",
-"2% c #0F41BF",
-"3% c #1741BE",
-"4% c #1F40BD",
-"5% c #234BBF",
-"6% c #234CBE",
-"7% c #214BBE",
-"8% c #244CBE",
-"9% c #214ABE",
-"0% c #214ABF",
-"a% c #1F48C0",
-"b% c #2746BE",
-"c% c #1F43BE",
-"d% c #0941BE",
-"e% c #0342BA",
-"f% c #0242BC",
-"g% c #1241B8",
-"h% c #1F40B7",
-"i% c #2F41AC",
-"j% c #2644AE",
-"k% c #2D49B4",
-"l% c #2649B6",
-"m% c #2949B7",
-"n% c #2849B5",
-"o% c #2149B8",
-"p% c #1E49B9",
-"q% c #1F48B8",
-"r% c #1F49B9",
-"s% c #2545B6",
-"t% c #2744B7",
-"u% c #2844B7",
-"v% c #2043B8",
-"w% c #1241B7",
-"x% c #1340B8",
-"y% c #0D41B8",
-"z% c #1941B8",
-"A% c #1F40B8",
-"B% c #203FB8",
-"C% c #2549B5",
-"D% c #2648B6",
-"E% c #2547B7",
-"F% c #2248B7",
-"G% c #2048B7",
-"H% c #2346B6",
-"I% c #2146B6",
-"J% c #2247B7",
-"K% c #2148B7",
-"L% c #2743B4",
-"M% c #2643B5",
-"N% c #2542B6",
-"O% c #1D42B7",
-"P% c #0E42B8",
-"Q% c #0C41B8",
-"R% c #1341B8",
-"S% c #1740B8",
-"T% c #1C41B8",
-"U% c #1F40B1",
-"V% c #2644B5",
-"W% c #2544B5",
-"X% c #2544B4",
-"Y% c #2444B5",
-"Z% c #2444B4",
-"`% c #2744B4",
-" & c #2241B7",
-".& c #1D41B8",
-"+& c #0B42B8",
-"@& c #0942B8",
-"#& c #0C42B8",
-"$& c #0F41B8",
-"%& c #1641B8",
-"&& c #2442B5",
-"*& c #2543B3",
-"=& c #2342B2",
-"-& c #2341B4",
-";& c #2141B3",
-">& c #2141B5",
-",& c #2140B5",
-"'& c #2040B5",
-")& c #1C40B7",
-"!& c #1B41B3",
-"~& c #0142B6",
-"{& c #0E41B7",
-"]& c #1141B7",
-"^& c #1440B2",
-"/& c #113FB0",
-"(& c #1440B0",
-"_& c #213EAF",
-":& c #233DAE",
-"<& c #223EAF",
-"[& c #1E40B1",
-"}& c #173EAD",
-"|& c #1440AF",
-"1& c #0D40AF",
-"2& c #0941B0",
-"3& c #0D3FAE",
-"4& c #1B3CAC",
-"5& c #233CAD",
-"6& c #203FB0",
-"7& c #273BAD",
-"8& c #1D40B0",
-"9& c #2040B1",
-"0& c #1E40B0",
-"a& c #1C40B0",
-"b& c #1B3DAC",
-"c& c #143DAC",
-"d& c #193DAD",
-"e& c #1B3DAD",
-"f& c #173DAD",
-"g& c #153DAC",
-"h& c #1C3CAC",
-"i& c #243CAD",
-"j& c #213FB0",
-"k& c #263BAA",
-"l& c #253CAE",
-"m& c #273AAC",
-"n& c #273AAD",
-"o& c #253BAD",
-"p& c #1D3CAC",
-"q& c #243BAD",
-"r& c #1E3CAC",
-"s& c #263BAD",
-"t& c #1A3DAC",
-"u& c #143DAB",
-"v& c #163DAC",
-"w& c #1A3CAC",
-"x& c #1F3CAD",
-"y& c #263BAB",
-"z& c #263BA6",
-"A& c #1E42A4",
-"B& c #2D40A5",
-"C& c #253BA6",
-"D& c #253CA7",
-"E& c #263AA5",
-"F& c #253BA7",
-"G& c #1E3BA6",
-"H& c #193DA6",
-"I& c #173DA5",
-"J& c #143DA6",
-"K& c #1A3DA7",
-"L& c #133DA6",
-"M& c #123DA5",
-"N& c #1A3CA7",
-"O& c #243BA6",
-"P& c #263AA7",
-"Q& c #273BA7",
-"R& c #263AA6",
-"S& c #223BA6",
-"T& c #1D3BA6",
-"U& c #173CA6",
-"V& c #133DA5",
-"W& c #1B3DA6",
-"X& c #193DA5",
-"Y& c #123DA4",
-"Z& c #163CA5",
-"`& c #213CA6",
-" * c #273BA8",
-".* c #263BA7",
-"+* c #253BA5",
-"@* c #263BA5",
-"#* c #1C3BA6",
-"$* c #1B3BA9",
-"%* c #133BA8",
-"&* c #0A3BA7",
-"** c #083AA6",
-"=* c #123CA5",
-"-* c #0839A8",
-";* c #0239A6",
-">* c #123AA8",
-",* c #1F49C8",
-"'* c #2F4DA4",
-")* c #2E4DA3",
-"!* c #384CA4",
-"~* c #3C4DA7",
-"{* c #394EA7",
-"]* c #3B4CA5",
-"^* c #3C52B1",
-"/* c #3551A8",
-"(* c #3759BE",
-"_* c #4161C7",
-":* c #0033A8",
-"<* c #596FA9",
-"[* c #2F4DA3",
-"}* c #2D4BA5",
-"|* c #2E4CA4",
-"1* c #2C4AA5",
-"2* c #2D4BA4",
-"3* c #354DA4",
-"4* c #3A4BA4",
-"5* c #394DA6",
-"6* c #4056AD",
-"7* c #445BBB",
-"8* c #B5B7B4",
-"9* c #1B2F85",
-"0* c #242F79",
-"a* c #B5B5B5",
-"b* c #B5B2B6",
-"c* c #C0C3C3",
-"d* c #E3E3E4",
-"e* c #EBEDEA",
+" c None",
+". c #6A779D",
+"+ c #6C789C",
+"@ c #6C789D",
+"# c #6B789D",
+"$ c #6A779E",
+"% c #66759E",
+"& c #64749E",
+"* c #63749E",
+"= c #61739D",
+"- c #576D9B",
+"; c #556C9C",
+"> c #4D679D",
+", c #4A649D",
+"' c #49629D",
+") c #465E9C",
+"! c #40579C",
+"~ c #3B5394",
+"{ c #2C4E97",
+"] c #314993",
+"^ c #2B4595",
+"/ c #1B4296",
+"( c #253D93",
+"_ c #19418F",
+": c #0F3C96",
+"< c #42599E",
+"[ c #758DC3",
+"} c #E8EAE7",
+"| c #EEF0ED",
+"1 c #FBFBFC",
+"2 c #6F7D9B",
+"3 c #6F7D9A",
+"4 c #6E7B9C",
+"5 c #67759E",
+"6 c #63739E",
+"7 c #62739D",
+"8 c #596F9C",
+"9 c #4A639D",
+"0 c #47609C",
+"a c #445B9F",
+"b c #3E5697",
+"c c #2E509A",
+"d c #2D509A",
+"e c #2D4F99",
+"f c #2D4F98",
+"g c #28418A",
+"h c #3E51A3",
+"i c #D0D3DC",
+"j c #A1B6EF",
+"k c #A2B6F0",
+"l c #A1B6F0",
+"m c #A3B6F0",
+"n c #A0B6EF",
+"o c #9DB6EE",
+"p c #9CB5EF",
+"q c #9CB2F0",
+"r c #9FB5EE",
+"s c #9CB4EB",
+"t c #9AB3EC",
+"u c #9AB0EC",
+"v c #9DB3EB",
+"w c #9BB4EC",
+"x c #9BB4EE",
+"y c #9BB1EF",
+"z c #9BB0F0",
+"A c #90ACF0",
+"B c #93ABEE",
+"C c #91A8EB",
+"D c #8BA3E8",
+"E c #88A1E7",
+"F c #809DE9",
+"G c #7A99E8",
+"H c #7491E5",
+"I c #698AE4",
+"J c #6184E3",
+"K c #507EDC",
+"L c #4E7CDB",
+"M c #4F7DDC",
+"N c #5479DA",
+"O c #567BDC",
+"P c #577CDD",
+"Q c #5074DA",
+"R c #5174DB",
+"S c #5175DC",
+"T c #5276DD",
+"U c #4D71DE",
+"V c #4C72D8",
+"W c #3A6CE0",
+"X c #2B49A6",
+"Y c #E0E2DF",
+"Z c #93AAE9",
+"` c #94A9E8",
+" . c #94AAE9",
+".. c #93A9E9",
+"+. c #92AAE9",
+"@. c #8DA9E8",
+"#. c #8CA7E9",
+"$. c #92ABE9",
+"%. c #8EAAE9",
+"&. c #8EA9E9",
+"*. c #8FAAE9",
+"=. c #8CA8E9",
+"-. c #8CA2E7",
+";. c #86A1E6",
+">. c #839EE9",
+",. c #7F9CE9",
+"'. c #7A97E8",
+"). c #7693E7",
+"!. c #6E8EE8",
+"~. c #678AE9",
+"{. c #5D84E3",
+"]. c #577CDF",
+"^. c #4E77DF",
+"/. c #4A70DB",
+"(. c #4870DB",
+"_. c #4870DC",
+":. c #4770E3",
+"<. c #496FDC",
+"[. c #486EDB",
+"}. c #466FE4",
+"|. c #466EE3",
+"1. c #4167D9",
+"2. c #4066D8",
+"3. c #3F66D8",
+"4. c #3D64D7",
+"5. c #3960DA",
+"6. c #476DD9",
+"7. c #446EE5",
+"8. c #305EC8",
+"9. c #8EAAE8",
+"0. c #8FAAE8",
+"a. c #91AAE9",
+"b. c #8FA9E8",
+"c. c #8BA8E8",
+"d. c #8AA7E9",
+"e. c #8BA5EA",
+"f. c #8AA7E8",
+"g. c #87A2E6",
+"h. c #859FE8",
+"i. c #7F9DE8",
+"j. c #7C9AE8",
+"k. c #7B95E7",
+"l. c #7090E8",
+"m. c #6B8BE9",
+"n. c #6386E6",
+"o. c #5881E1",
+"p. c #5479DE",
+"q. c #4D74DE",
+"r. c #476EDB",
+"s. c #446EE1",
+"t. c #446EE0",
+"u. c #446EDF",
+"v. c #446DE0",
+"w. c #426ADF",
+"x. c #3C64DA",
+"y. c #4360CC",
+"z. c #D3D5D2",
+"A. c #E6E3E8",
+"B. c #8DA2E7",
+"C. c #8CA6EA",
+"D. c #8DA3E9",
+"E. c #88A2E7",
+"F. c #87A1E7",
+"G. c #8AA1E7",
+"H. c #849EE9",
+"I. c #7D9AE9",
+"J. c #7B98E8",
+"K. c #7796E5",
+"L. c #7191E7",
+"M. c #688CE9",
+"N. c #6687E5",
+"O. c #5C83E1",
+"P. c #557BDE",
+"Q. c #4F76DE",
+"R. c #4C72DE",
+"S. c #456EDF",
+"T. c #426AD9",
+"U. c #4269D9",
+"V. c #4269D8",
+"W. c #3D64D9",
+"X. c #3A61DA",
+"Y. c #345ED6",
+"Z. c #335ECF",
+"`. c #C6C3C8",
+" + c #86A1E7",
+".+ c #87A2E7",
+"++ c #87A0E7",
+"@+ c #859EE8",
+"#+ c #849DE9",
+"$+ c #7E9BE9",
+"%+ c #7A99E9",
+"&+ c #7A95E5",
+"*+ c #7593E7",
+"=+ c #6F8EE9",
+"-+ c #668AE5",
+";+ c #6386E0",
+">+ c #5B82DF",
+",+ c #5379DE",
+"'+ c #5075DE",
+")+ c #4B6FDC",
+"!+ c #446AD7",
+"~+ c #4269D6",
+"{+ c #4269D5",
+"]+ c #3E65D7",
+"^+ c #C9CAC9",
+"/+ c #869EE9",
+"(+ c #859FE9",
+"_+ c #849FE9",
+":+ c #829DE8",
+"<+ c #819DE8",
+"[+ c #7B9AE9",
+"}+ c #7A96E6",
+"|+ c #7290E8",
+"1+ c #698CE6",
+"2+ c #6689E0",
+"3+ c #5D84E0",
+"4+ c #587FDF",
+"5+ c #5377DD",
+"6+ c #4B74DE",
+"7+ c #496BD8",
+"8+ c #7C9BE9",
+"9+ c #7E9CE9",
+"0+ c #7D9AEA",
+"a+ c #7D9BEA",
+"b+ c #7D98E8",
+"c+ c #7C98E8",
+"d+ c #7796E4",
+"e+ c #7592E6",
+"f+ c #7390E1",
+"g+ c #698DE0",
+"h+ c #6588DE",
+"i+ c #5E84E0",
+"j+ c #5880DF",
+"k+ c #5479DC",
+"l+ c #4F75DE",
+"m+ c #4A6FDB",
+"n+ c #436AD7",
+"o+ c #3F65D7",
+"p+ c #BAC3BE",
+"q+ c #7B9AE8",
+"r+ c #7B9AEA",
+"s+ c #7A9AEA",
+"t+ c #7B99E9",
+"u+ c #7D97E7",
+"v+ c #7D95E6",
+"w+ c #7D95E5",
+"x+ c #7C95E6",
+"y+ c #7493E3",
+"z+ c #7290DF",
+"A+ c #6C8DDE",
+"B+ c #6B89E1",
+"C+ c #6486DF",
+"D+ c #5D81DF",
+"E+ c #567DDE",
+"F+ c #4F73DE",
+"G+ c #496EDA",
+"H+ c #355ED6",
+"I+ c #345ED5",
+"J+ c #7E95E5",
+"K+ c #7C97E8",
+"L+ c #7C97E7",
+"M+ c #7B94E6",
+"N+ c #7A95E4",
+"O+ c #7695E5",
+"P+ c #7694E4",
+"Q+ c #7994E6",
+"R+ c #7995E4",
+"S+ c #7594E4",
+"T+ c #7391E2",
+"U+ c #6E8EDE",
+"V+ c #6B8ADE",
+"W+ c #6688DF",
+"X+ c #5F84E0",
+"Y+ c #5980E0",
+"Z+ c #4D72DD",
+"`+ c #456BD7",
+" @ c #4168D6",
+".@ c #3C64D7",
+"+@ c #335ED0",
+"@@ c #4659C7",
+"#@ c #7292E1",
+"$@ c #7392E1",
+"%@ c #7492E1",
+"&@ c #718FDF",
+"*@ c #6F8EDE",
+"=@ c #6D8BDE",
+"-@ c #6B88DF",
+";@ c #597FDF",
+">@ c #557ADD",
+",@ c #5176DC",
+"'@ c #4D74DD",
+")@ c #496DDA",
+"!@ c #3860D8",
+"~@ c #7391E0",
+"{@ c #7290DE",
+"]@ c #6D8EDD",
+"^@ c #6D8DDD",
+"/@ c #7190E0",
+"(@ c #6C8DDD",
+"_@ c #6B89DF",
+":@ c #6487E0",
+"<@ c #6085DF",
+"[@ c #5F81DE",
+"}@ c #567EDE",
+"|@ c #4F74D9",
+"1@ c #466BD7",
+"2@ c #4067D5",
+"3@ c #3C63D7",
+"4@ c #335ED3",
+"5@ c #335ED1",
+"6@ c #718EDD",
+"7@ c #728EDD",
+"8@ c #748EDD",
+"9@ c #708EDD",
+"0@ c #6F8DDD",
+"a@ c #6E8DDD",
+"b@ c #6C8ADE",
+"c@ c #6C89DF",
+"d@ c #6988DF",
+"e@ c #6387DF",
+"f@ c #6282DE",
+"g@ c #5681E0",
+"h@ c #577BDD",
+"i@ c #5277DB",
+"j@ c #4D73D8",
+"k@ c #4A70D8",
+"l@ c #436AD5",
+"m@ c #3F66D6",
+"n@ c #3C63D8",
+"o@ c #3960D8",
+"p@ c #3860D7",
+"q@ c #335ED2",
+"r@ c #345ED4",
+"s@ c #6C88DF",
+"t@ c #6D88DF",
+"u@ c #6B89DE",
+"v@ c #6888DF",
+"w@ c #6587E0",
+"x@ c #6989DF",
+"y@ c #6687E0",
+"z@ c #6287E0",
+"A@ c #6281DD",
+"B@ c #5881E0",
+"C@ c #557ADB",
+"D@ c #5176D9",
+"E@ c #4E75D7",
+"F@ c #4A6FD8",
+"G@ c #476BD6",
+"H@ c #4067D6",
+"I@ c #3C62D7",
+"J@ c #3C60D4",
+"K@ c #365ED1",
+"L@ c #345ED3",
+"M@ c #6786DF",
+"N@ c #5F85E0",
+"O@ c #5F86E0",
+"P@ c #6186DF",
+"Q@ c #6286E0",
+"R@ c #6284DF",
+"S@ c #6384DF",
+"T@ c #5B7FDE",
+"U@ c #577DDC",
+"V@ c #557BDA",
+"W@ c #5278D8",
+"X@ c #4E76D6",
+"Y@ c #4C72D7",
+"Z@ c #486DD8",
+"`@ c #4469D6",
+" # c #3F62D2",
+".# c #3C60CF",
+"+# c #345ECF",
+"@# c #6086DF",
+"## c #6085E0",
+"$# c #6285DF",
+"%# c #6383DD",
+"&# c #6481DC",
+"*# c #6380DD",
+"=# c #6183DE",
+"-# c #6083DD",
+";# c #6081DC",
+"># c #6080DD",
+",# c #6083DE",
+"'# c #6181DC",
+")# c #6280DD",
+"!# c #577EDB",
+"~# c #557CD7",
+"{# c #4F76D6",
+"]# c #4E74D7",
+"^# c #466CD7",
+"/# c #3B64D6",
+"(# c #4261CD",
+"_# c #375FCE",
+":# c #5A7FD8",
+"<# c #6281DA",
+"[# c #5F81D8",
+"}# c #5C80D8",
+"|# c #557DD7",
+"1# c #577ED8",
+"2# c #567ED7",
+"3# c #587DD8",
+"4# c #577DD8",
+"5# c #587ED8",
+"6# c #567DD8",
+"7# c #5379D9",
+"8# c #5177D7",
+"9# c #4D74D5",
+"0# c #486ED9",
+"a# c #4068D4",
+"b# c #3D65D2",
+"c# c #4361CC",
+"d# c #345ECE",
+"e# c #325DCF",
+"f# c #2C5AD1",
+"g# c #3959C5",
+"h# c #547BD8",
+"i# c #567DD7",
+"j# c #557BD8",
+"k# c #5279D9",
+"l# c #5278D9",
+"m# c #4D74D6",
+"n# c #4B71D8",
+"o# c #496CD8",
+"p# c #4669D7",
+"q# c #3D66D3",
+"r# c #3F62CF",
+"s# c #4260CC",
+"t# c #5379D8",
+"u# c #4E75D4",
+"v# c #4C73D7",
+"w# c #476CD7",
+"x# c #4869D0",
+"y# c #4067D2",
+"z# c #3D64D1",
+"A# c #4261CC",
+"B# c #395FCE",
+"C# c #4F75D3",
+"D# c #5074D2",
+"E# c #5174D1",
+"F# c #5175D1",
+"G# c #4F74D3",
+"H# c #4C73D5",
+"I# c #4C73D4",
+"J# c #4A72D1",
+"K# c #4B70CF",
+"L# c #506CCC",
+"M# c #4D6BCE",
+"N# c #4167D0",
+"O# c #3D65D1",
+"P# c #3F63CF",
+"Q# c #3B5FCD",
+"R# c #3159CD",
+"S# c #4971D0",
+"T# c #4870CF",
+"U# c #4C6FCF",
+"V# c #4E6CCE",
+"W# c #4E6BCE",
+"X# c #4769CF",
+"Y# c #3D66D0",
+"Z# c #3C65D1",
+"`# c #4062CE",
+" $ c #3D5FCD",
+".$ c #365FCF",
+"+$ c #325DCD",
+"@$ c #2D5AD0",
+"#$ c #3859C5",
+"$$ c #355FCF",
+"%$ c #355ECF",
+"&$ c #335ECE",
+"*$ c #305CCD",
+"=$ c #2B5ACE",
+"-$ c #3056C9",
+";$ c #2553C6",
+">$ c #2153C8",
+",$ c #1F4FC7",
+"'$ c #274CC5",
+")$ c #214AC7",
+"!$ c #1C48C8",
+"~$ c #1244C9",
+"{$ c #1043C9",
+"]$ c #1144C9",
+"^$ c #2A45BE",
+"/$ c #2744B5",
+"($ c #1D49C0",
+"_$ c #2B58DE",
+":$ c #002D94",
+"<$ c #2B59CA",
+"[$ c #2A59CA",
+"}$ c #2E57C8",
+"|$ c #3255C6",
+"1$ c #3355C5",
+"2$ c #1C52C8",
+"3$ c #1D50C7",
+"4$ c #234FC6",
+"5$ c #264CC5",
+"6$ c #1D48C7",
+"7$ c #1245C8",
+"8$ c #1F44C2",
+"9$ c #2945BE",
+"0$ c #2A45BD",
+"a$ c #2040BF",
+"b$ c #3156C7",
+"c$ c #3056C7",
+"d$ c #3354C5",
+"e$ c #3355C6",
+"f$ c #3255C5",
+"g$ c #3254C5",
+"h$ c #1952C7",
+"i$ c #1951C8",
+"j$ c #2050C7",
+"k$ c #274CC4",
+"l$ c #244CC6",
+"m$ c #1F49C7",
+"n$ c #1E47C5",
+"o$ c #2045C3",
+"p$ c #1C44BF",
+"q$ c #2045BE",
+"r$ c #2040B8",
+"s$ c #3254C6",
+"t$ c #3055C6",
+"u$ c #2A54C6",
+"v$ c #2353C7",
+"w$ c #3054C5",
+"x$ c #2F55C5",
+"y$ c #2A54C5",
+"z$ c #2553C5",
+"A$ c #2F54C5",
+"B$ c #3155C6",
+"C$ c #2A54C7",
+"D$ c #1A52C8",
+"E$ c #204FC2",
+"F$ c #264DC6",
+"G$ c #234BC5",
+"H$ c #1D48C1",
+"I$ c #1E48BF",
+"J$ c #2646BE",
+"K$ c #2B45BD",
+"L$ c #1E43BE",
+"M$ c #2643BF",
+"N$ c #2243BF",
+"O$ c #3049BC",
+"P$ c #1E50BE",
+"Q$ c #1D50C0",
+"R$ c #1D50BF",
+"S$ c #1852C1",
+"T$ c #1E51C0",
+"U$ c #214FBF",
+"V$ c #2050C0",
+"W$ c #244EBF",
+"X$ c #2151C0",
+"Y$ c #234FBF",
+"Z$ c #2350C0",
+"`$ c #2351C0",
+" % c #244FBF",
+".% c #2250C0",
+"+% c #2051C0",
+"@% c #1E50C0",
+"#% c #244DBE",
+"$% c #274DBF",
+"%% c #244CBF",
+"&% c #1C48C0",
+"*% c #2247BF",
+"=% c #2C44BD",
+"-% c #1C44BE",
+";% c #1444BF",
+">% c #1841BF",
+",% c #1F40BF",
+"'% c #254DBE",
+")% c #224FBE",
+"!% c #224FBF",
+"~% c #234EBF",
+"{% c #254CBD",
+"]% c #244DBD",
+"^% c #244CBD",
+"/% c #264DBE",
+"(% c #264DBD",
+"_% c #214BC0",
+":% c #1D48C0",
+"<% c #2347BF",
+"[% c #2B44BD",
+"}% c #2444BE",
+"|% c #0F42BF",
+"1% c #0641BF",
+"2% c #0F41BF",
+"3% c #1741BE",
+"4% c #1F40BD",
+"5% c #234BBF",
+"6% c #234CBE",
+"7% c #214BBE",
+"8% c #244CBE",
+"9% c #214ABE",
+"0% c #214ABF",
+"a% c #1F48C0",
+"b% c #2746BE",
+"c% c #1F43BE",
+"d% c #0941BE",
+"e% c #0342BA",
+"f% c #0242BC",
+"g% c #1241B8",
+"h% c #1F40B7",
+"i% c #2F41AC",
+"j% c #2644AE",
+"k% c #2D49B4",
+"l% c #2649B6",
+"m% c #2949B7",
+"n% c #2849B5",
+"o% c #2149B8",
+"p% c #1E49B9",
+"q% c #1F48B8",
+"r% c #1F49B9",
+"s% c #2545B6",
+"t% c #2744B7",
+"u% c #2844B7",
+"v% c #2043B8",
+"w% c #1241B7",
+"x% c #1340B8",
+"y% c #0D41B8",
+"z% c #1941B8",
+"A% c #1F40B8",
+"B% c #203FB8",
+"C% c #2549B5",
+"D% c #2648B6",
+"E% c #2547B7",
+"F% c #2248B7",
+"G% c #2048B7",
+"H% c #2346B6",
+"I% c #2146B6",
+"J% c #2247B7",
+"K% c #2148B7",
+"L% c #2743B4",
+"M% c #2643B5",
+"N% c #2542B6",
+"O% c #1D42B7",
+"P% c #0E42B8",
+"Q% c #0C41B8",
+"R% c #1341B8",
+"S% c #1740B8",
+"T% c #1C41B8",
+"U% c #1F40B1",
+"V% c #2644B5",
+"W% c #2544B5",
+"X% c #2544B4",
+"Y% c #2444B5",
+"Z% c #2444B4",
+"`% c #2744B4",
+" & c #2241B7",
+".& c #1D41B8",
+"+& c #0B42B8",
+"@& c #0942B8",
+"#& c #0C42B8",
+"$& c #0F41B8",
+"%& c #1641B8",
+"&& c #2442B5",
+"*& c #2543B3",
+"=& c #2342B2",
+"-& c #2341B4",
+";& c #2141B3",
+">& c #2141B5",
+",& c #2140B5",
+"'& c #2040B5",
+")& c #1C40B7",
+"!& c #1B41B3",
+"~& c #0142B6",
+"{& c #0E41B7",
+"]& c #1141B7",
+"^& c #1440B2",
+"/& c #113FB0",
+"(& c #1440B0",
+"_& c #213EAF",
+":& c #233DAE",
+"<& c #223EAF",
+"[& c #1E40B1",
+"}& c #173EAD",
+"|& c #1440AF",
+"1& c #0D40AF",
+"2& c #0941B0",
+"3& c #0D3FAE",
+"4& c #1B3CAC",
+"5& c #233CAD",
+"6& c #203FB0",
+"7& c #273BAD",
+"8& c #1D40B0",
+"9& c #2040B1",
+"0& c #1E40B0",
+"a& c #1C40B0",
+"b& c #1B3DAC",
+"c& c #143DAC",
+"d& c #193DAD",
+"e& c #1B3DAD",
+"f& c #173DAD",
+"g& c #153DAC",
+"h& c #1C3CAC",
+"i& c #243CAD",
+"j& c #213FB0",
+"k& c #263BAA",
+"l& c #253CAE",
+"m& c #273AAC",
+"n& c #273AAD",
+"o& c #253BAD",
+"p& c #1D3CAC",
+"q& c #243BAD",
+"r& c #1E3CAC",
+"s& c #263BAD",
+"t& c #1A3DAC",
+"u& c #143DAB",
+"v& c #163DAC",
+"w& c #1A3CAC",
+"x& c #1F3CAD",
+"y& c #263BAB",
+"z& c #263BA6",
+"A& c #1E42A4",
+"B& c #2D40A5",
+"C& c #253BA6",
+"D& c #253CA7",
+"E& c #263AA5",
+"F& c #253BA7",
+"G& c #1E3BA6",
+"H& c #193DA6",
+"I& c #173DA5",
+"J& c #143DA6",
+"K& c #1A3DA7",
+"L& c #133DA6",
+"M& c #123DA5",
+"N& c #1A3CA7",
+"O& c #243BA6",
+"P& c #263AA7",
+"Q& c #273BA7",
+"R& c #263AA6",
+"S& c #223BA6",
+"T& c #1D3BA6",
+"U& c #173CA6",
+"V& c #133DA5",
+"W& c #1B3DA6",
+"X& c #193DA5",
+"Y& c #123DA4",
+"Z& c #163CA5",
+"`& c #213CA6",
+" * c #273BA8",
+".* c #263BA7",
+"+* c #253BA5",
+"@* c #263BA5",
+"#* c #1C3BA6",
+"$* c #1B3BA9",
+"%* c #133BA8",
+"&* c #0A3BA7",
+"** c #083AA6",
+"=* c #123CA5",
+"-* c #0839A8",
+";* c #0239A6",
+">* c #123AA8",
+",* c #1F49C8",
+"'* c #2F4DA4",
+")* c #2E4DA3",
+"!* c #384CA4",
+"~* c #3C4DA7",
+"{* c #394EA7",
+"]* c #3B4CA5",
+"^* c #3C52B1",
+"/* c #3551A8",
+"(* c #3759BE",
+"_* c #4161C7",
+":* c #0033A8",
+"<* c #596FA9",
+"[* c #2F4DA3",
+"}* c #2D4BA5",
+"|* c #2E4CA4",
+"1* c #2C4AA5",
+"2* c #2D4BA4",
+"3* c #354DA4",
+"4* c #3A4BA4",
+"5* c #394DA6",
+"6* c #4056AD",
+"7* c #445BBB",
+"8* c #B5B7B4",
+"9* c #1B2F85",
+"0* c #242F79",
+"a* c #B5B5B5",
+"b* c #B5B2B6",
+"c* c #C0C3C3",
+"d* c #E3E3E4",
+"e* c #EBEDEA",
". + @ + # $ % & # $ % & # $ % & # $ % & & * = - ; > , ' ) ! ~ { { { { { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ / / / ( / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / _ _ / / : / < [ } | | | 1 1 ",
"2 2 2 2 3 2 4 @ 3 2 4 @ 3 2 4 @ 3 2 4 @ # 5 6 7 8 ; > 9 0 a b c d e f { { { ] ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ( ( ( ( ( ( ( ( ( / / / / / / / / / / / / / / / / / _ _ _ _ _ _ _ _ _ _ _ g g _ / / : : : h i } 1 | 1 ",
"j k l m n o p q n o p q r s t u v w x y z A B C D E F G H I J K L M N O P O O Q R S T T T T T T T T T T T T T T T T T T U U U U U U U U U U U U U U U U U U U U U U U U U U U U V V V U U W X : [ Y | | ",
@@ -3618,38 +3618,38 @@ static char * listviewhighcornerright_xpm[] = {
static char * tabmiddle_xpm[] = {
"33 42 32 1",
-" c None",
-". c #CECFEF",
-"+ c #CECBE7",
-"@ c #C6C7E7",
-"# c #C6CBE7",
-"$ c #BDBEDE",
-"% c #BDC3DE",
-"& c #CECBEF",
-"* c #B5B6D6",
-"= c #ADAECE",
-"- c #ADB2CE",
-"; c #BDBAD6",
-"> c #B5BAD6",
-", c #C6C3DE",
-"' c #ADAAC6",
-") c #B5B2CE",
-"! c #B5B6CE",
-"~ c #A5A2BD",
-"{ c #A5A6BD",
-"] c #9C9EB5",
-"^ c #9CA2BD",
-"/ c #ADAEC6",
-"( c #C6C3E7",
-"_ c #9C9AB5",
-": c #A5A6C6",
-"< c #949AAD",
-"[ c #A5AAC6",
-"} c #9496AD",
-"| c #BDBADE",
-"1 c #BDBED6",
-"2 c #9CA2B5",
-"3 c #A5AABD",
+" c None",
+". c #CECFEF",
+"+ c #CECBE7",
+"@ c #C6C7E7",
+"# c #C6CBE7",
+"$ c #BDBEDE",
+"% c #BDC3DE",
+"& c #CECBEF",
+"* c #B5B6D6",
+"= c #ADAECE",
+"- c #ADB2CE",
+"; c #BDBAD6",
+"> c #B5BAD6",
+", c #C6C3DE",
+"' c #ADAAC6",
+") c #B5B2CE",
+"! c #B5B6CE",
+"~ c #A5A2BD",
+"{ c #A5A6BD",
+"] c #9C9EB5",
+"^ c #9CA2BD",
+"/ c #ADAEC6",
+"( c #C6C3E7",
+"_ c #9C9AB5",
+": c #A5A6C6",
+"< c #949AAD",
+"[ c #A5AAC6",
+"} c #9496AD",
+"| c #BDBADE",
+"1 c #BDBED6",
+"2 c #9CA2B5",
+"3 c #A5AABD",
"..........................+@.#.#.",
"........................$@%&#.#..",
"......................**$$@@&#.#.",
@@ -3696,34 +3696,34 @@ static char * tabmiddle_xpm[] = {
static char * tabselectedbeginn_xpm[] = {
"33 39 28 1",
-" c None",
-". c #CECFEF",
-"+ c #EFF3EF",
-"@ c #FFFBFF",
-"# c #F7FBF7",
-"$ c #FFFFFF",
-"% c #EFEFEF",
-"& c #F7F7F7",
-"* c #DEDFDE",
-"= c #E7E7E7",
-"- c #D6D3D6",
-"; c #DEE3DE",
-"> c #EFEBEF",
-", c #F7F3F7",
-"' c #CECBCE",
-") c #CECFCE",
-"! c #D6D7D6",
-"~ c #DEDBDE",
-"{ c #E7EBE7",
-"] c #C6C7C6",
-"^ c #E7E3E7",
-"/ c #BDC3BD",
-"( c #CED3CE",
-"_ c #BDBABD",
-": c #C6C3C6",
-"< c #C6CBC6",
-"[ c #D6DBD6",
-"} c #BDBEBD",
+" c None",
+". c #CECFEF",
+"+ c #EFF3EF",
+"@ c #FFFBFF",
+"# c #F7FBF7",
+"$ c #FFFFFF",
+"% c #EFEFEF",
+"& c #F7F7F7",
+"* c #DEDFDE",
+"= c #E7E7E7",
+"- c #D6D3D6",
+"; c #DEE3DE",
+"> c #EFEBEF",
+", c #F7F3F7",
+"' c #CECBCE",
+") c #CECFCE",
+"! c #D6D7D6",
+"~ c #DEDBDE",
+"{ c #E7EBE7",
+"] c #C6C7C6",
+"^ c #E7E3E7",
+"/ c #BDC3BD",
+"( c #CED3CE",
+"_ c #BDBABD",
+": c #C6C3C6",
+"< c #C6CBC6",
+"[ c #D6DBD6",
+"} c #BDBEBD",
"..........................+@#$#$$",
"........................%%&&@#$#$",
"......................*==%%&&@#$$",
@@ -3767,39 +3767,39 @@ static char * tabselectedbeginn_xpm[] = {
static char * tabselectedend_xpm[] = {
"33 42 33 1",
-" c None",
-". c #FFFFFF",
-"+ c #CECBE7",
-"@ c #C6C7E7",
-"# c #CECFEF",
-"$ c #C6CBE7",
-"% c #BDBEDE",
-"& c #BDC3DE",
-"* c #CECBEF",
-"= c #B5B6D6",
-"- c #ADAECE",
-"; c #ADB2CE",
-"> c #BDBAD6",
-", c #B5BAD6",
-"' c #C6C3DE",
-") c #ADAAC6",
-"! c #B5B2CE",
-"~ c #B5B6CE",
-"{ c #A5A2BD",
-"] c #A5A6BD",
-"^ c #9C9EB5",
-"/ c #9CA2BD",
-"( c #ADAEC6",
-"_ c #C6C3E7",
-": c #9C9AB5",
-"< c #A5A6C6",
-"[ c #949AAD",
-"} c #A5AAC6",
-"| c #9496AD",
-"1 c #BDBADE",
-"2 c #BDBED6",
-"3 c #9CA2B5",
-"4 c #A5AABD",
+" c None",
+". c #FFFFFF",
+"+ c #CECBE7",
+"@ c #C6C7E7",
+"# c #CECFEF",
+"$ c #C6CBE7",
+"% c #BDBEDE",
+"& c #BDC3DE",
+"* c #CECBEF",
+"= c #B5B6D6",
+"- c #ADAECE",
+"; c #ADB2CE",
+"> c #BDBAD6",
+", c #B5BAD6",
+"' c #C6C3DE",
+") c #ADAAC6",
+"! c #B5B2CE",
+"~ c #B5B6CE",
+"{ c #A5A2BD",
+"] c #A5A6BD",
+"^ c #9C9EB5",
+"/ c #9CA2BD",
+"( c #ADAEC6",
+"_ c #C6C3E7",
+": c #9C9AB5",
+"< c #A5A6C6",
+"[ c #949AAD",
+"} c #A5AAC6",
+"| c #9496AD",
+"1 c #BDBADE",
+"2 c #BDBED6",
+"3 c #9CA2B5",
+"4 c #A5AABD",
"..........................+@#$#$#",
"........................%@&*$#$##",
"......................==%%@@*$#$#",
@@ -3846,9 +3846,9 @@ static char * tabselectedend_xpm[] = {
static char * tabend_xpm[] = {
"33 42 3 1",
-" c None",
-". c #CECFEF",
-"+ c #FFFFFF",
+" c None",
+". c #CECFEF",
+"+ c #FFFFFF",
"..........................+++++++",
"........................+++++++++",
"......................+++++++++++",
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index dde705f9b9..9ab8f8f08a 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -252,7 +252,7 @@ void QWindowsStyle::polish(QApplication *app)
d->inactiveGradientCaptionColor = app->palette().dark().color();
d->inactiveCaptionText = app->palette().background().color();
-#if defined(Q_OS_WIN) //fetch native title bar colors
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) //fetch native title bar colors
if(app->desktopSettingsAware()){
DWORD activeCaption = GetSysColor(COLOR_ACTIVECAPTION);
DWORD gradientActiveCaption = GetSysColor(COLOR_GRADIENTACTIVECAPTION);
@@ -413,6 +413,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
#if defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT // There is no title bar in Windows Runtime applications
case PM_TitleBarHeight:
if (widget && (widget->windowType() == Qt::Tool)) {
// MS always use one less than they say
@@ -426,16 +427,17 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
}
break;
+#endif // !Q_OS_WINRT
case PM_ScrollBarExtent:
{
-#ifndef Q_OS_WINCE
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
NONCLIENTMETRICS ncm;
ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
ret = qMax(ncm.iScrollHeight, ncm.iScrollWidth);
else
-#endif
+#endif // !Q_OS_WINCE && !Q_OS_WINRT
ret = QCommonStyle::pixelMetric(pm, opt, widget);
}
break;
@@ -446,6 +448,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
break;
#if defined(Q_OS_WIN)
+#ifndef Q_OS_WINRT // Mdi concept not available for WinRT applications
case PM_MdiSubWindowFrameWidth:
#if defined(Q_OS_WINCE)
ret = GetSystemMetrics(SM_CYDLGFRAME);
@@ -453,7 +456,8 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
ret = GetSystemMetrics(SM_CYFRAME);
#endif
break;
-#endif
+#endif // !Q_OS_WINRT
+#endif // Q_OS_WIN
case PM_ToolBarItemMargin:
ret = 1;
break;
@@ -477,7 +481,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW
QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
const QWidget *widget) const
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QPixmap desktopIcon;
switch(standardPixmap) {
case SP_DriveCDIcon:
@@ -516,7 +520,7 @@ QPixmap QWindowsStyle::standardPixmap(StandardPixmap standardPixmap, const QStyl
if (!desktopIcon.isNull()) {
return desktopIcon;
}
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINCE && !Q_OS_WINRT
return QCommonStyle::standardPixmap(standardPixmap, opt, widget);
}
@@ -554,7 +558,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
ret = 0;
break;
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Option not used on WinRT -> common style
case SH_UnderlineShortcut:
{
ret = 1;
@@ -590,7 +594,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
#endif // QT_NO_ACCESSIBILITY
break;
}
-#endif
+#endif // Q_OS_WIN && !Q_OS_WINRT
#ifndef QT_NO_RUBBERBAND
case SH_RubberBand_Mask:
if (const QStyleOptionRubberBand *rbOpt = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index af379b756e..6c7b71bd74 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -1236,7 +1236,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
case CE_MenuItem:
if (const QStyleOptionMenuItem *menuitem = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
// windows always has a check column, regardless whether we have an icon or not
- int checkcol = 28;
+ int checkcol = 25;
{
SIZE size;
MARGINS margins;
@@ -1244,11 +1244,13 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
MENU_POPUPCHECKBACKGROUND, MBI_HOT);
pGetThemePartSize(theme.handle(), NULL, MENU_POPUPCHECK, 0, NULL,TS_TRUE, &size);
pGetThemeMargins(theme.handle(), NULL, MENU_POPUPCHECK, 0, TMT_CONTENTMARGINS, NULL, &margins);
- checkcol = qMax(menuitem->maxIconWidth, int(6 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
+ checkcol = qMax(menuitem->maxIconWidth, int(3 + size.cx + margins.cxLeftWidth + margins.cxRightWidth));
}
QRect rect = option->rect;
//draw vertical menu line
+ if (option->direction == Qt::LeftToRight)
+ checkcol += rect.x();
QPoint p1 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.top()));
QPoint p2 = QStyle::visualPos(option->direction, menuitem->rect, QPoint(checkcol, rect.bottom()));
QRect gutterRect(p1.x(), p1.y(), 3, p2.y() - p1.y() + 1);
@@ -1340,11 +1342,9 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
painter->setPen(menuitem->palette.buttonText().color());
- QColor discol;
- if (dis) {
- discol = menuitem->palette.text().color();
- painter->setPen(discol);
- }
+ const QColor textColor = menuitem->palette.text().color();
+ if (dis)
+ painter->setPen(textColor);
int xm = windowsItemFrame + checkcol + windowsItemHMargin;
int xpos = menuitem->rect.x() + xm;
@@ -1368,7 +1368,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (menuitem->menuItemType == QStyleOptionMenuItem::DefaultItem)
font.setBold(true);
painter->setFont(font);
- painter->setPen(discol);
+ painter->setPen(textColor);
painter->drawText(vTextRect, text_flags, s.left(t));
painter->restore();
}
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 79ca0a5bdb..f1a69e6b36 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -505,10 +505,10 @@ QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title
si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
break;
case QSystemTrayIcon::Critical:
- si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
+ si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
break;
case QSystemTrayIcon::Information:
- si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
+ si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
break;
case QSystemTrayIcon::NoIcon:
default:
diff --git a/src/widgets/util/qsystemtrayicon_qpa.cpp b/src/widgets/util/qsystemtrayicon_qpa.cpp
index 3ce89e352d..f98aeaf678 100644
--- a/src/widgets/util/qsystemtrayicon_qpa.cpp
+++ b/src/widgets/util/qsystemtrayicon_qpa.cpp
@@ -99,8 +99,14 @@ void QSystemTrayIconPrivate::updateIcon_sys()
void QSystemTrayIconPrivate::updateMenu_sys()
{
- if (qpa_sys && menu)
+ if (qpa_sys && menu) {
+ if (!menu->platformMenu()) {
+ QPlatformMenu *platformMenu = qpa_sys->createMenu();
+ if (platformMenu)
+ menu->setPlatformMenu(platformMenu);
+ }
qpa_sys->updateMenu(menu->platformMenu());
+ }
}
void QSystemTrayIconPrivate::updateToolTip_sys()
diff --git a/src/widgets/util/util.pri b/src/widgets/util/util.pri
index 072c736f71..b4bbc5fc30 100644
--- a/src/widgets/util/util.pri
+++ b/src/widgets/util/util.pri
@@ -27,7 +27,7 @@ SOURCES += \
util/qundostack.cpp \
util/qundoview.cpp
-win32:!wince* {
+win32:!wince*:!winrt {
SOURCES += util/qsystemtrayicon_win.cpp
} else:contains(QT_CONFIG, xcb) {
SOURCES += util/qsystemtrayicon_x11.cpp
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 25369a01b6..92af91b66e 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -396,6 +396,30 @@ bool QAbstractSpinBox::isAccelerated() const
}
/*!
+ \property QAbstractSpinBox::showGroupSeparator
+ \since 5.3
+
+
+ This property holds whether a thousands separator is enabled. By default this
+ property is false.
+*/
+bool QAbstractSpinBox::isGroupSeparatorShown() const
+{
+ Q_D(const QAbstractSpinBox);
+ return d->showGroupSeparator;
+}
+
+void QAbstractSpinBox::setGroupSeparatorShown(bool shown)
+{
+ Q_D(QAbstractSpinBox);
+ if (d->showGroupSeparator == shown)
+ return;
+ d->showGroupSeparator = shown;
+ d->setValue(d->value, EmitIfChanged);
+ updateGeometry();
+}
+
+/*!
\enum QAbstractSpinBox::CorrectionMode
This enum type describes the mode the spinbox will use to correct
@@ -1316,7 +1340,8 @@ QAbstractSpinBoxPrivate::QAbstractSpinBoxPrivate()
cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false),
ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue),
- acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0)
+ acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows), validator(0),
+ showGroupSeparator(0)
{
}
@@ -1491,13 +1516,12 @@ void QAbstractSpinBoxPrivate::_q_editorCursorPositionChanged(int oldpos, int new
* (newpos < pos ? -1 : 1)) - newpos + pos
: 0;
- const bool wasBlocked = edit->blockSignals(true);
+ const QSignalBlocker blocker(edit);
if (selSize != 0) {
edit->setSelection(pos - selSize, selSize);
} else {
edit->setCursorPosition(pos);
}
- edit->blockSignals(wasBlocked);
}
ignoreCursorPositionChanged = false;
}
@@ -1697,7 +1721,7 @@ void QAbstractSpinBoxPrivate::updateEdit()
const bool empty = edit->text().isEmpty();
int cursor = edit->cursorPosition();
int selsize = edit->selectedText().size();
- const bool sb = edit->blockSignals(true);
+ const QSignalBlocker blocker(edit);
edit->setText(newText);
if (!specialValue()) {
@@ -1709,7 +1733,6 @@ void QAbstractSpinBoxPrivate::updateEdit()
edit->setCursorPosition(empty ? prefix.size() : cursor);
}
}
- edit->blockSignals(sb);
q->update();
}
diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h
index 4f6aad0cde..7989000cc8 100644
--- a/src/widgets/widgets/qabstractspinbox.h
+++ b/src/widgets/widgets/qabstractspinbox.h
@@ -72,6 +72,7 @@ class Q_WIDGETS_EXPORT QAbstractSpinBox : public QWidget
Q_PROPERTY(CorrectionMode correctionMode READ correctionMode WRITE setCorrectionMode)
Q_PROPERTY(bool acceptableInput READ hasAcceptableInput)
Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking)
+ Q_PROPERTY(bool showGroupSeparator READ isGroupSeparatorShown WRITE setGroupSeparatorShown)
public:
explicit QAbstractSpinBox(QWidget *parent = 0);
~QAbstractSpinBox();
@@ -114,6 +115,9 @@ public:
void setAccelerated(bool on);
bool isAccelerated() const;
+ void setGroupSeparatorShown(bool shown);
+ bool isGroupSeparatorShown() const;
+
QSize sizeHint() const;
QSize minimumSizeHint() const;
void interpretText();
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index 0eeec02abc..da9f1d9757 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -150,6 +150,7 @@ public:
QRect hoverRect;
QAbstractSpinBox::ButtonSymbols buttonSymbols;
QSpinBoxValidator *validator;
+ uint showGroupSeparator : 1;
};
class QSpinBoxValidator : public QValidator
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 2c09f5a8f1..17a6ededfe 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -2608,9 +2608,9 @@ void QComboBox::hidePopup()
Q_D(QComboBox);
if (d->container && d->container->isVisible()) {
#if !defined(QT_NO_EFFECTS)
- d->model->blockSignals(true);
- d->container->itemView()->blockSignals(true);
- d->container->blockSignals(true);
+ QSignalBlocker modelBlocker(d->model);
+ QSignalBlocker viewBlocker(d->container->itemView());
+ QSignalBlocker containerBlocker(d->container);
// Flash selected/triggered item (if any).
if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) {
QItemSelectionModel *selectionModel = view() ? view()->selectionModel() : 0;
@@ -2646,9 +2646,9 @@ void QComboBox::hidePopup()
#endif // Q_OS_MAC
// Other platform implementations welcome :-)
}
- d->model->blockSignals(false);
- d->container->itemView()->blockSignals(false);
- d->container->blockSignals(false);
+ containerBlocker.unblock();
+ viewBlocker.unblock();
+ modelBlocker.unblock();
if (!didFade)
#endif // QT_NO_EFFECTS
diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp
index a0bbbbf7c7..7a723c5f1f 100644
--- a/src/widgets/widgets/qdatetimeedit.cpp
+++ b/src/widgets/widgets/qdatetimeedit.cpp
@@ -1718,7 +1718,7 @@ void QDateTimeEditPrivate::updateEdit()
if (newText == displayText())
return;
int selsize = edit->selectedText().size();
- const bool sb = edit->blockSignals(true);
+ const QSignalBlocker blocker(edit);
edit->setText(newText);
@@ -1740,7 +1740,6 @@ void QDateTimeEditPrivate::updateEdit()
}
}
- edit->blockSignals(sb);
}
@@ -1871,7 +1870,7 @@ void QDateTimeEditPrivate::clearSection(int index)
{
const QLatin1Char space(' ');
int cursorPos = edit->cursorPosition();
- bool blocked = edit->blockSignals(true);
+ const QSignalBlocker blocker(edit);
QString t = edit->text();
const int pos = sectionPos(index);
if (pos == -1) {
@@ -1883,8 +1882,6 @@ void QDateTimeEditPrivate::clearSection(int index)
edit->setText(t);
edit->setCursorPosition(cursorPos);
QDTEDEBUG << cursorPos;
-
- edit->blockSignals(blocked);
}
@@ -2313,7 +2310,7 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event)
optCombo.init(this);
optCombo.editable = true;
- optCombo.frame = opt.frame;
+ optCombo.frame = opt.frame;
optCombo.subControls = opt.subControls;
optCombo.activeSubControls = opt.activeSubControls;
optCombo.state = opt.state;
@@ -2574,10 +2571,9 @@ void QDateTimeEditPrivate::syncCalendarWidget()
{
Q_Q(QDateTimeEdit);
if (monthCalendar) {
- const bool sb = monthCalendar->blockSignals(true);
+ const QSignalBlocker blocker(monthCalendar);
monthCalendar->setDateRange(q->minimumDate(), q->maximumDate());
monthCalendar->setDate(q->date());
- monthCalendar->blockSignals(sb);
}
}
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index 6b183d3759..3acd4f0701 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -46,7 +46,9 @@
#include <QtWidgets/qdialog.h>
#include <QtWidgets/qapplication.h>
#include <private/qwidget_p.h>
+#include <private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformdialoghelper.h>
+#include <QtGui/qpa/qplatformtheme.h>
#include <QtWidgets/qaction.h>
#include "qdialogbuttonbox.h"
@@ -148,77 +150,6 @@ QT_BEGIN_NAMESPACE
\sa QMessageBox, QPushButton, QDialog
*/
-enum {
- AcceptRole = QDialogButtonBox::AcceptRole,
- RejectRole = QDialogButtonBox::RejectRole,
- DestructiveRole = QDialogButtonBox::DestructiveRole,
- ActionRole = QDialogButtonBox::ActionRole,
- HelpRole = QDialogButtonBox::HelpRole,
- YesRole = QDialogButtonBox::YesRole,
- NoRole = QDialogButtonBox::NoRole,
- ApplyRole = QDialogButtonBox::ApplyRole,
- ResetRole = QDialogButtonBox::ResetRole,
-
- AlternateRole = 0x10000000,
- Stretch = 0x20000000,
- EOL = 0x40000000,
- Reverse = 0x80000000
-};
-
-static QDialogButtonBox::ButtonRole roleFor(QDialogButtonBox::StandardButton button)
-{
- return static_cast<QDialogButtonBox::ButtonRole>(QMessageDialogOptions::buttonRole(
- static_cast<QMessageDialogOptions::StandardButton>(button)));
-}
-
-static const uint layouts[2][5][14] =
-{
- // Qt::Horizontal
- {
- // WinLayout
- { ResetRole, Stretch, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, ActionRole, RejectRole, ApplyRole,
- HelpRole, EOL, EOL, EOL },
-
- // MacLayout
- { HelpRole, ResetRole, ApplyRole, ActionRole, Stretch, DestructiveRole | Reverse,
- AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL, EOL },
-
- // KdeLayout
- { HelpRole, ResetRole, Stretch, YesRole, NoRole, ActionRole, AcceptRole, AlternateRole,
- ApplyRole, DestructiveRole, RejectRole, EOL },
-
- // GnomeLayout
- { HelpRole, ResetRole, Stretch, ActionRole, ApplyRole | Reverse, DestructiveRole | Reverse,
- AlternateRole | Reverse, RejectRole | Reverse, AcceptRole | Reverse, NoRole | Reverse, YesRole | Reverse, EOL },
-
- // Mac modeless
- { ResetRole, ApplyRole, ActionRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
- },
-
- // Qt::Vertical
- {
- // WinLayout
- { ActionRole, YesRole, AcceptRole, AlternateRole, DestructiveRole, NoRole, RejectRole, ApplyRole, ResetRole,
- HelpRole, Stretch, EOL, EOL, EOL },
-
- // MacLayout
- { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, Stretch, ActionRole, ApplyRole,
- ResetRole, HelpRole, EOL, EOL },
-
- // KdeLayout
- { AcceptRole, AlternateRole, ApplyRole, ActionRole, YesRole, NoRole, Stretch, ResetRole,
- DestructiveRole, RejectRole, HelpRole, EOL },
-
- // GnomeLayout
- { YesRole, NoRole, AcceptRole, RejectRole, AlternateRole, DestructiveRole, ApplyRole, ActionRole, Stretch,
- ResetRole, HelpRole, EOL, EOL, EOL },
-
- // Mac modeless
- { ActionRole, ApplyRole, ResetRole, Stretch, HelpRole, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL, EOL }
- }
-};
-
-
class QDialogButtonBoxPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QDialogButtonBox)
@@ -246,7 +177,6 @@ public:
void _q_handleButtonClicked();
void addButtonsToLayout(const QList<QAbstractButton *> &buttonList, bool reverse);
void retranslateStrings();
- const char *standardButtonText(QDialogButtonBox::StandardButton sbutton) const;
};
QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
@@ -322,7 +252,8 @@ void QDialogButtonBoxPrivate::layoutButtons()
int tmpPolicy = layoutPolicy;
static const int M = 5;
- static const int ModalRoles[M] = { AcceptRole, RejectRole, DestructiveRole, YesRole, NoRole };
+ static const int ModalRoles[M] = { QPlatformDialogHelper::AcceptRole, QPlatformDialogHelper::RejectRole,
+ QPlatformDialogHelper::DestructiveRole, QPlatformDialogHelper::YesRole, QPlatformDialogHelper::NoRole };
if (tmpPolicy == QDialogButtonBox::MacLayout) {
bool hasModalButton = false;
for (int i = 0; i < M; ++i) {
@@ -335,23 +266,24 @@ void QDialogButtonBoxPrivate::layoutButtons()
tmpPolicy = 4; // Mac modeless
}
- const uint *currentLayout = layouts[orientation == Qt::Vertical][tmpPolicy];
+ const int *currentLayout = QPlatformDialogHelper::buttonLayout(
+ orientation, static_cast<QPlatformDialogHelper::ButtonLayout>(tmpPolicy));
if (center)
buttonLayout->addStretch();
- QList<QAbstractButton *> acceptRoleList = buttonLists[AcceptRole];
+ QList<QAbstractButton *> acceptRoleList = buttonLists[QPlatformDialogHelper::AcceptRole];
- while (*currentLayout != EOL) {
- int role = (*currentLayout & ~Reverse);
- bool reverse = (*currentLayout & Reverse);
+ while (*currentLayout != QPlatformDialogHelper::EOL) {
+ int role = (*currentLayout & ~QPlatformDialogHelper::Reverse);
+ bool reverse = (*currentLayout & QPlatformDialogHelper::Reverse);
switch (role) {
- case Stretch:
+ case QPlatformDialogHelper::Stretch:
if (!center)
buttonLayout->addStretch();
break;
- case AcceptRole: {
+ case QPlatformDialogHelper::AcceptRole: {
if (acceptRoleList.isEmpty())
break;
// Only the first one
@@ -360,7 +292,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
button->show();
}
break;
- case AlternateRole:
+ case QPlatformDialogHelper::AlternateRole:
{
if (acceptRoleList.size() < 2)
break;
@@ -369,7 +301,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
addButtonsToLayout(list, reverse);
}
break;
- case DestructiveRole:
+ case QPlatformDialogHelper::DestructiveRole:
{
const QList<QAbstractButton *> &list = buttonLists[role];
@@ -395,13 +327,13 @@ void QDialogButtonBoxPrivate::layoutButtons()
buttonLayout->addSpacing(MacGap);
}
break;
- case RejectRole:
- case ActionRole:
- case HelpRole:
- case YesRole:
- case NoRole:
- case ApplyRole:
- case ResetRole:
+ case QPlatformDialogHelper::RejectRole:
+ case QPlatformDialogHelper::ActionRole:
+ case QPlatformDialogHelper::HelpRole:
+ case QPlatformDialogHelper::YesRole:
+ case QPlatformDialogHelper::NoRole:
+ case QPlatformDialogHelper::ApplyRole:
+ case QPlatformDialogHelper::ResetRole:
addButtonsToLayout(buttonLists[role], reverse);
}
++currentLayout;
@@ -428,7 +360,6 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
bool doLayout)
{
Q_Q(QDialogButtonBox);
- const char *buttonText = 0;
int icon = 0;
switch (sbutton) {
@@ -477,17 +408,16 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
return 0;
;
}
- buttonText = standardButtonText(sbutton);
-
- QPushButton *button = new QPushButton(QDialogButtonBox::tr(buttonText), q);
+ QPushButton *button = new QPushButton(QGuiApplicationPrivate::platformTheme()->standardButtonText(sbutton), q);
QStyle *style = q->style();
if (style->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, 0, q) && icon != 0)
button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), 0, q));
if (style != QApplication::style()) // Propagate style
button->setStyle(style);
standardButtonHash.insert(button, sbutton);
- if (roleFor(sbutton) != QDialogButtonBox::InvalidRole) {
- addButton(button, roleFor(sbutton), doLayout);
+ QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast<QPlatformDialogHelper::StandardButton>(sbutton));
+ if (role != QPlatformDialogHelper::InvalidRole) {
+ addButton(button, static_cast<QDialogButtonBox::ButtonRole>(role), doLayout);
} else {
qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
}
@@ -525,87 +455,15 @@ void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardBu
layoutButtons();
}
-const char *QDialogButtonBoxPrivate::standardButtonText(QDialogButtonBox::StandardButton sbutton) const
-{
- const char *buttonText = 0;
- bool gnomeLayout = (layoutPolicy == QDialogButtonBox::GnomeLayout);
- switch (sbutton) {
- case QDialogButtonBox::Ok:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK") : QT_TRANSLATE_NOOP("QDialogButtonBox", "OK");
- break;
- case QDialogButtonBox::Save:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Save") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Save");
- break;
- case QDialogButtonBox::Open:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Open");
- break;
- case QDialogButtonBox::Cancel:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Cancel");
- break;
- case QDialogButtonBox::Close:
- buttonText = gnomeLayout ? QT_TRANSLATE_NOOP("QDialogButtonBox", "&Close") : QT_TRANSLATE_NOOP("QDialogButtonBox", "Close");
- break;
- case QDialogButtonBox::Apply:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Apply");
- break;
- case QDialogButtonBox::Reset:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Reset");
- break;
- case QDialogButtonBox::Help:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Help");
- break;
- case QDialogButtonBox::Discard:
- if (layoutPolicy == QDialogButtonBox::MacLayout)
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Don't Save");
- else if (layoutPolicy == QDialogButtonBox::GnomeLayout)
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Close without Saving");
- else
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Discard");
- break;
- case QDialogButtonBox::Yes:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&Yes");
- break;
- case QDialogButtonBox::YesToAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Yes to &All");
- break;
- case QDialogButtonBox::No:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "&No");
- break;
- case QDialogButtonBox::NoToAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "N&o to All");
- break;
- case QDialogButtonBox::SaveAll:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Save All");
- break;
- case QDialogButtonBox::Abort:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Abort");
- break;
- case QDialogButtonBox::Retry:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Retry");
- break;
- case QDialogButtonBox::Ignore:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Ignore");
- break;
- case QDialogButtonBox::RestoreDefaults:
- buttonText = QT_TRANSLATE_NOOP("QDialogButtonBox", "Restore Defaults");
- break;
- case QDialogButtonBox::NoButton:
- ;
- } // switch
- return buttonText;
-}
-
void QDialogButtonBoxPrivate::retranslateStrings()
{
- const char *buttonText = 0;
- QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator it = standardButtonHash.begin();
- while (it != standardButtonHash.end()) {
- buttonText = standardButtonText(it.value());
- if (buttonText) {
- QPushButton *button = it.key();
- button->setText(QDialogButtonBox::tr(buttonText));
- }
- ++it;
+ typedef QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator Iterator;
+
+ const Iterator end = standardButtonHash.end();
+ for (Iterator it = standardButtonHash.begin(); it != end; ++it) {
+ const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(it.value());
+ if (!text.isEmpty())
+ it.key()->setText(text);
}
}
@@ -1008,15 +866,15 @@ void QDialogButtonBoxPrivate::_q_handleButtonClicked()
emit q->clicked(button);
switch (q->buttonRole(button)) {
- case AcceptRole:
- case YesRole:
+ case QPlatformDialogHelper::AcceptRole:
+ case QPlatformDialogHelper::YesRole:
emit q->accepted();
break;
- case RejectRole:
- case NoRole:
+ case QPlatformDialogHelper::RejectRole:
+ case QPlatformDialogHelper::NoRole:
emit q->rejected();
break;
- case HelpRole:
+ case QPlatformDialogHelper::HelpRole:
emit q->helpRequested();
break;
default:
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
index d8e1a997d4..5cd94f88b0 100644
--- a/src/widgets/widgets/qdialogbuttonbox.h
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -61,7 +61,7 @@ class Q_WIDGETS_EXPORT QDialogButtonBox : public QWidget
public:
enum ButtonRole {
- // keep this in sync with QMessageBox::ButtonRole
+ // keep this in sync with QMessageBox::ButtonRole and QPlatformDialogHelper::ButtonRole
InvalidRole = -1,
AcceptRole,
RejectRole,
@@ -77,7 +77,7 @@ public:
};
enum StandardButton {
- // keep this in sync with QMessageBox::StandardButton
+ // keep this in sync with QMessageBox::StandardButton and QPlatformDialogHelper::StandardButton
NoButton = 0x00000000,
Ok = 0x00000400,
Save = 0x00000800,
@@ -107,6 +107,7 @@ public:
Q_DECLARE_FLAGS(StandardButtons, StandardButton)
enum ButtonLayout {
+ // keep this in sync with QMessageBox::ButtonLayout and QPlatformDialogHelper::ButtonLayout
WinLayout,
MacLayout,
KdeLayout,
diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp
index 72a463b30b..066b3c7a86 100644
--- a/src/widgets/widgets/qdockarealayout.cpp
+++ b/src/widgets/widgets/qdockarealayout.cpp
@@ -1940,9 +1940,9 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
} else {
QDockAreaLayoutItem item(new QDockWidgetItem(widget));
if (flags & StateFlagFloating) {
- bool drawer = false;
+ bool drawer = false;
#ifdef Q_WS_MAC // drawer support
- extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
+ extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp
extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp
drawer = qt_mac_is_macdrawer(widget);
#endif
@@ -1988,10 +1988,10 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*>
emit widget->dockLocationChanged(toDockWidgetArea(dockPos));
}
}
- if (testing) {
- //was it is not really added to the layout, we need to delete the object here
- delete item.widgetItem;
- }
+ if (testing) {
+ //was it is not really added to the layout, we need to delete the object here
+ delete item.widgetItem;
+ }
}
} else if (nextMarker == SequenceMarker) {
int dummy;
@@ -2096,7 +2096,7 @@ bool QDockAreaLayoutInfo::updateTabBar() const
that->tabBar->setDrawBase(true);
}
- bool blocked = tabBar->blockSignals(true);
+ const QSignalBlocker blocker(tabBar);
bool gap = false;
int tab_idx = 0;
@@ -2147,8 +2147,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const
tabBar->removeTab(tab_idx);
}
- tabBar->blockSignals(blocked);
-
//returns if the tabbar is visible or not
return ( (gap ? 1 : 0) + tabBar->count()) > 1;
}
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 46929397a0..ad9481a928 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -667,6 +667,7 @@ void QDockWidgetPrivate::updateButtons()
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q));
button->setVisible(canFloat && !hideButtons);
#ifndef QT_NO_ACCESSIBILITY
+ //: Accessible name for button undocking a dock widget (floating state)
button->setAccessibleName(QDockWidget::tr("Float"));
button->setAccessibleDescription(QDockWidget::tr("Undocks and re-attaches the dock widget"));
#endif
@@ -675,6 +676,7 @@ void QDockWidgetPrivate::updateButtons()
button->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q));
button->setVisible(canClose && !hideButtons);
#ifndef QT_NO_ACCESSIBILITY
+ //: Accessible name for button closing a dock widget
button->setAccessibleName(QDockWidget::tr("Close"));
button->setAccessibleDescription(QDockWidget::tr("Closes the dock widget"));
#endif
@@ -1104,8 +1106,8 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
\enum QDockWidget::DockWidgetFeature
\value DockWidgetClosable The dock widget can be closed. On some systems the dock
- widget always has a close button when it's floating
- (for example on MacOS 10.5).
+ widget always has a close button when it's floating
+ (for example on MacOS 10.5).
\value DockWidgetMovable The dock widget can be moved between docks
by the user.
\value DockWidgetFloatable The dock widget can be detached from the
diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h
index 800f523825..f7cd8c0039 100644
--- a/src/widgets/widgets/qdockwidget_p.h
+++ b/src/widgets/widgets/qdockwidget_p.h
@@ -84,7 +84,7 @@ class QDockWidgetPrivate : public QWidgetPrivate
public:
inline QDockWidgetPrivate()
- : QWidgetPrivate(), state(0),
+ : QWidgetPrivate(), state(0),
features(QDockWidget::DockWidgetClosable
| QDockWidget::DockWidgetMovable
| QDockWidget::DockWidgetFloatable),
diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp
index 83060bb571..cd8ae81ace 100644
--- a/src/widgets/widgets/qeffects.cpp
+++ b/src/widgets/widgets/qeffects.cpp
@@ -189,32 +189,32 @@ bool QAlphaWidget::eventFilter(QObject *o, QEvent *e)
{
switch (e->type()) {
case QEvent::Move:
- if (o != widget)
- break;
- move(widget->geometry().x(),widget->geometry().y());
- update();
- break;
+ if (o != widget)
+ break;
+ move(widget->geometry().x(),widget->geometry().y());
+ update();
+ break;
case QEvent::Hide:
case QEvent::Close:
- if (o != widget)
- break;
+ if (o != widget)
+ break;
case QEvent::MouseButtonPress:
- case QEvent::MouseButtonDblClick:
- showWidget = false;
- render();
- break;
+ case QEvent::MouseButtonDblClick:
+ showWidget = false;
+ render();
+ break;
case QEvent::KeyPress: {
- QKeyEvent *ke = (QKeyEvent*)e;
- if (ke->key() == Qt::Key_Escape) {
- showWidget = false;
- } else {
- duration = 0;
- }
- render();
- break;
- }
+ QKeyEvent *ke = (QKeyEvent*)e;
+ if (ke->key() == Qt::Key_Escape) {
+ showWidget = false;
+ } else {
+ duration = 0;
+ }
+ render();
+ break;
+ }
default:
- break;
+ break;
}
return QWidget::eventFilter(o, e);
}
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 0b0efa2bdf..2bbf3730db 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -346,9 +346,10 @@ void QFontComboBoxPrivate::_q_updateModel()
//this prevents the current index from changing
//it will be updated just after this
///TODO: we should finda way to avoid blocking signals and have a real update of the model
- const bool old = m->blockSignals(true);
- m->setStringList(list);
- m->blockSignals(old);
+ {
+ const QSignalBlocker blocker(m);
+ m->setStringList(list);
+ }
if (list.isEmpty()) {
if (currentFont != QFont()) {
diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h
index 3dde1527f2..ba7b2d8494 100644
--- a/src/widgets/widgets/qlcdnumber.h
+++ b/src/widgets/widgets/qlcdnumber.h
@@ -43,7 +43,6 @@
#define QLCDNUMBER_H
#include <QtWidgets/qframe.h>
-#include <QtCore/qbitarray.h>
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index df5ae0171c..1833dce40b 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -333,7 +333,12 @@ void QLineEdit::setText(const QString& text)
\brief the line edit's placeholder text
Setting this property makes the line edit display a grayed-out
- placeholder text as long as the text() is empty.
+ placeholder text as long as the line edit is empty.
+
+ Normally, an empty line edit shows the placeholder text even
+ when it has focus. However, if the content is horizontally
+ centered, the placeholder text is not displayed under
+ the cursor when the line edit has focus.
By default, this property contains an empty string.
@@ -350,7 +355,7 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText)
Q_D(QLineEdit);
if (d->placeholderText != placeholderText) {
d->placeholderText = placeholderText;
- if (d->control->text().isEmpty())
+ if (d->shouldShowPlaceholderText())
update();
}
}
@@ -1895,7 +1900,7 @@ void QLineEdit::paintEvent(QPaintEvent *)
int minLB = qMax(0, -fm.minLeftBearing());
int minRB = qMax(0, -fm.minRightBearing());
- if (d->control->text().isEmpty() && d->control->preeditAreaText().isEmpty()) {
+ if (d->shouldShowPlaceholderText()) {
if (!d->placeholderText.isEmpty()) {
QColor col = pal.text().color();
col.setAlpha(128);
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index 181a23449b..aa5b57a920 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -148,6 +148,11 @@ public:
{
return !control->isReadOnly();
}
+ inline bool shouldShowPlaceholderText() const
+ {
+ return control->text().isEmpty() && control->preeditAreaText().isEmpty()
+ && !((alignment & Qt::AlignHCenter) && q_func()->hasFocus());
+ }
static inline QLineEditPrivate *get(QLineEdit *lineEdit) {
return lineEdit->d_func();
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index 349d8c3423..600d9b536f 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -1115,10 +1115,9 @@ void QMdiAreaPrivate::updateActiveWindow(int removedIndex, bool activeRemoved)
#ifndef QT_NO_TABBAR
if (tabBar && removedIndex >= 0) {
- tabBar->blockSignals(true);
+ const QSignalBlocker blocker(tabBar);
tabBar->removeTab(removedIndex);
updateTabBarGeometry();
- tabBar->blockSignals(false);
}
#endif
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 8e1dcbee18..94674319bc 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -2057,13 +2057,13 @@ void QMdiSubWindowPrivate::restoreFocus()
/*!
\internal
- ### Please add QEvent::WindowFlagsChange event
*/
void QMdiSubWindowPrivate::setWindowFlags(Qt::WindowFlags windowFlags)
{
Q_Q(QMdiSubWindow);
+
if (!parent) {
- q->setWindowFlags(windowFlags);
+ QWidgetPrivate::setWindowFlags(windowFlags);
return;
}
@@ -2097,7 +2097,7 @@ void QMdiSubWindowPrivate::setWindowFlags(Qt::WindowFlags windowFlags)
delete sizeGrip;
#endif
- q->setWindowFlags(windowFlags);
+ QWidgetPrivate::setWindowFlags(windowFlags);
updateGeometryConstraints();
updateActions();
QSize currentSize = q->size();
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 3a4fd449c8..edfeb840b1 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -153,13 +153,48 @@ void QMenuPrivate::init()
scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone;
}
- platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu();
+ setPlatformMenu(QGuiApplicationPrivate::platformTheme()->createPlatformMenu());
+}
+
+void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu)
+{
+ Q_Q(QMenu);
+ if (!platformMenu.isNull() && !platformMenu->parent())
+ delete platformMenu.data();
+
+ platformMenu = menu;
if (!platformMenu.isNull()) {
QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow()));
QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide()));
}
}
+// forward declare function
+static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* item);
+
+void QMenuPrivate::syncPlatformMenu()
+{
+ Q_Q(QMenu);
+ if (platformMenu.isNull())
+ return;
+
+ QPlatformMenuItem *beforeItem = Q_NULLPTR;
+ QListIterator<QAction*> it(q->actions());
+ it.toBack();
+ while (it.hasPrevious()) {
+ QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
+ QAction *action = it.previous();
+ menuItem->setTag(reinterpret_cast<quintptr>(action));
+ QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()));
+ QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()));
+ copyActionToPlatformItem(action, menuItem);
+ platformMenu->insertMenuItem(menuItem, beforeItem);
+ beforeItem = menuItem;
+ }
+ platformMenu->syncSeparatorsCollapsible(collapsibleSeparators);
+ platformMenu->setEnabled(q->isEnabled());
+}
+
int QMenuPrivate::scrollerHeight() const
{
Q_Q(const QMenu);
@@ -435,7 +470,7 @@ void QMenuPrivate::hideMenu(QMenu *menu)
if (!menu)
return;
#if !defined(QT_NO_EFFECTS)
- menu->blockSignals(true);
+ QSignalBlocker blocker(menu);
aboutToHide = true;
// Flash item which is about to trigger (if any).
if (menu->style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)
@@ -455,7 +490,7 @@ void QMenuPrivate::hideMenu(QMenu *menu)
}
aboutToHide = false;
- menu->blockSignals(false);
+ blocker.unblock();
#endif // QT_NO_EFFECTS
menu->close();
}
@@ -2976,8 +3011,7 @@ void QMenu::actionEvent(QActionEvent *e)
if (!d->platformMenu.isNull()) {
if (e->type() == QEvent::ActionAdded) {
- QPlatformMenuItem *menuItem =
- QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();
+ QPlatformMenuItem *menuItem = d->platformMenu->createMenuItem();
menuItem->setTag(reinterpret_cast<quintptr>(e->action()));
QObject::connect(menuItem, SIGNAL(activated()), e->action(), SLOT(trigger()));
QObject::connect(menuItem, SIGNAL(hovered()), e->action(), SIGNAL(hovered()));
@@ -3154,6 +3188,14 @@ QPlatformMenu *QMenu::platformMenu()
return d_func()->platformMenu;
}
+/*!\internal
+*/
+void QMenu::setPlatformMenu(QPlatformMenu *platformMenu)
+{
+ d_func()->setPlatformMenu(platformMenu);
+ d_func()->syncPlatformMenu();
+}
+
/*!
\property QMenu::separatorsCollapsible
\since 4.2
diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h
index 7a128e871c..8a8eaf3bae 100644
--- a/src/widgets/widgets/qmenu.h
+++ b/src/widgets/widgets/qmenu.h
@@ -140,6 +140,7 @@ public:
void setNoReplayFor(QWidget *widget);
QPlatformMenu *platformMenu();
+ void setPlatformMenu(QPlatformMenu *platformMenu);
#ifdef Q_OS_WINCE
HMENU wceMenu();
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index 71a3fca237..afd34a5c47 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -108,6 +108,8 @@ public:
#endif
}
void init();
+ void setPlatformMenu(QPlatformMenu *menu);
+ void syncPlatformMenu();
static QMenuPrivate *get(QMenu *m) { return m->d_func(); }
int scrollerHeight() const;
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 01db2bda7a..03ab490823 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1833,9 +1833,9 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar)
d->platformMenuBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
}
- updateGeometry();
- if (!d->nativeMenuBar && parentWidget())
- setVisible(true);
+ updateGeometry();
+ if (!d->nativeMenuBar && parentWidget())
+ setVisible(true);
}
}
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 5f055d436a..d51dce4765 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -347,7 +347,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int /*charsRemoved*/, i
}
if (!d->blockUpdate)
- emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
+ emit update(QRectF(0., -doc->documentMargin(), 1000000000., 1000000000.)); // optimization potential
}
@@ -639,9 +639,10 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
lineNumber = maxTopLine - block.firstLineNumber();
}
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(newTopLine);
- vbar->blockSignals(vbarSignalsBlocked);
+ {
+ const QSignalBlocker blocker(vbar);
+ vbar->setValue(newTopLine);
+ }
if (!dx && blockNumber == control->topBlock && lineNumber == topLine)
return;
@@ -657,9 +658,10 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx)
control->topBlock = blockNumber;
topLine = lineNumber;
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(block.firstLineNumber() + lineNumber);
- vbar->blockSignals(vbarSignalsBlocked);
+ {
+ const QSignalBlocker blocker(vbar);
+ vbar->setValue(block.firstLineNumber() + lineNumber);
+ }
if (dx || dy) {
viewport->scroll(q->isRightToLeft() ? -dx : dx, dy);
@@ -1007,9 +1009,11 @@ void QPlainTextEditPrivate::_q_adjustScrollbars()
QTextBlock firstVisibleBlock = q->firstVisibleBlock();
if (firstVisibleBlock.isValid())
visualTopLine = firstVisibleBlock.firstLineNumber() + topLine;
- bool vbarSignalsBlocked = vbar->blockSignals(true);
- vbar->setValue(visualTopLine);
- vbar->blockSignals(vbarSignalsBlocked);
+
+ {
+ const QSignalBlocker blocker(vbar);
+ vbar->setValue(visualTopLine);
+ }
hbar->setRange(0, (int)documentSize.width() - viewport->width());
hbar->setPageStep(viewport->width());
@@ -1317,6 +1321,35 @@ QTextDocument *QPlainTextEdit::document() const
}
/*!
+ \since 5.3
+
+ \property QPlainTextEdit::placeholderText
+ \brief the editor placeholder text
+
+ Setting this property makes the editor display a grayed-out
+ placeholder text as long as the document() is empty.
+
+ By default, this property contains an empty string.
+
+ \sa document()
+*/
+void QPlainTextEdit::setPlaceholderText(const QString &placeholderText)
+{
+ Q_D(QPlainTextEdit);
+ if (d->placeholderText != placeholderText) {
+ d->placeholderText = placeholderText;
+ if (d->control->document()->isEmpty())
+ d->viewport->update();
+ }
+}
+
+QString QPlainTextEdit::placeholderText() const
+{
+ Q_D(const QPlainTextEdit);
+ return d->placeholderText;
+}
+
+/*!
Sets the visible \a cursor.
*/
void QPlainTextEdit::setTextCursor(const QTextCursor &cursor)
@@ -1942,7 +1975,16 @@ void QPlainTextEdit::paintEvent(QPaintEvent *e)
}
- layout->draw(&painter, offset, selections, er);
+ if (!placeholderText().isEmpty() && document()->isEmpty()) {
+ Q_D(QPlainTextEdit);
+ QColor col = d->control->palette().text().color();
+ col.setAlpha(128);
+ painter.setPen(col);
+ const int margin = int(document()->documentMargin());
+ painter.drawText(r.adjusted(margin, 0, 0, 0), Qt::AlignTop | Qt::TextWordWrap, placeholderText());
+ } else {
+ layout->draw(&painter, offset, selections, er);
+ }
if ((drawCursor && !drawCursorAsBlock)
|| (editable && context.cursorPosition < -1
&& !layout->preeditAreaText().isEmpty())) {
@@ -2150,7 +2192,7 @@ QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
v = QWidget::inputMethodQuery(property);
break;
default:
- v = d->control->inputMethodQuery(property);
+ v = d->control->inputMethodQuery(property, QVariant());
const QPoint offset(-d->horizontalOffset(), -0);
if (v.type() == QVariant::RectF)
v = v.toRectF().toRect().translated(offset);
@@ -2758,6 +2800,27 @@ bool QPlainTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
}
/*!
+ \fn bool QPlainTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
+
+ \since 5.3
+ \overload
+
+ Finds the next occurrence, matching the regular expression, \a exp, using the given
+ \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
+ use QRegExp::caseSensitivity instead.
+
+ Returns \c true if a match was found and changes the cursor to select the match;
+ otherwise returns \c false.
+*/
+#ifndef QT_NO_REGEXP
+bool QPlainTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QPlainTextEdit);
+ return d->control->find(exp, options);
+}
+#endif
+
+/*!
\fn void QPlainTextEdit::copyAvailable(bool yes)
This signal is emitted when text is selected or de-selected in the
diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h
index 81548818ef..1fb4625fb1 100644
--- a/src/widgets/widgets/qplaintextedit.h
+++ b/src/widgets/widgets/qplaintextedit.h
@@ -83,6 +83,7 @@ class Q_WIDGETS_EXPORT QPlainTextEdit : public QAbstractScrollArea
Q_PROPERTY(int maximumBlockCount READ maximumBlockCount WRITE setMaximumBlockCount)
Q_PROPERTY(bool backgroundVisible READ backgroundVisible WRITE setBackgroundVisible)
Q_PROPERTY(bool centerOnScroll READ centerOnScroll WRITE setCenterOnScroll)
+ Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText)
public:
enum LineWrapMode {
NoWrap,
@@ -96,6 +97,9 @@ public:
void setDocument(QTextDocument *document);
QTextDocument *document() const;
+ void setPlaceholderText(const QString &placeholderText);
+ QString placeholderText() const;
+
void setTextCursor(const QTextCursor &cursor);
QTextCursor textCursor() const;
@@ -141,6 +145,9 @@ public:
bool centerOnScroll() const;
bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+#ifndef QT_NO_REGEXP
+ bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0);
+#endif
inline QString toPlainText() const
{ return document()->toPlainText(); }
diff --git a/src/widgets/widgets/qplaintextedit_p.h b/src/widgets/widgets/qplaintextedit_p.h
index ab464676e5..3585b8307f 100644
--- a/src/widgets/widgets/qplaintextedit_p.h
+++ b/src/widgets/widgets/qplaintextedit_p.h
@@ -179,6 +179,7 @@ public:
void _q_modificationChanged(bool);
int originalOffsetY;
+ QString placeholderText;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp
index a10d726e36..264123abf0 100644
--- a/src/widgets/widgets/qpushbutton.cpp
+++ b/src/widgets/widgets/qpushbutton.cpp
@@ -647,7 +647,7 @@ void QPushButton::setFlat(bool flat)
if (d->flat == flat)
return;
d->flat = flat;
- d->resetLayoutItemMargins();
+ d->resetLayoutItemMargins();
d->sizeHint = QSize();
update();
updateGeometry();
@@ -673,8 +673,8 @@ bool QPushButton::event(QEvent *e)
|| e->type() == QEvent::MacSizeChange
#endif
) {
- d->resetLayoutItemMargins();
- updateGeometry();
+ d->resetLayoutItemMargins();
+ updateGeometry();
} else if (e->type() == QEvent::PolishRequest) {
updateGeometry();
}
diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp
index 106a8d770a..e46de3958f 100644
--- a/src/widgets/widgets/qsizegrip.cpp
+++ b/src/widgets/widgets/qsizegrip.cpp
@@ -482,7 +482,7 @@ bool QSizeGrip::eventFilter(QObject *o, QEvent *e)
Q_D(QSizeGrip);
if ((isHidden() && testAttribute(Qt::WA_WState_ExplicitShowHide))
|| e->type() != QEvent::WindowStateChange
- || o != d->tlw) {
+ || o != d->tlw) {
return QWidget::eventFilter(o, e);
}
Qt::WindowStates sizeGripNotVisibleState = Qt::WindowFullScreen;
diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp
index 2d91cd07e6..0ff31af630 100644
--- a/src/widgets/widgets/qslider.cpp
+++ b/src/widgets/widgets/qslider.cpp
@@ -63,7 +63,7 @@ public:
QSlider::TickPosition tickPosition;
int clickOffset;
void init();
- void resetLayoutItemMargins();
+ void resetLayoutItemMargins();
int pixelPosToRangeValue(int pos) const;
inline int pick(const QPoint &pt) const;
@@ -86,7 +86,7 @@ void QSliderPrivate::init()
sp.transpose();
q->setSizePolicy(sp);
q->setAttribute(Qt::WA_WState_OwnSizePolicy, false);
- resetLayoutItemMargins();
+ resetLayoutItemMargins();
}
void QSliderPrivate::resetLayoutItemMargins()
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 2a34451408..e198dae168 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -463,8 +463,8 @@ void QSpinBox::setDisplayIntegerBase(int base)
display the given \a value. The default implementation returns a
string containing \a value printed in the standard way using
QWidget::locale().toString(), but with the thousand separator
- removed. Reimplementations may return anything. (See the example
- in the detailed description.)
+ removed unless setGroupSeparatorShown() is set. Reimplementations may
+ return anything. (See the example in the detailed description.)
Note: QSpinBox does not call this function for specialValueText()
and that neither prefix() nor suffix() should be included in the
@@ -487,7 +487,7 @@ QString QSpinBox::textFromValue(int value) const
str.prepend('-');
} else {
str = locale().toString(value);
- if (qAbs(value) >= 1000 || value == INT_MIN) {
+ if (!d->showGroupSeparator && (qAbs(value) >= 1000 || value == INT_MIN)) {
str.remove(locale().groupSeparator());
}
}
@@ -538,7 +538,8 @@ QValidator::State QSpinBox::validate(QString &text, int &pos) const
*/
void QSpinBox::fixup(QString &input) const
{
- input.remove(locale().groupSeparator());
+ if (!isGroupSeparatorShown())
+ input.remove(locale().groupSeparator());
}
@@ -891,7 +892,8 @@ void QDoubleSpinBox::setDecimals(int decimals)
display the given \a value. The default implementation returns a string
containing \a value printed using QWidget::locale().toString(\a value,
QLatin1Char('f'), decimals()) and will remove the thousand
- separator. Reimplementations may return anything.
+ separator unless setGroupSeparatorShown() is set. Reimplementations may
+ return anything.
Note: QDoubleSpinBox does not call this function for
specialValueText() and that neither prefix() nor suffix() should
@@ -908,9 +910,9 @@ QString QDoubleSpinBox::textFromValue(double value) const
{
Q_D(const QDoubleSpinBox);
QString str = locale().toString(value, 'f', d->decimals);
- if (qAbs(value) >= 1000.0) {
+ if (!d->showGroupSeparator && qAbs(value) >= 1000.0)
str.remove(locale().groupSeparator());
- }
+
return str;
}
diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp
index b2a0d3f8b8..db9db68039 100644
--- a/src/widgets/widgets/qsplashscreen.cpp
+++ b/src/widgets/widgets/qsplashscreen.cpp
@@ -251,7 +251,9 @@ inline static bool waitForWindowExposed(QWindow *window, int timeout = 1000)
break;
QCoreApplication::processEvents(QEventLoop::AllEvents, remaining);
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WINRT)
+ WaitForSingleObjectEx(GetCurrentThread(), TimeOutMs, false);
+#elif defined(Q_OS_WIN)
Sleep(uint(TimeOutMs));
#else
struct timespec ts = { TimeOutMs / 1000, (TimeOutMs % 1000) * 1000 * 1000 };
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index 8c15b3e58e..fced1c01ec 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -759,11 +759,10 @@ void QTabWidgetPrivate::_q_removeTab(int index)
void QTabWidgetPrivate::_q_tabMoved(int from, int to)
{
- stack->blockSignals(true);
+ const QSignalBlocker blocker(stack);
QWidget *w = stack->widget(from);
stack->removeWidget(w);
stack->insertWidget(to, w);
- stack->blockSignals(false);
}
/*
diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp
index 273a5dabeb..9ecc87aac4 100644
--- a/src/widgets/widgets/qtextbrowser.cpp
+++ b/src/widgets/widgets/qtextbrowser.cpp
@@ -296,7 +296,7 @@ void QTextBrowserPrivate::setSource(const QUrl &url)
QTextCodec *codec = Qt::codecForHtml(ba);
txt = codec->toUnicode(ba);
#else
- txt = data.toString();
+ txt = data.toString();
#endif
}
if (txt.isEmpty())
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index 29538e1b70..a33ac0817f 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -1717,14 +1717,21 @@ void QTextEdit::scrollContentsBy(int dx, int dy)
*/
QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
+ return inputMethodQuery(property, QVariant());
+}
+
+/*!\internal
+ */
+QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const
+{
Q_D(const QTextEdit);
QVariant v;
- switch (property) {
+ switch (query) {
case Qt::ImHints:
- v = QWidget::inputMethodQuery(property);
+ v = QWidget::inputMethodQuery(query);
break;
default:
- v = d->control->inputMethodQuery(property);
+ v = d->control->inputMethodQuery(query, argument);
const QPoint offset(-d->horizontalOffset(), -d->verticalOffset());
if (v.type() == QVariant::RectF)
v = v.toRectF().toRect().translated(offset);
@@ -2456,6 +2463,27 @@ bool QTextEdit::find(const QString &exp, QTextDocument::FindFlags options)
}
/*!
+ \fn bool QTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
+
+ \since 5.3
+ \overload
+
+ Finds the next occurrence, matching the regular expression, \a exp, using the given
+ \a options. The QTextDocument::FindCaseSensitively option is ignored for this overload,
+ use QRegExp::caseSensitivity instead.
+
+ Returns \c true if a match was found and changes the cursor to select the match;
+ otherwise returns \c false.
+*/
+#ifndef QT_NO_REGEXP
+bool QTextEdit::find(const QRegExp &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QTextEdit);
+ return d->control->find(exp, options);
+}
+#endif
+
+/*!
\fn void QTextEdit::copyAvailable(bool yes)
This signal is emitted when text is selected or de-selected in the
diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h
index 06ec5fb889..a283a51b90 100644
--- a/src/widgets/widgets/qtextedit.h
+++ b/src/widgets/widgets/qtextedit.h
@@ -162,6 +162,9 @@ public:
void setWordWrapMode(QTextOption::WrapMode policy);
bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+#ifndef QT_NO_REGEXP
+ bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0);
+#endif
QString toPlainText() const;
#ifndef QT_NO_TEXTHTMLPARSER
@@ -209,6 +212,7 @@ public:
void print(QPagedPaintDevice *printer) const;
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
public Q_SLOTS:
void setFontPointSize(qreal s);
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index 5e7eb943ab..d20b7a380d 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -650,9 +650,9 @@ void QToolBar::setOrientation(Qt::Orientation orientation)
d->orientation = orientation;
if (orientation == Qt::Vertical)
- setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
+ setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
else
- setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+ setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
d->layout->invalidate();
d->layout->activate();
diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h
index 663497493f..fbe509f522 100644
--- a/src/widgets/widgets/qtoolbar.h
+++ b/src/widgets/widgets/qtoolbar.h
@@ -105,7 +105,7 @@ public:
QAction *addAction(const QIcon &icon, const QString &text);
QAction *addAction(const QString &text, const QObject *receiver, const char* member);
QAction *addAction(const QIcon &icon, const QString &text,
- const QObject *receiver, const char* member);
+ const QObject *receiver, const char* member);
QAction *addSeparator();
QAction *insertSeparator(QAction *before);
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index b8f8762240..98f85e681b 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -2024,7 +2024,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
emit q->microFocusChanged();
}
-QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
+QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
{
Q_D(const QWidgetTextControl);
QTextBlock block = d->cursor.block();
@@ -2043,6 +2043,47 @@ QVariant QWidgetTextControl::inputMethodQuery(Qt::InputMethodQuery property) con
return QVariant(); // No limit.
case Qt::ImAnchorPosition:
return QVariant(d->cursor.anchor() - block.position());
+ case Qt::ImAbsolutePosition:
+ return QVariant(d->cursor.position());
+ case Qt::ImTextAfterCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ QString result = block.text().mid(localPos);
+ while (result.length() < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ result += QLatin1Char('\n') + tmpCursor.block().text();
+ }
+ return QVariant(result);
+ }
+ case Qt::ImTextBeforeCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ int numBlocks = 0;
+ int resultLen = localPos;
+ while (resultLen < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::PreviousBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ numBlocks++;
+ resultLen += tmpCursor.block().length();
+ }
+ QString result;
+ while (numBlocks) {
+ result += tmpCursor.block().text() + QLatin1Char('\n');
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ --numBlocks;
+ }
+ result += block.text().mid(0,localPos);
+ return QVariant(result);
+ }
default:
return QVariant();
}
@@ -2958,6 +2999,19 @@ bool QWidgetTextControl::find(const QString &exp, QTextDocument::FindFlags optio
return true;
}
+#ifndef QT_NO_REGEXP
+bool QWidgetTextControl::find(const QRegExp &exp, QTextDocument::FindFlags options)
+{
+ Q_D(QWidgetTextControl);
+ QTextCursor search = d->doc->find(exp, d->cursor, options);
+ if (search.isNull())
+ return false;
+
+ setTextCursor(search);
+ return true;
+}
+#endif
+
QString QWidgetTextControl::toPlainText() const
{
return document()->toPlainText();
@@ -3126,7 +3180,7 @@ QRectF QWidgetTextControl::blockBoundingRect(const QTextBlock &block) const
}
#ifndef QT_NO_CONTEXTMENU
-#define NUM_CONTROL_CHARACTERS 10
+#define NUM_CONTROL_CHARACTERS 14
const struct QUnicodeControlCharacter {
const char *text;
ushort character;
@@ -3141,6 +3195,10 @@ const struct QUnicodeControlCharacter {
{ QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRO Start of left-to-right override"), 0x202d },
{ QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLO Start of right-to-left override"), 0x202e },
{ QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDF Pop directional formatting"), 0x202c },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "LRI Left-to-right isolate"), 0x2066 },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "RLI Right-to-left isolate"), 0x2067 },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "FSI First strong isolate"), 0x2068 },
+ { QT_TRANSLATE_NOOP("QUnicodeControlCharacterMenu", "PDI Pop directional isolate"), 0x2069 }
};
QUnicodeControlCharacterMenu::QUnicodeControlCharacterMenu(QObject *_editWidget, QWidget *parent)
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index e857fffba5..0c76355ca1 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -110,6 +110,9 @@ public:
QTextCharFormat currentCharFormat() const;
bool find(const QString &exp, QTextDocument::FindFlags options = 0);
+#ifndef QT_NO_REGEXP
+ bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0);
+#endif
QString toPlainText() const;
#ifndef QT_NO_TEXTHTMLPARSER
@@ -236,7 +239,7 @@ public:
void setFocus(bool focus, Qt::FocusReason = Qt::OtherFocusReason);
- virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ virtual QVariant inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const;
virtual QMimeData *createMimeDataFromSelection() const;
virtual bool canInsertFromMimeData(const QMimeData *source) const;
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index d0f138269f..151294d2c4 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -44,16 +44,29 @@
linking to the Qt DLL.
When a Windows application starts, the WinMain function is
- invoked. WinMain creates the WinRT application which in turn
- calls the main entry point.
+ invoked. This WinMain creates the WinRT application
+ container, which in turn calls the application's main()
+ entry point within the newly created GUI thread.
*/
-extern "C" int main(int, char **);
+#include <new.h>
+
+typedef struct
+{
+ int newmode;
+} _startupinfo;
+
+extern "C" {
+ int __getmainargs(int *argc, char ***argv, char ***env, int expandWildcards, _startupinfo *info);
+ int main(int, char **);
+}
#include <qbytearray.h>
#include <qstring.h>
#include <qlist.h>
#include <qvector.h>
+#include <qdir.h>
+#include <qstandardpaths.h>
#include <wrl.h>
#include <Windows.ApplicationModel.core.h>
@@ -66,22 +79,22 @@ using namespace Microsoft::WRL;
#define CoreApplicationClass RuntimeClass_Windows_ApplicationModel_Core_CoreApplication
typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEventArgs *> ActivatedHandler;
+static int g_mainExitCode;
+
class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
{
public:
- AppContainer(int argc, wchar_t **argv) : m_argc(argc)
+ AppContainer(int argc, char *argv[]) : m_argc(argc)
{
m_argv.reserve(argc);
- for (int i = 0; i < argc; ++i) {
- QByteArray arg = QString::fromWCharArray(argv[i]).toLocal8Bit();
- m_argv.append(qstrdup(arg.constData()));
- }
+ for (int i = 0; i < argc; ++i)
+ m_argv.append(argv[i]);
}
~AppContainer()
{
- foreach (const char *arg, m_argv)
- delete[] arg;
+ for (int i = m_argc; i < m_argv.size(); ++i)
+ delete[] m_argv[i];
}
// IFrameworkView Methods
@@ -95,7 +108,33 @@ public:
HRESULT __stdcall Load(HSTRING) { return S_OK; }
HRESULT __stdcall Run()
{
- return main(m_argv.count(), m_argv.data());
+ bool develMode = false;
+ bool debugWait = false;
+ foreach (const QByteArray &arg, m_argv) {
+ if (arg == "-qdevel")
+ develMode = true;
+ if (arg == "-qdebug")
+ debugWait = true;
+ }
+ if (develMode) {
+ // Write a PID file to help runner
+ const QString pidFileName = QDir(QStandardPaths::writableLocation(QStandardPaths::DataLocation))
+ .absoluteFilePath(QString::number(uint(GetCurrentProcessId())) + QStringLiteral(".pid"));
+ CREATEFILE2_EXTENDED_PARAMETERS params = {
+ sizeof(CREATEFILE2_EXTENDED_PARAMETERS),
+ FILE_ATTRIBUTE_NORMAL, FILE_FLAG_DELETE_ON_CLOSE
+ };
+ // (Unused) handle will automatically be closed when the app exits
+ CreateFile2(reinterpret_cast<LPCWSTR>(pidFileName.utf16()),
+ 0, FILE_SHARE_READ|FILE_SHARE_DELETE, CREATE_ALWAYS, &params);
+ }
+ // Wait for debugger before continuing
+ if (debugWait) {
+ while (!IsDebuggerPresent())
+ WaitForSingleObjectEx(GetCurrentThread(), 1, true);
+ }
+ g_mainExitCode = main(m_argv.count(), m_argv.data());
+ return S_OK;
}
HRESULT __stdcall Uninitialize() { return S_OK; }
@@ -110,9 +149,11 @@ private:
m_argv.resize(m_argc);
HSTRING arguments;
launchArgs->get_Arguments(&arguments);
- foreach (const QByteArray &arg, QString::fromWCharArray(
- WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) {
- m_argv.append(qstrdup(arg.constData()));
+ if (arguments) {
+ foreach (const QByteArray &arg, QString::fromWCharArray(
+ WindowsGetStringRawBuffer(arguments, nullptr)).toLocal8Bit().split(' ')) {
+ m_argv.append(qstrdup(arg.constData()));
+ }
}
}
return S_OK;
@@ -126,19 +167,32 @@ private:
class AppViewSource : public Microsoft::WRL::RuntimeClass<Core::IFrameworkViewSource>
{
public:
- AppViewSource(int argc, wchar_t *argv[]) : argc(argc), argv(argv) { }
+ AppViewSource(int argc, char **argv) : m_argc(argc), m_argv(argv) { }
HRESULT __stdcall CreateView(Core::IFrameworkView **frameworkView)
{
- return (*frameworkView = Make<AppContainer>(argc, argv).Detach()) ? S_OK : E_OUTOFMEMORY;
+ return (*frameworkView = Make<AppContainer>(m_argc, m_argv).Detach()) ? S_OK : E_OUTOFMEMORY;
}
private:
- int argc;
- wchar_t **argv;
+ int m_argc;
+ char **m_argv;
};
// Main entry point for Appx containers
-int wmain(int argc, wchar_t *argv[])
+int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
+ int argc = 0;
+ char **argv, **env;
+ _startupinfo info = { _query_new_mode() };
+ if (int init = __getmainargs(&argc, &argv, &env, false, &info))
+ return init;
+
+ for (int i = 0; env && env[i]; ++i) {
+ QByteArray var(env[i]);
+ int split = var.indexOf('=');
+ if (split > 0)
+ qputenv(var.mid(0, split), var.mid(split + 1));
+ }
+
if (FAILED(RoInitialize(RO_INIT_MULTITHREADED)))
return 1;
@@ -146,5 +200,6 @@ int wmain(int argc, wchar_t *argv[])
if (FAILED(RoGetActivationFactory(qHString(CoreApplicationClass), IID_PPV_ARGS(&appFactory))))
return 2;
- return appFactory->Run(Make<AppViewSource>(argc, argv).Get());
+ appFactory->Run(Make<AppViewSource>(argc, argv).Get());
+ return g_mainExitCode;
}
diff --git a/src/winmain/winmain.pro b/src/winmain/winmain.pro
index b0771caa55..998200cb1e 100644
--- a/src/winmain/winmain.pro
+++ b/src/winmain/winmain.pro
@@ -14,10 +14,9 @@ win32-msvc*:QMAKE_CFLAGS_DEBUG -= -Zi
win32-msvc*:QMAKE_CXXFLAGS_DEBUG -= -Zi
win32-msvc*:QMAKE_CFLAGS_DEBUG *= -Z7
win32-msvc*:QMAKE_CXXFLAGS_DEBUG *= -Z7
-win32-g++*: DEFINES += QT_NEEDS_QMAIN
+mingw: DEFINES += QT_NEEDS_QMAIN
winrt {
- QMAKE_LFLAGS += /ENTRY:wmainCRTStartup
SOURCES = qtmain_winrt.cpp
} else {
SOURCES = qtmain_win.cpp
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 1b05e049f1..4b434822b8 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -865,11 +865,11 @@ void QXmlNamespaceSupport::processName(const QString& qname,
nsuri.clear();
// attributes don't take default namespace
if (!isAttribute && !d->ns.isEmpty()) {
- /*
- We want to access d->ns.value(""), but as an optimization
- we use the fact that "" compares less than any other
- string, so it's either first in the map or not there.
- */
+ /*
+ We want to access d->ns.value(""), but as an optimization
+ we use the fact that "" compares less than any other
+ string, so it's either first in the map or not there.
+ */
NamespaceMap::const_iterator first = d->ns.constBegin();
if (first.key().isEmpty())
nsuri = first.value(); // get default namespace
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 3ff78a955f..a9aecc9448 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -19,6 +19,8 @@ SUBDIRS += \
installed_cmake.depends = cmake
+ios: SUBDIRS = corelib gui
+
wince*: SUBDIRS -= printsupport
cross_compile: SUBDIRS -= tools
!qtHaveModule(opengl): SUBDIRS -= opengl
diff --git a/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp b/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp
index 55c831bd35..09c3ac3c09 100644
--- a/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp
+++ b/tests/auto/corelib/codecs/qtextcodec/echo/main.cpp
@@ -47,8 +47,7 @@
int main(int argc, char **argv)
{
- static char lc_all[] = "LC_ALL=C";
- putenv(lc_all);
+ qputenv("LC_ALL", "C");
QCoreApplication app(argc, argv);
QString string(QChar(0x410));
diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
index 8e1b3cf3b2..12b81ee7d4 100644
--- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
+++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp
@@ -456,7 +456,7 @@ void tst_QTextCodec::flagF7808080() const
//QVERIFY(!codec->canEncode(QChar(0x1C0000)));
QTextCodec::ConverterState state(QTextCodec::ConvertInvalidToNull);
- QVERIFY(codec->toUnicode(input.constData(), input.length(), &state) == QChar(0));
+ QCOMPARE(codec->toUnicode(input.constData(), input.length(), &state), QString(input.size(), QChar(0)));
}
void tst_QTextCodec::nonFlaggedEFBFBF() const
@@ -689,8 +689,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xbf);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.2.4") << utf8 << str << -1;
// 2.2.5 U+03FFFFFF (not a valid Unicode character)
@@ -755,8 +754,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0x90);
utf8 += char(0x80);
utf8 += char(0x80);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 2.3.5") << utf8 << str << -1;
// 3.1.1
@@ -1244,7 +1242,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8.clear();
utf8 += char(0xc0);
utf8 += char(0xaf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.1") << utf8 << str << -1;
// 4.1.2
@@ -1252,7 +1250,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xe0);
utf8 += char(0x80);
utf8 += char(0xaf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.2") << utf8 << str << -1;
// 4.1.3
@@ -1261,7 +1259,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0x80);
utf8 += char(0x80);
utf8 += char(0xaf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.1.3") << utf8 << str << -1;
// 4.1.4
@@ -1289,7 +1287,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8.clear();
utf8 += char(0xc1);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.1") << utf8 << str << -1;
// 4.2.2
@@ -1297,7 +1295,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xe0);
utf8 += char(0x9f);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.2") << utf8 << str << -1;
// 4.2.3
@@ -1306,7 +1304,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0x8f);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.2.3") << utf8 << str << -1;
// 4.2.4
@@ -1334,7 +1332,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8.clear();
utf8 += char(0xc0);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.1") << utf8 << str << -1;
// 4.3.2
@@ -1342,7 +1340,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xe0);
utf8 += char(0x80);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.2") << utf8 << str << -1;
// 4.3.3
@@ -1351,7 +1349,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0x80);
utf8 += char(0x80);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 4.3.3") << utf8 << str << -1;
// 4.3.4
@@ -1380,7 +1378,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xa0);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.1") << utf8 << str << -1;
// 5.1.2
@@ -1388,7 +1386,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xad);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.2") << utf8 << str << -1;
// 5.1.3
@@ -1396,7 +1394,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xae);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.3") << utf8 << str << -1;
// 5.1.4
@@ -1404,7 +1402,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xaf);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.4") << utf8 << str << -1;
// 5.1.5
@@ -1412,7 +1410,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xb0);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.5") << utf8 << str << -1;
// 5.1.6
@@ -1420,7 +1418,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbe);
utf8 += char(0x80);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.6") << utf8 << str << -1;
// 5.1.7
@@ -1428,7 +1426,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str = QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.1.7") << utf8 << str << -1;
// 5.2.1
@@ -1439,9 +1437,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xb0);
utf8 += char(0x80);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.1") << utf8 << str << -1;
// 5.2.2
@@ -1452,9 +1448,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.2") << utf8 << str << -1;
// 5.2.3
@@ -1465,9 +1459,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xb0);
utf8 += char(0x80);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.3") << utf8 << str << -1;
// 5.2.4
@@ -1478,9 +1470,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.4") << utf8 << str << -1;
// 5.2.5
@@ -1491,9 +1481,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xb0);
utf8 += char(0x80);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.5") << utf8 << str << -1;
// 5.2.6
@@ -1504,9 +1492,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.6") << utf8 << str << -1;
// 5.2.7
@@ -1517,9 +1503,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xb0);
utf8 += char(0x80);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.7") << utf8 << str << -1;
// 5.2.8
@@ -1530,9 +1514,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xed);
utf8 += char(0xbf);
utf8 += char(0xbf);
- str.clear();
- str += QChar(QChar::ReplacementCharacter);
- str += QChar(QChar::ReplacementCharacter);
+ str = fromInvalidUtf8Sequence(utf8);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.2.8") << utf8 << str << -1;
// 5.3.1 - non-character code
@@ -1541,7 +1523,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xbf);
utf8 += char(0xbe);
//str = QChar(QChar::ReplacementCharacter);
- str = QString::fromUtf8(utf8);
+ str = QChar(0xfffe);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.1") << utf8 << str << -1;
// 5.3.2 - non-character code
@@ -1550,7 +1532,7 @@ void tst_QTextCodec::utf8Codec_data()
utf8 += char(0xbf);
utf8 += char(0xbf);
//str = QChar(QChar::ReplacementCharacter);
- str = QString::fromUtf8(utf8);
+ str = QChar(0xffff);
QTest::newRow("http://www.w3.org/2001/06/utf-8-wrong/UTF-8-test.html 5.3.2") << utf8 << str << -1;
}
diff --git a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
index e18f6f73b9..b00fd0dfd4 100644
--- a/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
+++ b/tests/auto/corelib/codecs/utf8/tst_utf8.cpp
@@ -53,7 +53,11 @@ public:
// test data:
QTextCodec *codec;
QString (*from8BitPtr)(const char *, int);
+#ifdef Q_COMPILER_REF_QUALIFIERS
+ QByteArray (QString:: *to8Bit)() const &;
+#else
QByteArray (QString:: *to8Bit)() const;
+#endif
inline QString from8Bit(const QByteArray &ba)
{ return from8BitPtr(ba.constData(), ba.length()); }
diff --git a/tests/auto/corelib/corelib.pro b/tests/auto/corelib/corelib.pro
index a85a385f80..4d88b04828 100644
--- a/tests/auto/corelib/corelib.pro
+++ b/tests/auto/corelib/corelib.pro
@@ -1,16 +1,18 @@
TEMPLATE=subdirs
-SUBDIRS=\
+
+SUBDIRS = \
+ kernel
+
+!ios: SUBDIRS += \
animation \
codecs \
global \
io \
itemmodels \
json \
- kernel \
mimetypes \
plugin \
statemachine \
thread \
tools \
xml
-
diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
index 31a4254344..21e07630e2 100644
--- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
+++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp
@@ -672,7 +672,7 @@ void tst_qmessagehandler::qMessagePattern()
QVERIFY(output.contains("debug tst_qlogging 57 main qDebug"));
QVERIFY(output.contains("warning tst_qlogging 58 main qWarning"));
QVERIFY(output.contains("critical tst_qlogging 59 main qCritical"));
- QVERIFY(output.contains("warning tst_qlogging 62 main qDebug with category "));
+ QVERIFY(output.contains("warning tst_qlogging 62 main qDebug with category"));
QVERIFY(output.contains("debug tst_qlogging 66 main qDebug2"));
environment = m_baseEnvironment;
@@ -712,7 +712,7 @@ void tst_qmessagehandler::qMessagePattern()
"[debug] qDebug\n"
"[warning] qWarning\n"
"[critical] qCritical\n"
- "[warning] qDebug with category \n";
+ "[warning] qDebug with category\n";
#ifdef Q_OS_WIN
output.replace("\r\n", "\n");
#endif
diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
index 20f99e9191..36e01a0ccd 100644
--- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
+++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
@@ -44,6 +44,7 @@
#include <QtGlobal>
#include <math.h>
+#include <float.h>
class tst_QNumeric: public QObject
{
@@ -53,6 +54,10 @@ private slots:
void fuzzyCompare_data();
void fuzzyCompare();
void qNan();
+ void floatDistance_data();
+ void floatDistance();
+ void floatDistance_double_data();
+ void floatDistance_double();
};
void tst_QNumeric::fuzzyCompare_data()
@@ -121,5 +126,93 @@ void tst_QNumeric::qNan()
QVERIFY(qFuzzyCompare(1/inf, 0.0));
}
+void tst_QNumeric::floatDistance_data()
+{
+ QTest::addColumn<float>("val1");
+ QTest::addColumn<float>("val2");
+ QTest::addColumn<quint32>("expectedDistance");
+
+ // exponent: 8 bits
+ // mantissa: 23 bits
+ const quint32 number_of_denormals = (1 << 23) - 1; // Set to 0 if denormals are not included
+
+ quint32 _0_to_1 = quint32((1 << 23) * 126 + 1 + number_of_denormals); // We need +1 to include the 0
+ quint32 _1_to_2 = quint32(1 << 23);
+
+ // We don't need +1 because FLT_MAX has all bits set in the mantissa. (Thus mantissa
+ // have not wrapped back to 0, which would be the case for 1 in _0_to_1
+ quint32 _0_to_FLT_MAX = quint32((1 << 23) * 254) + number_of_denormals;
+
+ quint32 _0_to_FLT_MIN = 1 + number_of_denormals;
+ QTest::newRow("[0,FLT_MIN]") << 0.F << FLT_MIN << _0_to_FLT_MIN;
+ QTest::newRow("[0,FLT_MAX]") << 0.F << FLT_MAX << _0_to_FLT_MAX;
+ QTest::newRow("[1,1.5]") << 1.0F << 1.5F << quint32(1 << 22);
+ QTest::newRow("[0,1]") << 0.F << 1.0F << _0_to_1;
+ QTest::newRow("[0.5,1]") << 0.5F << 1.0F << quint32(1 << 23);
+ QTest::newRow("[1,2]") << 1.F << 2.0F << _1_to_2;
+ QTest::newRow("[-1,+1]") << -1.F << +1.0F << 2 * _0_to_1;
+ QTest::newRow("[-1,0]") << -1.F << 0.0F << _0_to_1;
+ QTest::newRow("[-1,FLT_MAX]") << -1.F << FLT_MAX << _0_to_1 + _0_to_FLT_MAX;
+ QTest::newRow("[-2,-1") << -2.F << -1.F << _1_to_2;
+ QTest::newRow("[-1,-2") << -1.F << -2.F << _1_to_2;
+ QTest::newRow("[FLT_MIN,FLT_MAX]") << FLT_MIN << FLT_MAX << _0_to_FLT_MAX - _0_to_FLT_MIN;
+ QTest::newRow("[-FLT_MAX,FLT_MAX]") << -FLT_MAX << FLT_MAX << (2*_0_to_FLT_MAX);
+ float denormal = FLT_MIN;
+ denormal/=2.0F;
+ QTest::newRow("denormal") << 0.F << denormal << _0_to_FLT_MIN/2;
+}
+
+void tst_QNumeric::floatDistance()
+{
+ QFETCH(float, val1);
+ QFETCH(float, val2);
+ QFETCH(quint32, expectedDistance);
+ QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
+}
+
+void tst_QNumeric::floatDistance_double_data()
+{
+ QTest::addColumn<double>("val1");
+ QTest::addColumn<double>("val2");
+ QTest::addColumn<quint64>("expectedDistance");
+
+ // exponent: 11 bits
+ // mantissa: 52 bits
+ const quint64 number_of_denormals = (Q_UINT64_C(1) << 52) - 1; // Set to 0 if denormals are not included
+
+ quint64 _0_to_1 = (Q_UINT64_C(1) << 52) * ((1 << (11-1)) - 2) + 1 + number_of_denormals; // We need +1 to include the 0
+ quint64 _1_to_2 = Q_UINT64_C(1) << 52;
+
+ // We don't need +1 because DBL_MAX has all bits set in the mantissa. (Thus mantissa
+ // have not wrapped back to 0, which would be the case for 1 in _0_to_1
+ quint64 _0_to_DBL_MAX = quint64((Q_UINT64_C(1) << 52) * ((1 << 11) - 2)) + number_of_denormals;
+
+ quint64 _0_to_DBL_MIN = 1 + number_of_denormals;
+ QTest::newRow("[0,DBL_MIN]") << 0.0 << DBL_MIN << _0_to_DBL_MIN;
+ QTest::newRow("[0,DBL_MAX]") << 0.0 << DBL_MAX << _0_to_DBL_MAX;
+ QTest::newRow("[1,1.5]") << 1.0 << 1.5 << (Q_UINT64_C(1) << 51);
+ QTest::newRow("[0,1]") << 0.0 << 1.0 << _0_to_1;
+ QTest::newRow("[0.5,1]") << 0.5 << 1.0 << (Q_UINT64_C(1) << 52);
+ QTest::newRow("[1,2]") << 1.0 << 2.0 << _1_to_2;
+ QTest::newRow("[-1,+1]") << -1.0 << +1.0 << 2 * _0_to_1;
+ QTest::newRow("[-1,0]") << -1.0 << 0.0 << _0_to_1;
+ QTest::newRow("[-1,DBL_MAX]") << -1.0 << DBL_MAX << _0_to_1 + _0_to_DBL_MAX;
+ QTest::newRow("[-2,-1") << -2.0 << -1.0 << _1_to_2;
+ QTest::newRow("[-1,-2") << -1.0 << -2.0 << _1_to_2;
+ QTest::newRow("[DBL_MIN,DBL_MAX]") << DBL_MIN << DBL_MAX << _0_to_DBL_MAX - _0_to_DBL_MIN;
+ QTest::newRow("[-DBL_MAX,DBL_MAX]") << -DBL_MAX << DBL_MAX << (2*_0_to_DBL_MAX);
+ double denormal = DBL_MIN;
+ denormal/=2.0;
+ QTest::newRow("denormal") << 0.0 << denormal << _0_to_DBL_MIN/2;
+}
+
+void tst_QNumeric::floatDistance_double()
+{
+ QFETCH(double, val1);
+ QFETCH(double, val2);
+ QFETCH(quint64, expectedDistance);
+ QCOMPARE(qFloatDistance(val1, val2), expectedDistance);
+}
+
QTEST_APPLESS_MAIN(tst_QNumeric)
#include "tst_qnumeric.moc"
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
index ab66323d3b..ba055a4f3f 100644
--- a/tests/auto/corelib/io/io.pro
+++ b/tests/auto/corelib/io/io.pro
@@ -17,6 +17,7 @@ SUBDIRS=\
qipaddress \
qlockfile \
qloggingcategory \
+ qloggingregistry \
qnodebug \
qprocess \
qprocess-noapplication \
@@ -43,7 +44,6 @@ SUBDIRS=\
qsettings
!qtHaveModule(network): SUBDIRS -= \
- qfile \
qiodevice \
qprocess \
qtextstream
@@ -52,7 +52,14 @@ SUBDIRS=\
qabstractfileengine \
qfileinfo \
qipaddress \
- qurlinternal
+ qurlinternal \
+ qloggingregistry
win32:!contains(QT_CONFIG, private_tests): SUBDIRS -= \
qfilesystementry
+
+winrt: SUBDIRS -= \
+ qprocess \
+ qprocess-noapplication \
+ qprocessenvironment \
+ qwinoverlappedionotifier
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index f452efc1b3..29c7e6a81e 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -65,8 +65,8 @@ void tst_QDebug::assignment() const
QDebug debug1(QtDebugMsg);
QDebug debug2(QtWarningMsg);
- QTest::ignoreMessage(QtDebugMsg, "foo ");
- QTest::ignoreMessage(QtWarningMsg, "bar 1 2 ");
+ QTest::ignoreMessage(QtDebugMsg, "foo");
+ QTest::ignoreMessage(QtWarningMsg, "bar 1 2");
debug1 << "foo";
debug2 << "bar";
@@ -118,7 +118,7 @@ void tst_QDebug::warningWithoutDebug() const
{ qWarning() << "A qWarning() message"; }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtWarningMsg);
- QCOMPARE(s_msg, QString::fromLatin1("A qWarning() message "));
+ QCOMPARE(s_msg, QString::fromLatin1("A qWarning() message"));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
@@ -133,7 +133,7 @@ void tst_QDebug::criticalWithoutDebug() const
{ qCritical() << "A qCritical() message"; }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtCriticalMsg);
- QCOMPARE(s_msg, QString::fromLatin1("A qCritical() message "));
+ QCOMPARE(s_msg, QString::fromLatin1("A qCritical() message"));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
@@ -145,7 +145,7 @@ void tst_QDebug::debugWithBool() const
{ qDebug() << false << true; }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("false true "));
+ QCOMPARE(s_msg, QString::fromLatin1("false true"));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
@@ -215,7 +215,7 @@ void tst_QDebug::stateSaver() const
}
d.space() << 42;
}
- QCOMPARE(s_msg, QString::fromLatin1("02a 42 "));
+ QCOMPARE(s_msg, QString::fromLatin1("02a 42"));
}
void tst_QDebug::veryLongWarningMessage() const
@@ -247,7 +247,7 @@ void tst_QDebug::qDebugQStringRef() const
{ qDebug() << inRef; }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("\"input\" "));
+ QCOMPARE(s_msg, QString::fromLatin1("\"input\""));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
@@ -261,7 +261,7 @@ void tst_QDebug::qDebugQStringRef() const
{ qDebug() << inRef; }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("\"\" "));
+ QCOMPARE(s_msg, QString::fromLatin1("\"\""));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
@@ -274,7 +274,7 @@ void tst_QDebug::qDebugQLatin1String() const
{ qDebug() << QLatin1String("foo") << QLatin1String("") << QLatin1String("barbaz", 3); }
QString file = __FILE__; int line = __LINE__ - 1; QString function = Q_FUNC_INFO;
QCOMPARE(s_msgType, QtDebugMsg);
- QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\" "));
+ QCOMPARE(s_msg, QString::fromLatin1("\"foo\" \"\" \"bar\""));
QCOMPARE(QString::fromLatin1(s_file), file);
QCOMPARE(s_line, line);
QCOMPARE(QString::fromLatin1(s_function), function);
diff --git a/tests/auto/corelib/io/qfile/test/test.pro b/tests/auto/corelib/io/qfile/test/test.pro
index bc6922b4e9..03863e9943 100644
--- a/tests/auto/corelib/io/qfile/test/test.pro
+++ b/tests/auto/corelib/io/qfile/test/test.pro
@@ -1,7 +1,10 @@
CONFIG += testcase
CONFIG += parallel_test
CONFIG -= app_bundle debug_and_release_target
-QT = core-private core network testlib
+QT = core-private core testlib
+qtHaveModule(network): QT += network
+else: DEFINES += QT_NO_NETWORK
+
TARGET = ../tst_qfile
SOURCES = ../tst_qfile.cpp
wince*: SOURCES += $$QT_SOURCE_TREE/src/corelib/kernel/qfunctions_wince.cpp
@@ -13,5 +16,5 @@ TESTDATA += ../dosfile.txt ../noendofline.txt ../testfile.txt \
../Makefile ../forCopying.txt ../forRenaming.txt \
../resources/file1.ext1
-win32: LIBS+=-lole32 -luuid
+win32:!winrt: LIBS+=-lole32 -luuid
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp
index 2b029203e9..77ac4bcd86 100644
--- a/tests/auto/corelib/io/qfile/tst_qfile.cpp
+++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp
@@ -59,7 +59,7 @@ extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
QT_END_NAMESPACE
#endif
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(QT_NO_NETWORK)
#include <QHostInfo>
#endif
#include <QProcess>
@@ -527,7 +527,7 @@ void tst_QFile::open_data()
<< false << QFile::OpenError;
QTest::newRow("noreadfile") << QString::fromLatin1(noReadFile) << int(QIODevice::ReadOnly)
<< false << QFile::OpenError;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//opening devices requires administrative privileges (and elevation).
HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hTest != INVALID_HANDLE_VALUE) {
@@ -1057,7 +1057,7 @@ void tst_QFile::ungetChar()
QCOMPARE(buf[2], '4');
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString driveLetters()
{
wchar_t volumeName[MAX_PATH];
@@ -1094,7 +1094,7 @@ void tst_QFile::invalidFile_data()
#if !defined(Q_OS_WIN)
QTest::newRow( "x11" ) << QString( "qwe//" );
#else
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QTest::newRow( "colon2" ) << invalidDriveLetter() + QString::fromLatin1(":ail:invalid");
#endif
QTest::newRow( "colon3" ) << QString( ":failinvalid" );
@@ -1338,10 +1338,12 @@ void tst_QFile::copyFallback()
#ifdef Q_OS_WIN
#include <objbase.h>
+#ifndef Q_OS_WINPHONE
#include <shlobj.h>
#endif
+#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
static QString getWorkingDirectoryForLink(const QString &linkFileName)
{
bool neededCoInit = false;
@@ -1400,7 +1402,7 @@ void tst_QFile::link()
QCOMPARE(QFile::symLinkTarget("myLink.lnk"), referenceTarget);
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QString wd = getWorkingDirectoryForLink(info2.absoluteFilePath());
QCOMPARE(QDir::fromNativeSeparators(wd), QDir::cleanPath(info1.absolutePath()));
#endif
@@ -2243,7 +2245,7 @@ void tst_QFile::writeLargeDataBlock_data()
QTest::newRow("localfile-Fd") << "./largeblockfile.txt" << (int)OpenFd;
QTest::newRow("localfile-Stream") << "./largeblockfile.txt" << (int)OpenStream;
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(QT_NO_NETWORK)
// Some semi-randomness to avoid collisions.
QTest::newRow("unc file")
<< QString("//" + QtNetworkSettings::winServerName() + "/TESTSHAREWRITABLE/largefile-%1-%2.txt")
@@ -2690,8 +2692,12 @@ void tst_QFile::nativeHandleLeaks()
}
#ifdef Q_OS_WIN
+# ifndef Q_OS_WINRT
handle1 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+# else
+ handle1 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL);
+# endif
QVERIFY( INVALID_HANDLE_VALUE != handle1 );
QVERIFY( ::CloseHandle(handle1) );
#endif
@@ -2705,8 +2711,12 @@ void tst_QFile::nativeHandleLeaks()
}
#ifdef Q_OS_WIN
+# ifndef Q_OS_WINRT
handle2 = ::CreateFileA("qt_file.tmp", GENERIC_READ, 0, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+# else
+ handle2 = ::CreateFile2(L"qt_file.tmp", GENERIC_READ, 0, OPEN_ALWAYS, NULL);
+# endif
QVERIFY( INVALID_HANDLE_VALUE != handle2 );
QVERIFY( ::CloseHandle(handle2) );
#endif
diff --git a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
index c4b37a8847..64d289bc3c 100644
--- a/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
+++ b/tests/auto/corelib/io/qfileinfo/qfileinfo.pro
@@ -6,5 +6,5 @@ RESOURCES += qfileinfo.qrc
TESTDATA += qfileinfo.qrc qfileinfo.pro tst_qfileinfo.cpp resources/file1 resources/file1.ext1 resources/file1.ext1.ext2
-win32*:!wince*:LIBS += -ladvapi32 -lnetapi32
+win32*:!wince*:!winrt:LIBS += -ladvapi32 -lnetapi32
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
index d2171cc64a..74667a951f 100644
--- a/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/corelib/io/qfileinfo/tst_qfileinfo.cpp
@@ -62,7 +62,7 @@
#ifdef Q_OS_WIN
#include <qt_windows.h>
#include <qlibrary.h>
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#include <lm.h>
#endif
#endif
@@ -176,7 +176,7 @@ private slots:
void refresh();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void ntfsJunctionPointsAndSymlinks_data();
void ntfsJunctionPointsAndSymlinks();
void brokenShortcut();
@@ -193,7 +193,7 @@ private slots:
void detachingOperations();
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void owner();
#endif
void group();
@@ -1058,7 +1058,7 @@ void tst_QFileInfo::fileTimes()
//In Vista the last-access timestamp is not updated when the file is accessed/touched (by default).
//To enable this the HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
//is set to 0, in the test machine.
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
HKEY key;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\FileSystem",
0, KEY_READ, &key)) {
@@ -1085,8 +1085,8 @@ void tst_QFileInfo::fileTimes()
void tst_QFileInfo::fileTimes_oldFile()
{
- // This is not supported on WinCE
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ // This is not supported on WinCE or WinRT
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// All files are opened in share mode (both read and write).
DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
@@ -1329,7 +1329,7 @@ void tst_QFileInfo::refresh()
QCOMPARE(info2.size(), info.size());
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void tst_QFileInfo::ntfsJunctionPointsAndSymlinks_data()
{
QTest::addColumn<QString>("path");
@@ -1680,7 +1680,7 @@ void tst_QFileInfo::detachingOperations()
QVERIFY(!info1.caching());
}
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#if defined (Q_OS_WIN)
BOOL IsUserAdmin()
{
diff --git a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index fda6519d82..b681cec802 100644
--- a/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/corelib/io/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -55,6 +55,7 @@ class tst_QFileSystemWatcher : public QObject
public:
tst_QFileSystemWatcher();
+#ifndef QT_NO_FILESYSTEMWATCHER
private slots:
void basicTest_data();
void basicTest();
@@ -83,16 +84,20 @@ private slots:
private:
QString m_tempDirPattern;
+#endif // QT_NO_FILESYSTEMWATCHER
};
tst_QFileSystemWatcher::tst_QFileSystemWatcher()
{
+#ifndef QT_NO_FILESYSTEMWATCHER
m_tempDirPattern = QDir::tempPath();
if (!m_tempDirPattern.endsWith(QLatin1Char('/')))
m_tempDirPattern += QLatin1Char('/');
m_tempDirPattern += QStringLiteral("tst_qfilesystemwatcherXXXXXX");
+#endif // QT_NO_FILESYSTEMWATCHER
}
+#ifndef QT_NO_FILESYSTEMWATCHER
void tst_QFileSystemWatcher::basicTest_data()
{
QTest::addColumn<QString>("backend");
@@ -676,6 +681,7 @@ void tst_QFileSystemWatcher::signalsEmittedAfterFileMoved()
QTRY_COMPARE(changedSpy.count(), 10);
}
+#endif // QT_NO_FILESYSTEMWATCHER
QTEST_MAIN(tst_QFileSystemWatcher)
#include "tst_qfilesystemwatcher.moc"
diff --git a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
index 50268f20a4..b0d7a76f0f 100644
--- a/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
+++ b/tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp
@@ -271,8 +271,8 @@ private slots:
QCOMPARE(defaultCategory.isEnabled(QtCriticalMsg), true);
QLoggingCategory customCategory("custom");
- QCOMPARE(customCategory.isDebugEnabled(), false);
- QCOMPARE(customCategory.isEnabled(QtDebugMsg), false);
+ QCOMPARE(customCategory.isDebugEnabled(), true);
+ QCOMPARE(customCategory.isEnabled(QtDebugMsg), true);
QCOMPARE(customCategory.isWarningEnabled(), true);
QCOMPARE(customCategory.isEnabled(QtWarningMsg), true);
QCOMPARE(customCategory.isCriticalEnabled(), true);
@@ -309,7 +309,7 @@ private slots:
QLoggingCategory cat("custom");
QCOMPARE(customCategoryFilterArgs, QStringList() << "custom");
- QVERIFY(cat.isDebugEnabled());
+ QVERIFY(!cat.isDebugEnabled());
customCategoryFilterArgs.clear();
// install default filter
@@ -319,7 +319,7 @@ private slots:
QCOMPARE(customCategoryFilterArgs.size(), 0);
QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled());
- QVERIFY(!cat.isDebugEnabled());
+ QVERIFY(cat.isDebugEnabled());
// install default filter
currentFilter =
@@ -328,7 +328,7 @@ private slots:
QCOMPARE(customCategoryFilterArgs.size(), 0);
QVERIFY(QLoggingCategory::defaultCategory()->isDebugEnabled());
- QVERIFY(!cat.isDebugEnabled());
+ QVERIFY(cat.isDebugEnabled());
}
void qDebugMacros()
@@ -376,23 +376,33 @@ private slots:
buf = QStringLiteral("default.debug: Check debug with no filter active");
qCDebug(defaultCategory) << "Check debug with no filter active";
QCOMPARE(logMessage, buf);
+ qCDebug(defaultCategory, "Check debug with no filter active");
+ QCOMPARE(logMessage, buf);
// Check default warning
buf = QStringLiteral("default.warning: Check warning with no filter active");
qCWarning(defaultCategory) << "Check warning with no filter active";
QCOMPARE(logMessage, buf);
+ qCWarning(defaultCategory, "Check warning with no filter active");
+ QCOMPARE(logMessage, buf);
// Check default critical
buf = QStringLiteral("default.critical: Check critical with no filter active");
qCCritical(defaultCategory) << "Check critical with no filter active";
QCOMPARE(logMessage, buf);
+ qCCritical(defaultCategory, "Check critical with no filter active");
+ QCOMPARE(logMessage, buf);
QLoggingCategory customCategory("custom");
// Check custom debug
logMessage.clear();
+ buf = QStringLiteral("custom.debug: Check debug with no filter active");
+ qCDebug(customCategory, "Check debug with no filter active");
+ QCOMPARE(logMessage, buf);
+
qCDebug(customCategory) << "Check debug with no filter active";
- QCOMPARE(logMessage, QString());
+ QCOMPARE(logMessage, buf);
// Check custom warning
buf = QStringLiteral("custom.warning: Check warning with no filter active");
@@ -408,17 +418,38 @@ private slots:
QLoggingCategory::installFilter(customCategoryFilter);
// Check custom debug
- buf = QStringLiteral("custom.debug: Check debug with filter active");
+ logMessage.clear();
qCDebug(customCategory) << "Check debug with filter active";
+ QCOMPARE(logMessage, QString());
+
+ // Check different macro/category variants
+ buf = QStringLiteral("tst.log.debug: Check debug with no filter active");
+ qCDebug(TST_LOG) << "Check debug with no filter active";
+ QCOMPARE(logMessage, QString());
+ qCDebug(TST_LOG, "Check debug with no filter active");
+ QCOMPARE(logMessage, QString());
+ qCDebug(TST_LOG(), "Check debug with no filter active");
+ QCOMPARE(logMessage, QString());
+ buf = QStringLiteral("tst.log.warning: Check warning with no filter active");
+ qCWarning(TST_LOG) << "Check warning with no filter active";
+ QCOMPARE(logMessage, buf);
+ qCWarning(TST_LOG, "Check warning with no filter active");
+ QCOMPARE(logMessage, buf);
+ buf = QStringLiteral("tst.log.critical: Check critical with no filter active");
+ qCCritical(TST_LOG) << "Check critical with no filter active";
QCOMPARE(logMessage, buf);
+ qCCritical(TST_LOG, "Check critical with no filter active");
+ QCOMPARE(logMessage, buf);
+
// reset to default filter
QLoggingCategory::installFilter(0);
// Check custom debug
logMessage.clear();
+ buf = QStringLiteral("custom.debug: Check debug with no filter active");
qCDebug(customCategory) << "Check debug with no filter active";
- QCOMPARE(logMessage, QString());
+ QCOMPARE(logMessage, buf);
}
void checkLegacyMessageLogger()
@@ -453,11 +484,11 @@ private slots:
QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf));
// Check category debug
- logMessage = "should not change";
- buf = logMessage;
+ buf = QStringLiteral("tst.log.debug: Check category Debug with no log active");
qCDebug(TST_LOG) << "Check category Debug with no log active";
QCOMPARE(logMessage, buf);
+
// Check default warning
buf = QStringLiteral("tst.log.warning: Check category Warning with no log active");
qCWarning(TST_LOG) << "Check category Warning with no log active";
@@ -739,8 +770,7 @@ private slots:
{
// "" -> custom category
QLoggingCategory mycategoryobject1("");
- logMessage = "no change";
- QString buf = QStringLiteral("no change");
+ QString buf = QStringLiteral(".debug: My Category Object");
qCDebug(mycategoryobject1) << "My Category Object";
QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf));
diff --git a/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro
new file mode 100644
index 0000000000..c6c4caace3
--- /dev/null
+++ b/tests/auto/corelib/io/qloggingregistry/qloggingregistry.pro
@@ -0,0 +1,8 @@
+TEMPLATE = app
+TARGET = tst_qloggingregistry
+
+CONFIG += testcase
+QT = core core-private testlib
+
+SOURCES += tst_qloggingregistry.cpp
+OTHER_FILES += qtlogging.ini
diff --git a/tests/auto/corelib/io/qloggingregistry/qtlogging.ini b/tests/auto/corelib/io/qloggingregistry/qtlogging.ini
new file mode 100644
index 0000000000..63b384e36a
--- /dev/null
+++ b/tests/auto/corelib/io/qloggingregistry/qtlogging.ini
@@ -0,0 +1,2 @@
+[rules]
+*=true
diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
new file mode 100644
index 0000000000..b538525161
--- /dev/null
+++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QLoggingCategory>
+
+#include <QtCore/private/qloggingregistry_p.h>
+
+QT_USE_NAMESPACE
+
+class tst_QLoggingRegistry : public QObject
+{
+ Q_OBJECT
+
+private slots:
+
+ void initTestCase()
+ {
+ // ensure a clean environment
+ QStandardPaths::setTestModeEnabled(true);
+ qunsetenv("QT_LOGGING_CONF");
+ }
+
+ void QLoggingSettingsParser_iniStyle()
+ {
+ //
+ // Logging configuration can be described
+ // in an .ini file. [rules] is the
+ // default category, and optional ...
+ //
+ QLoggingSettingsParser parser;
+ parser.setContent("[rules]\n"
+ "default=false\n"
+ "default=true");
+ QCOMPARE(parser.rules().size(), 2);
+
+ parser.setContent("[rules]\n"
+ "default=false");
+ QCOMPARE(parser.rules().size(), 1);
+
+ parser.setContent("[OtherSection]\n"
+ "default=false");
+ QCOMPARE(parser.rules().size(), 0);
+ }
+
+ void QLoggingRegistry_environment()
+ {
+ //
+ // Check whether QT_LOGGING_CONF is picked up from environment
+ //
+
+ qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
+
+ QLoggingRegistry registry;
+ registry.init();
+
+ QCOMPARE(registry.apiRules.size(), 0);
+ QCOMPARE(registry.configRules.size(), 0);
+ QCOMPARE(registry.envRules.size(), 1);
+
+ QCOMPARE(registry.rules.size(), 1);
+ }
+
+ void QLoggingRegistry_config()
+ {
+ //
+ // Check whether QtProject/qtlogging.ini is loaded automatically
+ //
+
+ // first try to create a test file..
+ QString path = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
+ QVERIFY(!path.isEmpty());
+ QDir dir(path + "/QtProject");
+ if (!dir.exists())
+ QVERIFY(dir.mkpath(path + "/QtProject"));
+
+ QFile file(dir.absoluteFilePath("qtlogging.ini"));
+ QVERIFY(file.open(QFile::WriteOnly | QFile::Text));
+ QTextStream out(&file);
+ out << "[rules]\n";
+ out << "Digia.*=false\n";
+ file.close();
+
+ QLoggingRegistry registry;
+ registry.init();
+ QCOMPARE(registry.configRules.size(), 1);
+
+ // remove file again
+ QVERIFY(file.remove());
+ }
+
+ void QLoggingRegistry_rulePriorities()
+ {
+ //
+ // Rules can stem from 3 sources:
+ // via QLoggingCategory::setFilterRules (API)
+ // via qtlogging.ini file in settings (Config)
+ // via QT_LOGGING_CONF environment variable (Env)
+ //
+ // Rules set by environment should get higher precedence than qtlogging.conf,
+ // than QLoggingCategory::setFilterRules
+ //
+
+ QLoggingCategory cat("Digia.Berlin");
+ QLoggingRegistry *registry = QLoggingRegistry::instance();
+
+ // empty all rules , check default
+ registry->rules.clear();
+ registry->apiRules.clear();
+ registry->configRules.clear();
+ registry->envRules.clear();
+ registry->updateRules();
+
+ QVERIFY(cat.isWarningEnabled());
+
+ // set Config rule
+ QLoggingSettingsParser parser;
+ parser.setContent("[rules]\nDigia.*=false");
+ registry->configRules=parser.rules();
+ registry->updateRules();
+
+ QVERIFY(!cat.isWarningEnabled());
+
+ // set API rule, should overwrite API one
+ QLoggingCategory::setFilterRules("Digia.*=true");
+
+ QVERIFY(cat.isWarningEnabled());
+
+ // set Env rule, should overwrite Config one
+ parser.setContent("Digia.*=false");
+ registry->envRules=parser.rules();
+ registry->updateRules();
+
+ QVERIFY(!cat.isWarningEnabled());
+ }
+
+};
+
+QTEST_MAIN(tst_QLoggingRegistry)
+
+#include "tst_qloggingregistry.moc"
diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
index 157e42b447..a516b762f7 100644
--- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
+++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp
@@ -68,8 +68,8 @@ void tst_QNoDebug::noDebugOutput() const
qCDebug(cat) << "foo";
// qWarning still works, though
- QTest::ignoreMessage(QtWarningMsg, "bar ");
- QTest::ignoreMessage(QtWarningMsg, "custom-bar ");
+ QTest::ignoreMessage(QtWarningMsg, "bar");
+ QTest::ignoreMessage(QtWarningMsg, "custom-bar");
qWarning() << "bar";
qCWarning(cat) << "custom-bar";
}
@@ -79,7 +79,7 @@ void tst_QNoDebug::streaming() const
QDateTime dt(QDate(1,2,3),QTime(4,5,6));
QString debugString = dt.toString(QStringLiteral("yyyy-MM-dd HH:mm:ss.zzz t"))
+ QStringLiteral(" Qt::LocalTime");
- QTest::ignoreMessage(QtWarningMsg, qPrintable(QString::fromLatin1("QDateTime(\"%1\") ").arg(debugString)));
+ QTest::ignoreMessage(QtWarningMsg, qPrintable(QString::fromLatin1("QDateTime(\"%1\")").arg(debugString)));
qWarning() << dt;
}
diff --git a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
index 48fd2d0b69..8f77e46f74 100644
--- a/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
+++ b/tests/auto/corelib/io/qprocess/testProcessEOF/testProcessEOF.pro
@@ -2,6 +2,6 @@ SOURCES = main.cpp
CONFIG -= qt app_bundle
CONFIG += console
-win32:!win32-g++*:!equals(TEMPLATE_PREFIX, "vc"):QMAKE_CXXFLAGS += /GS-
+win32:!mingw:!equals(TEMPLATE_PREFIX, "vc"):QMAKE_CXXFLAGS += /GS-
DESTDIR = ./
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 37f224ff28..f5aa2c2412 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -943,7 +943,7 @@ void tst_QProcess::hardExit()
void tst_QProcess::softExit()
{
QProcess proc;
-
+ QCOMPARE(proc.processId(), 0);
proc.start("testSoftExit/testSoftExit");
QVERIFY(proc.waitForStarted(10000));
@@ -951,6 +951,8 @@ void tst_QProcess::softExit()
QVERIFY(proc.waitForReadyRead(10000));
#endif
+ QVERIFY(proc.processId() > 0);
+
proc.terminate();
QVERIFY(proc.waitForFinished(10000));
diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
index c5a9b421ee..42c360f2d8 100644
--- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
+++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp
@@ -119,7 +119,7 @@ private slots:
#if !defined(Q_OS_WIN) && !defined(QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER)
void dontReorderIniKeysNeedlessly();
#endif
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void consistentRegistryStorage();
#endif
@@ -274,7 +274,7 @@ void tst_QSettings::init()
QSettings::setSystemIniPath(settingsPath("__system__"));
QSettings::setUserIniPath(settingsPath("__user__"));
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QSettings("HKEY_CURRENT_USER\\Software\\software.org", QSettings::NativeFormat).clear();
QSettings("HKEY_LOCAL_MACHINE\\Software\\software.org", QSettings::NativeFormat).clear();
QSettings("HKEY_CURRENT_USER\\Software\\other.software.org", QSettings::NativeFormat).clear();
@@ -1496,7 +1496,7 @@ void tst_QSettings::sync()
// Now "some other app" will change other.software.org.ini
QString userConfDir = settingsPath("__user__") + QDir::separator();
-#if !defined(Q_OS_WINCE)
+#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
unlink((userConfDir + "other.software.org.ini").toLatin1());
rename((userConfDir + "software.org.ini").toLatin1(),
(userConfDir + "other.software.org.ini").toLatin1());
@@ -3197,7 +3197,7 @@ void tst_QSettings::recursionBug()
}
}
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
static DWORD readKeyType(HKEY handle, const QString &rSubKey)
{
diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
index 4503f6fcbc..7247b02498 100644
--- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
+++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
@@ -290,9 +290,9 @@ void tst_qstandardpaths::testDataLocation()
{
// On all platforms, DataLocation should be GenericDataLocation / organization name / app name
// This allows one app to access the data of another app.
- // Blackberry OS and Android are exceptions to this case, owing to the fact that
+ // Blackberry OS, Android and WinRT are an exception to this case, owing to the fact that
// applications are sandboxed.
-#if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID)
+#if !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) && !defined(Q_OS_WINRT)
const QString base = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::DataLocation), base + "/tst_qstandardpaths");
QCoreApplication::instance()->setOrganizationName("Qt");
@@ -336,6 +336,7 @@ void tst_qstandardpaths::testFindExecutable_data()
QTest::addColumn<QString>("needle");
QTest::addColumn<QString>("expected");
#ifdef Q_OS_WIN
+# ifndef Q_OS_WINRT
const QFileInfo cmdFi = QFileInfo(QDir::cleanPath(QString::fromLocal8Bit(qgetenv("COMSPEC"))));
const QString cmdPath = cmdFi.absoluteFilePath();
@@ -359,6 +360,7 @@ void tst_qstandardpaths::testFindExecutable_data()
QTest::newRow("win8-logo-nosuffix")
<< QString() << logo << logoPath;
}
+# endif // Q_OS_WINRT
#else
const QFileInfo shFi = findSh();
Q_ASSERT(shFi.exists());
diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
index 713d0c5c17..a6cc083d9c 100644
--- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
+++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp
@@ -257,7 +257,7 @@ void tst_QTemporaryDir::nonWritableCurrentDir()
void tst_QTemporaryDir::openOnRootDrives()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
// If it's possible to create a file in the root directory, it
@@ -271,7 +271,7 @@ void tst_QTemporaryDir::openOnRootDrives()
QVERIFY(dir.isValid());
}
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
SetErrorMode(lastErrorMode);
#endif
}
diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
index 6eb6f83d2a..5ad798ae1f 100644
--- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
+++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp
@@ -371,7 +371,7 @@ void tst_QTemporaryFile::resize()
void tst_QTemporaryFile::openOnRootDrives()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
#endif
// If it's possible to create a file in the root directory, it
@@ -385,7 +385,7 @@ void tst_QTemporaryFile::openOnRootDrives()
QVERIFY(file.open());
}
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
SetErrorMode(lastErrorMode);
#endif
}
diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
index d3a8bcfd13..28519e1161 100644
--- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
+++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp
@@ -1040,7 +1040,7 @@ void tst_QUrlInternal::encodingRecodeInvalidUtf8()
output = QTest::currentDataTag();
if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyEncoded))
output += input;
- for (int i = strlen(QTest::currentDataTag()); i < output.length(); ++i) {
+ for (int i = int(strlen(QTest::currentDataTag())); i < output.length(); ++i) {
QVERIFY2(output.at(i).unicode() < 0x80 || output.at(i) == QChar::ReplacementCharacter,
qPrintable(QString("Character at i == %1 was U+%2").arg(i).arg(output.at(i).unicode(), 4, 16, QLatin1Char('0'))));
}
diff --git a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp b/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp
index 0944f32443..8321f76bec 100644
--- a/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp
+++ b/tests/auto/corelib/io/qwinoverlappedionotifier/tst_qwinoverlappedionotifier.cpp
@@ -42,6 +42,7 @@
#include <QtTest/QtTest>
#include <private/qwinoverlappedionotifier_p.h>
#include <qbytearray.h>
+#include <qt_windows.h>
#ifndef PIPE_REJECT_REMOTE_CLIENTS
#define PIPE_REJECT_REMOTE_CLIENTS 0x08
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index c6c81ad75d..0f72b419a0 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -2768,9 +2768,9 @@ void tst_QSortFilterProxyModel::mapFromToSource()
QCOMPARE(proxy.mapToSource(QModelIndex()), QModelIndex());
#ifdef QT_NO_DEBUG //if Qt is compiled in debug mode, this will assert
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource ");
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapToSource");
QCOMPARE(proxy.mapToSource(source.index(2, 3)), QModelIndex());
- QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource ");
+ QTest::ignoreMessage(QtWarningMsg, "QSortFilterProxyModel: index from wrong model passed to mapFromSource");
QCOMPARE(proxy.mapFromSource(proxy.index(6, 2)), QModelIndex());
#endif
}
diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp
index c79e7273c0..aee5875613 100644
--- a/tests/auto/corelib/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/json/tst_qtjson.cpp
@@ -76,6 +76,7 @@ private Q_SLOTS:
void testObjectNested();
void testArrayNested();
void testArrayNestedEmpty();
+ void testArrayComfortOperators();
void testObjectNestedEmpty();
void testValueRef();
@@ -665,6 +666,20 @@ void tst_QtJson::testObjectNestedEmpty()
QCOMPARE(reconstituted.value("inner2").type(), QJsonValue::Object);
}
+void tst_QtJson::testArrayComfortOperators()
+{
+ QJsonArray first;
+ first.append(123.);
+ first.append(QLatin1String("foo"));
+
+ QJsonArray second = QJsonArray() << 123. << QLatin1String("foo");
+ QCOMPARE(first, second);
+
+ first = first + QLatin1String("bar");
+ second += QLatin1String("bar");
+ QCOMPARE(first, second);
+}
+
void tst_QtJson::testValueRef()
{
QJsonArray array;
@@ -1194,7 +1209,7 @@ void tst_QtJson::toJson()
QByteArray json = QJsonDocument(object).toJson(QJsonDocument::Compact);
QByteArray expected =
- "{\"Array\": [true,999,\"string\",null,\"\\\\\\u0007\\n\\r\\b\\tabcABC\\\"\"],\"\\\\Key\\n\": \"Value\",\"null\": null}";
+ "{\"Array\":[true,999,\"string\",null,\"\\\\\\u0007\\n\\r\\b\\tabcABC\\\"\"],\"\\\\Key\\n\":\"Value\",\"null\":null}";
QCOMPARE(json, expected);
QJsonDocument doc;
@@ -1546,7 +1561,7 @@ void tst_QtJson::fromJsonErrors()
QJsonDocument doc = QJsonDocument::fromJson(json, &error);
QVERIFY(doc.isEmpty());
QCOMPARE(error.error, QJsonParseError::IllegalUTF8String);
- QCOMPARE(error.offset, 14);
+ QCOMPARE(error.offset, 12);
}
{
QJsonParseError error;
@@ -1570,7 +1585,7 @@ void tst_QtJson::fromJsonErrors()
QJsonDocument doc = QJsonDocument::fromJson(json, &error);
QVERIFY(doc.isEmpty());
QCOMPARE(error.error, QJsonParseError::IllegalUTF8String);
- QCOMPARE(error.offset, 15);
+ QCOMPARE(error.offset, 13);
}
{
QJsonParseError error;
@@ -1985,11 +2000,11 @@ void tst_QtJson::testDebugStream()
// QJsonObject
QJsonObject object;
- QTest::ignoreMessage(QtDebugMsg, "QJsonObject() ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonObject()");
qDebug() << object;
object.insert(QLatin1String("foo"), QLatin1String("bar"));
- QTest::ignoreMessage(QtDebugMsg, "QJsonObject({\"foo\": \"bar\"}) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonObject({\"foo\":\"bar\"})");
qDebug() << object;
}
@@ -1997,12 +2012,12 @@ void tst_QtJson::testDebugStream()
// QJsonArray
QJsonArray array;
- QTest::ignoreMessage(QtDebugMsg, "QJsonArray() ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonArray()");
qDebug() << array;
array.append(1);
array.append(QLatin1String("foo"));
- QTest::ignoreMessage(QtDebugMsg, "QJsonArray([1,\"foo\"]) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonArray([1,\"foo\"])");
qDebug() << array;
}
@@ -2010,19 +2025,19 @@ void tst_QtJson::testDebugStream()
// QJsonDocument
QJsonDocument doc;
- QTest::ignoreMessage(QtDebugMsg, "QJsonDocument() ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonDocument()");
qDebug() << doc;
QJsonObject object;
object.insert(QLatin1String("foo"), QLatin1String("bar"));
doc.setObject(object);
- QTest::ignoreMessage(QtDebugMsg, "QJsonDocument({\"foo\": \"bar\"}) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonDocument({\"foo\":\"bar\"})");
qDebug() << doc;
QJsonArray array;
array.append(1);
array.append(QLatin1String("foo"));
- QTest::ignoreMessage(QtDebugMsg, "QJsonDocument([1,\"foo\"]) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonDocument([1,\"foo\"])");
doc.setArray(array);
qDebug() << doc;
}
@@ -2032,36 +2047,36 @@ void tst_QtJson::testDebugStream()
QJsonValue value;
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(null) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(null)");
qDebug() << value;
value = QJsonValue(true); // bool
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(bool, true) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(bool, true)");
qDebug() << value;
value = QJsonValue((double)4.2); // double
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(double, 4.2) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(double, 4.2)");
qDebug() << value;
value = QJsonValue((int)42); // int
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(double, 42) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(double, 42)");
qDebug() << value;
value = QJsonValue(QLatin1String("foo")); // string
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(string, \"foo\") ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(string, \"foo\")");
qDebug() << value;
QJsonArray array;
array.append(1);
array.append(QLatin1String("foo"));
value = QJsonValue(array); // array
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(array, QJsonArray([1,\"foo\"]) ) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(array, QJsonArray([1,\"foo\"]) )");
qDebug() << value;
QJsonObject object;
object.insert(QLatin1String("foo"), QLatin1String("bar"));
value = QJsonValue(object); // object
- QTest::ignoreMessage(QtDebugMsg, "QJsonValue(object, QJsonObject({\"foo\": \"bar\"}) ) ");
+ QTest::ignoreMessage(QtDebugMsg, "QJsonValue(object, QJsonObject({\"foo\":\"bar\"}) )");
qDebug() << value;
}
}
@@ -2227,6 +2242,14 @@ void tst_QtJson::valueEquals()
QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(true));
QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(1.));
QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonArray()));
+
+ QVERIFY(QJsonValue("foo") == QJsonValue(QLatin1String("foo")));
+ QVERIFY(QJsonValue("foo") == QJsonValue(QString("foo")));
+ QVERIFY(QJsonValue("\x66\x6f\x6f") == QJsonValue(QString("foo")));
+ QVERIFY(QJsonValue("\x62\x61\x72") == QJsonValue("bar"));
+ QVERIFY(QJsonValue(UNICODE_NON_CHARACTER) == QJsonValue(QString(UNICODE_NON_CHARACTER)));
+ QVERIFY(QJsonValue(UNICODE_DJE) == QJsonValue(QString(UNICODE_DJE)));
+ QVERIFY(QJsonValue("\xc3\xa9") == QJsonValue(QString("\xc3\xa9")));
}
void tst_QtJson::bom()
diff --git a/tests/auto/corelib/kernel/kernel.pro b/tests/auto/corelib/kernel/kernel.pro
index fe3e4b7e0a..4b3b2e824e 100644
--- a/tests/auto/corelib/kernel/kernel.pro
+++ b/tests/auto/corelib/kernel/kernel.pro
@@ -13,6 +13,7 @@ SUBDIRS=\
qobject \
qpointer \
qsharedmemory \
+ qsignalblocker \
qsignalmapper \
qsocketnotifier \
qsystemsemaphore \
@@ -34,6 +35,6 @@ SUBDIRS=\
qsharedmemory
# This test is only applicable on Windows
-!win32*:SUBDIRS -= qwineventnotifier
+!win32*|winrt: SUBDIRS -= qwineventnotifier
android|qnx: SUBDIRS -= qsharedmemory qsystemsemaphore
diff --git a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro
index e5bcc31e6a..5593aa2430 100644
--- a/tests/auto/corelib/kernel/qeventloop/qeventloop.pro
+++ b/tests/auto/corelib/kernel/qeventloop/qeventloop.pro
@@ -4,7 +4,7 @@ TARGET = tst_qeventloop
QT = core network testlib core-private
SOURCES = $$PWD/tst_qeventloop.cpp
-win32:!wince*:LIBS += -luser32
+win32:!wince*:!winrt:LIBS += -luser32
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
contains(QT_CONFIG, glib): DEFINES += HAVE_GLIB
diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
index c6d04e64db..a7833aa835 100644
--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
+++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp
@@ -504,8 +504,8 @@ void tst_QEventLoop::processEventsExcludeTimers()
// but not if we exclude timers
eventLoop.processEvents(QEventLoop::X11ExcludeTimers);
- QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
#if defined(Q_OS_UNIX)
+ QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
if (!qobject_cast<QEventDispatcherUNIX *>(eventDispatcher)
#if defined(HAVE_GLIB)
&& !qobject_cast<QEventDispatcherGlib *>(eventDispatcher)
diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
index 5cf3e6d97c..0e7005799e 100644
--- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
+++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp
@@ -1323,8 +1323,8 @@ bool tst_QMetaObjectBuilder::sameMetaObject
return false;
}
- const QMetaObject **objects1 = meta1->d.relatedMetaObjects;
- const QMetaObject **objects2 = meta2->d.relatedMetaObjects;
+ const QMetaObject * const *objects1 = meta1->d.relatedMetaObjects;
+ const QMetaObject * const *objects2 = meta2->d.relatedMetaObjects;
if (objects1 && !objects2)
return false;
if (objects2 && !objects1)
diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
index 23a8e6d23a..d19ec23760 100644
--- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
+++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro
@@ -6,11 +6,11 @@ SOURCES = tst_qmetatype.cpp
TESTDATA=./typeFlags.bin
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-win32-msvc*|wince {
+win32-msvc*|wince|winrt {
# Prevents "fatal error C1128: number of sections exceeded object file format limit".
QMAKE_CXXFLAGS += /bigobj
# Reduce compile time
- win32-msvc2012|wince {
+ win32-msvc2012|wince|winrt {
QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CFLAGS_RELEASE -= -O2
}
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index f0df10744d..1c0a495116 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -102,6 +102,7 @@ private slots:
#ifndef QT_NO_PROCESS
void recursiveSignalEmission();
#endif
+ void signalBlocking();
void blockingQueuedConnection();
void childEvents();
void installEventFilter();
@@ -455,7 +456,7 @@ void tst_QObject::connectSlotsByName()
sender.setObjectName("Sender");
QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: No matching signal for on_child_signal()");
- QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: Connecting slot on_Sender_signalManyParams() with the first of the following compatible signals: (\"signalManyParams(int,int,int,QString,bool)\", \"signalManyParams(int,int,int,QString,bool,bool)\") ");
+ QTest::ignoreMessage(QtWarningMsg, "QMetaObject::connectSlotsByName: Connecting slot on_Sender_signalManyParams() with the first of the following compatible signals: (\"signalManyParams(int,int,int,QString,bool)\", \"signalManyParams(int,int,int,QString,bool,bool)\")");
QMetaObject::connectSlotsByName(&receiver);
receiver.called_slots.clear();
@@ -2950,6 +2951,9 @@ void tst_QObject::dynamicProperties()
QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
QCOMPARE(obj.changedDynamicProperties.count(), 1);
QCOMPARE(obj.changedDynamicProperties.first(), QByteArray("myuserproperty"));
+ //check if there is no redundant DynamicPropertyChange events
+ QVERIFY(!obj.setProperty("myuserproperty", "Hello"));
+ QCOMPARE(obj.changedDynamicProperties.count(), 1);
obj.changedDynamicProperties.clear();
QCOMPARE(obj.property("myuserproperty").toString(), QString("Hello"));
@@ -2982,6 +2986,30 @@ void tst_QObject::recursiveSignalEmission()
}
#endif
+void tst_QObject::signalBlocking()
+{
+ SenderObject sender;
+ ReceiverObject receiver;
+
+ receiver.connect(&sender, SIGNAL(signal1()), SLOT(slot1()));
+
+ sender.emitSignal1();
+ QVERIFY(receiver.called(1));
+ receiver.reset();
+
+ sender.blockSignals(true);
+
+ sender.emitSignal1();
+ QVERIFY(!receiver.called(1));
+ receiver.reset();
+
+ sender.blockSignals(false);
+
+ sender.emitSignal1();
+ QVERIFY(receiver.called(1));
+ receiver.reset();
+}
+
void tst_QObject::blockingQueuedConnection()
{
{
@@ -4732,6 +4760,9 @@ class LotsOfSignalsAndSlots: public QObject
#endif*/
static void static_slot_vPFvvE(fptr) {}
+ void slot_vcRQObject(const QObject &) {}
+ void slot_vRQObject(QObject &) {}
+
signals:
void signal_v();
void signal_vi(int);
@@ -4749,6 +4780,9 @@ class LotsOfSignalsAndSlots: public QObject
void const_signal_v() const;
void const_signal_vi(int) const;
+ void signal_vcRQObject(const QObject &);
+ void signal_vRQObject(QObject &);
+
void signal(short&, short, long long, short);
void otherSignal(const char *);
};
@@ -4866,6 +4900,14 @@ void tst_QObject::connectCxx0xTypeMatching()
QVERIFY(QObject::connect(&obj, &Foo::const_signal_vi, &obj, &Foo::slot_vi));
QVERIFY(QObject::connect(&obj, &Foo::signal_vi, &obj, &Foo::const_slot_vi));
QVERIFY(QObject::connect(&obj, &Foo::signal_vi, &obj, &Foo::const_slot_v));
+
+ QVERIFY(QObject::connect(&obj, &Foo::signal_vcRQObject, &obj, &Foo::slot_vcRQObject));
+ QVERIFY(QObject::connect(&obj, &Foo::signal_vRQObject, &obj, &Foo::slot_vRQObject));
+ QVERIFY(QObject::connect(&obj, &Foo::signal_vRQObject, &obj, &Foo::slot_vcRQObject));
+ // QVERIFY(QObject::connect(&obj, &Foo::signal_vcRQObject, &obj, &Foo::slot_vRQObject)); // Should be an error (const& -> &)
+
+ QVERIFY(QObject::connect(&obj, &Foo::signal_vRi, &obj, &Foo::slot_vs));
+
}
class StringVariant : public QObject
@@ -5523,8 +5565,8 @@ public:
};
class ConnectToPrivateSlotPrivate : public QObjectPrivate {
-public:
Q_DECLARE_PUBLIC(ConnectToPrivateSlot)
+public:
int receivedCount;
QVariant receivedValue;
diff --git a/tests/auto/corelib/kernel/qsignalblocker/.gitignore b/tests/auto/corelib/kernel/qsignalblocker/.gitignore
new file mode 100644
index 0000000000..a841a2a0a8
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsignalblocker/.gitignore
@@ -0,0 +1 @@
+tst_qsignalblocker
diff --git a/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro b/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro
new file mode 100644
index 0000000000..c6c6f379eb
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsignalblocker/qsignalblocker.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase console
+CONFIG += parallel_test
+TARGET = tst_qsignalblocker
+QT = core testlib
+SOURCES = tst_qsignalblocker.cpp
+
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp b/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp
new file mode 100644
index 0000000000..3fc155bfe8
--- /dev/null
+++ b/tests/auto/corelib/kernel/qsignalblocker/tst_qsignalblocker.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@woboq.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include "qobject.h"
+
+class tst_QSignalBlocker : public QObject
+{
+ Q_OBJECT
+private slots:
+ void signalBlocking();
+ void moveAssignment();
+};
+
+void tst_QSignalBlocker::signalBlocking()
+{
+ QObject o;
+
+ QVERIFY(!o.signalsBlocked());
+
+ {
+ QSignalBlocker blocker(&o);
+ QVERIFY(o.signalsBlocked());
+
+ o.blockSignals(false);
+ QVERIFY(!o.signalsBlocked());
+
+ o.blockSignals(true);
+ QVERIFY(o.signalsBlocked());
+
+ blocker.unblock();
+ QVERIFY(!o.signalsBlocked());
+
+ blocker.reblock();
+ QVERIFY(o.signalsBlocked());
+ }
+
+ QVERIFY(!o.signalsBlocked());
+}
+
+void tst_QSignalBlocker::moveAssignment()
+{
+#ifdef Q_COMPILER_RVALUE_REFS
+ QObject o1, o2;
+
+ // move-assignment: both block other objects
+ {
+ QSignalBlocker b(&o1);
+ QVERIFY(o1.signalsBlocked());
+
+ QVERIFY(!o2.signalsBlocked());
+ b = QSignalBlocker(&o2);
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(o2.signalsBlocked());
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+ // move-assignment: from inert other
+ {
+ QSignalBlocker b(&o1);
+ QVERIFY(o1.signalsBlocked());
+ b = QSignalBlocker(0);
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+ // move-assignment: to inert *this
+ {
+ QSignalBlocker b(0);
+ QVERIFY(!o1.signalsBlocked());
+ {
+ QSignalBlocker inner(&o1);
+ QVERIFY(o1.signalsBlocked());
+ b = std::move(inner);
+ }
+ QVERIFY(o1.signalsBlocked());
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+ // move-assignment: both block the same object, neither is unblocked
+ {
+ QSignalBlocker b(&o1);
+ QVERIFY(o1.signalsBlocked());
+ {
+ b.unblock(); // make sure inner.m_blocked = false
+ QVERIFY(!o1.signalsBlocked());
+ QSignalBlocker inner(&o1);
+ QVERIFY(o1.signalsBlocked());
+ b.reblock();
+ QVERIFY(o1.signalsBlocked());
+ b = std::move(inner);
+ }
+ QVERIFY(o1.signalsBlocked());
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+ // move-assignment: both block the same object, but *this is unblocked
+ {
+ QSignalBlocker b(&o1);
+ QVERIFY(o1.signalsBlocked());
+ b.unblock();
+ QVERIFY(!o1.signalsBlocked());
+ b = QSignalBlocker(&o1);
+ QVERIFY(o1.signalsBlocked());
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+ // move-assignment: both block the same object, but other is unblocked
+ {
+ QSignalBlocker b(&o1);
+ {
+ QVERIFY(o1.signalsBlocked());
+ QSignalBlocker inner(&o1);
+ QVERIFY(o1.signalsBlocked());
+ inner.unblock();
+ QVERIFY(o1.signalsBlocked());
+ b = std::move(inner);
+ QVERIFY(!o1.signalsBlocked());
+ }
+ QVERIFY(!o1.signalsBlocked());
+ }
+
+ QVERIFY(!o1.signalsBlocked());
+ QVERIFY(!o2.signalsBlocked());
+
+#else
+ QSKIP("This compiler is not in C++11 mode or doesn't support move semantics");
+#endif // Q_COMPILER_RVALUE_REFS
+}
+
+QTEST_MAIN(tst_QSignalBlocker)
+#include "tst_qsignalblocker.moc"
diff --git a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
index 439594b661..5632bcacc4 100644
--- a/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
+++ b/tests/auto/corelib/kernel/qsocketnotifier/tst_qsocketnotifier.cpp
@@ -48,7 +48,11 @@
#include <QtCore/QSocketNotifier>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
+#ifndef Q_OS_WINRT
#include <private/qnativesocketengine_p.h>
+#else
+#include <private/qnativesocketengine_winrt_p.h>
+#endif
#define NATIVESOCKETENGINE QNativeSocketEngine
#ifdef Q_OS_UNIX
#include <private/qnet_unix_p.h>
diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
index fefc126bba..f0d817d37d 100644
--- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
+++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp
@@ -84,6 +84,8 @@ private slots:
void fetchAndAdd_data();
void fetchAndAdd();
+ void operators();
+
// stress tests
void testAndSet_loop();
void fetchAndAdd_loop();
@@ -99,10 +101,6 @@ static inline void assemblyMarker(void *ptr = 0)
puts((char *)ptr + I);
}
-QT_BEGIN_NAMESPACE
-template <typename T> class QBasicAtomicInteger; // even if it this class isn't supported
-QT_END_NAMESPACE
-
template <typename T, typename Atomic>
static void warningFreeHelperTemplate()
{
@@ -185,7 +183,7 @@ void tst_QAtomicInt::warningFreeHelper()
qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only.");
warningFreeHelperTemplate<int, QBasicAtomicInt>();
-#ifdef Q_ATOMIC_INT32_IS_SUPPORTED
+ // 32-bit are always supported:
warningFreeHelperTemplate<int, QBasicAtomicInteger<int> >();
warningFreeHelperTemplate<unsigned int, QBasicAtomicInteger<unsigned int> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<int> >();
@@ -194,7 +192,18 @@ void tst_QAtomicInt::warningFreeHelper()
warningFreeHelperTemplate<qint16, QBasicAtomicInteger<char32_t> >();
constexprFunctionsHelperTemplate<QBasicAtomicInteger<char32_t> >();
# endif
-#endif
+
+ // pointer-sized integers are always supported:
+ warningFreeHelperTemplate<int, QBasicAtomicInteger<qptrdiff> >();
+ warningFreeHelperTemplate<unsigned int, QBasicAtomicInteger<quintptr> >();
+ constexprFunctionsHelperTemplate<QBasicAtomicInteger<qptrdiff> >();
+ constexprFunctionsHelperTemplate<QBasicAtomicInteger<quintptr> >();
+
+ // long is always supported because it's either 32-bit or pointer-sized:
+ warningFreeHelperTemplate<int, QBasicAtomicInteger<long int> >();
+ warningFreeHelperTemplate<unsigned int, QBasicAtomicInteger<unsigned long int> >();
+ constexprFunctionsHelperTemplate<QBasicAtomicInteger<long int> >();
+ constexprFunctionsHelperTemplate<QBasicAtomicInteger<unsigned long int> >();
#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
warningFreeHelperTemplate<qint16, QBasicAtomicInteger<qint16> >();
@@ -533,6 +542,43 @@ void tst_QAtomicInt::testAndSet()
QAtomicInt atomic = value;
QTEST(atomic.testAndSetOrdered(expected, newval) ? 1 : 0, "result");
}
+
+#ifdef Q_ATOMIC_INT32_IS_SUPPORTED
+ QFETCH(int, result);
+ // the new implementation has the version that loads the current value
+
+ {
+ QAtomicInt atomic = value;
+ int currentval = 0xdeadbeef;
+ QCOMPARE(atomic.testAndSetRelaxed(expected, newval, currentval), result);
+ if (!result)
+ QCOMPARE(currentval, value);
+ }
+
+ {
+ QAtomicInt atomic = value;
+ int currentval = 0xdeadbeef;
+ QCOMPARE(atomic.testAndSetAcquire(expected, newval, currentval), result);
+ if (!result)
+ QCOMPARE(currentval, value);
+ }
+
+ {
+ QAtomicInt atomic = value;
+ int currentval = 0xdeadbeef;
+ QCOMPARE(atomic.testAndSetRelease(expected, newval, currentval), result);
+ if (!result)
+ QCOMPARE(currentval, value);
+ }
+
+ {
+ QAtomicInt atomic = value;
+ int currentval = 0xdeadbeef;
+ QCOMPARE(atomic.testAndSetOrdered(expected, newval, currentval), result);
+ if (!result)
+ QCOMPARE(currentval, value);
+ }
+#endif
}
void tst_QAtomicInt::isFetchAndStoreNative()
@@ -763,6 +809,58 @@ void tst_QAtomicInt::fetchAndAdd()
}
}
+void tst_QAtomicInt::operators()
+{
+ {
+ // Test that QBasicAtomicInt also has operator= and cast operators
+ // We've been using them for QAtomicInt elsewhere
+ QBasicAtomicInt atomic = Q_BASIC_ATOMIC_INITIALIZER(0);
+ atomic = 1;
+ QCOMPARE(int(atomic), 1);
+ }
+
+ QAtomicInt atomic = 0;
+ int x = ++atomic;
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 1);
+
+ x = atomic++;
+ QCOMPARE(int(atomic), x + 1);
+ QCOMPARE(int(atomic), 2);
+
+ x = atomic--;
+ QCOMPARE(int(atomic), x - 1);
+ QCOMPARE(int(atomic), 1);
+
+ x = --atomic;
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 0);
+
+ x = (atomic += 1);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 1);
+
+ x = (atomic -= 1);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 0);
+
+ x = (atomic |= 0xf);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 0xf);
+
+ x = (atomic &= 0x17);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 7);
+
+ x = (atomic ^= 0x14);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 0x13);
+
+ x = (atomic ^= atomic);
+ QCOMPARE(int(atomic), x);
+ QCOMPARE(int(atomic), 0);
+}
+
void tst_QAtomicInt::testAndSet_loop()
{
QTime stopWatch;
diff --git a/tests/auto/corelib/thread/qatomicinteger/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/char/char.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char/char.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/int/int.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/int/int.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/long/long.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/long/long.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
new file mode 100644
index 0000000000..dc7cc8bcec
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri
@@ -0,0 +1,7 @@
+isEmpty(TYPE): error("Project must define TYPE variable")
+
+CONFIG += testcase parallel_test
+QT = core testlib
+TARGET = tst_qatomicinteger_$$TYPE
+SOURCES = $$PWD/tst_qatomicinteger.cpp
+DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$TYPE
diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
new file mode 100644
index 0000000000..373e8801a4
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro
@@ -0,0 +1,19 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ char \
+ char16_t \
+ char32_t \
+ int \
+ long \
+ qlonglong \
+ qptrdiff \
+ quintptr \
+ qulonglong \
+ schar \
+ short \
+ uchar \
+ uint \
+ ulong \
+ ushort \
+ wchar_t \
+
diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/short/short.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/short/short.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
new file mode 100644
index 0000000000..6ddd2ff233
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp
@@ -0,0 +1,821 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest>
+#include <QAtomicInt>
+
+#include <limits>
+#include <limits.h>
+#include <wchar.h>
+
+#if !defined(Q_ATOMIC_INT32_IS_SUPPORTED)
+# error "QAtomicInteger for 32-bit types must be supported!"
+#endif
+#if QT_POINTER_SIZE == 8 && !defined(Q_ATOMIC_INT64_IS_SUPPORTED)
+# error "QAtomicInteger for 64-bit types must be supported on 64-bit builds!"
+#endif
+
+// always supported types:
+#define TYPE_SUPPORTED_int 1
+#define TYPE_SUPPORTED_uint 1
+#define TYPE_SUPPORTED_long 1
+#define TYPE_SUPPORTED_ulong 1
+#define TYPE_SUPPORTED_qptrdiff 1
+#define TYPE_SUPPORTED_quintptr 1
+#if (defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__-0) > 2) \
+ || (defined(WCHAR_MAX) && (WCHAR_MAX-0 > 0x10000))
+# define TYPE_SUPPORTED_wchar_t 1
+#endif
+#ifdef Q_COMPILER_UNICODE_STRINGS
+# define TYPE_SUPPORTED_char32_t 1
+#endif
+
+#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
+# define TYPE_SUPPORTED_char 1
+# define TYPE_SUPPORTED_uchar 1
+# define TYPE_SUPPORTED_schar 1
+#endif
+#ifdef Q_ATOMIC_INT16_IS_SUPPORTED
+# define TYPE_SUPPORTED_short 1
+# define TYPE_SUPPORTED_ushort 1
+# ifdef Q_COMPILER_UNICODE_STRINGS
+# define TYPE_SUPPORTED_char16_t 1
+# endif
+# ifndef TYPE_SUPPORTED_wchar_t
+# define TYPE_SUPPORTED_wchar_t 1
+# endif
+#endif
+#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
+# define TYPE_SUPPORTED_qlonglong 1
+# define TYPE_SUPPORTED_qulonglong 1
+#endif
+
+#ifdef Q_MOC_RUN
+# define QATOMIC_TYPE_SUPPORTED(type) 1
+#else
+# define QATOMIC_TYPE_SUPPORTED2(type) TYPE_SUPPORTED_ ## type
+# define QATOMIC_TYPE_SUPPORTED(type) QATOMIC_TYPE_SUPPORTED2(type)
+#endif // Q_MOC_RUN
+
+#if QATOMIC_TYPE_SUPPORTED(QATOMIC_TEST_TYPE)
+# define TEST_TYPE QATOMIC_TEST_TYPE
+#else
+# define TEST_TYPE int
+# define QATOMIC_TEST_NOT_SUPPORTED
+#endif
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
+# pragma GCC diagnostic ignored "-Wtype-limits"
+# pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
+#if defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
+# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
+#endif
+
+typedef signed char schar;
+
+typedef TEST_TYPE Type;
+typedef Type T; // shorthand
+enum {
+ TypeIsUnsigned = Type(-1) > Type(0),
+ TypeIsSigned = !TypeIsUnsigned
+};
+
+template <bool> struct LargeIntTemplate;
+template <> struct LargeIntTemplate<true> { typedef quint64 Type; };
+template <> struct LargeIntTemplate<false> { typedef qint64 Type; };
+typedef LargeIntTemplate<TypeIsUnsigned>::Type LargeInt;
+
+class tst_QAtomicIntegerXX : public QObject
+{
+ Q_OBJECT
+
+ void addData();
+
+private Q_SLOTS:
+ void initTestCase();
+ void static_checks();
+
+ void constructor_data() { addData(); }
+ void constructor();
+
+ void copy_data() { addData(); }
+ void copy();
+
+ void assign_data() { addData(); }
+ void assign();
+
+ void operatorInteger_data() { addData(); }
+ void operatorInteger();
+
+ void loadAcquireStoreRelease_data() { addData(); }
+ void loadAcquireStoreRelease();
+
+ void refDeref_data() { addData(); }
+ void refDeref();
+
+ void testAndSet_data() { addData(); }
+ void testAndSet();
+
+ void testAndSet3_data() { addData(); }
+ void testAndSet3();
+
+ void fetchAndStore_data() { addData(); }
+ void fetchAndStore();
+
+ void fetchAndAdd_data() { addData(); }
+ void fetchAndAdd();
+
+ void fetchAndSub_data() { addData(); }
+ void fetchAndSub();
+
+ void addSub_data() { addData(); }
+ void addSub();
+
+ void fetchAndOr_data() { addData(); }
+ void fetchAndOr();
+
+ void fetchAndAnd_data() { addData(); }
+ void fetchAndAnd();
+
+ void fetchAndXor_data() { addData(); }
+ void fetchAndXor();
+};
+
+template <bool> inline void booleanHelper() { }
+template <typename T> struct TypeInStruct { T type; };
+
+void tst_QAtomicIntegerXX::static_checks()
+{
+ Q_STATIC_ASSERT(sizeof(QAtomicInteger<T>) == sizeof(T));
+ Q_STATIC_ASSERT(Q_ALIGNOF(QAtomicInteger<T>) == Q_ALIGNOF(TypeInStruct<T>));
+
+ // statements with no effect
+ (void) QAtomicInteger<T>::isReferenceCountingNative();
+ (void) QAtomicInteger<T>::isReferenceCountingWaitFree();
+ (void) QAtomicInteger<T>::isTestAndSetNative();
+ (void) QAtomicInteger<T>::isTestAndSetWaitFree();
+ (void) QAtomicInteger<T>::isFetchAndStoreNative();
+ (void) QAtomicInteger<T>::isFetchAndStoreWaitFree();
+ (void) QAtomicInteger<T>::isFetchAndAddNative();
+ (void) QAtomicInteger<T>::isFetchAndAddWaitFree();
+
+#ifdef Q_COMPILER_CONSTEXPR
+ // this is a compile-time test only
+ booleanHelper<QAtomicInteger<T>::isReferenceCountingNative()>();
+ booleanHelper<QAtomicInteger<T>::isReferenceCountingWaitFree()>();
+ booleanHelper<QAtomicInteger<T>::isTestAndSetNative()>();
+ booleanHelper<QAtomicInteger<T>::isTestAndSetWaitFree()>();
+ booleanHelper<QAtomicInteger<T>::isFetchAndStoreNative()>();
+ booleanHelper<QAtomicInteger<T>::isFetchAndStoreWaitFree()>();
+ booleanHelper<QAtomicInteger<T>::isFetchAndAddNative()>();
+ booleanHelper<QAtomicInteger<T>::isFetchAndAddWaitFree()>();
+#endif
+}
+
+void tst_QAtomicIntegerXX::addData()
+{
+ typedef std::numeric_limits<T> Limits;
+ QTest::addColumn<LargeInt>("value");
+ QTest::newRow("0") << LargeInt(0);
+ QTest::newRow("+1") << LargeInt(1);
+ QTest::newRow("42") << LargeInt(42);
+ if (TypeIsSigned) {
+ QTest::newRow("-1") << qint64(-1);
+ QTest::newRow("-47") << qint64(-47);
+ }
+
+ // exercise bits
+ if (TypeIsSigned && Limits::min() < qint64(SCHAR_MIN))
+ QTest::newRow("int8_min") << qint64(SCHAR_MIN);
+ if (Limits::max() > LargeInt(SCHAR_MAX))
+ QTest::newRow("int8_max") << LargeInt(SCHAR_MAX);
+ if (Limits::max() > LargeInt(UCHAR_MAX))
+ QTest::newRow("uint8_max") << LargeInt(UCHAR_MAX);
+ if (TypeIsSigned && Limits::min() < -qint64(UCHAR_MAX))
+ QTest::newRow("-uint8_max") << -qint64(UCHAR_MAX);
+ if (Limits::max() > LargeInt(SHRT_MAX))
+ QTest::newRow("int16_max") << LargeInt(SHRT_MAX);
+ if (TypeIsSigned && Limits::min() < qint64(SHRT_MIN))
+ QTest::newRow("int16_min") << qint64(SHRT_MIN);
+ if (Limits::max() > LargeInt(USHRT_MAX))
+ QTest::newRow("uint16_max") << LargeInt(USHRT_MAX);
+ if (TypeIsSigned && Limits::min() < -qint64(USHRT_MAX))
+ QTest::newRow("-uint16_max") << -qint64(USHRT_MAX);
+ if (Limits::max() > LargeInt(INT_MAX))
+ QTest::newRow("int32_max") << LargeInt(INT_MAX);
+ if (TypeIsSigned && Limits::min() < qint64(INT_MIN))
+ QTest::newRow("int32_min") << qint64(INT_MIN);
+ if (Limits::max() > LargeInt(UINT_MAX))
+ QTest::newRow("uint32_max") << LargeInt(UINT_MAX);
+ if (Limits::max() > LargeInt(std::numeric_limits<qint64>::max()))
+ QTest::newRow("int64_max") << LargeInt(std::numeric_limits<qint64>::max());
+ if (TypeIsSigned && Limits::min() < -qint64(UINT_MAX))
+ QTest::newRow("-uint32_max") << -qint64(UINT_MAX);
+
+ if (TypeIsSigned)
+ QTest::newRow(QT_STRINGIFY(QATOMIC_TEST_TYPE) "_min") << qint64(Limits::min());
+ QTest::newRow(QT_STRINGIFY(QATOMIC_TEST_TYPE) "_max") << LargeInt(Limits::max());
+}
+
+void tst_QAtomicIntegerXX::initTestCase()
+{
+#ifdef QATOMIC_TEST_NOT_SUPPORTED
+ QSKIP("QAtomicInteger<" QT_STRINGIFY(QATOMIC_TEST_TYPE) "> is not supported on this platform");
+#endif
+}
+
+void tst_QAtomicIntegerXX::constructor()
+{
+ QFETCH(LargeInt, value);
+
+ QAtomicInteger<T> atomic(value);
+ QCOMPARE(atomic.load(), T(value));
+
+ QAtomicInteger<T> atomic2 = value;
+ QCOMPARE(atomic2.load(), T(value));
+
+ QVERIFY(atomic.load() >= std::numeric_limits<T>::min());
+ QVERIFY(atomic.load() <= std::numeric_limits<T>::max());
+}
+
+void tst_QAtomicIntegerXX::copy()
+{
+ QFETCH(LargeInt, value);
+
+ QAtomicInteger<T> atomic(value);
+ QAtomicInteger<T> copy(atomic);
+ QCOMPARE(copy.load(), atomic.load());
+
+ QAtomicInteger<T> copy2 = atomic;
+ QCOMPARE(copy2.load(), atomic.load());
+
+ // move
+ QAtomicInteger<T> copy3(qMove(copy));
+ QCOMPARE(copy3.load(), atomic.load());
+
+ QAtomicInteger<T> copy4 = qMove(copy2);
+ QCOMPARE(copy4.load(), atomic.load());
+}
+
+void tst_QAtomicIntegerXX::assign()
+{
+ QFETCH(LargeInt, value);
+
+ QAtomicInteger<T> atomic(value);
+ QAtomicInteger<T> copy;
+ copy = atomic;
+ QCOMPARE(copy.load(), atomic.load());
+
+ QAtomicInteger<T> copy2;
+ copy2 = atomic; // operator=(const QAtomicInteger &)
+ QCOMPARE(copy2.load(), atomic.load());
+
+ QAtomicInteger<T> copy2bis;
+ copy2bis = atomic.load(); // operator=(T)
+ QCOMPARE(copy2bis.load(), atomic.load());
+
+ // move
+ QAtomicInteger<T> copy3;
+ copy3 = qMove(copy);
+ QCOMPARE(copy3.load(), atomic.load());
+
+ QAtomicInteger<T> copy4;
+ copy4 = qMove(copy2);
+ QCOMPARE(copy4.load(), atomic.load());
+}
+
+void tst_QAtomicIntegerXX::operatorInteger()
+{
+ QFETCH(LargeInt, value);
+
+ QAtomicInteger<T> atomic(value);
+ T val2 = atomic;
+ QCOMPARE(val2, atomic.load());
+ QCOMPARE(val2, T(value));
+}
+
+void tst_QAtomicIntegerXX::loadAcquireStoreRelease()
+{
+ QFETCH(LargeInt, value);
+
+ QAtomicInteger<T> atomic(value);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ atomic.storeRelease(~value);
+ QCOMPARE(atomic.loadAcquire(), T(~value));
+
+ atomic.storeRelease(value);
+ QCOMPARE(atomic.load(), T(value));
+}
+
+void tst_QAtomicIntegerXX::refDeref()
+{
+ QFETCH(LargeInt, value);
+ T nextValue = T(value + 1);
+ T prevValue = T(value - 1);
+
+ QAtomicInteger<T> atomic(value);
+ QCOMPARE(atomic.ref(), (nextValue != 0));
+ QCOMPARE(atomic.load(), nextValue);
+ QCOMPARE(atomic.deref(), (value != 0));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.deref(), (prevValue != 0));
+ QCOMPARE(atomic.load(), prevValue);
+ QCOMPARE(atomic.ref(), (value != 0));
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(++atomic, nextValue);
+ QCOMPARE(--atomic, T(value));
+ QCOMPARE(--atomic, prevValue);
+ QCOMPARE(++atomic, T(value));
+
+ QCOMPARE(atomic++, T(value));
+ QCOMPARE(atomic--, nextValue);
+ QCOMPARE(atomic--, T(value));
+ QCOMPARE(atomic++, prevValue);
+ QCOMPARE(atomic.load(), T(value));
+}
+
+void tst_QAtomicIntegerXX::testAndSet()
+{
+ QFETCH(LargeInt, value);
+ T newValue = ~T(value);
+ QAtomicInteger<T> atomic(value);
+
+ QVERIFY(atomic.testAndSetRelaxed(value, newValue));
+ QCOMPARE(atomic.load(), newValue);
+ QVERIFY(!atomic.testAndSetRelaxed(value, newValue));
+ QVERIFY(atomic.testAndSetRelaxed(newValue, value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QVERIFY(atomic.testAndSetAcquire(value, newValue));
+ QCOMPARE(atomic.load(), newValue);
+ QVERIFY(!atomic.testAndSetAcquire(value, newValue));
+ QVERIFY(atomic.testAndSetAcquire(newValue, value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QVERIFY(atomic.testAndSetRelease(value, newValue));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QVERIFY(!atomic.testAndSetRelease(value, newValue));
+ QVERIFY(atomic.testAndSetRelease(newValue, value));
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ QVERIFY(atomic.testAndSetOrdered(value, newValue));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QVERIFY(!atomic.testAndSetOrdered(value, newValue));
+ QVERIFY(atomic.testAndSetOrdered(newValue, value));
+ QCOMPARE(atomic.loadAcquire(), T(value));
+}
+
+void tst_QAtomicIntegerXX::testAndSet3()
+{
+ QFETCH(LargeInt, value);
+ T newValue = ~T(value);
+ T oldValue;
+ QAtomicInteger<T> atomic(value);
+
+ QVERIFY(atomic.testAndSetRelaxed(value, newValue, oldValue));
+ QCOMPARE(atomic.load(), newValue);
+ QVERIFY(!atomic.testAndSetRelaxed(value, newValue, oldValue));
+ QCOMPARE(oldValue, newValue);
+ QVERIFY(atomic.testAndSetRelaxed(newValue, value, oldValue));
+ QCOMPARE(atomic.load(), T(value));
+
+ QVERIFY(atomic.testAndSetAcquire(value, newValue, oldValue));
+ QCOMPARE(atomic.load(), newValue);
+ QVERIFY(!atomic.testAndSetAcquire(value, newValue, oldValue));
+ QCOMPARE(oldValue, newValue);
+ QVERIFY(atomic.testAndSetAcquire(newValue, value, oldValue));
+ QCOMPARE(atomic.load(), T(value));
+
+ QVERIFY(atomic.testAndSetRelease(value, newValue, oldValue));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QVERIFY(!atomic.testAndSetRelease(value, newValue, oldValue));
+ QCOMPARE(oldValue, newValue);
+ QVERIFY(atomic.testAndSetRelease(newValue, value, oldValue));
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ QVERIFY(atomic.testAndSetOrdered(value, newValue, oldValue));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QVERIFY(!atomic.testAndSetOrdered(value, newValue, oldValue));
+ QCOMPARE(oldValue, newValue);
+ QVERIFY(atomic.testAndSetOrdered(newValue, value, oldValue));
+ QCOMPARE(atomic.loadAcquire(), T(value));
+}
+
+void tst_QAtomicIntegerXX::fetchAndStore()
+{
+ QFETCH(LargeInt, value);
+ T newValue = ~T(value);
+ QAtomicInteger<T> atomic(value);
+
+ QCOMPARE(atomic.fetchAndStoreRelaxed(newValue), T(value));
+ QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.fetchAndStoreRelaxed(value), newValue);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndStoreAcquire(newValue), T(value));
+ QCOMPARE(atomic.load(), newValue);
+ QCOMPARE(atomic.fetchAndStoreAcquire(value), newValue);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndStoreRelease(newValue), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QCOMPARE(atomic.fetchAndStoreRelease(value), newValue);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ QCOMPARE(atomic.fetchAndStoreOrdered(newValue), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue);
+ QCOMPARE(atomic.fetchAndStoreOrdered(value), newValue);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+}
+
+void tst_QAtomicIntegerXX::fetchAndAdd()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ // note: this test has undefined behavior for signed max and min
+ T parcel1 = 42;
+ T parcel2 = T(0-parcel1);
+ T newValue1 = T(value) + parcel1;
+ T newValue2 = T(value) + parcel2;
+
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue1);
+ QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+ QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue2);
+ QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue1);
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue2);
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ // operator+=
+ QCOMPARE(atomic += parcel1, newValue1);
+ QCOMPARE(atomic += parcel2, T(value));
+ QCOMPARE(atomic += parcel2, newValue2);
+ QCOMPARE(atomic += parcel1, T(value));
+}
+
+void tst_QAtomicIntegerXX::fetchAndSub()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ // note: this test has undefined behavior for signed max and min
+ T parcel1 = 42;
+ T parcel2 = T(0-parcel1);
+ T newValue1 = T(value) - parcel1;
+ T newValue2 = T(value) - parcel2;
+
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue1);
+ QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue1);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue2);
+ QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue2);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue1);
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue1);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value));
+ QCOMPARE(atomic.loadAcquire(), newValue2);
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue2);
+ QCOMPARE(atomic.loadAcquire(), T(value));
+
+ // operator-=
+ QCOMPARE(atomic -= parcel1, newValue1);
+ QCOMPARE(atomic -= parcel2, T(value));
+ QCOMPARE(atomic -= parcel2, newValue2);
+ QCOMPARE(atomic -= parcel1, T(value));
+}
+
+void tst_QAtomicIntegerXX::addSub()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ // note: this test has undefined behavior for signed max and min
+ T parcel1 = 42;
+ T parcel2 = T(0-parcel1);
+ T newValue1 = T(value) + parcel1;
+ T newValue2 = T(value) - parcel1;
+
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelaxed(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddRelaxed(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel1), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel2), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubAcquire(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddAcquire(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddRelease(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubRelease(parcel1), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelease(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddRelease(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddRelease(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubRelease(parcel2), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubRelease(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddRelease(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel1), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel1), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel1), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue2);
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel2), newValue2);
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndSubOrdered(parcel2), T(value));
+ QCOMPARE(atomic.load(), newValue1);
+ QCOMPARE(atomic.fetchAndAddOrdered(parcel2), newValue1);
+ QCOMPARE(atomic.load(), T(value));
+
+ // operator+= and operator-=
+ QCOMPARE(atomic += parcel1, newValue1);
+ QCOMPARE(atomic -= parcel1, T(value));
+ QCOMPARE(atomic -= parcel1, newValue2);
+ QCOMPARE(atomic += parcel1, T(value));
+ QCOMPARE(atomic += parcel2, newValue2);
+ QCOMPARE(atomic -= parcel2, T(value));
+ QCOMPARE(atomic -= parcel2, newValue1);
+ QCOMPARE(atomic += parcel2, T(value));
+}
+
+void tst_QAtomicIntegerXX::fetchAndOr()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ T zero = 0;
+ T one = 1;
+ T minusOne = T(~0);
+
+ QCOMPARE(atomic.fetchAndOrRelaxed(zero), T(value));
+ QCOMPARE(atomic.fetchAndOrRelaxed(one), T(value));
+ QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.fetchAndOrRelaxed(minusOne), T(value | 1));
+ QCOMPARE(atomic.load(), minusOne);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndOrAcquire(zero), T(value));
+ QCOMPARE(atomic.fetchAndOrAcquire(one), T(value));
+ QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.fetchAndOrAcquire(minusOne), T(value | 1));
+ QCOMPARE(atomic.load(), minusOne);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndOrRelease(zero), T(value));
+ QCOMPARE(atomic.fetchAndOrRelease(one), T(value));
+ QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.fetchAndOrRelease(minusOne), T(value | 1));
+ QCOMPARE(atomic.load(), minusOne);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndOrOrdered(zero), T(value));
+ QCOMPARE(atomic.fetchAndOrOrdered(one), T(value));
+ QCOMPARE(atomic.load(), T(value | 1));
+ QCOMPARE(atomic.fetchAndOrOrdered(minusOne), T(value | 1));
+ QCOMPARE(atomic.load(), minusOne);
+
+ atomic.store(value);
+ QCOMPARE(atomic |= zero, T(value));
+ QCOMPARE(atomic |= one, T(value | 1));
+ QCOMPARE(atomic |= minusOne, minusOne);
+}
+
+void tst_QAtomicIntegerXX::fetchAndAnd()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ T zero = 0;
+ T f = 0xf;
+ T minusOne = T(~0);
+
+ QCOMPARE(atomic.fetchAndAndRelaxed(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAndRelaxed(f), T(value));
+ QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.fetchAndAndRelaxed(zero), T(value & 0xf));
+ QCOMPARE(atomic.load(), zero);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndAndAcquire(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAndAcquire(f), T(value));
+ QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.fetchAndAndAcquire(zero), T(value & 0xf));
+ QCOMPARE(atomic.load(), zero);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndAndRelease(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAndRelease(f), T(value));
+ QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.fetchAndAndRelease(zero), T(value & 0xf));
+ QCOMPARE(atomic.load(), zero);
+
+ atomic.store(value);
+ QCOMPARE(atomic.fetchAndAndOrdered(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndAndOrdered(f), T(value));
+ QCOMPARE(atomic.load(), T(value & 0xf));
+ QCOMPARE(atomic.fetchAndAndOrdered(zero), T(value & 0xf));
+ QCOMPARE(atomic.load(), zero);
+
+ atomic.store(value);
+ QCOMPARE(atomic &= minusOne, T(value));
+ QCOMPARE(atomic &= f, T(value & 0xf));
+ QCOMPARE(atomic &= zero, zero);
+}
+
+void tst_QAtomicIntegerXX::fetchAndXor()
+{
+ QFETCH(LargeInt, value);
+ QAtomicInteger<T> atomic(value);
+
+ T zero = 0;
+ T pattern = T(Q_UINT64_C(0xcccccccccccccccc));
+ T minusOne = T(~0);
+
+ QCOMPARE(atomic.fetchAndXorRelaxed(zero), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorRelaxed(pattern), T(value));
+ QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.fetchAndXorRelaxed(pattern), T(value ^ pattern));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorRelaxed(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.fetchAndXorRelaxed(minusOne), T(~value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndXorAcquire(zero), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorAcquire(pattern), T(value));
+ QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.fetchAndXorAcquire(pattern), T(value ^ pattern));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorAcquire(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.fetchAndXorAcquire(minusOne), T(~value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndXorRelease(zero), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorRelease(pattern), T(value));
+ QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.fetchAndXorRelease(pattern), T(value ^ pattern));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorRelease(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.fetchAndXorRelease(minusOne), T(~value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic.fetchAndXorOrdered(zero), T(value));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorOrdered(pattern), T(value));
+ QCOMPARE(atomic.load(), T(value ^ pattern));
+ QCOMPARE(atomic.fetchAndXorOrdered(pattern), T(value ^ pattern));
+ QCOMPARE(atomic.load(), T(value));
+ QCOMPARE(atomic.fetchAndXorOrdered(minusOne), T(value));
+ QCOMPARE(atomic.load(), T(~value));
+ QCOMPARE(atomic.fetchAndXorOrdered(minusOne), T(~value));
+ QCOMPARE(atomic.load(), T(value));
+
+ QCOMPARE(atomic ^= zero, T(value));
+ QCOMPARE(atomic ^= pattern, T(value ^ pattern));
+ QCOMPARE(atomic ^= pattern, T(value));
+ QCOMPARE(atomic ^= minusOne, T(~value));
+ QCOMPARE(atomic ^= minusOne, T(value));
+}
+
+#include "tst_qatomicinteger.moc"
+
+QTEST_APPLESS_MAIN(tst_QAtomicIntegerXX)
+
diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
new file mode 100644
index 0000000000..51ef1add8f
--- /dev/null
+++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro
@@ -0,0 +1,2 @@
+TYPE = $$basename(PWD)
+include(../qatomicinteger.pri)
diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
index d4e777e35b..595808e270 100644
--- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
+++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp
@@ -70,6 +70,8 @@ private slots:
void constAndVolatile();
void forwardDeclared();
+
+ void operators();
private:
static void warningFreeHelper();
};
@@ -664,5 +666,56 @@ void tst_QAtomicPointer::forwardDeclared()
QVERIFY(true);
}
+template <typename T> static void operators_helper()
+{
+ typedef T *Ptr;
+ T array[3] = {};
+ Ptr zero = array;
+ Ptr one = array + 1;
+ Ptr two = array + 2;
+
+ {
+ // Test that QBasicAtomicPointer also has operator= and cast operators
+ // We've been using them for QAtomicPointer<T> elsewhere
+ QBasicAtomicPointer<T> atomic = Q_BASIC_ATOMIC_INITIALIZER(0);
+ atomic = one;
+ QCOMPARE(Ptr(atomic), one);
+ }
+
+ QAtomicPointer<T> atomic = zero;
+ Ptr x = ++atomic;
+ QCOMPARE(Ptr(atomic), x);
+ QCOMPARE(Ptr(atomic), one);
+
+ x = atomic++;
+ QCOMPARE(Ptr(atomic), x + 1);
+ QCOMPARE(Ptr(atomic), two);
+
+ x = atomic--;
+ QCOMPARE(Ptr(atomic), x - 1);
+ QCOMPARE(Ptr(atomic), one);
+
+ x = --atomic;
+ QCOMPARE(Ptr(atomic), x);
+ QCOMPARE(Ptr(atomic), zero);
+
+ x = (atomic += 1);
+ QCOMPARE(Ptr(atomic), x);
+ QCOMPARE(Ptr(atomic), one);
+
+ x = (atomic -= 1);
+ QCOMPARE(Ptr(atomic), x);
+ QCOMPARE(Ptr(atomic), zero);
+}
+
+struct Big { double d[10]; };
+void tst_QAtomicPointer::operators()
+{
+ operators_helper<char>();
+ operators_helper<int>();
+ operators_helper<double>();
+ operators_helper<Big>();
+}
+
QTEST_APPLESS_MAIN(tst_QAtomicPointer)
#include "tst_qatomicpointer.moc"
diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
index 5cc0e5bdb4..0e53139414 100644
--- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp
+++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp
@@ -55,6 +55,8 @@
#endif
#if defined(Q_OS_WINCE)
#include <windows.h>
+#elif defined(Q_OS_WINRT)
+#include <thread>
#elif defined(Q_OS_WIN)
#include <process.h>
#include <windows.h>
@@ -326,6 +328,9 @@ void tst_QThread::isRunning()
void tst_QThread::setPriority()
{
+#if defined(Q_OS_WINRT)
+ QSKIP("Thread priority is not supported on WinRT");
+#endif
Simple_Thread thread;
// cannot change the priority, since the thread is not running
@@ -460,6 +465,10 @@ void tst_QThread::start()
QVERIFY(!thread.isFinished());
QVERIFY(!thread.isRunning());
QMutexLocker locker(&thread.mutex);
+#ifdef Q_OS_WINRT
+ if (priorities[i] != QThread::NormalPriority && priorities[i] != QThread::InheritPriority)
+ QTest::ignoreMessage(QtWarningMsg, "QThread::start: Failed to set thread priority (not implemented)");
+#endif
thread.start(priorities[i]);
QVERIFY(thread.isRunning());
QVERIFY(!thread.isFinished());
@@ -472,6 +481,9 @@ void tst_QThread::start()
void tst_QThread::terminate()
{
+#if defined(Q_OS_WINRT)
+ QSKIP("Terminate is not supported on WinRT");
+#endif
Terminate_Thread thread;
{
QMutexLocker locker(&thread.mutex);
@@ -535,6 +547,9 @@ void tst_QThread::finished()
void tst_QThread::terminated()
{
+#if defined(Q_OS_WINRT)
+ QSKIP("Terminate is not supported on WinRT");
+#endif
SignalRecorder recorder;
Terminate_Thread thread;
connect(&thread, SIGNAL(finished()), &recorder, SLOT(slot()), Qt::DirectConnection);
@@ -630,6 +645,8 @@ void noop(void*) { }
#if defined Q_OS_UNIX
typedef pthread_t ThreadHandle;
+#elif defined Q_OS_WINRT
+ typedef std::thread ThreadHandle;
#elif defined Q_OS_WIN
typedef HANDLE ThreadHandle;
#endif
@@ -671,6 +688,8 @@ void NativeThreadWrapper::start(FunctionPointer functionPointer, void *data)
#if defined Q_OS_UNIX
const int state = pthread_create(&nativeThreadHandle, 0, NativeThreadWrapper::runUnix, this);
Q_UNUSED(state);
+#elif defined(Q_OS_WINRT)
+ nativeThreadHandle = std::thread(NativeThreadWrapper::runWin, this);
#elif defined(Q_OS_WINCE)
nativeThreadHandle = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NativeThreadWrapper::runWin , this, 0, NULL);
#elif defined Q_OS_WIN
@@ -690,6 +709,8 @@ void NativeThreadWrapper::join()
{
#if defined Q_OS_UNIX
pthread_join(nativeThreadHandle, 0);
+#elif defined Q_OS_WINRT
+ nativeThreadHandle.join();
#elif defined Q_OS_WIN
WaitForSingleObject(nativeThreadHandle, INFINITE);
CloseHandle(nativeThreadHandle);
@@ -780,6 +801,9 @@ void tst_QThread::adoptedThreadAffinity()
void tst_QThread::adoptedThreadSetPriority()
{
+#if defined(Q_OS_WINRT)
+ QSKIP("Thread priority is not supported on WinRT");
+#endif
NativeThreadWrapper nativeThread;
nativeThread.setWaitForStop();
@@ -857,6 +881,9 @@ void tst_QThread::adoptedThreadFinished()
nativeThread.join();
QTestEventLoop::instance().enterLoop(5);
+#if defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
+#endif
QVERIFY(!QTestEventLoop::instance().timeout());
}
@@ -872,6 +899,9 @@ void tst_QThread::adoptedThreadExecFinished()
nativeThread.join();
QTestEventLoop::instance().enterLoop(5);
+#if defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
+#endif
QVERIFY(!QTestEventLoop::instance().timeout());
}
@@ -908,6 +938,9 @@ void tst_QThread::adoptMultipleThreads()
}
QTestEventLoop::instance().enterLoop(5);
+#if defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
+#endif
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(recorder.activationCount.load(), numThreads);
}
@@ -950,6 +983,9 @@ void tst_QThread::adoptMultipleThreadsOverlap()
}
QTestEventLoop::instance().enterLoop(5);
+#if defined(Q_OS_WINRT)
+ QEXPECT_FAIL("", "QTBUG-31397: Known not to work on WinRT", Abort);
+#endif
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(recorder.activationCount.load(), numThreads);
}
diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
index 4a9932798c..859cd1b36a 100644
--- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
+++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp
@@ -80,6 +80,7 @@ private slots:
void destruction();
void threadRecycling();
void expiryTimeout();
+ void expiryTimeoutRace();
#ifndef QT_NO_EXCEPTIONS
void exceptions();
#endif
@@ -315,7 +316,7 @@ class ExpiryTimeoutTask : public QRunnable
{
public:
QThread *thread;
- int runCount;
+ QAtomicInt runCount;
QSemaphore semaphore;
ExpiryTimeoutTask()
@@ -327,7 +328,7 @@ public:
void run()
{
thread = QThread::currentThread();
- ++runCount;
+ runCount.ref();
semaphore.release();
}
};
@@ -346,7 +347,7 @@ void tst_QThreadPool::expiryTimeout()
// run the task
threadPool.start(&task);
QVERIFY(task.semaphore.tryAcquire(1, 10000));
- QCOMPARE(task.runCount, 1);
+ QCOMPARE(task.runCount.load(), 1);
QVERIFY(!task.thread->wait(100));
// thread should expire
QThread *firstThread = task.thread;
@@ -355,7 +356,7 @@ void tst_QThreadPool::expiryTimeout()
// run task again, thread should be restarted
threadPool.start(&task);
QVERIFY(task.semaphore.tryAcquire(1, 10000));
- QCOMPARE(task.runCount, 2);
+ QCOMPARE(task.runCount.load(), 2);
QVERIFY(!task.thread->wait(100));
// thread should expire again
QVERIFY(task.thread->wait(10000));
@@ -368,6 +369,22 @@ void tst_QThreadPool::expiryTimeout()
QCOMPARE(threadPool.expiryTimeout(), expiryTimeout);
}
+void tst_QThreadPool::expiryTimeoutRace() // QTBUG-3786
+{
+ ExpiryTimeoutTask task;
+
+ QThreadPool threadPool;
+ threadPool.setMaxThreadCount(1);
+ threadPool.setExpiryTimeout(50);
+ const int numTasks = 20;
+ for (int i = 0; i < numTasks; ++i) {
+ threadPool.start(&task);
+ QThread::msleep(50); // exactly the same as the expiry timeout
+ }
+ QCOMPARE(task.runCount.load(), numTasks);
+ QVERIFY(threadPool.waitForDone(2000));
+}
+
#ifndef QT_NO_EXCEPTIONS
class ExceptionTask : public QRunnable
{
@@ -503,7 +520,8 @@ void tst_QThreadPool::setMaxThreadCountStartsAndStopsThreads()
QVERIFY(task->waitForStarted.tryAcquire(6, 1000));
task->waitToFinish.release(10);
-// delete task;
+ threadPool.waitForDone();
+ delete task;
}
void tst_QThreadPool::reserveThread_data()
diff --git a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
index 2072034f5f..c96de29b98 100644
--- a/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
+++ b/tests/auto/corelib/thread/qthreadstorage/tst_qthreadstorage.cpp
@@ -232,7 +232,7 @@ void tst_QThreadStorage::adoptedThreads()
const int state = pthread_create(&thread, 0, testAdoptedThreadStorageUnix, &pointers);
QCOMPARE(state, 0);
pthread_join(thread, 0);
-#elif defined Q_OS_WIN
+#elif defined Q_OS_WIN && !defined(Q_OS_WINRT)
HANDLE thread;
#if defined(Q_OS_WINCE)
thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)testAdoptedThreadStorageWin, &pointers, 0, NULL);
diff --git a/tests/auto/corelib/thread/thread.pro b/tests/auto/corelib/thread/thread.pro
index f529bd8941..f18dad6a4c 100644
--- a/tests/auto/corelib/thread/thread.pro
+++ b/tests/auto/corelib/thread/thread.pro
@@ -1,6 +1,7 @@
TEMPLATE=subdirs
SUBDIRS=\
qatomicint \
+ qatomicinteger \
qatomicpointer \
qresultstore \
qfuture \
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 621b5811f9..f9ce7425f6 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -87,8 +87,7 @@ private slots:
void fromRawData_data();
void fromRawData();
void literals();
-#if defined(Q_COMPILER_VARIADIC_MACROS) \
- && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
void variadicLiterals();
#endif
#ifdef Q_COMPILER_RVALUE_REFS
@@ -469,7 +468,7 @@ void tst_QArrayData::simpleVector()
for (int i = 0; i < 60; ++i)
QCOMPARE(v1[i], v8[i % 10]);
- v1.insert(v1.size(), v6.constBegin(), v6.constEnd());
+ v1.insert(int(v1.size()), v6.constBegin(), v6.constEnd());
// v1 is now [ 0..9 x 6, <new data>0..9 x 3</new data> ]
QCOMPARE(v1.size(), size_t(90));
@@ -1235,7 +1234,7 @@ void tst_QArrayData::arrayOps2()
vo.resize(10);
for (size_t i = 7; i < 10; ++i) {
- vi[i] = i;
+ vi[i] = int(i);
vs[i] = QString::number(i);
QCOMPARE(vo[i].id, i);
@@ -1555,8 +1554,7 @@ void tst_QArrayData::literals()
QCOMPARE(v.size(), size_t(11));
// v.capacity() is unspecified, for now
-#if defined(Q_COMPILER_VARIADIC_MACROS) \
- && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
QVERIFY(v.isStatic());
#endif
@@ -1569,8 +1567,7 @@ void tst_QArrayData::literals()
}
}
-#if defined(Q_COMPILER_VARIADIC_MACROS) \
- && (defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU))
+#if defined(Q_COMPILER_VARIADIC_MACROS) && defined(Q_COMPILER_LAMBDA)
// Variadic Q_ARRAY_LITERAL need to be available in the current configuration.
void tst_QArrayData::variadicLiterals()
{
@@ -1727,7 +1724,7 @@ void tst_QArrayData::grow()
// Going element-wise is slow under valgrind
if (previousCapacity - i > 10) {
i = previousCapacity - 5;
- vector.back() = -i;
+ vector.back() = -int(i);
vector.resize(i);
// It's still not the time to re-allocate
diff --git a/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro b/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro
new file mode 100644
index 0000000000..2cd4522f67
--- /dev/null
+++ b/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro
@@ -0,0 +1,4 @@
+CONFIG += testcase parallel_test
+TARGET = tst_qbytearraylist
+QT = core testlib
+SOURCES = tst_qbytearraylist.cpp
diff --git a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
new file mode 100644
index 0000000000..86a56abae3
--- /dev/null
+++ b/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 by Southwest Research Institute (R)
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <qbytearraylist.h>
+
+#include <qmetatype.h>
+
+Q_DECLARE_METATYPE(QByteArrayList)
+
+class tst_QByteArrayList : public QObject
+{
+ Q_OBJECT
+private slots:
+ void join() const;
+ void join_data() const;
+ void joinByteArray() const;
+ void joinByteArray_data() const;
+ void joinChar() const;
+ void joinChar_data() const;
+ void joinEmptiness() const;
+
+ void operator_plus() const;
+ void operator_plus_data() const;
+
+ void initializeList() const;
+};
+
+void tst_QByteArrayList::join() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(), expectedResult);
+}
+
+void tst_QByteArrayList::join_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << QByteArray();
+
+ QTest::newRow("data2") << QByteArrayList("one")
+ << QByteArray("one");
+
+ QTest::newRow("data3") << (QByteArrayList() << "a" << "b")
+ << QByteArray("ab");
+
+ QTest::newRow("data4") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray("abc");
+}
+
+void tst_QByteArrayList::joinByteArray() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(QByteArray, separator);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+}
+
+void tst_QByteArrayList::joinByteArray_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<QByteArray>("separator");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << QByteArray()
+ << QByteArray();
+
+ QTest::newRow("data2") << QByteArrayList()
+ << QByteArray("separator")
+ << QByteArray();
+
+ QTest::newRow("data3") << QByteArrayList("one")
+ << QByteArray("separator")
+ << QByteArray("one");
+
+ QTest::newRow("data4") << (QByteArrayList() << "a" << "b")
+ << QByteArray(" ")
+ << QByteArray("a b");
+
+ QTest::newRow("data5") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray(" ")
+ << QByteArray("a b c");
+
+ QTest::newRow("data6") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray()
+ << QByteArray("abc");
+
+ QTest::newRow("data7") << (QByteArrayList() << "a" << "b" << "c")
+ << QByteArray("") //empty
+ << QByteArray("abc");
+}
+
+void tst_QByteArrayList::joinChar() const
+{
+ QFETCH(QByteArrayList, input);
+ QFETCH(char, separator);
+ QFETCH(QByteArray, expectedResult);
+
+ QCOMPARE(input.join(separator), expectedResult);
+}
+
+void tst_QByteArrayList::joinChar_data() const
+{
+ QTest::addColumn<QByteArrayList>("input");
+ QTest::addColumn<char>("separator");
+ QTest::addColumn<QByteArray>("expectedResult");
+
+ QTest::newRow("data1") << QByteArrayList()
+ << ' '
+ << QByteArray();
+
+ QTest::newRow("data2") << (QByteArrayList() << "a" << "b")
+ << ' '
+ << QByteArray("a b");
+
+ QTest::newRow("data3") << (QByteArrayList() << "a" << "b" << "c")
+ << ' '
+ << QByteArray("a b c");
+}
+
+void tst_QByteArrayList::joinEmptiness() const
+{
+ QByteArrayList list;
+ QByteArray string = list.join(QByteArray());
+
+ QVERIFY(string.isEmpty());
+ QVERIFY(string.isNull());
+}
+
+void tst_QByteArrayList::operator_plus() const
+{
+ QFETCH(QByteArrayList, a1);
+ QFETCH(QByteArrayList, a2);
+ QFETCH(QByteArrayList, expectedResult);
+
+ QCOMPARE(a1+a2, expectedResult);
+ a1 += a2;
+ QCOMPARE(a1, expectedResult);
+}
+
+void tst_QByteArrayList::operator_plus_data() const
+{
+ QTest::addColumn<QByteArrayList>("a1");
+ QTest::addColumn<QByteArrayList>("a2");
+ QTest::addColumn<QByteArrayList>("expectedResult");
+
+ QTest::newRow("simpl") << ( QByteArrayList() << "a" )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "a" << "b" << "c" );
+
+ QTest::newRow("blank1") << QByteArrayList()
+ << QByteArrayList()
+ << QByteArrayList();
+
+ QTest::newRow("blank2") << ( QByteArrayList() )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "b" << "c" );
+
+ QTest::newRow("empty1") << ( QByteArrayList() << "" )
+ << ( QByteArrayList() << "b" << "c" )
+ << ( QByteArrayList() << "" << "b" << "c" );
+
+ QTest::newRow("empty2") << ( QByteArrayList() << "a" )
+ << ( QByteArrayList() << "" << "c" )
+ << ( QByteArrayList() << "a" << "" << "c" );
+}
+
+void tst_QByteArrayList::initializeList() const
+{
+#ifdef Q_COMPILER_INITIALIZER_LISTS
+ // C++11 support is required
+ QByteArrayList v1{QByteArray("hello"),"world",QByteArray("plop")};
+ QCOMPARE(v1, (QByteArrayList() << "hello" << "world" << "plop"));
+ QCOMPARE(v1, (QByteArrayList{"hello","world","plop"}));
+#endif
+}
+
+QTEST_APPLESS_MAIN(tst_QByteArrayList)
+#include "tst_qbytearraylist.moc"
diff --git a/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt b/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt
index 806021a5a1..2dc2bd7aa3 100644
--- a/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt
+++ b/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt
@@ -1,8 +1,8 @@
-# NormalizationTest-6.2.0.txt
-# Date: 2012-08-14, 17:54:58 GMT [MD]
+# NormalizationTest-6.3.0.txt
+# Date: 2012-12-20, 22:18:30 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
index 2ec85882b8..81409eb866 100644
--- a/tests/auto/corelib/tools/qchar/tst_qchar.cpp
+++ b/tests/auto/corelib/tools/qchar/tst_qchar.cpp
@@ -74,7 +74,7 @@ private slots:
void isSpaceSpecial();
void category();
void direction();
- void joining();
+ void joiningType();
void combiningClass();
void digitValue();
void mirroredChar();
@@ -450,6 +450,18 @@ void tst_QChar::category()
void tst_QChar::direction()
{
+ QVERIFY(QChar::direction(0x200E) == QChar::DirL);
+ QVERIFY(QChar::direction(0x200F) == QChar::DirR);
+ QVERIFY(QChar::direction(0x202A) == QChar::DirLRE);
+ QVERIFY(QChar::direction(0x202B) == QChar::DirRLE);
+ QVERIFY(QChar::direction(0x202C) == QChar::DirPDF);
+ QVERIFY(QChar::direction(0x202D) == QChar::DirLRO);
+ QVERIFY(QChar::direction(0x202E) == QChar::DirRLO);
+ QVERIFY(QChar::direction(0x2066) == QChar::DirLRI);
+ QVERIFY(QChar::direction(0x2067) == QChar::DirRLI);
+ QVERIFY(QChar::direction(0x2068) == QChar::DirFSI);
+ QVERIFY(QChar::direction(0x2069) == QChar::DirPDI);
+
QVERIFY(QChar('a').direction() == QChar::DirL);
QVERIFY(QChar('0').direction() == QChar::DirEN);
QVERIFY(QChar((ushort)0x627).direction() == QChar::DirAL);
@@ -471,27 +483,32 @@ void tst_QChar::direction()
QVERIFY(QChar::direction(0x2FA17u) == QChar::DirL);
}
-void tst_QChar::joining()
+void tst_QChar::joiningType()
{
- QVERIFY(QChar('a').joining() == QChar::OtherJoining);
- QVERIFY(QChar('0').joining() == QChar::OtherJoining);
- QVERIFY(QChar((ushort)0x627).joining() == QChar::Right);
- QVERIFY(QChar((ushort)0x5d0).joining() == QChar::OtherJoining);
+ QVERIFY(QChar('a').joiningType() == QChar::Joining_None);
+ QVERIFY(QChar('0').joiningType() == QChar::Joining_None);
+ QVERIFY(QChar((ushort)0x0627).joiningType() == QChar::Joining_Right);
+ QVERIFY(QChar((ushort)0x05d0).joiningType() == QChar::Joining_None);
+ QVERIFY(QChar((ushort)0x00ad).joiningType() == QChar::Joining_Transparent);
+
+ QVERIFY(QChar::joiningType((ushort)'a') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((ushort)'0') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((ushort)0x0627) == QChar::Joining_Right);
+ QVERIFY(QChar::joiningType((ushort)0x05d0) == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((ushort)0x00ad) == QChar::Joining_Transparent);
- QVERIFY(QChar::joining((ushort)'a') == QChar::OtherJoining);
- QVERIFY(QChar::joining((ushort)'0') == QChar::OtherJoining);
- QVERIFY(QChar::joining((ushort)0x627) == QChar::Right);
- QVERIFY(QChar::joining((ushort)0x5d0) == QChar::OtherJoining);
+ QVERIFY(QChar::joiningType((uint)'a') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((uint)'0') == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((uint)0x0627) == QChar::Joining_Right);
+ QVERIFY(QChar::joiningType((uint)0x05d0) == QChar::Joining_None);
+ QVERIFY(QChar::joiningType((uint)0x00ad) == QChar::Joining_Transparent);
- QVERIFY(QChar::joining((uint)'a') == QChar::OtherJoining);
- QVERIFY(QChar::joining((uint)'0') == QChar::OtherJoining);
- QVERIFY(QChar::joining((uint)0x627) == QChar::Right);
- QVERIFY(QChar::joining((uint)0x5d0) == QChar::OtherJoining);
+ QVERIFY(QChar::joiningType(0xE01DAu) == QChar::Joining_Transparent);
+ QVERIFY(QChar::joiningType(0xf0000u) == QChar::Joining_None);
+ QVERIFY(QChar::joiningType(0xE0030u) == QChar::Joining_Transparent);
+ QVERIFY(QChar::joiningType(0x2FA17u) == QChar::Joining_None);
- QVERIFY(QChar::joining(0xE01DAu) == QChar::OtherJoining);
- QVERIFY(QChar::joining(0xf0000u) == QChar::OtherJoining);
- QVERIFY(QChar::joining(0xE0030u) == QChar::OtherJoining);
- QVERIFY(QChar::joining(0x2FA17u) == QChar::OtherJoining);
+ QVERIFY(QChar::joiningType((uint)0xA872) == QChar::Joining_Left);
}
void tst_QChar::combiningClass()
@@ -605,6 +622,11 @@ void tst_QChar::unicodeVersion()
QVERIFY(QChar::unicodeVersion((uint)0x20ba) == QChar::Unicode_6_2);
QVERIFY(QChar::unicodeVersion((uint)0x20ba) == QChar::Unicode_6_2);
+ QVERIFY(QChar(0x061c).unicodeVersion() == QChar::Unicode_6_3);
+ QVERIFY(QChar::unicodeVersion((ushort)0x061c) == QChar::Unicode_6_3);
+ QVERIFY(QChar::unicodeVersion((uint)0x061c) == QChar::Unicode_6_3);
+ QVERIFY(QChar::unicodeVersion((uint)0x061c) == QChar::Unicode_6_3);
+
QVERIFY(QChar(0x09ff).unicodeVersion() == QChar::Unicode_Unassigned);
QVERIFY(QChar::unicodeVersion((ushort)0x09ff) == QChar::Unicode_Unassigned);
QVERIFY(QChar::unicodeVersion((uint)0x09ff) == QChar::Unicode_Unassigned);
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
index 7d65309cb7..ce30710f7f 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
@@ -565,6 +565,9 @@ void tst_QCommandLineParser::testHelpOption()
void tst_QCommandLineParser::testQuoteEscaping()
{
+#ifdef QT_NO_PROCESS
+ QSKIP("This test requires QProcess support");
+#else
QCoreApplication app(empty_argc, empty_argv);
QProcess process;
process.start("testhelper/qcommandlineparser_test_helper", QStringList() <<
@@ -581,6 +584,7 @@ void tst_QCommandLineParser::testQuoteEscaping()
QVERIFY2(output.contains("KEY1=\"VALUE1\""), qPrintable(output));
QVERIFY2(output.contains("QTBUG-15379=C:\\path\\'file.ext"), qPrintable(output));
QVERIFY2(output.contains("QTBUG-30628=C:\\temp\\'file'.ext"), qPrintable(output));
+#endif // !QT_NO_PROCESS
}
QTEST_APPLESS_MAIN(tst_QCommandLineParser)
diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
index 866f68c99c..bda5fc707a 100644
--- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp
@@ -49,6 +49,9 @@
#ifdef Q_OS_WIN
# include <qt_windows.h>
+# if defined(Q_OS_WINRT)
+# define tzset()
+# endif
#endif
class tst_QDateTime : public QObject
@@ -213,7 +216,7 @@ void tst_QDateTime::init()
{
#if defined(Q_OS_WINCE)
SetUserDefaultLCID(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
-#elif defined(Q_OS_WIN)
+#elif defined(Q_OS_WIN32)
SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
#endif
}
@@ -1626,7 +1629,8 @@ void tst_QDateTime::operator_eqeq_data()
QTest::newRow("data10") << dateTime3 << dateTime3c << true << false;
QTest::newRow("data11") << dateTime3 << dateTime3d << true << false;
QTest::newRow("data12") << dateTime3c << dateTime3d << true << false;
- QTest::newRow("data13") << dateTime3 << dateTime3e << false << false;
+ QTest::newRow("data13") << dateTime3 << dateTime3e
+ << (localTimeType == LocalTimeIsUtc) << false;
QTest::newRow("invalid == invalid") << invalidDateTime() << invalidDateTime() << true << false;
QTest::newRow("invalid == valid #1") << invalidDateTime() << dateTime1 << false << false;
diff --git a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
index 3348b49110..3f46b92ec9 100644
--- a/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
+++ b/tests/auto/corelib/tools/qeasingcurve/tst_qeasingcurve.cpp
@@ -756,7 +756,7 @@ void tst_QEasingCurve::testCbrtDouble()
void tst_QEasingCurve::testCbrtFloat()
{
- const float errorBound = 0.0005;
+ const float errorBound = 0.0005f;
for (int i = 0; i < 100000; i++) {
float f = float(i) / 1000.0f;
diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
index af1c7aed15..ddb72a3c32 100644
--- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp
+++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp
@@ -64,6 +64,7 @@ private slots:
void rehash_isnt_quadratic();
void dont_need_default_constructor();
void qhash();
+ void fp_qhash_of_zero_is_zero();
void qmultihash_specific();
void compare();
@@ -1043,6 +1044,20 @@ void tst_QHash::qhash()
}
}
+void tst_QHash::fp_qhash_of_zero_is_zero()
+{
+ QCOMPARE(qHash(-0.0f), 0U);
+ QCOMPARE(qHash( 0.0f), 0U);
+
+ QCOMPARE(qHash(-0.0 ), 0U);
+ QCOMPARE(qHash( 0.0 ), 0U);
+
+#ifndef Q_OS_DARWIN
+ QCOMPARE(qHash(-0.0L), 0U);
+ QCOMPARE(qHash( 0.0L), 0U);
+#endif
+}
+
void tst_QHash::qmultihash_specific()
{
QMultiHash<int, int> hash1;
diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/tools/qlocale/test/test.pro
index 66a968b7c3..df12d35a09 100644
--- a/tests/auto/corelib/tools/qlocale/test/test.pro
+++ b/tests/auto/corelib/tools/qlocale/test/test.pro
@@ -16,6 +16,5 @@ win32 {
TEST_HELPER_INSTALLS = ../syslocaleapp/syslocaleapp
-win32:CONFIG+= insignificant_test # QTBUG-25284
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
blackberry:LIBS += -lpps
diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
index 028cea3d62..211fbca330 100644
--- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
+++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp
@@ -133,7 +133,7 @@ public:
private slots:
void initTestCase();
void cleanupTestCase();
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void windowsDefaultLocale();
#endif
#ifdef Q_OS_MAC
@@ -1172,9 +1172,9 @@ void tst_QLocale::formatDateTime_data()
QTest::newRow("5no_NO") << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13))
<< "dd/MM/yyy z" << "01/01/74y 0";
QTest::newRow("6no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "ddd/MMM/yy AP" << "man./des./74 PM";
+ << "ddd/MMM/yy AP" << "man./des./74 P.M.";
QTest::newRow("7no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
- << "dddd/MMMM/y apa" << "mandag/desember/y pmpm";
+ << "dddd/MMMM/y apa" << "mandag/desember/y p.m.p.m.";
QTest::newRow("8no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13))
<< "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13";
QTest::newRow("9no_NO") << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13))
@@ -1472,7 +1472,7 @@ void tst_QLocale::macDefaultLocale()
}
#endif // Q_OS_MAC
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
#include <qt_windows.h>
static QString getWinLocaleInfo(LCTYPE type)
@@ -1501,6 +1501,16 @@ static void setWinLocaleInfo(LCTYPE type, const QString &value)
SetLocaleInfo(id, type, reinterpret_cast<const wchar_t*>(value.utf16()));
}
+#ifndef LOCALE_SSHORTTIME
+# define LOCALE_SSHORTTIME 0x00000079
+#endif
+
+static inline LCTYPE shortTimeType()
+{
+ return (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7 ?
+ LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
+}
+
class RestoreLocaleHelper {
public:
RestoreLocaleHelper() {
@@ -1508,7 +1518,7 @@ public:
m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND);
m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE);
m_ldate = getWinLocaleInfo(LOCALE_SLONGDATE);
- m_time = getWinLocaleInfo(LOCALE_STIMEFORMAT);
+ m_time = getWinLocaleInfo(shortTimeType());
}
~RestoreLocaleHelper() {
@@ -1517,7 +1527,7 @@ public:
setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand);
setWinLocaleInfo(LOCALE_SSHORTDATE, m_sdate);
setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate);
- setWinLocaleInfo(LOCALE_STIMEFORMAT, m_time);
+ setWinLocaleInfo(shortTimeType(), m_time);
}
QString m_decimal, m_thousand, m_sdate, m_ldate, m_time;
@@ -1526,42 +1536,51 @@ public:
#endif // Q_OS_WIN
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+
void tst_QLocale::windowsDefaultLocale()
{
RestoreLocaleHelper systemLocale;
+ const bool win7OrLater = (QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion();
// set weird system defaults and make sure we're using them
setWinLocaleInfo(LOCALE_SDECIMAL, QLatin1String("@"));
setWinLocaleInfo(LOCALE_STHOUSAND, QLatin1String("?"));
- setWinLocaleInfo(LOCALE_SSHORTDATE, QLatin1String("d*M*yyyy"));
- setWinLocaleInfo(LOCALE_SLONGDATE, QLatin1String("d@M@yyyy"));
- setWinLocaleInfo(LOCALE_STIMEFORMAT, QLatin1String("h^m^s"));
+ const QString shortDateFormat = QStringLiteral("d*M*yyyy");
+ setWinLocaleInfo(LOCALE_SSHORTDATE, shortDateFormat);
+ const QString longDateFormat = QStringLiteral("d@M@yyyy");
+ setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat);
+ const QString shortTimeFormat = QStringLiteral("h^m^s");
+ setWinLocaleInfo(shortTimeType(), shortTimeFormat);
QLocale locale = QLocale::system();
// make sure we are seeing the system's format strings
QCOMPARE(locale.decimalPoint(), QChar('@'));
QCOMPARE(locale.groupSeparator(), QChar('?'));
- QCOMPARE(locale.dateFormat(QLocale::ShortFormat), QString("d*M*yyyy"));
- QCOMPARE(locale.dateFormat(QLocale::LongFormat), QString("d@M@yyyy"));
- QCOMPARE(locale.timeFormat(QLocale::ShortFormat), QString("h^m^s"));
- QCOMPARE(locale.timeFormat(QLocale::LongFormat), QString("h^m^s"));
- QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), QString("d*M*yyyy h^m^s"));
- QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), QString("d@M@yyyy h^m^s"));
+ QCOMPARE(locale.dateFormat(QLocale::ShortFormat), shortDateFormat);
+ QCOMPARE(locale.dateFormat(QLocale::LongFormat), longDateFormat);
+ QCOMPARE(locale.timeFormat(QLocale::ShortFormat), shortTimeFormat);
+ QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), shortDateFormat + QLatin1Char(' ') + shortTimeFormat);
+ const QString expectedLongDateTimeFormat = longDateFormat + QLatin1Char(' ')
+ + (win7OrLater ? QStringLiteral("h:mm:ss AP") : shortTimeFormat);
+ QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat);
// make sure we are using the system to parse them
QCOMPARE(locale.toString(1234.56), QString("1?234@56"));
QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat), QString("1*12*1974"));
QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat), locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat));
QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::LongFormat), QString("1@12@1974"));
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), QString("1^2^3"));
+ const QString expectedFormattedShortTimeSeconds = QStringLiteral("1^2^3");
+ const QString expectedFormattedShortTime = win7OrLater ? QStringLiteral("1^2") : expectedFormattedShortTimeSeconds;
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime);
QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat), locale.toString(QTime(1,2,3), QLocale::ShortFormat));
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), QString("1^2^3"));
+ const QString expectedFormattedLongTime = win7OrLater ? QStringLiteral("1:02:03 AM") : expectedFormattedShortTimeSeconds;
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat),
- QString("1*12*1974 1^2^3"));
+ QStringLiteral("1*12*1974 ") + expectedFormattedShortTime);
QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::NarrowFormat),
locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat));
QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat),
- QString("1@12@1974 1^2^3"));
- QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), QString("1^2^3"));
+ QStringLiteral("1@12@1974 ") + expectedFormattedLongTime);
+ QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime);
}
#endif // #ifdef Q_OS_WIN
@@ -1864,8 +1883,8 @@ void tst_QLocale::ampm()
QCOMPARE(id.pmText(), QLatin1String("PM"));
QLocale ta("ta_LK");
- QCOMPARE(ta.amText(), QLatin1String("AM"));
- QCOMPARE(ta.pmText(), QLatin1String("PM"));
+ QCOMPARE(ta.amText(), QString::fromUtf8("முற்பகல்"));
+ QCOMPARE(ta.pmText(), QString::fromUtf8("பிற்பகல்"));
}
void tst_QLocale::dateFormat()
@@ -1897,9 +1916,9 @@ void tst_QLocale::timeFormat()
QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat));
const QLocale no("no_NO");
- QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm"));
- QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm"));
- QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("'kl'. HH:mm:ss t"));
+ QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH.mm"));
+ QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
+ QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t"));
const QLocale id("id_ID");
QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm"));
@@ -1921,9 +1940,9 @@ void tst_QLocale::dateTimeFormat()
QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat));
const QLocale no("no_NO");
- QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yy HH:mm"));
- QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yy HH:mm"));
- QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy 'kl'. HH:mm:ss t"));
+ QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yy HH.mm"));
+ QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yy HH.mm"));
+ QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH.mm.ss t"));
}
void tst_QLocale::monthName()
@@ -2001,9 +2020,9 @@ void tst_QLocale::currency()
const QLocale en_US("en_US");
QCOMPARE(en_US.toCurrencyString(qulonglong(1234)), QString("$1,234"));
- QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("($1,234)"));
+ QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("$-1,234"));
QCOMPARE(en_US.toCurrencyString(double(1234.56)), QString("$1,234.56"));
- QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("($1,234.56)"));
+ QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("$-1,234.56"));
const QLocale ru_RU("ru_RU");
QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)), QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xd1\x80\xd1\x83\xd0\xb1."));
diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
index 12fe5259d9..629a095f9d 100644
--- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp
+++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp
@@ -223,6 +223,8 @@ private slots:
void split_regexp();
void fromUtf16_data();
void fromUtf16();
+ void fromUtf16_char16_data();
+ void fromUtf16_char16();
void latin1String();
void nanAndInf();
void compare_data();
@@ -1440,6 +1442,8 @@ void tst_QString::contains()
QVERIFY(a.contains('F',Qt::CaseInsensitive));
QVERIFY(a.contains("FG"));
QVERIFY(a.contains("FG",Qt::CaseInsensitive));
+ QVERIFY(a.contains(QLatin1String("FG")));
+ QVERIFY(a.contains(QLatin1String("fg"),Qt::CaseInsensitive));
QVERIFY(a.contains( QString(), Qt::CaseInsensitive));
QVERIFY(a.contains( "", Qt::CaseInsensitive));
QVERIFY(a.contains(QRegExp("[FG][HI]")));
@@ -3880,6 +3884,14 @@ void tst_QString::toLatin1Roundtrip()
// and back:
QCOMPARE(QString::fromLatin1(latin1, latin1.length()).length(), unicodedst.length());
QCOMPARE(QString::fromLatin1(latin1, latin1.length()), unicodedst);
+
+ // try the rvalue version of toLatin1()
+ QString s = unicodesrc;
+ QCOMPARE(qMove(s).toLatin1(), latin1);
+
+ // and verify that the moved-from object can still be used
+ s = "foo";
+ s.clear();
}
void tst_QString::stringRef_toLatin1Roundtrip_data()
@@ -3958,14 +3970,15 @@ void tst_QString::fromAscii()
void tst_QString::fromUcs4()
{
+ const uint *null = 0;
QString s;
- s = QString::fromUcs4( 0 );
+ s = QString::fromUcs4( null );
QVERIFY( s.isNull() );
QCOMPARE( s.size(), 0 );
- s = QString::fromUcs4( 0, 0 );
+ s = QString::fromUcs4( null, 0 );
QVERIFY( s.isNull() );
QCOMPARE( s.size(), 0 );
- s = QString::fromUcs4( 0, 5 );
+ s = QString::fromUcs4( null, 5 );
QVERIFY( s.isNull() );
QCOMPARE( s.size(), 0 );
@@ -3986,20 +3999,98 @@ void tst_QString::fromUcs4()
s = QString::fromUcs4( &smp, 1 );
QVERIFY( !s.isNull() );
QCOMPARE( s.size(), 2 );
+
+#ifdef Q_COMPILER_UNICODE_STRINGS
+ static const char32_t str1[] = U"Hello Unicode World";
+ s = QString::fromUcs4(str1, sizeof(str1) / sizeof(str1[0]) - 1);
+ QCOMPARE(s, QString("Hello Unicode World"));
+
+ s = QString::fromUcs4(str1);
+ QCOMPARE(s, QString("Hello Unicode World"));
+
+ s = QString::fromUcs4(str1, 5);
+ QCOMPARE(s, QString("Hello"));
+
+ s = QString::fromUcs4(U"\u221212\U000020AC\U00010000");
+ QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200"));
+#endif
}
void tst_QString::toUcs4()
{
QString s;
+ QVector<uint> ucs4;
QCOMPARE( s.toUcs4().size(), 0 );
- QChar bmp = QLatin1Char('a');
+ static const QChar bmp = QLatin1Char('a');
s = QString(&bmp, 1);
- QCOMPARE( s.toUcs4().size(), 1 );
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+
+#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
+
+ static const QChar smp[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
+ s = QSTRING_FROM_QCHARARRAY(smp);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0x10000u );
+
+ static const QChar smp2[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000), QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
+ s = QSTRING_FROM_QCHARARRAY(smp2);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 2 );
+ QCOMPARE( ucs4.at(0), 0x10000u );
+ QCOMPARE( ucs4.at(1), 0x10000u );
+
+ static const QChar invalid_01[] = { QChar(0xd800) };
+ s = QSTRING_FROM_QCHARARRAY(invalid_01);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0xFFFDu );
+
+ static const QChar invalid_02[] = { QChar(0xdc00) };
+ s = QSTRING_FROM_QCHARARRAY(invalid_02);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 1 );
+ QCOMPARE( ucs4.at(0), 0xFFFDu );
+
+ static const QChar invalid_03[] = { QLatin1Char('a'), QChar(0xd800), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_03);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 3 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0x0062u );
+
+ static const QChar invalid_04[] = { QLatin1Char('a'), QChar(0xdc00), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_04);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 3 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0x0062u );
+
+ static const QChar invalid_05[] = { QLatin1Char('a'), QChar(0xd800), QChar(0xd800), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_05);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 4 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0xFFFDu );
+ QCOMPARE( ucs4.at(3), 0x0062u );
+
+ static const QChar invalid_06[] = { QLatin1Char('a'), QChar(0xdc00), QChar(0xdc00), QLatin1Char('b') };
+ s = QSTRING_FROM_QCHARARRAY(invalid_06);
+ ucs4 = s.toUcs4();
+ QCOMPARE( ucs4.size(), 4 );
+ QCOMPARE( ucs4.at(0), 0x0061u );
+ QCOMPARE( ucs4.at(1), 0xFFFDu );
+ QCOMPARE( ucs4.at(2), 0xFFFDu );
+ QCOMPARE( ucs4.at(3), 0x0062u );
+
+#undef QSTRING_FROM_QCHARARRAY
- QChar smp[] = { QChar::highSurrogate(0x10000), QChar::lowSurrogate(0x10000) };
- s = QString(smp, 2);
- QCOMPARE( s.toUcs4().size(), 1 );
}
void tst_QString::arg()
@@ -4981,6 +5072,25 @@ void tst_QString::fromUtf16()
QCOMPARE(QString::fromUtf16(ucs2.utf16(), len), res);
}
+void tst_QString::fromUtf16_char16_data()
+{
+#ifdef Q_COMPILER_UNICODE_STRINGS
+ fromUtf16_data();
+#else
+ QSKIP("Compiler does not support C++11 unicode strings");
+#endif
+}
+
+void tst_QString::fromUtf16_char16()
+{
+#ifdef Q_COMPILER_UNICODE_STRINGS
+ QFETCH(QString, ucs2);
+ QFETCH(QString, res);
+ QFETCH(int, len);
+
+ QCOMPARE(QString::fromUtf16(reinterpret_cast<const char16_t *>(ucs2.utf16()), len), res);
+#endif
+}
void tst_QString::latin1String()
{
diff --git a/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro b/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro
new file mode 100644
index 0000000000..e5e625d520
--- /dev/null
+++ b/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase parallel_test
+TARGET = tst_qstringiterator
+QT = core core-private testlib
+SOURCES = tst_qstringiterator.cpp
+
diff --git a/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp b/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp
new file mode 100644
index 0000000000..d06d052676
--- /dev/null
+++ b/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp
@@ -0,0 +1,675 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtCore/QString>
+#include <private/qstringiterator_p.h>
+
+class tst_QStringIterator : public QObject
+{
+ Q_OBJECT
+private slots:
+ void sweep_data();
+ void sweep();
+
+ void position();
+};
+
+void tst_QStringIterator::sweep_data()
+{
+ QTest::addColumn<QString>("string");
+ QTest::addColumn<bool>("valid");
+ QTest::addColumn<int>("count");
+
+ QTest::newRow("sweep_00") << QString::fromUtf8("", 0) << true << 0;
+ QTest::newRow("sweep_01") << QString::fromUtf8("a", 1) << true << 1;
+ QTest::newRow("sweep_02") << QString::fromUtf8("a string", 8) << true << 8;
+ QTest::newRow("sweep_03") << QString::fromUtf8("\xc3\xa0\xc3\xa8\xc3\xac\xc3\xb2\xc3\xb9", 10) << true << 5;
+ QTest::newRow("sweep_04") << QString::fromUtf8("\xc3\x9f\xe2\x80\x94\xc2\xa1", 7) << true << 3;
+ QTest::newRow("sweep_05") << QString::fromUtf8("\xe6\xb0\xb4\xe6\xb0\xb5\xe6\xb0\xb6\xe6\xb0\xb7\xe6\xb0\xb8\xe6\xb0\xb9", 18) << true << 6;
+ QTest::newRow("sweep_06") << QString::fromUtf8("\xf0\x9f\x98\x81\xf0\x9f\x98\x82\x61\x62\x63\xf0\x9f\x98\x83\xc4\x91\xc3\xa8\xef\xac\x80\xf0\x9f\x98\x84\xf0\x9f\x98\x85", 30) << true << 11;
+ QTest::newRow("sweep_07") << QString::fromUtf8("\xf0\x9f\x82\xaa\xf0\x9f\x82\xab\xf0\x9f\x82\xad\xf0\x9f\x82\xae\xf0\x9f\x82\xa1\x20\x52\x4f\x59\x41\x4c\x20\x46\x4c\x55\x53\x48\x20\x4f\x46\x20\x53\x50\x41\x44\x45\x53", 42) << true << 27;
+ QTest::newRow("sweep_08") << QString::fromUtf8("abc\0def", 7) << true << 7;
+ QTest::newRow("sweep_09") << QString::fromUtf8("\xc3\xa0\xce\xb2\xc3\xa7\xf0\x9f\x80\xb9\xf0\x9f\x80\xb8\x00\xf0\x9f\x80\xb1\x00\xf0\x9f\x80\xb3\xf0\x9f\x81\x85\xe1\xb8\x8a\xc4\x99\xc6\x92", 35) << true << 13;
+
+ QTest::newRow("sweep_invalid_00") << QString(QChar(0xd800)) << false << 1;
+ QTest::newRow("sweep_invalid_01") << QString(QChar(0xdc00)) << false << 1;
+ QTest::newRow("sweep_invalid_02") << QString(QChar(0xdbff)) << false << 1;
+ QTest::newRow("sweep_invalid_03") << QString(QChar(0xdfff)) << false << 1;
+
+#define QSTRING_FROM_QCHARARRAY(x) (QString((x), sizeof(x)/sizeof((x)[0])))
+
+ static const QChar invalid_04[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800)
+ };
+ QTest::newRow("sweep_invalid_04") << QSTRING_FROM_QCHARARRAY(invalid_04) << false << 8;
+
+ static const QChar invalid_05[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_05") << QSTRING_FROM_QCHARARRAY(invalid_05) << false << 9;
+
+ static const QChar invalid_06[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00)
+ };
+ QTest::newRow("sweep_invalid_06") << QSTRING_FROM_QCHARARRAY(invalid_06) << false << 8;
+
+ static const QChar invalid_07[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_07") << QSTRING_FROM_QCHARARRAY(invalid_07) << false << 9;
+
+ static const QChar invalid_08[] = {
+ QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_08") << QSTRING_FROM_QCHARARRAY(invalid_08) << false << 8;
+
+ static const QChar invalid_09[] = {
+ QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_09") << QSTRING_FROM_QCHARARRAY(invalid_09) << false << 8;
+
+ static const QChar invalid_10[] = {
+ QChar(0xd800), QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_10") << QSTRING_FROM_QCHARARRAY(invalid_10) << false << 9;
+
+ static const QChar invalid_11[] = {
+ QChar(0xdc00), QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_11") << QSTRING_FROM_QCHARARRAY(invalid_11) << false << 9;
+
+ static const QChar invalid_12[] = {
+ QChar(0xdc00), QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_12") << QSTRING_FROM_QCHARARRAY(invalid_12) << false << 9;
+
+ static const QChar invalid_13[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800)
+ };
+ QTest::newRow("sweep_invalid_13") << QSTRING_FROM_QCHARARRAY(invalid_13) << false << 9;
+
+ static const QChar invalid_14[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xd800), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_14") << QSTRING_FROM_QCHARARRAY(invalid_14) << false << 10;
+
+ static const QChar invalid_15[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00)
+ };
+ QTest::newRow("sweep_invalid_15") << QSTRING_FROM_QCHARARRAY(invalid_15) << false << 9;
+
+ static const QChar invalid_16[] = {
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d'), QChar(0xdc00), QLatin1Char('x')
+ };
+ QTest::newRow("sweep_invalid_16") << QSTRING_FROM_QCHARARRAY(invalid_16) << false << 10;
+
+ static const QChar invalid_17[] = {
+ QChar(0xd800),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_17") << QSTRING_FROM_QCHARARRAY(invalid_17) << false << 9;
+
+ static const QChar invalid_18[] = {
+ QChar(0xdc00),
+ QLatin1Char('i'), QLatin1Char('n'), QLatin1Char('v'),
+ QChar(0xd800), QChar(0xdf00), // U+10300 OLD ITALIC LETTER A
+ QLatin1Char('a'), QLatin1Char('l'), QLatin1Char('i'),
+ QLatin1Char('d')
+ };
+ QTest::newRow("sweep_invalid_18") << QSTRING_FROM_QCHARARRAY(invalid_18) << false << 9;
+
+#undef QSTRING_FROM_QCHARARRAY
+}
+
+void tst_QStringIterator::sweep()
+{
+ QFETCH(QString, string);
+ QFETCH(bool, valid);
+
+ QStringIterator i(string);
+ int count = 0;
+ QString rebuiltString;
+
+ while (i.hasNext()) {
+ const uint peekedCodePoint = i.peekNext(~0u);
+ const uint codePoint = i.next(~0u);
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ if (codePoint == ~0u)
+ rebuiltString += *(i.position() - 1);
+ else
+ rebuiltString += QString::fromUcs4(&codePoint, 1);
+
+ ++count;
+ }
+
+ QTEST(count, "count");
+ QTEST(rebuiltString, "string");
+ rebuiltString.clear();
+
+ while (i.hasPrevious()) {
+ const uint peekedCodePoint = i.peekPrevious(~0u);
+ const uint codePoint = i.previous(~0u);
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ while (i.hasNext()) {
+ i.advance();
+ ++count;
+ }
+
+ QTEST(count, "count");
+
+ while (i.hasPrevious()) {
+ i.recede();
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ if (valid) {
+ while (i.hasNext()) {
+ const uint peekedCodePoint = i.peekNextUnchecked();
+ const uint codePoint = i.nextUnchecked();
+
+ QVERIFY(peekedCodePoint == codePoint);
+ QVERIFY(codePoint <= 0x10FFFFu);
+ rebuiltString += QString::fromUcs4(&codePoint, 1);
+ ++count;
+ }
+
+ QTEST(count, "count");
+ QTEST(rebuiltString, "string");
+
+ while (i.hasPrevious()) {
+ const uint peekedCodePoint = i.peekPreviousUnchecked();
+ const uint codePoint = i.previousUnchecked();
+
+ QVERIFY(peekedCodePoint == codePoint);
+
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+
+ while (i.hasNext()) {
+ i.advanceUnchecked();
+ ++count;
+ }
+
+ QTEST(count, "count");
+
+ while (i.hasPrevious()) {
+ i.recedeUnchecked();
+ --count;
+ }
+
+ QCOMPARE(count, 0);
+ }
+}
+
+void tst_QStringIterator::position()
+{
+ static const QChar stringData[] =
+ {
+ // codeunit count: 0
+ QLatin1Char('a'), QLatin1Char('b'), QLatin1Char('c'),
+ // codeunit count: 3
+ QChar(0x00A9), // U+00A9 COPYRIGHT SIGN
+ // codeunit count: 4
+ QChar(0x00AE), // U+00AE REGISTERED SIGN
+ // codeunit count: 5
+ QLatin1Char('d'), QLatin1Char('e'), QLatin1Char('f'),
+ // codeunit count: 8
+ QLatin1Char('\0'),
+ // codeunit count: 9
+ QLatin1Char('g'), QLatin1Char('h'), QLatin1Char('i'),
+ // codeunit count: 12
+ QChar(0xD834), QChar(0xDD1E), // U+1D11E MUSICAL SYMBOL G CLEF
+ // codeunit count: 14
+ QChar(0xD834), QChar(0xDD21), // U+1D121 MUSICAL SYMBOL C CLEF
+ // codeunit count: 16
+ QLatin1Char('j'),
+ // codeunit count: 17
+ QChar(0xD800), // stray high surrogate
+ // codeunit count: 18
+ QLatin1Char('k'),
+ // codeunit count: 19
+ QChar(0xDC00), // stray low surrogate
+ // codeunit count: 20
+ QLatin1Char('l'),
+ // codeunit count: 21
+ QChar(0xD800), QChar(0xD800), // two high surrogates
+ // codeunit count: 23
+ QLatin1Char('m'),
+ // codeunit count: 24
+ QChar(0xDC00), QChar(0xDC00), // two low surrogates
+ // codeunit count: 26
+ QLatin1Char('n'),
+ // codeunit count: 27
+ QChar(0xD800), QChar(0xD800), QChar(0xDC00), // stray high surrogate followed by valid pair
+ // codeunit count: 30
+ QLatin1Char('o'),
+ // codeunit count: 31
+ QChar(0xDC00), QChar(0xD800), QChar(0xDC00), // stray low surrogate followed by valid pair
+ // codeunit count: 34
+ QLatin1Char('p')
+ // codeunit count: 35
+ };
+
+ const QString string(stringData, sizeof(stringData) / sizeof(stringData[0]));
+ QStringIterator i(string);
+
+ QCOMPARE(i.position(), string.constBegin());
+ QVERIFY(i.hasNext());
+ QVERIFY(!i.hasPrevious());
+
+ i.setPosition(string.constEnd());
+ QCOMPARE(i.position(), string.constEnd());
+ QVERIFY(!i.hasNext());
+ QVERIFY(i.hasPrevious());
+
+#define QCHAR_UNICODE_VALUE(x) ((uint)(QChar(x).unicode()))
+
+ const QString::const_iterator begin = string.constBegin();
+ i.setPosition(begin);
+ QCOMPARE(i.position(), begin);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('a')));
+
+ QCOMPARE(i.position(), begin + 1);
+
+ i.setPosition(begin + 2);
+ QCOMPARE(i.position(), begin + 2);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('c')));
+
+ QCOMPARE(i.position(), begin + 3);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00A9));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00A9));
+
+ QCOMPARE(i.position(), begin + 4);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(0x00AE));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(0x00AE));
+
+ QCOMPARE(i.position(), begin + 5);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00AE));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00AE));
+
+ QCOMPARE(i.position(), begin + 4);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(0x00A9));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(0x00A9));
+
+ QCOMPARE(i.position(), begin + 3);
+
+ i.setPosition(begin + 8);
+ QCOMPARE(i.position(), begin + 8);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+
+ QCOMPARE(i.position(), begin + 9);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+
+ QCOMPARE(i.position(), begin + 10);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('g')));
+
+ QCOMPARE(i.position(), begin + 9);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('\0')));
+
+ QCOMPARE(i.position(), begin + 8);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('f')));
+
+ QCOMPARE(i.position(), begin + 7);
+
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+
+ QCOMPARE(i.position(), begin + 12);
+ QCOMPARE(i.peekNext(), 0x1D11Eu);
+ QCOMPARE(i.next(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekNext(), 0x1D121u);
+ QCOMPARE(i.next(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekPrevious(), 0x1D121u);
+ QCOMPARE(i.previous(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekPrevious(), 0x1D11Eu);
+ QCOMPARE(i.previous(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 12);
+
+
+ i.setPosition(begin + 13);
+ QCOMPARE(i.position(), begin + 13);
+
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekNext(), 0x1D121u);
+ QCOMPARE(i.next(), 0x1D121u);
+
+ QCOMPARE(i.position(), begin + 16);
+
+
+ i.setPosition(begin + 15);
+ QCOMPARE(i.position(), begin + 15);
+
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 14);
+ QCOMPARE(i.peekPrevious(), 0x1D11Eu);
+ QCOMPARE(i.previous(), 0x1D11Eu);
+
+ QCOMPARE(i.position(), begin + 12);
+
+ i.advanceUnchecked();
+ i.advanceUnchecked();
+
+ QCOMPARE(i.position(), begin + 16);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 18);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+
+ QCOMPARE(i.position(), begin + 19);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 20);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+
+ QCOMPARE(i.position(), begin + 21);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 22);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 23);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+
+ QCOMPARE(i.position(), begin + 24);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 25);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 26);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+
+ QCOMPARE(i.position(), begin + 27);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 28);
+ QCOMPARE(i.peekNext(), 0x10000u);
+ QCOMPARE(i.next(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 32);
+ QCOMPARE(i.peekNext(), 0x10000u);
+ QCOMPARE(i.next(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QVERIFY(!i.hasNext());
+
+ QCOMPARE(i.position(), begin + 35);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 32);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 28);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 27);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('n')));
+
+ QCOMPARE(i.position(), begin + 26);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 25);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 24);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('m')));
+
+ QCOMPARE(i.position(), begin + 23);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 22);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 21);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('l')));
+
+ QCOMPARE(i.position(), begin + 20);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 19);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('k')));
+
+ QCOMPARE(i.position(), begin + 18);
+ QCOMPARE(i.peekPrevious(), 0xFFFDu);
+ QCOMPARE(i.previous(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 17);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('j')));
+
+ i.setPosition(begin + 29);
+ QCOMPARE(i.position(), begin + 29);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 31);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('o')));
+
+ QCOMPARE(i.position(), begin + 30);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 28);
+
+ i.setPosition(begin + 33);
+ QCOMPARE(i.position(), begin + 33);
+ QCOMPARE(i.peekNext(), 0xFFFDu);
+ QCOMPARE(i.next(), 0xFFFDu);
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekNext(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.next(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 35);
+ QCOMPARE(i.peekPrevious(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+ QCOMPARE(i.previous(), QCHAR_UNICODE_VALUE(QLatin1Char('p')));
+
+ QCOMPARE(i.position(), begin + 34);
+ QCOMPARE(i.peekPrevious(), 0x10000u);
+ QCOMPARE(i.previous(), 0x10000u);
+
+ QCOMPARE(i.position(), begin + 32);
+
+
+ i.setPosition(begin + 16);
+ QCOMPARE(i.position(), begin + 16);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 12);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 8);
+
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ i.recedeUnchecked();
+ QCOMPARE(i.position(), begin + 2);
+
+#undef QCHAR_UNICODE_VALUE
+}
+
+QTEST_APPLESS_MAIN(tst_QStringIterator)
+
+#include "tst_qstringiterator.moc"
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt
index 90e15fed3e..88a98e7127 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt
+++ b/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt
@@ -1,8 +1,8 @@
-# GraphemeBreakTest-6.2.0.txt
-# Date: 2012-08-22, 12:41:15 GMT [MD]
+# GraphemeBreakTest-6.3.0.txt
+# Date: 2012-12-20, 22:18:29 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt
index ef6b44b559..339a43b7d2 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt
+++ b/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt
@@ -1,8 +1,8 @@
-# LineBreakTest-6.2.0.txt
-# Date: 2012-08-22, 12:41:17 GMT [MD]
+# LineBreakTest-6.3.0.txt
+# Date: 2012-12-20, 22:18:30 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
@@ -6214,7 +6214,7 @@
× 3067 ÷ 4F7F ÷ # × [0.3] HIRAGANA LETTER DE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4F7F (ID) ÷ [0.3]
× 3059 ÷ 308B ÷ # × [0.3] HIRAGANA LETTER SU (ID) ÷ [999.0] HIRAGANA LETTER RU (ID) ÷ [0.3]
× 306E ÷ 30D1 ÷ 30F3 ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] KATAKANA LETTER PA (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [0.3]
-× 3046 ÷ 3000 ÷ 3048 ÷ 3000 ÷ 304A × 300D ÷ # × [0.3] HIRAGANA LETTER U (ID) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] HIRAGANA LETTER E (ID) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] HIRAGANA LETTER O (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [0.3]
+× 3046 × 3000 ÷ 3048 × 3000 ÷ 304A × 300D ÷ # × [0.3] HIRAGANA LETTER U (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER E (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER O (ID) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [0.3]
× 308B × 0020 ÷ C740 ÷ C601 × 0020 ÷ 306B ÷ # × [0.3] HIRAGANA LETTER RU (ID) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE EUN (H3) ÷ [999.0] HANGUL SYLLABLE YEONG (H3) × [7.01] SPACE (SP) ÷ [18.0] HIRAGANA LETTER NI (ID) ÷ [0.3]
× 3057 × 3087 ÷ 3046 × 3002 ÷ # × [0.3] HIRAGANA LETTER SI (ID) × [21.03] HIRAGANA LETTER SMALL YO (CJ_NS) ÷ [999.0] HIRAGANA LETTER U (ID) × [13.02] IDEOGRAPHIC FULL STOP (CL) ÷ [0.3]
× 30E0 ÷ 306E ÷ 4E00 ÷ # × [0.3] KATAKANA LETTER MU (ID) ÷ [999.0] HIRAGANA LETTER NO (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-4E00 (ID) ÷ [0.3]
@@ -6226,15 +6226,15 @@
× 0061 × 002E ÷ 0032 × 0020 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [0.3]
× 0061 × 002E ÷ 0032 × 0020 ÷ 0915 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] DEVANAGARI LETTER KA (AL) ÷ [0.3]
× 0061 × 002E ÷ 0032 × 0020 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 ÷ 3000 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 ÷ 3000 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
-× 0061 × 002E ÷ 0032 ÷ 3000 ÷ 0033 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] DIGIT THREE (NU) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 672C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] CJK UNIFIED IDEOGRAPH-672C (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 307E ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER MA (ID) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 0033 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] DIGIT THREE (NU) ÷ [0.3]
× 0061 × 0062 × 002E × 0020 ÷ 0032 ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER B (AL) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] DIGIT TWO (NU) ÷ [0.3]
× 0041 × 002E ÷ 0031 × 0020 ÷ BABB ÷ # × [0.3] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT ONE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
× BD24 ÷ C5B4 × 002E × 0020 ÷ 0041 × 002E ÷ 0032 × 0020 ÷ BCFC ÷ # × [0.3] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE BOL (H3) ÷ [0.3]
× BD10 ÷ C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0033 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE BWA (H2) ÷ [999.0] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT THREE (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
× C694 × 002E × 0020 ÷ 0041 × 002E ÷ 0034 × 0020 ÷ BABB ÷ # × [0.3] HANGUL SYLLABLE YO (H2) × [13.02] FULL STOP (IS) × [7.01] SPACE (SP) ÷ [18.0] LATIN CAPITAL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT FOUR (NU) × [7.01] SPACE (SP) ÷ [18.0] HANGUL SYLLABLE MOS (H3) ÷ [0.3]
-× 0061 × 002E ÷ 0032 ÷ 3000 ÷ 300C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) ÷ [0.3]
+× 0061 × 002E ÷ 0032 × 3000 ÷ 300C ÷ # × [0.3] LATIN SMALL LETTER A (AL) × [13.02] FULL STOP (IS) ÷ [999.0] DIGIT TWO (NU) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] LEFT CORNER BRACKET (OP) ÷ [0.3]
× 306B ÷ 300C × 30D0 ÷ 0028 × 0062 × 0061 × 0029 × 300D ÷ 3084 ÷ 300C × 30B9 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER BA (ID) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] LATIN SMALL LETTER B (AL) × [28.0] LATIN SMALL LETTER A (AL) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER YA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER SU (ID) ÷ [0.3]
× 308B ÷ 300C × 0055 × 004B ÷ 30DD ÷ 30F3 ÷ 30C9 × 300D × FF09 × 3001 ÷ 30A8 ÷ # × [0.3] HIRAGANA LETTER RU (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] LATIN CAPITAL LETTER U (AL) × [28.0] LATIN CAPITAL LETTER K (AL) ÷ [999.0] KATAKANA LETTER PO (ID) ÷ [999.0] KATAKANA LETTER N (ID) ÷ [999.0] KATAKANA LETTER DO (ID) × [13.02] RIGHT CORNER BRACKET (CL) × [13.02] FULLWIDTH RIGHT PARENTHESIS (CL) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] KATAKANA LETTER E (ID) ÷ [0.3]
× 306F × 3001 ÷ 300C × 003D × 0072 × 0061 × 006E × 0064 × 0028 × 0029 × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER HA (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] EQUALS SIGN (AL) × [28.0] LATIN SMALL LETTER R (AL) × [28.0] LATIN SMALL LETTER A (AL) × [28.0] LATIN SMALL LETTER N (AL) × [28.0] LATIN SMALL LETTER D (AL) × [30.01] LEFT PARENTHESIS (OP) × [13.02] RIGHT PARENTHESIS (CP) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
@@ -6243,7 +6243,7 @@
× 3066 ÷ 300C × BD24 ÷ C5B4 × 003F × 300D ÷ 3068 ÷ # × [0.3] HIRAGANA LETTER TE (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE BWASS (H3) ÷ [999.0] HANGUL SYLLABLE EO (H2) × [13.01] QUESTION MARK (EX) × [13.02] RIGHT CORNER BRACKET (CL) ÷ [999.0] HIRAGANA LETTER TO (ID) ÷ [0.3]
× 306E ÷ 300C × 305D ÷ # × [0.3] HIRAGANA LETTER NO (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER SO (ID) ÷ [0.3]
× 306F ÷ 300C × 30A8 ÷ # × [0.3] HIRAGANA LETTER HA (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] KATAKANA LETTER E (ID) ÷ [0.3]
-× 4F8B × FF1A ÷ 300C × 3042 ÷ 3000 ÷ 3044 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER A (ID) ÷ [999.0] IDEOGRAPHIC SPACE (ID) ÷ [999.0] HIRAGANA LETTER I (ID) ÷ [0.3]
+× 4F8B × FF1A ÷ 300C × 3042 × 3000 ÷ 3044 ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-4F8B (ID) × [21.03] FULLWIDTH COLON (NS) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HIRAGANA LETTER A (ID) × [21.01] IDEOGRAPHIC SPACE (BA) ÷ [999.0] HIRAGANA LETTER I (ID) ÷ [0.3]
× 304F × 3001 ÷ 300C × D3C9 ÷ C591 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER KU (ID) × [13.02] IDEOGRAPHIC COMMA (CL) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE PYEONG (H3) ÷ [999.0] HANGUL SYLLABLE YANG (H3) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
× 306B ÷ 300C × C81C ÷ BAA9 ÷ 0028 × 984C ÷ 540D × 0029 ÷ C740 ÷ # × [0.3] HIRAGANA LETTER NI (ID) ÷ [999.0] LEFT CORNER BRACKET (OP) × [14.0] HANGUL SYLLABLE JE (H2) ÷ [999.0] HANGUL SYLLABLE MOG (H3) ÷ [999.0] LEFT PARENTHESIS (OP) × [14.0] CJK UNIFIED IDEOGRAPH-984C (ID) ÷ [999.0] CJK UNIFIED IDEOGRAPH-540D (ID) × [13.02] RIGHT PARENTHESIS (CP) ÷ [999.0] HANGUL SYLLABLE EUN (H3) ÷ [0.3]
× 5178 ÷ 300E × 30A6 × 30A3 ÷ 30AD ÷ # × [0.3] CJK UNIFIED IDEOGRAPH-5178 (ID) ÷ [999.0] LEFT WHITE CORNER BRACKET (OP) × [14.0] KATAKANA LETTER U (ID) × [21.03] KATAKANA LETTER SMALL I (CJ_NS) ÷ [999.0] KATAKANA LETTER KI (ID) ÷ [0.3]
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt
index c2f79f1c66..eeba36c0e5 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt
+++ b/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt
@@ -1,8 +1,8 @@
-# SentenceBreakTest-6.2.0.txt
-# Date: 2012-08-22, 12:41:18 GMT [MD]
+# SentenceBreakTest-6.3.0.txt
+# Date: 2012-12-20, 22:18:42 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt b/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt
index 864dbcef18..953ee2b861 100644
--- a/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt
+++ b/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt
@@ -1,8 +1,8 @@
-# WordBreakTest-6.2.0.txt
-# Date: 2012-08-22, 12:41:18 GMT [MD]
+# WordBreakTest-6.3.0.txt
+# Date: 2013-07-05, 14:09:03 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
@@ -36,14 +36,20 @@
÷ 0001 × 0308 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0001 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0001 × 0308 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0001 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0001 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0001 × 0308 ÷ 002E ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0001 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0001 × 0308 ÷ 0030 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0001 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0001 × 0308 ÷ 005F ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0001 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0001 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0001 × 0308 ÷ 05D0 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0001 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0022 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0001 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0001 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0001 × 0308 × 00AD ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0001 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -52,16 +58,16 @@
÷ 0001 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0001 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0001 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0001 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0001 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0001 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0001 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0001 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0001 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0001 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0001 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <START OF HEADING> (Other) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0001 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <START OF HEADING> (Other) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -82,14 +88,20 @@
÷ 000D ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000D ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000D ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000D ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 000D ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000D ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 000D ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000D ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000D ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000D ÷ 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000D ÷ 0308 × 00AD ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -98,16 +110,16 @@
÷ 000D ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000D ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000D ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000D ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000D ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000D ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000D ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000D ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000D ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -128,14 +140,20 @@
÷ 000A ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000A ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000A ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000A ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 000A ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000A ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 000A ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000A ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000A ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000A ÷ 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000A ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -144,16 +162,16 @@
÷ 000A ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000A ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000A ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -174,14 +192,20 @@
÷ 000B ÷ 0308 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000B ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMMA (MidNum) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 000B ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000B ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 002E ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 000B ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 0030 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 000B ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 005F ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 000B ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 000B ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 05D0 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 000B ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0022 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 000B ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000B ÷ 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000B ÷ 0308 × 00AD ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 000B ÷ 0300 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -190,16 +214,16 @@
÷ 000B ÷ 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000B ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 000B ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000B ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 000B ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 000B ÷ 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 000B ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000B ÷ 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 000B ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] <LINE TABULATION> (Newline) ÷ [3.1] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -220,14 +244,20 @@
÷ 3031 × 0308 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 3031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 3031 × 0308 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 3031 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 3031 × 0308 ÷ 002E ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 3031 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 3031 × 0308 ÷ 0030 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 3031 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 3031 × 0308 × 005F ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 3031 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 3031 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 3031 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 3031 × 0308 ÷ 05D0 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 3031 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0022 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 3031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 3031 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 3031 × 0308 × 00AD ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 3031 × 0300 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -236,16 +266,16 @@
÷ 3031 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 3031 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 3031 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 3031 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 3031 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 3031 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 3031 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 3031 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 3031 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 3031 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 3031 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 3031 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] VERTICAL KANA REPEAT MARK (Katakana) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -266,14 +296,20 @@
÷ 0041 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0041 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0041 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0041 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0041 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0041 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0041 × 0308 × 0030 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0041 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0041 × 0308 × 005F ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0041 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0041 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0041 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0041 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0041 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0041 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0041 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0041 × 0308 × 00AD ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0041 × 0300 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -282,16 +318,16 @@
÷ 0041 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0041 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0041 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0041 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0041 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0041 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0041 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0041 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0041 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0041 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0041 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0041 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0041 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN CAPITAL LETTER A (ALetter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -312,14 +348,20 @@
÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 003A ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 003A ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 003A ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 003A ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 003A ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 003A ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 003A ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 003A × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 003A × 0300 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -328,16 +370,16 @@
÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -358,14 +400,20 @@
÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 002C ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 002C ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 002C ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 002C ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 002C ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002C ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002C ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 002C × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 002C × 0300 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -374,66 +422,72 @@
÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 002C × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E × 0308 ÷ 0001 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 002E ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E × 0308 ÷ 000D ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 002E ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E × 0308 ÷ 000A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 002E ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002E × 0308 ÷ 000B ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 002E ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002E × 0308 ÷ 3031 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 002E ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0041 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 002E ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002E × 0308 ÷ 002E ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 002E ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E × 0308 ÷ 0030 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 002E ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002E × 0308 ÷ 005F ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 002E ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 002E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 002E ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002E × 0308 ÷ 05D0 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 002E ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0022 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 002E ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0308 × 00AD ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 002E × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E × 0308 × 0300 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 002E ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 002E ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 002E × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] FULL STOP (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0030 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0030 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0030 ÷ 000D ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
@@ -450,14 +504,20 @@
÷ 0030 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0030 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0030 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0030 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0030 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0030 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0030 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0030 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0030 × 0308 × 005F ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0030 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0030 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0030 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0030 × 0308 × 05D0 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0030 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0030 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0030 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0030 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0030 × 0300 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -466,16 +526,16 @@
÷ 0030 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0030 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0030 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0030 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0030 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0030 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0030 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0030 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0030 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0030 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0030 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0030 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [4.0] COMBINING DIAERESIS (Extend_FE) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0030 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ZERO (Numeric) × [8.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -496,14 +556,20 @@
÷ 005F × 0308 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 005F ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 005F × 0308 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 005F ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 005F × 0308 ÷ 002E ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 005F × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 005F × 0308 × 0030 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 005F × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 005F × 0308 × 005F ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 005F ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 005F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 005F × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 005F × 0308 × 05D0 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 005F ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 005F × 0308 ÷ 0022 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 005F ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 005F × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 005F × 0308 × 00AD ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 005F × 0300 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -512,16 +578,16 @@
÷ 005F × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 005F × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 005F × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 005F × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 005F × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 005F × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 005F × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 005F × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 005F × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 005F × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 005F × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 005F × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 005F × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LOW LINE (ExtendNumLet) × [13.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -542,14 +608,20 @@
÷ 1F1E6 × 0308 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 1F1E6 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 1F1E6 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 002E ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 1F1E6 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0030 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 1F1E6 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 005F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [13.3] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 1F1E6 × 0308 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.3] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 1F1E6 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 05D0 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 1F1E6 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0022 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 1F1E6 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 1F1E6 × 0308 × 00AD ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -558,20 +630,176 @@
÷ 1F1E6 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 1F1E6 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 1F1E6 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 1F1E6 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 1F1E6 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 1F1E6 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 1F1E6 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 1F1E6 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 1F1E6 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 0001 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 05D0 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000D ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 05D0 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 05D0 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 000B ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 05D0 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 3031 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 05D0 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0041 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 05D0 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 002E ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 05D0 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 05D0 × 0308 × 0030 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 05D0 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 05D0 × 0308 × 005F ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 05D0 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 05D0 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 05D0 × 0308 × 05D0 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 05D0 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 05D0 × 0308 ÷ 0022 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 05D0 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.1] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 00AD ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 05D0 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0300 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 05D0 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 05D0 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 05D0 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] HEBREW LETTER ALEF (Hebrew_Letter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0001 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0022 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000D ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0022 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0022 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0022 × 0308 ÷ 000B ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0022 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0022 × 0308 ÷ 3031 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0022 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0041 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0022 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0022 × 0308 ÷ 002E ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0022 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0030 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0022 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0022 × 0308 ÷ 005F ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0022 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0022 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0022 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 05D0 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0022 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0022 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0022 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 × 00AD ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0022 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 × 0308 × 0300 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0022 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0022 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] QUOTATION MARK (Double_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0027 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0027 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0027 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0027 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0027 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0027 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0027 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0027 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0027 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0027 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0027 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 00AD ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 00AD × 0308 ÷ 0001 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 00AD ÷ 000D ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
@@ -588,14 +816,20 @@
÷ 00AD × 0308 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 00AD ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 00AD × 0308 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 00AD ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 00AD × 0308 ÷ 002E ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 00AD ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 00AD × 0308 ÷ 0030 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 00AD ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 00AD × 0308 ÷ 005F ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 00AD ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 00AD × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 00AD ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 00AD × 0308 ÷ 05D0 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 00AD ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0022 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 00AD ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 00AD × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 00AD × 0308 × 00AD ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 00AD × 0300 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -604,16 +838,16 @@
÷ 00AD × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 00AD ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 00AD × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 00AD ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 00AD × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 00AD ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 00AD × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 00AD ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 00AD × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 00AD ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 00AD × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 00AD ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] SOFT HYPHEN (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -634,14 +868,20 @@
÷ 0300 × 0308 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0300 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0300 × 0308 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0300 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0300 × 0308 ÷ 002E ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0300 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0300 × 0308 ÷ 0030 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0300 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0300 × 0308 ÷ 005F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0300 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0300 × 0308 ÷ 05D0 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0300 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0022 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0300 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0300 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0300 × 0308 × 00AD ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -650,16 +890,16 @@
÷ 0300 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0300 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0300 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0300 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0300 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0300 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0300 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0300 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0300 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0300 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0300 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0300 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -680,14 +920,20 @@
÷ 0061 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0061 × 2060 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 × 2060 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [13.1] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0061 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -696,16 +942,16 @@
÷ 0061 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [5.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [9.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -726,14 +972,20 @@
÷ 0061 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 × 003A × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 ÷ 003A × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 ÷ 003A × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -742,112 +994,124 @@
÷ 0061 × 003A × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 × 003A × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 × 003A × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 003A × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 003A × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 × 003A × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 × 003A × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 0027 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 × 0027 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 0027 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 000B ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 3031 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0041 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 × 0027 × 2060 × 0308 × 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [7.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 0027 × 2060 × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 000D ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
@@ -864,14 +1128,20 @@
÷ 0061 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0030 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 ÷ 002C × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0061 ÷ 002C × 0300 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -880,16 +1150,16 @@
÷ 0061 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0061 ÷ 002C ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 002C × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0061 ÷ 002C ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -910,14 +1180,20 @@
÷ 0031 ÷ 003A × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 ÷ 003A × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 003A × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -926,66 +1202,72 @@
÷ 0031 ÷ 003A × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 003A ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 003A ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 003A × 0308 ÷ 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
-÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (MidNumLet) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE FEED (LF)> (LF) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 000B ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [3.2] <LINE TABULATION> (Newline) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 3031 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] VERTICAL KANA REPEAT MARK (Katakana) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0041 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN CAPITAL LETTER A (ALetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 × 0027 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 0027 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 ÷ 0027 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
+÷ 0031 × 0027 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 × 0027 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] APOSTROPHE (Single_Quote) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 0001 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] <START OF HEADING> (Other) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 000D ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [3.2] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3]
@@ -1002,14 +1284,20 @@
÷ 0031 ÷ 002C × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0031 × 002C × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 × 002C × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 ÷ 002C × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002C × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -1018,16 +1306,16 @@
÷ 0031 ÷ 002C × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002C ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002C ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 002C × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002C × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 × 002C × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 × 002C × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002C × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 × 002C × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002C × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002C × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -1048,14 +1336,20 @@
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 002E ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] FULL STOP (MidNumLet) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0308 × 0030 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ZERO (Numeric) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 005F ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LOW LINE (ExtendNumLet) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (Regional_Indicator) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 05D0 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] HEBREW LETTER ALEF (Hebrew_Letter) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0022 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] QUOTATION MARK (Double_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 × 00AD ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [4.0] SOFT HYPHEN (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0300 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING GRAVE ACCENT (Extend_FE) ÷ [0.3]
@@ -1064,26 +1358,26 @@
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 0027 × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 ÷ 002E × 2060 × 0308 ÷ 0061 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 003A ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COLON (MidLetter) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
-÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (MidNumLet) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
+÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 0027 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] APOSTROPHE (Single_Quote) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002C ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] COMMA (MidNum) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 0031 × 002E × 2060 × 0308 × 0031 ÷ 002E × 2060 ÷ # ÷ [0.2] DIGIT ONE (Numeric) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [4.0] COMBINING DIAERESIS (Extend_FE) × [11.0] DIGIT ONE (Numeric) ÷ [999.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
-÷ 0063 × 0061 × 006E × 0027 × 0074 ÷ # ÷ [0.2] LATIN SMALL LETTER C (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER N (ALetter) × [6.0] APOSTROPHE (MidNumLet) × [7.0] LATIN SMALL LETTER T (ALetter) ÷ [0.3]
+÷ 0063 × 0061 × 006E × 0027 × 0074 ÷ # ÷ [0.2] LATIN SMALL LETTER C (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER N (ALetter) × [6.0] APOSTROPHE (Single_Quote) × [7.0] LATIN SMALL LETTER T (ALetter) ÷ [0.3]
÷ 0063 × 0061 × 006E × 2019 × 0074 ÷ # ÷ [0.2] LATIN SMALL LETTER C (ALetter) × [5.0] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER N (ALetter) × [6.0] RIGHT SINGLE QUOTATION MARK (MidNumLet) × [7.0] LATIN SMALL LETTER T (ALetter) ÷ [0.3]
÷ 0061 × 0062 × 00AD × 0062 × 0079 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) × [5.0] LATIN SMALL LETTER B (ALetter) × [4.0] SOFT HYPHEN (Format_FE) × [5.0] LATIN SMALL LETTER B (ALetter) × [5.0] LATIN SMALL LETTER Y (ALetter) ÷ [0.3]
÷ 0061 ÷ 0024 ÷ 002D ÷ 0033 × 0034 × 002C × 0035 × 0036 × 0037 × 002E × 0031 × 0034 ÷ 0025 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (ALetter) ÷ [999.0] DOLLAR SIGN (Other) ÷ [999.0] HYPHEN-MINUS (Other) ÷ [999.0] DIGIT THREE (Numeric) × [8.0] DIGIT FOUR (Numeric) × [12.0] COMMA (MidNum) × [11.0] DIGIT FIVE (Numeric) × [8.0] DIGIT SIX (Numeric) × [8.0] DIGIT SEVEN (Numeric) × [12.0] FULL STOP (MidNumLet) × [11.0] DIGIT ONE (Numeric) × [8.0] DIGIT FOUR (Numeric) ÷ [999.0] PERCENT SIGN (Other) ÷ [999.0] LATIN SMALL LETTER B (ALetter) ÷ [0.3]
÷ 0033 × 0061 ÷ # ÷ [0.2] DIGIT THREE (Numeric) × [10.0] LATIN SMALL LETTER A (ALetter) ÷ [0.3]
-÷ 2060 ÷ 0063 × 2060 × 0061 × 2060 × 006E × 2060 × 0027 × 2060 × 0074 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER C (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER N (ALetter) × [4.0] WORD JOINER (Format_FE) × [6.0] APOSTROPHE (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER T (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
+÷ 2060 ÷ 0063 × 2060 × 0061 × 2060 × 006E × 2060 × 0027 × 2060 × 0074 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER C (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER N (ALetter) × [4.0] WORD JOINER (Format_FE) × [6.0] APOSTROPHE (Single_Quote) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER T (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 ÷ 0063 × 2060 × 0061 × 2060 × 006E × 2060 × 2019 × 2060 × 0074 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER C (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER N (ALetter) × [4.0] WORD JOINER (Format_FE) × [6.0] RIGHT SINGLE QUOTATION MARK (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [7.0] LATIN SMALL LETTER T (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 ÷ 0061 × 2060 × 0062 × 2060 × 00AD × 2060 × 0062 × 2060 × 0079 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER B (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] SOFT HYPHEN (Format_FE) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER B (ALetter) × [4.0] WORD JOINER (Format_FE) × [5.0] LATIN SMALL LETTER Y (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
÷ 2060 ÷ 0061 × 2060 ÷ 0024 × 2060 ÷ 002D × 2060 ÷ 0033 × 2060 × 0034 × 2060 × 002C × 2060 × 0035 × 2060 × 0036 × 2060 × 0037 × 2060 × 002E × 2060 × 0031 × 2060 × 0034 × 2060 ÷ 0025 × 2060 ÷ 0062 × 2060 × 2060 ÷ # ÷ [0.2] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER A (ALetter) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DOLLAR SIGN (Other) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] HYPHEN-MINUS (Other) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] DIGIT THREE (Numeric) × [4.0] WORD JOINER (Format_FE) × [8.0] DIGIT FOUR (Numeric) × [4.0] WORD JOINER (Format_FE) × [12.0] COMMA (MidNum) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT FIVE (Numeric) × [4.0] WORD JOINER (Format_FE) × [8.0] DIGIT SIX (Numeric) × [4.0] WORD JOINER (Format_FE) × [8.0] DIGIT SEVEN (Numeric) × [4.0] WORD JOINER (Format_FE) × [12.0] FULL STOP (MidNumLet) × [4.0] WORD JOINER (Format_FE) × [11.0] DIGIT ONE (Numeric) × [4.0] WORD JOINER (Format_FE) × [8.0] DIGIT FOUR (Numeric) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] PERCENT SIGN (Other) × [4.0] WORD JOINER (Format_FE) ÷ [999.0] LATIN SMALL LETTER B (ALetter) × [4.0] WORD JOINER (Format_FE) × [4.0] WORD JOINER (Format_FE) ÷ [0.3]
@@ -1099,6 +1393,6 @@
÷ 0020 × 200D ÷ 0646 ÷ # ÷ [0.2] SPACE (Other) × [4.0] ZERO WIDTH JOINER (Extend_FE) ÷ [999.0] ARABIC LETTER NOON (ALetter) ÷ [0.3]
÷ 0646 × 200D ÷ 0020 ÷ # ÷ [0.2] ARABIC LETTER NOON (ALetter) × [4.0] ZERO WIDTH JOINER (Extend_FE) ÷ [999.0] SPACE (Other) ÷ [0.3]
#
-# Lines: 1078
+# Lines: 1372
#
# EOF
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
index b4f13af0a1..d81bfc33fb 100644
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
@@ -827,7 +827,7 @@ void tst_QTimeZone::macTest()
void tst_QTimeZone::winTest()
{
-#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN)
+#if defined(QT_BUILD_INTERNAL) && defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0, 0), Qt::UTC).toMSecsSinceEpoch();
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index c19080e345..1507fc7007 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -59,6 +59,9 @@ private slots:
void first();
void last();
void squeeze();
+ void indexOf();
+ void lastIndexOf();
+ void contains();
};
int fooCtor = 0;
@@ -677,5 +680,67 @@ void tst_QVarLengthArray::squeeze()
QCOMPARE(list.capacity(), sizeOnHeap);
}
+void tst_QVarLengthArray::indexOf()
+{
+ QVarLengthArray<QString> myvec;
+ myvec << "A" << "B" << "C" << "B" << "A";
+
+ QVERIFY(myvec.indexOf("B") == 1);
+ QVERIFY(myvec.indexOf("B", 1) == 1);
+ QVERIFY(myvec.indexOf("B", 2) == 3);
+ QVERIFY(myvec.indexOf("X") == -1);
+ QVERIFY(myvec.indexOf("X", 2) == -1);
+
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.indexOf("X") == 5);
+ QVERIFY(myvec.indexOf("X", 5) == 5);
+ QVERIFY(myvec.indexOf("X", 6) == -1);
+
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.indexOf("A") == 3);
+ QVERIFY(myvec.indexOf("A", 3) == 3);
+ QVERIFY(myvec.indexOf("A", 4) == -1);
+}
+
+void tst_QVarLengthArray::lastIndexOf()
+{
+ QVarLengthArray<QString> myvec;
+ myvec << "A" << "B" << "C" << "B" << "A";
+
+ QVERIFY(myvec.lastIndexOf("B") == 3);
+ QVERIFY(myvec.lastIndexOf("B", 2) == 1);
+ QVERIFY(myvec.lastIndexOf("X") == -1);
+ QVERIFY(myvec.lastIndexOf("X", 2) == -1);
+
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.lastIndexOf("X") == 5);
+ QVERIFY(myvec.lastIndexOf("X", 5) == 5);
+ QVERIFY(myvec.lastIndexOf("X", 3) == -1);
+
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.lastIndexOf("A") == 3);
+ QVERIFY(myvec.lastIndexOf("A", 3) == 3);
+ QVERIFY(myvec.lastIndexOf("A", 2) == -1);
+}
+
+void tst_QVarLengthArray::contains()
+{
+ QVarLengthArray<QString> myvec;
+ myvec << "aaa" << "bbb" << "ccc";
+
+ QVERIFY(myvec.contains(QLatin1String("aaa")));
+ QVERIFY(myvec.contains(QLatin1String("bbb")));
+ QVERIFY(myvec.contains(QLatin1String("ccc")));
+ QVERIFY(!myvec.contains(QLatin1String("I don't exist")));
+
+ // add it and make sure it does :)
+ myvec.append(QLatin1String("I don't exist"));
+ QVERIFY(myvec.contains(QLatin1String("I don't exist")));
+}
+
QTEST_APPLESS_MAIN(tst_QVarLengthArray)
#include "tst_qvarlengtharray.moc"
diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro
index 286afdfd18..996879ea69 100644
--- a/tests/auto/corelib/tools/tools.pro
+++ b/tests/auto/corelib/tools/tools.pro
@@ -4,6 +4,7 @@ SUBDIRS=\
qarraydata \
qbitarray \
qbytearray \
+ qbytearraylist \
qbytearraymatcher \
qbytedatabuffer \
qcache \
@@ -44,6 +45,7 @@ SUBDIRS=\
qstring \
qstring_no_cast_from_bytearray \
qstringbuilder \
+ qstringiterator \
qstringlist \
qstringmatcher \
qstringref \
diff --git a/tests/auto/gui/gui.pro b/tests/auto/gui/gui.pro
index b6c55c5eaa..d250e45a4e 100644
--- a/tests/auto/gui/gui.pro
+++ b/tests/auto/gui/gui.pro
@@ -1,7 +1,10 @@
TEMPLATE=subdirs
-SUBDIRS=\
+
+SUBDIRS = \
+ kernel
+
+!ios: SUBDIRS += \
image \
- kernel \
math3d \
painting \
qopengl \
diff --git a/tests/auto/gui/image/qimage/qimage.pro b/tests/auto/gui/image/qimage/qimage.pro
index 467a59ec9f..117e34653d 100644
--- a/tests/auto/gui/image/qimage/qimage.pro
+++ b/tests/auto/gui/image/qimage/qimage.pro
@@ -4,5 +4,6 @@ TARGET = tst_qimage
SOURCES += tst_qimage.cpp
QT += core-private gui-private testlib
+contains(QT_CONFIG, c++11): CONFIG += c++11
TESTDATA += images/*
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 7fdb2f4cba..01a56883bf 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -149,9 +149,25 @@ private slots:
void rgbSwapped_data();
void rgbSwapped();
+ void mirrored_data();
+ void mirrored();
+
+ void inplaceRgbSwapped_data();
+ void inplaceRgbSwapped();
+
+ void inplaceMirrored_data();
+ void inplaceMirrored();
+
+ void inplaceRgbMirrored();
+
+ void inplaceConversion_data();
+ void inplaceConversion();
+
void deepCopyWhenPaintingActive();
void scaled_QTBUG19157();
+ void convertOverUnPreMul();
+
void cleanupFunctions();
};
@@ -183,9 +199,9 @@ void tst_QImage::create()
#if !defined(Q_OS_WINCE)
QT_TRY {
#endif
- //QImage image(7000000, 7000000, 8, 256, QImage::IgnoreEndian);
- QImage image(7000000, 7000000, QImage::Format_Indexed8);
- image.setColorCount(256);
+ //QImage image(7000000, 7000000, 8, 256, QImage::IgnoreEndian);
+ QImage image(7000000, 7000000, QImage::Format_Indexed8);
+ image.setColorCount(256);
cr = !image.isNull();
#if !defined(Q_OS_WINCE)
} QT_CATCH (...) {
@@ -204,15 +220,10 @@ void tst_QImage::createInvalidXPM()
void tst_QImage::createFromUChar()
{
- uchar data[] = {
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- 0xFF,
-#endif
- 1,1,1, 0xFF, 2,2,2, 0xFF, 3,3,3, 0xFF, 4,4,4,
-#if Q_BYTE_ORDER != Q_BIG_ENDIAN
- 0xFF,
-#endif
- };
+ uint data[] = { 0xff010101U,
+ 0xff020202U,
+ 0xff030303U,
+ 0xff040404U };
// When the data is const, nothing you do to the image will change the source data.
QImage i1((const uchar*)data, 2, 2, 8, QImage::Format_RGB32);
@@ -226,8 +237,8 @@ void tst_QImage::createFromUChar()
}
QCOMPARE(i1.pixel(0,0), 0xFF010101U);
QCOMPARE(*(QRgb*)data, 0xFF010101U);
- *((QRgb*)i1.bits()) = 7U;
- QCOMPARE(i1.pixel(0,0), 7U);
+ *((QRgb*)i1.bits()) = 0xFF070707U;
+ QCOMPARE(i1.pixel(0,0), 0xFF070707U);
QCOMPARE(*(QRgb*)data, 0xFF010101U);
// Changing copies should not change the original image or data.
@@ -254,16 +265,16 @@ void tst_QImage::createFromUChar()
}
QCOMPARE(i2.pixel(0,0), 0xFF010101U);
QCOMPARE(*(QRgb*)data, 0xFF010101U);
- *((QRgb*)i2.bits()) = 7U;
- QCOMPARE(i2.pixel(0,0), 7U);
- QCOMPARE(*(QRgb*)data, 7U);
+ *((QRgb*)i2.bits()) = 0xFF070707U;
+ QCOMPARE(i2.pixel(0,0), 0xFF070707U);
+ QCOMPARE(*(QRgb*)data, 0xFF070707U);
// Changing the data will change the image in either case.
QImage i3((uchar*)data, 2, 2, 8, QImage::Format_RGB32);
QImage i4((const uchar*)data, 2, 2, 8, QImage::Format_RGB32);
- *(QRgb*)data = 6U;
- QCOMPARE(i3.pixel(0,0), 6U);
- QCOMPARE(i4.pixel(0,0), 6U);
+ *(QRgb*)data = 0xFF060606U;
+ QCOMPARE(i3.pixel(0,0), 0xFF060606U);
+ QCOMPARE(i4.pixel(0,0), 0xFF060606U);
}
void tst_QImage::formatHandlersInput_data()
@@ -298,16 +309,16 @@ void tst_QImage::formatHandlersInput()
bool formatSupported = false;
for (QList<QByteArray>::Iterator it = formats.begin(); it != formats.end(); ++it) {
if (*it == testFormat.toLower()) {
- formatSupported = true;
- break;
- }
+ formatSupported = true;
+ break;
+ }
}
if (formatSupported) {
// qDebug(QImage::imageFormat(testFile));
- QCOMPARE(testFormat.toLatin1().toLower(), QImageReader::imageFormat(testFile));
+ QCOMPARE(testFormat.toLatin1().toLower(), QImageReader::imageFormat(testFile));
} else {
- QString msg = "Format not supported : ";
- QSKIP(QString(msg + testFormat).toLatin1());
+ QString msg = "Format not supported : ";
+ QSKIP(QString(msg + testFormat).toLatin1());
}
}
@@ -2106,6 +2117,287 @@ void tst_QImage::rgbSwapped()
QCOMPARE(memcmp(image.constBits(), imageSwappedTwice.constBits(), image.byteCount()), 0);
}
+void tst_QImage::mirrored_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<bool>("swap_vertical");
+ QTest::addColumn<bool>("swap_horizontal");
+
+ QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false;
+ QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false;
+ QTest::newRow("Format_ARGB32_Premultiplied, vertical") << QImage::Format_ARGB32_Premultiplied << true << false;
+ QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false;
+ QTest::newRow("Format_ARGB8565_Premultiplied, vertical") << QImage::Format_ARGB8565_Premultiplied << true << false;
+ QTest::newRow("Format_ARGB6666_Premultiplied, vertical") << QImage::Format_ARGB6666_Premultiplied << true << false;
+ QTest::newRow("Format_ARGB4444_Premultiplied, vertical") << QImage::Format_ARGB4444_Premultiplied << true << false;
+ QTest::newRow("Format_RGB666, vertical") << QImage::Format_RGB666 << true << false;
+ QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false;
+ QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false;
+ QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false;
+ QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false;
+ QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false;
+ QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << true << false;
+ QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false;
+ QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false;
+
+ QTest::newRow("Format_ARGB32_Premultiplied, horizontal") << QImage::Format_ARGB32_Premultiplied << false << true;
+ QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true;
+ QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true;
+ QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true;
+ QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true;
+
+ QTest::newRow("Format_ARGB32_Premultiplied, horizontal+vertical") << QImage::Format_ARGB32_Premultiplied << true << true;
+ QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true;
+ QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true;
+ QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true;
+ QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true;
+}
+
+void tst_QImage::mirrored()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(bool, swap_vertical);
+ QFETCH(bool, swap_horizontal);
+
+ QImage image(16, 16, format);
+
+ switch (format) {
+ case QImage::Format_Mono:
+ for (int i = 0; i < image.height(); ++i) {
+ ushort* scanLine = (ushort*)image.scanLine(i);
+ *scanLine = (i % 2) ? 0x5555U : 0xCCCCU;
+ }
+ break;
+ case QImage::Format_Indexed8:
+ for (int i = 0; i < image.height(); ++i) {
+ for (int j = 0; j < image.width(); ++j) {
+ image.setColor(i*16+j, qRgb(j*16, i*16, 0));
+ image.setPixel(j, i, i*16+j);
+ }
+ }
+ break;
+ default:
+ for (int i = 0; i < image.height(); ++i)
+ for (int j = 0; j < image.width(); ++j)
+ image.setPixel(j, i, qRgb(j*16, i*16, 0));
+ break;
+ }
+
+ QImage imageMirrored = image.mirrored(swap_horizontal, swap_vertical);
+
+ for (int i = 0; i < image.height(); ++i) {
+ int mirroredI = swap_vertical ? (image.height() - i - 1) : i;
+ for (int j = 0; j < image.width(); ++j) {
+ QRgb referenceColor = image.pixel(j, i);
+ int mirroredJ = swap_horizontal ? (image.width() - j - 1) : j;
+ QRgb mirroredColor = imageMirrored.pixel(mirroredJ, mirroredI);
+ QCOMPARE(mirroredColor, referenceColor);
+ }
+ }
+
+ QImage imageMirroredTwice = imageMirrored.mirrored(swap_horizontal, swap_vertical);
+
+ QCOMPARE(image, imageMirroredTwice);
+
+ if (format != QImage::Format_Mono)
+ QCOMPARE(memcmp(image.constBits(), imageMirroredTwice.constBits(), image.byteCount()), 0);
+ else {
+ for (int i = 0; i < image.height(); ++i)
+ for (int j = 0; j < image.width(); ++j)
+ QCOMPARE(image.pixel(j,i), imageMirroredTwice.pixel(j,i));
+ }
+}
+
+void tst_QImage::inplaceRgbSwapped_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+
+ QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
+ QTest::newRow("Format_RGBA8888") << QImage::Format_RGBA8888;
+ QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
+ QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
+ QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
+}
+
+void tst_QImage::inplaceRgbSwapped()
+{
+#if defined(Q_COMPILER_REF_QUALIFIERS)
+ QFETCH(QImage::Format, format);
+
+ QImage image(64, 1, format);
+ image.fill(0);
+
+ QVector<QRgb> testColor(image.width());
+ for (int i = 0; i < image.width(); ++i)
+ testColor[i] = qRgb(i * 2, i * 3, 255 - i * 4);
+
+ if (format == QImage::Format_Indexed8) {
+ for (int i = 0; i < image.width(); ++i) {
+ image.setColor(i, testColor[i]);
+ image.setPixel(i, 0, i);
+ }
+ } else {
+ for (int i = 0; i < image.width(); ++i)
+ image.setPixel(i, 0, testColor[i]);
+ }
+
+ const uchar* orginalPtr = image.constScanLine(0);
+ QImage imageSwapped = std::move(image).rgbSwapped();
+
+ for (int i = 0; i < imageSwapped.width(); ++i) {
+ QRgb referenceColor = testColor[i];
+ QRgb swappedColor = imageSwapped.pixel(i, 0);
+ QCOMPARE(qRed(swappedColor) & 0xf8, qBlue(referenceColor) & 0xf8);
+ QCOMPARE(qGreen(swappedColor) & 0xf8, qGreen(referenceColor) & 0xf8);
+ QCOMPARE(qBlue(swappedColor) & 0xf8, qRed(referenceColor) & 0xf8);
+ }
+
+ QCOMPARE(imageSwapped.constScanLine(0), orginalPtr);
+#endif
+}
+
+
+void tst_QImage::inplaceMirrored_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<bool>("swap_vertical");
+ QTest::addColumn<bool>("swap_horizontal");
+
+ QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false;
+ QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false;
+ QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false;
+ QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false;
+ QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false;
+
+ QTest::newRow("Format_ARGB32, horizontal") << QImage::Format_ARGB32 << false << true;
+ QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true;
+ QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true;
+ QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true;
+ QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true;
+
+ QTest::newRow("Format_ARGB32, horizontal+vertical") << QImage::Format_ARGB32 << true << true;
+ QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true;
+ QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true;
+ QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true;
+ QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true;
+}
+
+void tst_QImage::inplaceMirrored()
+{
+#if defined(Q_COMPILER_REF_QUALIFIERS)
+ QFETCH(QImage::Format, format);
+ QFETCH(bool, swap_vertical);
+ QFETCH(bool, swap_horizontal);
+
+ QImage image(16, 16, format);
+
+ switch (format) {
+ case QImage::Format_Mono:
+ for (int i = 0; i < image.height(); ++i) {
+ ushort* scanLine = (ushort*)image.scanLine(i);
+ *scanLine = (i % 2) ? 0x0fffU : 0xf000U;
+ }
+ break;
+ case QImage::Format_Indexed8:
+ for (int i = 0; i < image.height(); ++i) {
+ for (int j = 0; j < image.width(); ++j) {
+ image.setColor(i*16+j, qRgb(j*16, i*16, 0));
+ image.setPixel(j, i, i*16+j);
+ }
+ }
+ break;
+ default:
+ for (int i = 0; i < image.height(); ++i)
+ for (int j = 0; j < image.width(); ++j)
+ image.setPixel(j, i, qRgb(j*16, i*16, 0));
+ }
+
+ const uchar* originalPtr = image.constScanLine(0);
+
+ QImage imageMirrored = std::move(image).mirrored(swap_horizontal, swap_vertical);
+ if (format != QImage::Format_Mono) {
+ for (int i = 0; i < imageMirrored.height(); ++i) {
+ int mirroredI = swap_vertical ? (imageMirrored.height() - i - 1) : i;
+ for (int j = 0; j < imageMirrored.width(); ++j) {
+ int mirroredJ = swap_horizontal ? (imageMirrored.width() - j - 1) : j;
+ QRgb mirroredColor = imageMirrored.pixel(mirroredJ, mirroredI);
+ QCOMPARE(qRed(mirroredColor) & 0xF8, j * 16);
+ QCOMPARE(qGreen(mirroredColor) & 0xF8, i * 16);
+ }
+ }
+ } else {
+ for (int i = 0; i < imageMirrored.height(); ++i) {
+ ushort* scanLine = (ushort*)imageMirrored.scanLine(i);
+ ushort expect;
+ if (swap_vertical && swap_horizontal)
+ expect = (i % 2) ? 0x000fU : 0xfff0U;
+ else if (swap_vertical)
+ expect = (i % 2) ? 0xf000U : 0x0fffU;
+ else
+ expect = (i % 2) ? 0xfff0U : 0x000fU;
+ QCOMPARE(*scanLine, expect);
+ }
+ }
+ QCOMPARE(imageMirrored.constScanLine(0), originalPtr);
+#endif
+}
+
+void tst_QImage::inplaceRgbMirrored()
+{
+#if defined(Q_COMPILER_REF_QUALIFIERS)
+ QImage image1(32, 32, QImage::Format_ARGB32);
+ QImage image2(32, 32, QImage::Format_ARGB32);
+ image1.fill(0);
+ image2.fill(0);
+ const uchar* originalPtr1 = image1.constScanLine(0);
+ const uchar* originalPtr2 = image2.constScanLine(0);
+
+ QCOMPARE(std::move(image1).rgbSwapped().mirrored().constScanLine(0), originalPtr1);
+ QCOMPARE(std::move(image2).mirrored().rgbSwapped().constScanLine(0), originalPtr2);
+#endif
+}
+
+void tst_QImage::inplaceConversion_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<QImage::Format>("dest_format");
+
+ QTest::newRow("Format_ARGB32 -> Format_RGBA8888") << QImage::Format_ARGB32 << QImage::Format_RGBA8888;
+ QTest::newRow("Format_RGB888 -> Format_ARGB6666_Premultiplied") << QImage::Format_RGB888 << QImage::Format_ARGB6666_Premultiplied;
+ QTest::newRow("Format_RGB16 -> Format_RGB555") << QImage::Format_RGB16 << QImage::Format_RGB555;
+ QTest::newRow("Format_RGB666 -> Format_RGB888") << QImage::Format_RGB666 << QImage::Format_RGB888;
+ QTest::newRow("Format_ARGB8565_Premultiplied, Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8565_Premultiplied << QImage::Format_ARGB8555_Premultiplied;
+ QTest::newRow("Format_ARGB4444_Premultiplied, Format_RGB444") << QImage::Format_ARGB4444_Premultiplied << QImage::Format_RGB444;
+}
+
+void tst_QImage::inplaceConversion()
+{
+ // Test that conversions between RGB formats of the same bitwidth can be done inplace.
+#if defined(Q_COMPILER_REF_QUALIFIERS)
+ QFETCH(QImage::Format, format);
+ QFETCH(QImage::Format, dest_format);
+
+ QImage image(16, 16, format);
+
+ for (int i = 0; i < image.height(); ++i)
+ for (int j = 0; j < image.width(); ++j)
+ image.setPixel(j, i, qRgb(j*16, i*16, 0));
+
+ const uchar* originalPtr = image.constScanLine(0);
+
+ QImage imageConverted = std::move(image).convertToFormat(dest_format);
+ for (int i = 0; i < imageConverted.height(); ++i) {
+ for (int j = 0; j < imageConverted.width(); ++j) {
+ QRgb convertedColor = imageConverted.pixel(j,i);
+ QCOMPARE(qRed(convertedColor) & 0xF0, j * 16);
+ QCOMPARE(qGreen(convertedColor) & 0xF0, i * 16);
+ }
+ }
+
+ QCOMPARE(imageConverted.constScanLine(0), originalPtr);
+#endif
+}
+
void tst_QImage::deepCopyWhenPaintingActive()
{
QImage image(64, 64, QImage::Format_ARGB32_Premultiplied);
@@ -2127,6 +2419,26 @@ void tst_QImage::scaled_QTBUG19157()
QVERIFY(!foo.isNull());
}
+void tst_QImage::convertOverUnPreMul()
+{
+ QImage image(256, 256, QImage::Format_ARGB32_Premultiplied);
+
+ for (int j = 0; j < 256; j++) {
+ for (int i = 0; i <= j; i++) {
+ image.setPixel(i, j, qRgba(i, i, i, j));
+ }
+ }
+
+ QImage image2 = image.convertToFormat(QImage::Format_ARGB32).convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ for (int j = 0; j < 256; j++) {
+ for (int i = 0; i <= j; i++) {
+ QCOMPARE(qAlpha(image2.pixel(i, j)), qAlpha(image.pixel(i, j)));
+ QCOMPARE(qGray(image2.pixel(i, j)), qGray(image.pixel(i, j)));
+ }
+ }
+}
+
static void cleanupFunction(void* info)
{
bool *called = static_cast<bool*>(info);
diff --git a/tests/auto/gui/image/qpixmap/qpixmap.pro b/tests/auto/gui/image/qpixmap/qpixmap.pro
index bdd0c15788..33c301a500 100644
--- a/tests/auto/gui/image/qpixmap/qpixmap.pro
+++ b/tests/auto/gui/image/qpixmap/qpixmap.pro
@@ -5,7 +5,7 @@ QT += core-private gui-private testlib
qtHaveModule(widgets): QT += widgets widgets-private
SOURCES += tst_qpixmap.cpp
-!wince* {
+!wince*:!winrt {
win32:LIBS += -lgdi32 -luser32
}
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index cb5d836291..79dc3f311a 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -116,7 +116,7 @@ private slots:
void convertFromImageDetach();
void convertFromImageCacheKey();
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void toWinHBITMAP_data();
void toWinHBITMAP();
void fromWinHBITMAP_data();
@@ -805,7 +805,7 @@ void tst_QPixmap::convertFromImageCacheKey()
QCOMPARE(copy.cacheKey(), pix.cacheKey());
}
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap);
@@ -1024,7 +1024,7 @@ void tst_QPixmap::fromWinHICON()
#endif // Q_OS_WINCE
}
-#endif // Q_OS_WIN
+#endif // Q_OS_WIN && !Q_OS_WINRT
void tst_QPixmap::onlyNullPixmapsOutsideGuiThread()
{
diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
index 085dfd0461..761f6371db 100644
--- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
+++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp
@@ -1468,7 +1468,7 @@ static QModelIndex indexFromText(QStandardItemModel *model, const QString &text)
struct FriendlyTreeView : public QTreeView
{
friend class tst_QStandardItemModel;
- Q_DECLARE_PRIVATE(QTreeView)
+ Q_DECLARE_PRIVATE(QTreeView)
};
#endif
diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
index d4237b135f..6ef9957fa1 100644
--- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
+++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp
@@ -60,6 +60,7 @@ class tst_QGuiApplication: public tst_QCoreApplication
private slots:
void displayName();
+ void firstWindowTitle();
void focusObject();
void allWindows();
void topLevelWindows();
@@ -83,6 +84,17 @@ void tst_QGuiApplication::displayName()
QCOMPARE(QGuiApplication::applicationDisplayName(), QString::fromLatin1("The GUI Application"));
}
+void tst_QGuiApplication::firstWindowTitle()
+{
+ int argc = 3;
+ char *argv[] = { const_cast<char*>("tst_qguiapplication"), const_cast<char*>("-qwindowtitle"), const_cast<char*>("User Title") };
+ QGuiApplication app(argc, argv);
+ QWindow window;
+ window.setTitle("Application Title");
+ window.show();
+ QCOMPARE(window.title(), QString("User Title"));
+}
+
class DummyWindow : public QWindow
{
public:
diff --git a/tests/auto/gui/kernel/qguivariant/test/black.png b/tests/auto/gui/kernel/qguivariant/test/black.png
new file mode 100644
index 0000000000..6c94085ed5
--- /dev/null
+++ b/tests/auto/gui/kernel/qguivariant/test/black.png
Binary files differ
diff --git a/tests/auto/gui/kernel/qguivariant/test/black2.png b/tests/auto/gui/kernel/qguivariant/test/black2.png
new file mode 100644
index 0000000000..6c94085ed5
--- /dev/null
+++ b/tests/auto/gui/kernel/qguivariant/test/black2.png
Binary files differ
diff --git a/tests/auto/gui/kernel/qguivariant/test/test.pro b/tests/auto/gui/kernel/qguivariant/test/test.pro
index e3b4a350ca..c4123797d2 100644
--- a/tests/auto/gui/kernel/qguivariant/test/test.pro
+++ b/tests/auto/gui/kernel/qguivariant/test/test.pro
@@ -2,6 +2,7 @@ CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qguivariant
SOURCES += tst_qguivariant.cpp
+RESOURCES = tst_qguivariant.qrc
INCLUDEPATH += $$PWD/../../../../other/qvariant_common
QT += testlib
RESOURCES += qguivariant.qrc
diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
index 7512829e09..431db86330 100644
--- a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
+++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.cpp
@@ -126,6 +126,8 @@ private slots:
void implicitConstruction();
void guiVariantAtExit();
+
+ void iconEquality();
};
void tst_QGuiVariant::constructor_invalid_data()
@@ -466,8 +468,8 @@ void tst_QGuiVariant::vector3D()
QVariant variant;
QVector3D vector = qvariant_cast<QVector3D>(variant);
QVERIFY(vector.isNull());
- variant.setValue(QVector3D(0.1, 0.2, 0.3));
- QCOMPARE(QVector3D(0.1, 0.2, 0.3), qvariant_cast<QVector3D>(variant));
+ variant.setValue(QVector3D(0.1f, 0.2f, 0.3f));
+ QCOMPARE(QVector3D(0.1f, 0.2f, 0.3f), qvariant_cast<QVector3D>(variant));
void *pvector = QMetaType::create(QVariant::Vector3D, 0);
QVERIFY(pvector);
@@ -479,8 +481,8 @@ void tst_QGuiVariant::vector4D()
QVariant variant;
QVector4D vector = qvariant_cast<QVector4D>(variant);
QVERIFY(vector.isNull());
- variant.setValue(QVector4D(0.1, 0.2, 0.3, 0.4));
- QCOMPARE(QVector4D(0.1, 0.2, 0.3, 0.4), qvariant_cast<QVector4D>(variant));
+ variant.setValue(QVector4D(0.1f, 0.2f, 0.3f, 0.4f));
+ QCOMPARE(QVector4D(0.1f, 0.2f, 0.3f, 0.4f), qvariant_cast<QVector4D>(variant));
void *pvector = QMetaType::create(QVariant::Vector4D, 0);
QVERIFY(pvector);
@@ -492,8 +494,8 @@ void tst_QGuiVariant::quaternion()
QVariant variant;
QQuaternion quaternion = qvariant_cast<QQuaternion>(variant);
QVERIFY(quaternion.isIdentity());
- variant.setValue(QQuaternion(0.1, 0.2, 0.3, 0.4));
- QCOMPARE(QQuaternion(0.1, 0.2, 0.3, 0.4), qvariant_cast<QQuaternion>(variant));
+ variant.setValue(QQuaternion(0.1f, 0.2f, 0.3f, 0.4f));
+ QCOMPARE(QQuaternion(0.1f, 0.2f, 0.3f, 0.4f), qvariant_cast<QQuaternion>(variant));
void *pquaternion = QMetaType::create(QVariant::Quaternion, 0);
QVERIFY(pquaternion);
@@ -761,5 +763,32 @@ void tst_QGuiVariant::guiVariantAtExit()
QVERIFY(true);
}
+void tst_QGuiVariant::iconEquality()
+{
+ QIcon i;
+ QVariant a = i;
+ QVariant b = i;
+ QCOMPARE(a, b);
+
+ i = QIcon(":/black.png");
+ a = i;
+ QVERIFY(a != b);
+
+ b = a;
+ QCOMPARE(a, b);
+
+ i = QIcon(":/black2.png");
+ a = i;
+ QVERIFY(a != b);
+
+ b = i;
+ QCOMPARE(a, b);
+
+ // This is a "different" QIcon
+ // even if the contents are the same
+ b = QIcon(":/black2.png");
+ QVERIFY(a != b);
+}
+
QTEST_MAIN(tst_QGuiVariant)
#include "tst_qguivariant.moc"
diff --git a/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc
new file mode 100644
index 0000000000..15cfde5788
--- /dev/null
+++ b/tests/auto/gui/kernel/qguivariant/test/tst_qguivariant.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/">
+<file>black.png</file>
+<file>black2.png</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
index 493d7e20c5..94353703dc 100644
--- a/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
+++ b/tests/auto/gui/kernel/qkeysequence/tst_qkeysequence.cpp
@@ -50,7 +50,9 @@
#include <QLibraryInfo>
#ifdef Q_OS_MAC
+#ifdef Q_OS_OSX
#include <Carbon/Carbon.h>
+#endif
struct MacSpecialKey {
int key;
ushort macSymbol;
@@ -73,10 +75,12 @@ static const MacSpecialKey entries[NumEntries] = {
{ Qt::Key_Down, 0x2193 },
{ Qt::Key_PageUp, 0x21DE },
{ Qt::Key_PageDown, 0x21DF },
+#ifdef Q_OS_OSX
{ Qt::Key_Shift, kShiftUnicode },
{ Qt::Key_Control, kCommandUnicode },
{ Qt::Key_Meta, kControlUnicode },
{ Qt::Key_Alt, kOptionUnicode },
+#endif
{ Qt::Key_CapsLock, 0x21EA },
};
@@ -527,7 +531,7 @@ void tst_QKeySequence::toStringFromKeycode()
void tst_QKeySequence::streamOperators_data()
{
- operatorQString_data();
+ operatorQString_data();
}
void tst_QKeySequence::streamOperators()
@@ -535,21 +539,21 @@ void tst_QKeySequence::streamOperators()
QFETCH( int, modifiers );
QFETCH( int, keycode );
- QByteArray data;
- QKeySequence refK( modifiers | keycode );
- QKeySequence orgK( "Ctrl+A" );
- QKeySequence copyOrgK = orgK;
- QVERIFY( copyOrgK == orgK );
+ QByteArray data;
+ QKeySequence refK( modifiers | keycode );
+ QKeySequence orgK( "Ctrl+A" );
+ QKeySequence copyOrgK = orgK;
+ QVERIFY( copyOrgK == orgK );
- QDataStream in(&data, QIODevice::WriteOnly);
- in << refK;
- QDataStream out(&data, QIODevice::ReadOnly);
- out >> orgK;
+ QDataStream in(&data, QIODevice::WriteOnly);
+ in << refK;
+ QDataStream out(&data, QIODevice::ReadOnly);
+ out >> orgK;
- QVERIFY( orgK == refK );
+ QVERIFY( orgK == refK );
- // check if detached
- QVERIFY( orgK != copyOrgK );
+ // check if detached
+ QVERIFY( orgK != copyOrgK );
}
diff --git a/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp b/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp
index 424b5fea3a..828c1fc41f 100644
--- a/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp
+++ b/tests/auto/gui/kernel/qmouseevent/tst_qmouseevent.cpp
@@ -61,21 +61,21 @@ public:
protected:
void mousePressEvent(QMouseEvent *e)
{
- QWindow::mousePressEvent(e);
- mousePressButton = e->button();
- mousePressButtons = e->buttons();
- mousePressModifiers = e->modifiers();
- mousePressEventRecieved = true;
- e->accept();
+ QWindow::mousePressEvent(e);
+ mousePressButton = e->button();
+ mousePressButtons = e->buttons();
+ mousePressModifiers = e->modifiers();
+ mousePressEventRecieved = true;
+ e->accept();
}
void mouseReleaseEvent(QMouseEvent *e)
{
- QWindow::mouseReleaseEvent(e);
- mouseReleaseButton = e->button();
- mouseReleaseButtons = e->buttons();
- mouseReleaseModifiers = e->modifiers();
- mouseReleaseEventRecieved = true;
- e->accept();
+ QWindow::mouseReleaseEvent(e);
+ mouseReleaseButton = e->button();
+ mouseReleaseButtons = e->buttons();
+ mouseReleaseModifiers = e->modifiers();
+ mouseReleaseEventRecieved = true;
+ e->accept();
}
};
diff --git a/tests/auto/gui/kernel/qmouseevent_modal/tst_qmouseevent_modal.cpp b/tests/auto/gui/kernel/qmouseevent_modal/tst_qmouseevent_modal.cpp
index ef800bd995..48f079a24e 100644
--- a/tests/auto/gui/kernel/qmouseevent_modal/tst_qmouseevent_modal.cpp
+++ b/tests/auto/gui/kernel/qmouseevent_modal/tst_qmouseevent_modal.cpp
@@ -183,9 +183,9 @@ TstWidget::TstWidget()
connect( pb, SIGNAL(pressed()), this, SLOT(buttonPressed()) );
-// QScrollBar *sb = new QScrollBar( Qt::Horizontal, this );
+// QScrollBar *sb = new QScrollBar( Qt::Horizontal, this );
-// sb->setGeometry( 5, pb->geometry().bottom() + 5, 100, sb->sizeHint().height() );
+// sb->setGeometry( 5, pb->geometry().bottom() + 5, 100, sb->sizeHint().height() );
d = new TstDialog( pb, this , 0 );
}
@@ -218,8 +218,8 @@ void TstDialog::releaseMouse()
void TstDialog::closeDialog()
{
if ( isVisible() ) {
- c++;
- accept();
+ c++;
+ accept();
}
}
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index 259c840ae7..7e6313295b 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -61,6 +61,7 @@ private slots:
void eventOrderOnShow();
void resizeEventAfterResize();
void mapGlobal();
+ void positioning_data();
void positioning();
void isExposed();
void isActive();
@@ -81,6 +82,7 @@ private slots:
void windowModality_QTBUG27039();
void visibility();
void mask();
+ void initialSize();
void initTestCase()
{
@@ -93,7 +95,6 @@ private:
QTouchDevice *touchDevice;
};
-
void tst_QWindow::mapGlobal()
{
QWindow a;
@@ -116,10 +117,10 @@ void tst_QWindow::mapGlobal()
class Window : public QWindow
{
public:
- Window()
+ Window(const Qt::WindowFlags flags = Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
{
reset();
- setFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
+ setFlags(flags);
}
void reset()
@@ -188,6 +189,23 @@ void tst_QWindow::resizeEventAfterResize()
QTRY_COMPARE(window.received(QEvent::Resize), 2);
}
+void tst_QWindow::positioning_data()
+{
+ QTest::addColumn<int>("windowflags");
+ QTest::addColumn<int>("resizecount");
+
+ QTest::newRow("default") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint)
+#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
+ << 4;
+#else
+ << 3;
+#endif
+
+#ifdef Q_OS_OSX
+ QTest::newRow("fake") << int(Qt::Window | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) << 4;
+#endif
+}
+
void tst_QWindow::positioning()
{
if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(
@@ -200,7 +218,9 @@ void tst_QWindow::positioning()
const QSize size = QSize(300, 40);
const QRect geometry(QPoint(80, 80), size);
- Window window;
+ QFETCH(int, windowflags);
+ QFETCH(int, resizecount);
+ Window window((Qt::WindowFlags)windowflags);
window.setGeometry(QRect(QPoint(20, 20), size));
window.setFramePosition(QPoint(40, 40)); // Move window around before show, size must not change.
QCOMPARE(window.geometry().size(), size);
@@ -223,14 +243,13 @@ void tst_QWindow::positioning()
window.setWindowState(Qt::WindowFullScreen);
QCoreApplication::processEvents();
-#ifdef Q_OS_OSX
- QEXPECT_FAIL("", "Multiple failures in this test on Mac OS X, see QTBUG-23059", Abort);
-#endif
QTRY_COMPARE(window.received(QEvent::Resize), 2);
+ QTest::qWait(2000);
+
window.setWindowState(Qt::WindowNoState);
QCoreApplication::processEvents();
- QTRY_COMPARE(window.received(QEvent::Resize), 3);
+ QTRY_COMPARE(window.received(QEvent::Resize), resizecount);
QTRY_COMPARE(originalPos, window.position());
QTRY_COMPARE(originalFramePos, window.framePosition());
@@ -239,7 +258,7 @@ void tst_QWindow::positioning()
// if our positioning is actually fully respected by the window manager
// test whether it correctly handles frame positioning as well
if (originalPos == geometry.topLeft() && (originalMargins.top() != 0 || originalMargins.left() != 0)) {
- QPoint framePos = QGuiApplication::primaryScreen()->availableVirtualGeometry().topLeft() + QPoint(40, 40);
+ QPoint framePos = QPlatformScreen::platformScreenForWindow(&window)->availableGeometry().topLeft() + QPoint(40, 40);
window.reset();
window.setFramePosition(framePos);
@@ -1168,6 +1187,32 @@ void tst_QWindow::mask()
QCOMPARE(window.mask(), mask);
}
+void tst_QWindow::initialSize()
+{
+ QSize defaultSize(0,0);
+ {
+ Window w;
+ w.show();
+ QTRY_VERIFY(w.width() > 0);
+ QTRY_VERIFY(w.height() > 0);
+ defaultSize = QSize(w.width(), w.height());
+ }
+ {
+ Window w;
+ w.setWidth(200);
+ w.show();
+ QTRY_COMPARE(w.width(), 200);
+ QTRY_VERIFY(w.height() > 0);
+ }
+ {
+ Window w;
+ w.resize(200, 42);
+ w.show();
+ QTRY_COMPARE(w.width(), 200);
+ QTRY_COMPARE(w.height(), 42);
+ }
+}
+
#include <tst_qwindow.moc>
QTEST_MAIN(tst_QWindow)
diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
index 4c4e46de05..e4340451ce 100644
--- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
+++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp
@@ -80,6 +80,7 @@
Q_DECLARE_METATYPE(QGradientStops)
Q_DECLARE_METATYPE(QPainterPath)
Q_DECLARE_METATYPE(QImage::Format)
+Q_DECLARE_METATYPE(QPainter::CompositionMode)
class tst_QPainter : public QObject
{
@@ -290,6 +291,9 @@ private slots:
void cosmeticStrokerClipping_data();
void cosmeticStrokerClipping();
+ void blendARGBonRGB_data();
+ void blendARGBonRGB();
+
private:
void fillData();
void setPenColor(QPainter& p);
@@ -514,7 +518,7 @@ void tst_QPainter::drawPixmap_comp()
bool different = false;
for (int y=0; y<result.height(); ++y)
for (int x=0; x<result.width(); ++x) {
- bool diff;
+ bool diff;
if (qAlpha(expected) == 0) {
diff = qAlpha(result.pixel(x, y)) != 0;
} else {
@@ -526,12 +530,12 @@ void tst_QPainter::drawPixmap_comp()
|| (qAbs(qBlue(pix) - qBlue(expected)) > off)
|| (qAbs(qAlpha(pix) - qAlpha(expected)) > off);
}
- if (diff && !different)
- qDebug( "Different at %d,%d pixel [%d,%d,%d,%d] expected [%d,%d,%d,%d]", x, y,
+ if (diff && !different)
+ qDebug( "Different at %d,%d pixel [%d,%d,%d,%d] expected [%d,%d,%d,%d]", x, y,
qRed(result.pixel(x, y)), qGreen(result.pixel(x, y)),
qBlue(result.pixel(x, y)), qAlpha(result.pixel(x, y)),
qRed(expected), qGreen(expected), qBlue(expected), qAlpha(expected));
- different |= diff;
+ different |= diff;
}
QVERIFY(!different);
@@ -563,24 +567,24 @@ void tst_QPainter::saveAndRestore_data()
QRect viewport = p.viewport();
QTest::newRow("Original") << font << pen << brush << backgroundColor << int(backgroundMode)
- << brushOrigin << clipRegion << window << viewport;
+ << brushOrigin << clipRegion << window << viewport;
QFont font2 = font;
font2.setPointSize( 24 );
QTest::newRow("Modified font.pointSize, brush, backgroundColor, backgroundMode")
<< font2 << pen << QBrush(Qt::red) << QColor(Qt::blue) << int(Qt::TransparentMode)
- << brushOrigin << clipRegion << window << viewport;
+ << brushOrigin << clipRegion << window << viewport;
font2 = font;
font2.setPixelSize( 20 );
QTest::newRow("Modified font.pixelSize, brushOrigin, pos")
<< font2 << pen << brush << backgroundColor << int(backgroundMode)
- << QPoint( 50, 32 ) << clipRegion << window << viewport;
+ << QPoint( 50, 32 ) << clipRegion << window << viewport;
QTest::newRow("Modified clipRegion, window, viewport")
<< font << pen << brush << backgroundColor << int(backgroundMode)
- << brushOrigin << clipRegion.subtracted(QRect(10,10,50,30))
- << QRect(-500, -500, 500, 500 ) << QRect( 0, 0, 50, 50 );
+ << brushOrigin << clipRegion.subtracted(QRect(10,10,50,30))
+ << QRect(-500, -500, 500, 500 ) << QRect( 0, 0, 50, 50 );
}
void tst_QPainter::saveAndRestore()
@@ -665,13 +669,13 @@ QBitmap tst_QPainter::getBitmap( const QString &dir, const QString &filename, bo
return QBitmap();
}
if ( mask ) {
- QBitmap mask;
- QString maskFilename = dir + QString( "/%1-mask.xbm" ).arg( filename );
- if ( !mask.load( maskFilename ) ) {
- QWARN(QString("Could not load mask '%1'").arg(maskFilename).toLatin1());
- return QBitmap();
- }
- bm.setMask( mask );
+ QBitmap mask;
+ QString maskFilename = dir + QString( "/%1-mask.xbm" ).arg( filename );
+ if (!mask.load(maskFilename)) {
+ QWARN(QString("Could not load mask '%1'").arg(maskFilename).toLatin1());
+ return QBitmap();
+ }
+ bm.setMask( mask );
}
return bm;
}
@@ -701,17 +705,17 @@ static QRect getPaintedSize(const QImage &image, const QColor &background)
uint color = background.rgba();
for ( int y = 0; y < image.height(); ++y ) {
- for ( int x = 0; x < image.width(); ++x ) {
+ for (int x = 0; x < image.width(); ++x) {
QRgb pixel = image.pixel( x, y );
- if ( pixel != color && x < xmin )
- xmin = x;
- if ( pixel != color && x > xmax )
- xmax = x;
- if ( pixel != color && y < ymin )
- ymin = y;
- if ( pixel != color && y > ymax )
- ymax = y;
- }
+ if (pixel != color && x < xmin)
+ xmin = x;
+ if (pixel != color && x > xmax)
+ xmax = x;
+ if (pixel != color && y < ymin)
+ ymin = y;
+ if (pixel != color && y > ymax)
+ ymax = y;
+ }
}
return QRect(xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
@@ -4574,6 +4578,112 @@ void tst_QPainter::QTBUG25153_drawLine()
}
}
+void tst_QPainter::blendARGBonRGB_data()
+{
+ QTest::addColumn<QImage::Format>("dst_format");
+ QTest::addColumn<QImage::Format>("src_format");
+ QTest::addColumn<QPainter::CompositionMode>("compositionMode");
+ QTest::addColumn<QRgb>("color");
+ QTest::addColumn<int>("expected_red");
+
+ QTest::newRow("ARGB over ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127 ;
+ QTest::newRow("ARGB_PM over ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver<< qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 255;
+ QTest::newRow("ARGB_PM source ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 255;
+ QTest::newRow("ARGB source-in ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 255 ;
+ QTest::newRow("ARGB_PM source-in ARGB32") << QImage::Format_ARGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 255;
+ // Only ARGB does inverse premultiply, on the rest over and source gives similar results:
+ QTest::newRow("ARGB over RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM over RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source-in RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source-in RGB32") << QImage::Format_RGB32 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB over RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM over RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source-in RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source-in RGB888") << QImage::Format_RGB888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB over RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM over RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB source-in RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 127;
+ QTest::newRow("ARGB_PM source-in RGBx8888") << QImage::Format_RGBX8888 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 127;
+ QTest::newRow("ARGB over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 123;
+ QTest::newRow("ARGB_PM over RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 123;
+ QTest::newRow("ARGB source RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 123;
+ QTest::newRow("ARGB_PM source RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 123;
+ QTest::newRow("ARGB source-in RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 123;
+ QTest::newRow("ARGB_PM source-in RGB16") << QImage::Format_RGB16 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 123;
+ QTest::newRow("ARGB over RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceOver << qRgba(255, 0, 0, 127) << 125;
+ QTest::newRow("ARGB_PM over RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceOver << qRgba(127, 0, 0, 127) << 125;
+ QTest::newRow("ARGB source RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_Source << qRgba(255, 0, 0, 127) << 125;
+ QTest::newRow("ARGB_PM source RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_Source << qRgba(127, 0, 0, 127) << 125;
+ QTest::newRow("ARGB source-in RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32
+ << QPainter::CompositionMode_SourceIn << qRgba(255, 0, 0, 127) << 125;
+ QTest::newRow("ARGB_PM source-in RGB666") << QImage::Format_RGB666 << QImage::Format_ARGB32_Premultiplied
+ << QPainter::CompositionMode_SourceIn << qRgba(127, 0, 0, 127) << 125;
+}
+
+void tst_QPainter::blendARGBonRGB()
+{
+ QFETCH(QImage::Format, dst_format);
+ QFETCH(QImage::Format, src_format);
+ QFETCH(QPainter::CompositionMode, compositionMode);
+ QFETCH(QRgb, color);
+ QFETCH(int, expected_red);
+
+ QImage imageRgb(16,16, dst_format);
+ QImage imageArgb(16,16, src_format);
+ QPainter painter;
+
+ imageArgb.fill(color);
+
+ imageRgb.fill(Qt::black);
+ painter.begin(&imageRgb);
+ painter.setCompositionMode(compositionMode);
+ painter.drawImage(0, 0, imageArgb);
+ painter.end();
+
+ QCOMPARE(qRed(imageRgb.pixel(0,0)), expected_red);
+}
+
enum CosmeticStrokerPaint
{
Antialiasing,
diff --git a/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp b/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp
index 11ce8b947b..a6bf4eca8b 100644
--- a/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp
+++ b/tests/auto/gui/painting/qpainter/utils/createImages/main.cpp
@@ -61,15 +61,15 @@ static QPixmap createDestPixmap()
QPainter painter;
painter.begin( &pm );
for ( int i=0; i<colorbands; i++ ) {
- for ( int j=0; j<intensities; j++ ) {
- int intensity = 255 * (j+1) / intensities; // 25%, 50%, 75% and 100%
- for ( int k=0; k<8; k++ ) {
- QColor col = baseColor( k, intensity );
- painter.setPen( QPen( col, 1 ) );
- painter.setBrush( col );
- painter.drawRect( k*4, j*4 + i*intensities*4, 4, 4 );
- }
- }
+ for (int j = 0; j < intensities; j++) {
+ int intensity = 255 * (j+1) / intensities; // 25%, 50%, 75% and 100%
+ for (int k = 0; k < 8; k++) {
+ QColor col = baseColor(k, intensity);
+ painter.setPen(QPen(col, 1));
+ painter.setBrush(col);
+ painter.drawRect(k*4, j*4 + i*intensities*4, 4, 4);
+ }
+ }
}
painter.end();
return pm;
@@ -127,14 +127,14 @@ static QBitmap createSrcBitmap( int size, int border )
painter.drawRect( border, border, size, size2 );
painter.end();
if ( border > 0 ) {
- QBitmap mask( totalSize, totalSize, true );
- QPainter painter;
- painter.begin( &mask );
- painter.setPen( QPen( Qt::color1, 1 ) );
- painter.setBrush( Qt::color1 );
- painter.drawRect( border, border, size, size );
- painter.end();
- bm.setMask( mask );
+ QBitmap mask(totalSize, totalSize, true);
+ QPainter painter;
+ painter.begin(&mask);
+ painter.setPen(QPen(Qt::color1, 1));
+ painter.setBrush(Qt::color1);
+ painter.drawRect(border, border, size, size);
+ painter.end();
+ bm.setMask(mask);
}
return bm;
}
@@ -146,49 +146,49 @@ int main( int argc, char **argv )
// input for tst_QPainter::drawLine_rop_bitmap()
{
- QBitmap dst = createDestBitmap();
- dst.save( "../../drawLine_rop_bitmap/dst.xbm", "XBM" );
+ QBitmap dst = createDestBitmap();
+ dst.save("../../drawLine_rop_bitmap/dst.xbm", "XBM");
}
// input for tst_QPainter::drawPixmap_rop_bitmap()
{
- QBitmap dst = createDestBitmap();
- QBitmap src1 = createSrcBitmap( 4, 2 );
- QBitmap src2 = createSrcBitmap( 4, 0 );
- dst.save( "../../drawPixmap_rop_bitmap/dst.xbm", "XBM" );
- src1.save( "../../drawPixmap_rop_bitmap/src1.xbm", "XBM" );
- src1.mask()->save( "../../drawPixmap_rop_bitmap/src1-mask.xbm", "XBM" );
- src2.save( "../../drawPixmap_rop_bitmap/src2.xbm", "XBM" );
+ QBitmap dst = createDestBitmap();
+ QBitmap src1 = createSrcBitmap(4, 2);
+ QBitmap src2 = createSrcBitmap(4, 0);
+ dst.save("../../drawPixmap_rop_bitmap/dst.xbm", "XBM");
+ src1.save("../../drawPixmap_rop_bitmap/src1.xbm", "XBM");
+ src1.mask()->save("../../drawPixmap_rop_bitmap/src1-mask.xbm", "XBM");
+ src2.save("../../drawPixmap_rop_bitmap/src2.xbm", "XBM");
}
// input for tst_QPainter::drawPixmap_rop()
{
- QPixmap dst1 = createDestPixmap();
- QPixmap dst2 = createDestPixmap();
- dst2.resize( 32, 32 );
- QBitmap src1 = createSrcBitmap( 32, 0 );
+ QPixmap dst1 = createDestPixmap();
+ QPixmap dst2 = createDestPixmap();
+ dst2.resize(32, 32);
+ QBitmap src1 = createSrcBitmap(32, 0);
- QBitmap src_tmp = createSrcBitmap( 32, 0 ).xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
- src_tmp.resize( 32, 48 );
- QBitmap src2 = src_tmp.xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
- QBitmap mask( 32, 48, true );
- {
- QPainter painter;
- painter.begin( &mask );
- painter.setPen( QPen( Qt::color1, 1 ) );
- painter.setBrush( Qt::color1 );
- painter.drawRect( 0, 16, 32, 32 );
- painter.end();
- }
- src2.setMask( mask );
+ QBitmap src_tmp = createSrcBitmap(32, 0).xForm(QWMatrix(1, 0, 0, -1, 0, 0));
+ src_tmp.resize(32, 48);
+ QBitmap src2 = src_tmp.xForm(QWMatrix(1, 0, 0, -1, 0, 0));
+ QBitmap mask(32, 48, true);
+ {
+ QPainter painter;
+ painter.begin(&mask);
+ painter.setPen(QPen(Qt::color1, 1));
+ painter.setBrush(Qt::color1);
+ painter.drawRect(0, 16, 32, 32);
+ painter.end();
+ }
+ src2.setMask(mask);
- QBitmap src3 = createSrcBitmap( 32, 0 ).xForm( QWMatrix( 1, 0, 0, -1, 0, 0 ) );
+ QBitmap src3 = createSrcBitmap(32, 0).xForm(QWMatrix(1, 0, 0, -1, 0, 0));
- dst1.save( "../../drawPixmap_rop/dst1.png", "PNG" );
- dst2.save( "../../drawPixmap_rop/dst2.png", "PNG" );
- src1.save( "../../drawPixmap_rop/src1.xbm", "XBM" );
- src2.save( "../../drawPixmap_rop/src2.xbm", "XBM" );
- src2.mask()->save( "../../drawPixmap_rop/src2-mask.xbm", "XBM" );
- src3.save( "../../drawPixmap_rop/src3.xbm", "XBM" );
+ dst1.save("../../drawPixmap_rop/dst1.png", "PNG");
+ dst2.save("../../drawPixmap_rop/dst2.png", "PNG");
+ src1.save("../../drawPixmap_rop/src1.xbm", "XBM");
+ src2.save("../../drawPixmap_rop/src2.xbm", "XBM");
+ src2.mask()->save("../../drawPixmap_rop/src2-mask.xbm", "XBM");
+ src3.save("../../drawPixmap_rop/src3.xbm", "XBM");
}
}
diff --git a/tests/auto/gui/painting/qpen/tst_qpen.cpp b/tests/auto/gui/painting/qpen/tst_qpen.cpp
index 1444c4fc16..07c996d026 100644
--- a/tests/auto/gui/painting/qpen/tst_qpen.cpp
+++ b/tests/auto/gui/painting/qpen/tst_qpen.cpp
@@ -114,23 +114,23 @@ void tst_QPen::operator_eq_eq_data()
QTest::addColumn<bool>("isEqual");
QTest::newRow("differentColor") << QPen(Qt::red)
- << QPen(Qt::blue)
- << false;
+ << QPen(Qt::blue)
+ << false;
QTest::newRow("differentWidth") << QPen(Qt::red, 2)
- << QPen(Qt::red, 3)
- << false;
+ << QPen(Qt::red, 3)
+ << false;
QTest::newRow("differentPenStyle") << QPen(Qt::red, 2, Qt::DashLine)
- << QPen(Qt::red, 2, Qt::DotLine)
- << false;
+ << QPen(Qt::red, 2, Qt::DotLine)
+ << false;
QTest::newRow("differentCapStyle") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
- << QPen(Qt::red, 2, Qt::DashLine, Qt::SquareCap, Qt::BevelJoin)
- << false;
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::SquareCap, Qt::BevelJoin)
+ << false;
QTest::newRow("differentJoinStyle") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
- << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin)
- << false;
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::MiterJoin)
+ << false;
QTest::newRow("same") << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
- << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
- << true;
+ << QPen(Qt::red, 2, Qt::DashLine, Qt::RoundCap, Qt::BevelJoin)
+ << true;
}
diff --git a/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp
index 4a659a3159..07670b2ae2 100644
--- a/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp
+++ b/tests/auto/gui/painting/qpolygon/tst_qpolygon.cpp
@@ -77,11 +77,11 @@ void tst_QPolygon::makeEllipse()
// make sure that all points are R+-1 away from the center
bool err = false;
for (i = 1; i < pa.size(); i++) {
- QPoint p = pa.at( i );
- double r = sqrt( pow( double(p.x() - R), 2.0 ) + pow( double(p.y() - R), 2.0 ) );
- // ### too strict ? at least from visual inspection it looks
- // quite odd around the main axes. 2.0 passes easily.
- err |= ( qAbs( r - double(R) ) > 2.0 );
+ QPoint p = pa.at(i);
+ double r = sqrt(pow(double(p.x() - R), 2.0) + pow(double(p.y() - R), 2.0));
+ // ### too strict ? at least from visual inspection it looks
+ // quite odd around the main axes. 2.0 passes easily.
+ err |= (qAbs(r - double(R)) > 2.0);
}
QVERIFY( !err );
}
diff --git a/tests/auto/gui/painting/qregion/tst_qregion.cpp b/tests/auto/gui/painting/qregion/tst_qregion.cpp
index c099611755..121d98e653 100644
--- a/tests/auto/gui/painting/qregion/tst_qregion.cpp
+++ b/tests/auto/gui/painting/qregion/tst_qregion.cpp
@@ -109,19 +109,19 @@ tst_QRegion::tst_QRegion()
void tst_QRegion::boundingRect()
{
{
- QRect rect;
- QRegion region( rect );
- QCOMPARE( region.boundingRect(), rect );
+ QRect rect;
+ QRegion region(rect);
+ QCOMPARE(region.boundingRect(), rect);
}
{
- QRect rect( 10, -20, 30, 40 );
- QRegion region( rect );
- QCOMPARE( region.boundingRect(), rect );
+ QRect rect(10, -20, 30, 40);
+ QRegion region(rect);
+ QCOMPARE(region.boundingRect(), rect);
}
{
- QRect rect(15,25,10,10);
- QRegion region( rect );
- QCOMPARE( region.boundingRect(), rect );
+ QRect rect(15,25,10,10);
+ QRegion region(rect);
+ QCOMPARE(region.boundingRect(), rect);
}
}
@@ -129,75 +129,75 @@ void tst_QRegion::boundingRect()
void tst_QRegion::rects()
{
{
- QRect rect;
- QRegion region( rect );
- QVERIFY( region.isEmpty() );
- QVERIFY( region.rects().isEmpty() );
+ QRect rect;
+ QRegion region(rect);
+ QVERIFY(region.isEmpty());
+ QVERIFY(region.rects().isEmpty());
}
{
- QRect rect( 10, -20, 30, 40 );
- QRegion region( rect );
- QCOMPARE( region.rects().count(), 1 );
- QCOMPARE( region.rects()[0], rect );
+ QRect rect(10, -20, 30, 40);
+ QRegion region(rect);
+ QCOMPARE(region.rects().count(), 1);
+ QCOMPARE(region.rects()[0], rect);
}
{
- QRect r( QPoint(10, 10), QPoint(40, 40) );
- QRegion region( r );
- QVERIFY( region.contains( QPoint(10,10) ) );
- QVERIFY( region.contains( QPoint(20,40) ) );
- QVERIFY( region.contains( QPoint(40,20) ) );
- QVERIFY( !region.contains( QPoint(20,41) ) );
- QVERIFY( !region.contains( QPoint(41,20) ) );
+ QRect r(QPoint(10, 10), QPoint(40, 40));
+ QRegion region(r);
+ QVERIFY(region.contains(QPoint(10,10)));
+ QVERIFY(region.contains(QPoint(20,40)));
+ QVERIFY(region.contains(QPoint(40,20)));
+ QVERIFY(!region.contains(QPoint(20,41)));
+ QVERIFY(!region.contains(QPoint(41,20)));
}
{
- QRect r( 10, 10, 30, 30 );
- QRegion region( r );
- QVERIFY( region.contains( QPoint(10,10) ) );
- QVERIFY( region.contains( QPoint(20,39) ) );
- QVERIFY( region.contains( QPoint(39,20) ) );
- QVERIFY( !region.contains( QPoint(20,40) ) );
- QVERIFY( !region.contains( QPoint(40,20) ) );
+ QRect r(10, 10, 30, 30);
+ QRegion region(r);
+ QVERIFY(region.contains(QPoint(10,10)));
+ QVERIFY(region.contains(QPoint(20,39)));
+ QVERIFY(region.contains(QPoint(39,20)));
+ QVERIFY(!region.contains(QPoint(20,40)));
+ QVERIFY(!region.contains(QPoint(40,20)));
}
}
void tst_QRegion::swap()
{
- QRegion r1(QRect( 0, 0,10,10));
+ QRegion r1(QRect(0, 0,10,10));
QRegion r2(QRect(10,10,10,10));
r1.swap(r2);
QCOMPARE(r1.rects().front(), QRect(10,10,10,10));
- QCOMPARE(r2.rects().front(), QRect( 0, 0,10,10));
+ QCOMPARE(r2.rects().front(), QRect(0, 0,10,10));
}
void tst_QRegion::setRects()
{
{
- QRegion region;
- region.setRects( 0, 0 );
- QVERIFY( region.rects().isEmpty() );
+ QRegion region;
+ region.setRects(0, 0);
+ QVERIFY(region.rects().isEmpty());
}
{
- QRegion region;
- QRect rect;
- region.setRects( &rect, 0 );
+ QRegion region;
+ QRect rect;
+ region.setRects(&rect, 0);
QVERIFY(region.isEmpty());
QVERIFY(region == QRegion());
- QVERIFY(!region.boundingRect().isValid());
- QVERIFY(region.rects().isEmpty());
+ QVERIFY(!region.boundingRect().isValid());
+ QVERIFY(region.rects().isEmpty());
}
{
- QRegion region;
- QRect rect;
- region.setRects( &rect, 1 );
- QVERIFY( !region.boundingRect().isValid() );
- QVERIFY( region.rects().isEmpty() );
+ QRegion region;
+ QRect rect;
+ region.setRects(&rect, 1);
+ QVERIFY(!region.boundingRect().isValid());
+ QVERIFY(region.rects().isEmpty());
}
{
- QRegion region;
- QRect rect( 10, -20, 30, 40 );
- region.setRects( &rect, 1 );
- QCOMPARE( region.rects().count(), 1 );
- QCOMPARE( region.rects()[0], rect );
+ QRegion region;
+ QRect rect(10, -20, 30, 40);
+ region.setRects(&rect, 1);
+ QCOMPARE(region.rects().count(), 1);
+ QCOMPARE(region.rects()[0], rect);
}
}
@@ -242,30 +242,30 @@ void tst_QRegion::polygonRegion()
{
QPolygon pa;
{
- QRegion region ( pa );
- QVERIFY( region.isEmpty() );
+ QRegion region (pa);
+ QVERIFY(region.isEmpty());
}
{
- pa.setPoints( 8, 10, 10, // a____________b
- 40, 10, // | |
- 40, 20, // |___ ___|
- 30, 20, // | |
- 30, 40, // | |
- 20, 40, // | |
- 20, 20, // |____c
- 10, 20 );
+ pa.setPoints(8, 10, 10, // a____________b
+ 40, 10, // | |
+ 40, 20, // |___ ___|
+ 30, 20, // | |
+ 30, 40, // | |
+ 20, 40, // | |
+ 20, 20, // |____c
+ 10, 20);
- QRegion region ( pa );
- QVERIFY( !region.isEmpty() );
+ QRegion region (pa);
+ QVERIFY(!region.isEmpty());
- // These should not be inside the circle
- QVERIFY( !region.contains( QPoint( 9, 9 ) ) );
- QVERIFY( !region.contains( QPoint( 30, 41 ) ) );
- QVERIFY( !region.contains( QPoint( 41, 10 ) ) );
- QVERIFY( !region.contains( QPoint( 31, 21 ) ) );
+ // These should not be inside the circle
+ QVERIFY(!region.contains(QPoint( 9, 9)));
+ QVERIFY(!region.contains(QPoint(30, 41)));
+ QVERIFY(!region.contains(QPoint(41, 10)));
+ QVERIFY(!region.contains(QPoint(31, 21)));
- // These should be inside
- QVERIFY( region.contains( QPoint( 10, 10 ) ) ); // Upper-left (a)
+ // These should be inside
+ QVERIFY(region.contains(QPoint(10, 10))); // Upper-left (a)
}
}
@@ -317,8 +317,8 @@ void tst_QRegion::emptyPolygonRegion()
static const char *circle_xpm[] = {
"20 20 2 1",
- " c #FFFFFF",
- ". c #000000",
+ " c #FFFFFF",
+ ". c #000000",
" ...... ",
" .......... ",
" .............. ",
@@ -345,29 +345,29 @@ void tst_QRegion::bitmapRegion()
{
QBitmap circle;
{
- QRegion region( circle );
- QVERIFY( region.isEmpty() );
+ QRegion region(circle);
+ QVERIFY(region.isEmpty());
}
{
- circle = QPixmap( circle_xpm );
- QRegion region( circle );
-
- //// These should not be inside the circe
- QVERIFY( !region.contains( QPoint( 2, 2 ) ) );
- QVERIFY( !region.contains( QPoint( 2, 17 ) ) );
- QVERIFY( !region.contains( QPoint( 17, 2 ) ) );
- QVERIFY( !region.contains( QPoint( 17, 17 ) ) );
-
- //// These should be inside
- QVERIFY( region.contains( QPoint( 3, 3 ) ) );
- QVERIFY( region.contains( QPoint( 3, 16 ) ) );
- QVERIFY( region.contains( QPoint( 16, 3 ) ) );
- QVERIFY( region.contains( QPoint( 16, 16 ) ) );
-
- QVERIFY( region.contains( QPoint( 0, 10 ) ) ); // Mid-left
- QVERIFY( region.contains( QPoint( 10, 0 ) ) ); // Mid-top
- QVERIFY( region.contains( QPoint( 19, 10 ) ) ); // Mid-right
- QVERIFY( region.contains( QPoint( 10, 19 ) ) ); // Mid-bottom
+ circle = QPixmap(circle_xpm);
+ QRegion region(circle);
+
+ //// These should not be inside the circe
+ QVERIFY(!region.contains(QPoint(2, 2)));
+ QVERIFY(!region.contains(QPoint(2, 17)));
+ QVERIFY(!region.contains(QPoint(17, 2)));
+ QVERIFY(!region.contains(QPoint(17, 17)));
+
+ //// These should be inside
+ QVERIFY(region.contains(QPoint(3, 3)));
+ QVERIFY(region.contains(QPoint(3, 16)));
+ QVERIFY(region.contains(QPoint(16, 3)));
+ QVERIFY(region.contains(QPoint(16, 16)));
+
+ QVERIFY(region.contains(QPoint(0, 10))); // Mid-left
+ QVERIFY(region.contains(QPoint(10, 0))); // Mid-top
+ QVERIFY(region.contains(QPoint(19, 10))); // Mid-right
+ QVERIFY(region.contains(QPoint(10, 19))); // Mid-bottom
}
}
diff --git a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp
index 4c73676329..c62ca3fa38 100644
--- a/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp
+++ b/tests/auto/gui/painting/qwmatrix/tst_qwmatrix.cpp
@@ -112,47 +112,47 @@ void tst_QWMatrix::mapping_data()
//next we fill it with data
// identity
- QTest::newRow( "identity" ) << QMatrix( 1, 0, 0, 1, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 10, 20, 30, 40 ) );
+ QTest::newRow( "identity" ) << QMatrix( 1, 0, 0, 1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, 20, 30, 40 ) );
// scaling
QTest::newRow( "scale 0" ) << QMatrix( 2, 0, 0, 2, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 20, 40, 60, 80 ) );
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 20, 40, 60, 80 ) );
QTest::newRow( "scale 1" ) << QMatrix( 10, 0, 0, 10, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 100, 200, 300, 400 ) );
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 100, 200, 300, 400 ) );
// mirroring
- QTest::newRow( "mirror 0" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -40, 20, 30, 40 ) );
- QTest::newRow( "mirror 1" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 10, -60, 30, 40 ) );
- QTest::newRow( "mirror 2" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -40, -60, 30, 40 ) );
- QTest::newRow( "mirror 3" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -80, -120, 60, 80 ) );
- QTest::newRow( "mirror 4" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -400, -600, 300, 400 ) );
- QTest::newRow( "mirror 5" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -30, 0, 30, 40 ) );
- QTest::newRow( "mirror 6" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( 0, -40, 30, 40 ) );
- QTest::newRow( "mirror 7" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -30, -40, 30, 40 ) );
- QTest::newRow( "mirror 8" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -60, -80, 60, 80 ) );
- QTest::newRow( "mirror 9" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -300, -400, 300, 400 ) );
+ QTest::newRow( "mirror 0" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, 20, 30, 40 ) );
+ QTest::newRow( "mirror 1" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 10, -60, 30, 40 ) );
+ QTest::newRow( "mirror 2" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -40, -60, 30, 40 ) );
+ QTest::newRow( "mirror 3" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -80, -120, 60, 80 ) );
+ QTest::newRow( "mirror 4" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -400, -600, 300, 400 ) );
+ QTest::newRow( "mirror 5" ) << QMatrix( -1, 0, 0, 1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, 0, 30, 40 ) );
+ QTest::newRow( "mirror 6" ) << QMatrix( 1, 0, 0, -1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -40, 30, 40 ) );
+ QTest::newRow( "mirror 7" ) << QMatrix( -1, 0, 0, -1, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -30, -40, 30, 40 ) );
+ QTest::newRow( "mirror 8" ) << QMatrix( -2, 0, 0, -2, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -60, -80, 60, 80 ) );
+ QTest::newRow( "mirror 9" ) << QMatrix( -10, 0, 0, -10, 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -300, -400, 300, 400 ) );
#if (defined(Q_OS_WIN) || defined(Q_OS_WINCE)) && !defined(M_PI)
#define M_PI 3.14159265897932384626433832795f
@@ -161,126 +161,126 @@ void tst_QWMatrix::mapping_data()
// rotations
float deg = 0.;
QTest::newRow( "rot 0 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
deg = 0.00001f;
QTest::newRow( "rot 0 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon ( QRect( 0, 0, 30, 40 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon ( QRect( 0, 0, 30, 40 ) );
deg = 0.;
QTest::newRow( "rot 0 c" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon ( QRect( 10, 20, 30, 40 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
deg = 0.00001f;
QTest::newRow( "rot 0 d" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon ( QRect( 10, 20, 30, 40 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon ( QRect( 10, 20, 30, 40 ) );
#if 0
// rotations
deg = 90.;
QTest::newRow( "rotscale 90 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( 0, -299, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -299, 400, 300 ) );
deg = 90.00001;
QTest::newRow( "rotscale 90 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( 0, -299, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( 0, -299, 400, 300 ) );
deg = 90.;
QTest::newRow( "rotscale 90 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 200, -399, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -399, 400, 300 ) );
deg = 90.00001;
QTest::newRow( "rotscale 90 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 200, -399, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 200, -399, 400, 300 ) );
deg = 180.;
QTest::newRow( "rotscale 180 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -299, -399, 300, 400 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -299, -399, 300, 400 ) );
deg = 180.000001;
QTest::newRow( "rotscale 180 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -299, -399, 300, 400 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -299, -399, 300, 400 ) );
deg = 180.;
QTest::newRow( "rotscale 180 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -399, -599, 300, 400 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -399, -599, 300, 400 ) );
deg = 180.000001;
QTest::newRow( "rotscale 180 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -399, -599, 300, 400 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -399, -599, 300, 400 ) );
deg = 270.;
QTest::newRow( "rotscale 270 a" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -399, 00, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -399, 00, 400, 300 ) );
deg = 270.0000001;
QTest::newRow( "rotscale 270 b" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 30, 40 )
- << QPolygon( QRect( -399, 00, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 30, 40 )
+ << QPolygon( QRect( -399, 00, 400, 300 ) );
deg = 270.;
QTest::newRow( "rotscale 270 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -599, 100, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -599, 100, 400, 300 ) );
deg = 270.000001;
QTest::newRow( "rotscale 270 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -599, 100, 400, 300 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -599, 100, 400, 300 ) );
// rotations that are not multiples of 90 degrees. mapRect returns the bounding rect here.
deg = 45;
QTest::newRow( "rot 45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 10, 10 )
- << QPolygon( QRect( 0, -7, 14, 14 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -7, 14, 14 ) );
QTest::newRow( "rot 45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 21, -14, 49, 49 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 21, -14, 49, 49 ) );
QTest::newRow( "rot 45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 10, 10 )
- << QPolygon( QRect( 0, -70, 141, 141 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( 0, -70, 141, 141 ) );
QTest::newRow( "rot 45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( 212, -141, 495, 495 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( 212, -141, 495, 495 ) );
deg = -45;
QTest::newRow( "rot -45 a" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 10, 10 )
- << QPolygon( QRect( -7, 0, 14, 14 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -7, 0, 14, 14 ) );
QTest::newRow( "rot -45 b" ) << QMatrix( cos( M_PI*deg/180. ), -sin( M_PI*deg/180. ),
- sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -35, 21, 49, 49 ) );
+ sin( M_PI*deg/180. ), cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -35, 21, 49, 49 ) );
QTest::newRow( "rot -45 c" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 0, 0, 10, 10 )
- << QPolygon( QRect( -70, 0, 141, 141 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 0, 0, 10, 10 )
+ << QPolygon( QRect( -70, 0, 141, 141 ) );
QTest::newRow( "rot -45 d" ) << QMatrix( 10*cos( M_PI*deg/180. ), -10*sin( M_PI*deg/180. ),
- 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
- << QRect( 10, 20, 30, 40 )
- << QPolygon( QRect( -353, 212, 495, 495 ) );
+ 10*sin( M_PI*deg/180. ), 10*cos( M_PI*deg/180. ), 0, 0 )
+ << QRect( 10, 20, 30, 40 )
+ << QPolygon( QRect( -353, 212, 495, 495 ) );
#endif
}
diff --git a/tests/auto/gui/qopengl/tst_qopengl.cpp b/tests/auto/gui/qopengl/tst_qopengl.cpp
index 4defbe181f..975c2acefd 100644
--- a/tests/auto/gui/qopengl/tst_qopengl.cpp
+++ b/tests/auto/gui/qopengl/tst_qopengl.cpp
@@ -48,6 +48,10 @@
#include <QtGui/QScreen>
#include <QtGui/QWindow>
#include <QtGui/QOffscreenSurface>
+#include <QtGui/QGenericMatrix>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/private/qopengltextureblitter_p.h>
+
#include <QtTest/QtTest>
@@ -66,6 +70,8 @@ private slots:
void multiGroupSharedResourceCleanupCustom();
void fboSimpleRendering_data();
void fboSimpleRendering();
+ void fboTextureOwnership_data();
+ void fboTextureOwnership();
void fboRendering_data();
void fboRendering();
void fboHandleNulledAfterContextDestroyed();
@@ -73,6 +79,11 @@ private slots:
void openGLPaintDevice();
void aboutToBeDestroyed();
void QTBUG15621_triangulatingStrokerDivZero();
+ void textureblitterFullSourceRectTransform();
+ void textureblitterPartOriginBottomLeftSourceRectTransform();
+ void textureblitterPartOriginTopLeftSourceRectTransform();
+ void textureblitterFullTargetRectTransform();
+ void textureblitterPartTargetRectTransform();
};
struct SharedResourceTracker
@@ -429,6 +440,54 @@ void tst_QOpenGL::fboSimpleRendering()
delete fbo;
}
+void tst_QOpenGL::fboTextureOwnership_data()
+{
+ common_data();
+}
+
+void tst_QOpenGL::fboTextureOwnership()
+{
+ QFETCH(int, surfaceClass);
+ QScopedPointer<QSurface> surface(createSurface(surfaceClass));
+
+ QOpenGLContext ctx;
+ QVERIFY(ctx.create());
+
+ ctx.makeCurrent(surface.data());
+
+ if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects())
+ QSKIP("QOpenGLFramebufferObject not supported on this platform");
+
+ QOpenGLFramebufferObjectFormat fboFormat;
+ fboFormat.setAttachment(QOpenGLFramebufferObject::NoAttachment);
+
+ QOpenGLFramebufferObject *fbo = new QOpenGLFramebufferObject(200, 100, fboFormat);
+ QVERIFY(fbo->texture() != 0);
+ fbo->bind();
+
+ // pull out the texture
+ GLuint texture = fbo->takeTexture();
+ QVERIFY(texture != 0);
+ QVERIFY(fbo->texture() == 0);
+
+ // verify that the next bind() creates a new texture
+ fbo->bind();
+ QVERIFY(fbo->texture() != 0 && fbo->texture() != texture);
+
+ glClearColor(1.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glFinish();
+
+ QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32);
+ QImage reference(fb.size(), QImage::Format_RGB32);
+ reference.fill(0xffff0000);
+
+ QFUZZY_COMPARE_IMAGES(fb, reference);
+
+ glDeleteTextures(1, &texture);
+ delete fbo;
+}
+
void tst_QOpenGL::fboRendering_data()
{
common_data();
@@ -658,6 +717,188 @@ void tst_QOpenGL::QTBUG15621_triangulatingStrokerDivZero()
QCOMPARE(image.pixel(95, 95), blue);
}
+typedef QGenericMatrix<1, 3, float> TestVertex3D;
+static const float uv_top_left[] = {0.f, 1.f, 1.f};
+static const float uv_bottom_left[] = {0.f, 0.f, 1.f};
+static const float uv_top_right[] = {1.f, 1.f, 1.f};
+static const float uv_bottom_right[] = {1.f, 0.f, 1.f};
+
+bool q_fuzzy_compare(const TestVertex3D &left, const TestVertex3D &right) {
+ return qFuzzyCompare(left(0,0), right(0,0)) &&
+ qFuzzyCompare(left(1,0), right(1,0)) &&
+ qFuzzyCompare(left(2,0), right(2,0));
+}
+
+void tst_QOpenGL::textureblitterFullSourceRectTransform()
+{
+ TestVertex3D topLeft(uv_top_left);
+ TestVertex3D bottomLeft(uv_bottom_left);
+ TestVertex3D topRight(uv_top_right);
+ TestVertex3D bottomRight(uv_bottom_right);
+
+ QRectF rect(0,0,1,1);
+ QMatrix3x3 flippedMatrix = QOpenGLTextureBlitter::sourceTransform(rect, rect.size().toSize(), QOpenGLTextureBlitter::OriginTopLeft);
+
+ TestVertex3D flippedTopLeft = flippedMatrix * topLeft;
+ QCOMPARE(flippedTopLeft, bottomLeft);
+
+ TestVertex3D flippedBottomLeft = flippedMatrix * bottomLeft;
+ QCOMPARE(flippedBottomLeft, topLeft);
+
+ TestVertex3D flippedTopRight = flippedMatrix * topRight;
+ QCOMPARE(flippedTopRight, bottomRight);
+
+ TestVertex3D flippedBottomRight = flippedMatrix * bottomRight;
+ QCOMPARE(flippedBottomRight, topRight);
+
+ QMatrix3x3 identityMatrix = QOpenGLTextureBlitter::sourceTransform(rect, rect.size().toSize(), QOpenGLTextureBlitter::OriginBottomLeft);
+
+ TestVertex3D notFlippedTopLeft = identityMatrix * topLeft;
+ QCOMPARE(notFlippedTopLeft, topLeft);
+
+ TestVertex3D notFlippedBottomLeft = identityMatrix * bottomLeft;
+ QCOMPARE(notFlippedBottomLeft, bottomLeft);
+
+ TestVertex3D notFlippedTopRight = identityMatrix * topRight;
+ QCOMPARE(notFlippedTopRight, topRight);
+
+ TestVertex3D notFlippedBottomRight = identityMatrix * bottomRight;
+ QCOMPARE(notFlippedBottomRight, bottomRight);
+}
+
+void tst_QOpenGL::textureblitterPartOriginBottomLeftSourceRectTransform()
+{
+ TestVertex3D topLeft(uv_top_left);
+ TestVertex3D bottomLeft(uv_bottom_left);
+ TestVertex3D topRight(uv_top_right);
+ TestVertex3D bottomRight(uv_bottom_right);
+
+ QRectF sourceRect(50,200,200,200);
+ QSize textureSize(400,400);
+
+ QMatrix3x3 sourceMatrix = QOpenGLTextureBlitter::sourceTransform(sourceRect, textureSize, QOpenGLTextureBlitter::OriginBottomLeft);
+
+ const float x_point_ratio = sourceRect.topLeft().x() / textureSize.width();
+ const float y_point_ratio = sourceRect.topLeft().y() / textureSize.height();
+ const float width_ratio = sourceRect.width() / textureSize.width();
+ const float height_ratio = sourceRect.height() / textureSize.height();
+
+ TestVertex3D uvTopLeft = sourceMatrix * topLeft;
+ const float expected_top_left[] = { x_point_ratio, y_point_ratio + height_ratio, 1 };
+ TestVertex3D expectedTopLeft(expected_top_left);
+ QCOMPARE(uvTopLeft, expectedTopLeft);
+
+ TestVertex3D uvBottomLeft = sourceMatrix * bottomLeft;
+ const float expected_bottom_left[] = { x_point_ratio, y_point_ratio, 1 };
+ TestVertex3D expectedBottomLeft(expected_bottom_left);
+ QCOMPARE(uvBottomLeft, expectedBottomLeft);
+
+ TestVertex3D uvTopRight = sourceMatrix * topRight;
+ const float expected_top_right[] = { x_point_ratio + width_ratio, y_point_ratio + height_ratio, 1 };
+ TestVertex3D expectedTopRight(expected_top_right);
+ QCOMPARE(uvTopRight, expectedTopRight);
+
+ TestVertex3D uvBottomRight = sourceMatrix * bottomRight;
+ const float expected_bottom_right[] = { x_point_ratio + width_ratio, y_point_ratio, 1 };
+ TestVertex3D expectedBottomRight(expected_bottom_right);
+ QCOMPARE(uvBottomRight, expectedBottomRight);
+}
+
+void tst_QOpenGL::textureblitterPartOriginTopLeftSourceRectTransform()
+{
+ TestVertex3D topLeft(uv_top_left);
+ TestVertex3D bottomLeft(uv_bottom_left);
+ TestVertex3D topRight(uv_top_right);
+ TestVertex3D bottomRight(uv_bottom_right);
+
+ QRectF sourceRect(50,190,170,170);
+ QSize textureSize(400,400);
+
+ QMatrix3x3 sourceMatrix = QOpenGLTextureBlitter::sourceTransform(sourceRect, textureSize, QOpenGLTextureBlitter::OriginTopLeft);
+
+ const float x_point_ratio = sourceRect.topLeft().x() / textureSize.width();
+ const float y_point_ratio = sourceRect.topLeft().y() / textureSize.height();
+ const float width_ratio = sourceRect.width() / textureSize.width();
+ const float height_ratio = sourceRect.height() / textureSize.height();
+
+ TestVertex3D uvTopLeft = sourceMatrix * topLeft;
+ const float expected_top_left[] = { x_point_ratio, 1 - y_point_ratio - height_ratio, 1 };
+ TestVertex3D expectedTopLeft(expected_top_left);
+ QVERIFY(q_fuzzy_compare(uvTopLeft, expectedTopLeft));
+
+ TestVertex3D uvBottomLeft = sourceMatrix * bottomLeft;
+ const float expected_bottom_left[] = { x_point_ratio, 1 - y_point_ratio, 1 };
+ TestVertex3D expectedBottomLeft(expected_bottom_left);
+ QVERIFY(q_fuzzy_compare(uvBottomLeft, expectedBottomLeft));
+
+ TestVertex3D uvTopRight = sourceMatrix * topRight;
+ const float expected_top_right[] = { x_point_ratio + width_ratio, 1 - y_point_ratio - height_ratio, 1 };
+ TestVertex3D expectedTopRight(expected_top_right);
+ QVERIFY(q_fuzzy_compare(uvTopRight, expectedTopRight));
+
+ TestVertex3D uvBottomRight = sourceMatrix * bottomRight;
+ const float expected_bottom_right[] = { x_point_ratio + width_ratio, 1 - y_point_ratio, 1 };
+ TestVertex3D expectedBottomRight(expected_bottom_right);
+ QVERIFY(q_fuzzy_compare(uvBottomRight, expectedBottomRight));
+}
+
+void tst_QOpenGL::textureblitterFullTargetRectTransform()
+{
+ QVector4D topLeft(-1.f, 1.f, 0.f, 1.f);
+ QVector4D bottomLeft(-1.f, -1.f, 0.f, 1.f);
+ QVector4D topRight(1.f, 1.f, 0.f, 1.f);
+ QVector4D bottomRight(1.f, -1.f, 0.f, 1.f);
+
+ QRectF rect(0,0,200,200);
+ QMatrix4x4 targetMatrix = QOpenGLTextureBlitter::targetTransform(rect,rect.toRect());
+
+ QVector4D translatedTopLeft = targetMatrix * topLeft;
+ QCOMPARE(translatedTopLeft, topLeft);
+
+ QVector4D translatedBottomLeft = targetMatrix * bottomLeft;
+ QCOMPARE(translatedBottomLeft, bottomLeft);
+
+ QVector4D translatedTopRight = targetMatrix * topRight;
+ QCOMPARE(translatedTopRight, topRight);
+
+ QVector4D translatedBottomRight = targetMatrix * bottomRight;
+ QCOMPARE(translatedBottomRight, bottomRight);
+}
+
+void tst_QOpenGL::textureblitterPartTargetRectTransform()
+{
+ QVector4D topLeft(-1.f, 1.f, 0.f, 1.f);
+ QVector4D bottomLeft(-1.f, -1.f, 0.f, 1.f);
+ QVector4D topRight(1.f, 1.f, 0.f, 1.f);
+ QVector4D bottomRight(1.f, -1.f, 0.f, 1.f);
+
+ QRectF targetRect(50,50,200,200);
+ QRect viewport(0,0,400,400);
+
+ //multiply by 2 since coordinate system goes from -1 -> 1;
+ qreal x_point_ratio = (50. / 400.) * 2;
+ qreal y_point_ratio = (50. / 400.) * 2;
+ qreal width_ratio = (200. / 400.) * 2;
+ qreal height_ratio = (200. / 400.) * 2;
+
+ QMatrix4x4 targetMatrix = QOpenGLTextureBlitter::targetTransform(targetRect, viewport);
+
+ QVector4D targetTopLeft = targetMatrix * topLeft;
+ QVector4D expectedTopLeft(-1 + x_point_ratio, 1 - y_point_ratio, .0, 1.0);
+ QCOMPARE(targetTopLeft, expectedTopLeft);
+
+ QVector4D targetBottomLeft = targetMatrix * bottomLeft;
+ QVector4D expectedBottomLeft(-1 + x_point_ratio, 1 - y_point_ratio - height_ratio, 0.0, 1.0);
+ QCOMPARE(targetBottomLeft, expectedBottomLeft);
+
+ QVector4D targetTopRight = targetMatrix * topRight;
+ QVector4D expectedTopRight(-1 + x_point_ratio + width_ratio, 1 - y_point_ratio, 0.0, 1.0);
+ QCOMPARE(targetTopRight, expectedTopRight);
+
+ QVector4D targetBottomRight = targetMatrix * bottomRight;
+ QVector4D expectedBottomRight(-1 + x_point_ratio + width_ratio, 1 - y_point_ratio - height_ratio, 0.0, 1.0);
+ QCOMPARE(targetBottomRight, expectedBottomRight);
+}
QTEST_MAIN(tst_QOpenGL)
diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp
index a23579e6a5..dde4e54a8e 100644
--- a/tests/auto/gui/text/qfont/tst_qfont.cpp
+++ b/tests/auto/gui/text/qfont/tst_qfont.cpp
@@ -316,25 +316,25 @@ void tst_QFont::italicOblique()
QStringList::ConstIterator f_it, f_end = families.end();
for (f_it = families.begin(); f_it != f_end; ++f_it) {
- QString family = *f_it;
- QStringList styles = fdb.styles(family);
- QVERIFY(!styles.isEmpty());
- QStringList::ConstIterator s_it, s_end = styles.end();
- for (s_it = styles.begin(); s_it != s_end; ++s_it) {
- QString style = *s_it;
-
- if (fdb.isSmoothlyScalable(family, style)) {
- if (style.contains("Oblique")) {
- style.replace("Oblique", "Italic");
- } else if (style.contains("Italic")) {
- style.replace("Italic", "Oblique");
- } else {
- continue;
- }
- QFont f = fdb.font(family, style, 12);
- QVERIFY(f.italic());
- }
- }
+ QString family = *f_it;
+ QStringList styles = fdb.styles(family);
+ QVERIFY(!styles.isEmpty());
+ QStringList::ConstIterator s_it, s_end = styles.end();
+ for (s_it = styles.begin(); s_it != s_end; ++s_it) {
+ QString style = *s_it;
+
+ if (fdb.isSmoothlyScalable(family, style)) {
+ if (style.contains("Oblique")) {
+ style.replace("Oblique", "Italic");
+ } else if (style.contains("Italic")) {
+ style.replace("Italic", "Oblique");
+ } else {
+ continue;
+ }
+ QFont f = fdb.font(family, style, 12);
+ QVERIFY(f.italic());
+ }
+ }
}
}
@@ -342,16 +342,16 @@ void tst_QFont::compare()
{
QFont font;
{
- QFont font2 = font;
- font2.setPointSize( 24 );
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
+ QFont font2 = font;
+ font2.setPointSize(24);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
}
{
- QFont font2 = font;
- font2.setPixelSize( 24 );
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
+ QFont font2 = font;
+ font2.setPixelSize(24);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
}
font.setPointSize(12);
@@ -361,69 +361,69 @@ void tst_QFont::compare()
font.setStrikeOut(false);
font.setOverline(false);
{
- QFont font2 = font;
- font2.setPointSize( 24 );
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
+ QFont font2 = font;
+ font2.setPointSize(24);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
}
{
- QFont font2 = font;
- font2.setPixelSize( 24 );
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
+ QFont font2 = font;
+ font2.setPixelSize(24);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
}
{
- QFont font2 = font;
-
- font2.setItalic(true);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
- font2.setItalic(false);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
-
- font2.setWeight(QFont::Bold);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
- font2.setWeight(QFont::Normal);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
-
- font.setUnderline(true);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
- font.setUnderline(false);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
-
- font.setStrikeOut(true);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
- font.setStrikeOut(false);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
-
- font.setOverline(true);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
- font.setOverline(false);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
+ QFont font2 = font;
+
+ font2.setItalic(true);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
+ font2.setItalic(false);
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
+
+ font2.setWeight(QFont::Bold);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
+ font2.setWeight(QFont::Normal);
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
+
+ font.setUnderline(true);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
+ font.setUnderline(false);
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
+
+ font.setStrikeOut(true);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
+ font.setStrikeOut(false);
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
+
+ font.setOverline(true);
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
+ font.setOverline(false);
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
font.setCapitalization(QFont::SmallCaps);
- QVERIFY( font != font2 );
- QCOMPARE(font < font2,!(font2 < font));
+ QVERIFY(font != font2);
+ QCOMPARE(font < font2,!(font2 < font));
font.setCapitalization(QFont::MixedCase);
- QVERIFY( font == font2 );
- QVERIFY(!(font < font2));
+ QVERIFY(font == font2);
+ QVERIFY(!(font < font2));
}
#if defined(Q_WS_X11)
{
- QFont font1, font2;
- font1.setRawName("-Adobe-Helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1");
- font2.setRawName("-Adobe-Helvetica-medium-r-normal--24-240-75-75-p-130-iso8859-1");
- QVERIFY(font1 != font2);
+ QFont font1, font2;
+ font1.setRawName("-Adobe-Helvetica-medium-r-normal--12-120-75-75-p-67-iso8859-1");
+ font2.setRawName("-Adobe-Helvetica-medium-r-normal--24-240-75-75-p-130-iso8859-1");
+ QVERIFY(font1 != font2);
}
#endif
}
diff --git a/tests/auto/gui/text/qfontdatabase/FreeMono.ttf b/tests/auto/gui/text/qfontdatabase/FreeMono.ttf
deleted file mode 100644
index d7ce52ddc7..0000000000
--- a/tests/auto/gui/text/qfontdatabase/FreeMono.ttf
+++ /dev/null
Binary files differ
diff --git a/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF b/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF
new file mode 100644
index 0000000000..f87ea95e0e
--- /dev/null
+++ b/tests/auto/gui/text/qfontdatabase/LED_REAL.TTF
Binary files differ
diff --git a/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt b/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt
new file mode 100644
index 0000000000..06a5b40313
--- /dev/null
+++ b/tests/auto/gui/text/qfontdatabase/LED_REAL_readme.txt
@@ -0,0 +1,34 @@
+Font: LED Real (led_real.ttf)
+Created By: Matthew Welch
+E-Mail: daffy-duck@worldnet.att.net
+Web Address: http://home.att.net/~daffy-duck
+ (PGP public key available here)
+
+LED Real, like all of my fonts, is free. You can use it for most
+personal or business uses you'd like, and I ask for no money. I
+would, however, like to hear from you. If you use my fonts for
+something please send me a postcard or e-mail letting me know how
+you used it. Send me a copy if you can or let me know where I can
+find your work.
+
+You may use this font for graphical or printed work, but you may not
+sell it or include it in a collection of fonts (on CD or otherwise)
+being sold. You can redistribute this font as long as you charge
+nothing to receive it. If you redistribute it include this text file
+with it as is (without modifications).
+
+If you use this font for commercial purposes please credit me in
+at least some little way.
+
+About the font:
+
+Unlike most LED/LCD style fonts mine could be recreated with an
+actual LED. I created this font working from memories of the good
+old Speak and Spell display. Since I don't have an actual Speak
+and Spell to work from I had to just do as well as I could in its
+spirit. Be warned that some characters look just like others. The
+( and the <, for instance. Also C and [. Most of these will be
+pretty clear in context. To see all the sections of the LED "lit
+up" at once use character 127 (hold down alt and type 0127 on the
+numeric keypad). This font is, of course, monospaced.
+
diff --git a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
index 104d3465f2..28db0ba291 100644
--- a/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
+++ b/tests/auto/gui/text/qfontdatabase/tst_qfontdatabase.cpp
@@ -83,7 +83,7 @@ private:
};
tst_QFontDatabase::tst_QFontDatabase()
- : m_testFont(QFINDTESTDATA("FreeMono.ttf"))
+ : m_testFont(QFINDTESTDATA("LED_REAL.TTF"))
{
}
@@ -124,11 +124,11 @@ void tst_QFontDatabase::styles()
QStringList styles = fdb.styles( font );
QStringList::Iterator it = styles.begin();
while ( it != styles.end() ) {
- QString style = *it;
- QString trimmed = style.trimmed();
- ++it;
+ QString style = *it;
+ QString trimmed = style.trimmed();
+ ++it;
- QCOMPARE( style, trimmed );
+ QCOMPARE(style, trimmed);
}
}
@@ -160,7 +160,7 @@ void tst_QFontDatabase::fixedPitch()
QFontDatabase fdb;
if (!fdb.families().contains(font))
- QSKIP( "Font not installed");
+ QSKIP("Font not installed");
QCOMPARE(fdb.isFixedPitch(font), fixedPitch);
diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
index cddec5b6e7..7adaac9fac 100644
--- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
+++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp
@@ -163,7 +163,7 @@ void tst_QFontMetrics::metrics()
fontmetrics.lineSpacing());
}
}
- }
+ }
}
}
diff --git a/tests/auto/gui/text/qtextdocument/common.h b/tests/auto/gui/text/qtextdocument/common.h
index 8fb5fe2499..184b2f7ec7 100644
--- a/tests/auto/gui/text/qtextdocument/common.h
+++ b/tests/auto/gui/text/qtextdocument/common.h
@@ -79,11 +79,11 @@ public:
int l;
void expect(int from, int oldLength, int length) {
- f = from;
- o = oldLength;
- l = length;
- error = false;
- called = false;
+ f = from;
+ o = oldLength;
+ l = length;
+ error = false;
+ called = false;
}
bool error;
bool called;
diff --git a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
index d5ddf8fbec..53aef40df0 100644
--- a/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
+++ b/tests/auto/gui/text/qtextdocument/tst_qtextdocument.cpp
@@ -187,6 +187,9 @@ private slots:
void htmlExportImportBlockCount();
void QTBUG27354_spaceAndSoftSpace();
+ void baseUrl_data();
+ void baseUrl();
+
void QTBUG28998_linkColor();
private:
@@ -2947,6 +2950,53 @@ void tst_QTextDocument::QTBUG27354_spaceAndSoftSpace()
}
}
+class BaseDocument : public QTextDocument
+{
+public:
+ QUrl loadedResource() const { return resourceUrl; }
+
+ QVariant loadResource(int type, const QUrl &name)
+ {
+ resourceUrl = name;
+ return QTextDocument::loadResource(type, name);
+ }
+
+private:
+ QUrl resourceUrl;
+};
+
+void tst_QTextDocument::baseUrl_data()
+{
+ QTest::addColumn<QUrl>("base");
+ QTest::addColumn<QUrl>("resource");
+ QTest::addColumn<QUrl>("loaded");
+
+ QTest::newRow("1") << QUrl() << QUrl("images/logo.png") << QUrl("images/logo.png");
+ QTest::newRow("2") << QUrl("file:///path/to/content") << QUrl("images/logo.png") << QUrl("file:///path/to/images/logo.png");
+ QTest::newRow("3") << QUrl("file:///path/to/content/") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
+ QTest::newRow("4") << QUrl("file:///path/to/content/images") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
+ QTest::newRow("5") << QUrl("file:///path/to/content/images/") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/images/logo.png");
+ QTest::newRow("6") << QUrl("file:///path/to/content/images") << QUrl("../images/logo.png") << QUrl("file:///path/to/images/logo.png");
+ QTest::newRow("7") << QUrl("file:///path/to/content/images/") << QUrl("../images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
+ QTest::newRow("8") << QUrl("file:///path/to/content/index.html") << QUrl("images/logo.png") << QUrl("file:///path/to/content/images/logo.png");
+}
+
+void tst_QTextDocument::baseUrl()
+{
+ QFETCH(QUrl, base);
+ QFETCH(QUrl, resource);
+ QFETCH(QUrl, loaded);
+
+ BaseDocument document;
+ QVERIFY(!document.baseUrl().isValid());
+ document.setBaseUrl(base);
+ QCOMPARE(document.baseUrl(), base);
+
+ document.setHtml(QString("<img src='%1'/>").arg(resource.toString()));
+ document.resource(QTextDocument::ImageResource, resource);
+ QCOMPARE(document.loadedResource(), loaded);
+}
+
void tst_QTextDocument::QTBUG28998_linkColor()
{
QPalette pal;
diff --git a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
index 9f9b6acb02..4274753c37 100644
--- a/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
+++ b/tests/auto/gui/text/qtextdocumentfragment/tst_qtextdocumentfragment.cpp
@@ -266,6 +266,7 @@ private slots:
void html_metaInBody();
void html_importImageWithoutAspectRatio();
void html_fromFirefox();
+ void html_emptyInlineInsideBlock();
private:
inline void setHtml(const QString &html)
@@ -360,8 +361,8 @@ void tst_QTextDocumentFragment::listCopying2()
cursor.movePosition(QTextCursor::Start);
int listItemCount = 0;
do {
- if (cursor.currentList())
- listItemCount++;
+ if (cursor.currentList())
+ listItemCount++;
} while (cursor.movePosition(QTextCursor::NextBlock));
QCOMPARE(listItemCount, 4);
@@ -378,35 +379,35 @@ void tst_QTextDocumentFragment::tableCopying()
// as the pasiveness of the tablemanager.
QTextDocumentFragment fragment;
{
- QTextDocument doc;
- QTextCursor cursor(&doc);
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
- QTextTableFormat fmt;
- QTextTable *table = cursor.insertTable(2, 2, fmt);
+ QTextTableFormat fmt;
+ QTextTable *table = cursor.insertTable(2, 2, fmt);
- table->cellAt(0, 0).firstCursorPosition().insertText("First Cell");
- table->cellAt(0, 1).firstCursorPosition().insertText("Second Cell");
- table->cellAt(1, 0).firstCursorPosition().insertText("Third Cell");
- table->cellAt(1, 1).firstCursorPosition().insertText("Fourth Cell");
+ table->cellAt(0, 0).firstCursorPosition().insertText("First Cell");
+ table->cellAt(0, 1).firstCursorPosition().insertText("Second Cell");
+ table->cellAt(1, 0).firstCursorPosition().insertText("Third Cell");
+ table->cellAt(1, 1).firstCursorPosition().insertText("Fourth Cell");
- fragment = QTextDocumentFragment(&doc);
+ fragment = QTextDocumentFragment(&doc);
}
{
- QTextDocument doc;
- QTextCursor cursor(&doc);
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
- cursor.insertText("FooBar");
- cursor.insertBlock();
- cursor.movePosition(QTextCursor::Left);
+ cursor.insertText("FooBar");
+ cursor.insertBlock();
+ cursor.movePosition(QTextCursor::Left);
- cursor.insertFragment(fragment);
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::NextBlock);
+ cursor.insertFragment(fragment);
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
- QTextTable *table = cursor.currentTable();
- QVERIFY(table);
- QCOMPARE(table->rows(), 2);
- QCOMPARE(table->columns(), 2);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+ QCOMPARE(table->rows(), 2);
+ QCOMPARE(table->columns(), 2);
}
}
@@ -488,91 +489,91 @@ void tst_QTextDocumentFragment::tableImport()
void tst_QTextDocumentFragment::tableImport2()
{
{
- const char html[] = ""
- "<table>"
- "<tr><td>First Cell</td><td>Second Cell</td></tr>"
- "<tr><td>Third Cell</td><td>Fourth Cell</td></tr>"
- "</table>";
-
- QTextDocument doc;
- QTextCursor cursor(&doc);
- cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
-
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::NextBlock);
- QTextTable *table = cursor.currentTable();
- QVERIFY(table);
- QCOMPARE(table->columns(), 2);
- QCOMPARE(table->rows(), 2);
+ const char html[] = ""
+ "<table>"
+ "<tr><td>First Cell</td><td>Second Cell</td></tr>"
+ "<tr><td>Third Cell</td><td>Fourth Cell</td></tr>"
+ "</table>";
+
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
+ cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+ QCOMPARE(table->columns(), 2);
+ QCOMPARE(table->rows(), 2);
}
{
- const char html[] = ""
- "<table>"
- "<tr><td>First Cell</td><td>Second Cell</td></tr>"
- "<tr><td>Third Cell</td><td>"
- " <table>"
- " <tr><td>First Nested Cell</td><td>Second Nested Cell</td></tr>"
- " <tr><td>Third Nested Cell</td><td>Fourth Nested Cell</td></tr>"
- " <tr><td>Fifth Nested Cell</td><td>Sixth Nested Cell</td></tr>"
- " </table></td></tr>"
- "</table>";
-
- QTextDocument doc;
- QTextCursor cursor(&doc);
- cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
-
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::NextBlock);
- QTextTable *table = cursor.currentTable();
- QVERIFY(table);
- QCOMPARE(table->columns(), 2);
- QCOMPARE(table->rows(), 2);
+ const char html[] = ""
+ "<table>"
+ "<tr><td>First Cell</td><td>Second Cell</td></tr>"
+ "<tr><td>Third Cell</td><td>"
+ " <table>"
+ " <tr><td>First Nested Cell</td><td>Second Nested Cell</td></tr>"
+ " <tr><td>Third Nested Cell</td><td>Fourth Nested Cell</td></tr>"
+ " <tr><td>Fifth Nested Cell</td><td>Sixth Nested Cell</td></tr>"
+ " </table></td></tr>"
+ "</table>";
+
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
+ cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+ QCOMPARE(table->columns(), 2);
+ QCOMPARE(table->rows(), 2);
/*
- QTextCursor fourthCell = table->cellAt(1, 1).firstCursorPosition();
- fourthCell.movePosition(QTextCursor::NextBlock);
- table = fourthCell.currentTable();
- QVERIFY(table);
- QVERIFY(table != cursor.currentTable());
- QCOMPARE(table->columns(), 2);
- QCOMPARE(table->rows(), 3);
+ QTextCursor fourthCell = table->cellAt(1, 1).firstCursorPosition();
+ fourthCell.movePosition(QTextCursor::NextBlock);
+ table = fourthCell.currentTable();
+ QVERIFY(table);
+ QVERIFY(table != cursor.currentTable());
+ QCOMPARE(table->columns(), 2);
+ QCOMPARE(table->rows(), 3);
*/
}
{
- const char buggyHtml[] = ""
- "<table>"
- "<tr><td>First Cell<td>Second Cell"
- "<tr><td>Third Cell<td>Fourth Cell"
- "</table>";
-
- QTextDocument doc;
- QTextCursor cursor(&doc);
- cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(buggyHtml, sizeof(buggyHtml) / sizeof(buggyHtml[0]))));
-
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::NextBlock);
- QTextTable *table = cursor.currentTable();
- QVERIFY(table);
- QCOMPARE(table->columns(), 2);
- QCOMPARE(table->rows(), 2);
+ const char buggyHtml[] = ""
+ "<table>"
+ "<tr><td>First Cell<td>Second Cell"
+ "<tr><td>Third Cell<td>Fourth Cell"
+ "</table>";
+
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
+ cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(buggyHtml, sizeof(buggyHtml) / sizeof(buggyHtml[0]))));
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+ QCOMPARE(table->columns(), 2);
+ QCOMPARE(table->rows(), 2);
}
{
- const char buggyHtml[] = ""
- "<table>"
- "<tr><th>First Cell<th>Second Cell"
- "<tr><td>Third Cell<td>Fourth Cell"
- "</table>";
-
- QTextDocument doc;
- QTextCursor cursor(&doc);
- cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(buggyHtml, sizeof(buggyHtml) / sizeof(buggyHtml[0]))));
-
- cursor.movePosition(QTextCursor::Start);
- cursor.movePosition(QTextCursor::NextBlock);
- QTextTable *table = cursor.currentTable();
- QVERIFY(table);
- QCOMPARE(table->columns(), 2);
- QCOMPARE(table->rows(), 2);
+ const char buggyHtml[] = ""
+ "<table>"
+ "<tr><th>First Cell<th>Second Cell"
+ "<tr><td>Third Cell<td>Fourth Cell"
+ "</table>";
+
+ QTextDocument doc;
+ QTextCursor cursor(&doc);
+ cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(buggyHtml, sizeof(buggyHtml) / sizeof(buggyHtml[0]))));
+
+ cursor.movePosition(QTextCursor::Start);
+ cursor.movePosition(QTextCursor::NextBlock);
+ QTextTable *table = cursor.currentTable();
+ QVERIFY(table);
+ QCOMPARE(table->columns(), 2);
+ QCOMPARE(table->rows(), 2);
}
}
@@ -4004,5 +4005,11 @@ void tst_QTextDocumentFragment::html_fromFirefox()
QCOMPARE(doc->toPlainText(), QString::fromLatin1("Test Text "));
}
+void tst_QTextDocumentFragment::html_emptyInlineInsideBlock()
+{
+ doc->setHtml(QString::fromLatin1("<!--StartFragment--><blockquote><span/>Foobar</blockquote><!--EndFragment-->"));
+ QVERIFY(doc->firstBlock().blockFormat().leftMargin() > 0);
+}
+
QTEST_MAIN(tst_QTextDocumentFragment)
#include "tst_qtextdocumentfragment.moc"
diff --git a/tests/auto/gui/text/qtextformat/qtextformat.pro b/tests/auto/gui/text/qtextformat/qtextformat.pro
index b137dac9eb..c64d266916 100644
--- a/tests/auto/gui/text/qtextformat/qtextformat.pro
+++ b/tests/auto/gui/text/qtextformat/qtextformat.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
CONFIG += parallel_test
TARGET = tst_qtextformat
-QT += testlib
+QT += testlib core-private gui-private
SOURCES += tst_qtextformat.cpp
diff --git a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
index 1eb073d3b4..beb5069f06 100644
--- a/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
+++ b/tests/auto/gui/text/qtextformat/tst_qtextformat.cpp
@@ -46,6 +46,7 @@
#include <qdebug.h>
#include <qsettings.h>
#include <qtextformat.h>
+#include <private/qtextformat_p.h>
#include <qtextdocument.h>
#include <qtextcursor.h>
#include <qtextobject.h>
@@ -68,6 +69,10 @@ private slots:
void getSetTabs();
void testTabsUsed();
void testFontStyleSetters();
+ void setFont_data();
+ void setFont();
+ void setFont_collection_data();
+ void setFont_collection();
};
/*! \internal
@@ -410,5 +415,243 @@ void tst_QTextFormat::testFontStyleSetters()
QCOMPARE(format.font().kerning(), false);
}
+Q_DECLARE_METATYPE(QTextCharFormat)
+
+void tst_QTextFormat::setFont_data()
+{
+ QTest::addColumn<QTextCharFormat>("format1");
+ QTest::addColumn<QTextCharFormat>("format2");
+ QTest::addColumn<bool>("overrideAll");
+
+ QTextCharFormat format1;
+ format1.setFontStyleHint(QFont::Serif);
+ format1.setFontStyleStrategy(QFont::PreferOutline);
+ format1.setFontCapitalization(QFont::AllUppercase);
+ format1.setFontKerning(true);
+
+ {
+ QTest::newRow("noop|override") << format1 << format1 << true;
+ QTest::newRow("noop|inherit") << format1 << format1 << false;
+ }
+
+ {
+ QTextCharFormat format2;
+ format2.setFontStyleHint(QFont::SansSerif);
+ format2.setFontStyleStrategy(QFont::PreferAntialias);
+ format2.setFontCapitalization(QFont::MixedCase);
+ format2.setFontKerning(false);
+
+ QTest::newRow("coverage|override") << format1 << format2 << true;
+ QTest::newRow("coverage|inherit") << format1 << format2 << false;
+ }
+
+ {
+ QTextCharFormat format2;
+ format2.setFontStyleHint(QFont::SansSerif);
+ format2.setFontStyleStrategy(QFont::PreferAntialias);
+
+ QTest::newRow("partial|override") << format1 << format2 << true;
+ QTest::newRow("partial|inherit") << format1 << format2 << false;
+ }
+}
+
+void tst_QTextFormat::setFont()
+{
+ QFETCH(QTextCharFormat, format1);
+ QFETCH(QTextCharFormat, format2);
+ QFETCH(bool, overrideAll);
+
+ QTextCharFormat f;
+
+ f.merge(format1);
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ f.merge(format2);
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ if (format2.hasProperty(QTextFormat::FontStyleHint))
+ QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint());
+ if (format2.hasProperty(QTextFormat::FontStyleStrategy))
+ QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy());
+ if (format2.hasProperty(QTextFormat::FontCapitalization))
+ QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization());
+ if (format2.hasProperty(QTextFormat::FontKerning))
+ QCOMPARE(f.font().kerning(), format2.fontKerning());
+ else
+ QCOMPARE(f.font().kerning(), format1.fontKerning());
+
+
+ QFont font1 = format1.font();
+ QFont font2 = format2.font();
+
+ f = QTextCharFormat();
+
+ {
+ QTextCharFormat tmp;
+ tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ f.merge(tmp);
+ }
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ {
+ QTextCharFormat tmp;
+ tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ f.merge(tmp);
+ }
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+
+ if (overrideAll || (font2.resolve() & QFont::StyleHintResolved))
+ QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint());
+ if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved))
+ QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy());
+ if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved))
+ QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization());
+ if (overrideAll || (font2.resolve() & QFont::KerningResolved))
+ QCOMPARE(f.font().kerning(), font2.kerning());
+ else
+ QCOMPARE(f.font().kerning(), font1.kerning());
+}
+
+void tst_QTextFormat::setFont_collection_data()
+{
+ setFont_data();
+}
+
+void tst_QTextFormat::setFont_collection()
+{
+ QFETCH(QTextCharFormat, format1);
+ QFETCH(QTextCharFormat, format2);
+ QFETCH(bool, overrideAll);
+
+ QFont font1 = format1.font();
+ QFont font2 = format2.font();
+
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ int formatIndex = collection.indexForFormat(format1);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+ }
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ int formatIndex = collection.indexForFormat(format2);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ if (format2.hasProperty(QTextFormat::FontStyleHint))
+ QCOMPARE((int)f.font().styleHint(), (int)format2.fontStyleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)format1.fontStyleHint());
+ if (format2.hasProperty(QTextFormat::FontStyleStrategy))
+ QCOMPARE((int)f.font().styleStrategy(), (int)format2.fontStyleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)format1.fontStyleStrategy());
+ if (format2.hasProperty(QTextFormat::FontCapitalization))
+ QCOMPARE((int)f.font().capitalization(), (int)format2.fontCapitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)format1.fontCapitalization());
+ if (format2.hasProperty(QTextFormat::FontKerning))
+ QCOMPARE(f.font().kerning(), format2.fontKerning());
+ else
+ QCOMPARE(f.font().kerning(), format1.fontKerning());
+ }
+
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ QTextCharFormat tmp;
+ tmp.setFont(font1, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ int formatIndex = collection.indexForFormat(tmp);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ QCOMPARE((int)f.fontStyleHint(), (int)format1.fontStyleHint());
+ QCOMPARE((int)f.fontStyleStrategy(), (int)format1.fontStyleStrategy());
+ QCOMPARE((int)f.fontCapitalization(), (int)format1.fontCapitalization());
+ QCOMPARE(f.fontKerning(), format1.fontKerning());
+
+ QCOMPARE((int)f.font().styleHint(), (int)f.fontStyleHint());
+ QCOMPARE((int)f.font().styleStrategy(), (int)f.fontStyleStrategy());
+ QCOMPARE((int)f.font().capitalization(), (int)f.fontCapitalization());
+ QCOMPARE(f.font().kerning(), f.fontKerning());
+ }
+ {
+ QTextFormatCollection collection;
+ collection.setDefaultFont(font1);
+
+ QTextCharFormat tmp;
+ tmp.setFont(font2, overrideAll ? QTextCharFormat::FontPropertiesAll
+ : QTextCharFormat::FontPropertiesSpecifiedOnly);
+ int formatIndex = collection.indexForFormat(tmp);
+ QTextCharFormat f = collection.charFormat(formatIndex);
+
+ if (overrideAll || (font2.resolve() & QFont::StyleHintResolved))
+ QCOMPARE((int)f.font().styleHint(), (int)font2.styleHint());
+ else
+ QCOMPARE((int)f.font().styleHint(), (int)font1.styleHint());
+ if (overrideAll || (font2.resolve() & QFont::StyleStrategyResolved))
+ QCOMPARE((int)f.font().styleStrategy(), (int)font2.styleStrategy());
+ else
+ QCOMPARE((int)f.font().styleStrategy(), (int)font1.styleStrategy());
+ if (overrideAll || (font2.resolve() & QFont::CapitalizationResolved))
+ QCOMPARE((int)f.font().capitalization(), (int)font2.capitalization());
+ else
+ QCOMPARE((int)f.font().capitalization(), (int)font1.capitalization());
+ if (overrideAll || (font2.resolve() & QFont::KerningResolved))
+ QCOMPARE(f.font().kerning(), font2.kerning());
+ else
+ QCOMPARE(f.font().kerning(), font1.kerning());
+ }
+}
+
QTEST_MAIN(tst_QTextFormat)
#include "tst_qtextformat.moc"
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
index 90137079f3..56d6711dc6 100644
--- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
+++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp
@@ -212,63 +212,63 @@ void tst_QTextLayout::lineBreaking()
{
#if 0
struct Breaks {
- const char *utf8;
- uchar breaks[32];
+ const char *utf8;
+ uchar breaks[32];
};
Breaks brks[] = {
- { "11", { false, 0xff } },
- { "aa", { false, 0xff } },
- { "++", { false, 0xff } },
- { "--", { false, 0xff } },
- { "((", { false, 0xff } },
- { "))", { false, 0xff } },
- { "..", { false, 0xff } },
- { "\"\"", { false, 0xff } },
- { "$$", { false, 0xff } },
- { "!!", { false, 0xff } },
- { "??", { false, 0xff } },
- { ",,", { false, 0xff } },
-
- { ")()", { true, false, 0xff } },
- { "?!?", { false, false, 0xff } },
- { ".,.", { false, false, 0xff } },
- { "+-+", { false, false, 0xff } },
- { "+=+", { false, false, 0xff } },
- { "+(+", { false, false, 0xff } },
- { "+)+", { false, false, 0xff } },
-
- { "a b", { false, true, 0xff } },
- { "a(b", { false, false, 0xff } },
- { "a)b", { false, false, 0xff } },
- { "a-b", { false, true, 0xff } },
- { "a.b", { false, false, 0xff } },
- { "a+b", { false, false, 0xff } },
- { "a?b", { false, false, 0xff } },
- { "a!b", { false, false, 0xff } },
- { "a$b", { false, false, 0xff } },
- { "a,b", { false, false, 0xff } },
- { "a/b", { false, false, 0xff } },
- { "1/2", { false, false, 0xff } },
- { "./.", { false, false, 0xff } },
- { ",/,", { false, false, 0xff } },
- { "!/!", { false, false, 0xff } },
- { "\\/\\", { false, false, 0xff } },
- { "1 2", { false, true, 0xff } },
- { "1(2", { false, false, 0xff } },
- { "1)2", { false, false, 0xff } },
- { "1-2", { false, false, 0xff } },
- { "1.2", { false, false, 0xff } },
- { "1+2", { false, false, 0xff } },
- { "1?2", { false, true, 0xff } },
- { "1!2", { false, true, 0xff } },
- { "1$2", { false, false, 0xff } },
- { "1,2", { false, false, 0xff } },
- { "1/2", { false, false, 0xff } },
- { "\330\260\331\216\331\204\331\220\331\203\331\216", { false, false, false, false, false, 0xff } },
- { "\330\247\331\204\331\205 \330\247\331\204\331\205", { false, false, false, true, false, false, 0xff } },
- { "1#2", { false, false, 0xff } },
- { "!#!", { false, false, 0xff } },
- { 0, {} }
+ { "11", { false, 0xff } },
+ { "aa", { false, 0xff } },
+ { "++", { false, 0xff } },
+ { "--", { false, 0xff } },
+ { "((", { false, 0xff } },
+ { "))", { false, 0xff } },
+ { "..", { false, 0xff } },
+ { "\"\"", { false, 0xff } },
+ { "$$", { false, 0xff } },
+ { "!!", { false, 0xff } },
+ { "??", { false, 0xff } },
+ { ",,", { false, 0xff } },
+
+ { ")()", { true, false, 0xff } },
+ { "?!?", { false, false, 0xff } },
+ { ".,.", { false, false, 0xff } },
+ { "+-+", { false, false, 0xff } },
+ { "+=+", { false, false, 0xff } },
+ { "+(+", { false, false, 0xff } },
+ { "+)+", { false, false, 0xff } },
+
+ { "a b", { false, true, 0xff } },
+ { "a(b", { false, false, 0xff } },
+ { "a)b", { false, false, 0xff } },
+ { "a-b", { false, true, 0xff } },
+ { "a.b", { false, false, 0xff } },
+ { "a+b", { false, false, 0xff } },
+ { "a?b", { false, false, 0xff } },
+ { "a!b", { false, false, 0xff } },
+ { "a$b", { false, false, 0xff } },
+ { "a,b", { false, false, 0xff } },
+ { "a/b", { false, false, 0xff } },
+ { "1/2", { false, false, 0xff } },
+ { "./.", { false, false, 0xff } },
+ { ",/,", { false, false, 0xff } },
+ { "!/!", { false, false, 0xff } },
+ { "\\/\\", { false, false, 0xff } },
+ { "1 2", { false, true, 0xff } },
+ { "1(2", { false, false, 0xff } },
+ { "1)2", { false, false, 0xff } },
+ { "1-2", { false, false, 0xff } },
+ { "1.2", { false, false, 0xff } },
+ { "1+2", { false, false, 0xff } },
+ { "1?2", { false, true, 0xff } },
+ { "1!2", { false, true, 0xff } },
+ { "1$2", { false, false, 0xff } },
+ { "1,2", { false, false, 0xff } },
+ { "1/2", { false, false, 0xff } },
+ { "\330\260\331\216\331\204\331\220\331\203\331\216", { false, false, false, false, false, 0xff } },
+ { "\330\247\331\204\331\205 \330\247\331\204\331\205", { false, false, false, true, false, false, 0xff } },
+ { "1#2", { false, false, 0xff } },
+ { "!#!", { false, false, 0xff } },
+ { 0, {} }
};
Breaks *b = brks;
while (b->utf8) {
diff --git a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp
index 10a25ba437..0628cc66d1 100644
--- a/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp
+++ b/tests/auto/gui/text/qtextlist/tst_qtextlist.cpp
@@ -119,7 +119,7 @@ void tst_QTextList::autoNumbering()
QVERIFY(list);
for (int i = 0; i < 27; ++i)
- cursor.insertBlock();
+ cursor.insertBlock();
QVERIFY(list->count() == 28);
diff --git a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp
index 3359cc8d32..5efb532233 100644
--- a/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp
+++ b/tests/auto/gui/text/qtextpiecetable/tst_qtextpiecetable.cpp
@@ -158,12 +158,12 @@ void tst_QTextPieceTable::insertion3()
{
QString compare;
for (int i = 0; i < 20000; ++i) {
- int pos = rand() % (i+1);
- QChar c((unsigned short)(i & 0xff) + 1);
- QString str;
- str += c;
- table->insert(pos, str, charFormatIndex);
- compare.insert(pos, str);
+ int pos = rand() % (i+1);
+ QChar c((unsigned short)(i & 0xff) + 1);
+ QString str;
+ str += c;
+ table->insert(pos, str, charFormatIndex);
+ compare.insert(pos, str);
}
QVERIFY(table->plainText() == compare);
}
@@ -172,17 +172,17 @@ void tst_QTextPieceTable::insertion4()
{
QString compare;
for (int i = 0; i < 20000; ++i) {
- int pos = rand() % (i+1);
- QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
- QString str;
- str += c;
- str += c;
- table->insert(pos, str, charFormatIndex);
- compare.insert(pos, str);
- // if (table->text() != compare) {
- // qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
- // exit(12);
- // }
+ int pos = rand() % (i+1);
+ QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
+ QString str;
+ str += c;
+ str += c;
+ table->insert(pos, str, charFormatIndex);
+ compare.insert(pos, str);
+// if (table->text() != compare) {
+// qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
+// exit(12);
+// }
}
QVERIFY(table->plainText() == compare);
}
@@ -191,23 +191,23 @@ void tst_QTextPieceTable::insertion5()
{
QString compare;
for (int i = 0; i < 20000; ++i) {
- int pos = rand() % (i+1);
- QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
- QString str;
- str += c;
- str += c;
- if (c == 'a') {
- table->insertBlock(pos, blockFormatIndex, charFormatIndex);
- str = QChar(QChar::ParagraphSeparator);
- } else {
- table->insert(pos, str, charFormatIndex);
- }
- compare.insert(pos, str);
+ int pos = rand() % (i+1);
+ QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
+ QString str;
+ str += c;
+ str += c;
+ if (c == 'a') {
+ table->insertBlock(pos, blockFormatIndex, charFormatIndex);
+ str = QChar(QChar::ParagraphSeparator);
+ } else {
+ table->insert(pos, str, charFormatIndex);
+ }
+ compare.insert(pos, str);
}
QVERIFY(table->plainText() == compare);
for (QTextBlock it = table->blocksBegin(); it != table->blocksEnd(); it = it.next()) {
- QTextDocumentPrivate::FragmentIterator fit = table->find(it.position());
- QVERIFY(fit.position() == it.position());
+ QTextDocumentPrivate::FragmentIterator fit = table->find(it.position());
+ QVERIFY(fit.position() == it.position());
}
}
@@ -249,24 +249,24 @@ void tst_QTextPieceTable::removal3()
QString compare;
int l = 0;
for (int i = 0; i < 20000; ++i) {
- bool remove = l && (rand() % 2);
- int pos = rand() % (remove ? l : (l+1));
- QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
- QString str;
- str += c;
- str += c;
- if (remove && pos < table->length()) {
- compare.remove(pos, 1);
- table->remove(pos, 1);
- } else {
- compare.insert(pos, str);
- table->insert(pos, str, charFormatIndex);
- }
- l += remove ? -1 : 2;
- // if (table->text() != compare) {
- // qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
- // exit(12);
- // }
+ bool remove = l && (rand() % 2);
+ int pos = rand() % (remove ? l : (l+1));
+ QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
+ QString str;
+ str += c;
+ str += c;
+ if (remove && pos < table->length()) {
+ compare.remove(pos, 1);
+ table->remove(pos, 1);
+ } else {
+ compare.insert(pos, str);
+ table->insert(pos, str, charFormatIndex);
+ }
+ l += remove ? -1 : 2;
+// if (table->text() != compare) {
+// qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->text().latin1());
+// exit(12);
+// }
}
QVERIFY(table->plainText() == compare);
}
@@ -276,31 +276,31 @@ void tst_QTextPieceTable::removal4()
QString compare;
int l = 0;
for (int i = 0; i < 20000; ++i) {
- bool remove = l && (rand() % 2);
- int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
- QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
- QString str;
- if (c != 'a') {
- str += c;
- str += c;
- } else {
- str = QChar(QChar::ParagraphSeparator);
- }
- if (remove && pos < table->length() - 1) {
- compare.remove(pos, 1);
- table->remove(pos, 1);
- } else {
- if (str[0] == QChar(QChar::ParagraphSeparator))
- table->insertBlock(pos, blockFormatIndex, charFormatIndex);
- else
- table->insert(pos, str, charFormatIndex);
- compare.insert(pos, str);
- }
- l += remove ? -1 : 2;
-// if (table->plainText() != compare) {
-// qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->plainText().latin1());
-// exit(12);
-// }
+ bool remove = l && (rand() % 2);
+ int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
+ QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
+ QString str;
+ if (c != 'a') {
+ str += c;
+ str += c;
+ } else {
+ str = QChar(QChar::ParagraphSeparator);
+ }
+ if (remove && pos < table->length() - 1) {
+ compare.remove(pos, 1);
+ table->remove(pos, 1);
+ } else {
+ if (str[0] == QChar(QChar::ParagraphSeparator))
+ table->insertBlock(pos, blockFormatIndex, charFormatIndex);
+ else
+ table->insert(pos, str, charFormatIndex);
+ compare.insert(pos, str);
+ }
+ l += remove ? -1 : 2;
+// if (table->plainText() != compare) {
+// qDebug("compare failed: i=%d (current char=%c) insert at %d\nexpected '%s'\ngot '%s'", i, (i % 26) + (i>25?'A':'a'), pos, compare.latin1(), table->plainText().latin1());
+// exit(12);
+// }
}
QVERIFY(table->plainText() == compare);
}
@@ -490,27 +490,27 @@ void tst_QTextPieceTable::undoRedo11()
QString compare;
int l = 0;
for (int i = 0; i < loops; ++i) {
- bool remove = l && (rand() % 2);
- int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
- QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
- QString str;
- str += c;
- str += c;
- if (remove) {
- compare.remove(pos, 1);
- table->remove(pos, 1);
- } else {
- compare.insert(pos, str);
- table->insert(pos, str, charFormatIndex);
- }
- l += remove ? -1 : 2;
+ bool remove = l && (rand() % 2);
+ int pos = (l > 1) ? rand() % (remove ? l-1 : l) : 0;
+ QChar c((unsigned short)((i % 26) + (i>25?'A':'a')));
+ QString str;
+ str += c;
+ str += c;
+ if (remove) {
+ compare.remove(pos, 1);
+ table->remove(pos, 1);
+ } else {
+ compare.insert(pos, str);
+ table->insert(pos, str, charFormatIndex);
+ }
+ l += remove ? -1 : 2;
}
QVERIFY(table->plainText() == compare);
for (int i = 0; i < loops; ++i)
- table->undo();
+ table->undo();
QVERIFY(table->plainText() == QString(""));
for (int i = 0; i < loops; ++i)
- table->redo();
+ table->redo();
QVERIFY(table->plainText() == compare);
}
diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
index eebac28323..74802c3217 100644
--- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
+++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp
@@ -1067,7 +1067,7 @@ void tst_QTextScriptEngine::controlInSyllable_qtbug14204()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(2));
- QVERIFY(e->layoutData->glyphLayout.advances_x[1] != 0);
+ QVERIFY(e->layoutData->glyphLayout.advances[1].toInt() != 0);
#endif
}
@@ -1087,8 +1087,7 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(4));
- QEXPECT_FAIL("", "QTBUG-23064", Abort);
- QVERIFY(e->layoutData->glyphLayout.advances_y[2] > 0);
+ QCOMPARE(e->layoutData->glyphLayout.advances[2].toInt(), 0);
#else
QFontDatabase db;
@@ -1106,7 +1105,7 @@ void tst_QTextScriptEngine::combiningMarks_qtbug15675()
e->shape(0);
QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(3));
- QVERIFY(e->layoutData->glyphLayout.advances_x[1] == 0);
+ QCOMPARE(e->layoutData->glyphLayout.advances[1].toInt(), 0);
#endif
}
diff --git a/tests/auto/network/access/qftp/tst_qftp.cpp b/tests/auto/network/access/qftp/tst_qftp.cpp
index 71af9690be..fffe663f0a 100644
--- a/tests/auto/network/access/qftp/tst_qftp.cpp
+++ b/tests/auto/network/access/qftp/tst_qftp.cpp
@@ -197,14 +197,18 @@ void tst_QFtp::initTestCase_data()
QTest::addColumn<bool>("setSession");
QTest::newRow("WithoutProxy") << false << 0 << false;
+#ifndef QT_NO_SOCKS5
QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy) << false;
+#endif
//### doesn't work well yet.
//QTest::newRow("WithHttpProxy") << true << int(QNetworkProxy::HttpProxy);
#ifndef QT_NO_BEARERMANAGEMENT
QTest::newRow("WithoutProxyWithSession") << false << 0 << true;
+#ifndef QT_NO_SOCKS5
QTest::newRow("WithSocks5ProxyAndSession") << true << int(QNetworkProxy::Socks5Proxy) << true;
#endif
+#endif
}
void tst_QFtp::initTestCase()
@@ -232,11 +236,16 @@ void tst_QFtp::init()
QFETCH_GLOBAL(int, proxyType);
QFETCH_GLOBAL(bool, setSession);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
if (proxyType == QNetworkProxy::Socks5Proxy) {
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080));
} else if (proxyType == QNetworkProxy::HttpProxy) {
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128));
}
+#else // !QT_NO_NETWORKPROXY
+ Q_UNUSED(proxyType);
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
#ifndef QT_NO_BEARERMANAGEMENT
if (setSession) {
@@ -293,7 +302,11 @@ void tst_QFtp::cleanup()
}
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#else
+ QSKIP("No proxy support");
+#endif
}
delete ftp;
@@ -749,14 +762,14 @@ void tst_QFtp::put()
QFETCH( QByteArray, fileData );
QFETCH( bool, useIODevice );
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(QT_NO_NETWORKPROXY)
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 the put() test takes too long time on Windows.");
}
-#endif
+#endif // OS_WIN && !QT_NO_NETWORKPROXY
const int timestep = 50;
diff --git a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
index 4ee4b67ec0..bcfe9f090f 100644
--- a/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
+++ b/tests/auto/network/access/qnetworkcookiejar/tst_qnetworkcookiejar.cpp
@@ -211,6 +211,17 @@ void tst_QNetworkCookieJar::setCookiesFromUrl_data()
result += cookie;
QTest::newRow("effective-tld2-accepted") << preset << cookie << "http://www.gobiernoelectronico.ar" << result << true;
+ result.clear();
+ preset.clear();
+ cookie.setDomain("127.0.0.1");
+ result += cookie;
+ QTest::newRow("IPv4-address-as-domain") << preset << cookie << "http://127.0.0.1/" << result << true;
+
+ result.clear();
+ preset.clear();
+ cookie.setDomain("fe80::250:56ff:fec0:1");
+ result += cookie;
+ QTest::newRow("IPv6-address-as-domain") << preset << cookie << "http://[fe80::250:56ff:fec0:1]/" << result << true;
// setting the defaults:
finalCookie = cookie;
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 291b368e47..8e13c1de6e 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -97,7 +97,9 @@ Q_DECLARE_METATYPE(QSharedPointer<char>)
#include "../../../network-settings.h"
Q_DECLARE_METATYPE(QAuthenticator*)
+#ifndef QT_NO_NETWORKPROXY
Q_DECLARE_METATYPE(QNetworkProxyQuery)
+#endif
typedef QSharedPointer<QNetworkReply> QNetworkReplyPtr;
@@ -106,6 +108,7 @@ class tst_QNetworkReply: public QObject
{
Q_OBJECT
+#ifndef QT_NO_NETWORKPROXY
struct ProxyData {
ProxyData(const QNetworkProxy &p, const QByteArray &t, bool auth)
: tag(t), proxy(p), requiresAuthentication(auth)
@@ -114,6 +117,7 @@ class tst_QNetworkReply: public QObject
QNetworkProxy proxy;
bool requiresAuthentication;
};
+#endif // !QT_NO_NETWORKPROXY
static bool seedCreated;
static QString createUniqueExtension() {
@@ -134,7 +138,9 @@ class tst_QNetworkReply: public QObject
QString wronlyFileName;
#endif
QString uniqueExtension;
+#ifndef QT_NO_NETWORKPROXY
QList<ProxyData> proxies;
+#endif
QNetworkAccessManager manager;
MyCookieJar *cookieJar;
#ifndef QT_NO_SSL
@@ -203,8 +209,10 @@ private Q_SLOTS:
void getFromHttp();
void getErrors_data();
void getErrors();
+#ifndef QT_NO_NETWORKPROXY
void headFromHttp_data();
void headFromHttp();
+#endif // !QT_NO_NETWORKPROXY
void putToFile_data();
void putToFile();
void putToFtp_data();
@@ -261,9 +269,11 @@ private Q_SLOTS:
void ioGetFromHttpWithAuth_data();
void ioGetFromHttpWithAuth();
void ioGetFromHttpWithAuthSynchronous();
+#ifndef QT_NO_NETWORKPROXY
void ioGetFromHttpWithProxyAuth();
void ioGetFromHttpWithProxyAuthSynchronous();
void ioGetFromHttpWithSocksProxy();
+#endif // !QT_NO_NETWORKPROXY
#ifndef QT_NO_SSL
void ioGetFromHttpsWithSslErrors();
void ioGetFromHttpsWithIgnoreSslErrors();
@@ -278,8 +288,10 @@ private Q_SLOTS:
void ioGetFromHttpWithCache_data();
void ioGetFromHttpWithCache();
+#ifndef QT_NO_NETWORKPROXY
void ioGetWithManyProxies_data();
void ioGetWithManyProxies();
+#endif // !QT_NO_NETWORKPROXY
void ioPutToFileFromFile_data();
void ioPutToFileFromFile();
@@ -297,10 +309,12 @@ private Q_SLOTS:
void ioPutToHttpFromFile();
void ioPostToHttpFromFile_data();
void ioPostToHttpFromFile();
+#ifndef QT_NO_NETWORKPROXY
void ioPostToHttpFromSocket_data();
void ioPostToHttpFromSocket();
void ioPostToHttpFromSocketSynchronous();
void ioPostToHttpFromSocketSynchronous_data();
+#endif // !QT_NO_NETWORKPROXY
void ioPostToHttpFromMiddleOfFileToEnd();
void ioPostToHttpFromMiddleOfFileFiveBytes();
void ioPostToHttpFromMiddleOfQBufferFiveBytes();
@@ -339,11 +353,13 @@ private Q_SLOTS:
void nestedEventLoops();
+#ifndef QT_NO_NETWORKPROXY
void httpProxyCommands_data();
void httpProxyCommands();
void httpProxyCommandsSynchronous_data();
void httpProxyCommandsSynchronous();
void proxyChange();
+#endif // !QT_NO_NETWORKPROXY
void authorizationError_data();
void authorizationError();
@@ -419,9 +435,11 @@ private Q_SLOTS:
void dontInsertPartialContentIntoTheCache();
void httpUserAgent();
+#ifndef QT_NO_NETWORKPROXY
void authenticationCacheAfterCancel_data();
void authenticationCacheAfterCancel();
void authenticationWithDifferentRealm();
+#endif // !QT_NO_NETWORKPROXY
void synchronousAuthenticationCache();
void pipelining();
@@ -638,6 +656,7 @@ public:
{ QNetworkCookieJar::setAllCookies(cookieList); }
};
+#ifndef QT_NO_NETWORKPROXY
class MyProxyFactory: public QNetworkProxyFactory
{
public:
@@ -660,6 +679,7 @@ public:
return toReturn;
}
};
+#endif // !QT_NO_NETWORKPROXY
class MyMemoryCache: public QAbstractNetworkCache
{
@@ -1154,7 +1174,9 @@ tst_QNetworkReply::tst_QNetworkReply()
{
qRegisterMetaType<QNetworkReply *>(); // for QSignalSpy
qRegisterMetaType<QAuthenticator *>();
+#ifndef QT_NO_NETWORKPROXY
qRegisterMetaType<QNetworkProxy>();
+#endif
#ifndef QT_NO_SSL
qRegisterMetaType<QList<QSslError> >();
#endif
@@ -1165,6 +1187,7 @@ tst_QNetworkReply::tst_QNetworkReply()
cookieJar = new MyCookieJar;
manager.setCookieJar(cookieJar);
+#ifndef QT_NO_NETWORKPROXY
QHostInfo hostInfo = QHostInfo::fromName(QtNetworkSettings::serverName());
proxies << ProxyData(QNetworkProxy::NoProxy, "", false);
@@ -1178,10 +1201,13 @@ tst_QNetworkReply::tst_QNetworkReply()
<< ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1080), "+socks", false)
<< ProxyData(QNetworkProxy(QNetworkProxy::Socks5Proxy, proxyserver, 1081), "+socksauth", true);
} else {
+#endif // !QT_NO_NETWORKPROXY
printf("==================================================================\n");
printf("Proxy could not be looked up. No proxy will be used while testing!\n");
printf("==================================================================\n");
+#ifndef QT_NO_NETWORKPROXY
}
+#endif // !QT_NO_NETWORKPROXY
}
tst_QNetworkReply::~tst_QNetworkReply()
@@ -1438,7 +1464,9 @@ void tst_QNetworkReply::cleanup()
// clear the internal cache
manager.clearAccessCache();
+#ifndef QT_NO_NETWORKPROXY
manager.setProxy(QNetworkProxy());
+#endif
manager.setCache(0);
// clear cookies
@@ -1732,6 +1760,7 @@ void tst_QNetworkReply::getFromHttp()
QCOMPARE(reply->readAll(), reference.readAll());
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::headFromHttp_data()
{
QTest::addColumn<qint64>("referenceSize");
@@ -1790,6 +1819,7 @@ void tst_QNetworkReply::headFromHttp()
if (reply->header(QNetworkRequest::ContentTypeHeader).isValid())
QCOMPARE(reply->header(QNetworkRequest::ContentTypeHeader).toString(), contentType);
}
+#endif // !QT_NO_NETWORKPROXY
void tst_QNetworkReply::getErrors_data()
{
@@ -2826,9 +2856,9 @@ void tst_QNetworkReply::sendCustomRequestToHttp_data()
QTest::newRow("trace") << QUrl("http://" + QtNetworkSettings::serverName()) <<
QByteArray("TRACE") << (QBuffer *) 0 << 200 << QNetworkReply::NoError << QByteArray();
QTest::newRow("connect") << QUrl("http://" + QtNetworkSettings::serverName()) <<
- QByteArray("CONNECT") << (QBuffer *) 0 << 400 << QNetworkReply::UnknownContentError << QByteArray(); // 400 = Bad Request
+ QByteArray("CONNECT") << (QBuffer *) 0 << 400 << QNetworkReply::ProtocolInvalidOperationError << QByteArray(); // 400 = Bad Request
QTest::newRow("nonsense") << QUrl("http://" + QtNetworkSettings::serverName()) <<
- QByteArray("NONSENSE") << (QBuffer *) 0 << 501 << QNetworkReply::ProtocolUnknownError << QByteArray(); // 501 = Method Not Implemented
+ QByteArray("NONSENSE") << (QBuffer *) 0 << 501 << QNetworkReply::OperationNotImplementedError << QByteArray(); // 501 = Method Not Implemented
QByteArray ba("test");
QBuffer *buffer = new QBuffer;
@@ -3270,6 +3300,7 @@ void tst_QNetworkReply::ioGetFromHttpWithAuthSynchronous()
QCOMPARE(replySync->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 401);
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::ioGetFromHttpWithProxyAuth()
{
// This test sends three requests
@@ -3432,6 +3463,7 @@ void tst_QNetworkReply::ioGetFromHttpWithSocksProxy()
QCOMPARE(authspy.count(), 0);
}
}
+#endif // !QT_NO_NETWORKPROXY
#ifndef QT_NO_SSL
void tst_QNetworkReply::ioGetFromHttpsWithSslErrors()
@@ -3793,6 +3825,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache()
QCOMPARE(reply->readAll().constData(), qPrintable(body));
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::ioGetWithManyProxies_data()
{
QTest::addColumn<QList<QNetworkProxy> >("proxyList");
@@ -4054,6 +4087,7 @@ void tst_QNetworkReply::ioGetWithManyProxies()
QCOMPARE(authspy.count(), 0);
}
}
+#endif // !QT_NO_NETWORKPROXY
void tst_QNetworkReply::ioPutToFileFromFile_data()
{
@@ -4346,6 +4380,7 @@ void tst_QNetworkReply::ioPostToHttpFromFile()
QCOMPARE(reply->readAll().trimmed(), md5sum(sourceFile.readAll()).toHex());
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::ioPostToHttpFromSocket_data()
{
QTest::addColumn<QByteArray>("data");
@@ -4496,6 +4531,7 @@ void tst_QNetworkReply::ioPostToHttpFromSocketSynchronous()
QCOMPARE(reply->readAll().trimmed(), md5sum(data).toHex());
}
+#endif // !QT_NO_NETWORKPROXY
// this tests checks if rewinding the POST-data to some place in the middle
// worked.
@@ -5410,6 +5446,7 @@ void tst_QNetworkReply::nestedEventLoops()
QCOMPARE(errorspy.count(), 0);
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::httpProxyCommands_data()
{
QTest::addColumn<QUrl>("url");
@@ -5485,6 +5522,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous_data()
{
httpProxyCommands_data();
}
+#endif // !QT_NO_NETWORKPROXY
struct QThreadCleanup
{
@@ -5506,6 +5544,7 @@ struct QDeleteLaterCleanup
}
};
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::httpProxyCommandsSynchronous()
{
QFETCH(QUrl, url);
@@ -5586,6 +5625,7 @@ void tst_QNetworkReply::proxyChange()
QVERIFY(int(reply3->error()) > 0);
}
+#endif // !QT_NO_NETWORKPROXY
void tst_QNetworkReply::authorizationError_data()
{
@@ -6502,6 +6542,7 @@ void tst_QNetworkReply::qtbug4121unknownAuthentication()
QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError);
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QNetworkReply::authenticationCacheAfterCancel_data()
{
QTest::addColumn<QNetworkProxy>("proxy");
@@ -6715,6 +6756,7 @@ void tst_QNetworkReply::authenticationWithDifferentRealm()
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(reply->error(), QNetworkReply::NoError);
}
+#endif // !QT_NO_NETWORKPROXY
class QtBug13431Helper : public QObject {
Q_OBJECT
diff --git a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
index 5dede11e5b..8d222965eb 100644
--- a/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
+++ b/tests/auto/network/bearer/qnetworksession/test/tst_qnetworksession.cpp
@@ -749,7 +749,7 @@ void tst_QNetworkSession::sessionOpenCloseStop()
} else if (state == QNetworkSession::Disconnected) {
QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), TestTimeOut);
QTRY_VERIFY_WITH_TIMEOUT(session2.state() == QNetworkSession::Disconnected, TestTimeOut);
- } else if (state == QNetworkSession::Connected) {
+ } else if (state == QNetworkSession::Connected) {
QTRY_VERIFY_WITH_TIMEOUT(errorSpy.isEmpty(),TestTimeOut);
if (stateChangedSpy.count() > 1) {
@@ -1121,13 +1121,13 @@ bool openSession(QNetworkSession *session) {
}
if (session->configuration().state() != QNetworkConfiguration::Active) {
qDebug("tst_QNetworkSession::openSession() failure: session's configuration is not in 'Active' -state.");
- qDebug() << "tst_QNetworkSession::openSession() state is: " << session->configuration().state();
+ qDebug() << "tst_QNetworkSession::openSession() state is: " << session->configuration().state();
result = false;
}
if (result == false) {
- qDebug() << "tst_QNetworkSession::openSession() opening session failed.";
+ qDebug() << "tst_QNetworkSession::openSession() opening session failed.";
} else {
- qDebug() << "tst_QNetworkSession::openSession() opening session succeeded.";
+ qDebug() << "tst_QNetworkSession::openSession() opening session succeeded.";
}
qDebug() << "tst_QNetworkSession::openSession() name of the configuration is: " << session->configuration().name();
qDebug() << "tst_QNetworkSession::openSession() configuration state is: " << session->configuration().state();
@@ -1196,9 +1196,9 @@ bool closeSession(QNetworkSession *session, bool lastSessionOnConfiguration) {
result = false;
}
if (result == false) {
- qDebug() << "tst_QNetworkSession::closeSession() closing session failed.";
+ qDebug() << "tst_QNetworkSession::closeSession() closing session failed.";
} else {
- qDebug() << "tst_QNetworkSession::closeSession() closing session succeeded.";
+ qDebug() << "tst_QNetworkSession::closeSession() closing session succeeded.";
}
qDebug() << "tst_QNetworkSession::closeSession() name of the configuration is: " << session->configuration().name();
qDebug() << "tst_QNetworkSession::closeSession() configuration state is: " << session->configuration().state();
diff --git a/tests/auto/network/kernel/kernel.pro b/tests/auto/network/kernel/kernel.pro
index 14080a0548..8594ad5932 100644
--- a/tests/auto/network/kernel/kernel.pro
+++ b/tests/auto/network/kernel/kernel.pro
@@ -10,6 +10,10 @@ SUBDIRS=\
qnetworkaddressentry \
qhostaddress \
+winrt: SUBDIRS -= \
+ qnetworkproxy \
+ qnetworkproxyfactory \
+
!contains(QT_CONFIG, private_tests): SUBDIRS -= \
qauthenticator \
qhostinfo \
diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
index dd9202c748..c4d42206fe 100644
--- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
+++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
@@ -50,6 +50,9 @@
#include <qdatastream.h>
#ifdef Q_OS_WIN
# include <qt_windows.h>
+# if defined(Q_OS_WINRT)
+# include <winsock2.h>
+# endif
#endif
class tst_QHostAddress : public QObject
@@ -336,12 +339,15 @@ void tst_QHostAddress::assignment()
address = "::1";
QCOMPARE(address, QHostAddress("::1"));
+ // WinRT does not support sockaddr_in
+#ifndef Q_OS_WINRT
QHostAddress addr("4.2.2.1");
sockaddr_in sockAddr;
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = htonl(addr.toIPv4Address());
address.setAddress((sockaddr *)&sockAddr);
QCOMPARE(address, addr);
+#endif // !Q_OS_WINRT
}
void tst_QHostAddress::scopeId()
diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro
index b6f5c2badb..3b217f6e7b 100644
--- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro
+++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro
@@ -13,7 +13,7 @@ wince*: {
}
# needed for getaddrinfo with official MinGW
-win32-g++*:DEFINES += _WIN32_WINNT=0x0501
+mingw:DEFINES += _WIN32_WINNT=0x0501
linux-*:CONFIG+=insignificant_test # QTBUG-23837 - test is unstable
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
index e81c7f71db..e3156ceb3f 100644
--- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
+++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp
@@ -67,7 +67,7 @@
#include <time.h>
#include <qlibrary.h>
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN)
#include <windows.h>
#else
#include <unistd.h>
diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
index f474f97f5d..35028735e2 100644
--- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
+++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp
@@ -64,7 +64,11 @@
#define PLATFORMSOCKETENGINE QNativeSocketEngine
#define PLATFORMSOCKETENGINESTRING "QNativeSocketEngine"
-#include <private/qnativesocketengine_p.h>
+#ifndef Q_OS_WINRT
+# include <private/qnativesocketengine_p.h>
+#else
+# include <private/qnativesocketengine_winrt_p.h>
+#endif
#include <qstringlist.h>
@@ -97,7 +101,9 @@ private slots:
void networkError();
void setSocketDescriptor();
void invalidSend();
+#ifndef Q_OS_WINRT
void receiveUrgentData();
+#endif
void tooManySockets();
};
@@ -608,7 +614,9 @@ void tst_PlatformSocketEngine::networkError()
QVERIFY(client.state() == QAbstractSocket::ConnectedState);
// An unexpected network error!
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WINRT
+ client.close();
+#elif defined(Q_OS_WIN)
// could use shutdown to produce different errors
::closesocket(client.socketDescriptor());
#else
@@ -641,6 +649,7 @@ void tst_PlatformSocketEngine::invalidSend()
}
//---------------------------------------------------------------------------
+#ifndef Q_OS_WINRT
void tst_PlatformSocketEngine::receiveUrgentData()
{
PLATFORMSOCKETENGINE server;
@@ -703,6 +712,7 @@ void tst_PlatformSocketEngine::receiveUrgentData()
QCOMPARE(response.at(0), msg);
#endif
}
+#endif // !Q_OS_WINRT
QTEST_MAIN(tst_PlatformSocketEngine)
#include "tst_platformsocketengine.moc"
diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
index 9887acf7dd..6053021cf4 100644
--- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp
@@ -1026,7 +1026,7 @@ void tst_QLocalSocket::writeToClientAndDisconnect()
void tst_QLocalSocket::debug()
{
// Make sure this compiles
- QTest::ignoreMessage(QtDebugMsg, "QLocalSocket::ConnectionRefusedError QLocalSocket::UnconnectedState ");
+ QTest::ignoreMessage(QtDebugMsg, "QLocalSocket::ConnectionRefusedError QLocalSocket::UnconnectedState");
qDebug() << QLocalSocket::ConnectionRefusedError << QLocalSocket::UnconnectedState;
}
diff --git a/tests/auto/network/socket/qtcpserver/crashingServer/crashingServer.pro b/tests/auto/network/socket/qtcpserver/crashingServer/crashingServer.pro
index 3f3e5ba3d4..23b36ddade 100644
--- a/tests/auto/network/socket/qtcpserver/crashingServer/crashingServer.pro
+++ b/tests/auto/network/socket/qtcpserver/crashingServer/crashingServer.pro
@@ -5,5 +5,5 @@ DESTDIR = ./
# This means the auto test works on some machines for MinGW. No dialog stalls
# the application.
-win32-g++*:CONFIG += console
+mingw:CONFIG += console
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
index d838b463f7..10b41ced9e 100644
--- a/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/auto/network/socket/qtcpserver/tst_qtcpserver.cpp
@@ -100,16 +100,20 @@ private slots:
void maxPendingConnections();
void listenError();
void waitForConnectionTest();
+#ifndef Q_OS_WINRT
void setSocketDescriptor();
+#endif
void listenWhileListening();
#ifndef QT_NO_PROCESS
void addressReusable();
#endif
void setNewSocketDescriptorBlocking();
+#ifndef QT_NO_NETWORKPROXY
void invalidProxy_data();
void invalidProxy();
void proxyFactory_data();
void proxyFactory();
+#endif // !QT_NO_NETWORKPROXY
void qtbug14268_peek();
@@ -158,7 +162,9 @@ void tst_QTcpServer::initTestCase_data()
QTest::addColumn<int>("proxyType");
QTest::newRow("WithoutProxy") << false << 0;
+#ifndef QT_NO_SOCKS5
QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy);
+#endif
crashingServerDir = QFINDTESTDATA("crashingServer");
QVERIFY2(!crashingServerDir.isEmpty(), qPrintable(
@@ -181,16 +187,22 @@ void tst_QTcpServer::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy) {
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080));
}
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
}
void tst_QTcpServer::cleanup()
{
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#endif
}
//----------------------------------------------------------------------------------
@@ -369,9 +381,13 @@ void tst_QTcpServer::maxPendingConnections()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 only 1 connection is allowed ever");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
//### sees to fail sometimes ... a timing issue with the test on windows
QTcpServer server;
@@ -407,9 +423,13 @@ void tst_QTcpServer::listenError()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 we can not make hard requirements on the address or port");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif //QT_NO_NETWORKPROXY
}
QTcpServer server;
QVERIFY(!server.listen(QHostAddress("1.2.3.4"), 0));
@@ -453,9 +473,13 @@ void tst_QTcpServer::waitForConnectionTest()
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("Localhost servers don't work well with SOCKS5");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
QTcpSocket findLocalIpSocket;
@@ -481,6 +505,7 @@ void tst_QTcpServer::waitForConnectionTest()
}
//----------------------------------------------------------------------------------
+#ifndef Q_OS_WINRT
void tst_QTcpServer::setSocketDescriptor()
{
QTcpServer server;
@@ -510,6 +535,7 @@ void tst_QTcpServer::setSocketDescriptor()
WSACleanup();
#endif
}
+#endif // !Q_OS_WINRT
//----------------------------------------------------------------------------------
void tst_QTcpServer::listenWhileListening()
@@ -531,6 +557,7 @@ public:
bool ok;
protected:
+#ifndef Q_OS_WINRT
void incomingConnection(qintptr socketDescriptor)
{
// how a user woulddo it (qabstractsocketengine is not public)
@@ -543,6 +570,7 @@ protected:
::close(socketDescriptor);
#endif
}
+#endif // !Q_OS_WINRT
};
#ifndef QT_NO_PROCESS
@@ -550,9 +578,13 @@ void tst_QTcpServer::addressReusable()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 this test does not make senans at the momment");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
#if defined(Q_OS_WINCE)
QString signalName = QString::fromLatin1("/test_signal.txt");
@@ -596,9 +628,13 @@ void tst_QTcpServer::setNewSocketDescriptorBlocking()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 we can not make the socket descripter blocking");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
SeverWithBlockingSockets server;
QVERIFY(server.listen());
@@ -609,6 +645,7 @@ void tst_QTcpServer::setNewSocketDescriptorBlocking()
QVERIFY(server.ok);
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QTcpServer::invalidProxy_data()
{
QTest::addColumn<int>("type");
@@ -763,6 +800,7 @@ void tst_QTcpServer::proxyFactory()
// Sometimes, error codes change for the better
QTEST(int(server.serverError()), "expectedError");
}
+#endif // !QT_NO_NETWORKPROXY
class Qtbug14268Helper : public QObject
{
diff --git a/tests/auto/network/socket/qtcpsocket/stressTest/Test.h b/tests/auto/network/socket/qtcpsocket/stressTest/Test.h
index 1982244c1e..20ccf0d0cd 100644
--- a/tests/auto/network/socket/qtcpsocket/stressTest/Test.h
+++ b/tests/auto/network/socket/qtcpsocket/stressTest/Test.h
@@ -92,4 +92,4 @@ public:
};
//------------------------------------------------------------------------------
-#endif // TEST_H
+#endif // TEST_H
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index b6df536b98..e589d520cb 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -132,7 +132,9 @@ private slots:
void bind_data();
void bind();
void setInvalidSocketDescriptor();
+#ifndef Q_OS_WINRT
void setSocketDescriptor();
+#endif
void socketDescriptor();
void blockingIMAP();
void nonBlockingIMAP();
@@ -187,14 +189,17 @@ private slots:
void connectToMultiIP();
void moveToThread0();
void increaseReadBufferSize();
+ void increaseReadBufferSizeFromSlot();
void taskQtBug5799ConnectionErrorWaitForConnected();
void taskQtBug5799ConnectionErrorEventLoop();
void taskQtBug7054TimeoutErrorResetting();
+#ifndef QT_NO_NETWORKPROXY
void invalidProxy_data();
void invalidProxy();
void proxyFactory_data();
void proxyFactory();
+#endif // !QT_NO_NETWORKPROXY
void qtbug14268_peek();
@@ -216,9 +221,12 @@ protected slots:
void hostLookupSlot();
void abortiveClose_abortSlot();
void remoteCloseErrorSlot();
+#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
+#endif
void earlySocketBytesSent(qint64 bytes);
void earlySocketReadyRead();
+ void slotIncreaseReadBufferSizeReadyRead();
private:
QByteArray expectedReplyIMAP();
@@ -354,6 +362,7 @@ void tst_QTcpSocket::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
QList<QHostAddress> addresses = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses();
QVERIFY2(addresses.count() > 0, "failed to get ip address for test server");
@@ -382,6 +391,9 @@ void tst_QTcpSocket::init()
break;
}
QNetworkProxy::setApplicationProxy(proxy);
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
qt_qhostinfo_clear_cache();
@@ -406,15 +418,19 @@ QTcpSocket *tst_QTcpSocket::newSocket() const
void tst_QTcpSocket::cleanup()
{
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#endif
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QTcpSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
{
++proxyAuthCalled;
auth->setUser("qsockstest");
auth->setPassword("password");
}
+#endif // !QT_NO_NETWORKPROXY
//----------------------------------------------------------------------------------
@@ -552,6 +568,7 @@ void tst_QTcpSocket::setInvalidSocketDescriptor()
//----------------------------------------------------------------------------------
+#ifndef Q_OS_WINRT
void tst_QTcpSocket::setSocketDescriptor()
{
QFETCH_GLOBAL(bool, setProxy);
@@ -596,6 +613,7 @@ void tst_QTcpSocket::setSocketDescriptor()
delete dummy;
#endif
}
+#endif // !Q_OS_WINRT
//----------------------------------------------------------------------------------
@@ -1546,7 +1564,9 @@ void tst_QTcpSocket::synchronousApi()
void tst_QTcpSocket::dontCloseOnTimeout()
{
QTcpServer server;
+#ifndef QT_NO_NETWORKPROXY
server.setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
+#endif
QVERIFY(server.listen());
QHostAddress serverAddress = QHostAddress::LocalHost;
@@ -1673,11 +1693,13 @@ private slots:
{
quit();
}
+#ifndef QT_NO_NETWORKPROXY
inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
{
auth->setUser("qsockstest");
auth->setPassword("password");
}
+#endif // !QT_NO_NETWORKPROXY
private:
int exitCode;
QTcpSocket *socket;
@@ -1970,11 +1992,13 @@ public slots:
tst_QTcpSocket::exitLoop();
}
+#ifndef QT_NO_NETWORKPROXY
inline void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
{
auth->setUser("qsockstest");
auth->setPassword("password");
}
+#endif // !QT_NO_NETWORKPROXY
};
//----------------------------------------------------------------------------------
@@ -2437,6 +2461,57 @@ void tst_QTcpSocket::increaseReadBufferSize()
delete active;
}
+void tst_QTcpSocket::increaseReadBufferSizeFromSlot() // like KIO's socketconnectionbackend
+{
+ QFETCH_GLOBAL(bool, setProxy);
+ if (setProxy)
+ return; //proxy not useful for localhost test case
+ QTcpServer server;
+ QTcpSocket *active = newSocket();
+ connect(active, SIGNAL(readyRead()), SLOT(slotIncreaseReadBufferSizeReadyRead()));
+
+ // connect two sockets to each other:
+ QVERIFY(server.listen(QHostAddress::LocalHost));
+ active->connectToHost("127.0.0.1", server.serverPort());
+ QVERIFY(active->waitForConnected(5000));
+ QVERIFY(server.waitForNewConnection(5000));
+
+ QTcpSocket *passive = server.nextPendingConnection();
+ QVERIFY(passive);
+
+ // now write 512 bytes of data on one end
+ QByteArray data(512, 'a');
+ passive->write(data);
+ QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
+
+ // set the read buffer size to less than what was written,
+ // and increase it from the slot, first to 384 then to 1024.
+ active->setReadBufferSize(256);
+ enterLoop(10);
+ QVERIFY2(!timeout(), "Network timeout");
+ QCOMPARE(active->bytesAvailable(), qint64(data.size()));
+
+ // drain it and compare
+ QCOMPARE(active->readAll(), data);
+
+ delete active;
+}
+
+void tst_QTcpSocket::slotIncreaseReadBufferSizeReadyRead()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
+ const int currentBufferSize = socket->readBufferSize();
+ QCOMPARE(currentBufferSize, socket->bytesAvailable());
+ if (currentBufferSize == 256)
+ socket->setReadBufferSize(384);
+ else if (currentBufferSize == 384)
+ socket->setReadBufferSize(512);
+ else if (currentBufferSize == 512)
+ exitLoopSlot();
+ else // should not happen
+ qFatal("buffer size was %d", currentBufferSize);
+}
+
void tst_QTcpSocket::taskQtBug5799ConnectionErrorWaitForConnected()
{
QFETCH_GLOBAL(bool, setProxy);
@@ -2500,6 +2575,7 @@ void tst_QTcpSocket::taskQtBug7054TimeoutErrorResetting()
QVERIFY(socket->error() == QAbstractSocket::RemoteHostClosedError);
}
+#ifndef QT_NO_NETWORKPROXY
void tst_QTcpSocket::invalidProxy_data()
{
QTest::addColumn<int>("type");
@@ -2676,6 +2752,7 @@ void tst_QTcpSocket::proxyFactory()
delete socket;
}
+#endif // !QT_NO_NETWORKPROXY
// there is a similar test inside tst_qtcpserver that uses the event loop instead
void tst_QTcpSocket::qtbug14268_peek()
diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
index f08afaa9a5..f3cae6f4eb 100644
--- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
+++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp
@@ -162,8 +162,10 @@ void tst_QUdpSocket::initTestCase_data()
QTest::addColumn<int>("proxyType");
QTest::newRow("WithoutProxy") << false << 0;
+#ifndef QT_NO_SOCKS5
if (!newTestServer)
QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy);
+#endif
#ifndef QT_NO_BEARERMANAGEMENT
netConfMan = new QNetworkConfigurationManager(this);
@@ -186,16 +188,22 @@ void tst_QUdpSocket::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_SOCKS5
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy) {
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080));
}
+#else
+ QSKIP("No proxy support");
+#endif // !QT_NO_SOCKS5
}
}
void tst_QUdpSocket::cleanup()
{
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#endif // !QT_NO_NETWORKPROXY
}
@@ -265,9 +273,13 @@ void tst_QUdpSocket::broadcasting()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 Broadcast is not supported.");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
#ifdef Q_OS_AIX
QSKIP("Broadcast does not work on darko");
@@ -761,9 +773,13 @@ void tst_QUdpSocket::bindMode()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy)
QSKIP("With socks5 explicit port binding is not supported.");
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
QUdpSocket socket;
diff --git a/tests/auto/network/socket/socket.pro b/tests/auto/network/socket/socket.pro
index 6d86eab209..436ebe5c7f 100644
--- a/tests/auto/network/socket/socket.pro
+++ b/tests/auto/network/socket/socket.pro
@@ -14,3 +14,7 @@ SUBDIRS=\
qtcpsocket \
qhttpsocketengine \
qsocks5socketengine \
+
+winrt: SUBDIRS -= \
+ qhttpsocketengine \
+ qsocks5socketengine \
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index d19e08178a..6eb20dd1f5 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -111,7 +111,9 @@ public slots:
void initTestCase();
void init();
void cleanup();
+#ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth);
+#endif
#ifndef QT_NO_SSL
private slots:
@@ -276,6 +278,7 @@ void tst_QSslSocket::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
QString fluke = QHostInfo::fromName(QtNetworkSettings::serverName()).addresses().first().toString();
QNetworkProxy proxy;
@@ -302,6 +305,9 @@ void tst_QSslSocket::init()
break;
}
QNetworkProxy::setApplicationProxy(proxy);
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
qt_qhostinfo_clear_cache();
@@ -309,7 +315,9 @@ void tst_QSslSocket::init()
void tst_QSslSocket::cleanup()
{
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#endif
}
#ifndef QT_NO_SSL
@@ -326,12 +334,14 @@ QSslSocketPtr tst_QSslSocket::newSocket()
}
#endif
+#ifndef QT_NO_NETWORKPROXY
void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth)
{
++proxyAuthCalled;
auth->setUser("qsockstest");
auth->setPassword("password");
}
+#endif // !QT_NO_NETWORKPROXY
#ifndef QT_NO_SSL
@@ -579,13 +589,13 @@ void tst_QSslSocket::ciphers()
return;
QSslSocket socket;
- QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
+ QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers());
socket.setCiphers(QList<QSslCipher>());
QVERIFY(socket.ciphers().isEmpty());
socket.setCiphers(socket.defaultCiphers());
- QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
+ QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers());
socket.setCiphers(socket.defaultCiphers());
- QCOMPARE(socket.ciphers(), QSslSocket::supportedCiphers());
+ QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers());
// Task 164356
socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
@@ -668,6 +678,11 @@ void tst_QSslSocket::sessionCipher()
if (!socket->waitForEncrypted(5000))
QSKIP("Skipping flaky test - See QTBUG-29941");
QVERIFY(!socket->sessionCipher().isNull());
+
+ qDebug() << "Supported Ciphers:" << QSslSocket::supportedCiphers();
+ qDebug() << "Default Ciphers:" << QSslSocket::defaultCiphers();
+ qDebug() << "Session Cipher:" << socket->sessionCipher();
+
QVERIFY(QSslSocket::supportedCiphers().contains(socket->sessionCipher()));
socket->disconnectFromHost();
QVERIFY(socket->waitForDisconnected());
@@ -1376,6 +1391,15 @@ void tst_QSslSocket::defaultCaCertificates()
void tst_QSslSocket::defaultCiphers()
{
+ if (!QSslSocket::supportsSsl())
+ return;
+
+ QList<QSslCipher> ciphers = QSslSocket::defaultCiphers();
+ QVERIFY(ciphers.size() > 1);
+
+ QSslSocket socket;
+ QCOMPARE(socket.defaultCiphers(), ciphers);
+ QCOMPARE(socket.ciphers(), ciphers);
}
void tst_QSslSocket::resetDefaultCiphers()
@@ -1400,8 +1424,6 @@ void tst_QSslSocket::supportedCiphers()
QSslSocket socket;
QCOMPARE(socket.supportedCiphers(), ciphers);
- QCOMPARE(socket.defaultCiphers(), ciphers);
- QCOMPARE(socket.ciphers(), ciphers);
}
void tst_QSslSocket::systemCaCertificates()
diff --git a/tests/auto/network/ssl/ssl.pro b/tests/auto/network/ssl/ssl.pro
index 06f4a05241..0b8f269fac 100644
--- a/tests/auto/network/ssl/ssl.pro
+++ b/tests/auto/network/ssl/ssl.pro
@@ -12,3 +12,7 @@ contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked):
qsslsocket_onDemandCertificates_member \
qsslsocket_onDemandCertificates_static \
}
+
+winrt: SUBDIRS -= \
+ qsslsocket_onDemandCertificates_member \
+ qsslsocket_onDemandCertificates_static \
diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp
index 1ec1d88802..57128e4a82 100644
--- a/tests/auto/opengl/qgl/tst_qgl.cpp
+++ b/tests/auto/opengl/qgl/tst_qgl.cpp
@@ -49,6 +49,7 @@
#include <qglframebufferobject.h>
#include <qglcolormap.h>
#include <qpaintengine.h>
+#include <qopenglfunctions.h>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
@@ -751,7 +752,10 @@ void tst_QGL::openGLVersionCheck()
#elif defined(QT_OPENGL_ES_2)
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
#else
- QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
+ if (QOpenGLFunctions::isES())
+ QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
+ else
+ QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
#endif //defined(QT_OPENGL_ES_1)
}
#endif //QT_BUILD_INTERNAL
@@ -1511,12 +1515,6 @@ void tst_QGL::colormap()
QCOMPARE(cmap4.size(), 256);
}
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
#ifndef GL_TEXTURE_3D
#define GL_TEXTURE_3D 0x806F
#endif
@@ -1532,7 +1530,13 @@ void tst_QGL::fboFormat()
QCOMPARE(format1.samples(), 0);
QVERIFY(format1.attachment() == QGLFramebufferObject::NoAttachment);
QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D));
- QCOMPARE(int(format1.internalTextureFormat()), int(DEFAULT_FORMAT));
+ int expectedFormat =
+#ifdef QT_OPENGL_ES_2
+ GL_RGBA;
+#else
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
+#endif
+ QCOMPARE(int(format1.internalTextureFormat()), expectedFormat);
// Modify the values and re-check.
format1.setSamples(8);
@@ -1603,14 +1607,26 @@ void tst_QGL::fboFormat()
QGLFramebufferObjectFormat format4c;
QVERIFY(format1c == format3c);
QVERIFY(!(format1c != format3c));
- format3c.setInternalTextureFormat(DEFAULT_FORMAT);
+ format3c.setInternalTextureFormat(
+#ifdef QT_OPENGL_ES_2
+ GL_RGBA
+#else
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#endif
+ );
QVERIFY(!(format1c == format3c));
QVERIFY(format1c != format3c);
format4c = format1c;
QVERIFY(format1c == format4c);
QVERIFY(!(format1c != format4c));
- format4c.setInternalTextureFormat(DEFAULT_FORMAT);
+ format4c.setInternalTextureFormat(
+#ifdef QT_OPENGL_ES_2
+ GL_RGBA
+#else
+ QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
+#endif
+ );
QVERIFY(!(format1c == format4c));
QVERIFY(format1c != format4c);
}
diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp
index 975df7f554..fea3c7b643 100644
--- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp
+++ b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp
@@ -96,97 +96,99 @@ void tst_QGLFunctions::features()
funcs.initializeGLFunctions();
// Validate the features against what we expect for this platform.
-#if defined(QT_OPENGL_ES_2)
- QGLFunctions::OpenGLFeatures allFeatures =
- (QGLFunctions::Multitexture |
- QGLFunctions::Shaders |
- QGLFunctions::Buffers |
- QGLFunctions::Framebuffers |
- QGLFunctions::BlendColor |
- QGLFunctions::BlendEquation |
- QGLFunctions::BlendEquationSeparate |
- QGLFunctions::BlendFuncSeparate |
- QGLFunctions::BlendSubtract |
- QGLFunctions::CompressedTextures |
- QGLFunctions::Multisample |
- QGLFunctions::StencilSeparate |
- QGLFunctions::NPOTTextures);
- QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
-#elif defined(QT_OPENGL_ES)
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
- QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
-
- QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
- QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
- QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
-
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
- hasExtension("GL_OES_framebuffer_object"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
- hasExtension("GL_OES_blend_equation_separate"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
- hasExtension("GL_OES_blend_func_separate"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
- hasExtension("GL_OES_blend_subtract"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
- hasExtension("GL_OES_texture_npot"));
-#else
- // We check for both the extension name and the minimum OpenGL version
- // for the feature. This will help us catch situations where a platform
- // doesn't list an extension by name but does have the feature by virtue
- // of its version number.
- QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
- hasExtension("GL_ARB_multitexture") ||
- (versions & QGLFormat::OpenGL_Version_1_3) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
- hasExtension("GL_ARB_shader_objects") ||
- (versions & QGLFormat::OpenGL_Version_2_0) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
- (versions & QGLFormat::OpenGL_Version_1_5) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
- hasExtension("GL_EXT_framebuffer_object") ||
- hasExtension("GL_ARB_framebuffer_object"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
- hasExtension("GL_EXT_blend_color") ||
- (versions & QGLFormat::OpenGL_Version_1_2) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
- (versions & QGLFormat::OpenGL_Version_1_2) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
- hasExtension("GL_EXT_blend_equation_separate") ||
- (versions & QGLFormat::OpenGL_Version_2_0) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
- hasExtension("GL_EXT_blend_func_separate") ||
- (versions & QGLFormat::OpenGL_Version_1_4) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
- hasExtension("GL_EXT_blend_subtract"));
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
- hasExtension("GL_ARB_texture_compression") ||
- (versions & QGLFormat::OpenGL_Version_1_3) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
- hasExtension("GL_ARB_multisample") ||
- (versions & QGLFormat::OpenGL_Version_1_3) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
- (versions & QGLFormat::OpenGL_Version_2_0) != 0);
- QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
- hasExtension("GL_ARB_texture_non_power_of_two") ||
- (versions & QGLFormat::OpenGL_Version_2_0) != 0);
+ if (QOpenGLFunctions::isES()) {
+#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
+ QGLFunctions::OpenGLFeatures allFeatures =
+ (QGLFunctions::Multitexture |
+ QGLFunctions::Shaders |
+ QGLFunctions::Buffers |
+ QGLFunctions::Framebuffers |
+ QGLFunctions::BlendColor |
+ QGLFunctions::BlendEquation |
+ QGLFunctions::BlendEquationSeparate |
+ QGLFunctions::BlendFuncSeparate |
+ QGLFunctions::BlendSubtract |
+ QGLFunctions::CompressedTextures |
+ QGLFunctions::Multisample |
+ QGLFunctions::StencilSeparate |
+ QGLFunctions::NPOTTextures);
+ QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
+#elif defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2)
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
+ QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
+
+ QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
+ QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
+ QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
+
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
+ hasExtension("GL_OES_framebuffer_object"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
+ hasExtension("GL_OES_blend_equation_separate"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
+ hasExtension("GL_OES_blend_func_separate"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
+ hasExtension("GL_OES_blend_subtract"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
+ hasExtension("GL_OES_texture_npot"));
#endif
+ } else {
+ // We check for both the extension name and the minimum OpenGL version
+ // for the feature. This will help us catch situations where a platform
+ // doesn't list an extension by name but does have the feature by virtue
+ // of its version number.
+ QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
+ hasExtension("GL_ARB_multitexture") ||
+ (versions & QGLFormat::OpenGL_Version_1_3) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
+ hasExtension("GL_ARB_shader_objects") ||
+ (versions & QGLFormat::OpenGL_Version_2_0) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
+ (versions & QGLFormat::OpenGL_Version_1_5) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
+ hasExtension("GL_EXT_framebuffer_object") ||
+ hasExtension("GL_ARB_framebuffer_object"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
+ hasExtension("GL_EXT_blend_color") ||
+ (versions & QGLFormat::OpenGL_Version_1_2) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
+ (versions & QGLFormat::OpenGL_Version_1_2) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
+ hasExtension("GL_EXT_blend_equation_separate") ||
+ (versions & QGLFormat::OpenGL_Version_2_0) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
+ hasExtension("GL_EXT_blend_func_separate") ||
+ (versions & QGLFormat::OpenGL_Version_1_4) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
+ hasExtension("GL_EXT_blend_subtract"));
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
+ hasExtension("GL_ARB_texture_compression") ||
+ (versions & QGLFormat::OpenGL_Version_1_3) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
+ hasExtension("GL_ARB_multisample") ||
+ (versions & QGLFormat::OpenGL_Version_1_3) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
+ (versions & QGLFormat::OpenGL_Version_2_0) != 0);
+ QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
+ hasExtension("GL_ARB_texture_non_power_of_two") ||
+ (versions & QGLFormat::OpenGL_Version_2_0) != 0);
+ }
}
// Verify that the multitexture functions appear to resolve and work.
diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
index f5923764b8..765dc221dc 100644
--- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
+++ b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp
@@ -333,52 +333,55 @@ static inline float qrandom() { return (rand() % 100) / 100.f; }
void renderAScene(int w, int h)
{
-#ifdef QT_OPENGL_ES_2
- Q_UNUSED(w)
- Q_UNUSED(h)
- QGLShaderProgram program;
- program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
- program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
- program.bindAttributeLocation("pos", 0);
- program.bind();
-
- glEnableVertexAttribArray(0);
-
- for (int i=0; i<1000; ++i) {
- GLfloat pos[] = {
- (rand() % 100) / 100.f,
- (rand() % 100) / 100.f,
- (rand() % 100) / 100.f,
- (rand() % 100) / 100.f,
- (rand() % 100) / 100.f,
- (rand() % 100) / 100.f
- };
-
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
- }
-#else
- glViewport(0, 0, w, h);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(0, w, h, 0, 1, 100);
- glTranslated(0, 0, -1);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- for (int i=0;i<1000; ++i) {
- glBegin(GL_TRIANGLES);
- glColor3f(qrandom(), qrandom(), qrandom());
- glVertex2f(qrandom() * w, qrandom() * h);
- glColor3f(qrandom(), qrandom(), qrandom());
- glVertex2f(qrandom() * w, qrandom() * h);
- glColor3f(qrandom(), qrandom(), qrandom());
- glVertex2f(qrandom() * w, qrandom() * h);
- glEnd();
- }
+ if (QOpenGLFunctions::isES()) {
+ QGLFunctions funcs(QGLContext::currentContext());
+ Q_UNUSED(w);
+ Q_UNUSED(h);
+ QGLShaderProgram program;
+ program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
+ program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
+ program.bindAttributeLocation("pos", 0);
+ program.bind();
+
+ funcs.glEnableVertexAttribArray(0);
+
+ for (int i=0; i<1000; ++i) {
+ GLfloat pos[] = {
+ (rand() % 100) / 100.f,
+ (rand() % 100) / 100.f,
+ (rand() % 100) / 100.f,
+ (rand() % 100) / 100.f,
+ (rand() % 100) / 100.f,
+ (rand() % 100) / 100.f
+ };
+
+ funcs.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+ }
+ } else {
+#ifndef QT_OPENGL_ES_2
+ glViewport(0, 0, w, h);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(0, w, h, 0, 1, 100);
+ glTranslated(0, 0, -1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ for (int i=0;i<1000; ++i) {
+ glBegin(GL_TRIANGLES);
+ glColor3f(qrandom(), qrandom(), qrandom());
+ glVertex2f(qrandom() * w, qrandom() * h);
+ glColor3f(qrandom(), qrandom(), qrandom());
+ glVertex2f(qrandom() * w, qrandom() * h);
+ glColor3f(qrandom(), qrandom(), qrandom());
+ glVertex2f(qrandom() * w, qrandom() * h);
+ glEnd();
+ }
#endif
+ }
}
class ThreadSafeGLWidget : public QGLWidget
diff --git a/tests/auto/other/atwrapper/atWrapperAutotest.cpp b/tests/auto/other/atwrapper/atWrapperAutotest.cpp
index 7ece62806c..63116574b5 100644
--- a/tests/auto/other/atwrapper/atWrapperAutotest.cpp
+++ b/tests/auto/other/atwrapper/atWrapperAutotest.cpp
@@ -70,7 +70,7 @@ void atWrapperAutotest::runTest()
atWrapper wrapper;
if (!wrapper.runAutoTests())
- QSKIP("Arthur not tested on this machine");
+ QSKIP("Arthur not tested on this machine");
QVERIFY(true);
}
diff --git a/tests/auto/other/collections/tst_collections.cpp b/tests/auto/other/collections/tst_collections.cpp
index df622602c3..17ed9c8a45 100644
--- a/tests/auto/other/collections/tst_collections.cpp
+++ b/tests/auto/other/collections/tst_collections.cpp
@@ -210,231 +210,231 @@ void tst_Collections::typeinfo()
void tst_Collections::list()
{
{
- QList<int> list;
- QVERIFY(list.isEmpty());
- list.append(1);
- QVERIFY(list.size() == 1);
+ QList<int> list;
+ QVERIFY(list.isEmpty());
+ list.append(1);
+ QVERIFY(list.size() == 1);
- QVERIFY(*list.begin() == 1);
+ QVERIFY(*list.begin() == 1);
- list.push_back(2);
- list += (3);
- list << 4 << 5 << 6;
- QVERIFY(!list.isEmpty());
- QVERIFY(list.size() == 6);
- QVERIFY(list.end() - list.begin() == list.size());
+ list.push_back(2);
+ list += (3);
+ list << 4 << 5 << 6;
+ QVERIFY(!list.isEmpty());
+ QVERIFY(list.size() == 6);
+ QVERIFY(list.end() - list.begin() == list.size());
#if !defined(Q_CC_MSVC) && !defined(Q_CC_SUN)
- QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true);
- QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false);
+ QVERIFY(std::binary_search(list.begin(), list.end(), 2) == true);
+ QVERIFY(std::binary_search(list.begin(), list.end(), 9) == false);
#endif
- QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1);
- QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1);
+ QVERIFY(qBinaryFind(list.begin(), list.end(), 2) == list.begin() + 1);
+ QVERIFY(qLowerBound(list.begin(), list.end(), 2) == list.begin() + 1);
QVERIFY(qUpperBound(list.begin(), list.end(), 2) == list.begin() + 2);
- QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end());
- QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end());
+ QVERIFY(qBinaryFind(list.begin(), list.end(), 9) == list.end());
+ QVERIFY(qLowerBound(list.begin(), list.end(), 9) == list.end());
QVERIFY(qUpperBound(list.begin(), list.end(), 9) == list.end());
- {
- int sum = 0;
- QListIterator<int> i(list);
- while (i.hasNext())
- sum += i.next();
- QVERIFY(sum == 21);
- }
-
- {
- QList<int> list1;
+ {
+ int sum = 0;
+ QListIterator<int> i(list);
+ while (i.hasNext())
+ sum += i.next();
+ QVERIFY(sum == 21);
+ }
+
+ {
+ QList<int> list1;
list1 << 1 << 2 << 3 << 5 << 7 << 8 << 9;
- QList<int> list2 = list1;
+ QList<int> list2 = list1;
- QMutableListIterator<int> i1(list1);
+ QMutableListIterator<int> i1(list1);
while (i1.hasNext()) {
- if (i1.next() % 2 != 0)
- i1.remove();
- }
+ if (i1.next() % 2 != 0)
+ i1.remove();
+ }
- QMutableListIterator<int> i2(list2);
+ QMutableListIterator<int> i2(list2);
i2.toBack();
while (i2.hasPrevious()) {
- if (i2.previous() % 2 != 0)
- i2.remove();
+ if (i2.previous() % 2 != 0)
+ i2.remove();
}
QVERIFY(list1.size() == 2);
QVERIFY(list2.size() == 2);
QVERIFY(list1 == list2);
}
- {
- int sum = 0;
- for (int i = 0; i < list.size(); ++i)
- sum += list[i];
- QVERIFY(sum == 21);
- }
- {
- int sum = 0;
- QList<int>::const_iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 21);
- }
- {
- int sum = 0;
- QList<int>::ConstIterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 21);
- }
- {
- QList<int>::Iterator i = list.begin();
+ {
+ int sum = 0;
+ for (int i = 0; i < list.size(); ++i)
+ sum += list[i];
+ QVERIFY(sum == 21);
+ }
+ {
+ int sum = 0;
+ QList<int>::const_iterator i = list.begin();
+ while (i != list.end())
+ sum += *i++;
+ QVERIFY(sum == 21);
+ }
+ {
+ int sum = 0;
+ QList<int>::ConstIterator i = list.begin();
+ while (i != list.end())
+ sum += *i++;
+ QVERIFY(sum == 21);
+ }
+ {
+ QList<int>::Iterator i = list.begin();
i += 2;
QCOMPARE(*i, 3);
i -= 1;
QCOMPARE(*i, 2);
- }
- {
- QList<int>::ConstIterator i = list.begin();
+ }
+ {
+ QList<int>::ConstIterator i = list.begin();
i += 2;
QCOMPARE(*i, 3);
i -= 1;
QCOMPARE(*i, 2);
- }
- {
- int sum = 0;
- int i;
- for (i = 0; i < list.size(); ++i)
- list[i] = list[i] +1;
- for (i = 0; i < list.size(); ++i)
- sum += list[i];
- QVERIFY(sum == 21 + list.size());
- }
- {
- int sum = 0;
- int i;
- for (i = 0; i < list.size(); ++i)
- --list[i];
- for (i = 0; i < list.size(); ++i)
- sum += list[i];
- QVERIFY(sum == 21);
- }
- {
- QMutableListIterator<int> i(list);
- while (i.hasNext())
- i.setValue(2*i.next());
- }
- {
- int sum = 0;
- QListIterator<int> i(list);
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*21);
- }
- {
- QMutableListIterator<int> i(list);
- i.toBack();
- while (i.hasPrevious())
- i.setValue(2*i.previous());
- }
- {
- int sum = 0;
- QListIterator<int> i(list);
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*2*21);
- }
- {
- QMutableListIterator<int> i(list);
- while (i.hasNext()) {
- int a = i.next();
- i.insert(a);
- }
- }
- {
- int sum = 0;
- QList<int>::iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 2*2*2*21);
- }
- {
- int duplicates = 0;
- QListIterator<int> i(list);
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() && a == i.peekNext())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- int duplicates = 0;
- QListIterator<int> i(list);
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- QMutableListIterator<int> i(list);
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() &&
- i.peekNext() == a)
- i.remove();
- }
- }
- {
- int duplicates = 0;
- QMutableListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 0);
- }
- {
- QVERIFY(list.size() == 6);
- QMutableListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.peekNext();
- i.insert(42);
- QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
- i.next();
- }
- QVERIFY(list.size() == 12);
- i.toFront();
- while (i.findNext(42))
- i.remove();
- }
- {
- QList<int> l;
- l << 4 << 8 << 12 << 16 << 20 << 24;
- QVERIFY(l == list);
- QList<int> copy = list;
- list += list;
- QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
- l += copy;
- QVERIFY(l == list);
- list = copy;
- }
- {
- QList<int> copy = list;
- list << 8;
- QVERIFY(list.indexOf(8) == 1);
- QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6);
- int a = list.indexOf(8);
- QVERIFY(list.count(8) == 2);
- int r = list.removeAll(8);
- QVERIFY(r == 2);
- list.insert(a, 8);
- QVERIFY(list == copy);
- }
+ }
+ {
+ int sum = 0;
+ int i;
+ for (i = 0; i < list.size(); ++i)
+ list[i] = list[i] +1;
+ for (i = 0; i < list.size(); ++i)
+ sum += list[i];
+ QVERIFY(sum == 21 + list.size());
+ }
+ {
+ int sum = 0;
+ int i;
+ for (i = 0; i < list.size(); ++i)
+ --list[i];
+ for (i = 0; i < list.size(); ++i)
+ sum += list[i];
+ QVERIFY(sum == 21);
+ }
+ {
+ QMutableListIterator<int> i(list);
+ while (i.hasNext())
+ i.setValue(2*i.next());
+ }
+ {
+ int sum = 0;
+ QListIterator<int> i(list);
+ i.toBack();
+ while (i.hasPrevious())
+ sum += i.previous();
+ QVERIFY(sum == 2*21);
+ }
+ {
+ QMutableListIterator<int> i(list);
+ i.toBack();
+ while (i.hasPrevious())
+ i.setValue(2*i.previous());
+ }
+ {
+ int sum = 0;
+ QListIterator<int> i(list);
+ i.toBack();
+ while (i.hasPrevious())
+ sum += i.previous();
+ QVERIFY(sum == 2*2*21);
+ }
+ {
+ QMutableListIterator<int> i(list);
+ while (i.hasNext()) {
+ int a = i.next();
+ i.insert(a);
+ }
+ }
+ {
+ int sum = 0;
+ QList<int>::iterator i = list.begin();
+ while (i != list.end())
+ sum += *i++;
+ QVERIFY(sum == 2*2*2*21);
+ }
+ {
+ int duplicates = 0;
+ QListIterator<int> i(list);
+ while (i.hasNext()) {
+ int a = i.next();
+ if (i.hasNext() && a == i.peekNext())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 6);
+ }
+ {
+ int duplicates = 0;
+ QListIterator<int> i(list);
+ i.toBack();
+ while (i.hasPrevious()) {
+ int a = i.previous();
+ if (i.hasPrevious() && a == i.peekPrevious())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 6);
+ }
+ {
+ QMutableListIterator<int> i(list);
+ while (i.hasNext()) {
+ int a = i.next();
+ if (i.hasNext() &&
+ i.peekNext() == a)
+ i.remove();
+ }
+ }
+ {
+ int duplicates = 0;
+ QMutableListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious()) {
+ int a = i.previous();
+ if (i.hasPrevious() && a == i.peekPrevious())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 0);
+ }
+ {
+ QVERIFY(list.size() == 6);
+ QMutableListIterator<int> i = list;
+ while (i.hasNext()) {
+ int a = i.peekNext();
+ i.insert(42);
+ QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
+ i.next();
+ }
+ QVERIFY(list.size() == 12);
+ i.toFront();
+ while (i.findNext(42))
+ i.remove();
+ }
+ {
+ QList<int> l;
+ l << 4 << 8 << 12 << 16 << 20 << 24;
+ QVERIFY(l == list);
+ QList<int> copy = list;
+ list += list;
+ QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
+ l += copy;
+ QVERIFY(l == list);
+ list = copy;
+ }
+ {
+ QList<int> copy = list;
+ list << 8;
+ QVERIFY(list.indexOf(8) == 1);
+ QVERIFY(list.indexOf(8, list.indexOf(8)+1) == 6);
+ int a = list.indexOf(8);
+ QVERIFY(list.count(8) == 2);
+ int r = list.removeAll(8);
+ QVERIFY(r == 2);
+ list.insert(a, 8);
+ QVERIFY(list == copy);
+ }
{
QList<QString> list;
list << "one" << "two" << "three" << "four" << "five" << "six";
@@ -458,73 +458,73 @@ void tst_Collections::list()
QVERIFY(!list.removeOne("one"));
QVERIFY(list.isEmpty());
}
- {
- QList<int> copy = list;
- list << 8;
- QVERIFY(list.lastIndexOf(8) == 6);
- QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1);
- list = copy;
- }
- {
- QList<int> copy = list;
- list.insert(3, 999);
- QVERIFY(list[3] == 999);
- list.replace(3, 222);
- QVERIFY(list[3] == 222);
- QVERIFY(list.contains(222) && ! list.contains(999));
- list.removeAt(3);
- list = copy;
- QVERIFY(list == copy);
- }
- {
- list.clear();
- QVERIFY(list.isEmpty());
- QVERIFY(list.begin() == list.end());
- QListIterator<int> i(list);
- QVERIFY(!i.hasNext() && !i.hasPrevious());
- }
- {
- QList<int> l1;
- QList<int> l2;
- l1 << 1 << 2 << 3;
- l2 << 4 << 5 << 6;
- QList<int> l3 = l1 + l2;
- l1 += l2;
- QVERIFY(l3 == l1);
- }
- {
- QList<int> list;
- QVERIFY(list.isEmpty());
- list.append(1);
- QList<int> list2;
- list2 = list;
- list2.clear();
- QVERIFY(list2.size() == 0);
- QVERIFY(list.size() == 1);
- }
- {
- QList<int> list;
- list.append(1);
- list = list;
- QVERIFY(list.size() == 1);
- }
+ {
+ QList<int> copy = list;
+ list << 8;
+ QVERIFY(list.lastIndexOf(8) == 6);
+ QVERIFY(list.lastIndexOf(8, list.lastIndexOf(8)-1) == 1);
+ list = copy;
+ }
+ {
+ QList<int> copy = list;
+ list.insert(3, 999);
+ QVERIFY(list[3] == 999);
+ list.replace(3, 222);
+ QVERIFY(list[3] == 222);
+ QVERIFY(list.contains(222) && ! list.contains(999));
+ list.removeAt(3);
+ list = copy;
+ QVERIFY(list == copy);
+ }
+ {
+ list.clear();
+ QVERIFY(list.isEmpty());
+ QVERIFY(list.begin() == list.end());
+ QListIterator<int> i(list);
+ QVERIFY(!i.hasNext() && !i.hasPrevious());
+ }
+ {
+ QList<int> l1;
+ QList<int> l2;
+ l1 << 1 << 2 << 3;
+ l2 << 4 << 5 << 6;
+ QList<int> l3 = l1 + l2;
+ l1 += l2;
+ QVERIFY(l3 == l1);
+ }
+ {
+ QList<int> list;
+ QVERIFY(list.isEmpty());
+ list.append(1);
+ QList<int> list2;
+ list2 = list;
+ list2.clear();
+ QVERIFY(list2.size() == 0);
+ QVERIFY(list.size() == 1);
+ }
+ {
+ QList<int> list;
+ list.append(1);
+ list = list;
+ QVERIFY(list.size() == 1);
+ }
}
{
- QList<void*> list;
- list.append(0);
- list.append((void*)42);
- QCOMPARE(list.size(), 2);
- QCOMPARE(list.at(0), (void*)0);
- QCOMPARE(list.at(1), (void*)42);
+ QList<void*> list;
+ list.append(0);
+ list.append((void*)42);
+ QCOMPARE(list.size(), 2);
+ QCOMPARE(list.at(0), (void*)0);
+ QCOMPARE(list.at(1), (void*)42);
}
{
- QVector<QString> vector(5);
+ QVector<QString> vector(5);
vector[0] = "99";
vector[4] ="100";
QList<QString> list = vector.toList();
- QVERIFY(list.size() == 5);
+ QVERIFY(list.size() == 5);
QVERIFY(list.at(0) == "99");
QVERIFY(list.at(4) == "100");
list[0] = "10";
@@ -783,145 +783,145 @@ void tst_Collections::list()
void tst_Collections::linkedList()
{
{
- QLinkedList<int> list;
- QVERIFY(list.isEmpty());
- list.append(1);
- list.push_back(2);
- list += (3);
- list << 4 << 5 << 6;
- QVERIFY(!list.isEmpty());
- QVERIFY(list.size() == 6);
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- sum += i.next();
- }
- QVERIFY(sum == 21);
- }
- {
- int sum = 0;
- QLinkedList<int>::const_iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext())
- i.setValue(2*i.next());
- }
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- i.setValue(2*i.previous());
- }
- {
- int sum = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious())
- sum += i.previous();
- QVERIFY(sum == 2*2*21);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- i.insert(a);
- }
- }
- {
- int sum = 0;
- QLinkedList<int>::iterator i = list.begin();
- while (i != list.end())
- sum += *i++;
- QVERIFY(sum == 2*2*2*21);
- }
- {
- int duplicates = 0;
- QLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() && a == i.peekNext())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- int duplicates = 0;
- QLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 6);
- }
- {
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.next();
- if (i.hasNext() &&
- i.peekNext() == a)
- i.remove();
- }
- }
- {
- int duplicates = 0;
- QMutableLinkedListIterator<int> i = list;
- i.toBack();
- while (i.hasPrevious()) {
- int a = i.previous();
- if (i.hasPrevious() && a == i.peekPrevious())
- duplicates++;
- }
- QVERIFY(duplicates == 0);
- }
- {
- QVERIFY(list.size() == 6);
- QMutableLinkedListIterator<int> i = list;
- while (i.hasNext()) {
- int a = i.peekNext();
- i.insert(42);
- QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
- i.next();
- }
- QVERIFY(list.size() == 12);
- i.toFront();
- while (i.findNext(42))
- i.remove();
- }
- {
- QLinkedList<int> l;
- l << 4 << 8 << 12 << 16 << 20 << 24;
- QVERIFY(l == list);
- QLinkedList<int> copy = list;
- list += list;
- QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
- l += copy;
- QVERIFY(l == list);
- list = copy;
- }
- {
- QLinkedList<int> copy = list;
- list.prepend(999);
- list.append(999);
- QVERIFY(list.contains(999));
- QVERIFY(list.count(999) == 2);
- list.removeAll(999);
- QVERIFY(list == copy);
- }
+ QLinkedList<int> list;
+ QVERIFY(list.isEmpty());
+ list.append(1);
+ list.push_back(2);
+ list += (3);
+ list << 4 << 5 << 6;
+ QVERIFY(!list.isEmpty());
+ QVERIFY(list.size() == 6);
+ {
+ int sum = 0;
+ QLinkedListIterator<int> i = list;
+ while (i.hasNext()) {
+ sum += i.next();
+ }
+ QVERIFY(sum == 21);
+ }
+ {
+ int sum = 0;
+ QLinkedList<int>::const_iterator i = list.begin();
+ while (i != list.end())
+ sum += *i++;
+ QVERIFY(sum == 21);
+ }
+ {
+ QMutableLinkedListIterator<int> i = list;
+ while (i.hasNext())
+ i.setValue(2*i.next());
+ }
+ {
+ int sum = 0;
+ QLinkedListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious())
+ sum += i.previous();
+ QVERIFY(sum == 2*21);
+ }
+ {
+ QMutableLinkedListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious())
+ i.setValue(2*i.previous());
+ }
+ {
+ int sum = 0;
+ QLinkedListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious())
+ sum += i.previous();
+ QVERIFY(sum == 2*2*21);
+ }
+ {
+ QMutableLinkedListIterator<int> i = list;
+ while (i.hasNext()) {
+ int a = i.next();
+ i.insert(a);
+ }
+ }
+ {
+ int sum = 0;
+ QLinkedList<int>::iterator i = list.begin();
+ while (i != list.end())
+ sum += *i++;
+ QVERIFY(sum == 2*2*2*21);
+ }
+ {
+ int duplicates = 0;
+ QLinkedListIterator<int> i = list;
+ while (i.hasNext()) {
+ int a = i.next();
+ if (i.hasNext() && a == i.peekNext())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 6);
+ }
+ {
+ int duplicates = 0;
+ QLinkedListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious()) {
+ int a = i.previous();
+ if (i.hasPrevious() && a == i.peekPrevious())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 6);
+ }
+ {
+ QMutableLinkedListIterator<int> i = list;
+ while (i.hasNext()) {
+ int a = i.next();
+ if (i.hasNext() &&
+ i.peekNext() == a)
+ i.remove();
+ }
+ }
+ {
+ int duplicates = 0;
+ QMutableLinkedListIterator<int> i = list;
+ i.toBack();
+ while (i.hasPrevious()) {
+ int a = i.previous();
+ if (i.hasPrevious() && a == i.peekPrevious())
+ duplicates++;
+ }
+ QVERIFY(duplicates == 0);
+ }
+ {
+ QVERIFY(list.size() == 6);
+ QMutableLinkedListIterator<int> i = list;
+ while (i.hasNext()) {
+ int a = i.peekNext();
+ i.insert(42);
+ QVERIFY(i.peekPrevious() == 42 && i.peekNext() == a);
+ i.next();
+ }
+ QVERIFY(list.size() == 12);
+ i.toFront();
+ while (i.findNext(42))
+ i.remove();
+ }
+ {
+ QLinkedList<int> l;
+ l << 4 << 8 << 12 << 16 << 20 << 24;
+ QVERIFY(l == list);
+ QLinkedList<int> copy = list;
+ list += list;
+ QVERIFY(l != list && l.size() == list.size()/2 && l == copy);
+ l += copy;
+ QVERIFY(l == list);
+ list = copy;
+ }
+ {
+ QLinkedList<int> copy = list;
+ list.prepend(999);
+ list.append(999);
+ QVERIFY(list.contains(999));
+ QVERIFY(list.count(999) == 2);
+ list.removeAll(999);
+ QVERIFY(list == copy);
+ }
{
QLinkedList<QString> list;
list << "one" << "two" << "three" << "four" << "five" << "six";
@@ -946,12 +946,12 @@ void tst_Collections::linkedList()
QVERIFY(list.isEmpty());
}
{
- list.clear();
- QVERIFY(list.isEmpty());
- QVERIFY(list.begin() == list.end());
- QLinkedListIterator<int> i(list);
- QVERIFY(!i.hasNext() && !i.hasPrevious());
- }
+ list.clear();
+ QVERIFY(list.isEmpty());
+ QVERIFY(list.begin() == list.end());
+ QLinkedListIterator<int> i(list);
+ QVERIFY(!i.hasNext() && !i.hasPrevious());
+ }
}
{
@@ -1102,7 +1102,7 @@ void tst_Collections::vector()
dummy = new LargeStatic;
vector.append(LargeStatic());
}
- delete dummy;
+ delete dummy;
}
QVERIFY(LargeStatic::count == originalLargeStaticCount);
@@ -1364,11 +1364,11 @@ void tst_Collections::byteArray()
ba1 += ba1;
QCOMPARE(ba1, QByteArray("yyyyyy"));
- ba1.remove(1, -1); // do nothing
- QCOMPARE(ba1, QByteArray("yyyyyy"));
+ ba1.remove(1, -1); // do nothing
+ QCOMPARE(ba1, QByteArray("yyyyyy"));
- ba1.replace(0, -1, "ZZZ");
- QCOMPARE(ba1, QByteArray("ZZZyyyyyy"));
+ ba1.replace(0, -1, "ZZZ");
+ QCOMPARE(ba1, QByteArray("ZZZyyyyyy"));
}
};
@@ -1382,16 +1382,16 @@ void tst_Collections::stack()
i.toBack();
int sum = 0;
while (i.hasPrevious())
- sum += i.previous();
+ sum += i.previous();
QVERIFY(sum == 6);
sum = 0;
for (QStack<int>::iterator i = stack.begin(); i != stack.end(); ++i)
- sum += *i;
+ sum += *i;
QVERIFY(sum == 6);
while (!stack.isEmpty())
- sum -= stack.pop();
+ sum -= stack.pop();
QVERIFY(sum == 0);
}
@@ -1403,194 +1403,194 @@ void tst_Collections::hash()
const char *monde = "monde";
{
- typedef QHash<QString, QString> Hash;
- Hash hash;
- QString key;
- for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
- for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
- hash.insert(key, "V" + key);
- }
- }
-
- for (int i = 0; i < 10; ++i) {
- key[0] = i + '0';
- for (int j = 0; j < 10; ++j) {
- key[1] = j + '0';
- hash.remove(key);
- }
- }
+ typedef QHash<QString, QString> Hash;
+ Hash hash;
+ QString key;
+ for (int i = 0; i < 10; ++i) {
+ key[0] = i + '0';
+ for (int j = 0; j < 10; ++j) {
+ key[1] = j + '0';
+ hash.insert(key, "V" + key);
+ }
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ key[0] = i + '0';
+ for (int j = 0; j < 10; ++j) {
+ key[1] = j + '0';
+ hash.remove(key);
+ }
+ }
}
{
- typedef QHash<int, const char *> Hash;
- Hash hash;
- hash.insert(1, hello);
- hash.insert(2, world);
-
- QVERIFY(hash.size() == 2);
- QVERIFY(!hash.isEmpty());
-
- {
- Hash hash2 = hash;
- hash2 = hash;
- hash = hash2;
- hash2 = hash2;
- hash = hash;
- hash2.clear();
- hash2 = hash2;
- QVERIFY(hash2.size() == 0);
- QVERIFY(hash2.isEmpty());
- }
- QVERIFY(hash.size() == 2);
-
- {
- Hash hash2 = hash;
- hash2[1] = allo;
- hash2[2] = monde;
-
- QVERIFY(hash2[1] == allo);
- QVERIFY(hash2[2] == monde);
- QVERIFY(hash[1] == hello);
- QVERIFY(hash[2] == world);
-
- hash2[1] = hash[1];
- hash2[2] = hash[2];
-
- QVERIFY(hash2[1] == hello);
- QVERIFY(hash2[2] == world);
-
- hash[1] = hash[1];
- QVERIFY(hash[1] == hello);
- }
-
- {
- Hash hash2 = hash;
- hash2.detach();
- hash2.remove(1);
- QVERIFY(hash2.size() == 1);
- hash2.remove(1);
- QVERIFY(hash2.size() == 1);
- hash2.remove(0);
- QVERIFY(hash2.size() == 1);
- hash2.remove(2);
- QVERIFY(hash2.size() == 0);
- QVERIFY(hash.size() == 2);
- }
-
- hash.detach();
-
- {
- Hash::iterator it1 = hash.find(1);
- QVERIFY(it1 != hash.end());
-
- Hash::iterator it2 = hash.find(0);
- QVERIFY(it2 != hash.begin());
- QVERIFY(it2 == hash.end());
-
- *it1 = monde;
- QVERIFY(*it1 == monde);
- QVERIFY(hash[1] == monde);
-
- *it1 = hello;
- QVERIFY(*it1 == hello);
- QVERIFY(hash[1] == hello);
-
- hash[1] = monde;
- QVERIFY(it1.key() == 1);
- QVERIFY(it1.value() == monde);
- QVERIFY(*it1 == monde);
- QVERIFY(hash[1] == monde);
-
- hash[1] = hello;
- QVERIFY(*it1 == hello);
- QVERIFY(hash[1] == hello);
- }
-
- {
- const Hash hash2 = hash;
-
- Hash::const_iterator it1 = hash2.find(1);
- QVERIFY(it1 != hash2.end());
- QVERIFY(it1.key() == 1);
- QVERIFY(it1.value() == hello);
- QVERIFY(*it1 == hello);
-
- Hash::const_iterator it2 = hash2.find(2);
- QVERIFY(it1 != it2);
- QVERIFY(it1 != hash2.end());
- QVERIFY(it2 != hash2.end());
-
- int count = 0;
- it1 = hash2.begin();
- while (it1 != hash2.end()) {
- count++;
- ++it1;
- }
- QVERIFY(count == 2);
-
- count = 0;
- it1 = hash.begin();
- while (it1 != hash.end()) {
- count++;
- ++it1;
- }
- QVERIFY(count == 2);
- }
-
- {
- QVERIFY(hash.contains(1));
- QVERIFY(hash.contains(2));
- QVERIFY(!hash.contains(0));
- QVERIFY(!hash.contains(3));
- }
-
- {
- QVERIFY(hash.value(1) == hello);
- QVERIFY(hash.value(2) == world);
- QVERIFY(hash.value(3) == 0);
- QVERIFY(hash.value(1, allo) == hello);
- QVERIFY(hash.value(2, allo) == world);
- QVERIFY(hash.value(3, allo) == allo);
- QVERIFY(hash.value(0, monde) == monde);
- }
-
- {
- QHash<int,LargeStatic> hash;
- for (int i = 0; i < 10; i++)
- hash.insert(i, LargeStatic());
- QVERIFY(LargeStatic::count == 10);
- hash.remove(7);
- QVERIFY(LargeStatic::count == 9);
-
- }
- QVERIFY(LargeStatic::count == 0);
- {
- QHash<int, int*> hash;
- QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
- }
-
- {
- /*
+ typedef QHash<int, const char *> Hash;
+ Hash hash;
+ hash.insert(1, hello);
+ hash.insert(2, world);
+
+ QVERIFY(hash.size() == 2);
+ QVERIFY(!hash.isEmpty());
+
+ {
+ Hash hash2 = hash;
+ hash2 = hash;
+ hash = hash2;
+ hash2 = hash2;
+ hash = hash;
+ hash2.clear();
+ hash2 = hash2;
+ QVERIFY(hash2.size() == 0);
+ QVERIFY(hash2.isEmpty());
+ }
+ QVERIFY(hash.size() == 2);
+
+ {
+ Hash hash2 = hash;
+ hash2[1] = allo;
+ hash2[2] = monde;
+
+ QVERIFY(hash2[1] == allo);
+ QVERIFY(hash2[2] == monde);
+ QVERIFY(hash[1] == hello);
+ QVERIFY(hash[2] == world);
+
+ hash2[1] = hash[1];
+ hash2[2] = hash[2];
+
+ QVERIFY(hash2[1] == hello);
+ QVERIFY(hash2[2] == world);
+
+ hash[1] = hash[1];
+ QVERIFY(hash[1] == hello);
+ }
+
+ {
+ Hash hash2 = hash;
+ hash2.detach();
+ hash2.remove(1);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(1);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(0);
+ QVERIFY(hash2.size() == 1);
+ hash2.remove(2);
+ QVERIFY(hash2.size() == 0);
+ QVERIFY(hash.size() == 2);
+ }
+
+ hash.detach();
+
+ {
+ Hash::iterator it1 = hash.find(1);
+ QVERIFY(it1 != hash.end());
+
+ Hash::iterator it2 = hash.find(0);
+ QVERIFY(it2 != hash.begin());
+ QVERIFY(it2 == hash.end());
+
+ *it1 = monde;
+ QVERIFY(*it1 == monde);
+ QVERIFY(hash[1] == monde);
+
+ *it1 = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(hash[1] == hello);
+
+ hash[1] = monde;
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == monde);
+ QVERIFY(*it1 == monde);
+ QVERIFY(hash[1] == monde);
+
+ hash[1] = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(hash[1] == hello);
+ }
+
+ {
+ const Hash hash2 = hash;
+
+ Hash::const_iterator it1 = hash2.find(1);
+ QVERIFY(it1 != hash2.end());
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == hello);
+ QVERIFY(*it1 == hello);
+
+ Hash::const_iterator it2 = hash2.find(2);
+ QVERIFY(it1 != it2);
+ QVERIFY(it1 != hash2.end());
+ QVERIFY(it2 != hash2.end());
+
+ int count = 0;
+ it1 = hash2.begin();
+ while (it1 != hash2.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+
+ count = 0;
+ it1 = hash.begin();
+ while (it1 != hash.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+ }
+
+ {
+ QVERIFY(hash.contains(1));
+ QVERIFY(hash.contains(2));
+ QVERIFY(!hash.contains(0));
+ QVERIFY(!hash.contains(3));
+ }
+
+ {
+ QVERIFY(hash.value(1) == hello);
+ QVERIFY(hash.value(2) == world);
+ QVERIFY(hash.value(3) == 0);
+ QVERIFY(hash.value(1, allo) == hello);
+ QVERIFY(hash.value(2, allo) == world);
+ QVERIFY(hash.value(3, allo) == allo);
+ QVERIFY(hash.value(0, monde) == monde);
+ }
+
+ {
+ QHash<int,LargeStatic> hash;
+ for (int i = 0; i < 10; i++)
+ hash.insert(i, LargeStatic());
+ QVERIFY(LargeStatic::count == 10);
+ hash.remove(7);
+ QVERIFY(LargeStatic::count == 9);
+
+ }
+ QVERIFY(LargeStatic::count == 0);
+ {
+ QHash<int, int*> hash;
+ QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
+ }
+
+ {
+ /*
This test relies on a certain implementation of
QHash. If you change the way QHash works internally,
change this test as well.
*/
- QHash<int, int> hash;
+ QHash<int, int> hash;
for (int i = 0; i < 1000; ++i)
- hash.insert(i, i);
- QVERIFY(hash.capacity() == 1031);
+ hash.insert(i, i);
+ QVERIFY(hash.capacity() == 1031);
hash.squeeze();
QVERIFY(hash.capacity() == 521);
- hash.insert(12345, 12345);
+ hash.insert(12345, 12345);
QVERIFY(hash.capacity() == 1031);
- for (int j = 0; j < 900; ++j)
- hash.remove(j);
+ for (int j = 0; j < 900; ++j)
+ hash.remove(j);
QVERIFY(hash.capacity() == 257);
- hash.squeeze();
+ hash.squeeze();
QVERIFY(hash.capacity() == 67);
hash.reserve(0);
}
@@ -1643,211 +1643,211 @@ void tst_Collections::map()
const char *monde = "monde";
{
- typedef QMap<int, const char *> Map;
- Map map;
- map.insert(1, hello);
- map.insert(2, world);
-
- QVERIFY(*map.begin() == hello);
-
- QVERIFY(map.size() == 2);
- QVERIFY(!map.isEmpty());
-
- {
- Map map2 = map;
- map2 = map;
- map = map2;
- map2 = map2;
- map = map;
- map2.clear();
- map2 = map2;
- QVERIFY(map2.size() == 0);
- QVERIFY(map2.isEmpty());
- }
- QVERIFY(map.size() == 2);
-
- {
- Map map2 = map;
- map2[1] = allo;
- map2[2] = monde;
-
- QVERIFY(map2[1] == allo);
- QVERIFY(map2[2] == monde);
- QVERIFY(map[1] == hello);
- QVERIFY(map[2] == world);
-
- map2[1] = map[1];
- map2[2] = map[2];
-
- QVERIFY(map2[1] == hello);
- QVERIFY(map2[2] == world);
-
- map[1] = map[1];
- QVERIFY(map[1] == hello);
- }
-
- {
- Map map2 = map;
- map2.detach();
- map2.remove(1);
- QVERIFY(map2.size() == 1);
- map2.remove(1);
- QVERIFY(map2.size() == 1);
- map2.remove(0);
- QVERIFY(map2.size() == 1);
- map2.remove(2);
- QVERIFY(map2.size() == 0);
- QVERIFY(map.size() == 2);
- }
-
- map.detach();
-
- {
- Map::iterator it1 = map.find(1);
- QVERIFY(it1 == map.begin());
- QVERIFY(it1 != map.end());
-
- Map::iterator it2 = map.find(0);
- QVERIFY(it2 != map.begin());
- QVERIFY(it2 == map.end());
-
- *it1 = monde;
- QVERIFY(*it1 == monde);
- QVERIFY(map[1] == monde);
-
- *it1 = hello;
- QVERIFY(*it1 == hello);
- QVERIFY(map[1] == hello);
-
- map[1] = monde;
- QVERIFY(it1.key() == 1);
- QVERIFY(it1.value() == monde);
- QVERIFY(*it1 == monde);
- QVERIFY(map[1] == monde);
-
- map[1] = hello;
- QVERIFY(*it1 == hello);
- QVERIFY(map[1] == hello);
-
- *++it1 = allo;
- QVERIFY(*it1 == allo);
- QVERIFY(map[2] == allo);
- *it1 = world;
-
- ++it1;
- QVERIFY(it1 == map.end());
-
- int count = 0;
- it1 = map.begin();
- while (it1 != map.end()) {
- count++;
- ++it1;
- }
- QVERIFY(count == 2);
- }
-
- {
- const Map map2 = map;
-
- Map::const_iterator it1 = map2.find(1);
- QVERIFY(it1 != map2.end());
- QVERIFY(it1.key() == 1);
- QVERIFY(it1.value() == hello);
- QVERIFY(*it1 == hello);
- ++it1;
-
- Map::const_iterator it2 = map2.find(2);
- QVERIFY(it1 == it2);
- ++it1;
- QVERIFY(it1 == map2.end());
- QVERIFY(it2 != map2.end());
- QVERIFY(it1 != it2);
-
- int count = 0;
- it1 = map2.begin();
- while (it1 != map2.end()) {
- count++;
- ++it1;
- }
- QVERIFY(count == 2);
-
- count = 0;
- it1 = map.begin();
- while (it1 != map.end()) {
- count++;
- ++it1;
- }
- QVERIFY(count == 2);
- }
-
- {
- QVERIFY(map.contains(1));
- QVERIFY(map.contains(2));
- QVERIFY(!map.contains(0));
- QVERIFY(!map.contains(3));
- }
-
- {
- QVERIFY(map.value(1) == hello);
- QVERIFY(map.value(2) == world);
- QVERIFY(map.value(3) == 0);
- QVERIFY(map.value(1, allo) == hello);
- QVERIFY(map.value(2, allo) == world);
- QVERIFY(map.value(3, allo) == allo);
- QVERIFY(map.value(0, monde) == monde);
- }
- int originalLargeStaticCount = LargeStatic::count;
- {
- QMap<int,LargeStatic> map;
- for (int i = 0; i < 10; i++)
- map.insert(i, LargeStatic());
+ typedef QMap<int, const char *> Map;
+ Map map;
+ map.insert(1, hello);
+ map.insert(2, world);
+
+ QVERIFY(*map.begin() == hello);
+
+ QVERIFY(map.size() == 2);
+ QVERIFY(!map.isEmpty());
+
+ {
+ Map map2 = map;
+ map2 = map;
+ map = map2;
+ map2 = map2;
+ map = map;
+ map2.clear();
+ map2 = map2;
+ QVERIFY(map2.size() == 0);
+ QVERIFY(map2.isEmpty());
+ }
+ QVERIFY(map.size() == 2);
+
+ {
+ Map map2 = map;
+ map2[1] = allo;
+ map2[2] = monde;
+
+ QVERIFY(map2[1] == allo);
+ QVERIFY(map2[2] == monde);
+ QVERIFY(map[1] == hello);
+ QVERIFY(map[2] == world);
+
+ map2[1] = map[1];
+ map2[2] = map[2];
+
+ QVERIFY(map2[1] == hello);
+ QVERIFY(map2[2] == world);
+
+ map[1] = map[1];
+ QVERIFY(map[1] == hello);
+ }
+
+ {
+ Map map2 = map;
+ map2.detach();
+ map2.remove(1);
+ QVERIFY(map2.size() == 1);
+ map2.remove(1);
+ QVERIFY(map2.size() == 1);
+ map2.remove(0);
+ QVERIFY(map2.size() == 1);
+ map2.remove(2);
+ QVERIFY(map2.size() == 0);
+ QVERIFY(map.size() == 2);
+ }
+
+ map.detach();
+
+ {
+ Map::iterator it1 = map.find(1);
+ QVERIFY(it1 == map.begin());
+ QVERIFY(it1 != map.end());
+
+ Map::iterator it2 = map.find(0);
+ QVERIFY(it2 != map.begin());
+ QVERIFY(it2 == map.end());
+
+ *it1 = monde;
+ QVERIFY(*it1 == monde);
+ QVERIFY(map[1] == monde);
+
+ *it1 = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(map[1] == hello);
+
+ map[1] = monde;
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == monde);
+ QVERIFY(*it1 == monde);
+ QVERIFY(map[1] == monde);
+
+ map[1] = hello;
+ QVERIFY(*it1 == hello);
+ QVERIFY(map[1] == hello);
+
+ *++it1 = allo;
+ QVERIFY(*it1 == allo);
+ QVERIFY(map[2] == allo);
+ *it1 = world;
+
+ ++it1;
+ QVERIFY(it1 == map.end());
+
+ int count = 0;
+ it1 = map.begin();
+ while (it1 != map.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+ }
+
+ {
+ const Map map2 = map;
+
+ Map::const_iterator it1 = map2.find(1);
+ QVERIFY(it1 != map2.end());
+ QVERIFY(it1.key() == 1);
+ QVERIFY(it1.value() == hello);
+ QVERIFY(*it1 == hello);
+ ++it1;
+
+ Map::const_iterator it2 = map2.find(2);
+ QVERIFY(it1 == it2);
+ ++it1;
+ QVERIFY(it1 == map2.end());
+ QVERIFY(it2 != map2.end());
+ QVERIFY(it1 != it2);
+
+ int count = 0;
+ it1 = map2.begin();
+ while (it1 != map2.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+
+ count = 0;
+ it1 = map.begin();
+ while (it1 != map.end()) {
+ count++;
+ ++it1;
+ }
+ QVERIFY(count == 2);
+ }
+
+ {
+ QVERIFY(map.contains(1));
+ QVERIFY(map.contains(2));
+ QVERIFY(!map.contains(0));
+ QVERIFY(!map.contains(3));
+ }
+
+ {
+ QVERIFY(map.value(1) == hello);
+ QVERIFY(map.value(2) == world);
+ QVERIFY(map.value(3) == 0);
+ QVERIFY(map.value(1, allo) == hello);
+ QVERIFY(map.value(2, allo) == world);
+ QVERIFY(map.value(3, allo) == allo);
+ QVERIFY(map.value(0, monde) == monde);
+ }
+ int originalLargeStaticCount = LargeStatic::count;
+ {
+ QMap<int,LargeStatic> map;
+ for (int i = 0; i < 10; i++)
+ map.insert(i, LargeStatic());
QVERIFY(LargeStatic::count == (originalLargeStaticCount + 10));
- map.remove(7);
- QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9));
-
- }
- QVERIFY(LargeStatic::count == originalLargeStaticCount);
- {
- QMap<int, int*> map;
- QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0);
- }
-
- {
- QMap<int, int> map;
- map[0] = 1;
- map[1] = 2;
- map[2] = 4;
- map[3] = 8;
- int sum = 0;
- int sumkey = 0;
- QMapIterator<int,int> i = map;
- while (i.hasNext()) {
- sum += i.next().value();
- sumkey += i.key();
- }
- QVERIFY(sum == 15);
- QVERIFY(sumkey == 6);
- }
- {
- QMap<int, int> map;
- map[0] = 1;
- map[1] = 2;
- map[2] = 4;
- map[3] = 8;
- int sum = 0;
- QMutableMapIterator<int,int> i = map;
- while(i.hasNext())
- if (i.next().key() == 2)
- i.remove();
- i.toFront();
- while(i.hasNext()) {
- sum += i.next().value();
+ map.remove(7);
+ QVERIFY(LargeStatic::count == (originalLargeStaticCount + 9));
+
+ }
+ QVERIFY(LargeStatic::count == originalLargeStaticCount);
+ {
+ QMap<int, int*> map;
+ QVERIFY(((const QMap<int,int*>*) &map)->operator[](7) == 0);
+ }
+
+ {
+ QMap<int, int> map;
+ map[0] = 1;
+ map[1] = 2;
+ map[2] = 4;
+ map[3] = 8;
+ int sum = 0;
+ int sumkey = 0;
+ QMapIterator<int,int> i = map;
+ while (i.hasNext()) {
+ sum += i.next().value();
+ sumkey += i.key();
+ }
+ QVERIFY(sum == 15);
+ QVERIFY(sumkey == 6);
+ }
+ {
+ QMap<int, int> map;
+ map[0] = 1;
+ map[1] = 2;
+ map[2] = 4;
+ map[3] = 8;
+ int sum = 0;
+ QMutableMapIterator<int,int> i = map;
+ while (i.hasNext())
+ if (i.next().key() == 2)
+ i.remove();
+ i.toFront();
+ while (i.hasNext()) {
+ sum += i.next().value();
i.setValue(10);
i.value() += 22;
QVERIFY(i.value() == 32);
}
- QVERIFY(sum == 11);
- }
+ QVERIFY(sum == 11);
+ }
{
QMap<int, int> map;
map[0] = 1;
@@ -2177,14 +2177,14 @@ void tst_Collections::qstring()
QVERIFY(s == "stl rocks");
{
- QString str("Bananas");
- QVERIFY(str.startsWith("Ban"));
- QVERIFY(false == str.startsWith("Car"));
+ QString str("Bananas");
+ QVERIFY(str.startsWith("Ban"));
+ QVERIFY(false == str.startsWith("Car"));
}
{
- QString str("Bananas");
- QVERIFY(str.endsWith("anas"));
- QVERIFY(false == str.endsWith("pple"));
+ QString str("Bananas");
+ QVERIFY(str.endsWith("anas"));
+ QVERIFY(false == str.endsWith("pple"));
}
@@ -2257,7 +2257,7 @@ void tst_Collections::bitArray()
QVERIFY(ba[4]);
int sum = 0;
for(int i = 0; i < 20; i++)
- sum += ba.testBit(i) ? 1 : 0;
+ sum += ba.testBit(i) ? 1 : 0;
QVERIFY(sum == 2);
ba = QBitArray(7, true);
@@ -2288,36 +2288,36 @@ int CacheFoo::counter = 0;
void tst_Collections::cache()
{
{
- QCache<int, CacheFoo> cache(120);
- int i;
- for (i = 0; i < 30; i++) {
+ QCache<int, CacheFoo> cache(120);
+ int i;
+ for (i = 0; i < 30; i++) {
cache.object(10);
- cache.insert(i, new CacheFoo(i), i);
- }
+ cache.insert(i, new CacheFoo(i), i);
+ }
- QVERIFY(cache.contains(10));
- QVERIFY(!cache.contains(1));
- QVERIFY(!cache.contains(2));
- delete cache.take(10);
+ QVERIFY(cache.contains(10));
+ QVERIFY(!cache.contains(1));
+ QVERIFY(!cache.contains(2));
+ delete cache.take(10);
}
{
- QCache<int, QString> cache(120);
- int i;
- QString two;
- for (i = 0; i < 30; i++) {
- QString s = QString::number(i);
- cache.insert(i, new QString(s), i);
- if (i == 2)
- two = s;
- }
- QVERIFY(!cache.contains(3));
- QVERIFY(!cache.contains(2));
+ QCache<int, QString> cache(120);
+ int i;
+ QString two;
+ for (i = 0; i < 30; i++) {
+ QString s = QString::number(i);
+ cache.insert(i, new QString(s), i);
+ if (i == 2)
+ two = s;
+ }
+ QVERIFY(!cache.contains(3));
+ QVERIFY(!cache.contains(2));
}
{
- QCache<int, int> cache(100);
- cache.insert(2, new int(2));
- *cache[2] = 3;
- QVERIFY(*cache.object(2) == 3);
+ QCache<int, int> cache(100);
+ cache.insert(2, new int(2));
+ *cache[2] = 3;
+ QVERIFY(*cache.object(2) == 3);
}
QVERIFY(CacheFoo::counter == 0);
diff --git a/tests/auto/other/d3dcompiler/d3dcompiler.pro b/tests/auto/other/d3dcompiler/d3dcompiler.pro
new file mode 100644
index 0000000000..6242d0a554
--- /dev/null
+++ b/tests/auto/other/d3dcompiler/d3dcompiler.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+TARGET = tst_d3dcompiler
+QT = core testlib
+
+SOURCES = tst_d3dcompiler.cpp
diff --git a/tests/auto/other/d3dcompiler/tst_d3dcompiler.cpp b/tests/auto/other/d3dcompiler/tst_d3dcompiler.cpp
new file mode 100644
index 0000000000..1a34c2076b
--- /dev/null
+++ b/tests/auto/other/d3dcompiler/tst_d3dcompiler.cpp
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This test verifies the behavior of d3dcompiler_qt, which is only built when ANGLE is enabled
+
+#include <QCryptographicHash>
+#include <QDir>
+#include <QFuture>
+#include <QObject>
+#include <QStandardPaths>
+#include <QTemporaryDir>
+#include <QTest>
+#include <QThread>
+
+#if defined(Q_OS_WIN)
+
+#include <d3dcommon.h>
+
+#ifndef Q_OS_WINRT
+#define loadLibrary(library) LoadLibrary(library)
+#else
+#define loadLibrary(library) LoadPackagedLibrary(library, NULL)
+#endif
+
+#ifdef D3DCOMPILER_DLL
+#undef D3DCOMPILER_DLL
+#endif
+
+#ifdef QT_NO_DEBUG
+#define D3DCOMPILER_DLL L"d3dcompiler_qt"
+#else
+#define D3DCOMPILER_DLL L"d3dcompiler_qtd"
+#endif
+
+#define getCompilerFunc(dll) reinterpret_cast<D3DCompileFunc>(GetProcAddress(dll, "D3DCompile"))
+
+typedef HRESULT (WINAPI *D3DCompileFunc)(const void *data, SIZE_T data_size, const char *filename,
+ const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
+ const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages);
+
+static const wchar_t *compilerDlls[] = {
+ L"d3dcompiler_47.dll",
+ L"d3dcompiler_46.dll",
+ L"d3dcompiler_45.dll",
+ L"d3dcompiler_44.dll",
+ L"d3dcompiler_43.dll",
+ 0
+};
+
+static const char hlsl[] =
+ "uniform SamplerState Sampler : register(s0);\n"
+ "uniform Texture2D Texture : register(t0);\n"
+ "float4 main(in float4 gl_Position : SV_POSITION, in float2 coord : TEXCOORD0) : SV_TARGET0\n"
+ "{\n"
+ "return Texture.Sample(Sampler, coord);\n"
+ "}\n";
+
+static inline QByteArray blobToByteArray(ID3DBlob *blob)
+{
+ return blob ? QByteArray::fromRawData(reinterpret_cast<const char *>(blob->GetBufferPointer()), blob->GetBufferSize()) : QByteArray();
+}
+
+class CompileRunner : public QThread
+{
+public:
+ CompileRunner(D3DCompileFunc d3dCompile, const QByteArray &data, ID3DBlob **shader, ID3DBlob **error)
+ : m_d3dCompile(d3dCompile), m_data(data), m_shader(shader), m_error(error)
+ {
+ }
+
+ HRESULT result() const
+ {
+ return m_result;
+ }
+
+private:
+ void run()
+ {
+ m_result = m_d3dCompile(m_data.constData(), m_data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, m_shader, m_error);
+ }
+
+ HRESULT m_result;
+ D3DCompileFunc m_d3dCompile;
+ QByteArray m_data;
+ ID3DBlob **m_shader;
+ ID3DBlob **m_error;
+};
+
+class tst_d3dcompiler : public QObject
+{
+ Q_OBJECT
+private slots:
+ void initTestCase();
+ void init();
+ void cleanup();
+ void service_data();
+ void service();
+ void offlineCompile();
+ void onlineCompile();
+
+private:
+ QString blobPath();
+
+ HMODULE d3dcompiler_qt;
+ HMODULE d3dcompiler_win;
+
+ D3DCompileFunc d3dCompile;
+
+ QTemporaryDir tempDir;
+};
+
+QString tst_d3dcompiler::blobPath()
+{
+ QDir path;
+ if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
+ path.setPath(qgetenv("QT_D3DCOMPILER_DIR"));
+ else
+ path.setPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QStringLiteral("/d3dcompiler"));
+
+ path.mkdir(QStringLiteral("binary"));
+ path.mkdir(QStringLiteral("source"));
+
+ return path.absolutePath();
+}
+
+void tst_d3dcompiler::initTestCase()
+{
+ QVERIFY(tempDir.isValid());
+}
+
+void tst_d3dcompiler::init()
+{
+ qunsetenv("QT_D3DCOMPILER_DIR");
+ qunsetenv("QT_D3DCOMPILER_TIMEOUT");
+}
+
+void tst_d3dcompiler::cleanup()
+{
+ FreeLibrary(d3dcompiler_qt);
+ FreeLibrary(d3dcompiler_win);
+
+ QDir path(blobPath());
+ foreach (const QString &entry, path.entryList(QStringList(), QDir::Files|QDir::NoDotAndDotDot))
+ path.remove(entry);
+ foreach (const QString &entry, path.entryList(QStringList(), QDir::Dirs|QDir::NoDotAndDotDot)) {
+ QDir dir(path.absoluteFilePath(entry + QStringLiteral("/")));
+ dir.removeRecursively();
+ }
+}
+
+void tst_d3dcompiler::service_data()
+{
+ QTest::addColumn<QByteArray>("compilerDir");
+ QTest::addColumn<bool>("exists");
+ QTest::addColumn<HRESULT>("result");
+
+ // Don't test the default case, as it would clutter the AppData directory
+ //QTest::newRow("default") << QByteArrayLiteral("") << true << E_ABORT;
+ QTest::newRow("temporary") << QFile::encodeName(tempDir.path()) << true << E_ABORT;
+ QTest::newRow("invalid") << QByteArrayLiteral("ZZ:\\") << false << S_OK;
+ QTest::newRow("empty") << QByteArrayLiteral("") << false << S_OK;
+}
+
+void tst_d3dcompiler::service()
+{
+ QFETCH(QByteArray, compilerDir);
+ QFETCH(bool, exists);
+ QFETCH(HRESULT, result);
+ qputenv("QT_D3DCOMPILER_DIR", compilerDir);
+ const QDir path = blobPath();
+
+ if (exists) {
+ // Activate service
+ QVERIFY(path.exists());
+
+ QFile control(path.absoluteFilePath(QStringLiteral("control")));
+ QVERIFY(control.open(QFile::WriteOnly));
+ control.close();
+ QVERIFY(control.exists());
+ } else {
+ QVERIFY(!path.exists());
+ }
+
+ // Run compiler (fast fail)
+ d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
+ QVERIFY(d3dcompiler_qt);
+ d3dCompile = getCompilerFunc(d3dcompiler_qt);
+ QVERIFY(d3dCompile);
+
+ qputenv("QT_D3DCOMPILER_TIMEOUT", "1");
+ const QByteArray data(hlsl);
+ ID3DBlob *shader = 0, *errorMessage = 0;
+ HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
+ QVERIFY2(hr == result, blobToByteArray(errorMessage));
+
+ // Check that passthrough works
+ if (hr == S_OK) {
+ for (int i = 0; compilerDlls[i]; ++i) {
+ d3dcompiler_win = loadLibrary(compilerDlls[i]);
+ if (d3dcompiler_win)
+ break;
+ }
+ QVERIFY(d3dcompiler_win);
+ d3dCompile = getCompilerFunc(d3dcompiler_win);
+ QVERIFY(d3dCompile);
+
+ // Compile a shader to compare with
+ ID3DBlob *reference = 0;
+ HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &reference, &errorMessage);
+ QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage));
+
+ QByteArray shaderData(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
+ QByteArray referenceData(reinterpret_cast<const char *>(reference->GetBufferPointer()), reference->GetBufferSize());
+ reference->Release();
+ QCOMPARE(shaderData, referenceData);
+ } else {
+ QVERIFY(FAILED(hr));
+ }
+
+ if (shader)
+ shader->Release();
+}
+
+void tst_d3dcompiler::offlineCompile()
+{
+ qputenv("QT_D3DCOMPILER_DIR", QFile::encodeName(tempDir.path()));
+
+ for (int i = 0; compilerDlls[i]; ++i) {
+ d3dcompiler_win = loadLibrary(compilerDlls[i]);
+ if (d3dcompiler_win)
+ break;
+ }
+ QVERIFY(d3dcompiler_win);
+ d3dCompile = getCompilerFunc(d3dcompiler_win);
+ QVERIFY(d3dCompile);
+
+ // Compile a shader to place in binary directory
+ const QByteArray data(hlsl);
+ ID3DBlob *shader = 0, *errorMessage = 0;
+ HRESULT hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
+ QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage));
+ QVERIFY(shader);
+
+ QDir outputPath(blobPath());
+ QVERIFY(outputPath.exists());
+ QVERIFY(outputPath.exists(QStringLiteral("binary")));
+ outputPath.cd(QStringLiteral("binary"));
+ QFile output(outputPath.absoluteFilePath(QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex()));
+ QVERIFY(output.open(QFile::WriteOnly));
+ output.write(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
+ shader->Release();
+
+ // Run compiler
+ d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
+ QVERIFY(d3dcompiler_qt);
+ d3dCompile = getCompilerFunc(d3dcompiler_qt);
+ QVERIFY(d3dCompile);
+
+ hr = d3dCompile(data.constData(), data.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &shader, &errorMessage);
+ // Returns S_FALSE if a cached shader was found
+ QVERIFY2(hr == S_FALSE, blobToByteArray(errorMessage));
+}
+
+void tst_d3dcompiler::onlineCompile()
+{
+ qputenv("QT_D3DCOMPILER_DIR", QFile::encodeName(tempDir.path()));
+
+ QByteArray data(hlsl);
+
+ const QDir path = blobPath();
+
+ // Activate service
+ QVERIFY(path.exists());
+ QFile control(path.absoluteFilePath(QStringLiteral("control")));
+ QVERIFY(control.open(QFile::WriteOnly));
+ control.close();
+ QVERIFY(control.exists());
+
+ d3dcompiler_qt = loadLibrary(D3DCOMPILER_DLL);
+ QVERIFY(d3dcompiler_qt);
+ D3DCompileFunc concurrentCompile = getCompilerFunc(d3dcompiler_qt);
+ QVERIFY(d3dCompile);
+
+ // Run async
+ ID3DBlob *shader = 0, *errorMessage = 0;
+ CompileRunner runner(concurrentCompile, data, &shader, &errorMessage);
+ runner.start();
+
+ // Wait for source to appear
+ QVERIFY(path.exists());
+ QVERIFY(path.exists(QStringLiteral("source")));
+ QVERIFY(path.exists(QStringLiteral("binary")));
+
+ const QString fileName = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex()
+ + QStringLiteral("!main!ps_4_0!0");
+ QFile input(path.absoluteFilePath(QStringLiteral("source/") + fileName));
+ QTRY_VERIFY_WITH_TIMEOUT(input.exists(), 3000);
+ QTRY_VERIFY_WITH_TIMEOUT(input.isOpen() || input.open(QFile::ReadOnly), 1000);
+
+ // Compile passed source
+ const QByteArray inputData = input.readAll();
+ for (int i = 0; compilerDlls[i]; ++i) {
+ d3dcompiler_win = loadLibrary(compilerDlls[i]);
+ if (d3dcompiler_win)
+ break;
+ }
+ QVERIFY(d3dcompiler_win);
+ d3dCompile = getCompilerFunc(d3dcompiler_win);
+ QVERIFY(d3dCompile);
+ ID3DBlob *reference = 0, *errorMessage2 = 0;
+ HRESULT hr = d3dCompile(inputData.constData(), inputData.size(), 0, 0, 0, "main", "ps_4_0", 0, 0, &reference, &errorMessage2);
+ QVERIFY2(SUCCEEDED(hr), blobToByteArray(errorMessage2));
+ const QByteArray referenceData(reinterpret_cast<const char *>(reference->GetBufferPointer()), reference->GetBufferSize());
+ reference->Release();
+
+ // Write to output directory
+ QFile output(path.absoluteFilePath(QStringLiteral("binary/") + fileName));
+ QVERIFY(output.open(QFile::WriteOnly));
+ output.write(referenceData);
+ output.close();
+
+ // All done
+ QVERIFY(runner.wait(3000));
+ hr = runner.result();
+ QVERIFY2(hr == S_FALSE, blobToByteArray(errorMessage2));
+ const QByteArray resultData(reinterpret_cast<const char *>(shader->GetBufferPointer()), shader->GetBufferSize());
+ shader->Release();
+ QVERIFY(referenceData == resultData);
+}
+
+QTEST_MAIN(tst_d3dcompiler)
+#include "tst_d3dcompiler.moc"
+
+#endif // Q_OS_WIN
diff --git a/tests/auto/other/languagechange/tst_languagechange.cpp b/tests/auto/other/languagechange/tst_languagechange.cpp
index cc01d70454..16c3d56385 100644
--- a/tests/auto/other/languagechange/tst_languagechange.cpp
+++ b/tests/auto/other/languagechange/tst_languagechange.cpp
@@ -188,11 +188,11 @@ void tst_languageChange::retranslatability_data()
//next we fill it with data
QTest::newRow( "QInputDialog" )
<< int(InputDialog) << (QSet<QByteArray>()
- << "QDialogButtonBox::Cancel");
+ << "QPlatformTheme::Cancel");
QTest::newRow( "QColorDialog" )
<< int(ColorDialog) << (QSet<QByteArray>()
- << "QDialogButtonBox::Cancel"
+ << "QPlatformTheme::Cancel"
<< "QColorDialog::&Sat:"
<< "QColorDialog::&Add to Custom Colors"
<< "QColorDialog::&Green:"
@@ -237,8 +237,8 @@ void tst_languageChange::retranslatability_data()
<< "QFileSystemModel::Type::All other platforms"
#endif
// << "QFileSystemModel::%1 KB"
- << "QDialogButtonBox::Cancel"
- << "QDialogButtonBox::Open"
+ << "QPlatformTheme::Cancel"
+ << "QPlatformTheme::Open"
<< "QFileDialog::File &name:");
}
diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro
index 63cbca539d..2bddc8d127 100644
--- a/tests/auto/other/other.pro
+++ b/tests/auto/other/other.pro
@@ -4,6 +4,7 @@ SUBDIRS=\
baselineexample \
collections \
compiler \
+ d3dcompiler \
gestures \
headersclean \
lancelot \
@@ -57,6 +58,8 @@ cross_compile: SUBDIRS -= \
wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility
+!angle_d3d11: SUBDIRS -= d3dcompiler
+
!contains(QT_CONFIG, accessibility-atspi-bridge): SUBDIRS -= qaccessibilitylinux
!mac: SUBDIRS -= \
diff --git a/tests/auto/other/qaccessibility/qaccessibility.pro b/tests/auto/other/qaccessibility/qaccessibility.pro
index 70f6633195..e6c5bb1149 100644
--- a/tests/auto/other/qaccessibility/qaccessibility.pro
+++ b/tests/auto/other/qaccessibility/qaccessibility.pro
@@ -13,10 +13,11 @@ wince*: {
}
win32 {
- !*g++ {
+ !*g++:!winrt {
include(../../../../src/3rdparty/iaccessible2/iaccessible2.pri)
DEFINES += QT_SUPPORTS_IACCESSIBLE2
}
- LIBS += -loleacc -loleaut32 -lole32 -luuid
+ LIBS += -luuid
+ !winphone: LIBS += -loleacc -loleaut32 -lole32
}
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 73bf4aab6a..dc3f266025 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -43,7 +43,9 @@
#include <QtCore/qglobal.h>
#ifdef Q_OS_WIN
# include <QtCore/qt_windows.h>
+#ifndef Q_OS_WINRT
# include <oleacc.h>
+#endif
# include <servprov.h>
# include <winuser.h>
# ifdef QT_SUPPORTS_IACCESSIBLE2
@@ -3366,7 +3368,7 @@ void tst_QAccessibility::bridgeTest()
{
// For now this is a simple test to see if the bridge is working at all.
// Ideally it should be extended to test all aspects of the bridge.
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
// First, test MSAA part of bridge
QWidget *window = new QWidget;
QVBoxLayout *lay = new QVBoxLayout(window);
diff --git a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
index 79fd29f2a1..50bf342365 100644
--- a/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
+++ b/tests/auto/other/qaccessibilitylinux/tst_qaccessibilitylinux.cpp
@@ -90,6 +90,9 @@ class tst_QAccessibilityLinux : public QObject
{
Q_OBJECT
+public:
+ tst_QAccessibilityLinux() : m_window(0), root(0), rootApplication(0), mainWindow(0) {}
+
private slots:
void initTestCase();
diff --git a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp
index ff440948a2..7eb8479372 100644
--- a/tests/auto/other/qcomplextext/tst_qcomplextext.cpp
+++ b/tests/auto/other/qcomplextext/tst_qcomplextext.cpp
@@ -102,12 +102,12 @@ void tst_QComplexText::bidiReorderString_data()
const LV *data = logical_visual;
while ( data->name ) {
- //next we fill it with data
- QTest::newRow( data->name )
- << QString::fromUtf8( data->logical )
- << QString::fromUtf8( data->visual )
- << (int) data->basicDir;
- data++;
+ //next we fill it with data
+ QTest::newRow( data->name )
+ << QString::fromUtf8( data->logical )
+ << QString::fromUtf8( data->visual )
+ << (int) data->basicDir;
+ data++;
}
}
@@ -127,34 +127,34 @@ void tst_QComplexText::bidiReorderString()
int nitems = e.layoutData->items.size();
int i;
for (i = 0; i < nitems; ++i) {
- //qDebug("item %d bidiLevel=%d", i, e.items[i].analysis.bidiLevel);
- levels[i] = e.layoutData->items[i].analysis.bidiLevel;
+ //qDebug("item %d bidiLevel=%d", i, e.items[i].analysis.bidiLevel);
+ levels[i] = e.layoutData->items[i].analysis.bidiLevel;
}
e.bidiReorder(nitems, levels, visualOrder);
QString visual;
for (i = 0; i < nitems; ++i) {
- QScriptItem &si = e.layoutData->items[visualOrder[i]];
- QString sub = logical.mid(si.position, e.length(visualOrder[i]));
- if (si.analysis.bidiLevel % 2) {
- // reverse sub
- QChar *a = (QChar *)sub.unicode();
- QChar *b = a + sub.length() - 1;
- while (a < b) {
- QChar tmp = *a;
- *a = *b;
- *b = tmp;
- ++a;
- --b;
- }
- a = (QChar *)sub.unicode();
- b = a + sub.length();
- while (a<b) {
- *a = a->mirroredChar();
- ++a;
- }
- }
- visual += sub;
+ QScriptItem &si = e.layoutData->items[visualOrder[i]];
+ QString sub = logical.mid(si.position, e.length(visualOrder[i]));
+ if (si.analysis.bidiLevel % 2) {
+ // reverse sub
+ QChar *a = (QChar *)sub.unicode();
+ QChar *b = a + sub.length() - 1;
+ while (a < b) {
+ QChar tmp = *a;
+ *a = *b;
+ *b = tmp;
+ ++a;
+ --b;
+ }
+ a = (QChar *)sub.unicode();
+ b = a + sub.length();
+ while (a<b) {
+ *a = a->mirroredChar();
+ ++a;
+ }
+ }
+ visual += sub;
}
// replace Unicode newline back with \n to compare.
visual.replace(QChar(0x2028), QChar('\n'));
diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
index b194d08a65..33deed9737 100644
--- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
+++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
@@ -72,14 +72,14 @@ protected:
{
QLineEdit::focusInEvent( e );
focusInEventReason = e->reason();
- focusInEventGotFocus = e->gotFocus();
+ focusInEventGotFocus = e->gotFocus();
focusInEventRecieved = true;
}
void focusOutEvent( QFocusEvent* e )
{
QLineEdit::focusOutEvent( e );
focusOutEventReason = e->reason();
- focusOutEventLostFocus = !e->gotFocus();
+ focusOutEventLostFocus = !e->gotFocus();
focusOutEventRecieved = true;
}
};
@@ -372,9 +372,6 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
#if defined(Q_OS_IRIX)
QEXPECT_FAIL("", "IRIX requires explicit activateWindow(), so this test does not make any sense.", Abort);
#endif
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-22815", Abort);
-#endif
QTRY_VERIFY(childFocusWidgetOne->focusInEventRecieved);
QVERIFY(childFocusWidgetOne->focusInEventGotFocus);
diff --git a/tests/auto/other/qvariant_common/tst_qvariant_common.h b/tests/auto/other/qvariant_common/tst_qvariant_common.h
index fc3eff4b91..7a34d7b0c2 100644
--- a/tests/auto/other/qvariant_common/tst_qvariant_common.h
+++ b/tests/auto/other/qvariant_common/tst_qvariant_common.h
@@ -107,7 +107,7 @@ protected:
currentName.chop(1);
ok &= (msg.contains(", " + currentName) || msg.contains(", 0x0"));
}
- ok &= msg.endsWith(") ");
+ ok &= msg.endsWith(")");
QVERIFY2(ok, (QString::fromLatin1("Message is not correctly finished: '") + msg + '\'').toLatin1().constData());
}
diff --git a/tests/auto/printsupport/dialogs/dialogs.pro b/tests/auto/printsupport/dialogs/dialogs.pro
new file mode 100644
index 0000000000..419bd13ccf
--- /dev/null
+++ b/tests/auto/printsupport/dialogs/dialogs.pro
@@ -0,0 +1,3 @@
+TEMPLATE=subdirs
+SUBDIRS=\
+ qabstractprintdialog \
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore b/tests/auto/printsupport/dialogs/qabstractprintdialog/.gitignore
index a768494da5..a768494da5 100644
--- a/tests/auto/widgets/dialogs/qabstractprintdialog/.gitignore
+++ b/tests/auto/printsupport/dialogs/qabstractprintdialog/.gitignore
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro b/tests/auto/printsupport/dialogs/qabstractprintdialog/qabstractprintdialog.pro
index 2e9ae33592..2e9ae33592 100644
--- a/tests/auto/widgets/dialogs/qabstractprintdialog/qabstractprintdialog.pro
+++ b/tests/auto/printsupport/dialogs/qabstractprintdialog/qabstractprintdialog.pro
diff --git a/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp b/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
index c79a4a97ef..c79a4a97ef 100644
--- a/tests/auto/widgets/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
+++ b/tests/auto/printsupport/dialogs/qabstractprintdialog/tst_qabstractprintdialog.cpp
diff --git a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
index b8b4c00549..9571cb4110 100644
--- a/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
+++ b/tests/auto/printsupport/kernel/qprinter/tst_qprinter.cpp
@@ -88,10 +88,7 @@ public slots:
void cleanupTestCase();
#else
private slots:
- void getSetCheck();
-// Add your testfunctions and testdata create functions here
#ifdef Q_OS_WIN
- void testPageSize();
void testNonExistentPrinter();
#endif
void testPageRectAndPaperRect();
@@ -105,10 +102,8 @@ private slots:
void testMulitpleSets();
void testPageMargins_data();
void testPageMargins();
- void changingOutputFormat();
void outputFormatFromSuffix();
void setGetPaperSize();
- void valuePreservation();
void errorReporting();
void testCustomPageSizes();
void customPaperSizeAndMargins_data();
@@ -118,14 +113,41 @@ private slots:
#if !defined(QT_NO_COMPLETER) && !defined(QT_NO_FILEDIALOG)
void printDialogCompleter();
#endif
-
- void testCopyCount();
void testCurrentPage();
-
void taskQTBUG4497_reusePrinterOnDifferentFiles();
void testPdfTitle();
void testPageMetrics_data();
void testPageMetrics();
+
+ // Test QPrintEngine keys and their QPrinter setters/getters
+ void testMultipleKeys();
+ void collateCopies();
+ void colorMode();
+ void copyCount();
+ void creator();
+ void docName();
+ void doubleSidedPrinting();
+ void duplex();
+ void fontEmbedding();
+ void fullPage();
+ void orientation();
+ void outputFileName();
+ void pageOrder();
+ void pageSize();
+ void paperSize();
+ void paperSource();
+ void printerName();
+ void printerSelectionOption();
+ void printProgram();
+ void printRange();
+ void resolution();
+ void supportedPaperSources();
+ void supportedResolutions();
+ void windowsPageSize();
+
+ // Test QPrinter setters/getters for non-QPrintEngine options
+ void outputFormat();
+ void fromToPage();
#endif
};
@@ -140,98 +162,6 @@ void tst_QPrinter::cleanupTestCase()
QSKIP("This test requires printing support");
}
#else
-// Testing get/set functions
-void tst_QPrinter::getSetCheck()
-{
- QPrinter obj1;
- // OutputFormat QPrinter::outputFormat()
- // void QPrinter::setOutputFormat(OutputFormat)
- obj1.setOutputFormat(QPrinter::OutputFormat(QPrinter::PdfFormat));
- QCOMPARE(QPrinter::OutputFormat(QPrinter::PdfFormat), obj1.outputFormat());
-
- // bool QPrinter::collateCopies()
- // void QPrinter::setCollateCopies(bool)
- obj1.setCollateCopies(false);
- QCOMPARE(false, obj1.collateCopies());
- obj1.setCollateCopies(true);
- QCOMPARE(true, obj1.collateCopies());
-
- obj1.setColorMode(QPrinter::GrayScale);
- QCOMPARE(obj1.colorMode(), QPrinter::GrayScale);
- obj1.setColorMode(QPrinter::Color);
- QCOMPARE(obj1.colorMode(), QPrinter::Color);
-
- obj1.setCreator(QString::fromLatin1("RandomQtUser"));
- QCOMPARE(obj1.creator(), QString::fromLatin1("RandomQtUser"));
-
- obj1.setDocName(QString::fromLatin1("RandomQtDocument"));
- QCOMPARE(obj1.docName(), QString::fromLatin1("RandomQtDocument"));
-
- obj1.setDoubleSidedPrinting(true);
- QCOMPARE(obj1.doubleSidedPrinting(), true);
- obj1.setDoubleSidedPrinting(false);
- QCOMPARE(obj1.doubleSidedPrinting(), false);
-
- obj1.setFromTo(1, 4);
- QCOMPARE(obj1.fromPage(), 1);
- QCOMPARE(obj1.toPage(), 4);
-
- obj1.setFullPage(true);
- QCOMPARE(obj1.fullPage(), true);
- obj1.setFullPage(false);
- QCOMPARE(obj1.fullPage(), false);
-
- obj1.setOrientation(QPrinter::Landscape);
- QCOMPARE(obj1.orientation(), QPrinter::Landscape);
- obj1.setOrientation(QPrinter::Portrait);
- QCOMPARE(obj1.orientation(), QPrinter::Portrait);
-
- obj1.setOutputFileName(QString::fromLatin1("RandomQtName"));
- QCOMPARE(obj1.outputFileName(), QString::fromLatin1("RandomQtName"));
-
- obj1.setPageOrder(QPrinter::FirstPageFirst);
- QCOMPARE(obj1.pageOrder(), QPrinter::FirstPageFirst);
- obj1.setPageOrder(QPrinter::LastPageFirst);
- QCOMPARE(obj1.pageOrder(), QPrinter::LastPageFirst);
-
- obj1.setPaperSource(QPrinter::Cassette);
- QCOMPARE(obj1.paperSource(), QPrinter::Cassette);
- obj1.setPaperSource(QPrinter::Middle);
- QCOMPARE(obj1.paperSource(), QPrinter::Middle);
-
-#ifdef Q_OS_UNIX
- obj1.setPrintProgram(QString::fromLatin1("/bin/true"));
- QCOMPARE(obj1.printProgram(), QString::fromLatin1("/bin/true"));
-
- obj1.setPrinterSelectionOption(QString::fromLatin1("--option"));
- QCOMPARE(obj1.printerSelectionOption(), QString::fromLatin1("--option"));
-#endif
-
- // bool QPrinter::fontEmbeddingEnabled()
- // void QPrinter::setFontEmbeddingEnabled(bool)
- obj1.setFontEmbeddingEnabled(false);
- QCOMPARE(false, obj1.fontEmbeddingEnabled());
- obj1.setFontEmbeddingEnabled(true);
- QCOMPARE(true, obj1.fontEmbeddingEnabled());
-
- // PageSize QPrinter::pageSize()
- // void QPrinter::setPageSize(PageSize)
- obj1.setPageSize(QPrinter::PageSize(QPrinter::A4));
- QCOMPARE(QPrinter::PageSize(QPrinter::A4), obj1.pageSize());
- obj1.setPageSize(QPrinter::PageSize(QPrinter::Letter));
- QCOMPARE(QPrinter::PageSize(QPrinter::Letter), obj1.pageSize());
- obj1.setPageSize(QPrinter::PageSize(QPrinter::Legal));
- QCOMPARE(QPrinter::PageSize(QPrinter::Legal), obj1.pageSize());
-
- // PrintRange QPrinter::printRange()
- // void QPrinter::setPrintRange(PrintRange)
- obj1.setPrintRange(QPrinter::PrintRange(QPrinter::AllPages));
- QCOMPARE(QPrinter::PrintRange(QPrinter::AllPages), obj1.printRange());
- obj1.setPrintRange(QPrinter::PrintRange(QPrinter::Selection));
- QCOMPARE(QPrinter::PrintRange(QPrinter::Selection), obj1.printRange());
- obj1.setPrintRange(QPrinter::PrintRange(QPrinter::PageRange));
- QCOMPARE(QPrinter::PrintRange(QPrinter::PageRange), obj1.printRange());
-}
#define MYCOMPARE(a, b) QCOMPARE(QVariant((int)a), QVariant((int)b))
@@ -287,30 +217,6 @@ void tst_QPrinter::testPrintPreviewDialog()
QCOMPARE(widget->currentPage(), 1);
}
-#ifdef Q_OS_WIN
-// QPrinter::winPageSize(): Windows only.
-void tst_QPrinter::testPageSize()
-{
- QPrinter prn;
-
- prn.setPageSize(QPrinter::Letter);
- MYCOMPARE(prn.pageSize(), QPrinter::Letter);
- MYCOMPARE(prn.winPageSize(), DMPAPER_LETTER);
-
- prn.setPageSize(QPrinter::A4);
- MYCOMPARE(prn.pageSize(), QPrinter::A4);
- MYCOMPARE(prn.winPageSize(), DMPAPER_A4);
-
- prn.setWinPageSize(DMPAPER_LETTER);
- MYCOMPARE(prn.winPageSize(), DMPAPER_LETTER);
- MYCOMPARE(prn.pageSize(), QPrinter::Letter);
-
- prn.setWinPageSize(DMPAPER_A4);
- MYCOMPARE(prn.winPageSize(), DMPAPER_A4);
- MYCOMPARE(prn.pageSize(), QPrinter::A4);
-}
-#endif // Q_OS_WIN
-
void tst_QPrinter::testPageRectAndPaperRect_data()
{
QTest::addColumn<int>("orientation");
@@ -558,17 +464,6 @@ void tst_QPrinter::testMulitpleSets()
QVERIFY(qAbs(paperHeight - widthMMAfter) <= 2);
}
-void tst_QPrinter::changingOutputFormat()
-{
-#if QT_VERSION < 0x050000
- QPrinter p;
- p.setOutputFormat(QPrinter::PostScriptFormat);
- p.setPageSize(QPrinter::A8);
- p.setOutputFormat(QPrinter::PdfFormat);
- QCOMPARE(p.pageSize(), QPrinter::A8);
-#endif
-}
-
void tst_QPrinter::outputFormatFromSuffix()
{
if (QPrinterInfo::availablePrinters().size() == 0)
@@ -673,271 +568,6 @@ void tst_QPrinter::testPageMargins()
QVERIFY(fabs(bottom*toMillimeters[unit] - nBottom*toMillimeters[QPrinter::Cicero]) < tolerance);
}
-void tst_QPrinter::valuePreservation()
-{
- QPrinter::OutputFormat oldFormat = QPrinter::PdfFormat;
- QPrinter::OutputFormat newFormat = QPrinter::NativeFormat; // TODO: Correct?
-
- // Some properties are documented to only be supported by NativeFormat in X11 environment
- bool doX11Tests = QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive) == 0;
- bool windowsPlatform = QGuiApplication::platformName().compare(QLatin1String("windows"), Qt::CaseInsensitive) == 0;
- bool manualSourceSupported = true;
-
-#ifdef Q_OS_WIN
- // QPrinter::supportedPaperSources() is only available on Windows, so just assuming manual is supported on others.
- QPrinter printer;
- printer.setOutputFormat(newFormat);
- QList<QPrinter::PaperSource> sources = printer.supportedPaperSources();
- if (!sources.contains(QPrinter::Manual)) {
- manualSourceSupported = false;
- qWarning() << "Manual paper source not supported by native printer, skipping related test.";
- }
-#endif // Q_OS_WIN
-
- // Querying PPK_CollateCopies is hardcoded to return false with Windows native print engine,
- // so skip testing that in Windows.
- if (!windowsPlatform) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- bool status = printer.collateCopies();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.collateCopies(), status);
-
- printer.setCollateCopies(!status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.collateCopies(), !status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.collateCopies(), !status);
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::ColorMode status = printer.colorMode();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.colorMode(), status);
-
- printer.setColorMode(QPrinter::ColorMode(!status));
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.colorMode(), QPrinter::ColorMode(!status));
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.colorMode(), QPrinter::ColorMode(!status));
- }
- if (doX11Tests) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.creator();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.creator(), status);
-
- status = QString::fromLatin1("Mr. Test");
- printer.setCreator(status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.creator(), status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.creator(), status);
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.docName();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.docName(), status);
-
- status = QString::fromLatin1("Test document");
- printer.setDocName(status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.docName(), status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.docName(), status);
- }
- if (doX11Tests) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- bool status = printer.doubleSidedPrinting();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.doubleSidedPrinting(), status);
-
- printer.setDoubleSidedPrinting(!status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.doubleSidedPrinting(), !status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.doubleSidedPrinting(), !status);
- }
- if (doX11Tests) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- bool status = printer.fontEmbeddingEnabled();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.fontEmbeddingEnabled(), status);
-
- printer.setFontEmbeddingEnabled(!status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.fontEmbeddingEnabled(), !status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.fontEmbeddingEnabled(), !status);
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- bool status = printer.fullPage();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.fullPage(), status);
-
- printer.setFullPage(!status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.fullPage(), !status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.fullPage(), !status);
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::Orientation status = printer.orientation();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.orientation(), status);
-
- printer.setOrientation(QPrinter::Orientation(!status));
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.orientation(), QPrinter::Orientation(!status));
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.orientation(), QPrinter::Orientation(!status));
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.outputFileName();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.outputFileName(), status);
-
- status = QString::fromLatin1("Test file");
- printer.setOutputFileName(status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.outputFileName(), status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.outputFileName(), status);
- }
- if (doX11Tests) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::PageOrder status = printer.pageOrder();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.pageOrder(), status);
-
- printer.setPageOrder(QPrinter::PageOrder(!status));
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.pageOrder(), QPrinter::PageOrder(!status));
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.pageOrder(), QPrinter::PageOrder(!status));
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::PageSize status = printer.pageSize();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.pageSize(), status);
-
- printer.setPageSize(QPrinter::B5);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.pageSize(), QPrinter::B5);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.pageSize(), QPrinter::B5);
- }
- if (manualSourceSupported) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::PaperSource status = printer.paperSource();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.paperSource(), status);
-
- printer.setPaperSource(QPrinter::Manual);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.paperSource(), QPrinter::Manual);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.paperSource(), QPrinter::Manual);
- }
- if (doX11Tests) {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.printProgram();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printProgram(), status);
-
- status = QString::fromLatin1("/usr/local/bin/lpr");
- printer.setPrintProgram(status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.printProgram(), status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printProgram(), status);
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QPrinter::PrintRange status = printer.printRange();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printRange(), status);
-
- printer.setPrintRange(QPrinter::PrintRange(!status));
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.printRange(), QPrinter::PrintRange(!status));
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printRange(), QPrinter::PrintRange(!status));
- }
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.printerName();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printerName(), status);
- }
- // QPrinter::printerSelectionOption is explicitly documented not to be available on Windows.
-#ifndef Q_OS_WIN
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- QString status = printer.printerSelectionOption();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printerSelectionOption(), status);
-
- status = QString::fromLatin1("Optional option");
- printer.setPrinterSelectionOption(status);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.printerSelectionOption(), status);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.printerSelectionOption(), status);
- }
-#endif // Q_OS_WIN
- {
- QPrinter printer;
- printer.setOutputFormat(oldFormat);
- int status = printer.resolution();
- printer.setOutputFormat(newFormat);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.resolution(), status);
-
- printer.setResolution(status-150);
- printer.setOutputFormat(newFormat);
- QCOMPARE(printer.resolution(), status-150);
- printer.setOutputFormat(oldFormat);
- QCOMPARE(printer.resolution(), status-150);
- }
-}
-
void tst_QPrinter::errorReporting()
{
QPrinter p;
@@ -1057,13 +687,6 @@ void tst_QPrinter::printDialogCompleter()
}
#endif
-void tst_QPrinter::testCopyCount()
-{
- QPrinter p;
- p.setCopyCount(15);
- QCOMPARE(p.copyCount(), 15);
-}
-
static void printPage(QPainter *painter)
{
painter->setPen(QPen(Qt::black, 4));
@@ -1255,6 +878,970 @@ void tst_QPrinter::customPaperNameSettingByName()
}
}
+// Test QPrintEngine keys and their QPrinter setters/getters
+
+void tst_QPrinter::testMultipleKeys()
+{
+ // Tests multiple keys preservation, note are only ones that are consistent across all engines
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Check default values
+ QCOMPARE(native.fullPage(), false);
+ QCOMPARE(native.orientation(), QPrinter::Portrait);
+ QCOMPARE(native.copyCount(), 1);
+ QCOMPARE(native.collateCopies(), true);
+ QCOMPARE(native.printRange(), QPrinter::AllPages);
+
+ // Change values
+ native.setFullPage(true);
+ native.setOrientation(QPrinter::Landscape);
+ native.setCopyCount(9);
+ native.setCollateCopies(false);
+ native.setPrintRange(QPrinter::CurrentPage);
+
+ // Check changed values
+ QCOMPARE(native.fullPage(), true);
+ QCOMPARE(native.orientation(), QPrinter::Landscape);
+ QCOMPARE(native.copyCount(), 9);
+ QCOMPARE(native.collateCopies(), false);
+ QCOMPARE(native.printRange(), QPrinter::CurrentPage);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.fullPage(), true);
+ QCOMPARE(native.orientation(), QPrinter::Landscape);
+ QCOMPARE(native.copyCount(), 9);
+ QCOMPARE(native.collateCopies(), false);
+ QCOMPARE(native.printRange(), QPrinter::CurrentPage);
+
+ // Change values
+ native.setFullPage(false);
+ native.setOrientation(QPrinter::Portrait);
+ native.setCopyCount(5);
+ native.setCollateCopies(true);
+ native.setPrintRange(QPrinter::PageRange);
+
+ // Check changed values
+ QCOMPARE(native.fullPage(), false);
+ QCOMPARE(native.orientation(), QPrinter::Portrait);
+ QCOMPARE(native.copyCount(), 5);
+ QCOMPARE(native.collateCopies(), true);
+ QCOMPARE(native.printRange(), QPrinter::PageRange);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::collateCopies()
+{
+ // collateCopies() / setCollateCopies() / PPK_ColorMode
+ // PdfFormat: Supported, default true
+ // NativeFormat, Cups: Supported, default true
+ // NativeFormat, Win: Supported, default true
+ // NativeFormat, Mac: Supported, default true
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.collateCopies(), true);
+ pdf.setCollateCopies(false);
+ QCOMPARE(pdf.collateCopies(), false);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.collateCopies(), true);
+
+ // Test set/get
+ bool expected = false;
+ native.setCollateCopies(expected);
+ QCOMPARE(native.collateCopies(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.collateCopies(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.collateCopies(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::colorMode()
+{
+ // colorMode() / setColorMode() / PPK_ColorMode
+ // PdfFormat: Supported, default QPrinter::Color
+ // NativeFormat, Cups: Supported, default QPrinter::Color
+ // NativeFormat, Win: Supported if valid DevMode, otherwise QPrinter::Color
+ // NativeFormat, Mac: Unsupported, always QPrinter::Color
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.colorMode(), QPrinter::Color);
+ pdf.setColorMode(QPrinter::GrayScale);
+ QCOMPARE(pdf.colorMode(), QPrinter::GrayScale);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::colorMode()
+ //QCOMPARE(native.colorMode(), QPrinter::Color);
+
+ // Test set/get
+ QPrinter::ColorMode expected = QPrinter::GrayScale;
+ native.setColorMode(expected);
+#ifdef Q_OS_MAC
+ expected = QPrinter::Color;
+#endif // Q_OS_MAC
+ QCOMPARE(native.colorMode(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.colorMode(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.colorMode(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::copyCount()
+{
+ // copyCount() / setCopyCount() / PPK_CopyCount
+ // numCopies() / setNumCopies() / PPK_NumberOfCopies
+ // actualNumCopies() / supportsMultipleCopies()
+ // PdfFormat: Supported, multiple copies unsupported, default 1
+ // NativeFormat, Cups: Supported, multiple copies supported, default 1
+ // NativeFormat, Win: Supported, multiple copies supported, default 1
+ // NativeFormat, Mac: Supported, multiple copies supported, default 1
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.supportsMultipleCopies(), false);
+ QCOMPARE(pdf.copyCount(), 1);
+ QCOMPARE(pdf.numCopies(), 1);
+ QCOMPARE(pdf.actualNumCopies(), 1);
+ pdf.setCopyCount(9);
+ QCOMPARE(pdf.copyCount(), 9);
+ QCOMPARE(pdf.numCopies(), 9);
+ QCOMPARE(pdf.actualNumCopies(), 9);
+ pdf.setNumCopies(7);
+ QCOMPARE(pdf.copyCount(), 7);
+ QCOMPARE(pdf.numCopies(), 7);
+ QCOMPARE(pdf.actualNumCopies(), 7);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.supportsMultipleCopies(), true);
+ QCOMPARE(native.copyCount(), 1);
+ QCOMPARE(native.numCopies(), 1);
+ QCOMPARE(native.actualNumCopies(), 1);
+
+ // Test set/get
+ native.setCopyCount(9);
+ QCOMPARE(native.copyCount(), 9);
+ QCOMPARE(native.numCopies(), 1);
+ QCOMPARE(native.actualNumCopies(), 9);
+ native.setNumCopies(7);
+ QCOMPARE(native.copyCount(), 7);
+ QCOMPARE(native.numCopies(), 1);
+ QCOMPARE(native.actualNumCopies(), 7);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.copyCount(), 7);
+ QCOMPARE(native.numCopies(), 7);
+ QCOMPARE(native.actualNumCopies(), 7);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.copyCount(), 7);
+ QCOMPARE(native.numCopies(), 1);
+ QCOMPARE(native.actualNumCopies(), 7);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::creator()
+{
+ // creator() / setCreator() / PPK_Creator
+ // PdfFormat: Supported, default QString()
+ // NativeFormat, Cups: Supported, default QString()
+ // NativeFormat, Win: Supported, default QString()
+ // NativeFormat, Mac: Supported, default QString()
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.creator(), QString());
+ pdf.setCreator(QStringLiteral("Test Creator"));
+ QCOMPARE(pdf.creator(), QStringLiteral("Test Creator"));
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.creator(), QString());
+
+ // Test set/get
+ QString expected = QStringLiteral("Test Creator");
+ native.setCreator(expected);
+ QCOMPARE(native.creator(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.creator(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.creator(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::docName()
+{
+ // docName() / setDocName() / PPK_DocumentName
+ // PdfFormat: Supported, default QString()
+ // NativeFormat, Cups: Supported, default QString()
+ // NativeFormat, Win: Supported, default QString()
+ // NativeFormat, Mac: Supported, default QString()
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.docName(), QString());
+ pdf.setDocName(QStringLiteral("Test Name"));
+ QCOMPARE(pdf.docName(), QStringLiteral("Test Name"));
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.docName(), QString());
+
+ // Test set/get
+ QString expected = QStringLiteral("Test Name");
+ native.setDocName(expected);
+ QCOMPARE(native.docName(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.docName(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.docName(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::duplex()
+{
+ // duplex()) / setDuplex() / PPK_Duplex
+ // PdfFormat: Supported, default QPrinter::DuplexNone
+ // NativeFormat, Cups: Supported, default QPrinter::DuplexNone
+ // NativeFormat, Win: Unsupported, always QPrinter::DuplexNone
+ // NativeFormat, Mac: Unsupported, always QPrinter::DuplexNone
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.duplex(), QPrinter::DuplexNone);
+ pdf.setDuplex(QPrinter::DuplexAuto);
+ QCOMPARE(pdf.duplex(), QPrinter::DuplexAuto);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::duplex()
+ //QCOMPARE(native.duplex(), QPrinter::DuplexNone);
+
+ // Test set/get
+ QPrinter::DuplexMode expected = QPrinter::DuplexAuto;
+ native.setDuplex(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected = QPrinter::DuplexNone;
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.duplex(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.duplex(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.duplex(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::doubleSidedPrinting()
+{
+ // PdfFormat: Supported, default false
+ // NativeFormat, Cups: Supported, default false
+ // NativeFormat, Win: Unsupported, always false
+ // NativeFormat, Mac: Unsupported, always false
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.doubleSidedPrinting(), false);
+ pdf.setDoubleSidedPrinting(true);
+ QCOMPARE(pdf.doubleSidedPrinting(), true);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::duplex()
+ //QCOMPARE(native.doubleSidedPrinting(), false);
+
+ // Test set/get
+ bool expected = true;
+ native.setDoubleSidedPrinting(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected = false;
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.doubleSidedPrinting(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.doubleSidedPrinting(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.doubleSidedPrinting(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::fontEmbedding()
+{
+ // fontEmbeddingEnabled() / setFontEmbeddingEnabled() / PPK_FontEmbedding
+ // PdfFormat: Supported, default true
+ // NativeFormat, Cups: Supported, default true
+ // NativeFormat, Win: Unsupported, always false
+ // NativeFormat, Mac: Unsupported, always false
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.fontEmbeddingEnabled(), true);
+ pdf.setFontEmbeddingEnabled(false);
+ QCOMPARE(pdf.fontEmbeddingEnabled(), false);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ QCOMPARE(native.fontEmbeddingEnabled(), false);
+#else
+ QCOMPARE(native.fontEmbeddingEnabled(), true);
+#endif // Q_OS_MAC || Q_OS_WIN
+
+ // Test set/get
+ bool expected = true;
+ native.setFontEmbeddingEnabled(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected = false;
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.fontEmbeddingEnabled(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.fontEmbeddingEnabled(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.fontEmbeddingEnabled(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::fullPage()
+{
+ // fullPage() / setFullPage() / PPK_FullPage
+ // PdfFormat: Supported, default false
+ // NativeFormat, Cups: Supported, default false
+ // NativeFormat, Win: Supported, default false
+ // NativeFormat, Mac: Supported, default false
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.fullPage(), false);
+ pdf.setFullPage(true);
+ QCOMPARE(pdf.fullPage(), true);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.fullPage(), false);
+
+ // Test set/get
+ bool expected = true;
+ native.setFullPage(expected);
+ QCOMPARE(native.fullPage(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.fullPage(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.fullPage(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::orientation()
+{
+ // orientation() / setOrientation() / PPK_Orientation
+ // PdfFormat: Supported, default QPrinter::Portrait
+ // NativeFormat, Cups: Supported, default QPrinter::Portrait
+ // NativeFormat, Win: Supported, default QPrinter::Portrait
+ // NativeFormat, Mac: Supported, default QPrinter::Portrait
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.orientation(), QPrinter::Portrait);
+ pdf.setOrientation(QPrinter::Landscape);
+ QCOMPARE(pdf.orientation(), QPrinter::Landscape);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::orientation()
+ //QCOMPARE(native.orientation(), QPrinter::Portrait);
+
+ // Test set/get
+ QPrinter::Orientation expected = QPrinter::Landscape;
+ native.setOrientation(expected);
+ QCOMPARE(native.orientation(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.orientation(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.orientation(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::outputFileName()
+{
+ // outputFileName() / setOutputFileName() / PPK_OutputFileName
+ // PdfFormat: Supported, default QString()
+ // NativeFormat, Cups: Supported, default QString()
+ // NativeFormat, Win: Supported, default QString()
+ // NativeFormat, Mac: Supported, default QString()
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.outputFileName(), QString());
+ pdf.setOutputFileName(QStringLiteral("Test File"));
+ QCOMPARE(pdf.outputFileName(), QString("Test File"));
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.outputFileName(), QString());
+
+ // Test set/get
+ QString expected = QStringLiteral("Test File");
+ native.setOutputFileName(expected);
+ QCOMPARE(native.outputFileName(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.outputFileName(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.outputFileName(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::pageOrder()
+{
+ // pageOrder() / setPageOrder() / PPK_PageOrder
+ // PdfFormat: Supported, default QPrinter::FirstPageFirst
+ // NativeFormat, Cups: Supported, default QPrinter::FirstPageFirst
+ // NativeFormat, Win: Unsupported, always QPrinter::FirstPageFirst
+ // NativeFormat, Mac: Unsupported, always QPrinter::FirstPageFirst
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.pageOrder(), QPrinter::FirstPageFirst);
+ pdf.setPageOrder(QPrinter::LastPageFirst);
+ QCOMPARE(pdf.pageOrder(), QPrinter::LastPageFirst);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.pageOrder(), QPrinter::FirstPageFirst);
+
+ // Test set/get
+ QPrinter::PageOrder expected = QPrinter::LastPageFirst;
+ native.setPageOrder(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected = QPrinter::FirstPageFirst;
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.pageOrder(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.pageOrder(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.pageOrder(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::pageSize()
+{
+ // Note PPK_PaperSize == PPK_PageSize
+ // pageSize() / setPageSize() / PPK_PageSize
+ // PdfFormat: Supported, defaults to QPrinter::A4
+ // NativeFormat, Cups: Supported, defaults to printer default
+ // NativeFormat, Win: Supported, defaults to printer default
+ // NativeFormat, Mac: Supported, must be supported size, defaults to printer default
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.pageSize(), QPrinter::A4);
+ pdf.setPageSize(QPrinter::A1);
+ QCOMPARE(pdf.pageSize(), QPrinter::A1);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::paperSize()
+ //QCOMPARE(native.pageSize(), QPrinter::A4);
+
+ // Test set/get
+ QPrinter::PaperSize expected = QPrinter::A4;
+ QPrinterInfo info = QPrinterInfo::printerInfo(native.printerName());
+ foreach (QPrinter::PaperSize supported, info.supportedPaperSizes()) {
+ if (supported != QPrinter::Custom && supported != native.paperSize()) {
+ expected = supported;
+ break;
+ }
+ }
+ native.setPageSize(expected);
+ QCOMPARE(native.pageSize(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.pageSize(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.pageSize(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::paperSize()
+{
+ // PPK_PaperSize == PPK_PageSize
+ // paperSize() / setPaperSize() / PPK_PaperSize
+ // pageSize() / setPageSize() / PPK_PageSize
+ // PdfFormat: Supported, defaults to QPrinter::A4
+ // NativeFormat, Cups: Supported, defaults to printer default
+ // NativeFormat, Win: Supported, defaults to printer default
+ // NativeFormat, Mac: Supported, must be supported size, defaults to printer default
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.paperSize(), QPrinter::A4);
+ pdf.setPaperSize(QPrinter::A1);
+ QCOMPARE(pdf.paperSize(), QPrinter::A1);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::paperSize()
+ //QCOMPARE(native.paperSize(), QPrinter::A4);
+
+ // Test set/get
+ QPrinter::PaperSize expected = QPrinter::A4;
+ QPrinterInfo info = QPrinterInfo::printerInfo(native.printerName());
+ foreach (QPrinter::PaperSize supported, info.supportedPaperSizes()) {
+ if (supported != QPrinter::Custom && supported != native.paperSize()) {
+ expected = supported;
+ break;
+ }
+ }
+ native.setPaperSize(expected);
+ QCOMPARE(native.paperSize(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.paperSize(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.paperSize(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::paperSource()
+{
+ // paperSource() / setPaperSource() / PPK_PaperSource
+ // PdfFormat: Supported, defaults to QPrinter::Auto
+ // NativeFormat, Cups: Supported, defaults to QPrinter::Auto
+ // NativeFormat, Win: Supported if valid DevMode and in supportedPaperSources(), otherwise QPrinter::Auto
+ // NativeFormat, Mac: Unsupported, always QPrinter::Auto
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.paperSource(), QPrinter::Auto);
+ pdf.setPaperSource(QPrinter::Lower);
+ QCOMPARE(pdf.paperSource(), QPrinter::Lower);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::paperSource()
+ //QCOMPARE(native.paperSource(), QPrinter::Auto);
+
+ // Test set/get
+ QPrinter::PaperSource expected = QPrinter::Manual;
+#ifdef Q_OS_WIN
+ expected = QPrinter::Auto;
+ foreach (QPrinter::PaperSource supported, native.supportedPaperSources()) {
+ if (supported != QPrinter::Auto) {
+ expected = supported;
+ break;
+ }
+ }
+#endif // Q_OS_WIN
+ native.setPaperSource(expected);
+#ifdef Q_OS_MAC
+ expected = QPrinter::Auto;
+#endif // Q_OS_MAC
+ QCOMPARE(native.paperSource(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.paperSource(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.paperSource(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::printProgram()
+{
+ // printProgram() / setPrintProgram() / PPK_PrintProgram
+ // PdfFormat: Supported, default QString()
+ // NativeFormat, Cups: Supported, default QString()
+ // NativeFormat, Win: Unsupported, always QString()
+ // NativeFormat, Mac: Unsupported, always QString()
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.printProgram(), QString());
+ pdf.setPrintProgram(QStringLiteral("/usr/bin/lpr"));
+ QCOMPARE(pdf.printProgram(), QStringLiteral("/usr/bin/lpr"));
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.printProgram(), QString());
+
+ // Test set/get
+ QString expected = QStringLiteral("/usr/bin/lpr");
+ native.setPrintProgram(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected.clear();
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.printProgram(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.printProgram(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.printProgram(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::printRange()
+{
+ // printRange() / setPrintRange() / PPK_PrintRange
+ // PdfFormat: Supported, default QPrinter::AllPages
+ // NativeFormat, Cups: Supported, default QPrinter::AllPages
+ // NativeFormat, Win: Supported, default QPrinter::AllPages
+ // NativeFormat, Mac: Supported, default QPrinter::AllPages
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.printRange(), QPrinter::AllPages);
+ pdf.setPrintRange(QPrinter::CurrentPage);
+ QCOMPARE(pdf.printRange(), QPrinter::CurrentPage);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.printRange(), QPrinter::AllPages);
+
+ // Test set/get
+ QPrinter::PrintRange expected = QPrinter::PageRange;
+ native.setPrintRange(expected);
+ QCOMPARE(native.printRange(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.printRange(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.printRange(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::printerName()
+{
+ // printerName() / setPrinterName() / PPK_PrinterName
+ // PdfFormat: Supported, default QString
+ // NativeFormat, Cups: Supported, default printer
+ // NativeFormat, Win: Supported, default printer
+ // NativeFormat, Mac: Supported, default printer
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.printerName(), QString());
+ if (QPrinterInfo::availablePrinters().size() == 0) {
+ pdf.setPrinterName(QStringLiteral("Test Printer"));
+ QCOMPARE(pdf.printerName(), QString());
+ QCOMPARE(pdf.outputFormat(), QPrinter::PdfFormat);
+ } else {
+ pdf.setPrinterName(QPrinterInfo::defaultPrinter().printerName());
+ QCOMPARE(pdf.printerName(), QPrinterInfo::defaultPrinter().printerName());
+ QCOMPARE(pdf.outputFormat(), QPrinter::NativeFormat);
+ }
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.printerName(), QPrinterInfo::defaultPrinter().printerName());
+
+ // Test set/get
+ QString expected = QPrinterInfo::defaultPrinter().printerName();
+ foreach (const QPrinterInfo &available, QPrinterInfo::availablePrinters()) {
+ if (available.printerName() != expected) {
+ expected = available.printerName();
+ break;
+ }
+ }
+ native.setPrinterName(expected);
+ QCOMPARE(native.printerName(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.printerName(), QString());
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.printerName(), QPrinterInfo::defaultPrinter().printerName());
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::printerSelectionOption()
+{
+ // printerSelectionOption() / setPrinterSelectionOption() / PPK_SelectionOption
+ // PdfFormat: Supported
+ // NativeFormat, Cups: Supported
+ // NativeFormat, Win: Unsupported, always QString()
+ // NativeFormat, Mac: Unsupported, always QString()
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdf.printerSelectionOption(), QString());
+ pdf.setPrinterSelectionOption(QStringLiteral("Optional option"));
+ QCOMPARE(pdf.printerSelectionOption(), QString("Optional option"));
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ QCOMPARE(native.printerSelectionOption(), QString());
+
+ // Test set/get
+ QString expected = QStringLiteral("Optional option");
+ native.setPrinterSelectionOption(expected);
+#if defined Q_OS_MAC || defined Q_OS_WIN
+ expected.clear();
+#endif // Q_OS_MAC || Q_OS_WIN
+ QCOMPARE(native.printerSelectionOption(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.printerSelectionOption(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.printerSelectionOption(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::resolution()
+{
+ // resolution() / setResolution() / PPK_Resolution
+ // PdfFormat: Supported, can be any number, but only 72 returned by supportedResolutions()
+ // NativeFormat, Cups: Supported, can be any number, but only 72 returned by supportedResolutions()
+ // NativeFormat, Win: Supported, can be any number, but supportedResolutions() returns valid list
+ // NativeFormat, Mac: Supported, but can only be value returned by supportedResolutions()
+
+ QPrinter pdfScreen(QPrinter::ScreenResolution);
+ pdfScreen.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdfScreen.resolution(), 96);
+ pdfScreen.setResolution(333);
+ QCOMPARE(pdfScreen.resolution(), 333);
+
+ QPrinter pdfPrinter(QPrinter::PrinterResolution);
+ pdfPrinter.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdfPrinter.resolution(), 72);
+ pdfPrinter.setResolution(333);
+ QCOMPARE(pdfPrinter.resolution(), 333);
+
+ QPrinter pdfHigh(QPrinter::HighResolution);
+ pdfHigh.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(pdfHigh.resolution(), 1200);
+ pdfHigh.setResolution(333);
+ QCOMPARE(pdfHigh.resolution(), 333);
+
+ QPrinter native(QPrinter::HighResolution);
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test default
+ // TODO Printer specific, need QPrinterInfo::resolution()
+ //QCOMPARE(native.resolution(), 300);
+
+ // Test set/get
+ int expected = 333;
+#ifdef Q_OS_MAC
+ expected = native.resolution();
+ foreach (int supported, native.supportedResolutions()) {
+ if (supported != expected) {
+ expected = supported;
+ break;
+ }
+ }
+#endif // Q_OS_MAC
+ native.setResolution(expected);
+ QCOMPARE(native.resolution(), expected);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.resolution(), expected);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.resolution(), expected);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::supportedPaperSources()
+{
+ // supportedPaperSources() / PPK_PaperSources
+ // PdfFormat: ifdef'd out TODO remove ifdef
+ // NativeFormat, Cups: ifdef'd out TODO remove ifdef
+ // NativeFormat, Win: Supported, defaults to printer default
+ // NativeFormat, Mac: ifdef'd out TODO remove ifdef
+
+#ifdef Q_OS_WIN
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ native.supportedPaperSources();
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+#endif // Q_OS_WIN
+}
+
+void tst_QPrinter::supportedResolutions()
+{
+ // supportedResolutions() / PPK_SupportedResolutions
+ // PdfFormat: Supported, only returns 72
+ // NativeFormat, Cups: Supported, only returns 72
+ // NativeFormat, Win: Supported, defaults to printer list
+ // NativeFormat, Mac: Supported, defaults to printer list
+
+ QList<int> expected;
+
+ QPrinter pdf;
+ pdf.setOutputFormat(QPrinter::PdfFormat);
+ expected << 72;
+ QCOMPARE(pdf.supportedResolutions(), expected);
+
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ native.supportedResolutions();
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+}
+
+void tst_QPrinter::windowsPageSize()
+{
+ // winPageSize() / setWinPageSize() / PPK_WindowsPageSize
+ // PdfFormat: ifdef'd out TODO remove ifdef
+ // NativeFormat, Cups: ifdef'd out TODO remove ifdef
+ // NativeFormat, Win: Supported, defaults to printer default
+ // NativeFormat, Mac: ifdef'd out TODO remove ifdef
+
+#ifdef Q_OS_WIN
+ QPrinter native;
+ if (native.outputFormat() == QPrinter::NativeFormat) {
+ // Test set/get
+ native.setPaperSize(QPrinter::A4);
+ QCOMPARE(native.pageSize(), QPrinter::A4);
+ QCOMPARE(native.winPageSize(), DMPAPER_A4);
+
+ native.setPaperSize(QPrinter::Letter);
+ QCOMPARE(native.pageSize(), QPrinter::Letter);
+ QCOMPARE(native.winPageSize(), DMPAPER_LETTER);
+
+ native.setWinPageSize(DMPAPER_A4);
+ QCOMPARE(native.pageSize(), QPrinter::A4);
+ QCOMPARE(native.winPageSize(), DMPAPER_A4);
+
+ native.setWinPageSize(DMPAPER_LETTER);
+ QCOMPARE(native.pageSize(), QPrinter::Letter);
+ QCOMPARE(native.winPageSize(), DMPAPER_LETTER);
+
+ // Test value preservation
+ native.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(native.pageSize(), QPrinter::Letter);
+ QEXPECT_FAIL("", "Win paper size doesn't persist over format change", Continue);
+ QCOMPARE(native.winPageSize(), DMPAPER_LETTER);
+ native.setOutputFormat(QPrinter::NativeFormat);
+ QCOMPARE(native.pageSize(), QPrinter::Letter);
+ QCOMPARE(native.winPageSize(), DMPAPER_LETTER);
+ } else {
+ QSKIP("No printers installed, cannot test NativeFormat, please install printers to test");
+ }
+#endif // Q_OS_WIN
+}
+
+// Test QPrinter setters/getters for non-QPrintEngine options
+
+void tst_QPrinter::outputFormat()
+{
+ QPrinter printer;
+ if (QPrinterInfo::availablePrinters().size() == 0) {
+ QCOMPARE(printer.outputFormat(), QPrinter::PdfFormat);
+ QCOMPARE(printer.printerName(), QString());
+ } else {
+ QCOMPARE(printer.outputFormat(), QPrinter::NativeFormat);
+ QCOMPARE(printer.printerName(), QPrinterInfo::defaultPrinter().printerName());
+ }
+
+ printer.setOutputFormat(QPrinter::PdfFormat);
+ QCOMPARE(printer.outputFormat(), QPrinter::PdfFormat);
+ QCOMPARE(printer.printerName(), QString());
+}
+
+void tst_QPrinter::fromToPage()
+{
+ QPrinter printer;
+ QCOMPARE(printer.fromPage(), 0);
+ QCOMPARE(printer.toPage(), 0);
+ printer.setFromTo(3, 7);
+ QCOMPARE(printer.fromPage(), 3);
+ QCOMPARE(printer.toPage(), 7);
+}
+
#endif // QT_NO_PRINTER
QTEST_MAIN(tst_QPrinter)
diff --git a/tests/auto/printsupport/printsupport.pro b/tests/auto/printsupport/printsupport.pro
index 69ba296738..062f46980a 100644
--- a/tests/auto/printsupport/printsupport.pro
+++ b/tests/auto/printsupport/printsupport.pro
@@ -1,3 +1,4 @@
TEMPLATE=subdirs
SUBDIRS=\
+ dialogs \
kernel \
diff --git a/tests/auto/shared/platformclipboard.h b/tests/auto/shared/platformclipboard.h
index a430beef93..455ad9b276 100644
--- a/tests/auto/shared/platformclipboard.h
+++ b/tests/auto/shared/platformclipboard.h
@@ -44,7 +44,7 @@
#include <qglobal.h>
-#ifdef Q_OS_MAC
+#ifdef Q_OS_OSX
#include <Carbon/Carbon.h>
#endif
@@ -54,7 +54,7 @@ struct PlatformClipboard
{
#if defined(QT_NO_CLIPBOARD)
return false;
-#elif defined(Q_OS_MAC)
+#elif defined(Q_OS_OSX)
PasteboardRef pasteboard;
OSStatus status = PasteboardCreate(0, &pasteboard);
if (status == noErr)
diff --git a/tests/auto/sql/kernel/qsql/qsql.pro b/tests/auto/sql/kernel/qsql/qsql.pro
index 20cee413b2..6bef8d4601 100644
--- a/tests/auto/sql/kernel/qsql/qsql.pro
+++ b/tests/auto/sql/kernel/qsql/qsql.pro
@@ -8,5 +8,5 @@ QT = core-private sql-private testlib
wince*: {
DEPLOYMENT_PLUGIN += qsqlite
}
-win32-g++*: LIBS += -lws2_32
+mingw: LIBS += -lws2_32
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
index c0b558312f..5c8b3ef728 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
@@ -55,11 +55,14 @@
#include <QtSql/private/qsqldriver_p.h>
#include <QtTest/QtTest>
-#if defined (Q_OS_WIN) || defined (Q_OS_WIN32)
+#if defined(Q_OS_WIN)
# include <qt_windows.h>
-# if defined (Q_OS_WINCE)
+# if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
# include <winsock2.h>
# endif
+# if defined(Q_OS_WINRT) && !defined(Q_OS_WINPHONE)
+static inline int gethostname(char *name, int len) { qstrcpy(name, "localhost"); return 9; }
+# endif
#else
#include <unistd.h>
#endif
@@ -512,8 +515,8 @@ public:
static QByteArray printError( const QSqlError& err )
{
QString result;
- if(err.number() > 0)
- result += '(' + QString::number(err.number()) + ") ";
+ if (!err.nativeErrorCode().isEmpty())
+ result += '(' + err.nativeErrorCode() + ") ";
result += '\'';
if(!err.driverText().isEmpty())
result += err.driverText() + "' || '";
@@ -524,8 +527,8 @@ public:
static QByteArray printError( const QSqlError& err, const QSqlDatabase& db )
{
QString result(dbToString(db) + ": ");
- if(err.number() > 0)
- result += '(' + QString::number(err.number()) + ") ";
+ if (!err.nativeErrorCode().isEmpty())
+ result += '(' + err.nativeErrorCode() + ") ";
result += '\'';
if(!err.driverText().isEmpty())
result += err.driverText() + "' || '";
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
index 91ed7360c3..6e199d5a71 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
@@ -668,7 +668,7 @@ void tst_QSqlDatabase::testRecord(const FieldDef fieldDefs[], const QSqlRecord&
}
QVERIFY(!inf.field(i+1).isAutoValue());
-// qDebug(QString(" field: %1 type: %2 variant type: %3").arg(fieldDefs[ i ].fieldName()).arg(QVariant::typeToName(inf.field(i+1)->type())).arg(QVariant::typeToName(inf.field(i+1)->value().type())));
+// qDebug(QString(" field: %1 type: %2 variant type: %3").arg(fieldDefs[ i ].fieldName()).arg(QVariant::typeToName(inf.field(i+1)->type())).arg(QVariant::typeToName(inf.field(i+1)->value().type())));
}
}
@@ -692,28 +692,28 @@ void tst_QSqlDatabase::recordTDS()
CHECK_DATABASE(db);
static const FieldDef fieldDefs[] = {
- FieldDef("tinyint", QVariant::Int, 255),
- FieldDef("smallint", QVariant::Int, 32767),
- FieldDef("int", QVariant::Int, 2147483647),
- FieldDef("numeric(10,9)", QVariant::Double, 1.23456789),
- FieldDef("decimal(10,9)", QVariant::Double, 1.23456789),
- FieldDef("float(4)", QVariant::Double, 1.23456789),
- FieldDef("double precision", QVariant::Double, 1.23456789),
- FieldDef("real", QVariant::Double, 1.23456789),
- FieldDef("smallmoney", QVariant::Double, 100.42),
- FieldDef("money", QVariant::Double, 200.42),
- // accuracy is that of a minute
- FieldDef("smalldatetime", QVariant::DateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 0, 0))),
- // accuracy is that of a second
- FieldDef("datetime", QVariant::DateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 3, 0))),
- FieldDef("char(20)", QVariant::String, "blah1"),
- FieldDef("varchar(20)", QVariant::String, "blah2"),
- FieldDef("nchar(20)", QVariant::String, "blah3"),
- FieldDef("nvarchar(20)", QVariant::String, "blah4"),
- FieldDef("text", QVariant::String, "blah5"),
- FieldDef("bit", QVariant::Int, 1, false),
+ FieldDef("tinyint", QVariant::Int, 255),
+ FieldDef("smallint", QVariant::Int, 32767),
+ FieldDef("int", QVariant::Int, 2147483647),
+ FieldDef("numeric(10,9)", QVariant::Double, 1.23456789),
+ FieldDef("decimal(10,9)", QVariant::Double, 1.23456789),
+ FieldDef("float(4)", QVariant::Double, 1.23456789),
+ FieldDef("double precision", QVariant::Double, 1.23456789),
+ FieldDef("real", QVariant::Double, 1.23456789),
+ FieldDef("smallmoney", QVariant::Double, 100.42),
+ FieldDef("money", QVariant::Double, 200.42),
+ // accuracy is that of a minute
+ FieldDef("smalldatetime", QVariant::DateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 0, 0))),
+ // accuracy is that of a second
+ FieldDef("datetime", QVariant::DateTime, QDateTime(QDate::currentDate(), QTime(1, 2, 3, 0))),
+ FieldDef("char(20)", QVariant::String, "blah1"),
+ FieldDef("varchar(20)", QVariant::String, "blah2"),
+ FieldDef("nchar(20)", QVariant::String, "blah3"),
+ FieldDef("nvarchar(20)", QVariant::String, "blah4"),
+ FieldDef("text", QVariant::String, "blah5"),
+ FieldDef("bit", QVariant::Int, 1, false),
- FieldDef()
+ FieldDef()
};
const int fieldCount = createFieldTable(fieldDefs, db);
@@ -800,40 +800,40 @@ void tst_QSqlDatabase::recordPSQL()
if (db.driver()->hasFeature(QSqlDriver::BLOB))
byteadef = FieldDef("bytea", QVariant::ByteArray, QByteArray("bl\\ah"));
static FieldDef fieldDefs[] = {
- FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
- FieldDef("bigserial", QVariant::LongLong, 100, false),
- FieldDef("bit", QVariant::String, "1"), // a bit in postgres is a bit-string
- FieldDef("box", QVariant::String, "(5,6),(1,2)"),
- FieldDef("char(20)", QVariant::String, "blah5678901234567890"),
- FieldDef("varchar(20)", QVariant::String, "blah5678901234567890"),
- FieldDef("cidr", QVariant::String, "12.123.0.0/24"),
- FieldDef("circle", QVariant::String, "<(1,2),3>"),
- FieldDef("date", QVariant::Date, QDate::currentDate()),
- FieldDef("float8", QVariant::Double, 1.12345678912),
- FieldDef("inet", QVariant::String, "12.123.12.23"),
- FieldDef("integer", QVariant::Int, 2147483647),
- FieldDef("interval", QVariant::String, "1 day 12:59:10"),
-// LOL... you can create a "line" datatype in PostgreSQL <= 7.2.x but
-// as soon as you want to insert data you get a "not implemented yet" error
-// FieldDef("line", QVariant::Polygon, QPolygon(QRect(1, 2, 3, 4))),
- FieldDef("lseg", QVariant::String, "[(1,1),(2,2)]"),
- FieldDef("macaddr", QVariant::String, "08:00:2b:01:02:03"),
- FieldDef("money", QVariant::String, "$12.23"),
- FieldDef("numeric", QVariant::Double, 1.2345678912),
- FieldDef("path", QVariant::String, "((1,2),(3,2),(3,5),(1,5))"),
- FieldDef("point", QVariant::String, "(1,2)"),
- FieldDef("polygon", QVariant::String, "((1,2),(3,2),(3,5),(1,5))"),
- FieldDef("real", QVariant::Double, 1.1234),
- FieldDef("smallint", QVariant::Int, 32767),
- FieldDef("serial", QVariant::Int, 100, false),
- FieldDef("text", QVariant::String, "blah"),
- FieldDef("time(6)", QVariant::Time, QTime(1, 2, 3)),
- FieldDef("timetz", QVariant::Time, QTime(1, 2, 3)),
- FieldDef("timestamp(6)", QVariant::DateTime, QDateTime::currentDateTime()),
- FieldDef("timestamptz", QVariant::DateTime, QDateTime::currentDateTime()),
- byteadef,
+ FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
+ FieldDef("bigserial", QVariant::LongLong, 100, false),
+ FieldDef("bit", QVariant::String, "1"), // a bit in postgres is a bit-string
+ FieldDef("box", QVariant::String, "(5,6),(1,2)"),
+ FieldDef("char(20)", QVariant::String, "blah5678901234567890"),
+ FieldDef("varchar(20)", QVariant::String, "blah5678901234567890"),
+ FieldDef("cidr", QVariant::String, "12.123.0.0/24"),
+ FieldDef("circle", QVariant::String, "<(1,2),3>"),
+ FieldDef("date", QVariant::Date, QDate::currentDate()),
+ FieldDef("float8", QVariant::Double, 1.12345678912),
+ FieldDef("inet", QVariant::String, "12.123.12.23"),
+ FieldDef("integer", QVariant::Int, 2147483647),
+ FieldDef("interval", QVariant::String, "1 day 12:59:10"),
+// LOL... you can create a "line" datatype in PostgreSQL <= 7.2.x but
+// as soon as you want to insert data you get a "not implemented yet" error
+// FieldDef("line", QVariant::Polygon, QPolygon(QRect(1, 2, 3, 4))),
+ FieldDef("lseg", QVariant::String, "[(1,1),(2,2)]"),
+ FieldDef("macaddr", QVariant::String, "08:00:2b:01:02:03"),
+ FieldDef("money", QVariant::String, "$12.23"),
+ FieldDef("numeric", QVariant::Double, 1.2345678912),
+ FieldDef("path", QVariant::String, "((1,2),(3,2),(3,5),(1,5))"),
+ FieldDef("point", QVariant::String, "(1,2)"),
+ FieldDef("polygon", QVariant::String, "((1,2),(3,2),(3,5),(1,5))"),
+ FieldDef("real", QVariant::Double, 1.1234),
+ FieldDef("smallint", QVariant::Int, 32767),
+ FieldDef("serial", QVariant::Int, 100, false),
+ FieldDef("text", QVariant::String, "blah"),
+ FieldDef("time(6)", QVariant::Time, QTime(1, 2, 3)),
+ FieldDef("timetz", QVariant::Time, QTime(1, 2, 3)),
+ FieldDef("timestamp(6)", QVariant::DateTime, QDateTime::currentDateTime()),
+ FieldDef("timestamptz", QVariant::DateTime, QDateTime::currentDateTime()),
+ byteadef,
- FieldDef()
+ FieldDef()
};
QSqlQuery q(db);
@@ -853,17 +853,17 @@ void tst_QSqlDatabase::recordPSQL()
commonFieldTest(fieldDefs, db, fieldCount);
for (int i = 0; i < ITERATION_COUNT; ++i) {
- // increase serial values
- for (int i2 = 0; !fieldDefs[ i2 ].typeName.isNull(); ++i2) {
- if (fieldDefs[ i2 ].typeName == "serial" ||
- fieldDefs[ i2 ].typeName == "bigserial") {
-
- FieldDef def = fieldDefs[ i2 ];
- def.val = def.val.toInt() + 1;
- fieldDefs[ i2 ] = def;
+ // increase serial values
+ for (int i2 = 0; !fieldDefs[ i2 ].typeName.isNull(); ++i2) {
+ if (fieldDefs[ i2 ].typeName == "serial" ||
+ fieldDefs[ i2 ].typeName == "bigserial") {
+
+ FieldDef def = fieldDefs[ i2 ];
+ def.val = def.val.toInt() + 1;
+ fieldDefs[ i2 ] = def;
+ }
}
}
- }
}
void tst_QSqlDatabase::recordMySQL()
@@ -890,34 +890,34 @@ void tst_QSqlDatabase::recordMySQL()
static QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0));
static const FieldDef fieldDefs[] = {
- FieldDef("tinyint", QVariant::Int, 127),
- FieldDef("tinyint unsigned", QVariant::UInt, 255),
- FieldDef("smallint", QVariant::Int, 32767),
- FieldDef("smallint unsigned", QVariant::UInt, 65535),
- FieldDef("mediumint", QVariant::Int, 8388607),
- FieldDef("mediumint unsigned", QVariant::UInt, 16777215),
- FieldDef("integer", QVariant::Int, 2147483647),
- FieldDef("integer unsigned", QVariant::UInt, 4294967295u),
- FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
- FieldDef("bigint unsigned", QVariant::ULongLong, Q_UINT64_C(18446744073709551615)),
- FieldDef("float", QVariant::Double, 1.12345),
- FieldDef("double", QVariant::Double, 1.123456789),
- FieldDef("decimal(10, 9)", QVariant::Double,1.123456789),
- FieldDef("numeric(5, 2)", QVariant::Double, 123.67),
- FieldDef("date", QVariant::Date, QDate::currentDate()),
- FieldDef("datetime", QVariant::DateTime, dt),
- FieldDef("timestamp", QVariant::DateTime, dt, false),
- FieldDef("time", QVariant::Time, dt.time()),
- FieldDef("year", QVariant::Int, 2003),
- FieldDef("char(20)", QVariant::String, "Blah"),
- FieldDef("varchar(20)", QVariant::String, "BlahBlah"),
- FieldDef("tinytext", QVariant::String, QString("blah5")),
- FieldDef("text", QVariant::String, QString("blah6")),
- FieldDef("mediumtext", QVariant::String, QString("blah7")),
- FieldDef("longtext", QVariant::String, QString("blah8")),
- // SET OF?
+ FieldDef("tinyint", QVariant::Int, 127),
+ FieldDef("tinyint unsigned", QVariant::UInt, 255),
+ FieldDef("smallint", QVariant::Int, 32767),
+ FieldDef("smallint unsigned", QVariant::UInt, 65535),
+ FieldDef("mediumint", QVariant::Int, 8388607),
+ FieldDef("mediumint unsigned", QVariant::UInt, 16777215),
+ FieldDef("integer", QVariant::Int, 2147483647),
+ FieldDef("integer unsigned", QVariant::UInt, 4294967295u),
+ FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
+ FieldDef("bigint unsigned", QVariant::ULongLong, Q_UINT64_C(18446744073709551615)),
+ FieldDef("float", QVariant::Double, 1.12345),
+ FieldDef("double", QVariant::Double, 1.123456789),
+ FieldDef("decimal(10, 9)", QVariant::Double, 1.123456789),
+ FieldDef("numeric(5, 2)", QVariant::Double, 123.67),
+ FieldDef("date", QVariant::Date, QDate::currentDate()),
+ FieldDef("datetime", QVariant::DateTime, dt),
+ FieldDef("timestamp", QVariant::DateTime, dt, false),
+ FieldDef("time", QVariant::Time, dt.time()),
+ FieldDef("year", QVariant::Int, 2003),
+ FieldDef("char(20)", QVariant::String, "Blah"),
+ FieldDef("varchar(20)", QVariant::String, "BlahBlah"),
+ FieldDef("tinytext", QVariant::String, QString("blah5")),
+ FieldDef("text", QVariant::String, QString("blah6")),
+ FieldDef("mediumtext", QVariant::String, QString("blah7")),
+ FieldDef("longtext", QVariant::String, QString("blah8")),
+ // SET OF?
- FieldDef()
+ FieldDef()
};
const int fieldCount = createFieldTable(fieldDefs, db);
@@ -938,27 +938,27 @@ void tst_QSqlDatabase::recordDB2()
CHECK_DATABASE(db);
static const FieldDef fieldDefs[] = {
- FieldDef("char(20)", QVariant::String, QString("Blah1")),
- FieldDef("varchar(20)", QVariant::String, QString("Blah2")),
- FieldDef("long varchar", QVariant::String, QString("Blah3")),
- // using BOOLEAN results in "SQL0486N The BOOLEAN data type is currently only supported internally."
-//X FieldDef("boolean" , QVariant::Bool, QVariant(true, 1)),
- FieldDef("smallint", QVariant::Int, 32767),
- FieldDef("integer", QVariant::Int, 2147483647),
- FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
- FieldDef("real", QVariant::Double, 1.12345),
- FieldDef("double", QVariant::Double, 1.23456789),
- FieldDef("float", QVariant::Double, 1.23456789),
- FieldDef("decimal(10,9)", QVariant::Double, 1.234567891),
- FieldDef("numeric(10,9)", QVariant::Double, 1.234567891),
- FieldDef("date", QVariant::Date, QDate::currentDate()),
- FieldDef("time", QVariant::Time, QTime(1, 2, 3)),
- FieldDef("timestamp", QVariant::DateTime, QDateTime::currentDateTime()),
-// FieldDef("graphic(20)", QVariant::String, QString("Blah4")),
-// FieldDef("vargraphic(20)", QVariant::String, QString("Blah5")),
-// FieldDef("long vargraphic", QVariant::String, QString("Blah6")),
- //X FieldDef("datalink", QVariant::String, QString("DLVALUE('Blah10')")),
- FieldDef()
+ FieldDef("char(20)", QVariant::String, QString("Blah1")),
+ FieldDef("varchar(20)", QVariant::String, QString("Blah2")),
+ FieldDef("long varchar", QVariant::String, QString("Blah3")),
+ // using BOOLEAN results in "SQL0486N The BOOLEAN data type is currently only supported internally."
+//X FieldDef("boolean" , QVariant::Bool, QVariant(true, 1)),
+ FieldDef("smallint", QVariant::Int, 32767),
+ FieldDef("integer", QVariant::Int, 2147483647),
+ FieldDef("bigint", QVariant::LongLong, Q_INT64_C(9223372036854775807)),
+ FieldDef("real", QVariant::Double, 1.12345),
+ FieldDef("double", QVariant::Double, 1.23456789),
+ FieldDef("float", QVariant::Double, 1.23456789),
+ FieldDef("decimal(10,9)", QVariant::Double, 1.234567891),
+ FieldDef("numeric(10,9)", QVariant::Double, 1.234567891),
+ FieldDef("date", QVariant::Date, QDate::currentDate()),
+ FieldDef("time", QVariant::Time, QTime(1, 2, 3)),
+ FieldDef("timestamp", QVariant::DateTime, QDateTime::currentDateTime()),
+// FieldDef("graphic(20)", QVariant::String, QString("Blah4")),
+// FieldDef("vargraphic(20)", QVariant::String, QString("Blah5")),
+// FieldDef("long vargraphic", QVariant::String, QString("Blah6")),
+ //X FieldDef("datalink", QVariant::String, QString("DLVALUE('Blah10')")),
+ FieldDef()
};
const int fieldCount = createFieldTable(fieldDefs, db);
diff --git a/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro b/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro
index abdc157c7f..13674f7c9e 100644
--- a/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro
+++ b/tests/auto/sql/kernel/qsqldriver/qsqldriver.pro
@@ -11,7 +11,7 @@ wince*: {
DEPLOYMENT += plugFiles
LIBS += -lws2
} else {
- win32-g++* {
+ mingw {
LIBS += -lws2_32
} else:win32 {
LIBS += ws2_32.lib
diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
index bee4441c0f..9763e3e7e6 100644
--- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
+++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp
@@ -120,6 +120,24 @@ void tst_QSqlError::construction()
QSqlError obj4;
QVERIFY(!obj4.isValid());
+
+ QSqlError obj5(QStringLiteral("drivertext"), QStringLiteral("databasetext"),
+ QSqlError::UnknownError, QStringLiteral("123"));
+ QCOMPARE(obj5.driverText(), QString("drivertext"));
+ QCOMPARE(obj5.databaseText(), QString("databasetext"));
+ QCOMPARE(obj5.type(), QSqlError::UnknownError);
+ QCOMPARE(obj5.number(), 123);
+ QCOMPARE(obj5.nativeErrorCode(), QStringLiteral("123"));
+ QVERIFY(obj5.isValid());
+
+ QSqlError obj6(QStringLiteral("drivertext"), QStringLiteral("databasetext"),
+ QSqlError::UnknownError, QStringLiteral("Err123"));
+ QCOMPARE(obj6.driverText(), QString("drivertext"));
+ QCOMPARE(obj6.databaseText(), QString("databasetext"));
+ QCOMPARE(obj6.type(), QSqlError::UnknownError);
+ QCOMPARE(obj6.number(), 0);
+ QCOMPARE(obj6.nativeErrorCode(), QStringLiteral("Err123"));
+ QVERIFY(obj6.isValid());
}
void tst_QSqlError::operators()
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 1a100ce706..38f561dbaa 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -1384,7 +1384,9 @@ void tst_QSqlQuery::isNull()
QVERIFY_SQL(q, exec("select id, t_varchar from " + qTableName("qtest_null", __FILE__, db) + " order by id"));
QVERIFY( q.next() );
QVERIFY( !q.isNull( 0 ) );
+ QVERIFY(!q.isNull("id"));
QVERIFY( q.isNull( 1 ) );
+ QVERIFY(q.isNull("t_varchar"));
QCOMPARE( q.value( 0 ).toInt(), 0 );
QCOMPARE( q.value( 1 ).toString(), QString() );
QVERIFY( !q.value( 0 ).isNull() );
@@ -1392,7 +1394,13 @@ void tst_QSqlQuery::isNull()
QVERIFY( q.next() );
QVERIFY( !q.isNull( 0 ) );
+ QVERIFY(!q.isNull("id"));
QVERIFY( !q.isNull( 1 ) );
+ QVERIFY(!q.isNull("t_varchar"));
+
+ // For a non existent field, it should be returning true.
+ QVERIFY(q.isNull(2));
+ QVERIFY(q.isNull("unknown"));
}
/*! TDS specific BIT field test */
@@ -2849,7 +2857,7 @@ void tst_QSqlQuery::task_250026()
QVERIFY_SQL( q, next() );
QCOMPARE( q.value( 0 ).toString().length(), data258.length() );
QVERIFY_SQL( q, next() );
- QCOMPARE( q.value( 0 ).toString().length(), data1026.length() );
+ QCOMPARE( q.value( 0 ).toString().length(), data1026.length() );
}
void tst_QSqlQuery::task_205701()
diff --git a/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp b/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
index b251e54cca..a76ecec84d 100644
--- a/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
+++ b/tests/auto/sql/kernel/qsqlrecord/tst_qsqlrecord.cpp
@@ -114,8 +114,8 @@ void tst_QSqlRecord::cleanup()
{
delete rec;
for ( int i = 0; i < NUM_FIELDS; ++i ) {
- delete fields[ i ];
- fields[ i ] = 0;
+ delete fields[ i ];
+ fields[ i ] = 0;
}
rec = 0;
}
@@ -129,7 +129,7 @@ void tst_QSqlRecord::createTestRecord()
fields[ 2 ] = new QSqlField( "double", QVariant::Double );
fields[ 3 ] = new QSqlField( "bool", QVariant::Bool );
for ( int i = 0; i < NUM_FIELDS; ++i )
- rec->append( *(fields[ i ] ) );
+ rec->append( *(fields[ i ] ) );
}
@@ -237,7 +237,7 @@ void tst_QSqlRecord::contains()
{
createTestRecord();
for ( int i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->contains( fields[ i ]->name() ) );
+ QVERIFY( rec->contains( fields[ i ]->name() ) );
QVERIFY( !rec->contains( "__Harry__" ) );
}
@@ -258,10 +258,10 @@ void tst_QSqlRecord::field()
int i;
for ( i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->field( i ) == *fields[ i ] );
+ QVERIFY( rec->field( i ) == *fields[ i ] );
for ( i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
+ QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
QVERIFY( rec->indexOf( "_This should give a warning!_" ) == -1 );
}
@@ -270,7 +270,7 @@ void tst_QSqlRecord::fieldName()
createTestRecord();
for ( int i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
+ QVERIFY( rec->field( (fields[ i ] )->name() ) == *( fields[ i ] ) );
QVERIFY( rec->fieldName( NUM_FIELDS ).isNull() );
}
@@ -279,10 +279,10 @@ void tst_QSqlRecord::insert()
QSqlRecord iRec;
int i;
for ( i = 0; i <= 100; ++i ) {
- iRec.insert( i, QSqlField( QString::number( i ), QVariant::Int ) );
+ iRec.insert( i, QSqlField( QString::number( i ), QVariant::Int ) );
}
for ( i = 0; i <= 100; ++i ) {
- QCOMPARE( iRec.fieldName( i ), QString::number( i ) );
+ QCOMPARE( iRec.fieldName( i ), QString::number( i ) );
}
// iRec.insert( 505, QSqlField( "Harry", QVariant::Double ) );
// QCOMPARE( iRec.fieldName( 505 ), (QString)"Harry" );
@@ -313,30 +313,30 @@ void tst_QSqlRecord::isGenerated()
int i;
for ( i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->isGenerated( i ) );
+ QVERIFY( rec->isGenerated( i ) );
for ( i = 0; i < NUM_FIELDS; ++i )
- QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
+ QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
for ( i = 0; i < NUM_FIELDS; ++i ) {
- if ( i % 2 )
- rec->setGenerated( i, false );
+ if ( i % 2 )
+ rec->setGenerated( i, false );
}
rec->setGenerated( NUM_FIELDS * 2, false ); // nothing should happen here
for ( i = 0; i < NUM_FIELDS; ++i ) {
- if ( i % 2 ) {
- QVERIFY( !rec->isGenerated( i ) );
- } else {
- QVERIFY( rec->isGenerated( i ) );
+ if ( i % 2 ) {
+ QVERIFY( !rec->isGenerated( i ) );
+ } else {
+ QVERIFY( rec->isGenerated( i ) );
}
}
for ( i = 0; i < NUM_FIELDS; ++i )
- if ( i % 2 ) {
- QVERIFY( !rec->isGenerated( fields[ i ]->name() ) );
- } else {
- QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
+ if ( i % 2 ) {
+ QVERIFY( !rec->isGenerated( fields[ i ]->name() ) );
+ } else {
+ QVERIFY( rec->isGenerated( fields[ i ]->name() ) );
}
rec->setGenerated( "_This should give a warning!_", false ); // nothing should happen here
@@ -348,31 +348,31 @@ void tst_QSqlRecord::isNull()
int i;
for ( i = 0; i < NUM_FIELDS; ++i ) {
- QVERIFY( rec->isNull( i ) );
- QVERIFY( rec->isNull( fields[ i ]->name() ) );
+ QVERIFY( rec->isNull( i ) );
+ QVERIFY( rec->isNull( fields[ i ]->name() ) );
}
for ( i = 0; i < NUM_FIELDS; ++i ) {
- if ( i % 2 )
- rec->setNull( i );
+ if ( i % 2 )
+ rec->setNull( i );
}
rec->setNull( NUM_FIELDS ); // nothing should happen here
for ( i = 0; i < NUM_FIELDS; ++i ) {
- if ( i % 2 ) {
- QVERIFY( rec->isNull( i ) );
- QVERIFY( rec->isNull( fields[ i ]->name() ) );
+ if ( i % 2 ) {
+ QVERIFY( rec->isNull( i ) );
+ QVERIFY( rec->isNull( fields[ i ]->name() ) );
}
}
for ( i = 0; i < NUM_FIELDS; ++i ) {
- rec->setNull( fields[ i ]->name() );
+ rec->setNull( fields[ i ]->name() );
}
rec->setNull( "_This should give a warning!_" ); // nothing should happen here
for ( i = 0; i < NUM_FIELDS; ++i ) {
- QVERIFY( rec->isNull( i ) );
- QVERIFY( rec->isNull( fields[ i ]->name() ) );
+ QVERIFY( rec->isNull( i ) );
+ QVERIFY( rec->isNull( fields[ i ]->name() ) );
}
}
@@ -385,19 +385,19 @@ void tst_QSqlRecord::operator_Assign()
buf3 = *rec;
buf4 = *rec;
for ( i = 0; i < NUM_FIELDS; ++i ) {
- QVERIFY( buf2.field( i ) == *fields[ i ] );
- QVERIFY( buf3.field( i ) == *( fields[ i ] ) );
- QVERIFY( buf4.field( i ) == *( fields[ i ] ) );
+ QVERIFY( buf2.field( i ) == *fields[ i ] );
+ QVERIFY( buf3.field( i ) == *( fields[ i ] ) );
+ QVERIFY( buf4.field( i ) == *( fields[ i ] ) );
}
for ( i = 0; i < NUM_FIELDS; ++i )
- buf3.setNull( i );
+ buf3.setNull( i );
buf3.remove( NUM_FIELDS - 1 );
QSqlRecord buf5 = buf3;
for ( i = 0; i < NUM_FIELDS - 1; ++i ) {
- QSqlField fi ( fields[ i ]->name(), fields[ i ]->type() );
- fi.clear();
- QVERIFY( buf5.field( i ) == fi );
- QVERIFY( buf5.isGenerated( i ) );
+ QSqlField fi ( fields[ i ]->name(), fields[ i ]->type() );
+ fi.clear();
+ QVERIFY( buf5.field( i ) == fi );
+ QVERIFY( buf5.isGenerated( i ) );
}
}
@@ -406,7 +406,7 @@ void tst_QSqlRecord::position()
createTestRecord();
int i;
for ( i = 0; i < NUM_FIELDS; ++i ) {
- QCOMPARE( rec->indexOf( fields[ i ]->name() ), i );
+ QCOMPARE( rec->indexOf( fields[ i ]->name() ), i );
}
}
@@ -415,15 +415,15 @@ void tst_QSqlRecord::remove()
createTestRecord();
int i;
for ( i = 0; i < NUM_FIELDS; ++i ) {
- rec->setGenerated( i, false );
- QCOMPARE( (int)rec->count(), NUM_FIELDS - i );
- rec->remove( 0 );
- QCOMPARE( (int)rec->count(), NUM_FIELDS - i - 1 );
+ rec->setGenerated( i, false );
+ QCOMPARE( (int)rec->count(), NUM_FIELDS - i );
+ rec->remove( 0 );
+ QCOMPARE( (int)rec->count(), NUM_FIELDS - i - 1 );
}
rec->remove( NUM_FIELDS * 2 ); // nothing should happen
for ( i = 0; i < NUM_FIELDS; ++i ) {
- rec->insert( i, QSqlField( fields[ i ]->name(), fields[ i ]->type() ) );
- QVERIFY( rec->isGenerated( i ) );
+ rec->insert( i, QSqlField( fields[ i ]->name(), fields[ i ]->type() ) );
+ QVERIFY( rec->isGenerated( i ) );
}
}
@@ -472,7 +472,7 @@ void tst_QSqlRecord::setValue()
QFETCH( int, bval );
for ( i = 0; i < 4; ++i )
- rec->setNull( i );
+ rec->setNull( i );
rec->setValue( 0, sval );
rec->setValue( 1, ival );
@@ -483,7 +483,7 @@ void tst_QSqlRecord::setValue()
QVERIFY( rec->value( 2 ) == dval );
QVERIFY( rec->value( 3 ) == QVariant(bval) );
for ( i = 0; i < 4; ++i )
- QVERIFY( !rec->isNull( i ) );
+ QVERIFY( !rec->isNull( i ) );
QSqlRecord rec2 = *rec;
QVERIFY( rec2.value( 0 ) == sval );
@@ -495,7 +495,7 @@ void tst_QSqlRecord::setValue()
QVERIFY( rec2.value( 0 ) == "__Harry__" );
for ( i = 0; i < 4; ++i )
- QVERIFY( !rec2.isNull( i ) );
+ QVERIFY( !rec2.isNull( i ) );
QCOMPARE( rec->value( 0 ).toString(), sval );
QCOMPARE( rec->value( 1 ).toInt(), ival );
diff --git a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
index 114327effb..2e4c3f998d 100644
--- a/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
+++ b/tests/auto/sql/kernel/qsqlresult/qsqlresult.pro
@@ -6,5 +6,5 @@ QT = core core-private sql sql-private testlib
SOURCES += tst_qsqlresult.cpp
HEADERS += testsqldriver.h
-win32-g++*: LIBS += -lws2_32
+mingw: LIBS += -lws2_32
diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
index c5eafb37fb..fe0f6abd9d 100644
--- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
@@ -126,20 +126,20 @@ void tst_QSqlQueryModel::initTestCase()
{
dbs.open();
for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) {
- QSqlDatabase db = QSqlDatabase::database((*it));
- CHECK_DATABASE(db);
- dropTestTables(db); //in case of leftovers
- createTestTables(db);
- populateTestTables(db);
+ QSqlDatabase db = QSqlDatabase::database((*it));
+ CHECK_DATABASE(db);
+ dropTestTables(db); //in case of leftovers
+ createTestTables(db);
+ populateTestTables(db);
}
}
void tst_QSqlQueryModel::cleanupTestCase()
{
for (QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it) {
- QSqlDatabase db = QSqlDatabase::database((*it));
- CHECK_DATABASE(db);
- dropTestTables(db);
+ QSqlDatabase db = QSqlDatabase::database((*it));
+ CHECK_DATABASE(db);
+ dropTestTables(db);
}
dbs.close();
}
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro b/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro
index e0503e1600..6bcc3a1870 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro
@@ -11,7 +11,7 @@ wince*: {
DEPLOYMENT += plugFiles
LIBS += -lws2
} else {
- win32-g++* {
+ mingw {
LIBS += -lws2_32
} else:win32 {
LIBS += ws2_32.lib
diff --git a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
index 1ccbdd7899..3f2385bb30 100644
--- a/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
+++ b/tests/auto/testlib/selftests/badxml/tst_badxml.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
#include <QtTest/QtTest>
#include <private/qmetaobjectbuilder_p.h>
@@ -61,6 +62,8 @@ private slots:
void failWithNoFile() const;
+ void encoding();
+
public:
static QList<QByteArray> const& badStrings();
};
@@ -126,6 +129,24 @@ void tst_BadXml::failWithNoFile() const
QTest::qFail("failure message", 0, 0);
}
+// QTBUG-35743, test whether XML is using correct UTF-8 encoding
+// on platforms where the console encoding differs.
+void tst_BadXml::encoding()
+{
+ QStringList arguments = QCoreApplication::arguments();
+ arguments.pop_front(); // Prevent match on binary "badxml"
+ if (arguments.filter(QStringLiteral("xml")).isEmpty())
+ QSKIP("Skipped for text due to unpredictable console encoding.");
+ QString string;
+ string += QChar(ushort(0xDC)); // German umlaut Ue
+ string += QStringLiteral("lrich ");
+ string += QChar(ushort(0xDC)); // German umlaut Ue
+ string += QStringLiteral("ml");
+ string += QChar(ushort(0xE4)); // German umlaut ae
+ string += QStringLiteral("ut");
+ qDebug() << string;
+}
+
/*
Outputs a message containing a bad string.
*/
diff --git a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp
index 067c2a9f4f..3b73d87876 100644
--- a/tests/auto/testlib/selftests/crashes/tst_crashes.cpp
+++ b/tests/auto/testlib/selftests/crashes/tst_crashes.cpp
@@ -57,7 +57,7 @@ private slots:
void tst_Crashes::crash()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
//we avoid the error dialogbox to appear on windows
SetErrorMode( SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#endif
diff --git a/tests/auto/testlib/selftests/expected_assert.lightxml b/tests/auto/testlib/selftests/expected_assert.lightxml
index c2cc1da7ab..d2d4ae5153 100644
--- a/tests/auto/testlib/selftests/expected_assert.lightxml
+++ b/tests/auto/testlib/selftests/expected_assert.lightxml
@@ -4,9 +4,11 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testNumber1">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testNumber2">
<Message type="qfatal" file="" line="0">
@@ -15,4 +17,6 @@
<Incident type="fail" file="Unknown file" line="0">
<Description><![CDATA[Received a fatal error.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_assert.xml b/tests/auto/testlib/selftests/expected_assert.xml
index 8dc20628af..9e5ea760ae 100644
--- a/tests/auto/testlib/selftests/expected_assert.xml
+++ b/tests/auto/testlib/selftests/expected_assert.xml
@@ -6,9 +6,11 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testNumber1">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testNumber2">
<Message type="qfatal" file="" line="0">
@@ -17,5 +19,7 @@
<Incident type="fail" file="Unknown file" line="0">
<Description><![CDATA[Received a fatal error.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_badxml.lightxml b/tests/auto/testlib/selftests/expected_badxml.lightxml
index 08ba497efa..e4c79e3bb0 100644
--- a/tests/auto/testlib/selftests/expected_badxml.lightxml
+++ b/tests/auto/testlib/selftests/expected_badxml.lightxml
@@ -4,13 +4,14 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="badDataTag">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail end cdata ]]]><![CDATA[]> text ]]]><![CDATA[]> more text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail end cdata ]]]><![CDATA[]> text ]]]><![CDATA[]> more text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -26,7 +27,7 @@
<DataTag><![CDATA[fail quotes " text" more text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail quotes " text" more text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -42,7 +43,7 @@
<DataTag><![CDATA[fail xml close > open < tags < text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail xml close > open < tags < text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -58,7 +59,7 @@
<DataTag><![CDATA[fail all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -70,6 +71,7 @@
<DataTag><![CDATA[pass all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
</Incident>
<BenchmarkResult metric="Events" tag="pass all &gt; &quot; mixed ]]&gt; up &gt; &quot; in &lt; the ]]&gt; hopes &lt; of triggering &quot;&lt; ]]&gt; bugs" value="0" iterations="1" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="badMessage">
<Message type="qdebug" file="" line="0">
@@ -100,12 +102,23 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[string 3]]></DataTag>
</Incident>
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="failWithNoFile">
<Incident type="fail" file="" line="0">
<Description><![CDATA[failure message]]></Description>
</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="encoding">
+<Message type="qdebug" file="" line="0">
+ <Description><![CDATA["Ülrich Ümläut"]]></Description>
+</Message>
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_badxml.txt b/tests/auto/testlib/selftests/expected_badxml.txt
index 0458401b44..a42013df0b 100644
--- a/tests/auto/testlib/selftests/expected_badxml.txt
+++ b/tests/auto/testlib/selftests/expected_badxml.txt
@@ -3,28 +3,28 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_BadXml::initTestCase()
QDEBUG : tst_BadXml::badDataTag(fail end cdata ]]> text ]]> more text) a message
FAIL! : tst_BadXml::badDataTag(fail end cdata ]]> text ]]> more text) a failure
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)]
+ Loc: [tst_badxml.cpp(114)]
QDEBUG : tst_BadXml::badDataTag(pass end cdata ]]> text ]]> more text) a message
PASS : tst_BadXml::badDataTag(pass end cdata ]]> text ]]> more text)
RESULT : tst_BadXml::badDataTag():"pass end cdata ]]> text ]]> more text":
0 events per iteration (total: 0, iterations: 1)
QDEBUG : tst_BadXml::badDataTag(fail quotes " text" more text) a message
FAIL! : tst_BadXml::badDataTag(fail quotes " text" more text) a failure
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)]
+ Loc: [tst_badxml.cpp(114)]
QDEBUG : tst_BadXml::badDataTag(pass quotes " text" more text) a message
PASS : tst_BadXml::badDataTag(pass quotes " text" more text)
RESULT : tst_BadXml::badDataTag():"pass quotes " text" more text":
0 events per iteration (total: 0, iterations: 1)
QDEBUG : tst_BadXml::badDataTag(fail xml close > open < tags < text) a message
FAIL! : tst_BadXml::badDataTag(fail xml close > open < tags < text) a failure
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)]
+ Loc: [tst_badxml.cpp(114)]
QDEBUG : tst_BadXml::badDataTag(pass xml close > open < tags < text) a message
PASS : tst_BadXml::badDataTag(pass xml close > open < tags < text)
RESULT : tst_BadXml::badDataTag():"pass xml close > open < tags < text":
0 events per iteration (total: 0, iterations: 1)
QDEBUG : tst_BadXml::badDataTag(fail all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a message
FAIL! : tst_BadXml::badDataTag(fail all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a failure
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp(111)]
+ Loc: [tst_badxml.cpp(114)]
QDEBUG : tst_BadXml::badDataTag(pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs) a message
PASS : tst_BadXml::badDataTag(pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs)
RESULT : tst_BadXml::badDataTag():"pass all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs":
@@ -38,6 +38,8 @@ PASS : tst_BadXml::badMessage(string 2)
QDEBUG : tst_BadXml::badMessage(string 3) all > " mixed ]]> up > " in < the ]]> hopes < of triggering "< ]]> bugs
PASS : tst_BadXml::badMessage(string 3)
FAIL! : tst_BadXml::failWithNoFile() failure message
+SKIP : tst_BadXml::encoding() Skipped for text due to unpredictable console encoding.
+ Loc: [tst_badxml.cpp(139)]
PASS : tst_BadXml::cleanupTestCase()
-Totals: 10 passed, 5 failed, 0 skipped
+Totals: 10 passed, 5 failed, 1 skipped
********* Finished testing of tst_BadXml *********
diff --git a/tests/auto/testlib/selftests/expected_badxml.xml b/tests/auto/testlib/selftests/expected_badxml.xml
index 97e917602e..0811db0f3a 100644
--- a/tests/auto/testlib/selftests/expected_badxml.xml
+++ b/tests/auto/testlib/selftests/expected_badxml.xml
@@ -6,13 +6,14 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="badDataTag">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail end cdata ]]]><![CDATA[]> text ]]]><![CDATA[]> more text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail end cdata ]]]><![CDATA[]> text ]]]><![CDATA[]> more text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -28,7 +29,7 @@
<DataTag><![CDATA[fail quotes " text" more text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail quotes " text" more text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -44,7 +45,7 @@
<DataTag><![CDATA[fail xml close > open < tags < text]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail xml close > open < tags < text]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -60,7 +61,7 @@
<DataTag><![CDATA[fail all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
<Description><![CDATA[a message]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/badxml/tst_badxml.cpp" line="111">
+<Incident type="fail" file="tst_badxml.cpp" line="114">
<DataTag><![CDATA[fail all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
<Description><![CDATA[a failure]]></Description>
</Incident>
@@ -72,6 +73,7 @@
<DataTag><![CDATA[pass all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]></DataTag>
</Incident>
<BenchmarkResult metric="Events" tag="pass all &gt; &quot; mixed ]]&gt; up &gt; &quot; in &lt; the ]]&gt; hopes &lt; of triggering &quot;&lt; ]]&gt; bugs" value="0" iterations="1" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="badMessage">
<Message type="qdebug" file="" line="0">
@@ -102,13 +104,24 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[string 3]]></DataTag>
</Incident>
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="failWithNoFile">
<Incident type="fail" file="" line="0">
<Description><![CDATA[failure message]]></Description>
</Incident>
+ <Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="encoding">
+<Message type="qdebug" file="" line="0">
+ <Description><![CDATA["Ülrich Ümläut"]]></Description>
+</Message>
+<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+ <Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_badxml.xunitxml b/tests/auto/testlib/selftests/expected_badxml.xunitxml
index 939e887a88..a696da58c9 100644
--- a/tests/auto/testlib/selftests/expected_badxml.xunitxml
+++ b/tests/auto/testlib/selftests/expected_badxml.xunitxml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<testsuite errors="12" failures="5" tests="5" name="tst_BadXml">
+<testsuite errors="13" failures="5" tests="6" name="tst_BadXml">
<properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@@ -28,6 +28,9 @@
<testcase result="fail" name="failWithNoFile">
<failure message="failure message" result="fail"/>
</testcase>
+ <testcase result="pass" name="encoding">
+ <!-- message="&quot;Ülrich Ümläut&quot;" type="qdebug" -->
+ </testcase>
<testcase result="pass" name="cleanupTestCase"/>
<system-err>
<![CDATA[a message]]>
@@ -42,5 +45,6 @@
<![CDATA[quotes " text" more text]]>
<![CDATA[xml close > open < tags < text]]>
<![CDATA[all > " mixed ]]]><![CDATA[]> up > " in < the ]]]><![CDATA[]> hopes < of triggering "< ]]]><![CDATA[]> bugs]]>
+<![CDATA["Ülrich Ümläut"]]>
</system-err>
</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_benchlibcallgrind.csv b/tests/auto/testlib/selftests/expected_benchlibcallgrind.csv
new file mode 100644
index 0000000000..6ce2e2ced8
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibcallgrind.csv
@@ -0,0 +1 @@
+"twoHundredMillionInstructions","","InstructionReads",200000158,200000158,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.csv b/tests/auto/testlib/selftests/expected_benchlibcounting.csv
new file mode 100644
index 0000000000..f3368b6854
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibcounting.csv
@@ -0,0 +1 @@
+"passingBenchmark","","Events",0,0,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml b/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml
index 5c436a53e0..08872be733 100644
--- a/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml
+++ b/tests/auto/testlib/selftests/expected_benchlibcounting.lightxml
@@ -4,21 +4,27 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="passingBenchmark">
<Incident type="pass" file="" line="0" />
<BenchmarkResult metric="Events" tag="" value="0" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skippingBenchmark">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp" line="64">
+<Message type="skip" file="tst_benchlibcounting.cpp" line="64">
<Description><![CDATA[This is a skipping benchmark]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failingBenchmark">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp" line="71">
+<Incident type="fail" file="tst_benchlibcounting.cpp" line="71">
<Description><![CDATA[This is a failing benchmark]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.txt b/tests/auto/testlib/selftests/expected_benchlibcounting.txt
index 23dd19d2cd..8be8206afc 100644
--- a/tests/auto/testlib/selftests/expected_benchlibcounting.txt
+++ b/tests/auto/testlib/selftests/expected_benchlibcounting.txt
@@ -5,9 +5,9 @@ PASS : tst_BenchlibCounting::passingBenchmark()
RESULT : tst_BenchlibCounting::passingBenchmark():
0 events per iteration (total: 0, iterations: 1)
SKIP : tst_BenchlibCounting::skippingBenchmark() This is a skipping benchmark
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp(64)]
+ Loc: [tst_benchlibcounting.cpp(64)]
FAIL! : tst_BenchlibCounting::failingBenchmark() This is a failing benchmark
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp(71)]
+ Loc: [tst_benchlibcounting.cpp(71)]
PASS : tst_BenchlibCounting::cleanupTestCase()
Totals: 3 passed, 1 failed, 1 skipped
********* Finished testing of tst_BenchlibCounting *********
diff --git a/tests/auto/testlib/selftests/expected_benchlibcounting.xml b/tests/auto/testlib/selftests/expected_benchlibcounting.xml
index 1e0f4531e2..ee6fd98ef2 100644
--- a/tests/auto/testlib/selftests/expected_benchlibcounting.xml
+++ b/tests/auto/testlib/selftests/expected_benchlibcounting.xml
@@ -6,22 +6,28 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="passingBenchmark">
<Incident type="pass" file="" line="0" />
<BenchmarkResult metric="Events" tag="" value="0" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skippingBenchmark">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp" line="64">
+<Message type="skip" file="tst_benchlibcounting.cpp" line="64">
<Description><![CDATA[This is a skipping benchmark]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failingBenchmark">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/benchlibcounting/tst_benchlibcounting.cpp" line="71">
+<Incident type="fail" file="tst_benchlibcounting.cpp" line="71">
<Description><![CDATA[This is a failing benchmark]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.csv b/tests/auto/testlib/selftests/expected_benchlibeventcounter.csv
new file mode 100644
index 0000000000..2627687289
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.csv
@@ -0,0 +1,7 @@
+"events","0","Events",0,0,1
+"events","1","Events",1,1,1
+"events","10","Events",10,10,1
+"events","100","Events",100,100,1
+"events","500","Events",500,500,1
+"events","5000","Events",5000,5000,1
+"events","100000","Events",100000,100000,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml b/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml
index 3cb59d209b..cba91a374f 100644
--- a/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml
+++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="events">
<Incident type="pass" file="" line="0">
@@ -34,7 +35,10 @@
<DataTag><![CDATA[100000]]></DataTag>
</Incident>
<BenchmarkResult metric="Events" tag="100000" value="100000" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml b/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml
index cead0adf8c..7d28975ead 100644
--- a/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml
+++ b/tests/auto/testlib/selftests/expected_benchlibeventcounter.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="events">
<Incident type="pass" file="" line="0">
@@ -36,8 +37,11 @@
<DataTag><![CDATA[100000]]></DataTag>
</Incident>
<BenchmarkResult metric="Events" tag="100000" value="100000" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_benchliboptions.csv b/tests/auto/testlib/selftests/expected_benchliboptions.csv
new file mode 100644
index 0000000000..9b899aed90
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchliboptions.csv
@@ -0,0 +1,3 @@
+"threeEvents","","Events",3,3,1
+"threeEvents","","Events",3,45,15
+"threeEvents","","Events",3,3,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibtickcounter.csv b/tests/auto/testlib/selftests/expected_benchlibtickcounter.csv
new file mode 100644
index 0000000000..fe5af1e7c8
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibtickcounter.csv
@@ -0,0 +1 @@
+"threeBillionTicks","","CPUTicks",3000000000,3000000000,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibtickcounter.lightxml b/tests/auto/testlib/selftests/expected_benchlibtickcounter.lightxml
index 845fd9c161..97422240d9 100644
--- a/tests/auto/testlib/selftests/expected_benchlibtickcounter.lightxml
+++ b/tests/auto/testlib/selftests/expected_benchlibtickcounter.lightxml
@@ -4,12 +4,15 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="threeBillionTicks">
-<Incident type="pass" file="" line="0">
-<BenchmarkResult metric="walltime" tag="" value="1059" iterations="1" />
-</Incident>
+<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="CPUTicks" tag="" value="3.00001e+09" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_benchlibtickcounter.txt b/tests/auto/testlib/selftests/expected_benchlibtickcounter.txt
index 9519e1d340..ee2f0f28c4 100644
--- a/tests/auto/testlib/selftests/expected_benchlibtickcounter.txt
+++ b/tests/auto/testlib/selftests/expected_benchlibtickcounter.txt
@@ -1,9 +1,9 @@
********* Start testing of tst_BenchlibTickCounter *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_BenchlibTickCounter::initTestCase()
-RESULT : tst_BenchlibTickCounter::threeBillionTicks():
- 3,000,000,000 ticks per iteration (total: 3000000000, iterations: 1)
PASS : tst_BenchlibTickCounter::threeBillionTicks()
+RESULT : tst_BenchlibTickCounter::threeBillionTicks():
+ 3,000,005,772 CPU ticks per iteration (total: 3,000,005,772, iterations: 1)
PASS : tst_BenchlibTickCounter::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of tst_BenchlibTickCounter *********
diff --git a/tests/auto/testlib/selftests/expected_benchlibtickcounter.xml b/tests/auto/testlib/selftests/expected_benchlibtickcounter.xml
index 8c9d823485..24c2e51084 100644
--- a/tests/auto/testlib/selftests/expected_benchlibtickcounter.xml
+++ b/tests/auto/testlib/selftests/expected_benchlibtickcounter.xml
@@ -6,12 +6,16 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="threeBillionTicks">
-<BenchmarkResult metric="walltime" tag="" value="1059" iterations="1" />
<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="CPUTicks" tag="" value="3.00002e+09" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_benchlibwalltime.csv b/tests/auto/testlib/selftests/expected_benchlibwalltime.csv
new file mode 100644
index 0000000000..0dc2dee876
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_benchlibwalltime.csv
@@ -0,0 +1,3 @@
+"waitForOneThousand","","WalltimeMilliseconds",1000,1000,1
+"waitForFourThousand","","WalltimeMilliseconds",4000,4000,1
+"qbenchmark_once","","WalltimeMilliseconds",0,0,1
diff --git a/tests/auto/testlib/selftests/expected_benchlibwalltime.lightxml b/tests/auto/testlib/selftests/expected_benchlibwalltime.lightxml
index f1d89328ef..b2e819b26d 100644
--- a/tests/auto/testlib/selftests/expected_benchlibwalltime.lightxml
+++ b/tests/auto/testlib/selftests/expected_benchlibwalltime.lightxml
@@ -3,23 +3,26 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<ncident type="pass" file="" line="0" />
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="waitForOneThousand">
-<Incident type="pass" file="" line="0">
-<BenchmarkResult metric="walltime" tag="" value="1004" iterations="1" />
-</Incident>
+<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="1004" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="waitForFourThousand">
-<Incident type="pass" file="" line="0">
-<BenchmarkResult metric="walltime" tag="" value="4007" iterations="1" />
-</Incident>
+<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="4004" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="qbenchmark_once">
-<Incident type="pass" file="" line="0">
-<BenchmarkResult metric="walltime" tag="" value="0" iterations="1" />
-</Incident>
+<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="0" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_benchlibwalltime.txt b/tests/auto/testlib/selftests/expected_benchlibwalltime.txt
index b0e78ae78d..f1e353703b 100644
--- a/tests/auto/testlib/selftests/expected_benchlibwalltime.txt
+++ b/tests/auto/testlib/selftests/expected_benchlibwalltime.txt
@@ -1,15 +1,15 @@
********* Start testing of tst_BenchlibWalltime *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_BenchlibWalltime::initTestCase()
-RESULT : tst_BenchlibWalltime::waitForOneThousand():
- 1,000 msec per iteration (total: 1000, iterations: 1)
PASS : tst_BenchlibWalltime::waitForOneThousand()
-RESULT : tst_BenchlibWalltime::waitForFourThousand():
- 4,000 msec per iteration (total: 4000, iterations: 1)
+RESULT : tst_BenchlibWalltime::waitForOneThousand():
+ 1,006 msecs per iteration (total: 1,006, iterations: 1)
PASS : tst_BenchlibWalltime::waitForFourThousand()
-RESULT : tst_BenchlibWalltime::qbenchmark_once():
- 0 msec per iteration (total: 0, iterations: 1)
+RESULT : tst_BenchlibWalltime::waitForFourThousand():
+ 4,008 msecs per iteration (total: 4,008, iterations: 1)
PASS : tst_BenchlibWalltime::qbenchmark_once()
+RESULT : tst_BenchlibWalltime::qbenchmark_once():
+ 0 msecs per iteration (total: 0, iterations: 1)
PASS : tst_BenchlibWalltime::cleanupTestCase()
Totals: 5 passed, 0 failed, 0 skipped
********* Finished testing of tst_BenchlibWalltime *********
diff --git a/tests/auto/testlib/selftests/expected_benchlibwalltime.xml b/tests/auto/testlib/selftests/expected_benchlibwalltime.xml
index 69d025b9cf..6ae355783a 100644
--- a/tests/auto/testlib/selftests/expected_benchlibwalltime.xml
+++ b/tests/auto/testlib/selftests/expected_benchlibwalltime.xml
@@ -6,20 +6,26 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="waitForOneThousand">
-<BenchmarkResult metric="walltime" tag="" value="1005" iterations="1" />
<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="1008" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="waitForFourThousand">
-<BenchmarkResult metric="walltime" tag="" value="4008" iterations="1" />
<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="4002" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="qbenchmark_once">
-<BenchmarkResult metric="walltime" tag="" value="0" iterations="1" />
<Incident type="pass" file="" line="0" />
+<BenchmarkResult metric="WalltimeMilliseconds" tag="" value="0" iterations="1" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml
index 99e2e825c0..3a776ea7cb 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.lightxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml
@@ -4,15 +4,18 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_boolfuncs">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_pointerfuncs">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_tostring">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[int, string]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(int,123)
@@ -21,24 +24,25 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both invalid]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[null hash, invalid]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[string, null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[both non-null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQStringLists">
<Incident type="pass" file="" line="0">
@@ -47,62 +51,65 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal lists]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[last item different]]></DataTag>
<Description><![CDATA[Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS']]></Description>
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[second-last item different]]></DataTag>
<Description><![CDATA[Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS']]></Description>
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[prefix]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '2'
- Expected (opB) size: '1']]></Description>
+ Actual (opA) size: 2
+ Expected (opB) size: 1]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[short list second]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '12'
- Expected (opB) size: '1']]></Description>
+ Actual (opA) size: 12
+ Expected (opB) size: 1]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[short list first]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '1'
- Expected (opB) size: '12']]></Description>
+ Actual (opA) size: 1
+ Expected (opB) size: 12]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQListInt">
-<Incident type="fail" file="tst_cmptest.cpp" line="316">
+<Incident type="fail" file="tst_cmptest.cpp" line="320">
<Description><![CDATA[Compared lists differ at index 2.
- Actual (int1): '3'
- Expected (int2): '4']]></Description>
+ Actual (int1): 3
+ Expected (int2): 4]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQListDouble">
-<Incident type="fail" file="tst_cmptest.cpp" line="323">
+<Incident type="fail" file="tst_cmptest.cpp" line="327">
<Description><![CDATA[Compared lists differ at index 0.
- Actual (double1): '1.5'
- Expected (double2): '1']]></Description>
+ Actual (double1): 1.5
+ Expected (double2): 1]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQPixmaps">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both null]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[one null]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[other null]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ.
Actual (opA).isNull(): 0
@@ -111,28 +118,29 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[different size]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ in size.
Actual (opA): 11x20
Expected (opB): 20x20]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[different pixels]]></DataTag>
<Description><![CDATA[Compared values are not the same]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQImages">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both null]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[one null]]></DataTag>
<Description><![CDATA[Compared QImages differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[other null]]></DataTag>
<Description><![CDATA[Compared QImages differ.
Actual (opA).isNull(): 0
@@ -141,23 +149,26 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different size]]></DataTag>
<Description><![CDATA[Compared QImages differ in size.
Actual (opA): 11x20
Expected (opB): 20x20]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different format]]></DataTag>
<Description><![CDATA[Compared QImages differ in format.
Actual (opA): 6
Expected (opB): 3]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different pixels]]></DataTag>
<Description><![CDATA[Compared values are not the same]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt
index 504507f032..8473b4528e 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.txt
+++ b/tests/auto/testlib/selftests/expected_cmptest.txt
@@ -6,86 +6,86 @@ PASS : tst_Cmptest::compare_pointerfuncs()
FAIL! : tst_Cmptest::compare_tostring(int, string) Compared values are not the same
Actual (actual) : QVariant(int,123)
Expected (expected): QVariant(QString,hi)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
+ Loc: [tst_cmptest.cpp(219)]
PASS : tst_Cmptest::compare_tostring(both invalid)
FAIL! : tst_Cmptest::compare_tostring(null hash, invalid) Compared values are not the same
Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
+ Loc: [tst_cmptest.cpp(219)]
FAIL! : tst_Cmptest::compare_tostring(string, null user type) Compared values are not the same
Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
+ Loc: [tst_cmptest.cpp(219)]
FAIL! : tst_Cmptest::compare_tostring(both non-null user type) Compared values are not the same
Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(214)]
+ Loc: [tst_cmptest.cpp(219)]
PASS : tst_Cmptest::compareQStringLists(empty lists)
PASS : tst_Cmptest::compareQStringLists(equal lists)
FAIL! : tst_Cmptest::compareQStringLists(last item different) Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)]
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"
+ Loc: [tst_cmptest.cpp(313)]
FAIL! : tst_Cmptest::compareQStringLists(second-last item different) Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)]
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"
+ Loc: [tst_cmptest.cpp(313)]
FAIL! : tst_Cmptest::compareQStringLists(prefix) Compared lists have different sizes.
- Actual (opA) size: '2'
- Expected (opB) size: '1'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)]
+ Actual (opA) size: 2
+ Expected (opB) size: 1
+ Loc: [tst_cmptest.cpp(313)]
FAIL! : tst_Cmptest::compareQStringLists(short list second) Compared lists have different sizes.
- Actual (opA) size: '12'
- Expected (opB) size: '1'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)]
+ Actual (opA) size: 12
+ Expected (opB) size: 1
+ Loc: [tst_cmptest.cpp(313)]
FAIL! : tst_Cmptest::compareQStringLists(short list first) Compared lists have different sizes.
- Actual (opA) size: '1'
- Expected (opB) size: '12'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(308)]
+ Actual (opA) size: 1
+ Expected (opB) size: 12
+ Loc: [tst_cmptest.cpp(313)]
FAIL! : tst_Cmptest::compareQListInt() Compared lists differ at index 2.
- Actual (int1): '3'
- Expected (int2): '4'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(316)]
+ Actual (int1): 3
+ Expected (int2): 4
+ Loc: [tst_cmptest.cpp(320)]
FAIL! : tst_Cmptest::compareQListDouble() Compared lists differ at index 0.
- Actual (double1): '1.5'
- Expected (double2): '1'
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(323)]
+ Actual (double1): 1.5
+ Expected (double2): 1
+ Loc: [tst_cmptest.cpp(327)]
PASS : tst_Cmptest::compareQPixmaps(both null)
FAIL! : tst_Cmptest::compareQPixmaps(one null) Compared QPixmaps differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)]
+ Loc: [tst_cmptest.cpp(353)]
FAIL! : tst_Cmptest::compareQPixmaps(other null) Compared QPixmaps differ.
Actual (opA).isNull(): 0
Expected (opB).isNull(): 1
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)]
+ Loc: [tst_cmptest.cpp(353)]
PASS : tst_Cmptest::compareQPixmaps(equal)
FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ in size.
Actual (opA): 11x20
Expected (opB): 20x20
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)]
+ Loc: [tst_cmptest.cpp(353)]
FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(333)]
+ Loc: [tst_cmptest.cpp(353)]
PASS : tst_Cmptest::compareQImages(both null)
FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)]
+ Loc: [tst_cmptest.cpp(380)]
FAIL! : tst_Cmptest::compareQImages(other null) Compared QImages differ.
Actual (opA).isNull(): 0
Expected (opB).isNull(): 1
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)]
+ Loc: [tst_cmptest.cpp(380)]
PASS : tst_Cmptest::compareQImages(equal)
FAIL! : tst_Cmptest::compareQImages(different size) Compared QImages differ in size.
Actual (opA): 11x20
Expected (opB): 20x20
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)]
+ Loc: [tst_cmptest.cpp(380)]
FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ in format.
Actual (opA): 6
Expected (opB): 3
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)]
+ Loc: [tst_cmptest.cpp(380)]
FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(360)]
+ Loc: [tst_cmptest.cpp(380)]
PASS : tst_Cmptest::cleanupTestCase()
Totals: 11 passed, 20 failed, 0 skipped
********* Finished testing of tst_Cmptest *********
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml
index df35058acc..970544e4b6 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xml
@@ -6,15 +6,18 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_boolfuncs">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_pointerfuncs">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compare_tostring">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[int, string]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(int,123)
@@ -23,24 +26,25 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both invalid]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[null hash, invalid]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(QVariantHash)
Expected (expected): QVariant()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[string, null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(QString,A simple string)
Expected (expected): QVariant(PhonyClass)]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="214">
+<Incident type="fail" file="tst_cmptest.cpp" line="219">
<DataTag><![CDATA[both non-null user type]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (actual) : QVariant(PhonyClass,<value not representable as string>)
Expected (expected): QVariant(PhonyClass,<value not representable as string>)]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQStringLists">
<Incident type="pass" file="" line="0">
@@ -49,62 +53,65 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal lists]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[last item different]]></DataTag>
<Description><![CDATA[Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS']]></Description>
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[second-last item different]]></DataTag>
<Description><![CDATA[Compared lists differ at index 2.
- Actual (opA): 'string3'
- Expected (opB): 'DIFFERS']]></Description>
+ Actual (opA): "string3"
+ Expected (opB): "DIFFERS"]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[prefix]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '2'
- Expected (opB) size: '1']]></Description>
+ Actual (opA) size: 2
+ Expected (opB) size: 1]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[short list second]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '12'
- Expected (opB) size: '1']]></Description>
+ Actual (opA) size: 12
+ Expected (opB) size: 1]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="308">
+<Incident type="fail" file="tst_cmptest.cpp" line="313">
<DataTag><![CDATA[short list first]]></DataTag>
<Description><![CDATA[Compared lists have different sizes.
- Actual (opA) size: '1'
- Expected (opB) size: '12']]></Description>
+ Actual (opA) size: 1
+ Expected (opB) size: 12]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQListInt">
-<Incident type="fail" file="tst_cmptest.cpp" line="316">
+<Incident type="fail" file="tst_cmptest.cpp" line="320">
<Description><![CDATA[Compared lists differ at index 2.
- Actual (int1): '3'
- Expected (int2): '4']]></Description>
+ Actual (int1): 3
+ Expected (int2): 4]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQListDouble">
-<Incident type="fail" file="tst_cmptest.cpp" line="323">
+<Incident type="fail" file="tst_cmptest.cpp" line="327">
<Description><![CDATA[Compared lists differ at index 0.
- Actual (double1): '1.5'
- Expected (double2): '1']]></Description>
+ Actual (double1): 1.5
+ Expected (double2): 1]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQPixmaps">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both null]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[one null]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[other null]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ.
Actual (opA).isNull(): 0
@@ -113,28 +120,29 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[different size]]></DataTag>
<Description><![CDATA[Compared QPixmaps differ in size.
Actual (opA): 11x20
Expected (opB): 20x20]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="333">
+<Incident type="fail" file="tst_cmptest.cpp" line="353">
<DataTag><![CDATA[different pixels]]></DataTag>
<Description><![CDATA[Compared values are not the same]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareQImages">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[both null]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[one null]]></DataTag>
<Description><![CDATA[Compared QImages differ.
Actual (opA).isNull(): 1
Expected (opB).isNull(): 0]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[other null]]></DataTag>
<Description><![CDATA[Compared QImages differ.
Actual (opA).isNull(): 0
@@ -143,24 +151,27 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[equal]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different size]]></DataTag>
<Description><![CDATA[Compared QImages differ in size.
Actual (opA): 11x20
Expected (opB): 20x20]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different format]]></DataTag>
<Description><![CDATA[Compared QImages differ in format.
Actual (opA): 6
Expected (opB): 3]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp" line="360">
+<Incident type="fail" file="tst_cmptest.cpp" line="380">
<DataTag><![CDATA[different pixels]]></DataTag>
<Description><![CDATA[Compared values are not the same]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
index e7d76ac839..7874c6c52e 100644
--- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml
+++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml
@@ -23,30 +23,30 @@
</testcase>
<testcase result="fail" name="compareQStringLists">
<failure tag="last item different" message="Compared lists differ at index 2.
- Actual (opA): &apos;string3&apos;
- Expected (opB): &apos;DIFFERS&apos;" result="fail"/>
+ Actual (opA): &quot;string3&quot;
+ Expected (opB): &quot;DIFFERS&quot;" result="fail"/>
<failure tag="second&#x002D;last item different" message="Compared lists differ at index 2.
- Actual (opA): &apos;string3&apos;
- Expected (opB): &apos;DIFFERS&apos;" result="fail"/>
+ Actual (opA): &quot;string3&quot;
+ Expected (opB): &quot;DIFFERS&quot;" result="fail"/>
<failure tag="prefix" message="Compared lists have different sizes.
- Actual (opA) size: &apos;2&apos;
- Expected (opB) size: &apos;1&apos;" result="fail"/>
+ Actual (opA) size: 2
+ Expected (opB) size: 1" result="fail"/>
<failure tag="short list second" message="Compared lists have different sizes.
- Actual (opA) size: &apos;12&apos;
- Expected (opB) size: &apos;1&apos;" result="fail"/>
+ Actual (opA) size: 12
+ Expected (opB) size: 1" result="fail"/>
<failure tag="short list first" message="Compared lists have different sizes.
- Actual (opA) size: &apos;1&apos;
- Expected (opB) size: &apos;12&apos;" result="fail"/>
+ Actual (opA) size: 1
+ Expected (opB) size: 12" result="fail"/>
</testcase>
<testcase result="fail" name="compareQListInt">
<failure message="Compared lists differ at index 2.
- Actual (int1): &apos;3&apos;
- Expected (int2): &apos;4&apos;" result="fail"/>
+ Actual (int1): 3
+ Expected (int2): 4" result="fail"/>
</testcase>
<testcase result="fail" name="compareQListDouble">
<failure message="Compared lists differ at index 0.
- Actual (double1): &apos;1.5&apos;
- Expected (double2): &apos;1&apos;" result="fail"/>
+ Actual (double1): 1.5
+ Expected (double2): 1" result="fail"/>
</testcase>
<testcase result="fail" name="compareQPixmaps">
<failure tag="one null" message="Compared QPixmaps differ.
diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.lightxml b/tests/auto/testlib/selftests/expected_commandlinedata.lightxml
index 37eb5f5a2b..c11017f022 100644
--- a/tests/auto/testlib/selftests/expected_commandlinedata.lightxml
+++ b/tests/auto/testlib/selftests/expected_commandlinedata.lightxml
@@ -4,53 +4,58 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data2]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data2]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data3]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data3]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data4]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data4]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data5]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.txt b/tests/auto/testlib/selftests/expected_commandlinedata.txt
index 7c16267b74..509f6a2de5 100644
--- a/tests/auto/testlib/selftests/expected_commandlinedata.txt
+++ b/tests/auto/testlib/selftests/expected_commandlinedata.txt
@@ -4,23 +4,23 @@ INFO : tst_DataTable::initTestCase() entering
PASS : tst_DataTable::initTestCase()
INFO : tst_DataTable::fiveTablePasses() entering
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data1)
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data2) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data2)
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data3) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data3)
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data4) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data4)
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data5) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data5)
INFO : tst_DataTable::fiveTablePasses() entering
INFO : tst_DataTable::fiveTablePasses(fiveTablePasses_data1) QVERIFY(test)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp(65)]
+ Loc: [tst_commandlinedata.cpp(65)]
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data1)
INFO : tst_DataTable::cleanupTestCase() entering
PASS : tst_DataTable::cleanupTestCase()
diff --git a/tests/auto/testlib/selftests/expected_commandlinedata.xml b/tests/auto/testlib/selftests/expected_commandlinedata.xml
index 76e297801c..20dc0c6a7c 100644
--- a/tests/auto/testlib/selftests/expected_commandlinedata.xml
+++ b/tests/auto/testlib/selftests/expected_commandlinedata.xml
@@ -6,54 +6,59 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data2]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data2]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data3]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data3]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data4]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data4]]></DataTag>
</Incident>
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data5]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/commandlinedata/tst_commandlinedata.cpp" line="65">
+<Message type="info" file="tst_commandlinedata.cpp" line="65">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
<Description><![CDATA[QVERIFY(test)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data1]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_counting.lightxml b/tests/auto/testlib/selftests/expected_counting.lightxml
index c49792fec4..e5fe1ee3cf 100644
--- a/tests/auto/testlib/selftests/expected_counting.lightxml
+++ b/tests/auto/testlib/selftests/expected_counting.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
<Incident type="pass" file="" line="0">
@@ -12,94 +13,104 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -107,27 +118,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -135,16 +148,19 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_counting.txt b/tests/auto/testlib/selftests/expected_counting.txt
index f413882c2a..cdabf6770e 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(118)]
+ Loc: [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(115)]
+ Loc: [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(118)]
+ Loc: [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(118)]
+ Loc: [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)]
+ Loc: [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(118)]
+ Loc: [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)]
+ Loc: [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)]
+ Loc: [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(115)]
+ Loc: [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)]
+ Loc: [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(115)]
+ Loc: [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)]
+ Loc: [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(234)]
+ Loc: [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()
+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)]
+ Loc: [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(236)]
+ Loc: [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()
+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)]
+ Loc: [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 7caa915f65..e015dddcc6 100644
--- a/tests/auto/testlib/selftests/expected_counting.xml
+++ b/tests/auto/testlib/selftests/expected_counting.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
<Incident type="pass" file="" line="0">
@@ -14,94 +15,104 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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">
+<Message type="skip" file="tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="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">
+<Incident type="fail" file="tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -109,27 +120,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -137,17 +150,20 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_counting.xunitxml b/tests/auto/testlib/selftests/expected_counting.xunitxml
index f317ed5923..72bf047ba8 100644
--- a/tests/auto/testlib/selftests/expected_counting.xunitxml
+++ b/tests/auto/testlib/selftests/expected_counting.xunitxml
@@ -38,14 +38,14 @@
<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" -->
+ <!-- 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="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"/>
@@ -56,9 +56,9 @@
<![CDATA[Skipping]]>
<![CDATA[Skipping]]>
<![CDATA[Skipping]]>
-<![CDATA[This test function should execute and then QFAIL in cleanup() ]]>
+<![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[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_datatable.lightxml b/tests/auto/testlib/selftests/expected_datatable.lightxml
index 83ac0c0b5d..6cc2d1c46f 100644
--- a/tests/auto/testlib/selftests/expected_datatable.lightxml
+++ b/tests/auto/testlib/selftests/expected_datatable.lightxml
@@ -4,12 +4,15 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleTestFunction1">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleTestFunction2">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
<Incident type="pass" file="" line="0">
@@ -27,31 +30,33 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTableFailures">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 1]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 2]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 3]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 4]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 5]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="startsWithFailure">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[startsWithFailure_data 1]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
@@ -67,6 +72,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[startsWithFailure_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="endsWithFailure">
<Incident type="pass" file="" line="0">
@@ -81,10 +87,11 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[endsWithFailure 4]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[endsWithFailure 5]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failureInMiddle">
<Incident type="pass" file="" line="0">
@@ -93,7 +100,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[failureInMiddle_data 2]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[failureInMiddle_data 3]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
@@ -103,29 +110,33 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[failureInMiddle_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveIsolatedFailures">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 1]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 2]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 3]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 4]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 5]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_datatable.txt b/tests/auto/testlib/selftests/expected_datatable.txt
index 24b39becd2..63118b5d33 100644
--- a/tests/auto/testlib/selftests/expected_datatable.txt
+++ b/tests/auto/testlib/selftests/expected_datatable.txt
@@ -9,17 +9,17 @@ PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 3)
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 4)
PASS : tst_DataTable::fiveTablePasses(fiveTablePasses_data 5)
FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 1) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 2) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 3) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 4) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
FAIL! : tst_DataTable::fiveTableFailures(fiveTableFailures_data 5) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
FAIL! : tst_DataTable::startsWithFailure(startsWithFailure_data 1) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 2)
PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 3)
PASS : tst_DataTable::startsWithFailure(startsWithFailure_data 4)
@@ -29,23 +29,23 @@ PASS : tst_DataTable::endsWithFailure(endsWithFailure 2)
PASS : tst_DataTable::endsWithFailure(endsWithFailure 3)
PASS : tst_DataTable::endsWithFailure(endsWithFailure 4)
FAIL! : tst_DataTable::endsWithFailure(endsWithFailure 5) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 1)
PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 2)
FAIL! : tst_DataTable::failureInMiddle(failureInMiddle_data 3) 'test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(91)]
+ Loc: [tst_datatable.cpp(91)]
PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 4)
PASS : tst_DataTable::failureInMiddle(failureInMiddle_data 5)
FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 1) '!test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)]
+ Loc: [tst_datatable.cpp(173)]
FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 2) '!test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)]
+ Loc: [tst_datatable.cpp(173)]
FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 3) '!test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)]
+ Loc: [tst_datatable.cpp(173)]
FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 4) '!test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)]
+ Loc: [tst_datatable.cpp(173)]
FAIL! : tst_DataTable::fiveIsolatedFailures(fiveIsolatedFailures_data 5) '!test' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp(173)]
+ Loc: [tst_datatable.cpp(173)]
PASS : tst_DataTable::cleanupTestCase()
Totals: 21 passed, 13 failed, 0 skipped
********* Finished testing of tst_DataTable *********
diff --git a/tests/auto/testlib/selftests/expected_datatable.xml b/tests/auto/testlib/selftests/expected_datatable.xml
index 2579ff24cc..79963db0a4 100644
--- a/tests/auto/testlib/selftests/expected_datatable.xml
+++ b/tests/auto/testlib/selftests/expected_datatable.xml
@@ -6,12 +6,15 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleTestFunction1">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleTestFunction2">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTablePasses">
<Incident type="pass" file="" line="0">
@@ -29,31 +32,33 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[fiveTablePasses_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveTableFailures">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 1]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 2]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 3]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 4]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[fiveTableFailures_data 5]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="startsWithFailure">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[startsWithFailure_data 1]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
@@ -69,6 +74,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[startsWithFailure_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="endsWithFailure">
<Incident type="pass" file="" line="0">
@@ -83,10 +89,11 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[endsWithFailure 4]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[endsWithFailure 5]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failureInMiddle">
<Incident type="pass" file="" line="0">
@@ -95,7 +102,7 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[failureInMiddle_data 2]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="91">
+<Incident type="fail" file="tst_datatable.cpp" line="91">
<DataTag><![CDATA[failureInMiddle_data 3]]></DataTag>
<Description><![CDATA['test' returned FALSE. ()]]></Description>
</Incident>
@@ -105,30 +112,34 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[failureInMiddle_data 5]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fiveIsolatedFailures">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 1]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 2]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 3]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 4]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datatable/tst_datatable.cpp" line="173">
+<Incident type="fail" file="tst_datatable.cpp" line="173">
<DataTag><![CDATA[fiveIsolatedFailures_data 5]]></DataTag>
<Description><![CDATA['!test' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_datetime.lightxml b/tests/auto/testlib/selftests/expected_datetime.lightxml
index 183744b2e2..02c60d04f9 100644
--- a/tests/auto/testlib/selftests/expected_datetime.lightxml
+++ b/tests/auto/testlib/selftests/expected_datetime.lightxml
@@ -4,25 +4,27 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="dateTime">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66">
+<Incident type="fail" file="tst_datetime.cpp" line="65">
<Description><![CDATA[Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="qurl">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[empty urls]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="74">
+<Incident type="fail" file="tst_datetime.cpp" line="73">
<DataTag><![CDATA[empty rhs]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (operandA): http://example.com
Expected (operandB): Invalid URL: ]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="74">
+<Incident type="fail" file="tst_datetime.cpp" line="73">
<DataTag><![CDATA[empty lhs]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (operandA): Invalid URL:
@@ -31,7 +33,10 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[same urls]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_datetime.txt b/tests/auto/testlib/selftests/expected_datetime.txt
index 0cbc6506d5..f48e28ea38 100644
--- a/tests/auto/testlib/selftests/expected_datetime.txt
+++ b/tests/auto/testlib/selftests/expected_datetime.txt
@@ -4,16 +4,16 @@ PASS : tst_DateTime::initTestCase()
FAIL! : tst_DateTime::dateTime() Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
Expected (utc) : 2000/05/03 04:03:04.000[UTC]
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(33)]
+ Loc: [tst_datetime.cpp(65)]
PASS : tst_DateTime::qurl(empty urls)
FAIL! : tst_DateTime::qurl(empty rhs) Compared values are not the same
Actual (operandA): http://example.com
Expected (operandB): Invalid URL:
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(41)]
+ Loc: [tst_datetime.cpp(73)]
FAIL! : tst_DateTime::qurl(empty lhs) Compared values are not the same
Actual (operandA): Invalid URL:
Expected (operandB): http://example.com
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp(41)]
+ Loc: [tst_datetime.cpp(73)]
PASS : tst_DateTime::qurl(same urls)
PASS : tst_DateTime::cleanupTestCase()
Totals: 4 passed, 3 failed, 0 skipped
diff --git a/tests/auto/testlib/selftests/expected_datetime.xml b/tests/auto/testlib/selftests/expected_datetime.xml
index 42b566c074..03aec4430e 100644
--- a/tests/auto/testlib/selftests/expected_datetime.xml
+++ b/tests/auto/testlib/selftests/expected_datetime.xml
@@ -6,25 +6,27 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="dateTime">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="66">
+<Incident type="fail" file="tst_datetime.cpp" line="65">
<Description><![CDATA[Compared values are not the same
Actual (local): 2000/05/03 04:03:04.000[local time]
Expected (utc) : 2000/05/03 04:03:04.000[UTC]]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="qurl">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[empty urls]]></DataTag>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="74">
+<Incident type="fail" file="tst_datetime.cpp" line="73">
<DataTag><![CDATA[empty rhs]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (operandA): http://example.com
Expected (operandB): Invalid URL: ]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/datetime/tst_datetime.cpp" line="74">
+<Incident type="fail" file="tst_datetime.cpp" line="73">
<DataTag><![CDATA[empty lhs]]></DataTag>
<Description><![CDATA[Compared values are not the same
Actual (operandA): Invalid URL:
@@ -33,8 +35,11 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[same urls]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_exceptionthrow.lightxml b/tests/auto/testlib/selftests/expected_exceptionthrow.lightxml
index e4f87fa611..6c9675a2aa 100644
--- a/tests/auto/testlib/selftests/expected_exceptionthrow.lightxml
+++ b/tests/auto/testlib/selftests/expected_exceptionthrow.lightxml
@@ -4,9 +4,12 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="throwException">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase//src/testlib/qtestcase.cpp" line="1691">
+<Incident type="fail" file="/home/frederik/dev/qt/qt&#x002D;src&#x002D;dev/qtbase/src/testlib/qtestcase.cpp" line="2229">
<Description><![CDATA[Caught unhandled exception]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_exceptionthrow.txt b/tests/auto/testlib/selftests/expected_exceptionthrow.txt
index ecbc7da01a..671e609230 100644
--- a/tests/auto/testlib/selftests/expected_exceptionthrow.txt
+++ b/tests/auto/testlib/selftests/expected_exceptionthrow.txt
@@ -2,6 +2,6 @@
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_Exception::initTestCase()
FAIL! : tst_Exception::throwException() Caught unhandled exception
- Loc: [/home/user/dev/qt5/qtbase/src/testlib/qtestcase.cpp(1220)]
+ Loc: [/home/frederik/dev/qt/qt-src-dev/qtbase/src/testlib/qtestcase.cpp(2229)]
Totals: 1 passed, 1 failed, 0 skipped
********* Finished testing of tst_Exception *********
diff --git a/tests/auto/testlib/selftests/expected_exceptionthrow.xml b/tests/auto/testlib/selftests/expected_exceptionthrow.xml
index ab0f9a917e..87d9d2d431 100644
--- a/tests/auto/testlib/selftests/expected_exceptionthrow.xml
+++ b/tests/auto/testlib/selftests/expected_exceptionthrow.xml
@@ -6,10 +6,13 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="throwException">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/src/testlib/qtestcase.cpp" line="1691">
+<Incident type="fail" file="/home/frederik/dev/qt/qt&#x002D;src&#x002D;dev/qtbase/src/testlib/qtestcase.cpp" line="2229">
<Description><![CDATA[Caught unhandled exception]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_expectfail.lightxml b/tests/auto/testlib/selftests/expected_expectfail.lightxml
index 55bd9578a8..e5fcca5875 100644
--- a/tests/auto/testlib/selftests/expected_expectfail.lightxml
+++ b/tests/auto/testlib/selftests/expected_expectfail.lightxml
@@ -4,41 +4,46 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailAndContinue">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[begin]]></Description>
</Message>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="78">
+<Incident type="xfail" file="tst_expectfail.cpp" line="78">
<Description><![CDATA[This should xfail]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<Description><![CDATA[after]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailAndAbort">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[begin]]></Description>
</Message>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="86">
+<Incident type="xfail" file="tst_expectfail.cpp" line="86">
<Description><![CDATA[This should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailTwice">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="96">
+<Incident type="fail" file="tst_expectfail.cpp" line="96">
<Description><![CDATA[Already expecting a fail]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailWithQString">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="105">
+<Incident type="xfail" file="tst_expectfail.cpp" line="105">
<Description><![CDATA[A string]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="110">
+<Incident type="xfail" file="tst_expectfail.cpp" line="110">
<Description><![CDATA[Bug 5 (The message)]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailDataDrivenWithQVerify">
<Incident type="pass" file="" line="0">
@@ -47,20 +52,21 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass 2]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="139">
+<Incident type="xfail" file="tst_expectfail.cpp" line="139">
<DataTag><![CDATA[Abort]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Abort]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="139">
+<Incident type="xfail" file="tst_expectfail.cpp" line="139">
<DataTag><![CDATA[Continue]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Continue]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailDataDrivenWithQCompare">
<Incident type="pass" file="" line="0">
@@ -69,41 +75,44 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass 2]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="173">
+<Incident type="xfail" file="tst_expectfail.cpp" line="173">
<DataTag><![CDATA[Abort]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Abort]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="173">
+<Incident type="xfail" file="tst_expectfail.cpp" line="173">
<DataTag><![CDATA[Continue]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Continue]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailOnWrongRow">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[right row]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailOnAnyRow">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="208">
+<Incident type="xfail" file="tst_expectfail.cpp" line="208">
<DataTag><![CDATA[first row]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[first row]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="208">
+<Incident type="xfail" file="tst_expectfail.cpp" line="208">
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[second row]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailWithoutVerify">
<Incident type="fail" file="" line="0">
@@ -114,30 +123,36 @@
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[QEXPECT_FAIL was called without any subsequent verification statements]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpass">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="228">
+<Incident type="xpass" file="tst_expectfail.cpp" line="228">
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpassDataDrivenWithQVerify">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="250">
+<Incident type="xpass" file="tst_expectfail.cpp" line="250">
<DataTag><![CDATA[XPass]]></DataTag>
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpassDataDrivenWithQCompare">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="271">
+<Incident type="xpass" file="tst_expectfail.cpp" line="271">
<DataTag><![CDATA[XPass]]></DataTag>
<Description><![CDATA[QCOMPARE(1, 1) returned TRUE unexpectedly.]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_expectfail.txt b/tests/auto/testlib/selftests/expected_expectfail.txt
index abd1cdc32c..39f3c17f70 100644
--- a/tests/auto/testlib/selftests/expected_expectfail.txt
+++ b/tests/auto/testlib/selftests/expected_expectfail.txt
@@ -3,52 +3,52 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_ExpectFail::initTestCase()
QDEBUG : tst_ExpectFail::xfailAndContinue() begin
XFAIL : tst_ExpectFail::xfailAndContinue() This should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(78)]
+ Loc: [tst_expectfail.cpp(78)]
QDEBUG : tst_ExpectFail::xfailAndContinue() after
PASS : tst_ExpectFail::xfailAndContinue()
QDEBUG : tst_ExpectFail::xfailAndAbort() begin
XFAIL : tst_ExpectFail::xfailAndAbort() This should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(86)]
+ Loc: [tst_expectfail.cpp(86)]
PASS : tst_ExpectFail::xfailAndAbort()
FAIL! : tst_ExpectFail::xfailTwice() Already expecting a fail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(96)]
+ Loc: [tst_expectfail.cpp(96)]
XFAIL : tst_ExpectFail::xfailWithQString() A string
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(105)]
+ Loc: [tst_expectfail.cpp(105)]
XFAIL : tst_ExpectFail::xfailWithQString() Bug 5 (The message)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(110)]
+ Loc: [tst_expectfail.cpp(110)]
PASS : tst_ExpectFail::xfailWithQString()
PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Pass 1)
PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Pass 2)
XFAIL : tst_ExpectFail::xfailDataDrivenWithQVerify(Abort) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(139)]
+ Loc: [tst_expectfail.cpp(139)]
PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Abort)
XFAIL : tst_ExpectFail::xfailDataDrivenWithQVerify(Continue) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(139)]
+ Loc: [tst_expectfail.cpp(139)]
PASS : tst_ExpectFail::xfailDataDrivenWithQVerify(Continue)
PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Pass 1)
PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Pass 2)
XFAIL : tst_ExpectFail::xfailDataDrivenWithQCompare(Abort) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(173)]
+ Loc: [tst_expectfail.cpp(173)]
PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Abort)
XFAIL : tst_ExpectFail::xfailDataDrivenWithQCompare(Continue) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(173)]
+ Loc: [tst_expectfail.cpp(173)]
PASS : tst_ExpectFail::xfailDataDrivenWithQCompare(Continue)
PASS : tst_ExpectFail::xfailOnWrongRow(right row)
XFAIL : tst_ExpectFail::xfailOnAnyRow(first row) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(208)]
+ Loc: [tst_expectfail.cpp(208)]
PASS : tst_ExpectFail::xfailOnAnyRow(first row)
XFAIL : tst_ExpectFail::xfailOnAnyRow(second row) This test should xfail
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(208)]
+ Loc: [tst_expectfail.cpp(208)]
PASS : tst_ExpectFail::xfailOnAnyRow(second row)
FAIL! : tst_ExpectFail::xfailWithoutVerify(first row) QEXPECT_FAIL was called without any subsequent verification statements
FAIL! : tst_ExpectFail::xfailWithoutVerify(second row) QEXPECT_FAIL was called without any subsequent verification statements
XPASS : tst_ExpectFail::xpass() 'true' returned TRUE unexpectedly. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(228)]
+ Loc: [tst_expectfail.cpp(228)]
XPASS : tst_ExpectFail::xpassDataDrivenWithQVerify(XPass) 'true' returned TRUE unexpectedly. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(250)]
+ Loc: [tst_expectfail.cpp(250)]
PASS : tst_ExpectFail::xpassDataDrivenWithQVerify(Pass)
XPASS : tst_ExpectFail::xpassDataDrivenWithQCompare(XPass) QCOMPARE(1, 1) returned TRUE unexpectedly.
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp(271)]
+ Loc: [tst_expectfail.cpp(271)]
PASS : tst_ExpectFail::xpassDataDrivenWithQCompare(Pass)
PASS : tst_ExpectFail::cleanupTestCase()
Totals: 18 passed, 6 failed, 0 skipped
diff --git a/tests/auto/testlib/selftests/expected_expectfail.xml b/tests/auto/testlib/selftests/expected_expectfail.xml
index 58a48197b0..14fee2129e 100644
--- a/tests/auto/testlib/selftests/expected_expectfail.xml
+++ b/tests/auto/testlib/selftests/expected_expectfail.xml
@@ -6,41 +6,46 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailAndContinue">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[begin]]></Description>
</Message>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="78">
+<Incident type="xfail" file="tst_expectfail.cpp" line="78">
<Description><![CDATA[This should xfail]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<Description><![CDATA[after]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailAndAbort">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[begin]]></Description>
</Message>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="86">
+<Incident type="xfail" file="tst_expectfail.cpp" line="86">
<Description><![CDATA[This should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailTwice">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="96">
+<Incident type="fail" file="tst_expectfail.cpp" line="96">
<Description><![CDATA[Already expecting a fail]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailWithQString">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="105">
+<Incident type="xfail" file="tst_expectfail.cpp" line="105">
<Description><![CDATA[A string]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="110">
+<Incident type="xfail" file="tst_expectfail.cpp" line="110">
<Description><![CDATA[Bug 5 (The message)]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailDataDrivenWithQVerify">
<Incident type="pass" file="" line="0">
@@ -49,20 +54,21 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass 2]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="139">
+<Incident type="xfail" file="tst_expectfail.cpp" line="139">
<DataTag><![CDATA[Abort]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Abort]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="139">
+<Incident type="xfail" file="tst_expectfail.cpp" line="139">
<DataTag><![CDATA[Continue]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Continue]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailDataDrivenWithQCompare">
<Incident type="pass" file="" line="0">
@@ -71,41 +77,44 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass 2]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="173">
+<Incident type="xfail" file="tst_expectfail.cpp" line="173">
<DataTag><![CDATA[Abort]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Abort]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="173">
+<Incident type="xfail" file="tst_expectfail.cpp" line="173">
<DataTag><![CDATA[Continue]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Continue]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailOnWrongRow">
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[right row]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailOnAnyRow">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="208">
+<Incident type="xfail" file="tst_expectfail.cpp" line="208">
<DataTag><![CDATA[first row]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[first row]]></DataTag>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="208">
+<Incident type="xfail" file="tst_expectfail.cpp" line="208">
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[This test should xfail]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[second row]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xfailWithoutVerify">
<Incident type="fail" file="" line="0">
@@ -116,31 +125,37 @@
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[QEXPECT_FAIL was called without any subsequent verification statements]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpass">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="228">
+<Incident type="xpass" file="tst_expectfail.cpp" line="228">
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpassDataDrivenWithQVerify">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="250">
+<Incident type="xpass" file="tst_expectfail.cpp" line="250">
<DataTag><![CDATA[XPass]]></DataTag>
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="xpassDataDrivenWithQCompare">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/expectfail/tst_expectfail.cpp" line="271">
+<Incident type="xpass" file="tst_expectfail.cpp" line="271">
<DataTag><![CDATA[XPass]]></DataTag>
<Description><![CDATA[QCOMPARE(1, 1) returned TRUE unexpectedly.]]></Description>
</Incident>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[Pass]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_failcleanup.lightxml b/tests/auto/testlib/selftests/expected_failcleanup.lightxml
index 83ce7a7b15..cfc18ef5da 100644
--- a/tests/auto/testlib/selftests/expected_failcleanup.lightxml
+++ b/tests/auto/testlib/selftests/expected_failcleanup.lightxml
@@ -4,12 +4,16 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="aTestFunction">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp" line="59">
+<Incident type="fail" file="tst_failcleanup.cpp" line="59">
<Description><![CDATA['false' returned FALSE. (Fail inside cleanupTestCase)]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_failcleanup.txt b/tests/auto/testlib/selftests/expected_failcleanup.txt
index 1d9405b326..59d0c26794 100644
--- a/tests/auto/testlib/selftests/expected_failcleanup.txt
+++ b/tests/auto/testlib/selftests/expected_failcleanup.txt
@@ -3,6 +3,6 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_FailCleanup::initTestCase()
PASS : tst_FailCleanup::aTestFunction()
FAIL! : tst_FailCleanup::cleanupTestCase() 'false' returned FALSE. (Fail inside cleanupTestCase)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp(59)]
+ Loc: [tst_failcleanup.cpp(59)]
Totals: 2 passed, 1 failed, 0 skipped
********* Finished testing of tst_FailCleanup *********
diff --git a/tests/auto/testlib/selftests/expected_failcleanup.xml b/tests/auto/testlib/selftests/expected_failcleanup.xml
index 13633a8a0d..3aa7aa265d 100644
--- a/tests/auto/testlib/selftests/expected_failcleanup.xml
+++ b/tests/auto/testlib/selftests/expected_failcleanup.xml
@@ -6,13 +6,17 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="aTestFunction">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failcleanup/tst_failcleanup.cpp" line="59">
+<Incident type="fail" file="tst_failcleanup.cpp" line="59">
<Description><![CDATA['false' returned FALSE. (Fail inside cleanupTestCase)]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_failinit.lightxml b/tests/auto/testlib/selftests/expected_failinit.lightxml
index f80d8075ca..c0d193998d 100644
--- a/tests/auto/testlib/selftests/expected_failinit.lightxml
+++ b/tests/auto/testlib/selftests/expected_failinit.lightxml
@@ -3,10 +3,13 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failinit/tst_failinit.cpp" line="55">
+<Incident type="fail" file="tst_failinit.cpp" line="55">
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_failinit.txt b/tests/auto/testlib/selftests/expected_failinit.txt
index a6cf55b2e2..2265898d69 100644
--- a/tests/auto/testlib/selftests/expected_failinit.txt
+++ b/tests/auto/testlib/selftests/expected_failinit.txt
@@ -1,7 +1,7 @@
********* Start testing of tst_FailInit *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
FAIL! : tst_FailInit::initTestCase() 'false' returned FALSE. ()
- Loc: [tst_failinit.cpp(22)]
+ Loc: [tst_failinit.cpp(55)]
PASS : tst_FailInit::cleanupTestCase()
Totals: 1 passed, 1 failed, 0 skipped
********* Finished testing of tst_FailInit *********
diff --git a/tests/auto/testlib/selftests/expected_failinit.xml b/tests/auto/testlib/selftests/expected_failinit.xml
index 4ab455c966..70ad613f3f 100644
--- a/tests/auto/testlib/selftests/expected_failinit.xml
+++ b/tests/auto/testlib/selftests/expected_failinit.xml
@@ -5,11 +5,14 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failinit/tst_failinit.cpp" line="55">
+<Incident type="fail" file="tst_failinit.cpp" line="55">
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_failinitdata.lightxml b/tests/auto/testlib/selftests/expected_failinitdata.lightxml
index 11ba1f0c2e..285471470f 100644
--- a/tests/auto/testlib/selftests/expected_failinitdata.lightxml
+++ b/tests/auto/testlib/selftests/expected_failinitdata.lightxml
@@ -3,7 +3,9 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failinitdata/tst_failinitdata.cpp" line="56">
+<Incident type="fail" file="tst_failinitdata.cpp" line="56">
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_failinitdata.txt b/tests/auto/testlib/selftests/expected_failinitdata.txt
index 40b36526ba..982db4b2c2 100644
--- a/tests/auto/testlib/selftests/expected_failinitdata.txt
+++ b/tests/auto/testlib/selftests/expected_failinitdata.txt
@@ -1,6 +1,6 @@
********* Start testing of tst_FailInitData *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
FAIL! : tst_FailInitData::initTestCase() 'false' returned FALSE. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failinitdata/tst_failinitdata.cpp(23)]
+ Loc: [tst_failinitdata.cpp(56)]
Totals: 0 passed, 1 failed, 0 skipped
********* Finished testing of tst_FailInitData *********
diff --git a/tests/auto/testlib/selftests/expected_failinitdata.xml b/tests/auto/testlib/selftests/expected_failinitdata.xml
index e4da823112..e86e102202 100644
--- a/tests/auto/testlib/selftests/expected_failinitdata.xml
+++ b/tests/auto/testlib/selftests/expected_failinitdata.xml
@@ -5,8 +5,10 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/failinitdata/tst_failinitdata.cpp" line="56">
+<Incident type="fail" file="tst_failinitdata.cpp" line="56">
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_fetchbogus.lightxml b/tests/auto/testlib/selftests/expected_fetchbogus.lightxml
index 1812c0e6b5..c5587cf031 100644
--- a/tests/auto/testlib/selftests/expected_fetchbogus.lightxml
+++ b/tests/auto/testlib/selftests/expected_fetchbogus.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fetchBogus">
<Message type="qfatal" file="" line="0">
@@ -14,4 +15,6 @@
<DataTag><![CDATA[foo]]></DataTag>
<Description><![CDATA[Received a fatal error.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_fetchbogus.xml b/tests/auto/testlib/selftests/expected_fetchbogus.xml
index ee33a85dc4..40295bdebc 100644
--- a/tests/auto/testlib/selftests/expected_fetchbogus.xml
+++ b/tests/auto/testlib/selftests/expected_fetchbogus.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="fetchBogus">
<Message type="qfatal" file="" line="0">
@@ -16,5 +17,7 @@
<DataTag><![CDATA[foo]]></DataTag>
<Description><![CDATA[Received a fatal error.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_findtestdata.lightxml b/tests/auto/testlib/selftests/expected_findtestdata.lightxml
index f1944c4897..4c1c7298ed 100644
--- a/tests/auto/testlib/selftests/expected_findtestdata.lightxml
+++ b/tests/auto/testlib/selftests/expected_findtestdata.lightxml
@@ -4,13 +4,17 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="paths">
-<Message type="warn" file="findtestdata.cpp" line="131">
+<Message type="warn" file="findtestdata.cpp" line="154">
<Description><![CDATA[testdata testfile could not be located!]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_findtestdata.txt b/tests/auto/testlib/selftests/expected_findtestdata.txt
index 22c2e851d4..d92b167d3e 100644
--- a/tests/auto/testlib/selftests/expected_findtestdata.txt
+++ b/tests/auto/testlib/selftests/expected_findtestdata.txt
@@ -2,7 +2,7 @@
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : FindTestData::initTestCase()
WARNING: FindTestData::paths() testdata testfile could not be located!
- Loc: [findtestdata.cpp(131)]
+ Loc: [findtestdata.cpp(154)]
PASS : FindTestData::paths()
PASS : FindTestData::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped
diff --git a/tests/auto/testlib/selftests/expected_findtestdata.xml b/tests/auto/testlib/selftests/expected_findtestdata.xml
index dd1fc08f68..b1f33abaf6 100644
--- a/tests/auto/testlib/selftests/expected_findtestdata.xml
+++ b/tests/auto/testlib/selftests/expected_findtestdata.xml
@@ -6,14 +6,18 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="paths">
-<Message type="warn" file="findtestdata.cpp" line="131">
+<Message type="warn" file="findtestdata.cpp" line="154">
<Description><![CDATA[testdata testfile could not be located!]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_float.txt b/tests/auto/testlib/selftests/expected_float.txt
index da98f9c19d..6d0588981c 100644
--- a/tests/auto/testlib/selftests/expected_float.txt
+++ b/tests/auto/testlib/selftests/expected_float.txt
@@ -5,28 +5,28 @@ PASS : tst_float::floatComparisons(should SUCCEED 1)
FAIL! : tst_float::floatComparisons(should FAIL 1) Compared floats are not the same (fuzzy compare)
Actual (operandLeft) : 1
Expected (operandRight): 3
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
+ Loc: [tst_float.cpp(61)]
FAIL! : tst_float::floatComparisons(should FAIL 2) Compared floats are not the same (fuzzy compare)
Actual (operandLeft) : 1e-07
Expected (operandRight): 3e-07
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
+ Loc: [tst_float.cpp(61)]
FAIL! : tst_float::floatComparisons(should FAIL 3) Compared floats are not the same (fuzzy compare)
Actual (operandLeft) : 99998
Expected (operandRight): 99999
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(61)]
+ Loc: [tst_float.cpp(61)]
PASS : tst_float::floatComparisons(should SUCCEED 2)
FAIL! : tst_float::compareFloatTests(1e0) Compared floats are not the same (fuzzy compare)
Actual (t1): 1
Expected (t3): 3
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)]
+ Loc: [tst_float.cpp(109)]
FAIL! : tst_float::compareFloatTests(1e-7) Compared floats are not the same (fuzzy compare)
Actual (t1): 1e-07
Expected (t3): 3e-07
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)]
+ Loc: [tst_float.cpp(109)]
FAIL! : tst_float::compareFloatTests(1e+7) Compared floats are not the same (fuzzy compare)
Actual (t1): 1e+07
Expected (t3): 3e+07
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/float/tst_float.cpp(104)]
+ Loc: [tst_float.cpp(109)]
PASS : tst_float::cleanupTestCase()
Totals: 4 passed, 6 failed, 0 skipped
********* Finished testing of tst_float *********
diff --git a/tests/auto/testlib/selftests/expected_globaldata.lightxml b/tests/auto/testlib/selftests/expected_globaldata.lightxml
index 6d68bfbdb5..fd128d2c61 100644
--- a/tests/auto/testlib/selftests/expected_globaldata.lightxml
+++ b/tests/auto/testlib/selftests/expected_globaldata.lightxml
@@ -4,182 +4,189 @@
</Environment>
<TestFunction name="initTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[initTestCase initTestCase (null) ]]></Description>
+ <Description><![CDATA[initTestCase initTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testGlobal">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init testGlobal local 1 ]]></Description>
+ <Description><![CDATA[init testGlobal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[global: false ]]></Description>
+ <Description><![CDATA[global: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[local: false ]]></Description>
+ <Description><![CDATA[local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 1 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init testGlobal local 2 ]]></Description>
+ <Description><![CDATA[init testGlobal local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[global: false ]]></Description>
+ <Description><![CDATA[global: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[local: true ]]></Description>
+ <Description><![CDATA[local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 2 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[init testGlobal local 1 ]]></Description>
+ <Description><![CDATA[init testGlobal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[global: true ]]></Description>
+ <Description><![CDATA[global: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[local: false ]]></Description>
+ <Description><![CDATA[local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 1 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[init testGlobal local 2 ]]></Description>
+ <Description><![CDATA[init testGlobal local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[global: true ]]></Description>
+ <Description><![CDATA[global: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[local: true ]]></Description>
+ <Description><![CDATA[local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 2 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="129">
+<Message type="skip" file="tst_globaldata.cpp" line="129">
<DataTag><![CDATA[1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skipLocal">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init skipLocal local 1 ]]></Description>
+ <Description><![CDATA[init skipLocal local 1]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="149">
+<Message type="skip" file="tst_globaldata.cpp" line="149">
<DataTag><![CDATA[1:local 1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipLocal local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipLocal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init skipLocal local 2 ]]></Description>
+ <Description><![CDATA[init skipLocal local 2]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="149">
+<Message type="skip" file="tst_globaldata.cpp" line="149">
<DataTag><![CDATA[1:local 2]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipLocal local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipLocal local 2]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skipSingle">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init skipSingle local 1 ]]></Description>
+ <Description><![CDATA[init skipSingle local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[global: false local: false ]]></Description>
+ <Description><![CDATA[global: false local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init skipSingle local 2 ]]></Description>
+ <Description><![CDATA[init skipSingle local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[global: false local: true ]]></Description>
+ <Description><![CDATA[global: false local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[init skipSingle local 1 ]]></Description>
+ <Description><![CDATA[init skipSingle local 1]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="143">
+<Message type="skip" file="tst_globaldata.cpp" line="143">
<DataTag><![CDATA[2:local 1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[init skipSingle local 2 ]]></Description>
+ <Description><![CDATA[init skipSingle local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[global: true local: true ]]></Description>
+ <Description><![CDATA[global: true local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanupTestCase cleanupTestCase (null) ]]></Description>
+ <Description><![CDATA[cleanupTestCase cleanupTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_globaldata.txt b/tests/auto/testlib/selftests/expected_globaldata.txt
index e5d9cacc9c..a7c18e765b 100644
--- a/tests/auto/testlib/selftests/expected_globaldata.txt
+++ b/tests/auto/testlib/selftests/expected_globaldata.txt
@@ -1,54 +1,54 @@
********* Start testing of tst_globaldata *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
-QDEBUG : tst_globaldata::initTestCase() initTestCase initTestCase (null)
+QDEBUG : tst_globaldata::initTestCase() initTestCase initTestCase (null)
PASS : tst_globaldata::initTestCase()
-QDEBUG : tst_globaldata::testGlobal(1:local 1) init testGlobal local 1
-QDEBUG : tst_globaldata::testGlobal(1:local 1) global: false
-QDEBUG : tst_globaldata::testGlobal(1:local 1) local: false
-QDEBUG : tst_globaldata::testGlobal(1:local 1) cleanup testGlobal local 1
+QDEBUG : tst_globaldata::testGlobal(1:local 1) init testGlobal local 1
+QDEBUG : tst_globaldata::testGlobal(1:local 1) global: false
+QDEBUG : tst_globaldata::testGlobal(1:local 1) local: false
+QDEBUG : tst_globaldata::testGlobal(1:local 1) cleanup testGlobal local 1
PASS : tst_globaldata::testGlobal(1:local 1)
-QDEBUG : tst_globaldata::testGlobal(1:local 2) init testGlobal local 2
-QDEBUG : tst_globaldata::testGlobal(1:local 2) global: false
-QDEBUG : tst_globaldata::testGlobal(1:local 2) local: true
-QDEBUG : tst_globaldata::testGlobal(1:local 2) cleanup testGlobal local 2
+QDEBUG : tst_globaldata::testGlobal(1:local 2) init testGlobal local 2
+QDEBUG : tst_globaldata::testGlobal(1:local 2) global: false
+QDEBUG : tst_globaldata::testGlobal(1:local 2) local: true
+QDEBUG : tst_globaldata::testGlobal(1:local 2) cleanup testGlobal local 2
PASS : tst_globaldata::testGlobal(1:local 2)
-QDEBUG : tst_globaldata::testGlobal(2:local 1) init testGlobal local 1
-QDEBUG : tst_globaldata::testGlobal(2:local 1) global: true
-QDEBUG : tst_globaldata::testGlobal(2:local 1) local: false
-QDEBUG : tst_globaldata::testGlobal(2:local 1) cleanup testGlobal local 1
+QDEBUG : tst_globaldata::testGlobal(2:local 1) init testGlobal local 1
+QDEBUG : tst_globaldata::testGlobal(2:local 1) global: true
+QDEBUG : tst_globaldata::testGlobal(2:local 1) local: false
+QDEBUG : tst_globaldata::testGlobal(2:local 1) cleanup testGlobal local 1
PASS : tst_globaldata::testGlobal(2:local 1)
-QDEBUG : tst_globaldata::testGlobal(2:local 2) init testGlobal local 2
-QDEBUG : tst_globaldata::testGlobal(2:local 2) global: true
-QDEBUG : tst_globaldata::testGlobal(2:local 2) local: true
-QDEBUG : tst_globaldata::testGlobal(2:local 2) cleanup testGlobal local 2
+QDEBUG : tst_globaldata::testGlobal(2:local 2) init testGlobal local 2
+QDEBUG : tst_globaldata::testGlobal(2:local 2) global: true
+QDEBUG : tst_globaldata::testGlobal(2:local 2) local: true
+QDEBUG : tst_globaldata::testGlobal(2:local 2) cleanup testGlobal local 2
PASS : tst_globaldata::testGlobal(2:local 2)
SKIP : tst_globaldata::skip(1) skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(129)]
-QDEBUG : tst_globaldata::skipLocal(1:local 1) init skipLocal local 1
+ Loc: [tst_globaldata.cpp(129)]
+QDEBUG : tst_globaldata::skipLocal(1:local 1) init skipLocal local 1
SKIP : tst_globaldata::skipLocal(1:local 1) skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(149)]
-QDEBUG : tst_globaldata::skipLocal(1:local 1) cleanup skipLocal local 1
-QDEBUG : tst_globaldata::skipLocal(1:local 2) init skipLocal local 2
+ Loc: [tst_globaldata.cpp(149)]
+QDEBUG : tst_globaldata::skipLocal(1:local 1) cleanup skipLocal local 1
+QDEBUG : tst_globaldata::skipLocal(1:local 2) init skipLocal local 2
SKIP : tst_globaldata::skipLocal(1:local 2) skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(149)]
-QDEBUG : tst_globaldata::skipLocal(1:local 2) cleanup skipLocal local 2
-QDEBUG : tst_globaldata::skipSingle(1:local 1) init skipSingle local 1
-QDEBUG : tst_globaldata::skipSingle(1:local 1) global: false local: false
-QDEBUG : tst_globaldata::skipSingle(1:local 1) cleanup skipSingle local 1
+ Loc: [tst_globaldata.cpp(149)]
+QDEBUG : tst_globaldata::skipLocal(1:local 2) cleanup skipLocal local 2
+QDEBUG : tst_globaldata::skipSingle(1:local 1) init skipSingle local 1
+QDEBUG : tst_globaldata::skipSingle(1:local 1) global: false local: false
+QDEBUG : tst_globaldata::skipSingle(1:local 1) cleanup skipSingle local 1
PASS : tst_globaldata::skipSingle(1:local 1)
-QDEBUG : tst_globaldata::skipSingle(1:local 2) init skipSingle local 2
-QDEBUG : tst_globaldata::skipSingle(1:local 2) global: false local: true
-QDEBUG : tst_globaldata::skipSingle(1:local 2) cleanup skipSingle local 2
+QDEBUG : tst_globaldata::skipSingle(1:local 2) init skipSingle local 2
+QDEBUG : tst_globaldata::skipSingle(1:local 2) global: false local: true
+QDEBUG : tst_globaldata::skipSingle(1:local 2) cleanup skipSingle local 2
PASS : tst_globaldata::skipSingle(1:local 2)
-QDEBUG : tst_globaldata::skipSingle(2:local 1) init skipSingle local 1
+QDEBUG : tst_globaldata::skipSingle(2:local 1) init skipSingle local 1
SKIP : tst_globaldata::skipSingle(2:local 1) skipping
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp(143)]
-QDEBUG : tst_globaldata::skipSingle(2:local 1) cleanup skipSingle local 1
-QDEBUG : tst_globaldata::skipSingle(2:local 2) init skipSingle local 2
-QDEBUG : tst_globaldata::skipSingle(2:local 2) global: true local: true
-QDEBUG : tst_globaldata::skipSingle(2:local 2) cleanup skipSingle local 2
+ Loc: [tst_globaldata.cpp(143)]
+QDEBUG : tst_globaldata::skipSingle(2:local 1) cleanup skipSingle local 1
+QDEBUG : tst_globaldata::skipSingle(2:local 2) init skipSingle local 2
+QDEBUG : tst_globaldata::skipSingle(2:local 2) global: true local: true
+QDEBUG : tst_globaldata::skipSingle(2:local 2) cleanup skipSingle local 2
PASS : tst_globaldata::skipSingle(2:local 2)
-QDEBUG : tst_globaldata::cleanupTestCase() cleanupTestCase cleanupTestCase (null)
+QDEBUG : tst_globaldata::cleanupTestCase() cleanupTestCase cleanupTestCase (null)
PASS : tst_globaldata::cleanupTestCase()
Totals: 9 passed, 0 failed, 4 skipped
********* Finished testing of tst_globaldata *********
diff --git a/tests/auto/testlib/selftests/expected_globaldata.xml b/tests/auto/testlib/selftests/expected_globaldata.xml
index 906e66ca68..0867619fde 100644
--- a/tests/auto/testlib/selftests/expected_globaldata.xml
+++ b/tests/auto/testlib/selftests/expected_globaldata.xml
@@ -6,183 +6,190 @@
</Environment>
<TestFunction name="initTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[initTestCase initTestCase (null) ]]></Description>
+ <Description><![CDATA[initTestCase initTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testGlobal">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init testGlobal local 1 ]]></Description>
+ <Description><![CDATA[init testGlobal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[global: false ]]></Description>
+ <Description><![CDATA[global: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[local: false ]]></Description>
+ <Description><![CDATA[local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 1 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init testGlobal local 2 ]]></Description>
+ <Description><![CDATA[init testGlobal local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[global: false ]]></Description>
+ <Description><![CDATA[global: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[local: true ]]></Description>
+ <Description><![CDATA[local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 2 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[init testGlobal local 1 ]]></Description>
+ <Description><![CDATA[init testGlobal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[global: true ]]></Description>
+ <Description><![CDATA[global: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[local: false ]]></Description>
+ <Description><![CDATA[local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 1 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[init testGlobal local 2 ]]></Description>
+ <Description><![CDATA[init testGlobal local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[global: true ]]></Description>
+ <Description><![CDATA[global: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[local: true ]]></Description>
+ <Description><![CDATA[local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[cleanup testGlobal local 2 ]]></Description>
+ <Description><![CDATA[cleanup testGlobal local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="129">
+<Message type="skip" file="tst_globaldata.cpp" line="129">
<DataTag><![CDATA[1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skipLocal">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init skipLocal local 1 ]]></Description>
+ <Description><![CDATA[init skipLocal local 1]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="149">
+<Message type="skip" file="tst_globaldata.cpp" line="149">
<DataTag><![CDATA[1:local 1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipLocal local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipLocal local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init skipLocal local 2 ]]></Description>
+ <Description><![CDATA[init skipLocal local 2]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="149">
+<Message type="skip" file="tst_globaldata.cpp" line="149">
<DataTag><![CDATA[1:local 2]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipLocal local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipLocal local 2]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="skipSingle">
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[init skipSingle local 1 ]]></Description>
+ <Description><![CDATA[init skipSingle local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[global: false local: false ]]></Description>
+ <Description><![CDATA[global: false local: false]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[init skipSingle local 2 ]]></Description>
+ <Description><![CDATA[init skipSingle local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[global: false local: true ]]></Description>
+ <Description><![CDATA[global: false local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[1:local 2]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[init skipSingle local 1 ]]></Description>
+ <Description><![CDATA[init skipSingle local 1]]></Description>
</Message>
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/globaldata/tst_globaldata.cpp" line="143">
+<Message type="skip" file="tst_globaldata.cpp" line="143">
<DataTag><![CDATA[2:local 1]]></DataTag>
<Description><![CDATA[skipping]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 1]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 1 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[init skipSingle local 2 ]]></Description>
+ <Description><![CDATA[init skipSingle local 2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[global: true local: true ]]></Description>
+ <Description><![CDATA[global: true local: true]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
- <Description><![CDATA[cleanup skipSingle local 2 ]]></Description>
+ <Description><![CDATA[cleanup skipSingle local 2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[2:local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanupTestCase cleanupTestCase (null) ]]></Description>
+ <Description><![CDATA[cleanupTestCase cleanupTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_globaldata.xunitxml b/tests/auto/testlib/selftests/expected_globaldata.xunitxml
index 9e0cd149dc..e8cd03a59c 100644
--- a/tests/auto/testlib/selftests/expected_globaldata.xunitxml
+++ b/tests/auto/testlib/selftests/expected_globaldata.xunitxml
@@ -5,91 +5,91 @@
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
</properties>
<testcase result="pass" name="initTestCase">
- <!-- message="initTestCase initTestCase (null) " type="qdebug" -->
+ <!-- message="initTestCase initTestCase (null)" type="qdebug" -->
</testcase>
<testcase result="pass" name="testGlobal">
- <!-- tag="1:local 1" message="init testGlobal local 1 " type="qdebug" -->
- <!-- tag="1:local 1" message="global: false " type="qdebug" -->
- <!-- tag="1:local 1" message="local: false " type="qdebug" -->
- <!-- tag="1:local 1" message="cleanup testGlobal local 1 " type="qdebug" -->
- <!-- tag="1:local 2" message="init testGlobal local 2 " type="qdebug" -->
- <!-- tag="1:local 2" message="global: false " type="qdebug" -->
- <!-- tag="1:local 2" message="local: true " type="qdebug" -->
- <!-- tag="1:local 2" message="cleanup testGlobal local 2 " type="qdebug" -->
- <!-- tag="2:local 1" message="init testGlobal local 1 " type="qdebug" -->
- <!-- tag="2:local 1" message="global: true " type="qdebug" -->
- <!-- tag="2:local 1" message="local: false " type="qdebug" -->
- <!-- tag="2:local 1" message="cleanup testGlobal local 1 " type="qdebug" -->
- <!-- tag="2:local 2" message="init testGlobal local 2 " type="qdebug" -->
- <!-- tag="2:local 2" message="global: true " type="qdebug" -->
- <!-- tag="2:local 2" message="local: true " type="qdebug" -->
- <!-- tag="2:local 2" message="cleanup testGlobal local 2 " type="qdebug" -->
+ <!-- tag="1:local 1" message="init testGlobal local 1" type="qdebug" -->
+ <!-- tag="1:local 1" message="global: false" type="qdebug" -->
+ <!-- tag="1:local 1" message="local: false" type="qdebug" -->
+ <!-- tag="1:local 1" message="cleanup testGlobal local 1" type="qdebug" -->
+ <!-- tag="1:local 2" message="init testGlobal local 2" type="qdebug" -->
+ <!-- tag="1:local 2" message="global: false" type="qdebug" -->
+ <!-- tag="1:local 2" message="local: true" type="qdebug" -->
+ <!-- tag="1:local 2" message="cleanup testGlobal local 2" type="qdebug" -->
+ <!-- tag="2:local 1" message="init testGlobal local 1" type="qdebug" -->
+ <!-- tag="2:local 1" message="global: true" type="qdebug" -->
+ <!-- tag="2:local 1" message="local: false" type="qdebug" -->
+ <!-- tag="2:local 1" message="cleanup testGlobal local 1" type="qdebug" -->
+ <!-- tag="2:local 2" message="init testGlobal local 2" type="qdebug" -->
+ <!-- tag="2:local 2" message="global: true" type="qdebug" -->
+ <!-- tag="2:local 2" message="local: true" type="qdebug" -->
+ <!-- tag="2:local 2" message="cleanup testGlobal local 2" type="qdebug" -->
</testcase>
<testcase name="skip">
<!-- tag="1" message="skipping" type="skip" -->
</testcase>
<testcase name="skipLocal">
- <!-- tag="1:local 1" message="init skipLocal local 1 " type="qdebug" -->
+ <!-- tag="1:local 1" message="init skipLocal local 1" type="qdebug" -->
<!-- tag="1:local 1" message="skipping" type="skip" -->
- <!-- tag="1:local 1" message="cleanup skipLocal local 1 " type="qdebug" -->
- <!-- tag="1:local 2" message="init skipLocal local 2 " type="qdebug" -->
+ <!-- tag="1:local 1" message="cleanup skipLocal local 1" type="qdebug" -->
+ <!-- tag="1:local 2" message="init skipLocal local 2" type="qdebug" -->
<!-- tag="1:local 2" message="skipping" type="skip" -->
- <!-- tag="1:local 2" message="cleanup skipLocal local 2 " type="qdebug" -->
+ <!-- tag="1:local 2" message="cleanup skipLocal local 2" type="qdebug" -->
</testcase>
<testcase result="pass" name="skipSingle">
- <!-- tag="1:local 1" message="init skipSingle local 1 " type="qdebug" -->
- <!-- tag="1:local 1" message="global: false local: false " type="qdebug" -->
- <!-- tag="1:local 1" message="cleanup skipSingle local 1 " type="qdebug" -->
- <!-- tag="1:local 2" message="init skipSingle local 2 " type="qdebug" -->
- <!-- tag="1:local 2" message="global: false local: true " type="qdebug" -->
- <!-- tag="1:local 2" message="cleanup skipSingle local 2 " type="qdebug" -->
- <!-- tag="2:local 1" message="init skipSingle local 1 " type="qdebug" -->
+ <!-- tag="1:local 1" message="init skipSingle local 1" type="qdebug" -->
+ <!-- tag="1:local 1" message="global: false local: false" type="qdebug" -->
+ <!-- tag="1:local 1" message="cleanup skipSingle local 1" type="qdebug" -->
+ <!-- tag="1:local 2" message="init skipSingle local 2" type="qdebug" -->
+ <!-- tag="1:local 2" message="global: false local: true" type="qdebug" -->
+ <!-- tag="1:local 2" message="cleanup skipSingle local 2" type="qdebug" -->
+ <!-- tag="2:local 1" message="init skipSingle local 1" type="qdebug" -->
<!-- tag="2:local 1" message="skipping" type="skip" -->
- <!-- tag="2:local 1" message="cleanup skipSingle local 1 " type="qdebug" -->
- <!-- tag="2:local 2" message="init skipSingle local 2 " type="qdebug" -->
- <!-- tag="2:local 2" message="global: true local: true " type="qdebug" -->
- <!-- tag="2:local 2" message="cleanup skipSingle local 2 " type="qdebug" -->
+ <!-- tag="2:local 1" message="cleanup skipSingle local 1" type="qdebug" -->
+ <!-- tag="2:local 2" message="init skipSingle local 2" type="qdebug" -->
+ <!-- tag="2:local 2" message="global: true local: true" type="qdebug" -->
+ <!-- tag="2:local 2" message="cleanup skipSingle local 2" type="qdebug" -->
</testcase>
<testcase result="pass" name="cleanupTestCase">
- <!-- message="cleanupTestCase cleanupTestCase (null) " type="qdebug" -->
+ <!-- message="cleanupTestCase cleanupTestCase (null)" type="qdebug" -->
</testcase>
<system-err>
-<![CDATA[initTestCase initTestCase (null) ]]>
-<![CDATA[init testGlobal local 1 ]]>
-<![CDATA[global: false ]]>
-<![CDATA[local: false ]]>
-<![CDATA[cleanup testGlobal local 1 ]]>
-<![CDATA[init testGlobal local 2 ]]>
-<![CDATA[global: false ]]>
-<![CDATA[local: true ]]>
-<![CDATA[cleanup testGlobal local 2 ]]>
-<![CDATA[init testGlobal local 1 ]]>
-<![CDATA[global: true ]]>
-<![CDATA[local: false ]]>
-<![CDATA[cleanup testGlobal local 1 ]]>
-<![CDATA[init testGlobal local 2 ]]>
-<![CDATA[global: true ]]>
-<![CDATA[local: true ]]>
-<![CDATA[cleanup testGlobal local 2 ]]>
+<![CDATA[initTestCase initTestCase (null)]]>
+<![CDATA[init testGlobal local 1]]>
+<![CDATA[global: false]]>
+<![CDATA[local: false]]>
+<![CDATA[cleanup testGlobal local 1]]>
+<![CDATA[init testGlobal local 2]]>
+<![CDATA[global: false]]>
+<![CDATA[local: true]]>
+<![CDATA[cleanup testGlobal local 2]]>
+<![CDATA[init testGlobal local 1]]>
+<![CDATA[global: true]]>
+<![CDATA[local: false]]>
+<![CDATA[cleanup testGlobal local 1]]>
+<![CDATA[init testGlobal local 2]]>
+<![CDATA[global: true]]>
+<![CDATA[local: true]]>
+<![CDATA[cleanup testGlobal local 2]]>
<![CDATA[skipping]]>
-<![CDATA[init skipLocal local 1 ]]>
+<![CDATA[init skipLocal local 1]]>
<![CDATA[skipping]]>
-<![CDATA[cleanup skipLocal local 1 ]]>
-<![CDATA[init skipLocal local 2 ]]>
+<![CDATA[cleanup skipLocal local 1]]>
+<![CDATA[init skipLocal local 2]]>
<![CDATA[skipping]]>
-<![CDATA[cleanup skipLocal local 2 ]]>
-<![CDATA[init skipSingle local 1 ]]>
-<![CDATA[global: false local: false ]]>
-<![CDATA[cleanup skipSingle local 1 ]]>
-<![CDATA[init skipSingle local 2 ]]>
-<![CDATA[global: false local: true ]]>
-<![CDATA[cleanup skipSingle local 2 ]]>
-<![CDATA[init skipSingle local 1 ]]>
+<![CDATA[cleanup skipLocal local 2]]>
+<![CDATA[init skipSingle local 1]]>
+<![CDATA[global: false local: false]]>
+<![CDATA[cleanup skipSingle local 1]]>
+<![CDATA[init skipSingle local 2]]>
+<![CDATA[global: false local: true]]>
+<![CDATA[cleanup skipSingle local 2]]>
+<![CDATA[init skipSingle local 1]]>
<![CDATA[skipping]]>
-<![CDATA[cleanup skipSingle local 1 ]]>
-<![CDATA[init skipSingle local 2 ]]>
-<![CDATA[global: true local: true ]]>
-<![CDATA[cleanup skipSingle local 2 ]]>
-<![CDATA[cleanupTestCase cleanupTestCase (null) ]]>
+<![CDATA[cleanup skipSingle local 1]]>
+<![CDATA[init skipSingle local 2]]>
+<![CDATA[global: true local: true]]>
+<![CDATA[cleanup skipSingle local 2]]>
+<![CDATA[cleanupTestCase cleanupTestCase (null)]]>
</system-err>
</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_longstring.lightxml b/tests/auto/testlib/selftests/expected_longstring.lightxml
index 80c528e0d7..45c6d3f78d 100644
--- a/tests/auto/testlib/selftests/expected_longstring.lightxml
+++ b/tests/auto/testlib/selftests/expected_longstring.lightxml
@@ -4,9 +4,10 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failWithLongString">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/longstring/tst_longstring.cpp" line="67">
+<Incident type="fail" file="tst_longstring.cpp" line="67">
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.
Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.
@@ -17,7 +18,10 @@ Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. M
Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_longstring.txt b/tests/auto/testlib/selftests/expected_longstring.txt
index b367e64959..364c8cf4a7 100644
--- a/tests/auto/testlib/selftests/expected_longstring.txt
+++ b/tests/auto/testlib/selftests/expected_longstring.txt
@@ -10,7 +10,7 @@ Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, impe
Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis.
Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/longstring/tst_longstring.cpp(67)]
+ Loc: [tst_longstring.cpp(67)]
PASS : tst_LongString::cleanupTestCase()
Totals: 2 passed, 1 failed, 0 skipped
********* Finished testing of tst_LongString *********
diff --git a/tests/auto/testlib/selftests/expected_longstring.xml b/tests/auto/testlib/selftests/expected_longstring.xml
index b3d1c5c846..efc29d6def 100644
--- a/tests/auto/testlib/selftests/expected_longstring.xml
+++ b/tests/auto/testlib/selftests/expected_longstring.xml
@@ -6,9 +6,10 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failWithLongString">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/longstring/tst_longstring.cpp" line="67">
+<Incident type="fail" file="tst_longstring.cpp" line="67">
<Description><![CDATA[Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.
Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia.
@@ -19,8 +20,11 @@ Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. M
Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_maxwarnings.lightxml b/tests/auto/testlib/selftests/expected_maxwarnings.lightxml
index 054108fe6d..ce6d828eb2 100644
--- a/tests/auto/testlib/selftests/expected_maxwarnings.lightxml
+++ b/tests/auto/testlib/selftests/expected_maxwarnings.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="warn">
<Message type="qwarn" file="" line="0">
@@ -6013,7 +6014,10 @@
<Description><![CDATA[Maximum amount of warnings exceeded. Use -maxwarnings to override.]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_maxwarnings.xml b/tests/auto/testlib/selftests/expected_maxwarnings.xml
index d5845ebf1d..758af9d6d5 100644
--- a/tests/auto/testlib/selftests/expected_maxwarnings.xml
+++ b/tests/auto/testlib/selftests/expected_maxwarnings.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="warn">
<Message type="qwarn" file="" line="0">
@@ -6015,8 +6016,11 @@
<Description><![CDATA[Maximum amount of warnings exceeded. Use -maxwarnings to override.]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_silent.txt b/tests/auto/testlib/selftests/expected_silent.txt
index 39e0bfc601..5d4c77bffd 100644
--- a/tests/auto/testlib/selftests/expected_silent.txt
+++ b/tests/auto/testlib/selftests/expected_silent.txt
@@ -1,8 +1,8 @@
Testing tst_Silent
FAIL! : tst_Silent::fail() 'false' returned FALSE. (This test should fail)
- Loc: [/home/jasmcdon/depot/qt5-test/qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp(73)]
+ Loc: [tst_silent.cpp(73)]
XPASS : tst_Silent::xpass() 'true' returned TRUE unexpectedly. (This test should XPASS)
- Loc: [/home/jasmcdon/depot/qt5-test/qtbase/tests/auto/testlib/selftests/silent/tst_silent.cpp(85)]
+ Loc: [tst_silent.cpp(85)]
QFATAL : tst_Silent::messages() This is a fatal error message that should still appear in silent test output
FAIL! : tst_Silent::messages() Received a fatal error.
Loc: [Unknown file(0)]
diff --git a/tests/auto/testlib/selftests/expected_singleskip.lightxml b/tests/auto/testlib/selftests/expected_singleskip.lightxml
index b49b624ffe..685396a243 100644
--- a/tests/auto/testlib/selftests/expected_singleskip.lightxml
+++ b/tests/auto/testlib/selftests/expected_singleskip.lightxml
@@ -4,12 +4,16 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="myTest">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/singleskip/tst_singleskip.cpp" line="56">
+<Message type="skip" file="tst_singleskip.cpp" line="56">
<Description><![CDATA[skipping test]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_singleskip.txt b/tests/auto/testlib/selftests/expected_singleskip.txt
index 46b40e5791..ba5415a216 100644
--- a/tests/auto/testlib/selftests/expected_singleskip.txt
+++ b/tests/auto/testlib/selftests/expected_singleskip.txt
@@ -2,7 +2,7 @@
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_SingleSkip::initTestCase()
SKIP : tst_SingleSkip::myTest() skipping test
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/singleskip/tst_singleskip.cpp(56)]
+ Loc: [tst_singleskip.cpp(56)]
PASS : tst_SingleSkip::cleanupTestCase()
Totals: 2 passed, 0 failed, 1 skipped
********* Finished testing of tst_SingleSkip *********
diff --git a/tests/auto/testlib/selftests/expected_singleskip.xml b/tests/auto/testlib/selftests/expected_singleskip.xml
index 393344b478..c10626ca41 100644
--- a/tests/auto/testlib/selftests/expected_singleskip.xml
+++ b/tests/auto/testlib/selftests/expected_singleskip.xml
@@ -6,13 +6,17 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="myTest">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/singleskip/tst_singleskip.cpp" line="56">
+<Message type="skip" file="tst_singleskip.cpp" line="56">
<Description><![CDATA[skipping test]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_skip.lightxml b/tests/auto/testlib/selftests/expected_skip.lightxml
index b01570e275..408bc44871 100644
--- a/tests/auto/testlib/selftests/expected_skip.lightxml
+++ b/tests/auto/testlib/selftests/expected_skip.lightxml
@@ -4,19 +4,22 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="68">
+<Message type="skip" file="tst_skip.cpp" line="68">
<Description><![CDATA[skipping all]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="emptytest">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="78">
+<Message type="skip" file="tst_skip.cpp" line="78">
<Description><![CDATA[skipping all]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="97">
+<Message type="skip" file="tst_skip.cpp" line="97">
<DataTag><![CDATA[local 1]]></DataTag>
<Description><![CDATA[skipping one]]></Description>
</Message>
@@ -27,7 +30,10 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_skip.txt b/tests/auto/testlib/selftests/expected_skip.txt
index ef96d08d83..9a79e35de3 100644
--- a/tests/auto/testlib/selftests/expected_skip.txt
+++ b/tests/auto/testlib/selftests/expected_skip.txt
@@ -2,11 +2,11 @@
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_Skip::initTestCase()
SKIP : tst_Skip::test() skipping all
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp(68)]
+ Loc: [tst_skip.cpp(68)]
SKIP : tst_Skip::emptytest() skipping all
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp(78)]
+ Loc: [tst_skip.cpp(78)]
SKIP : tst_Skip::singleSkip(local 1) skipping one
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp(97)]
+ Loc: [tst_skip.cpp(97)]
QDEBUG : tst_Skip::singleSkip(local 2) this line should only be reached once (true)
PASS : tst_Skip::singleSkip(local 2)
PASS : tst_Skip::cleanupTestCase()
diff --git a/tests/auto/testlib/selftests/expected_skip.xml b/tests/auto/testlib/selftests/expected_skip.xml
index 0f010860d4..b220722b6c 100644
--- a/tests/auto/testlib/selftests/expected_skip.xml
+++ b/tests/auto/testlib/selftests/expected_skip.xml
@@ -6,19 +6,22 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="68">
+<Message type="skip" file="tst_skip.cpp" line="68">
<Description><![CDATA[skipping all]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="emptytest">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="78">
+<Message type="skip" file="tst_skip.cpp" line="78">
<Description><![CDATA[skipping all]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="singleSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skip/tst_skip.cpp" line="97">
+<Message type="skip" file="tst_skip.cpp" line="97">
<DataTag><![CDATA[local 1]]></DataTag>
<Description><![CDATA[skipping one]]></Description>
</Message>
@@ -29,8 +32,11 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[local 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.lightxml b/tests/auto/testlib/selftests/expected_skipcleanup.lightxml
index d2bc3b766e..49c9d148f5 100644
--- a/tests/auto/testlib/selftests/expected_skipcleanup.lightxml
+++ b/tests/auto/testlib/selftests/expected_skipcleanup.lightxml
@@ -4,12 +4,16 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="aTestFunction">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp" line="59">
+<Message type="skip" file="tst_skipcleanup.cpp" line="59">
<Description><![CDATA[Skip inside cleanupTestCase.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.txt b/tests/auto/testlib/selftests/expected_skipcleanup.txt
index 52845c355e..35c5d3dccb 100644
--- a/tests/auto/testlib/selftests/expected_skipcleanup.txt
+++ b/tests/auto/testlib/selftests/expected_skipcleanup.txt
@@ -3,6 +3,6 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_SkipCleanup::initTestCase()
PASS : tst_SkipCleanup::aTestFunction()
SKIP : tst_SkipCleanup::cleanupTestCase() Skip inside cleanupTestCase.
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp(59)]
+ Loc: [tst_skipcleanup.cpp(59)]
Totals: 2 passed, 0 failed, 1 skipped
********* Finished testing of tst_SkipCleanup *********
diff --git a/tests/auto/testlib/selftests/expected_skipcleanup.xml b/tests/auto/testlib/selftests/expected_skipcleanup.xml
index e6c5d85783..0bf1fe53a3 100644
--- a/tests/auto/testlib/selftests/expected_skipcleanup.xml
+++ b/tests/auto/testlib/selftests/expected_skipcleanup.xml
@@ -6,13 +6,17 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="aTestFunction">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipcleanup/tst_skipcleanup.cpp" line="59">
+<Message type="skip" file="tst_skipcleanup.cpp" line="59">
<Description><![CDATA[Skip inside cleanupTestCase.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_skipinit.lightxml b/tests/auto/testlib/selftests/expected_skipinit.lightxml
index b5a73d614a..e06c745205 100644
--- a/tests/auto/testlib/selftests/expected_skipinit.lightxml
+++ b/tests/auto/testlib/selftests/expected_skipinit.lightxml
@@ -3,10 +3,13 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinit/tst_skipinit.cpp" line="55">
+<Message type="skip" file="tst_skipinit.cpp" line="55">
<Description><![CDATA[Skip inside initTestCase. This should skip all tests in the class.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_skipinit.txt b/tests/auto/testlib/selftests/expected_skipinit.txt
index dcd0322e9d..f3de6cd2df 100644
--- a/tests/auto/testlib/selftests/expected_skipinit.txt
+++ b/tests/auto/testlib/selftests/expected_skipinit.txt
@@ -1,7 +1,7 @@
********* Start testing of tst_SkipInit *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
SKIP : tst_SkipInit::initTestCase() Skip inside initTestCase. This should skip all tests in the class.
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinit/tst_skipinit.cpp(55)]
+ Loc: [tst_skipinit.cpp(55)]
PASS : tst_SkipInit::cleanupTestCase()
Totals: 1 passed, 0 failed, 1 skipped
********* Finished testing of tst_SkipInit *********
diff --git a/tests/auto/testlib/selftests/expected_skipinit.xml b/tests/auto/testlib/selftests/expected_skipinit.xml
index bc6b7d12f8..6a62b93614 100644
--- a/tests/auto/testlib/selftests/expected_skipinit.xml
+++ b/tests/auto/testlib/selftests/expected_skipinit.xml
@@ -5,11 +5,14 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinit/tst_skipinit.cpp" line="55">
+<Message type="skip" file="tst_skipinit.cpp" line="55">
<Description><![CDATA[Skip inside initTestCase. This should skip all tests in the class.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_skipinitdata.lightxml b/tests/auto/testlib/selftests/expected_skipinitdata.lightxml
index cd820240fd..41abd5dccd 100644
--- a/tests/auto/testlib/selftests/expected_skipinitdata.lightxml
+++ b/tests/auto/testlib/selftests/expected_skipinitdata.lightxml
@@ -3,7 +3,9 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinitdata/tst_skipinitdata.cpp" line="56">
+<Message type="skip" file="tst_skipinitdata.cpp" line="56">
<Description><![CDATA[Skip inside initTestCase_data. This should skip all tests in the class.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_skipinitdata.txt b/tests/auto/testlib/selftests/expected_skipinitdata.txt
index 1010f97689..912ab8cd6d 100644
--- a/tests/auto/testlib/selftests/expected_skipinitdata.txt
+++ b/tests/auto/testlib/selftests/expected_skipinitdata.txt
@@ -1,6 +1,6 @@
********* Start testing of tst_SkipInitData *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
SKIP : tst_SkipInitData::initTestCase() Skip inside initTestCase_data. This should skip all tests in the class.
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinitdata/tst_skipinitdata.cpp(56)]
+ Loc: [tst_skipinitdata.cpp(56)]
Totals: 0 passed, 0 failed, 1 skipped
********* Finished testing of tst_SkipInitData *********
diff --git a/tests/auto/testlib/selftests/expected_skipinitdata.xml b/tests/auto/testlib/selftests/expected_skipinitdata.xml
index eb42569598..8efe12195e 100644
--- a/tests/auto/testlib/selftests/expected_skipinitdata.xml
+++ b/tests/auto/testlib/selftests/expected_skipinitdata.xml
@@ -5,8 +5,10 @@
<QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
</Environment>
<TestFunction name="initTestCase">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/skipinitdata/tst_skipinitdata.cpp" line="56">
+<Message type="skip" file="tst_skipinitdata.cpp" line="56">
<Description><![CDATA[Skip inside initTestCase_data. This should skip all tests in the class.]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_strcmp.lightxml b/tests/auto/testlib/selftests/expected_strcmp.lightxml
index 4c30c9f801..f0d266d400 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.lightxml
+++ b/tests/auto/testlib/selftests/expected_strcmp.lightxml
@@ -4,54 +4,63 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareCharStars">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareByteArray">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="88">
+<Incident type="xfail" file="tst_strcmp.cpp" line="88">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="95">
+<Incident type="xfail" file="tst_strcmp.cpp" line="95">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="102">
+<Incident type="xfail" file="tst_strcmp.cpp" line="102">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="109">
+<Incident type="fail" file="tst_strcmp.cpp" line="109">
<Description><![CDATA[Compared values are not the same
Actual (a): 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 ...
Expected (b): 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ...]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArray">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="115">
+<Incident type="fail" file="tst_strcmp.cpp" line="115">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("abc")): 61 62 63
Expected (QByteArray("cba")): 63 62 61]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayNull">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121">
+<Incident type="fail" file="tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
Expected (QByteArray()) : ]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126">
+<Incident type="fail" file="tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArraySingleChars">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="133">
+<Incident type="fail" file="tst_strcmp.cpp" line="133">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("6")): 36
Expected (QByteArray("7")): 37]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_strcmp.txt b/tests/auto/testlib/selftests/expected_strcmp.txt
index f3ad169fb7..4bd3844d08 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.txt
+++ b/tests/auto/testlib/selftests/expected_strcmp.txt
@@ -3,31 +3,31 @@ Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HER
PASS : tst_StrCmp::initTestCase()
PASS : tst_StrCmp::compareCharStars()
XFAIL : tst_StrCmp::compareByteArray() Next test should fail
- Loc: [./tst_strcmp.cpp(55)]
+ Loc: [tst_strcmp.cpp(88)]
XFAIL : tst_StrCmp::compareByteArray() Next test should fail
- Loc: [./tst_strcmp.cpp(62)]
+ Loc: [tst_strcmp.cpp(95)]
XFAIL : tst_StrCmp::compareByteArray() Next test should fail
- Loc: [./tst_strcmp.cpp(69)]
+ Loc: [tst_strcmp.cpp(102)]
FAIL! : tst_StrCmp::compareByteArray() Compared values are not the same
Actual (a): 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 ...
Expected (b): 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ...
- Loc: [./tst_strcmp.cpp(76)]
+ Loc: [tst_strcmp.cpp(109)]
FAIL! : tst_StrCmp::failByteArray() Compared values are not the same
Actual (QByteArray("abc")): 61 62 63
Expected (QByteArray("cba")): 63 62 61
- Loc: [./tst_strcmp.cpp(82)]
+ Loc: [tst_strcmp.cpp(115)]
FAIL! : tst_StrCmp::failByteArrayNull() Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
Expected (QByteArray()) :
- Loc: [./tst_strcmp.cpp(88)]
+ Loc: [tst_strcmp.cpp(121)]
FAIL! : tst_StrCmp::failByteArrayEmpty() Compared values are not the same
Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F
- Loc: [./tst_strcmp.cpp(93)]
+ Loc: [tst_strcmp.cpp(126)]
FAIL! : tst_StrCmp::failByteArraySingleChars() Compared values are not the same
Actual (QByteArray("6")): 36
Expected (QByteArray("7")): 37
- Loc: [./tst_strcmp.cpp(100)]
+ Loc: [tst_strcmp.cpp(133)]
PASS : tst_StrCmp::cleanupTestCase()
Totals: 3 passed, 5 failed, 0 skipped
********* Finished testing of tst_StrCmp *********
diff --git a/tests/auto/testlib/selftests/expected_strcmp.xml b/tests/auto/testlib/selftests/expected_strcmp.xml
index db9ed34bb8..20ffee0611 100644
--- a/tests/auto/testlib/selftests/expected_strcmp.xml
+++ b/tests/auto/testlib/selftests/expected_strcmp.xml
@@ -6,55 +6,64 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareCharStars">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="compareByteArray">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="88">
+<Incident type="xfail" file="tst_strcmp.cpp" line="88">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="95">
+<Incident type="xfail" file="tst_strcmp.cpp" line="95">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="102">
+<Incident type="xfail" file="tst_strcmp.cpp" line="102">
<Description><![CDATA[Next test should fail]]></Description>
</Incident>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="109">
+<Incident type="fail" file="tst_strcmp.cpp" line="109">
<Description><![CDATA[Compared values are not the same
Actual (a): 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 42 ...
Expected (b): 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 ...]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArray">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="115">
+<Incident type="fail" file="tst_strcmp.cpp" line="115">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("abc")): 61 62 63
Expected (QByteArray("cba")): 63 62 61]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayNull">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="121">
+<Incident type="fail" file="tst_strcmp.cpp" line="121">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("foo")): 66 6F 6F
Expected (QByteArray()) : ]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArrayEmpty">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="126">
+<Incident type="fail" file="tst_strcmp.cpp" line="126">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("")) :
Expected (QByteArray("foo")): 66 6F 6F]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="failByteArraySingleChars">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/strcmp/tst_strcmp.cpp" line="133">
+<Incident type="fail" file="tst_strcmp.cpp" line="133">
<Description><![CDATA[Compared values are not the same
Actual (QByteArray("6")): 36
Expected (QByteArray("7")): 37]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_subtest.lightxml b/tests/auto/testlib/selftests/expected_subtest.lightxml
index 5adbb771af..467fabb7ac 100644
--- a/tests/auto/testlib/selftests/expected_subtest.lightxml
+++ b/tests/auto/testlib/selftests/expected_subtest.lightxml
@@ -4,153 +4,159 @@
</Environment>
<TestFunction name="initTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[initTestCase initTestCase (null) ]]></Description>
+ <Description><![CDATA[initTestCase initTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test1">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[init test1 (null) ]]></Description>
+ <Description><![CDATA[init test1 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test1 test1 (null) ]]></Description>
+ <Description><![CDATA[test1 test1 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanup test1 (null) ]]></Description>
+ <Description><![CDATA[cleanup test1 (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test2">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test2_data test2 (null) ]]></Description>
+ <Description><![CDATA[test2_data test2 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test2_data end ]]></Description>
+ <Description><![CDATA[test2_data end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[init test2 data0 ]]></Description>
+ <Description><![CDATA[init test2 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 test2 data0 ]]></Description>
+ <Description><![CDATA[test2 test2 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[cleanup test2 data0 ]]></Description>
+ <Description><![CDATA[cleanup test2 data0]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[init test2 data1 ]]></Description>
+ <Description><![CDATA[init test2 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 test2 data1 ]]></Description>
+ <Description><![CDATA[test2 test2 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[cleanup test2 data1 ]]></Description>
+ <Description><![CDATA[cleanup test2 data1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[init test2 data2 ]]></Description>
+ <Description><![CDATA[init test2 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 test2 data2 ]]></Description>
+ <Description><![CDATA[test2 test2 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[cleanup test2 data2 ]]></Description>
+ <Description><![CDATA[cleanup test2 data2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test3">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test3_data test3 (null) ]]></Description>
+ <Description><![CDATA[test3_data test3 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test3_data end ]]></Description>
+ <Description><![CDATA[test3_data end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[init test3 data0 ]]></Description>
+ <Description><![CDATA[init test3 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 test3 data0 ]]></Description>
+ <Description><![CDATA[test2 test3 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[cleanup test3 data0 ]]></Description>
+ <Description><![CDATA[cleanup test3 data0]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[init test3 data1 ]]></Description>
+ <Description><![CDATA[init test3 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 test3 data1 ]]></Description>
+ <Description><![CDATA[test2 test3 data1]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
+<Incident type="fail" file="tst_subtest.cpp" line="154">
<DataTag><![CDATA[data1]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str) : hello1
- Expected (QString("hello0")): hello0]]></Description>
+ Actual (str) : "hello1"
+ Expected (QString("hello0")): "hello0"]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[cleanup test3 data1 ]]></Description>
+ <Description><![CDATA[cleanup test3 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[init test3 data2 ]]></Description>
+ <Description><![CDATA[init test3 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 test3 data2 ]]></Description>
+ <Description><![CDATA[test2 test3 data2]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
+<Incident type="fail" file="tst_subtest.cpp" line="154">
<DataTag><![CDATA[data2]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str) : hello2
- Expected (QString("hello0")): hello0]]></Description>
+ Actual (str) : "hello2"
+ Expected (QString("hello0")): "hello0"]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[cleanup test3 data2 ]]></Description>
+ <Description><![CDATA[cleanup test3 data2]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanupTestCase cleanupTestCase (null) ]]></Description>
+ <Description><![CDATA[cleanupTestCase cleanupTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_subtest.txt b/tests/auto/testlib/selftests/expected_subtest.txt
index bb88f189ec..9990b5439d 100644
--- a/tests/auto/testlib/selftests/expected_subtest.txt
+++ b/tests/auto/testlib/selftests/expected_subtest.txt
@@ -1,50 +1,50 @@
********* Start testing of tst_Subtest *********
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
-QDEBUG : tst_Subtest::initTestCase() initTestCase initTestCase (null)
+QDEBUG : tst_Subtest::initTestCase() initTestCase initTestCase (null)
PASS : tst_Subtest::initTestCase()
-QDEBUG : tst_Subtest::test1() init test1 (null)
-QDEBUG : tst_Subtest::test1() test1 test1 (null)
-QDEBUG : tst_Subtest::test1() cleanup test1 (null)
+QDEBUG : tst_Subtest::test1() init test1 (null)
+QDEBUG : tst_Subtest::test1() test1 test1 (null)
+QDEBUG : tst_Subtest::test1() cleanup test1 (null)
PASS : tst_Subtest::test1()
-QDEBUG : tst_Subtest::test2() test2_data test2 (null)
-QDEBUG : tst_Subtest::test2() test2_data end
-QDEBUG : tst_Subtest::test2(data0) init test2 data0
-QDEBUG : tst_Subtest::test2(data0) test2 test2 data0
-QDEBUG : tst_Subtest::test2(data0) test2 end
-QDEBUG : tst_Subtest::test2(data0) cleanup test2 data0
+QDEBUG : tst_Subtest::test2() test2_data test2 (null)
+QDEBUG : tst_Subtest::test2() test2_data end
+QDEBUG : tst_Subtest::test2(data0) init test2 data0
+QDEBUG : tst_Subtest::test2(data0) test2 test2 data0
+QDEBUG : tst_Subtest::test2(data0) test2 end
+QDEBUG : tst_Subtest::test2(data0) cleanup test2 data0
PASS : tst_Subtest::test2(data0)
-QDEBUG : tst_Subtest::test2(data1) init test2 data1
-QDEBUG : tst_Subtest::test2(data1) test2 test2 data1
-QDEBUG : tst_Subtest::test2(data1) test2 end
-QDEBUG : tst_Subtest::test2(data1) cleanup test2 data1
+QDEBUG : tst_Subtest::test2(data1) init test2 data1
+QDEBUG : tst_Subtest::test2(data1) test2 test2 data1
+QDEBUG : tst_Subtest::test2(data1) test2 end
+QDEBUG : tst_Subtest::test2(data1) cleanup test2 data1
PASS : tst_Subtest::test2(data1)
-QDEBUG : tst_Subtest::test2(data2) init test2 data2
-QDEBUG : tst_Subtest::test2(data2) test2 test2 data2
-QDEBUG : tst_Subtest::test2(data2) test2 end
-QDEBUG : tst_Subtest::test2(data2) cleanup test2 data2
+QDEBUG : tst_Subtest::test2(data2) init test2 data2
+QDEBUG : tst_Subtest::test2(data2) test2 test2 data2
+QDEBUG : tst_Subtest::test2(data2) test2 end
+QDEBUG : tst_Subtest::test2(data2) cleanup test2 data2
PASS : tst_Subtest::test2(data2)
-QDEBUG : tst_Subtest::test3() test3_data test3 (null)
-QDEBUG : tst_Subtest::test3() test3_data end
-QDEBUG : tst_Subtest::test3(data0) init test3 data0
-QDEBUG : tst_Subtest::test3(data0) test2 test3 data0
-QDEBUG : tst_Subtest::test3(data0) test2 end
-QDEBUG : tst_Subtest::test3(data0) cleanup test3 data0
+QDEBUG : tst_Subtest::test3() test3_data test3 (null)
+QDEBUG : tst_Subtest::test3() test3_data end
+QDEBUG : tst_Subtest::test3(data0) init test3 data0
+QDEBUG : tst_Subtest::test3(data0) test2 test3 data0
+QDEBUG : tst_Subtest::test3(data0) test2 end
+QDEBUG : tst_Subtest::test3(data0) cleanup test3 data0
PASS : tst_Subtest::test3(data0)
-QDEBUG : tst_Subtest::test3(data1) init test3 data1
-QDEBUG : tst_Subtest::test3(data1) test2 test3 data1
+QDEBUG : tst_Subtest::test3(data1) init test3 data1
+QDEBUG : tst_Subtest::test3(data1) test2 test3 data1
FAIL! : tst_Subtest::test3(data1) Compared values are not the same
- Actual (str) : hello1
- Expected (QString("hello0")): hello0
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)]
-QDEBUG : tst_Subtest::test3(data1) cleanup test3 data1
-QDEBUG : tst_Subtest::test3(data2) init test3 data2
-QDEBUG : tst_Subtest::test3(data2) test2 test3 data2
+ Actual (str) : "hello1"
+ Expected (QString("hello0")): "hello0"
+ Loc: [tst_subtest.cpp(154)]
+QDEBUG : tst_Subtest::test3(data1) cleanup test3 data1
+QDEBUG : tst_Subtest::test3(data2) init test3 data2
+QDEBUG : tst_Subtest::test3(data2) test2 test3 data2
FAIL! : tst_Subtest::test3(data2) Compared values are not the same
- Actual (str) : hello2
- Expected (QString("hello0")): hello0
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp(154)]
-QDEBUG : tst_Subtest::test3(data2) cleanup test3 data2
-QDEBUG : tst_Subtest::cleanupTestCase() cleanupTestCase cleanupTestCase (null)
+ Actual (str) : "hello2"
+ Expected (QString("hello0")): "hello0"
+ Loc: [tst_subtest.cpp(154)]
+QDEBUG : tst_Subtest::test3(data2) cleanup test3 data2
+QDEBUG : tst_Subtest::cleanupTestCase() cleanupTestCase cleanupTestCase (null)
PASS : tst_Subtest::cleanupTestCase()
Totals: 7 passed, 2 failed, 0 skipped
********* Finished testing of tst_Subtest *********
diff --git a/tests/auto/testlib/selftests/expected_subtest.xml b/tests/auto/testlib/selftests/expected_subtest.xml
index 094e22383d..1107bcb070 100644
--- a/tests/auto/testlib/selftests/expected_subtest.xml
+++ b/tests/auto/testlib/selftests/expected_subtest.xml
@@ -6,154 +6,160 @@
</Environment>
<TestFunction name="initTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[initTestCase initTestCase (null) ]]></Description>
+ <Description><![CDATA[initTestCase initTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test1">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[init test1 (null) ]]></Description>
+ <Description><![CDATA[init test1 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test1 test1 (null) ]]></Description>
+ <Description><![CDATA[test1 test1 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanup test1 (null) ]]></Description>
+ <Description><![CDATA[cleanup test1 (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test2">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test2_data test2 (null) ]]></Description>
+ <Description><![CDATA[test2_data test2 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test2_data end ]]></Description>
+ <Description><![CDATA[test2_data end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[init test2 data0 ]]></Description>
+ <Description><![CDATA[init test2 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 test2 data0 ]]></Description>
+ <Description><![CDATA[test2 test2 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[cleanup test2 data0 ]]></Description>
+ <Description><![CDATA[cleanup test2 data0]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[init test2 data1 ]]></Description>
+ <Description><![CDATA[init test2 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 test2 data1 ]]></Description>
+ <Description><![CDATA[test2 test2 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[cleanup test2 data1 ]]></Description>
+ <Description><![CDATA[cleanup test2 data1]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[init test2 data2 ]]></Description>
+ <Description><![CDATA[init test2 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 test2 data2 ]]></Description>
+ <Description><![CDATA[test2 test2 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[cleanup test2 data2 ]]></Description>
+ <Description><![CDATA[cleanup test2 data2]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="test3">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test3_data test3 (null) ]]></Description>
+ <Description><![CDATA[test3_data test3 (null)]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[test3_data end ]]></Description>
+ <Description><![CDATA[test3_data end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[init test3 data0 ]]></Description>
+ <Description><![CDATA[init test3 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 test3 data0 ]]></Description>
+ <Description><![CDATA[test2 test3 data0]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[test2 end ]]></Description>
+ <Description><![CDATA[test2 end]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
- <Description><![CDATA[cleanup test3 data0 ]]></Description>
+ <Description><![CDATA[cleanup test3 data0]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[data0]]></DataTag>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[init test3 data1 ]]></Description>
+ <Description><![CDATA[init test3 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[test2 test3 data1 ]]></Description>
+ <Description><![CDATA[test2 test3 data1]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
+<Incident type="fail" file="tst_subtest.cpp" line="154">
<DataTag><![CDATA[data1]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str) : hello1
- Expected (QString("hello0")): hello0]]></Description>
+ Actual (str) : "hello1"
+ Expected (QString("hello0")): "hello0"]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data1]]></DataTag>
- <Description><![CDATA[cleanup test3 data1 ]]></Description>
+ <Description><![CDATA[cleanup test3 data1]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[init test3 data2 ]]></Description>
+ <Description><![CDATA[init test3 data2]]></Description>
</Message>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[test2 test3 data2 ]]></Description>
+ <Description><![CDATA[test2 test3 data2]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/subtest/tst_subtest.cpp" line="154">
+<Incident type="fail" file="tst_subtest.cpp" line="154">
<DataTag><![CDATA[data2]]></DataTag>
<Description><![CDATA[Compared values are not the same
- Actual (str) : hello2
- Expected (QString("hello0")): hello0]]></Description>
+ Actual (str) : "hello2"
+ Expected (QString("hello0")): "hello0"]]></Description>
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[data2]]></DataTag>
- <Description><![CDATA[cleanup test3 data2 ]]></Description>
+ <Description><![CDATA[cleanup test3 data2]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Message type="qdebug" file="" line="0">
- <Description><![CDATA[cleanupTestCase cleanupTestCase (null) ]]></Description>
+ <Description><![CDATA[cleanupTestCase cleanupTestCase (null)]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_subtest.xunitxml b/tests/auto/testlib/selftests/expected_subtest.xunitxml
index 6f8fc3db45..753711f837 100644
--- a/tests/auto/testlib/selftests/expected_subtest.xunitxml
+++ b/tests/auto/testlib/selftests/expected_subtest.xunitxml
@@ -5,83 +5,83 @@
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
</properties>
<testcase result="pass" name="initTestCase">
- <!-- message="initTestCase initTestCase (null) " type="qdebug" -->
+ <!-- message="initTestCase initTestCase (null)" type="qdebug" -->
</testcase>
<testcase result="pass" name="test1">
- <!-- message="init test1 (null) " type="qdebug" -->
- <!-- message="test1 test1 (null) " type="qdebug" -->
- <!-- message="cleanup test1 (null) " type="qdebug" -->
+ <!-- message="init test1 (null)" type="qdebug" -->
+ <!-- message="test1 test1 (null)" type="qdebug" -->
+ <!-- message="cleanup test1 (null)" type="qdebug" -->
</testcase>
<testcase result="pass" name="test2">
- <!-- message="test2_data test2 (null) " type="qdebug" -->
- <!-- message="test2_data end " type="qdebug" -->
- <!-- tag="data0" message="init test2 data0 " type="qdebug" -->
- <!-- tag="data0" message="test2 test2 data0 " type="qdebug" -->
- <!-- tag="data0" message="test2 end " type="qdebug" -->
- <!-- tag="data0" message="cleanup test2 data0 " type="qdebug" -->
- <!-- tag="data1" message="init test2 data1 " type="qdebug" -->
- <!-- tag="data1" message="test2 test2 data1 " type="qdebug" -->
- <!-- tag="data1" message="test2 end " type="qdebug" -->
- <!-- tag="data1" message="cleanup test2 data1 " type="qdebug" -->
- <!-- tag="data2" message="init test2 data2 " type="qdebug" -->
- <!-- tag="data2" message="test2 test2 data2 " type="qdebug" -->
- <!-- tag="data2" message="test2 end " type="qdebug" -->
- <!-- tag="data2" message="cleanup test2 data2 " type="qdebug" -->
+ <!-- message="test2_data test2 (null)" type="qdebug" -->
+ <!-- message="test2_data end" type="qdebug" -->
+ <!-- tag="data0" message="init test2 data0" type="qdebug" -->
+ <!-- tag="data0" message="test2 test2 data0" type="qdebug" -->
+ <!-- tag="data0" message="test2 end" type="qdebug" -->
+ <!-- tag="data0" message="cleanup test2 data0" type="qdebug" -->
+ <!-- tag="data1" message="init test2 data1" type="qdebug" -->
+ <!-- tag="data1" message="test2 test2 data1" type="qdebug" -->
+ <!-- tag="data1" message="test2 end" type="qdebug" -->
+ <!-- tag="data1" message="cleanup test2 data1" type="qdebug" -->
+ <!-- tag="data2" message="init test2 data2" type="qdebug" -->
+ <!-- tag="data2" message="test2 test2 data2" type="qdebug" -->
+ <!-- tag="data2" message="test2 end" type="qdebug" -->
+ <!-- tag="data2" message="cleanup test2 data2" type="qdebug" -->
</testcase>
<testcase result="fail" name="test3">
- <!-- message="test3_data test3 (null) " type="qdebug" -->
- <!-- message="test3_data end " type="qdebug" -->
- <!-- tag="data0" message="init test3 data0 " type="qdebug" -->
- <!-- tag="data0" message="test2 test3 data0 " type="qdebug" -->
- <!-- tag="data0" message="test2 end " type="qdebug" -->
- <!-- tag="data0" message="cleanup test3 data0 " type="qdebug" -->
- <!-- tag="data1" message="init test3 data1 " type="qdebug" -->
- <!-- tag="data1" message="test2 test3 data1 " type="qdebug" -->
+ <!-- message="test3_data test3 (null)" type="qdebug" -->
+ <!-- message="test3_data end" type="qdebug" -->
+ <!-- tag="data0" message="init test3 data0" type="qdebug" -->
+ <!-- tag="data0" message="test2 test3 data0" type="qdebug" -->
+ <!-- tag="data0" message="test2 end" type="qdebug" -->
+ <!-- tag="data0" message="cleanup test3 data0" type="qdebug" -->
+ <!-- tag="data1" message="init test3 data1" type="qdebug" -->
+ <!-- tag="data1" message="test2 test3 data1" type="qdebug" -->
<failure tag="data1" message="Compared values are not the same
- Actual (str) : hello1
- Expected (QString(&quot;hello0&quot;)): hello0" result="fail"/>
- <!-- tag="data1" message="cleanup test3 data1 " type="qdebug" -->
- <!-- tag="data2" message="init test3 data2 " type="qdebug" -->
- <!-- tag="data2" message="test2 test3 data2 " type="qdebug" -->
+ Actual (str) : &quot;hello1&quot;
+ Expected (QString(&quot;hello0&quot;)): &quot;hello0&quot;" result="fail"/>
+ <!-- tag="data1" message="cleanup test3 data1" type="qdebug" -->
+ <!-- tag="data2" message="init test3 data2" type="qdebug" -->
+ <!-- tag="data2" message="test2 test3 data2" type="qdebug" -->
<failure tag="data2" message="Compared values are not the same
- Actual (str) : hello2
- Expected (QString(&quot;hello0&quot;)): hello0" result="fail"/>
- <!-- tag="data2" message="cleanup test3 data2 " type="qdebug" -->
+ Actual (str) : &quot;hello2&quot;
+ Expected (QString(&quot;hello0&quot;)): &quot;hello0&quot;" result="fail"/>
+ <!-- tag="data2" message="cleanup test3 data2" type="qdebug" -->
</testcase>
<testcase result="pass" name="cleanupTestCase">
- <!-- message="cleanupTestCase cleanupTestCase (null) " type="qdebug" -->
+ <!-- message="cleanupTestCase cleanupTestCase (null)" type="qdebug" -->
</testcase>
<system-err>
-<![CDATA[initTestCase initTestCase (null) ]]>
-<![CDATA[init test1 (null) ]]>
-<![CDATA[test1 test1 (null) ]]>
-<![CDATA[cleanup test1 (null) ]]>
-<![CDATA[test2_data test2 (null) ]]>
-<![CDATA[test2_data end ]]>
-<![CDATA[init test2 data0 ]]>
-<![CDATA[test2 test2 data0 ]]>
-<![CDATA[test2 end ]]>
-<![CDATA[cleanup test2 data0 ]]>
-<![CDATA[init test2 data1 ]]>
-<![CDATA[test2 test2 data1 ]]>
-<![CDATA[test2 end ]]>
-<![CDATA[cleanup test2 data1 ]]>
-<![CDATA[init test2 data2 ]]>
-<![CDATA[test2 test2 data2 ]]>
-<![CDATA[test2 end ]]>
-<![CDATA[cleanup test2 data2 ]]>
-<![CDATA[test3_data test3 (null) ]]>
-<![CDATA[test3_data end ]]>
-<![CDATA[init test3 data0 ]]>
-<![CDATA[test2 test3 data0 ]]>
-<![CDATA[test2 end ]]>
-<![CDATA[cleanup test3 data0 ]]>
-<![CDATA[init test3 data1 ]]>
-<![CDATA[test2 test3 data1 ]]>
-<![CDATA[cleanup test3 data1 ]]>
-<![CDATA[init test3 data2 ]]>
-<![CDATA[test2 test3 data2 ]]>
-<![CDATA[cleanup test3 data2 ]]>
-<![CDATA[cleanupTestCase cleanupTestCase (null) ]]>
+<![CDATA[initTestCase initTestCase (null)]]>
+<![CDATA[init test1 (null)]]>
+<![CDATA[test1 test1 (null)]]>
+<![CDATA[cleanup test1 (null)]]>
+<![CDATA[test2_data test2 (null)]]>
+<![CDATA[test2_data end]]>
+<![CDATA[init test2 data0]]>
+<![CDATA[test2 test2 data0]]>
+<![CDATA[test2 end]]>
+<![CDATA[cleanup test2 data0]]>
+<![CDATA[init test2 data1]]>
+<![CDATA[test2 test2 data1]]>
+<![CDATA[test2 end]]>
+<![CDATA[cleanup test2 data1]]>
+<![CDATA[init test2 data2]]>
+<![CDATA[test2 test2 data2]]>
+<![CDATA[test2 end]]>
+<![CDATA[cleanup test2 data2]]>
+<![CDATA[test3_data test3 (null)]]>
+<![CDATA[test3_data end]]>
+<![CDATA[init test3 data0]]>
+<![CDATA[test2 test3 data0]]>
+<![CDATA[test2 end]]>
+<![CDATA[cleanup test3 data0]]>
+<![CDATA[init test3 data1]]>
+<![CDATA[test2 test3 data1]]>
+<![CDATA[cleanup test3 data1]]>
+<![CDATA[init test3 data2]]>
+<![CDATA[test2 test3 data2]]>
+<![CDATA[cleanup test3 data2]]>
+<![CDATA[cleanupTestCase cleanupTestCase (null)]]>
</system-err>
</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.lightxml b/tests/auto/testlib/selftests/expected_verbose1.lightxml
index c49792fec4..45dca139fa 100644
--- a/tests/auto/testlib/selftests/expected_verbose1.lightxml
+++ b/tests/auto/testlib/selftests/expected_verbose1.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
<Incident type="pass" file="" line="0">
@@ -12,94 +13,104 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -107,27 +118,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -135,16 +148,19 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.txt b/tests/auto/testlib/selftests/expected_verbose1.txt
index 4ba42c1c8e..1711a33004 100644
--- a/tests/auto/testlib/selftests/expected_verbose1.txt
+++ b/tests/auto/testlib/selftests/expected_verbose1.txt
@@ -8,60 +8,60 @@ 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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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()
+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)]
+ Loc: [../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)]
+ Loc: [../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()
+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)]
+ Loc: [../counting/tst_counting.cpp(244)]
PASS : tst_Counting::testSkipInCleanup(after)
INFO : tst_Counting::cleanupTestCase() entering
PASS : tst_Counting::cleanupTestCase()
diff --git a/tests/auto/testlib/selftests/expected_verbose1.xml b/tests/auto/testlib/selftests/expected_verbose1.xml
index 7caa915f65..7a182183c1 100644
--- a/tests/auto/testlib/selftests/expected_verbose1.xml
+++ b/tests/auto/testlib/selftests/expected_verbose1.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
<Incident type="pass" file="" line="0">
@@ -14,94 +15,104 @@
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Incident type="fail" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -109,27 +120,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -137,17 +150,20 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_verbose1.xunitxml b/tests/auto/testlib/selftests/expected_verbose1.xunitxml
index f317ed5923..72bf047ba8 100644
--- a/tests/auto/testlib/selftests/expected_verbose1.xunitxml
+++ b/tests/auto/testlib/selftests/expected_verbose1.xunitxml
@@ -38,14 +38,14 @@
<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" -->
+ <!-- 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="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"/>
@@ -56,9 +56,9 @@
<![CDATA[Skipping]]>
<![CDATA[Skipping]]>
<![CDATA[Skipping]]>
-<![CDATA[This test function should execute and then QFAIL in cleanup() ]]>
+<![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[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
index 2937adbe01..0ead76884c 100644
--- a/tests/auto/testlib/selftests/expected_verbose2.lightxml
+++ b/tests/auto/testlib/selftests/expected_verbose2.lightxml
@@ -4,174 +4,185 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassSkip">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassFail">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -179,27 +190,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -207,16 +220,19 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_verbose2.txt b/tests/auto/testlib/selftests/expected_verbose2.txt
index e9c7838f6d..068e7357e8 100644
--- a/tests/auto/testlib/selftests/expected_verbose2.txt
+++ b/tests/auto/testlib/selftests/expected_verbose2.txt
@@ -4,100 +4,100 @@ 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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testPassPass(row 1) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testPassPass(row 2) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testPassSkip(row 1) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testPassFail(row 1) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testSkipPass(row 2) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../counting/tst_counting.cpp(111)]
INFO : tst_Counting::testFailPass(row 2) QCOMPARE(2 + 1, 3)
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp(112)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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)]
+ Loc: [../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()
+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)]
+ Loc: [../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)]
+ Loc: [../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()
+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)]
+ Loc: [../counting/tst_counting.cpp(244)]
PASS : tst_Counting::testSkipInCleanup(after)
INFO : tst_Counting::cleanupTestCase() entering
PASS : tst_Counting::cleanupTestCase()
diff --git a/tests/auto/testlib/selftests/expected_verbose2.xml b/tests/auto/testlib/selftests/expected_verbose2.xml
index bbdca567d3..6d592f4a52 100644
--- a/tests/auto/testlib/selftests/expected_verbose2.xml
+++ b/tests/auto/testlib/selftests/expected_verbose2.xml
@@ -6,174 +6,185 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassPass">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassSkip">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testPassFail">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="111">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 1]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipPass">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipSkip">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipFail">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="118">
+<Message type="skip" file="../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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailPass">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="info" file="../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">
+<Message type="info" file="../counting/tst_counting.cpp" line="112">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[QCOMPARE(2 + 1, 3)]]></Description>
</Message>
<Incident type="pass" file="" line="0">
<DataTag><![CDATA[row 2]]></DataTag>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailSkip">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="skip" file="../counting/tst_counting.cpp" line="118">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA[Skipping]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailFail">
-<Message type="info" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/counting/tst_counting.cpp" line="115">
+<Message type="info" file="../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">
+<Incident type="fail" file="../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">
+<Message type="info" file="../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">
+<Incident type="fail" file="../counting/tst_counting.cpp" line="115">
<DataTag><![CDATA[row 2]]></DataTag>
<Description><![CDATA['false' returned FALSE. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFailInCleanup">
<Incident type="pass" file="" line="0">
@@ -181,27 +192,29 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[fail]]></DataTag>
- <Description><![CDATA[This test function should execute and then QFAIL in cleanup() ]]></Description>
+ <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">
+<Incident type="fail" file="../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>
+<Duration msecs="0"/>
</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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testSkipInCleanup">
<Incident type="pass" file="" line="0">
@@ -209,17 +222,20 @@
</Incident>
<Message type="qdebug" file="" line="0">
<DataTag><![CDATA[skip]]></DataTag>
- <Description><![CDATA[This test function should execute and then QSKIP in cleanup() ]]></Description>
+ <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">
+<Message type="skip" file="../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>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_verbose2.xunitxml b/tests/auto/testlib/selftests/expected_verbose2.xunitxml
index a774cb9d9f..6dabbd34fc 100644
--- a/tests/auto/testlib/selftests/expected_verbose2.xunitxml
+++ b/tests/auto/testlib/selftests/expected_verbose2.xunitxml
@@ -57,14 +57,14 @@
<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" -->
+ <!-- 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="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"/>
@@ -93,9 +93,9 @@
<![CDATA[Skipping]]>
<![CDATA[QVERIFY(false)]]>
<![CDATA[QVERIFY(false)]]>
-<![CDATA[This test function should execute and then QFAIL in cleanup() ]]>
+<![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[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_verifyexceptionthrown.lightxml b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.lightxml
new file mode 100644
index 0000000000..fb8f61503e
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.lightxml
@@ -0,0 +1,61 @@
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectStdTypes">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectStdExceptions">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectMyExceptions">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailInt">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="128">
+ <Description><![CDATA[Expected exception of type double to be thrown but unknown exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailStdString">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="133">
+ <Description><![CDATA[Expected exception of type char* to be thrown but unknown exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailStdRuntimeError">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="138">
+ <Description><![CDATA[Expected exception of type std::runtime_error to be thrown but std::exception caught with message: logic error]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailMyException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="143">
+ <Description><![CDATA[Expected exception of type MyBaseException to be thrown but std::exception caught with message: logic error]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailMyDerivedException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="148">
+ <Description><![CDATA[Expected exception of type std::runtime_error to be thrown but std::exception caught with message: MyDerivedException]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailNoException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="153">
+ <Description><![CDATA[Expected exception of type std::exception to be thrown but no exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_verifyexceptionthrown.txt b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.txt
new file mode 100644
index 0000000000..04db60eccd
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.txt
@@ -0,0 +1,21 @@
+********* Start testing of tst_VerifyExceptionThrown *********
+Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
+PASS : tst_VerifyExceptionThrown::initTestCase()
+PASS : tst_VerifyExceptionThrown::testCorrectStdTypes()
+PASS : tst_VerifyExceptionThrown::testCorrectStdExceptions()
+PASS : tst_VerifyExceptionThrown::testCorrectMyExceptions()
+FAIL! : tst_VerifyExceptionThrown::testFailInt() Expected exception of type double to be thrown but unknown exception caught
+ Loc: [tst_verifyexceptionthrown.cpp(128)]
+FAIL! : tst_VerifyExceptionThrown::testFailStdString() Expected exception of type char* to be thrown but unknown exception caught
+ Loc: [tst_verifyexceptionthrown.cpp(133)]
+FAIL! : tst_VerifyExceptionThrown::testFailStdRuntimeError() Expected exception of type std::runtime_error to be thrown but std::exception caught with message: logic error
+ Loc: [tst_verifyexceptionthrown.cpp(138)]
+FAIL! : tst_VerifyExceptionThrown::testFailMyException() Expected exception of type MyBaseException to be thrown but std::exception caught with message: logic error
+ Loc: [tst_verifyexceptionthrown.cpp(143)]
+FAIL! : tst_VerifyExceptionThrown::testFailMyDerivedException() Expected exception of type std::runtime_error to be thrown but std::exception caught with message: MyDerivedException
+ Loc: [tst_verifyexceptionthrown.cpp(148)]
+FAIL! : tst_VerifyExceptionThrown::testFailNoException() Expected exception of type std::exception to be thrown but no exception caught
+ Loc: [tst_verifyexceptionthrown.cpp(153)]
+PASS : tst_VerifyExceptionThrown::cleanupTestCase()
+Totals: 5 passed, 6 failed, 0 skipped
+********* Finished testing of tst_VerifyExceptionThrown *********
diff --git a/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xml b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xml
new file mode 100644
index 0000000000..a89528cfb8
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<TestCase name="tst_VerifyExceptionThrown">
+<Environment>
+ <QtVersion>@INSERT_QT_VERSION_HERE@</QtVersion>
+ <QTestVersion>@INSERT_QT_VERSION_HERE@</QTestVersion>
+</Environment>
+<TestFunction name="initTestCase">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectStdTypes">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectStdExceptions">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testCorrectMyExceptions">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailInt">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="128">
+ <Description><![CDATA[Expected exception of type double to be thrown but unknown exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailStdString">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="133">
+ <Description><![CDATA[Expected exception of type char* to be thrown but unknown exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailStdRuntimeError">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="138">
+ <Description><![CDATA[Expected exception of type std::runtime_error to be thrown but std::exception caught with message: logic error]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailMyException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="143">
+ <Description><![CDATA[Expected exception of type MyBaseException to be thrown but std::exception caught with message: logic error]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailMyDerivedException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="148">
+ <Description><![CDATA[Expected exception of type std::runtime_error to be thrown but std::exception caught with message: MyDerivedException]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testFailNoException">
+<Incident type="fail" file="tst_verifyexceptionthrown.cpp" line="153">
+ <Description><![CDATA[Expected exception of type std::exception to be thrown but no exception caught]]></Description>
+</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="cleanupTestCase">
+<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
+</TestFunction>
+<Duration msecs="0"/>
+</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xunitxml b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xunitxml
new file mode 100644
index 0000000000..f49746a9af
--- /dev/null
+++ b/tests/auto/testlib/selftests/expected_verifyexceptionthrown.xunitxml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<testsuite errors="0" failures="6" tests="11" name="tst_VerifyExceptionThrown">
+ <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="testCorrectStdTypes"/>
+ <testcase result="pass" name="testCorrectStdExceptions"/>
+ <testcase result="pass" name="testCorrectMyExceptions"/>
+ <testcase result="fail" name="testFailInt">
+ <failure message="Expected exception of type double to be thrown but unknown exception caught" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailStdString">
+ <failure message="Expected exception of type char* to be thrown but unknown exception caught" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailStdRuntimeError">
+ <failure message="Expected exception of type std::runtime_error to be thrown but std::exception caught with message: logic error" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailMyException">
+ <failure message="Expected exception of type MyBaseException to be thrown but std::exception caught with message: logic error" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailMyDerivedException">
+ <failure message="Expected exception of type std::runtime_error to be thrown but std::exception caught with message: MyDerivedException" result="fail"/>
+ </testcase>
+ <testcase result="fail" name="testFailNoException">
+ <failure message="Expected exception of type std::exception to be thrown but no exception caught" result="fail"/>
+ </testcase>
+ <testcase result="pass" name="cleanupTestCase"/>
+ <system-err/>
+</testsuite>
diff --git a/tests/auto/testlib/selftests/expected_warnings.lightxml b/tests/auto/testlib/selftests/expected_warnings.lightxml
index ad786832ca..bbc96b7010 100644
--- a/tests/auto/testlib/selftests/expected_warnings.lightxml
+++ b/tests/auto/testlib/selftests/expected_warnings.lightxml
@@ -4,6 +4,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testWarnings">
<Message type="qwarn" file="" line="0">
@@ -24,7 +25,14 @@
<Message type="qdebug" file="" line="0">
<Description><![CDATA[Baba]]></Description>
</Message>
+<Message type="qdebug" file="" line="0">
+ <Description><![CDATA[Bubublabla]]></Description>
+</Message>
+<Message type="qwarn" file="" line="0">
+ <Description><![CDATA[Babablabla]]></Description>
+</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testMissingWarnings">
<Message type="info" file="" line="0">
@@ -36,6 +44,16 @@
<Incident type="fail" file="" line="0">
<Description><![CDATA[Not all expected messages were received]]></Description>
</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testMissingWarningsRegularExpression">
+<Message type="info" file="" line="0">
+ <Description><![CDATA[Did not receive any message matching: "Warning\s\d"]]></Description>
+</Message>
+<Incident type="fail" file="" line="0">
+ <Description><![CDATA[Not all expected messages were received]]></Description>
+</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testMissingWarningsWithData">
<Message type="info" file="" line="0">
@@ -62,7 +80,10 @@
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[Not all expected messages were received]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_warnings.txt b/tests/auto/testlib/selftests/expected_warnings.txt
index d8064651b0..e73de980cb 100644
--- a/tests/auto/testlib/selftests/expected_warnings.txt
+++ b/tests/auto/testlib/selftests/expected_warnings.txt
@@ -7,10 +7,14 @@ QDEBUG : tst_Warnings::testWarnings() Debug
QDEBUG : tst_Warnings::testWarnings() Debug
QDEBUG : tst_Warnings::testWarnings() Baba
QDEBUG : tst_Warnings::testWarnings() Baba
+QDEBUG : tst_Warnings::testWarnings() Bubublabla
+QWARN : tst_Warnings::testWarnings() Babablabla
PASS : tst_Warnings::testWarnings()
INFO : tst_Warnings::testMissingWarnings() Did not receive message: "Warning0"
INFO : tst_Warnings::testMissingWarnings() Did not receive message: "Warning1"
FAIL! : tst_Warnings::testMissingWarnings() Not all expected messages were received
+INFO : tst_Warnings::testMissingWarningsRegularExpression() Did not receive any message matching: "Warning\s\d"
+FAIL! : tst_Warnings::testMissingWarningsRegularExpression() Not all expected messages were received
INFO : tst_Warnings::testMissingWarningsWithData(first row) Did not receive message: "Warning0"
INFO : tst_Warnings::testMissingWarningsWithData(first row) Did not receive message: "Warning1"
FAIL! : tst_Warnings::testMissingWarningsWithData(first row) Not all expected messages were received
@@ -18,5 +22,5 @@ INFO : tst_Warnings::testMissingWarningsWithData(second row) Did not receive m
INFO : tst_Warnings::testMissingWarningsWithData(second row) Did not receive message: "Warning1"
FAIL! : tst_Warnings::testMissingWarningsWithData(second row) Not all expected messages were received
PASS : tst_Warnings::cleanupTestCase()
-Totals: 3 passed, 3 failed, 0 skipped
+Totals: 3 passed, 4 failed, 0 skipped
********* Finished testing of tst_Warnings *********
diff --git a/tests/auto/testlib/selftests/expected_warnings.xml b/tests/auto/testlib/selftests/expected_warnings.xml
index 8ad236b52a..acb80e4f2a 100644
--- a/tests/auto/testlib/selftests/expected_warnings.xml
+++ b/tests/auto/testlib/selftests/expected_warnings.xml
@@ -6,6 +6,7 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testWarnings">
<Message type="qwarn" file="" line="0">
@@ -26,7 +27,14 @@
<Message type="qdebug" file="" line="0">
<Description><![CDATA[Baba]]></Description>
</Message>
+<Message type="qdebug" file="" line="0">
+ <Description><![CDATA[Bubublabla]]></Description>
+</Message>
+<Message type="qwarn" file="" line="0">
+ <Description><![CDATA[Babablabla]]></Description>
+</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testMissingWarnings">
<Message type="info" file="" line="0">
@@ -38,6 +46,16 @@
<Incident type="fail" file="" line="0">
<Description><![CDATA[Not all expected messages were received]]></Description>
</Incident>
+<Duration msecs="0"/>
+</TestFunction>
+<TestFunction name="testMissingWarningsRegularExpression">
+<Message type="info" file="" line="0">
+ <Description><![CDATA[Did not receive any message matching: "Warning\s\d"]]></Description>
+</Message>
+<Incident type="fail" file="" line="0">
+ <Description><![CDATA[Not all expected messages were received]]></Description>
+</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testMissingWarningsWithData">
<Message type="info" file="" line="0">
@@ -64,8 +82,11 @@
<DataTag><![CDATA[second row]]></DataTag>
<Description><![CDATA[Not all expected messages were received]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/expected_warnings.xunitxml b/tests/auto/testlib/selftests/expected_warnings.xunitxml
index 3e3b9ce18e..7be47174c6 100644
--- a/tests/auto/testlib/selftests/expected_warnings.xunitxml
+++ b/tests/auto/testlib/selftests/expected_warnings.xunitxml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<testsuite errors="12" failures="3" tests="5" name="tst_Warnings">
+<testsuite errors="15" failures="4" tests="6" name="tst_Warnings">
<properties>
<property value="@INSERT_QT_VERSION_HERE@" name="QTestVersion"/>
<property value="@INSERT_QT_VERSION_HERE@" name="QtVersion"/>
@@ -12,12 +12,18 @@
<!-- message="Debug" type="qdebug" -->
<!-- message="Baba" type="qdebug" -->
<!-- message="Baba" type="qdebug" -->
+ <!-- message="Bubublabla" type="qdebug" -->
+ <!-- message="Babablabla" type="qwarn" -->
</testcase>
<testcase result="fail" name="testMissingWarnings">
<!-- message="Did not receive message: &quot;Warning0&quot;" type="info" -->
<!-- message="Did not receive message: &quot;Warning1&quot;" type="info" -->
<failure message="Not all expected messages were received" result="fail"/>
</testcase>
+ <testcase result="fail" name="testMissingWarningsRegularExpression">
+ <!-- message="Did not receive any message matching: &quot;Warning\s\d&quot;" type="info" -->
+ <failure message="Not all expected messages were received" result="fail"/>
+ </testcase>
<testcase result="fail" name="testMissingWarningsWithData">
<!-- tag="first row" message="Did not receive message: &quot;Warning0&quot;" type="info" -->
<!-- tag="first row" message="Did not receive message: &quot;Warning1&quot;" type="info" -->
@@ -34,8 +40,11 @@
<![CDATA[Debug]]>
<![CDATA[Baba]]>
<![CDATA[Baba]]>
+<![CDATA[Bubublabla]]>
+<![CDATA[Babablabla]]>
<![CDATA[Did not receive message: "Warning0"]]>
<![CDATA[Did not receive message: "Warning1"]]>
+<![CDATA[Did not receive any message matching: "Warning\s\d"]]>
<![CDATA[Did not receive message: "Warning0"]]>
<![CDATA[Did not receive message: "Warning1"]]>
<![CDATA[Did not receive message: "Warning0"]]>
diff --git a/tests/auto/testlib/selftests/expected_xunit.lightxml b/tests/auto/testlib/selftests/expected_xunit.lightxml
index 0615f6fd61..6660cf4e7a 100644
--- a/tests/auto/testlib/selftests/expected_xunit.lightxml
+++ b/tests/auto/testlib/selftests/expected_xunit.lightxml
@@ -4,50 +4,60 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc1">
-<Message type="warn" file="" line="0">
+<Message type="warn" file="tst_xunit.cpp" line="67">
<Description><![CDATA[just a QWARN() !]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc2">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[a qDebug() call with comment-ending stuff -->]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="74">
+<Incident type="fail" file="tst_xunit.cpp" line="74">
<Description><![CDATA[Compared values are not the same
Actual (2): 2
Expected (3): 3]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc3">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="79">
+<Message type="skip" file="tst_xunit.cpp" line="79">
<Description><![CDATA[skipping this function!]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc4">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="84">
+<Incident type="fail" file="tst_xunit.cpp" line="84">
<Description><![CDATA[a forced failure!]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc5">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="98">
+<Incident type="xfail" file="tst_xunit.cpp" line="98">
<Description><![CDATA[this failure is expected]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc6">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="104">
+<Incident type="xfail" file="tst_xunit.cpp" line="104">
<Description><![CDATA[this failure is also expected]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc7">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="110">
+<Incident type="xpass" file="tst_xunit.cpp" line="110">
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
diff --git a/tests/auto/testlib/selftests/expected_xunit.txt b/tests/auto/testlib/selftests/expected_xunit.txt
index 722db18de4..f0b14752f0 100644
--- a/tests/auto/testlib/selftests/expected_xunit.txt
+++ b/tests/auto/testlib/selftests/expected_xunit.txt
@@ -2,25 +2,25 @@
Config: Using QtTest library @INSERT_QT_VERSION_HERE@, Qt @INSERT_QT_VERSION_HERE@
PASS : tst_Xunit::initTestCase()
WARNING: tst_Xunit::testFunc1() just a QWARN() !
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(67)]
+ Loc: [tst_xunit.cpp(67)]
PASS : tst_Xunit::testFunc1()
QDEBUG : tst_Xunit::testFunc2() a qDebug() call with comment-ending stuff -->
FAIL! : tst_Xunit::testFunc2() Compared values are not the same
Actual (2): 2
Expected (3): 3
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(74)]
+ Loc: [tst_xunit.cpp(74)]
SKIP : tst_Xunit::testFunc3() skipping this function!
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(79)]
+ Loc: [tst_xunit.cpp(79)]
FAIL! : tst_Xunit::testFunc4() a forced failure!
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(84)]
+ Loc: [tst_xunit.cpp(84)]
XFAIL : tst_Xunit::testFunc5() this failure is expected
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(98)]
+ Loc: [tst_xunit.cpp(98)]
PASS : tst_Xunit::testFunc5()
XFAIL : tst_Xunit::testFunc6() this failure is also expected
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(104)]
+ Loc: [tst_xunit.cpp(104)]
PASS : tst_Xunit::testFunc6()
XPASS : tst_Xunit::testFunc7() 'true' returned TRUE unexpectedly. ()
- Loc: [/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp(110)]
+ Loc: [tst_xunit.cpp(110)]
PASS : tst_Xunit::cleanupTestCase()
Totals: 5 passed, 3 failed, 1 skipped
********* Finished testing of tst_Xunit *********
diff --git a/tests/auto/testlib/selftests/expected_xunit.xml b/tests/auto/testlib/selftests/expected_xunit.xml
index e5d2876e20..af9fe1f502 100644
--- a/tests/auto/testlib/selftests/expected_xunit.xml
+++ b/tests/auto/testlib/selftests/expected_xunit.xml
@@ -6,51 +6,61 @@
</Environment>
<TestFunction name="initTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc1">
-<Message type="warn" file="" line="0">
+<Message type="warn" file="tst_xunit.cpp" line="67">
<Description><![CDATA[just a QWARN() !]]></Description>
</Message>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc2">
<Message type="qdebug" file="" line="0">
<Description><![CDATA[a qDebug() call with comment-ending stuff -->]]></Description>
</Message>
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="74">
+<Incident type="fail" file="tst_xunit.cpp" line="74">
<Description><![CDATA[Compared values are not the same
Actual (2): 2
Expected (3): 3]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc3">
-<Message type="skip" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="79">
+<Message type="skip" file="tst_xunit.cpp" line="79">
<Description><![CDATA[skipping this function!]]></Description>
</Message>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc4">
-<Incident type="fail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="84">
+<Incident type="fail" file="tst_xunit.cpp" line="84">
<Description><![CDATA[a forced failure!]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc5">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="98">
+<Incident type="xfail" file="tst_xunit.cpp" line="98">
<Description><![CDATA[this failure is expected]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc6">
-<Incident type="xfail" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="104">
+<Incident type="xfail" file="tst_xunit.cpp" line="104">
<Description><![CDATA[this failure is also expected]]></Description>
</Incident>
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="testFunc7">
-<Incident type="xpass" file="/home/user/dev/qt5/qtbase/tests/auto/testlib/selftests/xunit/tst_xunit.cpp" line="110">
+<Incident type="xpass" file="tst_xunit.cpp" line="110">
<Description><![CDATA['true' returned TRUE unexpectedly. ()]]></Description>
</Incident>
+<Duration msecs="0"/>
</TestFunction>
<TestFunction name="cleanupTestCase">
<Incident type="pass" file="" line="0" />
+<Duration msecs="0"/>
</TestFunction>
+<Duration msecs="0"/>
</TestCase>
diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py
new file mode 100755
index 0000000000..1c09faf4db
--- /dev/null
+++ b/tests/auto/testlib/selftests/generate_expected_output.py
@@ -0,0 +1,124 @@
+#!/usr/bin/env python3
+#############################################################################
+##
+## Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+## Contact: http://www.qt-project.org/legal
+##
+## This file is part of the release tools of the Qt Toolkit.
+##
+## $QT_BEGIN_LICENSE:LGPL$
+## Commercial License Usage
+## Licensees holding valid commercial Qt licenses may use this file in
+## accordance with the commercial license agreement provided with the
+## Software or, alternatively, in accordance with the terms contained in
+## a written agreement between you and Digia. For licensing terms and
+## conditions see http://qt.digia.com/licensing. For further information
+## use the contact form at http://qt.digia.com/contact-us.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, 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, Digia gives you certain additional
+## rights. These rights are described in the Digia 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.
+##
+##
+## $QT_END_LICENSE$
+##
+#############################################################################
+
+#regenerate all test's output
+
+import os
+import sys
+import subprocess
+import re
+
+formats = ['xml', 'txt', 'xunitxml', 'lightxml']
+
+qtver = subprocess.check_output(['qmake', '-query', 'QT_VERSION']).strip().decode('utf-8')
+rootPath = os.getcwd()
+
+isWindows = sys.platform == 'win32'
+
+replacements = [
+ (qtver, r'@INSERT_QT_VERSION_HERE@'),
+ (rootPath.encode('unicode-escape').decode('utf-8'), r''),
+ (r'( *)<Duration msecs="[\d\.]+"/>', r'\1<Duration msecs="0"/>'),
+]
+
+extraArgs = {
+ "commandlinedata": "fiveTablePasses fiveTablePasses:fiveTablePasses_data1 -v2",
+ "benchlibcallgrind": "-callgrind",
+ "benchlibeventcounter": "-eventcounter",
+ "benchliboptions": "-eventcounter",
+ "benchlibtickcounter": "-tickcounter",
+ "badxml": "-eventcounter",
+ "benchlibcounting": "-eventcounter",
+ "printdatatags": "-datatags",
+ "printdatatagswithglobaltags": "-datatags",
+ "silent": "-silent",
+ "verbose1": "-v1",
+ "verbose2": "-v2",
+}
+
+# Replace all occurrences of searchExp in one file
+def replaceInFile(file):
+ import sys
+ import fileinput
+ for line in fileinput.input(file, inplace=1):
+ for searchExp, replaceExp in replacements:
+ line = re.sub(searchExp, replaceExp, line)
+ sys.stdout.write(line)
+
+def subdirs():
+ result = []
+ for path in os.listdir('.'):
+ if os.path.isdir('./' + path):
+ result.append(path)
+ return result
+
+def getTestForPath(path):
+ if isWindows:
+ testpath = path + '\\' + path + '.exe'
+ else:
+ testpath = path + '/' + path
+ return testpath
+
+def generateTestData(testname):
+ print(" running " + testname)
+ for format in formats:
+ cmd = [getTestForPath(testname) + ' -' + format + ' ' + extraArgs.get(testname, '')]
+ result = 'expected_' + testname + '.' + format
+ data = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).communicate()[0]
+ out = open(result, 'w')
+ out.write(data)
+ out.close()
+ replaceInFile(result)
+
+if isWindows:
+ print("This script does not work on Windows.")
+ exit()
+
+tests = sys.argv[1:]
+if len(tests) == 0:
+ tests = subdirs()
+print("Generating " + str(len(tests)) + " test results for: " + qtver + " in: " + rootPath)
+for path in tests:
+ if os.path.isfile(getTestForPath(path)):
+ generateTestData(path)
+ else:
+ print("Warning: directory " + path + " contains no test executable")
diff --git a/tests/auto/testlib/selftests/selftests.pri b/tests/auto/testlib/selftests/selftests.pri
index c9474419eb..7b706735a9 100644
--- a/tests/auto/testlib/selftests/selftests.pri
+++ b/tests/auto/testlib/selftests/selftests.pri
@@ -41,5 +41,6 @@ SUBPROGRAMS = \
subtest \
verbose1 \
verbose2 \
+ verifyexceptionthrown \
warnings \
xunit
diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc
index 03de05fb89..ba567f1fb4 100644
--- a/tests/auto/testlib/selftests/selftests.qrc
+++ b/tests/auto/testlib/selftests/selftests.qrc
@@ -10,23 +10,28 @@
<file>expected_badxml.xml</file>
<file>expected_badxml.xunitxml</file>
<file>expected_benchlibcallgrind.txt</file>
+ <file>expected_benchlibcallgrind.csv</file>
<file>expected_benchlibcounting.lightxml</file>
<file>expected_benchlibcounting.txt</file>
<file>expected_benchlibcounting.xml</file>
<file>expected_benchlibcounting.xunitxml</file>
+ <file>expected_benchlibcounting.csv</file>
<file>expected_benchlibeventcounter.lightxml</file>
<file>expected_benchlibeventcounter.txt</file>
<file>expected_benchlibeventcounter.xml</file>
<file>expected_benchlibeventcounter.xunitxml</file>
+ <file>expected_benchlibeventcounter.csv</file>
<file>expected_benchliboptions.txt</file>
<file>expected_benchlibtickcounter.lightxml</file>
<file>expected_benchlibtickcounter.txt</file>
<file>expected_benchlibtickcounter.xml</file>
<file>expected_benchlibtickcounter.xunitxml</file>
+ <file>expected_benchlibtickcounter.csv</file>
<file>expected_benchlibwalltime.lightxml</file>
<file>expected_benchlibwalltime.txt</file>
<file>expected_benchlibwalltime.xml</file>
<file>expected_benchlibwalltime.xunitxml</file>
+ <file>expected_benchlibwalltime.csv</file>
<file>expected_cmptest.lightxml</file>
<file>expected_cmptest.txt</file>
<file>expected_cmptest.xml</file>
@@ -134,6 +139,10 @@
<file>expected_verbose2.txt</file>
<file>expected_verbose2.xml</file>
<file>expected_verbose2.xunitxml</file>
+ <file>expected_verifyexceptionthrown.lightxml</file>
+ <file>expected_verifyexceptionthrown.txt</file>
+ <file>expected_verifyexceptionthrown.xml</file>
+ <file>expected_verifyexceptionthrown.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 e332f01861..8167a96eaa 100644
--- a/tests/auto/testlib/selftests/tst_selftests.cpp
+++ b/tests/auto/testlib/selftests/tst_selftests.cpp
@@ -68,6 +68,7 @@ private:
QList<LoggerSet> allLoggerSets() const;
QTemporaryDir tempDir;
+ QRegularExpression durationRegExp;
};
struct BenchmarkResult
@@ -99,13 +100,13 @@ inline bool qCompare
// Now check the value. Some variance is allowed, and how much depends on
// the measured unit.
qreal variance = 0.;
- if (r1.unit == "msec") {
+ if (r1.unit == "msecs" || r1.unit == "WalltimeMilliseconds") {
variance = 0.1;
}
else if (r1.unit == "instruction reads") {
variance = 0.001;
}
- else if (r1.unit == "ticks") {
+ else if (r1.unit == "CPU ticks" || r1.unit == "CPUTicks") {
variance = 0.001;
}
if (variance == 0.) {
@@ -233,6 +234,12 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
QStringList() << "lightxml",
QStringList() << "-lightxml" << "-o" << logName("lightxml")
)
+ << LoggerSet("old stdout csv", // benchmarks only
+ QStringList() << "stdout csv",
+ QStringList() << "-csv")
+ << LoggerSet("old csv", // benchmarks only
+ QStringList() << "csv",
+ QStringList() << "-csv" << "-o" << logName("csv"))
// Test with new-style options for a single logger
<< LoggerSet("new stdout txt",
QStringList() << "stdout txt",
@@ -266,6 +273,12 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
QStringList() << "lightxml",
QStringList() << "-o" << logName("lightxml")+",lightxml"
)
+ << LoggerSet("new stdout csv", // benchmarks only
+ QStringList() << "stdout csv",
+ QStringList() << "-o" << "-,csv")
+ << LoggerSet("new csv", // benchmarks only
+ QStringList() << "csv",
+ QStringList() << "-o" << logName("csv")+",csv")
// Test with two loggers (don't test all 32 combinations, just a sample)
<< LoggerSet("stdout txt + txt",
QStringList() << "stdout txt" << "txt",
@@ -287,7 +300,7 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
QStringList() << "-o" << logName("lightxml")+",lightxml"
<< "-o" << "-,xunitxml"
)
- // All loggers at the same time
+ // All loggers at the same time (except csv)
<< LoggerSet("all loggers",
QStringList() << "txt" << "xml" << "lightxml" << "stdout txt" << "xunitxml",
QStringList() << "-o" << logName("txt")+",txt"
@@ -301,6 +314,7 @@ QList<LoggerSet> tst_Selftests::allLoggerSets() const
tst_Selftests::tst_Selftests()
: tempDir(QDir::tempPath() + "/tst_selftests.XXXXXX")
+ , durationRegExp("<Duration msecs=\"[\\d\\.]+\"/>")
{}
void tst_Selftests::initTestCase()
@@ -381,6 +395,10 @@ void tst_Selftests::runSubTest_data()
<< "subtest"
<< "verbose1"
<< "verbose2"
+#ifndef QT_NO_EXCEPTIONS
+ // this test will test nothing if the exceptions are disabled
+ << "verifyexceptionthrown"
+#endif //!QT_NO_EXCEPTIONS
<< "warnings"
<< "xunit"
;
@@ -480,6 +498,12 @@ void tst_Selftests::runSubTest_data()
continue;
}
}
+ if (subtest == "badxml" && (loggerSet.name == "all loggers" || loggerSet.name.contains("txt")))
+ continue; // XML only, do not mix txt and XML for encoding test.
+
+ if (loggerSet.name.contains("csv") && !subtest.startsWith("benchlib"))
+ continue;
+
const bool crashes = subtest == QLatin1String("assert") || subtest == QLatin1String("exceptionthrow")
|| subtest == QLatin1String("fetchbogus") || subtest == QLatin1String("crashedterminate")
|| subtest == QLatin1String("crashes") || subtest == QLatin1String("silent");
@@ -633,9 +657,19 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge
.arg(loggers.at(n))));
}
} else {
- QVERIFY2(res.count() == exp.count(),
+ if (res.count() != exp.count()) {
+ qDebug() << "<<<<<<";
+ foreach (const QByteArray &line, res)
+ qDebug() << line;
+ qDebug() << "======";
+ foreach (const QByteArray &line, exp)
+ qDebug() << line;
+ qDebug() << ">>>>>>";
+
+ QVERIFY2(res.count() == exp.count(),
qPrintable(QString::fromLatin1("Mismatch in line count: %1 != %2 (%3).")
.arg(res.count()).arg(exp.count()).arg(loggers.at(n))));
+ }
}
// By this point, we should have loaded a non-empty expected data file.
@@ -688,7 +722,7 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge
else if (expected.startsWith(QLatin1String("FAIL! : tst_Exception::throwException() Caught unhandled exce")) && expected != output)
// On some platforms we compile without RTTI, and as a result we never throw an exception.
QCOMPARE(output.simplified(), QString::fromLatin1("tst_Exception::throwException()").simplified());
- else if (benchmark || line.startsWith("<BenchmarkResult")) {
+ else if (benchmark || line.startsWith("<BenchmarkResult") || (logFormat(logger) == "csv" && line.startsWith('"'))) {
// Don't do a literal comparison for benchmark results, since
// results have some natural variance.
QString error;
@@ -700,6 +734,10 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge
QVERIFY2(error.isEmpty(), qPrintable(QString("Expected line didn't parse as benchmark result: %1\nLine: %2").arg(error).arg(expected)));
QCOMPARE(actualResult, expectedResult);
+ } else if (line.startsWith(" <Duration msecs=") || line.startsWith("<Duration msecs=")) {
+ QRegularExpressionMatch match = durationRegExp.match(line);
+ QVERIFY2(match.hasMatch(), qPrintable(QString::fromLatin1("Invalid Duration tag at line %1 (%2): '%3'")
+ .arg(i).arg(loggers.at(n), output)));
} else {
QVERIFY2(output == expected,
qPrintable(QString::fromLatin1("Mismatch at line %1 (%2): '%3' != '%4'")
@@ -791,6 +829,35 @@ BenchmarkResult BenchmarkResult::parse(QString const& line, QString* error)
out.iterations = iterations;
return out;
}
+
+ if (line.startsWith('"')) {
+ // CSV result
+ // format:
+ // "function","[globaltag:]tag","metric",value_per_iteration,total,iterations
+ QStringList split = line.split(',');
+ if (split.count() != 6) {
+ if (error) *error = QString("Wrong number of columns (%1)").arg(split.count());
+ return out;
+ }
+
+ bool ok;
+ double total = split.at(4).toDouble(&ok);
+ if (!ok) {
+ if (error) *error = split.at(4) + " is not a valid number";
+ return out;
+ }
+ double iterations = split.at(5).toDouble(&ok);
+ if (!ok) {
+ if (error) *error = split.at(5) + " is not a valid number";
+ return out;
+ }
+
+ out.unit = split.at(2);
+ out.total = total;
+ out.iterations = iterations;
+ return out;
+ }
+
// Text result
// This code avoids using a QRegExp because QRegExp might be broken.
// Sample format: 4,000 msec per iteration (total: 4,000, iterations: 1)
diff --git a/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp b/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
new file mode 100644
index 0000000000..fc57f19c4f
--- /dev/null
+++ b/tests/auto/testlib/selftests/verifyexceptionthrown/tst_verifyexceptionthrown.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+
+#ifndef QT_NO_EXCEPTIONS
+# include <stdexcept>
+#endif
+
+
+#ifndef QT_NO_EXCEPTIONS
+
+class MyBaseException
+{
+
+};
+
+class MyDerivedException: public MyBaseException, public std::domain_error
+{
+public:
+ MyDerivedException(): std::domain_error("MyDerivedException") {}
+};
+
+
+#endif // !QT_NO_EXCEPTIONS
+
+
+class tst_VerifyExceptionThrown: public QObject
+{
+ Q_OBJECT
+private:
+ void doSomething() const {}
+
+private slots:
+// Remove all test cases if exceptions are not available
+#ifndef QT_NO_EXCEPTIONS
+ void testCorrectStdTypes() const;
+ void testCorrectStdExceptions() const;
+ void testCorrectMyExceptions() const;
+
+ void testFailInt() const;
+ void testFailStdString() const;
+ void testFailStdRuntimeError() const;
+ void testFailMyException() const;
+ void testFailMyDerivedException() const;
+
+ void testFailNoException() const;
+#endif // !QT_NO_EXCEPTIONS
+};
+
+
+
+#ifndef QT_NO_EXCEPTIONS
+
+void tst_VerifyExceptionThrown::testCorrectStdTypes() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw int(5), int);
+ QVERIFY_EXCEPTION_THROWN(throw float(9.8), float);
+ QVERIFY_EXCEPTION_THROWN(throw bool(true), bool);
+ QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), std::string);
+}
+
+void tst_VerifyExceptionThrown::testCorrectStdExceptions() const
+{
+ // same type
+ QVERIFY_EXCEPTION_THROWN(throw std::exception(), std::exception);
+ QVERIFY_EXCEPTION_THROWN(throw std::runtime_error("runtime error"), std::runtime_error);
+ QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::overflow_error);
+
+ // inheritance
+ QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::runtime_error);
+ QVERIFY_EXCEPTION_THROWN(throw std::overflow_error("overflow error"), std::exception);
+}
+
+void tst_VerifyExceptionThrown::testCorrectMyExceptions() const
+{
+ // same type
+ QVERIFY_EXCEPTION_THROWN(throw MyBaseException(), MyBaseException);
+ QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), MyDerivedException);
+
+ // inheritance
+ QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), MyBaseException);
+ QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), std::domain_error);
+}
+
+void tst_VerifyExceptionThrown::testFailInt() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw int(5), double);
+}
+
+void tst_VerifyExceptionThrown::testFailStdString() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw std::string("some string"), char*);
+}
+
+void tst_VerifyExceptionThrown::testFailStdRuntimeError() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw std::logic_error("logic error"), std::runtime_error);
+}
+
+void tst_VerifyExceptionThrown::testFailMyException() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw std::logic_error("logic error"), MyBaseException);
+}
+
+void tst_VerifyExceptionThrown::testFailMyDerivedException() const
+{
+ QVERIFY_EXCEPTION_THROWN(throw MyDerivedException(), std::runtime_error);
+}
+
+void tst_VerifyExceptionThrown::testFailNoException() const
+{
+ QVERIFY_EXCEPTION_THROWN(doSomething(), std::exception);
+}
+
+#endif // !QT_NO_EXCEPTIONS
+
+
+
+QTEST_MAIN(tst_VerifyExceptionThrown)
+
+#include "tst_verifyexceptionthrown.moc"
diff --git a/tests/auto/testlib/selftests/verifyexceptionthrown/verifyexceptionthrown.pro b/tests/auto/testlib/selftests/verifyexceptionthrown/verifyexceptionthrown.pro
new file mode 100644
index 0000000000..51f108c9d7
--- /dev/null
+++ b/tests/auto/testlib/selftests/verifyexceptionthrown/verifyexceptionthrown.pro
@@ -0,0 +1,8 @@
+SOURCES += tst_verifyexceptionthrown.cpp
+QT = core testlib
+
+mac:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+CONFIG += exceptions
+
+TARGET = verifyexceptionthrown
diff --git a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp
index 20f53fdc91..4e3620caab 100644
--- a/tests/auto/testlib/selftests/warnings/tst_warnings.cpp
+++ b/tests/auto/testlib/selftests/warnings/tst_warnings.cpp
@@ -41,6 +41,7 @@
#include <QtCore/QCoreApplication>
+#include <QtCore/QRegularExpression>
#include <QtTest/QtTest>
class tst_Warnings: public QObject
@@ -49,6 +50,7 @@ class tst_Warnings: public QObject
private slots:
void testWarnings();
void testMissingWarnings();
+ void testMissingWarningsRegularExpression();
void testMissingWarningsWithData_data();
void testMissingWarningsWithData();
};
@@ -73,6 +75,17 @@ void tst_Warnings::testWarnings()
qDebug("Baba");
qDebug("Bubu");
qDebug("Baba");
+
+ QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^Bubu.*"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("^Baba.*"));
+ qDebug("Bubublabla");
+ qWarning("Babablabla");
+ qDebug("Bubublabla");
+ qWarning("Babablabla");
+
+ // accept redundant space at end to keep compatibility with Qt < 5.2
+ QTest::ignoreMessage(QtDebugMsg, "Bubu ");
+ qDebug() << "Bubu";
}
void tst_Warnings::testMissingWarnings()
@@ -84,6 +97,14 @@ void tst_Warnings::testMissingWarnings()
qWarning("Warning2");
}
+void tst_Warnings::testMissingWarningsRegularExpression()
+{
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Warning\\d\\d"));
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Warning\\s\\d"));
+
+ qWarning("Warning11");
+}
+
void tst_Warnings::testMissingWarningsWithData_data()
{
QTest::addColumn<int>("dummy");
diff --git a/tests/auto/tools/moc/assign-namespace.h b/tests/auto/tools/moc/assign-namespace.h
index 8f5ecc23e7..7377b38f6b 100644
--- a/tests/auto/tools/moc/assign-namespace.h
+++ b/tests/auto/tools/moc/assign-namespace.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef ASSIGN_NAMESPACE_H
+#define ASSIGN_NAMESPACE_H
+
namespace A
{
namespace Nested
@@ -50,3 +53,4 @@ namespace A
namespace Mine = Qt;
namespace Theirs = A::Nested::Space;
+#endif // ASSIGN_NAMESPACE_H
diff --git a/tests/auto/tools/moc/backslash-newlines.h b/tests/auto/tools/moc/backslash-newlines.h
index 27c47843a2..29d800f26f 100644
--- a/tests/auto/tools/moc/backslash-newlines.h
+++ b/tests/auto/tools/moc/backslash-newlines.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef BACKSLASH_NEWLINES_H
+#define BACKSLASH_NEWLINES_H
+
#include <QObject>
const int blackslashNewlinesDummy = 0
@@ -61,3 +64,4 @@ public slots:
#undef value
+#endif // BACKSLASH_NEWLINES_H
diff --git a/tests/auto/tools/moc/c-comments.h b/tests/auto/tools/moc/c-comments.h
index bded642737..dff4492287 100644
--- a/tests/auto/tools/moc/c-comments.h
+++ b/tests/auto/tools/moc/c-comments.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef C_COMMENTS_H
+#define C_COMMENTS_H
#include <qobject.h>
/* test support for multi-line comments in preprocessor statements */
@@ -53,3 +56,4 @@ public:
};
#endif
+#endif // C_COMMENTS_H
diff --git a/tests/auto/tools/moc/cstyle-enums.h b/tests/auto/tools/moc/cstyle-enums.h
index 38c5932f69..7d1f6d0147 100644
--- a/tests/auto/tools/moc/cstyle-enums.h
+++ b/tests/auto/tools/moc/cstyle-enums.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef CSTYLE_ENUMS_H
+#define CSTYLE_ENUMS_H
#include <QObject>
class CStyleEnums
@@ -48,3 +51,4 @@ public:
typedef enum { Foo, Bar } Baz;
};
+#endif // CSTYLE_ENUMS_H
diff --git a/tests/auto/tools/moc/cxx11-enums.h b/tests/auto/tools/moc/cxx11-enums.h
index 0bd99b762c..215ae093d9 100644
--- a/tests/auto/tools/moc/cxx11-enums.h
+++ b/tests/auto/tools/moc/cxx11-enums.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef CXX11_ENUMS_H
+#define CXX11_ENUMS_H
#include <QtCore/QObject>
#if defined(Q_COMPILER_CLASS_ENUM) || defined(Q_MOC_RUN)
@@ -64,3 +67,4 @@ public:
enum TypedEnum { B0, B1 , B2, B3 };
};
#endif
+#endif // CXX11_ENUMS_H
diff --git a/tests/auto/tools/moc/dir-in-include-path.h b/tests/auto/tools/moc/dir-in-include-path.h
index 0d46f69d63..34f96bea6b 100644
--- a/tests/auto/tools/moc/dir-in-include-path.h
+++ b/tests/auto/tools/moc/dir-in-include-path.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef DIR_IN_INCLUDE_PATH_H
+#define DIR_IN_INCLUDE_PATH_H
#include <Plugin>
class DirInIncludePath : public QObject, public MyInterface
@@ -45,3 +48,4 @@ class DirInIncludePath : public QObject, public MyInterface
Q_OBJECT
Q_INTERFACES(MyInterface)
};
+#endif // DIR_IN_INCLUDE_PATH_H
diff --git a/tests/auto/tools/moc/dollars.h b/tests/auto/tools/moc/dollars.h
index 8fab45559c..b136b00881 100644
--- a/tests/auto/tools/moc/dollars.h
+++ b/tests/auto/tools/moc/dollars.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef DOLLARS_H
+#define DOLLARS_H
+
/* both GCC and clang allow $ in identifiers
* So moc should not throw a parse error if it parses a file that contains such identifiers
*/
@@ -68,3 +71,4 @@ namespace $NS {
};
}
+#endif // DOLLARS_H
diff --git a/tests/auto/tools/moc/error-on-wrong-notify.h b/tests/auto/tools/moc/error-on-wrong-notify.h
index d13e352143..7358f4e77a 100644
--- a/tests/auto/tools/moc/error-on-wrong-notify.h
+++ b/tests/auto/tools/moc/error-on-wrong-notify.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef ERROR_ON_WRONG_NOTIFY_H
+#define ERROR_ON_WRONG_NOTIFY_H
#include <QObject>
class ClassWithWrongNOTIFY : public QObject
@@ -51,3 +54,4 @@ public:
int foo() { return m_foo; }
};
+#endif // ERROR_ON_WRONG_NOTIFY_H
diff --git a/tests/auto/tools/moc/escapes-in-string-literals.h b/tests/auto/tools/moc/escapes-in-string-literals.h
index e2f044e196..25f9df2e74 100644
--- a/tests/auto/tools/moc/escapes-in-string-literals.h
+++ b/tests/auto/tools/moc/escapes-in-string-literals.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef ESCAPES_IN_STRING_LITERALS_H
+#define ESCAPES_IN_STRING_LITERALS_H
#include <QObject>
class StringLiterals: public QObject
@@ -47,3 +50,4 @@ class StringLiterals: public QObject
Q_CLASSINFO("Test2", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\123")
Q_CLASSINFO("Test3", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\nb")
};
+#endif // ESCAPES_IN_STRING_LITERALS_H
diff --git a/tests/auto/tools/moc/extraqualification.h b/tests/auto/tools/moc/extraqualification.h
index 5c69699067..875eb56184 100644
--- a/tests/auto/tools/moc/extraqualification.h
+++ b/tests/auto/tools/moc/extraqualification.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef EXTRAQUALIFICATION_H
+#define EXTRAQUALIFICATION_H
+
#include <QObject>
class Test : public QObject
@@ -55,3 +58,4 @@ public slots:
public:
Q_SLOT void Test::anotherOne() {}
};
+#endif // EXTRAQUALIFICATION_H
diff --git a/tests/auto/tools/moc/forgotten-qinterface.h b/tests/auto/tools/moc/forgotten-qinterface.h
index 4c8aa45d92..0c2fd87aa5 100644
--- a/tests/auto/tools/moc/forgotten-qinterface.h
+++ b/tests/auto/tools/moc/forgotten-qinterface.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef FORGOTTEN_QINTERFACE_H
+#define FORGOTTEN_QINTERFACE_H
+
#include <QObject>
struct MyInterface
@@ -53,3 +56,4 @@ class Test : public QObject, public MyInterface
{
Q_OBJECT
};
+#endif // FORGOTTEN_QINTERFACE_H
diff --git a/tests/auto/tools/moc/forward-declared-param.h b/tests/auto/tools/moc/forward-declared-param.h
index 013c6563e8..441745f9fc 100644
--- a/tests/auto/tools/moc/forward-declared-param.h
+++ b/tests/auto/tools/moc/forward-declared-param.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef FORWARD_DECLARED_PARAM_H
+#define FORWARD_DECLARED_PARAM_H
#include <qobject.h>
#include <qmetatype.h>
@@ -73,4 +76,5 @@ signals:
void signalQSet(const QSet<int> &);
void signalQSet(const QSet<QString> &);
void signalQSet(const QSet<FullyDefined> &);
-}; \ No newline at end of file
+};
+#endif // FORWARD_DECLARED_PARAM_H
diff --git a/tests/auto/tools/moc/function-with-attributes.h b/tests/auto/tools/moc/function-with-attributes.h
index afa02e6f3a..88f3e3fcb3 100644
--- a/tests/auto/tools/moc/function-with-attributes.h
+++ b/tests/auto/tools/moc/function-with-attributes.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef FUNCTION_WITH_ATTRIBUTES_H
+#define FUNCTION_WITH_ATTRIBUTES_H
#include <qobject.h>
// test support for gcc attributes with functions
@@ -62,3 +65,4 @@ public slots:
DEPRECATED2 void test2() {}
};
+#endif // FUNCTION_WITH_ATTRIBUTES_H
diff --git a/tests/auto/tools/moc/interface-from-framework.h b/tests/auto/tools/moc/interface-from-framework.h
index 8a4188e5ab..c961d18bb9 100644
--- a/tests/auto/tools/moc/interface-from-framework.h
+++ b/tests/auto/tools/moc/interface-from-framework.h
@@ -38,7 +38,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef INTERFACE_FROM-FRAMEWORK_H
+
+#ifndef INTERFACE_FROM_FRAMEWORK_H
#define INTERFACE_FROM_FRAMEWORK_H
#include <Test/testinterface.h>
diff --git a/tests/auto/tools/moc/macro-on-cmdline.h b/tests/auto/tools/moc/macro-on-cmdline.h
index 9609b7cd31..681340471d 100644
--- a/tests/auto/tools/moc/macro-on-cmdline.h
+++ b/tests/auto/tools/moc/macro-on-cmdline.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef MACRO_ON_CMDLINE_H
+#define MACRO_ON_CMDLINE_H
+
#if FOO
class Test : public QObject
@@ -48,3 +51,4 @@ public:
};
#endif
+#endif // MACRO_ON_CMDLINE_H
diff --git a/tests/auto/tools/moc/moc.pro b/tests/auto/tools/moc/moc.pro
index 9a3fee38f0..cc8c2c671d 100644
--- a/tests/auto/tools/moc/moc.pro
+++ b/tests/auto/tools/moc/moc.pro
@@ -24,7 +24,11 @@ HEADERS += using-namespaces.h no-keywords.h task87883.h c-comments.h backslash-n
parse-defines.h \
function-with-attributes.h \
plugin_metadata.h \
- single-quote-digit-separator-n3781.h
+ single-quote-digit-separator-n3781.h \
+ related-metaobjects-in-namespaces.h \
+ qtbug-35657-gadget.h \
+ related-metaobjects-in-gadget.h \
+ related-metaobjects-name-conflict.h
if(*-g++*|*-icc*|*-clang*|*-llvm):!irix-*:!win32-*: HEADERS += os9-newlines.h win-newlines.h
diff --git a/tests/auto/tools/moc/namespaced-flags.h b/tests/auto/tools/moc/namespaced-flags.h
index 97aecfbf3c..ce1e12d83f 100644
--- a/tests/auto/tools/moc/namespaced-flags.h
+++ b/tests/auto/tools/moc/namespaced-flags.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef NAMESPACED_FLAGS_H
+#define NAMESPACED_FLAGS_H
#include <QObject>
namespace Foo {
@@ -78,3 +81,4 @@ namespace Foo {
}
Q_DECLARE_OPERATORS_FOR_FLAGS( Foo::Bar::Flags )
+#endif // NAMESPACED_FLAGS_H
diff --git a/tests/auto/tools/moc/no-keywords.h b/tests/auto/tools/moc/no-keywords.h
index ffd5928370..3fa6f089e0 100644
--- a/tests/auto/tools/moc/no-keywords.h
+++ b/tests/auto/tools/moc/no-keywords.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef NO_KEYWORDS_H
+#define NO_KEYWORDS_H
+
#define QT_NO_KEYWORDS
#undef signals
#undef slots
@@ -85,3 +88,4 @@ private:
#define emit
#undef QT_NO_KEYWORDS
+#endif // NO_KEYWORDS_H
diff --git a/tests/auto/tools/moc/oldstyle-casts.h b/tests/auto/tools/moc/oldstyle-casts.h
index 89f90a3504..0c4e9e8e00 100644
--- a/tests/auto/tools/moc/oldstyle-casts.h
+++ b/tests/auto/tools/moc/oldstyle-casts.h
@@ -38,9 +38,12 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef OLDSTYLE_CASTS_H
+#define OLDSTYLE_CASTS_H
#include <QtCore/qobject.h>
-class Foo: public QObject
+class OldStyleCast: public QObject
{
Q_OBJECT
public:
@@ -54,3 +57,4 @@ public slots:
inline void slot(int, QObject * const) {}
};
+#endif // OLDSTYLE_CASTS_H
diff --git a/tests/auto/tools/moc/parse-boost.h b/tests/auto/tools/moc/parse-boost.h
index b93eb7130c..4dd7693358 100644
--- a/tests/auto/tools/moc/parse-boost.h
+++ b/tests/auto/tools/moc/parse-boost.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef PARSE_BOOST_H
+#define PARSE_BOOST_H
#include <boost/aligned_storage.hpp>
#include <boost/any.hpp>
#include <boost/array.hpp>
@@ -124,3 +127,4 @@
#include <boost/version.hpp>
#include <boost/visit_each.hpp>
#include <boost/weak_ptr.hpp>
+#endif // PARSE_BOOST_H
diff --git a/tests/auto/tools/moc/pp-dollar-signs.h b/tests/auto/tools/moc/pp-dollar-signs.h
index 98134a5019..a90b654ee4 100644
--- a/tests/auto/tools/moc/pp-dollar-signs.h
+++ b/tests/auto/tools/moc/pp-dollar-signs.h
@@ -39,4 +39,8 @@
**
****************************************************************************/
+#ifndef PP_DOLLAR_SIGNS_H
+#define PP_DOLLAR_SIGNS_H
+
$$ = parser->createFoo()
+#endif // PP_DOLLAR_SIGNS_H
diff --git a/tests/auto/tools/moc/pure-virtual-signals.h b/tests/auto/tools/moc/pure-virtual-signals.h
index fb23089b30..070f5894a3 100644
--- a/tests/auto/tools/moc/pure-virtual-signals.h
+++ b/tests/auto/tools/moc/pure-virtual-signals.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef PURE_VIRTUAL_SIGNALS_H
+#define PURE_VIRTUAL_SIGNALS_H
#include <QObject>
class PureVirtualSignalsTest : public QObject
@@ -58,3 +61,4 @@ signals:
void mySignal();
void mySignal2(int foo);
};
+#endif // PURE_VIRTUAL_SIGNALS_H
diff --git a/tests/auto/tools/moc/qinvokable.h b/tests/auto/tools/moc/qinvokable.h
index 9070f2ab8e..a47ae72b2b 100644
--- a/tests/auto/tools/moc/qinvokable.h
+++ b/tests/auto/tools/moc/qinvokable.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef QINVOKABLE_H
+#define QINVOKABLE_H
+
#include <QObject>
class InvokableBeforeReturnType : public QObject
@@ -55,3 +58,4 @@ public:
Q_INVOKABLE inline void foo() {}
Q_INVOKABLE virtual void bar() {}
};
+#endif // QINVOKABLE_H
diff --git a/tests/auto/tools/moc/qprivateslots.h b/tests/auto/tools/moc/qprivateslots.h
index 5b0db3d27e..82a68270af 100644
--- a/tests/auto/tools/moc/qprivateslots.h
+++ b/tests/auto/tools/moc/qprivateslots.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef QPRIVATESLOTS_H
+#define QPRIVATESLOTS_H
+
#include <QObject>
struct TestQPrivateSlots_Private
@@ -58,3 +61,4 @@ private:
TestQPrivateSlots_Private *d;
};
+#endif // QPRIVATESLOTS_H
diff --git a/tests/auto/tools/moc/qtbug-35657-gadget.h b/tests/auto/tools/moc/qtbug-35657-gadget.h
new file mode 100644
index 0000000000..c030405c67
--- /dev/null
+++ b/tests/auto/tools/moc/qtbug-35657-gadget.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTBUG_35657_GADGET_H
+#define QTBUG_35657_GADGET_H
+
+#include <QObject>
+
+namespace QTBUG_35657 {
+ class A {
+ Q_GADGET
+ Q_ENUMS(SomeEnum)
+ public:
+ enum SomeEnum { SomeEnumValue = 0 };
+ };
+}
+
+#endif // QTBUG_35657_GADGET_H
diff --git a/tests/auto/tools/moc/related-metaobjects-in-gadget.h b/tests/auto/tools/moc/related-metaobjects-in-gadget.h
new file mode 100644
index 0000000000..556e92efaf
--- /dev/null
+++ b/tests/auto/tools/moc/related-metaobjects-in-gadget.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RELATED_METAOBJECTS_IN_GADGET_H
+#define RELATED_METAOBJECTS_IN_GADGET_H
+
+#include <QObject>
+#include "qtbug-35657-gadget.h"
+
+namespace QTBUG_35657 {
+ class B : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(A::SomeEnum blah READ blah)
+ public:
+
+ A::SomeEnum blah() const { return A::SomeEnumValue; }
+ };
+}
+
+#endif // RELATED_METAOBJECTS_IN_GADGET_H
diff --git a/tests/auto/tools/moc/related-metaobjects-in-namespaces.h b/tests/auto/tools/moc/related-metaobjects-in-namespaces.h
new file mode 100644
index 0000000000..4be856391f
--- /dev/null
+++ b/tests/auto/tools/moc/related-metaobjects-in-namespaces.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RELATED_METAOBJECTS_IN_NAMESPACES_H
+#define RELATED_METAOBJECTS_IN_NAMESPACES_H
+
+#include <QObject>
+
+namespace QTBUG_2151 {
+ class A : public QObject {
+ Q_OBJECT
+ Q_ENUMS(SomeEnum)
+ public:
+ enum SomeEnum { SomeEnumValue = 0 };
+ };
+
+ class B : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(A::SomeEnum blah READ blah)
+ public:
+
+ A::SomeEnum blah() const { return A::SomeEnumValue; }
+ };
+}
+
+#endif // RELATED_METAOBJECTS_IN_NAMESPACES_H
diff --git a/tests/auto/tools/moc/related-metaobjects-name-conflict.h b/tests/auto/tools/moc/related-metaobjects-name-conflict.h
new file mode 100644
index 0000000000..551ab461e3
--- /dev/null
+++ b/tests/auto/tools/moc/related-metaobjects-name-conflict.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RELATED_METAOBJECTS_NAME_CONFLICT_H
+#define RELATED_METAOBJECTS_NAME_CONFLICT_H
+
+#include <QObject>
+
+#define DECLARE_GADGET_AND_OBJECT_CLASSES \
+ class Gadget { \
+ Q_GADGET \
+ Q_ENUMS(SomeEnum) \
+ public: \
+ enum SomeEnum { SomeEnumValue = 0 }; \
+ }; \
+ class Object : public QObject{ \
+ Q_OBJECT \
+ Q_ENUMS(SomeEnum) \
+ public: \
+ enum SomeEnum { SomeEnumValue = 0 }; \
+ };
+
+#define DECLARE_DEPENDING_CLASSES \
+ class DependingObject : public QObject \
+ { \
+ Q_OBJECT \
+ Q_PROPERTY(Gadget::SomeEnum gadgetPoperty READ gadgetPoperty) \
+ Q_PROPERTY(Object::SomeEnum objectPoperty READ objectPoperty) \
+ public: \
+ Gadget::SomeEnum gadgetPoperty() const { return Gadget::SomeEnumValue; } \
+ Object::SomeEnum objectPoperty() const { return Object::SomeEnumValue; } \
+ };\
+ struct DependingNestedGadget : public QObject \
+ { \
+ Q_OBJECT \
+ Q_PROPERTY(Nested::Gadget::SomeEnum nestedGadgetPoperty READ nestedGadgetPoperty) \
+ Nested::Gadget::SomeEnum nestedGadgetPoperty() const { return Nested::Gadget::SomeEnumValue; } \
+ };\
+ struct DependingNestedObject : public QObject \
+ { \
+ Q_OBJECT \
+ Q_PROPERTY(Nested::Object::SomeEnum nestedObjectPoperty READ nestedObjectPoperty) \
+ Nested::Object::SomeEnum nestedObjectPoperty() const { return Nested::Object::SomeEnumValue; } \
+ };\
+
+
+namespace Unsused {
+ DECLARE_GADGET_AND_OBJECT_CLASSES
+} // Unused
+
+namespace NS1 {
+namespace Nested {
+ DECLARE_GADGET_AND_OBJECT_CLASSES
+} // Nested
+
+namespace NestedUnsused {
+ DECLARE_GADGET_AND_OBJECT_CLASSES
+} // NestedUnused
+
+DECLARE_GADGET_AND_OBJECT_CLASSES
+DECLARE_DEPENDING_CLASSES
+
+} // NS1
+
+namespace NS2 {
+namespace Nested {
+ DECLARE_GADGET_AND_OBJECT_CLASSES
+} // Nested
+
+namespace NestedUnsused {
+ DECLARE_GADGET_AND_OBJECT_CLASSES
+} // NestedUnused
+
+DECLARE_GADGET_AND_OBJECT_CLASSES
+DECLARE_DEPENDING_CLASSES
+
+} // NS2
+
+#endif // RELATED_METAOBJECTS_NAME_CONFLICT_H
diff --git a/tests/auto/tools/moc/single-quote-digit-separator-n3781.h b/tests/auto/tools/moc/single-quote-digit-separator-n3781.h
index 0b234011d5..f5f39c7dd7 100644
--- a/tests/auto/tools/moc/single-quote-digit-separator-n3781.h
+++ b/tests/auto/tools/moc/single-quote-digit-separator-n3781.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef SINGLE_QUOTE_DIGIT_SEPARATOR_N3781_H
+#define SINGLE_QUOTE_DIGIT_SEPARATOR_N3781_H
+
#include <QObject>
class KDAB : public QObject
@@ -56,3 +59,4 @@ public:
};
Q_ENUMS(Salaries)
};
+#endif // SINGLE_QUOTE_DIGIT_SEPARATOR_N3781_H
diff --git a/tests/auto/tools/moc/single_function_keyword.h b/tests/auto/tools/moc/single_function_keyword.h
index 44a1a41d30..6717509517 100644
--- a/tests/auto/tools/moc/single_function_keyword.h
+++ b/tests/auto/tools/moc/single_function_keyword.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef SINGLE_FUNCTION_KEYWORD_H
+#define SINGLE_FUNCTION_KEYWORD_H
#include <QObject>
class SingleFunctionKeywordBeforeReturnType : public QObject
@@ -73,3 +76,4 @@ public:
inline Q_SLOT void mySlot() { emit mySignal(); }
};
+#endif // SINGLE_FUNCTION_KEYWORD_H
diff --git a/tests/auto/tools/moc/slots-with-void-template.h b/tests/auto/tools/moc/slots-with-void-template.h
index c38437ca54..524d565345 100644
--- a/tests/auto/tools/moc/slots-with-void-template.h
+++ b/tests/auto/tools/moc/slots-with-void-template.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef SLOTS_WITH_VOID_TEMPLATE_H
+#define SLOTS_WITH_VOID_TEMPLATE_H
#include <QObject>
template <typename T>
@@ -59,3 +62,4 @@ signals:
void myVoidSignal();
void myVoidSignal2(void);
};
+#endif // SLOTS_WITH_VOID_TEMPLATE_H
diff --git a/tests/auto/tools/moc/task192552.h b/tests/auto/tools/moc/task192552.h
index 23665bbb07..b221984d7d 100644
--- a/tests/auto/tools/moc/task192552.h
+++ b/tests/auto/tools/moc/task192552.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef TASK192552_H
+#define TASK192552_H
/*
<:: is not valid C++, but we want moc to treat it as < :: since this
is usually the intention
@@ -53,3 +56,4 @@ public:
QList<::QObject*> m_objects;
#endif
};
+#endif // TASK192552_H
diff --git a/tests/auto/tools/moc/task234909.h b/tests/auto/tools/moc/task234909.h
index 2ad8b9a410..37948441eb 100644
--- a/tests/auto/tools/moc/task234909.h
+++ b/tests/auto/tools/moc/task234909.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef TASK234909_H
+#define TASK234909_H
#include <qobject.h>
namespace NS_A {
@@ -71,3 +74,4 @@ namespace NS_Main {
}
}
+#endif // TASK234909_H
diff --git a/tests/auto/tools/moc/task87883.h b/tests/auto/tools/moc/task87883.h
index d6687588f7..65988221f1 100644
--- a/tests/auto/tools/moc/task87883.h
+++ b/tests/auto/tools/moc/task87883.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef TASK87883_H
+#define TASK87883_H
/*
The bug is triggered only if there is a multiline comment after an #include
statement that in the following line contains a single quote but lacks a finishing
@@ -55,3 +58,4 @@ public:
inline Task87883() {}
};
+#endif // TASK87883_H
diff --git a/tests/auto/tools/moc/template-gtgt.h b/tests/auto/tools/moc/template-gtgt.h
index 2c2f56c34d..b5d83b5796 100644
--- a/tests/auto/tools/moc/template-gtgt.h
+++ b/tests/auto/tools/moc/template-gtgt.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef TEMPLATE_GTGT_H
+#define TEMPLATE_GTGT_H
template<class TYPE, size_t COUNT>
class myTemplate :
QString,
@@ -58,3 +61,4 @@ public:
{
}
};
+#endif // TEMPLATE_GTGT_H
diff --git a/tests/auto/tools/moc/trigraphs.h b/tests/auto/tools/moc/trigraphs.h
index cc1824190e..301ea35265 100644
--- a/tests/auto/tools/moc/trigraphs.h
+++ b/tests/auto/tools/moc/trigraphs.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef TRIGRAPHS_H
+#define TRIGRAPHS_H
+
#include <QObject>
namespace AAA {
@@ -61,3 +64,4 @@ namespace BBB {
};
}
+#endif // TRIGRAPHS_H
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index bf2d6afdb4..04140fa4a1 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -76,6 +76,9 @@
#include "cxx11-explicit-override-control.h"
#include "parse-defines.h"
+#include "related-metaobjects-in-namespaces.h"
+#include "related-metaobjects-in-gadget.h"
+#include "related-metaobjects-name-conflict.h"
QT_USE_NAMESPACE
@@ -569,6 +572,11 @@ private slots:
void preprocessorOnly();
void unterminatedFunctionMacro();
void QTBUG32933_relatedObjectsDontIncludeItself();
+ void writeEnumFromUnrelatedClass();
+ void relatedMetaObjectsWithinNamespaces();
+ void relatedMetaObjectsInGadget();
+ void relatedMetaObjectsNameConflict_data();
+ void relatedMetaObjectsNameConflict();
signals:
void sigWithUnsignedArg(unsigned foo);
@@ -688,8 +696,8 @@ void tst_Moc::warnOnExtraSignalSlotQualifiaction()
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocWarning, header +
- QString(":53: Warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
- header + QString(":56: Warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
+ QString(":56: Warning: Function declaration Test::badFunctionDeclaration contains extra qualification. Ignoring as signal or slot.\n") +
+ header + QString(":59: Warning: parsemaybe: Function declaration Test::anotherOne contains extra qualification. Ignoring as signal or slot.\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -885,7 +893,7 @@ void tst_Moc::testExtraDataForEnum()
const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject;
QCOMPARE(mobjUser->enumeratorCount(), 0);
- const QMetaObject **objects = mobjUser->d.relatedMetaObjects;
+ const QMetaObject * const *objects = mobjUser->d.relatedMetaObjects;
QVERIFY(objects);
QVERIFY(objects[0] == mobjSource);
QVERIFY(objects[1] == 0);
@@ -967,7 +975,7 @@ void tst_Moc::warnOnMultipleInheritance()
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocWarning, header +
- QString(":53: Warning: Class Bar inherits from two QObject subclasses QWindow and Foo. This is not supported!\n"));
+ QString(":56: Warning: Class Bar inherits from two QObject subclasses QWindow and Foo. This is not supported!\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -1030,7 +1038,7 @@ void tst_Moc::forgottenQInterface()
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocWarning, header +
- QString(":55: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
+ QString(":58: Warning: Class Test implements the interface MyInterface but does not list it in Q_INTERFACES. qobject_cast to MyInterface will not work!\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -1346,7 +1354,7 @@ void tst_Moc::warnOnPropertyWithoutREAD()
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocWarning, header +
- QString(":46: Warning: Property declaration foo has no READ accessor function or associated MEMBER variable. The property will be invalid.\n"));
+ QString(":49: Warning: Property declaration foo has no READ accessor function or associated MEMBER variable. The property will be invalid.\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -1456,8 +1464,8 @@ void tst_Moc::warnOnVirtualSignal()
QByteArray mocOut = proc.readAllStandardOutput();
QVERIFY(!mocOut.isEmpty());
QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError());
- QCOMPARE(mocWarning, header + QString(":48: Warning: Signals cannot be declared virtual\n") +
- header + QString(":50: Warning: Signals cannot be declared virtual\n"));
+ QCOMPARE(mocWarning, header + QString(":51: Warning: Signals cannot be declared virtual\n") +
+ header + QString(":53: Warning: Signals cannot be declared virtual\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -1590,7 +1598,7 @@ void tst_Moc::notifyError()
QVERIFY(mocOut.isEmpty());
QString mocError = QString::fromLocal8Bit(proc.readAllStandardError());
QCOMPARE(mocError, header +
- QString(":52: Error: NOTIFY signal 'fooChanged' of property 'foo' does not exist in class ClassWithWrongNOTIFY.\n"));
+ QString(":55: Error: NOTIFY signal 'fooChanged' of property 'foo' does not exist in class ClassWithWrongNOTIFY.\n"));
#else
QSKIP("Only tested on linux/gcc");
#endif
@@ -3121,12 +3129,129 @@ namespace QTBUG32933_relatedObjectsDontIncludeItself {
void tst_Moc::QTBUG32933_relatedObjectsDontIncludeItself()
{
const QMetaObject *mo = &QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::staticMetaObject;
- const QMetaObject **objects = mo->d.relatedMetaObjects;
+ const QMetaObject * const *objects = mo->d.relatedMetaObjects;
// the related objects should be empty because the enums is in the same object.
QVERIFY(!objects);
}
+class UnrelatedClass : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(UnrelatedEnum)
+public:
+ enum UnrelatedEnum {
+ UnrelatedInvalidValue = -1,
+ UnrelatedValue = 42
+ };
+};
+
+// The presence of this macro used to confuse moc and prevent
+// UnrelatedClass from being listed in the related meta objects.
+Q_DECLARE_METATYPE(UnrelatedClass::UnrelatedEnum)
+
+class TestClassReferencingUnrelatedEnum : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(UnrelatedClass::UnrelatedEnum enumProperty READ enumProperty WRITE setEnumProperty)
+public:
+ TestClassReferencingUnrelatedEnum()
+ : m_enumProperty(UnrelatedClass::UnrelatedInvalidValue)
+ {}
+
+ UnrelatedClass::UnrelatedEnum enumProperty() const {
+ return m_enumProperty;
+ }
+
+ void setEnumProperty(UnrelatedClass::UnrelatedEnum arg) {
+ m_enumProperty = arg;
+ }
+
+private:
+ UnrelatedClass::UnrelatedEnum m_enumProperty;
+};
+
+void tst_Moc::writeEnumFromUnrelatedClass()
+{
+ TestClassReferencingUnrelatedEnum obj;
+ QString enumValueAsString("UnrelatedValue");
+ obj.setProperty("enumProperty", enumValueAsString);
+ QCOMPARE(int(obj.enumProperty()), int(UnrelatedClass::UnrelatedValue));
+}
+
+
+
+void tst_Moc::relatedMetaObjectsWithinNamespaces()
+{
+ const QMetaObject *relatedMo = &QTBUG_2151::A::staticMetaObject;
+
+ const QMetaObject *testMo = &QTBUG_2151::B::staticMetaObject;
+ QVERIFY(testMo->d.relatedMetaObjects);
+ QVERIFY(testMo->d.relatedMetaObjects[0] == relatedMo);
+}
+
+void tst_Moc::relatedMetaObjectsInGadget()
+{
+ const QMetaObject *relatedMo = &QTBUG_35657::A::staticMetaObject;
+
+ const QMetaObject *testMo = &QTBUG_35657::B::staticMetaObject;
+ QVERIFY(testMo->d.relatedMetaObjects);
+ QVERIFY(testMo->d.relatedMetaObjects[0] == relatedMo);
+}
+
+void tst_Moc::relatedMetaObjectsNameConflict_data()
+{
+ typedef QVector<const QMetaObject*> QMetaObjects;
+ QTest::addColumn<const QMetaObject*>("dependingObject");
+ QTest::addColumn<QMetaObjects>("relatedMetaObjects");
+
+ //NS1
+ const QMetaObject *n1gadget = &NS1::Gadget::staticMetaObject;
+ const QMetaObject *n1object = &NS1::Object::staticMetaObject;
+ const QMetaObject *n1nestedGadget = &NS1::Nested::Gadget::staticMetaObject;
+ const QMetaObject *n1nestedObject = &NS1::Nested::Object::staticMetaObject;
+ //N2
+ const QMetaObject *n2gadget = &NS2::Gadget::staticMetaObject;
+ const QMetaObject *n2object = &NS2::Object::staticMetaObject;
+ const QMetaObject *n2nestedGadget = &NS2::Nested::Gadget::staticMetaObject;
+ const QMetaObject *n2nestedObject = &NS2::Nested::Object::staticMetaObject;
+
+ QTest::newRow("N1::dependingObject") << &NS1::DependingObject::staticMetaObject
+ << (QMetaObjects() << n1gadget << n1object);
+ QTest::newRow("N2::dependingObject") << &NS2::DependingObject::staticMetaObject
+ << (QMetaObjects() << n2gadget << n2object);
+ QTest::newRow("N1::dependingNestedObject") << &NS1::DependingNestedObject::staticMetaObject
+ << (QMetaObjects() << n1nestedObject);
+ QTest::newRow("N2::dependingNestedObject") << &NS2::DependingNestedObject::staticMetaObject
+ << (QMetaObjects() << n2nestedObject);
+ QTest::newRow("N1::dependingNestedGadget") << &NS1::DependingNestedGadget::staticMetaObject
+ << (QMetaObjects() << n1nestedGadget);
+ QTest::newRow("N2::dependingNestedGadget") << &NS2::DependingNestedGadget::staticMetaObject
+ << (QMetaObjects() << n2nestedGadget);
+}
+
+void tst_Moc::relatedMetaObjectsNameConflict()
+{
+ typedef QVector<const QMetaObject*> QMetaObjects;
+ QFETCH(const QMetaObject*, dependingObject);
+ QFETCH(QMetaObjects, relatedMetaObjects);
+
+ // load all specified metaobjects int a set
+ QSet<const QMetaObject*> dependency;
+ const QMetaObject *const *i = dependingObject->d.relatedMetaObjects;
+ while (*i) {
+ dependency.insert(*i);
+ ++i;
+ }
+
+ // check if all required metaobjects are specified
+ foreach (const QMetaObject *mo, relatedMetaObjects)
+ QVERIFY(dependency.contains(mo));
+
+ // check if no additional metaobjects ara specified
+ QCOMPARE(dependency.size(), relatedMetaObjects.size());
+}
+
QTEST_MAIN(tst_Moc)
// the generated code must compile with QT_NO_KEYWORDS
diff --git a/tests/auto/tools/moc/unterminated-function-macro.h b/tests/auto/tools/moc/unterminated-function-macro.h
index 813d60f0e4..60595d1536 100644
--- a/tests/auto/tools/moc/unterminated-function-macro.h
+++ b/tests/auto/tools/moc/unterminated-function-macro.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef UNTERMINATED_FUNCTION_MACRO_H
+#define UNTERMINATED_FUNCTION_MACRO_H
+
class Dummy : public QObject {
Q_OBJECT
}
@@ -49,3 +52,4 @@ static void foo() {
MACRO(foo
}
+#endif // UNTERMINATED_FUNCTION_MACRO_H
diff --git a/tests/auto/tools/moc/using-namespaces.h b/tests/auto/tools/moc/using-namespaces.h
index c662bb762a..64ffa96a21 100644
--- a/tests/auto/tools/moc/using-namespaces.h
+++ b/tests/auto/tools/moc/using-namespaces.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef USING_NAMESPACES_H
+#define USING_NAMESPACES_H
+
namespace Foo {}
namespace Bar
{
@@ -54,3 +57,4 @@ using namespace Foo;
using namespace Bar::Huh;
using namespace ::Top;
+#endif // USING_NAMESPACES_H
diff --git a/tests/auto/tools/moc/warn-on-multiple-qobject-subclasses.h b/tests/auto/tools/moc/warn-on-multiple-qobject-subclasses.h
index 346909cca1..bbe416f7f0 100644
--- a/tests/auto/tools/moc/warn-on-multiple-qobject-subclasses.h
+++ b/tests/auto/tools/moc/warn-on-multiple-qobject-subclasses.h
@@ -39,6 +39,9 @@
**
****************************************************************************/
+#ifndef WARN_ON_MULTIPLE_QOBJECT_SUBCLASSES_H
+#define WARN_ON_MULTIPLE_QOBJECT_SUBCLASSES_H
+
#include <QtGui>
class Foo : public QObject
@@ -53,3 +56,4 @@ class Bar : public QWindow, public Foo
};
+#endif // WARN_ON_MULTIPLE_QOBJECT_SUBCLASSES_H
diff --git a/tests/auto/tools/moc/warn-on-property-without-read.h b/tests/auto/tools/moc/warn-on-property-without-read.h
index 75d2953aa1..85c092d240 100644
--- a/tests/auto/tools/moc/warn-on-property-without-read.h
+++ b/tests/auto/tools/moc/warn-on-property-without-read.h
@@ -38,6 +38,9 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#ifndef WARN_ON_PROPERTY_WITHOUT_READ_H
+#define WARN_ON_PROPERTY_WITHOUT_READ_H
#include <QObject>
class ClassWithPropertyWithoutREAD : public QObject
@@ -46,3 +49,4 @@ class ClassWithPropertyWithoutREAD : public QObject
Q_PROPERTY(int foo)
Q_PROPERTY(int bar READ bar)
};
+#endif // WARN_ON_PROPERTY_WITHOUT_READ_H
diff --git a/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h b/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h
new file mode 100644
index 0000000000..597728e207
--- /dev/null
+++ b/tests/auto/tools/uic/baseline/translation/Dialog_without_Buttons_tr.h
@@ -0,0 +1,50 @@
+/********************************************************************************
+** Form generated from reading UI file 'Dialog_without_Buttons.ui'
+**
+** Created by: Qt User Interface Compiler version 5.3.0
+**
+** WARNING! All changes made in this file will be lost when recompiling UI file!
+********************************************************************************/
+
+#ifndef DIALOG_WITHOUT_BUTTONS_TR_H
+#define DIALOG_WITHOUT_BUTTONS_TR_H
+
+#include <QtCore/QVariant>
+#include <QtWidgets/QAction>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QButtonGroup>
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QHeaderView>
+#include <ki18n.h>
+
+QT_BEGIN_NAMESPACE
+
+class Ui_Dialog
+{
+public:
+
+ void setupUi(QDialog *Dialog)
+ {
+ if (Dialog->objectName().isEmpty())
+ Dialog->setObjectName(QStringLiteral("Dialog"));
+ Dialog->resize(400, 300);
+
+ retranslateUi(Dialog);
+
+ QMetaObject::connectSlotsByName(Dialog);
+ } // setupUi
+
+ void retranslateUi(QDialog *Dialog)
+ {
+ Dialog->setWindowTitle(i18n("Dialog", 0));
+ } // retranslateUi
+
+};
+
+namespace Ui {
+ class Dialog: public Ui_Dialog {};
+} // namespace Ui
+
+QT_END_NAMESPACE
+
+#endif // DIALOG_WITHOUT_BUTTONS_TR_H
diff --git a/tests/auto/tools/uic/tst_uic.cpp b/tests/auto/tools/uic/tst_uic.cpp
index c6e8466d89..02a19c0c33 100644
--- a/tests/auto/tools/uic/tst_uic.cpp
+++ b/tests/auto/tools/uic/tst_uic.cpp
@@ -64,9 +64,13 @@ private Q_SLOTS:
void run();
void run_data() const;
+ void runTranslation();
+
void compare();
void compare_data() const;
+ void runCompare();
+
private:
const QString m_command;
QString m_baseline;
@@ -220,5 +224,53 @@ void tst_uic::compare_data() const
}
}
+void tst_uic::runTranslation()
+{
+ QProcess process;
+
+ QDir baseline(m_baseline);
+
+ QDir generated(m_generated.path());
+ generated.mkdir(QLatin1String("translation"));
+ QString generatedFile = generated.absolutePath() + QLatin1String("/translation/Dialog_without_Buttons_tr.h");
+
+ process.start(m_command, QStringList(baseline.filePath("Dialog_without_Buttons.ui"))
+ << QString(QLatin1String("-tr")) << "i18n"
+ << QString(QLatin1String("-include")) << "ki18n.h"
+ << QString(QLatin1String("-o")) << generatedFile);
+ QVERIFY2(process.waitForStarted(), msgProcessStartFailed(m_command, process.errorString()));
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(QFileInfo(generatedFile).exists(), true);
+}
+
+
+void tst_uic::runCompare()
+{
+ QFile orgFile(m_baseline + QLatin1String("/translation/Dialog_without_Buttons_tr.h"));
+
+ QDir generated(m_generated.path());
+ QFile genFile(generated.absolutePath() + QLatin1String("/translation/Dialog_without_Buttons_tr.h"));
+
+ if (!orgFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QString err(QLatin1String("Could not read file: %1..."));
+ QFAIL(err.arg(orgFile.fileName()).toUtf8());
+ }
+
+ if (!genFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QString err(QLatin1String("Could not read file: %1..."));
+ QFAIL(err.arg(genFile.fileName()).toUtf8());
+ }
+
+ QString originalFile = orgFile.readAll();
+ originalFile.replace(QRegExp(QLatin1String("Created by: Qt User Interface Compiler version [.\\d]{5,5}")), "");
+
+ QString generatedFile = genFile.readAll();
+ generatedFile.replace(QRegExp(QLatin1String("Created by: Qt User Interface Compiler version [.\\d]{5,5}")), "");
+
+ QCOMPARE(generatedFile, originalFile);
+}
+
QTEST_MAIN(tst_uic)
#include "tst_uic.moc"
diff --git a/tests/auto/widgets/dialogs/dialogs.pro b/tests/auto/widgets/dialogs/dialogs.pro
index acff1df5ba..c6667824d9 100644
--- a/tests/auto/widgets/dialogs/dialogs.pro
+++ b/tests/auto/widgets/dialogs/dialogs.pro
@@ -1,6 +1,5 @@
TEMPLATE=subdirs
SUBDIRS=\
- qabstractprintdialog \
qcolordialog \
qdialog \
qerrormessage \
@@ -14,10 +13,8 @@ SUBDIRS=\
qsidebar \
qwizard \
-wince*|!qtHaveModule(printsupport):SUBDIRS -= qabstractprintdialog
-
!contains(QT_CONFIG, private_tests): SUBDIRS -= \
qsidebar \
mac:qinputdialog.CONFIG += no_check_target # QTBUG-25496
-win32-g++*: SUBDIRS -= qfilesystemmodel # QTBUG-29403
+mingw: SUBDIRS -= qfilesystemmodel # QTBUG-29403
diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
index 1aab794e1b..d8833e232d 100644
--- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
+++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp
@@ -200,7 +200,7 @@ void tst_QDialog::showExtension()
// show
((DummyDialog*)testWidget)->showExtension( true );
// while ( testWidget->size() == dlgSize )
-// qApp->processEvents();
+// qApp->processEvents();
QTEST( testWidget->size(), "result" );
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
index b9e6c82d84..217fb4c30b 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -310,10 +310,10 @@ void tst_QFileDialog2::unc()
void tst_QFileDialog2::emptyUncPath()
{
QNonNativeFileDialog fd;
- fd.show();
+ fd.show();
QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
QVERIFY(lineEdit);
- // press 'keys' for the input
+ // press 'keys' for the input
for (int i = 0; i < 3 ; ++i)
QTest::keyPress(lineEdit, Qt::Key_Backslash);
QFileSystemModel *model = fd.findChild<QFileSystemModel*>("qt_filesystem_model");
diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
index eac3f9c9ae..9e0446388e 100644
--- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
+++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp
@@ -166,12 +166,12 @@ void tst_QFileSystemModel::cleanup()
for (int i = 0; i < list.count(); ++i) {
QFileInfo fi(dir.path() + '/' + list.at(i));
if (fi.exists() && fi.isFile()) {
- QFile p(fi.absoluteFilePath());
+ QFile p(fi.absoluteFilePath());
p.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther);
- QFile dead(dir.path() + '/' + list.at(i));
- dead.remove();
- }
- if (fi.exists() && fi.isDir())
+ QFile dead(dir.path() + '/' + list.at(i));
+ dead.remove();
+ }
+ if (fi.exists() && fi.isDir())
QVERIFY(dir.rmdir(list.at(i)));
}
list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot);
@@ -426,7 +426,14 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi
wchar_t nativeHiddenFile[MAX_PATH];
memset(nativeHiddenFile, 0, sizeof(nativeHiddenFile));
hiddenFile.toWCharArray(nativeHiddenFile);
+#ifndef Q_OS_WINRT
DWORD currentAttributes = ::GetFileAttributes(nativeHiddenFile);
+#else // !Q_OS_WINRT
+ WIN32_FILE_ATTRIBUTE_DATA attributeData;
+ if (!::GetFileAttributesEx(nativeHiddenFile, GetFileExInfoStandard, &attributeData))
+ attributeData.dwFileAttributes = 0xFFFFFFFF;
+ DWORD currentAttributes = attributeData.dwFileAttributes;
+#endif // Q_OS_WINRT
if (currentAttributes == 0xFFFFFFFF) {
qErrnoWarning("failed to get file attributes: %s", qPrintable(hiddenFile));
return false;
diff --git a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
index 1762e40a9d..6eb36115cb 100644
--- a/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
+++ b/tests/auto/widgets/dialogs/qfontdialog/tst_qfontdialog.cpp
@@ -108,11 +108,11 @@ void tst_QFontDialog::cleanup()
void tst_QFontDialog::postKeyReturn() {
QWidgetList list = QApplication::topLevelWidgets();
for (int i=0; i<list.count(); ++i) {
- QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]);
- if (dialog) {
- QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
- return;
- }
+ QFontDialog *dialog = qobject_cast<QFontDialog*>(list[i]);
+ if (dialog) {
+ QTest::keyClick( list[i], Qt::Key_Return, Qt::NoModifier );
+ return;
+ }
}
}
diff --git a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
index 7d8077d77d..abd120db86 100644
--- a/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
+++ b/tests/auto/widgets/dialogs/qinputdialog/tst_qinputdialog.cpp
@@ -110,7 +110,7 @@ void testTypingValue(
sbox->selectAll();
for (int i = 0; i < value.size(); ++i) {
const QChar valChar = value[i];
- _keyClick(static_cast<QWidget *>(sbox), valChar.toLatin1()); // ### always guaranteed to work?
+ _keyClick(static_cast<QWidget *>(sbox), valChar.toLatin1()); // ### always guaranteed to work?
if (sbox->hasAcceptableInput())
QVERIFY(okButton->isEnabled());
else
@@ -123,7 +123,7 @@ void testTypingValue(QLineEdit *ledit, QPushButton *okButton, const QString &val
ledit->selectAll();
for (int i = 0; i < value.size(); ++i) {
const QChar valChar = value[i];
- _keyClick(ledit, valChar.toLatin1()); // ### always guaranteed to work?
+ _keyClick(ledit, valChar.toLatin1()); // ### always guaranteed to work?
QVERIFY(ledit->hasAcceptableInput());
QVERIFY(okButton->isEnabled());
}
diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
index a711bc28e3..4c07b48c00 100644
--- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
+++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp
@@ -90,6 +90,7 @@ private slots:
void setOption_HaveNextButtonOnLastPage();
void setOption_HaveFinishButtonOnEarlyPages();
void setOption_NoCancelButton();
+ void setOption_NoCancelButtonOnLastPage();
void setOption_CancelButtonOnLeft();
void setOption_HaveHelpButton();
void setOption_HelpButtonOnRight();
@@ -1423,6 +1424,50 @@ void tst_QWizard::setOption_NoCancelButton()
}
}
+void tst_QWizard::setOption_NoCancelButtonOnLastPage()
+{
+ for (int i = 0; i < 2; ++i) {
+ QWizard wizard;
+ wizard.setOption(QWizard::NoCancelButton, false);
+ wizard.setOption(QWizard::NoCancelButtonOnLastPage, true);
+ wizard.addPage(new QWizardPage);
+ wizard.addPage(new QWizardPage);
+ wizard.page(1)->setFinalPage(true); // changes nothing (final != last in general)
+ wizard.addPage(new QWizardPage);
+
+ wizard.setStartId(1);
+ wizard.show();
+ qApp->processEvents();
+
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.back();
+ qApp->processEvents();
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.next();
+ qApp->processEvents();
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButtonOnLastPage, false);
+ QVERIFY(wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.setOption(QWizard::NoCancelButtonOnLastPage, true);
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible());
+
+ wizard.addPage(new QWizardPage);
+ QVERIFY(!wizard.button(QWizard::CancelButton)->isVisible()); // this is maybe wrong
+ }
+}
+
void tst_QWizard::setOption_CancelButtonOnLeft()
{
for (int i = 0; i < 2; ++i) {
@@ -1767,7 +1812,7 @@ public:
QWizardPage *page_to_delete = page(id);
removePage(id);
delete page_to_delete;
- }
+ }
}
void applyOperations(const QList<Operation *> &operations)
diff --git a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index 1ffb5c3b5c..78ab8027d8 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -2974,7 +2974,7 @@ void tst_QGraphicsGridLayout::geometries()
void tst_QGraphicsGridLayout::avoidRecursionInInsertItem()
{
QGraphicsWidget window(0, Qt::Window);
- QGraphicsGridLayout *layout = new QGraphicsGridLayout(&window);
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout(&window);
QCOMPARE(layout->count(), 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::addItem: cannot insert itself");
layout->addItem(layout, 0, 0);
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro
index 0c3b46c5d5..527f62b22d 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/qgraphicsitem.pro
@@ -5,5 +5,5 @@ QT += core-private gui-private
SOURCES += tst_qgraphicsitem.cpp
DEFINES += QT_NO_CAST_TO_ASCII
-win32:!wince*: LIBS += -luser32
+win32:!wince*:!winrt: LIBS += -luser32
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
index fc1d0e34cb..de7c528825 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -71,7 +71,7 @@ Q_DECLARE_METATYPE(QPainterPath)
#include "../../../qtest-config.h"
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#include <windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
diff --git a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
index 6366f86250..6a3e69d0a8 100644
--- a/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
@@ -1,3 +1,4 @@
+
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
@@ -47,6 +48,8 @@
#include <qgraphicsscene.h>
#include <qgraphicsview.h>
#include <qapplication.h>
+#include <QtWidgets/qstyle.h>
+#include <QtWidgets/qproxystyle.h>
class tst_QGraphicsLinearLayout : public QObject {
Q_OBJECT
@@ -86,6 +89,7 @@ private slots:
void removeItem();
void setGeometry_data();
void setGeometry();
+ void defaultSpacing();
void setSpacing_data();
void setSpacing();
void setItemSpacing_data();
@@ -770,7 +774,7 @@ void tst_QGraphicsLinearLayout::orientation()
layout.setOrientation(orientation);
QCOMPARE(layout.orientation(), orientation);
- // important to resize to preferredsize when orientation is switched
+ // important to resize to preferredsize when orientation is switched
widget->resize(widget->effectiveSizeHint(Qt::PreferredSize));
qApp->processEvents();
for (i = 0; i < positions.count(); ++i) {
@@ -909,6 +913,94 @@ void tst_QGraphicsLinearLayout::setGeometry()
delete widget;
}
+class LayoutStyle : public QProxyStyle
+{
+public:
+ LayoutStyle(const QString &key)
+ : QProxyStyle(key),
+ horizontalSpacing(-1), verticalSpacing(-1) {}
+
+ virtual int pixelMetric(QStyle::PixelMetric pm, const QStyleOption *option = 0, const QWidget *widget = 0) const Q_DECL_OVERRIDE
+ {
+ if (pm == QStyle::PM_LayoutHorizontalSpacing && horizontalSpacing >= 0) {
+ return horizontalSpacing;
+ } else if (pm == QStyle::PM_LayoutVerticalSpacing && verticalSpacing >= 0) {
+ return verticalSpacing;
+ }
+ return QProxyStyle::pixelMetric(pm, option, widget);
+ }
+
+ int horizontalSpacing;
+ int verticalSpacing;
+};
+
+void tst_QGraphicsLinearLayout::defaultSpacing()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ LayoutStyle *style = new LayoutStyle(QLatin1String("windows"));
+ style->horizontalSpacing = 5;
+ style->verticalSpacing = 3;
+ LayoutStyle *style2 = new LayoutStyle(QLatin1String("windows"));
+ style2->horizontalSpacing = 25;
+ style2->verticalSpacing = 23;
+
+ QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
+ widget->setStyle(style);
+
+ // Horizontal layout
+ SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout(Qt::Horizontal);
+ widget->setLayout(layout);
+ Q_ASSERT(widget->style());
+ scene.addItem(widget);
+ layout->setContentsMargins(0, 0, 0, 0);
+ view.show();
+
+ for (int i = 0; i < 2; ++i) {
+ QGraphicsWidget *w = new QGraphicsWidget;
+ layout->addItem(w);
+ }
+
+ // Horizontal layout
+ qreal styleSpacing = (qreal)style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ QCOMPARE(styleSpacing, qreal(5));
+ QCOMPARE(styleSpacing, layout->spacing());
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(105));
+ style->horizontalSpacing = 15;
+ // If the style method changes return value, the layout must be invalidated by the application
+ layout->invalidate();
+ styleSpacing = (qreal)style->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
+ QCOMPARE(styleSpacing, qreal(15));
+ QCOMPARE(styleSpacing, layout->spacing());
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(115));
+ widget->setStyle(style2);
+ // If the style itself changes, the layout will pick that up
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).width(), qreal(125));
+ QCOMPARE(layout->spacing(), qreal(25));
+
+ // Vertical layout
+ widget->setStyle(style);
+ layout->setOrientation(Qt::Vertical);
+ styleSpacing = (qreal)style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ QCOMPARE(styleSpacing, qreal(3));
+ QCOMPARE(styleSpacing, layout->spacing());
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(103));
+ style->verticalSpacing = 13;
+ // If the style method changes return value, the layout must be invalidated by the application
+ layout->invalidate();
+ styleSpacing = (qreal)style->pixelMetric(QStyle::PM_LayoutVerticalSpacing);
+ QCOMPARE(styleSpacing, qreal(13));
+ QCOMPARE(styleSpacing, layout->spacing());
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(113));
+ widget->setStyle(style2);
+ // If the style itself changes, the layout will pick that up
+ QCOMPARE(layout->effectiveSizeHint(Qt::PreferredSize).height(), qreal(123));
+ QCOMPARE(layout->spacing(), qreal(23));
+
+
+ delete widget;
+}
+
void tst_QGraphicsLinearLayout::setSpacing_data()
{
QTest::addColumn<qreal>("spacing");
@@ -1469,7 +1561,7 @@ void tst_QGraphicsLinearLayout::removeLayout()
void tst_QGraphicsLinearLayout::avoidRecursionInInsertItem()
{
QGraphicsWidget window(0, Qt::Window);
- QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window);
+ QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window);
QCOMPARE(layout->count(), 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert itself");
layout->insertItem(0, layout);
diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
index 92de2c6733..d3f6c2db00 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp
@@ -1230,17 +1230,17 @@ void tst_QGraphicsProxyWidget::mousePressReleaseEvent()
view.resize(100, 100);
if (hasWidget) {
proxy->setWidget(widget);
- proxy->show();
+ proxy->show();
}
proxy->setPos(50, 0);
scene.addItem(proxy);
proxy->setFocus();
QTest::mousePress(view.viewport(), Qt::LeftButton, 0,
- view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
+ view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
QTRY_COMPARE(spy.count(), 0);
QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0,
- view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
+ view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
QTRY_COMPARE(spy.count(), (hasWidget) ? 1 : 0);
if (!hasWidget)
@@ -1439,16 +1439,16 @@ class View : public QGraphicsView
{
public:
View(QGraphicsScene *scene, QWidget *parent = 0)
- : QGraphicsView(scene, parent), npaints(0)
+ : QGraphicsView(scene, parent), npaints(0)
{ }
QRegion paintEventRegion;
int npaints;
protected:
void paintEvent(QPaintEvent *event)
{
- ++npaints;
- paintEventRegion += event->region();
- QGraphicsView::paintEvent(event);
+ ++npaints;
+ paintEventRegion += event->region();
+ QGraphicsView::paintEvent(event);
}
};
@@ -1458,7 +1458,7 @@ class ScrollWidget : public QWidget
public:
ScrollWidget() : npaints(0)
{
- resize(200, 200);
+ resize(200, 200);
}
QRegion paintEventRegion;
int npaints;
@@ -1466,17 +1466,17 @@ public:
public slots:
void updateScroll()
{
- update(0, 0, 200, 10);
- scroll(0, 10, QRect(0, 0, 100, 20));
+ update(0, 0, 200, 10);
+ scroll(0, 10, QRect(0, 0, 100, 20));
}
protected:
void paintEvent(QPaintEvent *event)
{
- ++npaints;
- paintEventRegion += event->region();
- QPainter painter(this);
- painter.fillRect(event->rect(), Qt::blue);
+ ++npaints;
+ paintEventRegion += event->region();
+ QPainter painter(this);
+ painter.fillRect(event->rect(), Qt::blue);
}
};
@@ -1502,7 +1502,7 @@ void tst_QGraphicsProxyWidget::scrollUpdate()
// QRect(0, 12, 102, 10) is the scroll update, expanded (-2, -2, 2, 2),
// intersected with the above update.
QCOMPARE(view.paintEventRegion.rects(),
- QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
+ QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
QCOMPARE(widget->npaints, 2);
QCOMPARE(widget->paintEventRegion.rects(),
QVector<QRect>() << QRect(0, 0, 200, 12) << QRect(0, 12, 102, 10));
@@ -2458,7 +2458,7 @@ void tst_QGraphicsProxyWidget::popup_basic()
QComboBox *box = new QComboBox;
box->setGeometry(0, 0, 320, 40);
box->addItems(QStringList() << "monday" << "tuesday" << "wednesday"
- << "thursday" << "saturday" << "sunday");
+ << "thursday" << "saturday" << "sunday");
QCOMPARE(proxy->childItems().count(), 0);
proxy->setWidget(box);
proxy->show();
@@ -2472,7 +2472,7 @@ void tst_QGraphicsProxyWidget::popup_basic()
QApplication::processEvents();
QTest::mousePress(view.viewport(), Qt::LeftButton, 0,
- view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
+ view.mapFromScene(proxy->mapToScene(proxy->boundingRect().center())));
QTRY_COMPARE(box->pos(), QPoint());
@@ -2511,7 +2511,7 @@ void tst_QGraphicsProxyWidget::popup_subwidget()
QComboBox *box = new QComboBox;
box->addItems(QStringList() << "monday" << "tuesday" << "wednesday"
- << "thursday" << "saturday" << "sunday");
+ << "thursday" << "saturday" << "sunday");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(new QLineEdit("QLineEdit"));
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro
index 8d00931ef1..a6022e0d7d 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/qgraphicsscene.pro
@@ -4,7 +4,7 @@ QT += widgets widgets-private testlib
QT += core-private gui-private
SOURCES += tst_qgraphicsscene.cpp
RESOURCES += images.qrc
-win32:!wince*: LIBS += -luser32
+win32:!wince*:!winrt: LIBS += -luser32
!wince*:DEFINES += SRCDIR=\\\"$$PWD\\\"
DEFINES += QT_NO_CAST_TO_ASCII
diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
index 15c92663ec..dfc8465210 100644
--- a/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
+++ b/tests/auto/widgets/graphicsview/qgraphicsscene/tst_qgraphicsscene.cpp
@@ -54,7 +54,7 @@
#include "../../../shared/platforminputcontext.h"
#include <private/qinputmethod_p.h>
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#include <windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index d4aad98ae9..c3aaf6be16 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -216,10 +216,10 @@ private slots:
void persistentEditorFocus();
void setItemDelegate();
void setItemDelegate_data();
- // The dragAndDrop() test doesn't work, and is thus disabled on Mac and Windows
- // for the following reasons:
- // Mac: use of GetCurrentEventButtonState() in QDragManager::drag()
- // Win: unknown reason
+ // The dragAndDrop() test doesn't work, and is thus disabled on Mac and Windows
+ // for the following reasons:
+ // Mac: use of GetCurrentEventButtonState() in QDragManager::drag()
+ // Win: unknown reason
#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN)
#if 0
void dragAndDrop();
diff --git a/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro b/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro
index 8bc1bf2412..2cc8e9ea01 100644
--- a/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro
+++ b/tests/auto/widgets/itemviews/qcolumnview/qcolumnview.pro
@@ -4,4 +4,5 @@ QT += widgets widgets-private
QT += gui-private core-private testlib
SOURCES += tst_qcolumnview.cpp
+HEADERS += ../../../../shared/fakedirmodel.h
TARGET = tst_qcolumnview
diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
index e2b2fb9551..1ed33b9233 100644
--- a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
+++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp
@@ -39,14 +39,12 @@
**
****************************************************************************/
-
+#include "../../../../shared/fakedirmodel.h"
#include <QtTest/QtTest>
-#include <qstandarditemmodel.h>
#include <qitemdelegate.h>
#include <qcolumnview.h>
#include <private/qcolumnviewgrip_p.h>
#include <private/qfilesystemmodel_p.h>
-#include <qdirmodel.h>
#include <qstringlistmodel.h>
#include <qdebug.h>
#include <qitemdelegate.h>
@@ -64,6 +62,7 @@ public:
virtual ~tst_QColumnView();
public Q_SLOTS:
+ void initTestCase();
void init();
void cleanup();
@@ -107,6 +106,10 @@ private slots:
protected slots:
void setPreviewWidget();
+
+private:
+ QStandardItemModel m_fakeDirModel;
+ QModelIndex m_fakeDirHomeIndex;
};
class TreeModel : public QStandardItemModel
@@ -182,12 +185,20 @@ protected:
tst_QColumnView::tst_QColumnView()
{
+ QStandardItem *homeItem = populateFakeDirModel(&m_fakeDirModel);
+ m_fakeDirHomeIndex = m_fakeDirModel.indexFromItem(homeItem);
}
tst_QColumnView::~tst_QColumnView()
{
}
+void tst_QColumnView::initTestCase()
+{
+ QVERIFY(m_fakeDirHomeIndex.isValid());
+ QVERIFY(m_fakeDirModel.rowCount(m_fakeDirHomeIndex) > 1); // Needs some entries in 'home'.
+}
+
void tst_QColumnView::init()
{
qApp->setLayoutDirection(Qt::LeftToRight);
@@ -268,8 +279,7 @@ void tst_QColumnView::rootIndex()
void tst_QColumnView::grips()
{
QColumnView view;
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
QCOMPARE(view.resizeGripsVisible(), true);
view.setResizeGripsVisible(true);
@@ -304,8 +314,7 @@ void tst_QColumnView::isIndexHidden()
ColumnView view;
QModelIndex idx;
QCOMPARE(view.IsIndexHidden(idx), false);
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
QCOMPARE(view.IsIndexHidden(idx), false);
}
@@ -313,22 +322,20 @@ void tst_QColumnView::indexAt()
{
QColumnView view;
QCOMPARE(view.indexAt(QPoint(0,0)), QModelIndex());
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
- QModelIndex home = model.index(QDir::homePath());
- QModelIndex homeFile = model.index(0, 0, home);
+ QModelIndex homeFile = m_fakeDirModel.index(0, 0, m_fakeDirHomeIndex);
if (!homeFile.isValid())
return;
- view.setRootIndex(home);
+ view.setRootIndex(m_fakeDirHomeIndex);
QRect rect = view.visualRect(QModelIndex());
QVERIFY(!rect.isValid());
rect = view.visualRect(homeFile);
QVERIFY(rect.isValid());
QModelIndex child;
- for (int i = 0; i < model.rowCount(home); ++i) {
- child = model.index(i, 0, home);
+ for (int i = 0; i < m_fakeDirModel.rowCount(m_fakeDirHomeIndex); ++i) {
+ child = m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex);
rect = view.visualRect(child);
QVERIFY(rect.isValid());
if (i > 0)
@@ -341,8 +348,8 @@ void tst_QColumnView::indexAt()
QTest::qWait(200);
// test that the second row doesn't start at 0
- if (model.rowCount(child) > 0) {
- child = model.index(0, 0, child);
+ if (m_fakeDirModel.rowCount(child) > 0) {
+ child = m_fakeDirModel.index(0, 0, child);
QVERIFY(child.isValid());
rect = view.visualRect(child);
QVERIFY(rect.isValid());
@@ -363,9 +370,9 @@ void tst_QColumnView::scrollContentsBy_data()
void tst_QColumnView::scrollContentsBy()
{
QFETCH(bool, reverse);
- if (reverse)
- qApp->setLayoutDirection(Qt::RightToLeft);
ColumnView view;
+ if (reverse)
+ view.setLayoutDirection(Qt::RightToLeft);
view.ScrollContentsBy(-1, -1);
view.ScrollContentsBy(0, 0);
@@ -398,9 +405,9 @@ void tst_QColumnView::scrollTo()
{
QFETCH(bool, reverse);
QFETCH(bool, giveFocus);
- if (reverse)
- qApp->setLayoutDirection(Qt::RightToLeft);
QWidget topLevel;
+ if (reverse)
+ topLevel.setLayoutDirection(Qt::RightToLeft);
ColumnView view(&topLevel);
view.resize(200, 200);
topLevel.show();
@@ -507,57 +514,57 @@ void tst_QColumnView::moveCursor_data()
void tst_QColumnView::moveCursor()
{
QFETCH(bool, reverse);
- if (reverse)
- qApp->setLayoutDirection(Qt::RightToLeft);
ColumnView view;
-
+ if (reverse)
+ view.setLayoutDirection(Qt::RightToLeft);
// don't crash
view.MoveCursor(ColumnView::MoveUp, Qt::NoModifier);
// don't do anything
QCOMPARE(view.MoveCursor(ColumnView::MoveEnd, Qt::NoModifier), QModelIndex());
- QDirModel model;
- view.setModel(&model);
- QModelIndex home = model.index(QDir::homePath());
+ view.setModel(&m_fakeDirModel);
QModelIndex ci = view.currentIndex();
QCOMPARE(view.MoveCursor(ColumnView::MoveUp, Qt::NoModifier), QModelIndex());
QCOMPARE(view.MoveCursor(ColumnView::MoveDown, Qt::NoModifier), QModelIndex());
// left at root
- view.setCurrentIndex(model.index(0,0));
+ view.setCurrentIndex(m_fakeDirModel.index(0,0));
ColumnView::PublicCursorAction action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft;
- QCOMPARE(view.MoveCursor(action, Qt::NoModifier), model.index(0,0));
+ QCOMPARE(view.MoveCursor(action, Qt::NoModifier), m_fakeDirModel.index(0,0));
// left shouldn't move up
int i = 0;
- ci = model.index(0, 0);
- while (i < model.rowCount() - 1 && !model.hasChildren(ci))
- ci = model.index(++i, 0);
- QVERIFY(model.hasChildren(ci));
+ ci = m_fakeDirModel.index(0, 0);
+ while (i < m_fakeDirModel.rowCount() - 1 && !m_fakeDirModel.hasChildren(ci))
+ ci = m_fakeDirModel.index(++i, 0);
+ QVERIFY(m_fakeDirModel.hasChildren(ci));
view.setCurrentIndex(ci);
action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft;
QCOMPARE(view.MoveCursor(action, Qt::NoModifier), ci);
// now move to the left (i.e. move over one column)
- view.setCurrentIndex(home);
- QCOMPARE(view.MoveCursor(action, Qt::NoModifier), home.parent());
+ view.setCurrentIndex(m_fakeDirHomeIndex);
+ QCOMPARE(view.MoveCursor(action, Qt::NoModifier), m_fakeDirHomeIndex.parent());
// right
action = reverse ? ColumnView::MoveLeft : ColumnView::MoveRight;
view.setCurrentIndex(ci);
QModelIndex mc = view.MoveCursor(action, Qt::NoModifier);
- QCOMPARE(mc, model.index(0,0, ci));
+ QCOMPARE(mc, m_fakeDirModel.index(0,0, ci));
- // next one should move down
- QModelIndex idx = model.index(0, 0, ci);
- while (model.hasChildren(idx) && model.rowCount(ci) > idx.row() + 1)
+ // for empty directories (no way to go 'right'), next one should move down
+ QModelIndex idx = m_fakeDirModel.index(0, 0, ci);
+ const int rowCount = m_fakeDirModel.rowCount(ci);
+ while (m_fakeDirModel.hasChildren(idx) && rowCount > idx.row() + 1) {
idx = idx.sibling(idx.row() + 1, idx.column());
+ }
+ static const char error[] = "This test requires an empty directory followed by another directory.";
+ QVERIFY2(idx.isValid(), error);
+ QVERIFY2(!m_fakeDirModel.hasChildren(idx), error);
+ QVERIFY2(idx.row() + 1 < rowCount, error);
view.setCurrentIndex(idx);
mc = view.MoveCursor(action, Qt::NoModifier);
-#ifdef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-23697", Continue);
-#endif
QCOMPARE(mc, idx.sibling(idx.row() + 1, idx.column()));
}
@@ -566,20 +573,18 @@ void tst_QColumnView::selectAll()
ColumnView view;
view.selectAll();
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
view.selectAll();
QVERIFY(view.selectionModel()->selectedIndexes().count() >= 0);
- QModelIndex home = model.index(QDir::homePath());
- view.setCurrentIndex(home);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
view.selectAll();
QVERIFY(view.selectionModel()->selectedIndexes().count() > 0);
QModelIndex file;
- for (int i = 0; i < model.rowCount(home); ++i)
- if (!model.hasChildren(model.index(i, 0, home))) {
- file = model.index(i, 0, home);
+ for (int i = 0; i < m_fakeDirModel.rowCount(m_fakeDirHomeIndex); ++i)
+ if (!m_fakeDirModel.hasChildren(m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex))) {
+ file = m_fakeDirModel.index(i, 0, m_fakeDirHomeIndex);
break;
}
view.setCurrentIndex(file);
@@ -594,22 +599,19 @@ void tst_QColumnView::clicked()
{
ColumnView view;
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
view.resize(800,300);
view.show();
- QModelIndex home = model.index(QDir::homePath());
- QVERIFY(home.isValid());
- view.setCurrentIndex(home);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
QTest::qWait(ANIMATION_DELAY);
- QModelIndex parent = home.parent();
+ QModelIndex parent = m_fakeDirHomeIndex.parent();
QVERIFY(parent.isValid());
QSignalSpy clickedSpy(&view, SIGNAL(clicked(QModelIndex)));
- QPoint localPoint = view.visualRect(home).center();
+ QPoint localPoint = view.visualRect(m_fakeDirHomeIndex).center();
QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, localPoint);
QCOMPARE(clickedSpy.count(), 1);
qApp->processEvents();
@@ -619,7 +621,7 @@ void tst_QColumnView::clicked()
for (int i = 0; i < view.createdColumns.count(); ++i) {
QAbstractItemView *column = view.createdColumns.at(i);
- if (column && column->selectionModel() && (column->rootIndex() == home))
+ if (column && column->selectionModel() && (column->rootIndex() == m_fakeDirHomeIndex))
QVERIFY(column->selectionModel()->selectedIndexes().isEmpty());
}
}
@@ -627,13 +629,11 @@ void tst_QColumnView::clicked()
void tst_QColumnView::selectedColumns()
{
ColumnView view;
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
view.resize(800,300);
view.show();
- QModelIndex home = model.index(QDir::homePath());
- view.setCurrentIndex(home);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
QTest::qWait(ANIMATION_DELAY);
@@ -641,7 +641,7 @@ void tst_QColumnView::selectedColumns()
QAbstractItemView *column = view.createdColumns.at(i);
if (!column)
continue;
- if (!column->rootIndex().isValid() || column->rootIndex() == home)
+ if (!column->rootIndex().isValid() || column->rootIndex() == m_fakeDirHomeIndex)
continue;
QTRY_VERIFY(column->currentIndex().isValid());
}
@@ -658,15 +658,13 @@ void tst_QColumnView::setSelection()
void tst_QColumnView::setSelectionModel()
{
ColumnView view;
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
view.show();
- QModelIndex home = model.index(QDir::homePath());
- view.setCurrentIndex(home);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
QTest::qWait(ANIMATION_DELAY);
- QItemSelectionModel *selectionModel = new QItemSelectionModel(&model);
+ QItemSelectionModel *selectionModel = new QItemSelectionModel(&m_fakeDirModel);
view.setSelectionModel(selectionModel);
bool found = false;
@@ -686,19 +684,10 @@ void tst_QColumnView::visualRegionForSelection()
QCOMPARE(QRegion(), view.getVisualRegionForSelection(emptyItemSelection));
// a region that isn't empty
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
- // On Windows CE the home directory might actually be empty.
-#ifndef Q_OS_WINCE
- QString location = QDir::homePath();
-#else
- QString location = QLatin1String("/Windows");
-#endif
- QModelIndex home = model.index(location);
- QVERIFY(model.rowCount(home) > 1);
- QItemSelection itemSelection(model.index(0, 0, home), model.index(model.rowCount(home) - 1, 0, home));
+ QItemSelection itemSelection(m_fakeDirModel.index(0, 0, m_fakeDirHomeIndex), m_fakeDirModel.index(m_fakeDirModel.rowCount(m_fakeDirHomeIndex) - 1, 0, m_fakeDirHomeIndex));
QVERIFY(QRegion() != view.getVisualRegionForSelection(itemSelection));
}
@@ -732,9 +721,9 @@ void tst_QColumnView::moveGrip_data()
void tst_QColumnView::moveGrip()
{
QFETCH(bool, reverse);
- if (reverse)
- qApp->setLayoutDirection(Qt::RightToLeft);
QWidget topLevel;
+ if (reverse)
+ topLevel.setLayoutDirection(Qt::RightToLeft);
ColumnView view(&topLevel);
TreeModel model;
view.setModel(&model);
@@ -871,10 +860,8 @@ void tst_QColumnView::sizes()
view.setColumnWidths(newSizes);
QCOMPARE(view.columnWidths(), visibleSizes);
- QDirModel model;
- view.setModel(&model);
- QModelIndex home = model.index(QDir::homePath());
- view.setCurrentIndex(home);
+ view.setModel(&m_fakeDirModel);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
QList<int> postSizes = view.columnWidths().mid(0, newSizes.count());
QCOMPARE(postSizes, newSizes.mid(0, postSizes.count()));
@@ -895,8 +882,7 @@ void tst_QColumnView::rowDelegate()
QItemDelegate *d = new QItemDelegate;
view.setItemDelegateForRow(3, d);
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
for (int i = 0; i < view.createdColumns.count(); ++i) {
QAbstractItemView *column = view.createdColumns.at(i);
QCOMPARE(column->itemDelegateForRow(3), (QAbstractItemDelegate*)d);
@@ -908,13 +894,11 @@ void tst_QColumnView::resize()
{
QWidget topLevel;
ColumnView view(&topLevel);
- QDirModel model;
- view.setModel(&model);
+ view.setModel(&m_fakeDirModel);
view.resize(200, 200);
topLevel.show();
- QModelIndex home = model.index(QDir::homePath()).parent();
- view.setCurrentIndex(home);
+ view.setCurrentIndex(m_fakeDirHomeIndex);
QTest::qWait(ANIMATION_DELAY);
view.resize(200, 300);
QTest::qWait(ANIMATION_DELAY);
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro
index cb935fd2fd..313cadd6a1 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro
+++ b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro
@@ -3,4 +3,4 @@ TARGET = tst_qitemdelegate
QT += widgets testlib
SOURCES += tst_qitemdelegate.cpp
-win32:!wince*: LIBS += -luser32
+win32:!wince*:!winrt: LIBS += -luser32
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
index 439725b257..addb226101 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
+++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp
@@ -66,7 +66,7 @@
Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint)
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
#include <windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
diff --git a/tests/auto/widgets/itemviews/qlistview/qlistview.pro b/tests/auto/widgets/itemviews/qlistview/qlistview.pro
index 413304bdcf..1ea8beb8df 100644
--- a/tests/auto/widgets/itemviews/qlistview/qlistview.pro
+++ b/tests/auto/widgets/itemviews/qlistview/qlistview.pro
@@ -2,4 +2,4 @@ CONFIG += testcase
TARGET = tst_qlistview
QT += widgets gui-private widgets-private core-private testlib
SOURCES += tst_qlistview.cpp
-win32:!wince*: LIBS += -luser32
+win32:!wince*:!winrt: LIBS += -luser32
diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
index 268276bd4a..9f5484983d 100644
--- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
+++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp
@@ -1484,7 +1484,7 @@ void tst_QListView::wordWrap()
QTRY_COMPARE(lv.verticalScrollBar()->isVisible(), true);
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
class SetCurrentIndexAfterAppendRowCrashDialog : public QDialog
{
Q_OBJECT
@@ -1525,7 +1525,7 @@ private:
};
#endif
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && WINVER >= 0x0500
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) && WINVER >= 0x0500
// This test only makes sense on windows 2000 and higher.
void tst_QListView::setCurrentIndexAfterAppendRowCrash()
{
diff --git a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
index 42975cfb5e..153144db63 100644
--- a/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
+++ b/tests/auto/widgets/itemviews/qlistwidget/tst_qlistwidget.cpp
@@ -1646,29 +1646,29 @@ void tst_QListWidget::QTBUG8086_currentItemChangedOnClick()
class ItemDelegate : public QItemDelegate
{
public:
- ItemDelegate(QObject *parent = 0) : QItemDelegate(parent)
- {}
- virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
- {
- QLineEdit *lineEdit = new QLineEdit(parent);
- lineEdit->setFrame(false);
- QCompleter *completer = new QCompleter(QStringList() << "completer", lineEdit);
- completer->setCompletionMode(QCompleter::InlineCompletion);
- lineEdit->setCompleter(completer);
- return lineEdit;
- }
+ ItemDelegate(QObject *parent = 0) : QItemDelegate(parent)
+ {}
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
+ {
+ QLineEdit *lineEdit = new QLineEdit(parent);
+ lineEdit->setFrame(false);
+ QCompleter *completer = new QCompleter(QStringList() << "completer", lineEdit);
+ completer->setCompletionMode(QCompleter::InlineCompletion);
+ lineEdit->setCompleter(completer);
+ return lineEdit;
+ }
};
void tst_QListWidget::QTBUG14363_completerWithAnyKeyPressedEditTriggers()
{
- QListWidget listWidget;
- listWidget.setEditTriggers(QAbstractItemView::AnyKeyPressed);
+ QListWidget listWidget;
+ listWidget.setEditTriggers(QAbstractItemView::AnyKeyPressed);
listWidget.setItemDelegate(new ItemDelegate);
QListWidgetItem *item = new QListWidgetItem(QLatin1String("select an item (don't start editing)"), &listWidget);
item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable|Qt::ItemIsEditable);
new QListWidgetItem(QLatin1String("try to type the letter 'c'"), &listWidget);
new QListWidgetItem(QLatin1String("completer"), &listWidget);
- listWidget.show();
+ listWidget.show();
listWidget.setCurrentItem(item);
qApp->setActiveWindow(&listWidget);
QVERIFY(QTest::qWaitForWindowActive(&listWidget));
diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
index 4afe80b087..38367fb4ee 100644
--- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
+++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp
@@ -1645,7 +1645,7 @@ void tst_QTableView::selection()
view.setColumnWidth(c, columnWidth);
view.setSelection(QRect(x, y, width, height),
- QItemSelectionModel::SelectionFlags(command));
+ QItemSelectionModel::SelectionFlags(command));
QCOMPARE(view.selectedIndexes().count(), selectedCount);
}
@@ -2952,7 +2952,7 @@ void tst_QTableView::span()
if (hiddenRow > -1) {
QModelIndex hidden = model.index(hiddenRow, columnCount - 1);
- QVERIFY(view.isIndexHidden(hidden));
+ QVERIFY(view.isIndexHidden(hidden));
}
if (hiddenColumn > -1) {
@@ -3599,7 +3599,7 @@ void tst_QTableView::task173773_updateVerticalHeader()
void tst_QTableView::task227953_setRootIndex()
{
- QTableView tableView;
+ QTableView tableView;
//model = tree with two items with tables as children
QStandardItemModel model;
@@ -3621,16 +3621,16 @@ void tst_QTableView::task227953_setRootIndex()
//show the first 10 rows of the first table
QModelIndex root = model.indexFromItem(&item1);
- tableView.setRootIndex(root);
- for (int i = 10; i != 40; ++i) {
- tableView.setRowHidden(i, true);
- }
+ tableView.setRootIndex(root);
+ for (int i = 10; i != 40; ++i) {
+ tableView.setRowHidden(i, true);
+ }
QCOMPARE(tableView.verticalHeader()->count(), 40);
QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 30);
- //show the first 10 rows of the second table
- tableView.setRootIndex(model.indexFromItem(&item2));
+ //show the first 10 rows of the second table
+ tableView.setRootIndex(model.indexFromItem(&item2));
QCOMPARE(tableView.verticalHeader()->count(), 10);
QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 0);
@@ -3672,8 +3672,8 @@ void tst_QTableView::task248688_autoScrollNavigation()
QTableView view;
view.setModel(&model);
- view.hideColumn(8);
- view.hideRow(8);
+ view.hideColumn(8);
+ view.hideRow(8);
view.show();
for (int r = 0; r < model.rowCount(); ++r) {
if (view.isRowHidden(r))
diff --git a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro
index 001331c0cf..3abd58e73d 100644
--- a/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro
+++ b/tests/auto/widgets/itemviews/qtreeview/qtreeview.pro
@@ -3,4 +3,4 @@ TARGET = tst_qtreeview
QT += widgets testlib
QT += widgets-private gui-private core-private
SOURCES += tst_qtreeview.cpp
-
+HEADERS += ../../../../shared/fakedirmodel.h
diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
index ccdce1fe0c..b07009aa3c 100644
--- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
+++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "../../../../shared/fakedirmodel.h"
#include <qabstractitemview.h>
#include <QtTest/QtTest>
#include <QtGui/QtGui>
@@ -3719,7 +3720,9 @@ void tst_QTreeView::task246536_scrollbarsNotWorking()
void tst_QTreeView::task250683_wrongSectionSize()
{
- QDirModel model;
+ QStandardItemModel model;
+ populateFakeDirModel(&model);
+
QTreeView treeView;
treeView.header()->setSectionResizeMode(QHeaderView::ResizeToContents);
treeView.setModel(&model);
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
index 83ba1ddcda..dfa7592813 100644
--- a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -1467,14 +1467,14 @@ void tst_QTreeWidget::keyboardNavigation()
QVector<Qt::Key> keymoves;
keymoves << Qt::Key_Down << Qt::Key_Right << Qt::Key_Left
- << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down
- << Qt::Key_Right
- << Qt::Key_Up << Qt::Key_Left << Qt::Key_Left
- << Qt::Key_Up << Qt::Key_Down << Qt::Key_Up << Qt::Key_Up
- << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up
+ << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down
+ << Qt::Key_Right
+ << Qt::Key_Up << Qt::Key_Left << Qt::Key_Left
+ << Qt::Key_Up << Qt::Key_Down << Qt::Key_Up << Qt::Key_Up
+ << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up
<< Qt::Key_Down << Qt::Key_Right << Qt::Key_Down << Qt::Key_Down
<< Qt::Key_Down << Qt::Key_Right << Qt::Key_Down << Qt::Key_Down
- << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down
+ << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down
<< Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Left
<< Qt::Key_Down << Qt::Key_Right << Qt::Key_Right << Qt::Key_Right
<< Qt::Key_Left << Qt::Key_Left << Qt::Key_Right << Qt::Key_Left;
@@ -1499,16 +1499,16 @@ void tst_QTreeWidget::keyboardNavigation()
switch (key) {
case Qt::Key_Up:
- if (row > 0) {
+ if (row > 0) {
if (item->parent())
item = item->parent()->child(row - 1);
else
item = testWidget->topLevelItem(row - 1);
- row -= 1;
- } else if (item->parent()) {
- item = item->parent();
- row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);
- }
+ row -= 1;
+ } else if (item->parent()) {
+ item = item->parent();
+ row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);
+ }
break;
case Qt::Key_Down:
if (testWidget->isItemExpanded(item)) {
@@ -1537,7 +1537,7 @@ void tst_QTreeWidget::keyboardNavigation()
case Qt::Key_Right:
if (checkScroll)
QCOMPARE(scrollBar->value(), valueBeforeClick + scrollBar->singleStep());
- // windows style right will walk to the first child
+ // windows style right will walk to the first child
if (testWidget->currentItem() != item) {
QCOMPARE(testWidget->currentItem()->parent(), item);
row = item->indexOfChild(testWidget->currentItem());
@@ -1758,9 +1758,7 @@ void tst_QTreeWidget::setData()
QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
QCOMPARE(qvariant_cast<int>(args.at(1)), j);
item->setIcon(j, icon);
- // #### shouldn't cause dataChanged()
- QCOMPARE(itemChangedSpy.count(), 1);
- itemChangedSpy.clear();
+ QCOMPARE(itemChangedSpy.count(), 0);
QString toolTip = QString("toolTip %0").arg(i);
item->setToolTip(j, toolTip);
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index 091927abe4..9d7d3d1f34 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -179,6 +179,8 @@ private slots:
void globalStaticObjectDestruction(); // run this last
void abortQuitOnShow();
+
+ void settableStyleHints(); // Needs to run last as it changes style hints.
};
class EventSpy : public QObject
@@ -286,7 +288,7 @@ public:
TestApplication( int &argc, char **argv )
: QApplication( argc, argv)
{
- startTimer( 150 );
+ startTimer( 150 );
}
void timerEvent( QTimerEvent * )
@@ -336,24 +338,24 @@ void tst_QApplication::multiple()
int i = 0;
int argc = 0;
- while ( i++ < 5 ) {
- TestApplication app( argc, 0 );
-
- if ( features.contains( "QFont" ) ) {
- // create font and force loading
- QFont font( "Arial", 12 );
- QFontInfo finfo( font );
- finfo.exactMatch();
- }
- if ( features.contains( "QPixmap" ) ) {
- QPixmap pix( 100, 100 );
- pix.fill( Qt::black );
- }
- if ( features.contains( "QWidget" ) ) {
- QWidget widget;
- }
-
- QVERIFY(!app.exec());
+ while (i++ < 5) {
+ TestApplication app(argc, 0);
+
+ if (features.contains("QFont")) {
+ // create font and force loading
+ QFont font("Arial", 12);
+ QFontInfo finfo(font);
+ finfo.exactMatch();
+ }
+ if (features.contains("QPixmap")) {
+ QPixmap pix(100, 100);
+ pix.fill(Qt::black);
+ }
+ if (features.contains("QWidget")) {
+ QWidget widget;
+ }
+
+ QVERIFY(!app.exec());
}
}
@@ -382,29 +384,29 @@ void tst_QApplication::setFont_data()
QFontDatabase fdb;
QStringList families = fdb.families();
for (QStringList::const_iterator itr = families.begin();
- itr != families.end();
- ++itr) {
- if (cnt < 3) {
- QString family = *itr;
- QStringList styles = fdb.styles(family);
- if (styles.size() > 0) {
- QString style = styles.first();
- QList<int> sizes = fdb.pointSizes(family, style);
- if (!sizes.size())
- sizes = fdb.standardSizes();
- if (sizes.size() > 0) {
- QTest::newRow(QString("data%1a").arg(cnt).toLatin1().constData())
- << family
- << sizes.first()
+ itr != families.end();
+ ++itr) {
+ if (cnt < 3) {
+ QString family = *itr;
+ QStringList styles = fdb.styles(family);
+ if (styles.size() > 0) {
+ QString style = styles.first();
+ QList<int> sizes = fdb.pointSizes(family, style);
+ if (!sizes.size())
+ sizes = fdb.standardSizes();
+ if (sizes.size() > 0) {
+ QTest::newRow(QString("data%1a").arg(cnt).toLatin1().constData())
+ << family
+ << sizes.first()
<< false;
- QTest::newRow(QString("data%1b").arg(cnt).toLatin1().constData())
- << family
- << sizes.first()
+ QTest::newRow(QString("data%1b").arg(cnt).toLatin1().constData())
+ << family
+ << sizes.first()
<< true;
}
- }
- }
- ++cnt;
+ }
+ }
+ ++cnt;
}
QTest::newRow("nonexistingfont after") << "nosuchfont_probably_quiteunlikely"
@@ -450,7 +452,7 @@ void tst_QApplication::args_data()
QTest::newRow( "No arguments" ) << 0 << QString() << 0 << QString();
QTest::newRow( "App name, style" ) << 3 << "/usr/bin/appname -style windows" << 1 << "/usr/bin/appname";
QTest::newRow( "App name, style, arbitrary, reverse" ) << 5 << "/usr/bin/appname -style windows -arbitrary -reverse"
- << 2 << "/usr/bin/appname -arbitrary";
+ << 2 << "/usr/bin/appname -arbitrary";
}
void tst_QApplication::task109149()
@@ -489,14 +491,14 @@ static QString cstrings2QString( char **args )
{
QString string;
if ( !args )
- return string;
+ return string;
int i = 0;
while ( args[i] ) {
- string += args[i];
- if ( args[i+1] )
- string += " ";
- ++i;
+ string += args[i];
+ if ( args[i+1] )
+ string += " ";
+ ++i;
}
return string;
}
@@ -1949,7 +1951,7 @@ void tst_QApplication::windowsCommandLine_data()
void tst_QApplication::windowsCommandLine()
{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
QFETCH(QString, args);
QFETCH(QString, expected);
@@ -2305,6 +2307,22 @@ void tst_QApplication::abortQuitOnShow()
QCOMPARE(app.exec(), 1);
}
+void tst_QApplication::settableStyleHints()
+{
+ int argc = 0;
+ QApplication app(argc, 0);
+ QApplication::setCursorFlashTime(437);
+ QCOMPARE(QApplication::cursorFlashTime(), 437);
+ QApplication::setDoubleClickInterval(128);
+ QCOMPARE(QApplication::doubleClickInterval(), 128);
+ QApplication::setStartDragDistance(122000);
+ QCOMPARE(QApplication::startDragDistance(), 122000);
+ QApplication::setStartDragTime(834);
+ QCOMPARE(QApplication::startDragTime(), 834);
+ QApplication::setKeyboardInputInterval(309);
+ QCOMPARE(QApplication::keyboardInputInterval(), 309);
+}
+
/*
This test is meant to ensure that certain objects (public & commonly used)
can safely be used in a Q_GLOBAL_STATIC such that their destructors are
@@ -2314,7 +2332,9 @@ Q_GLOBAL_STATIC(QLocale, tst_qapp_locale);
#ifndef QT_NO_PROCESS
Q_GLOBAL_STATIC(QProcess, tst_qapp_process);
#endif
+#ifndef QT_NO_FILESYSTEMWATCHER
Q_GLOBAL_STATIC(QFileSystemWatcher, tst_qapp_fileSystemWatcher);
+#endif
#ifndef QT_NO_SHAREDMEMORY
Q_GLOBAL_STATIC(QSharedMemory, tst_qapp_sharedMemory);
#endif
@@ -2337,7 +2357,9 @@ void tst_QApplication::globalStaticObjectDestruction()
#ifndef QT_NO_PROCESS
QVERIFY(tst_qapp_process());
#endif
+#ifndef QT_NO_FILESYSTEMWATCHER
QVERIFY(tst_qapp_fileSystemWatcher());
+#endif
#ifndef QT_NO_SHAREDMEMORY
QVERIFY(tst_qapp_sharedMemory());
#endif
diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
index d04b812878..9df7e1662d 100644
--- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
+++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp
@@ -263,7 +263,7 @@ void tst_QFormLayout::wrapping()
{
QWidget *w = new QWidget;
QFormLayout *fl = new QFormLayout(w);
- fl->setRowWrapPolicy(QFormLayout::WrapLongRows);
+ fl->setRowWrapPolicy(QFormLayout::WrapLongRows);
QLineEdit *le = new QLineEdit;
QLabel *lbl = new QLabel("A long label");
diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
index e067b071e7..1003a9fb1f 100644
--- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
+++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp
@@ -974,8 +974,8 @@ QRect CustomLayoutStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_GroupBoxLayoutItem:
rect = opt->rect.adjusted(0, +10, 0, 0);
break;
- default:
- break;
+ default:
+ break;
}
}
if (rect.isNull())
diff --git a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp
index 962fd3a8ab..306b049467 100644
--- a/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp
+++ b/tests/auto/widgets/kernel/qshortcut/tst_qshortcut.cpp
@@ -160,7 +160,7 @@ class TestEdit : public QTextEdit
Q_OBJECT
public:
TestEdit(QWidget *parent, const char *name)
- : QTextEdit(parent)
+ : QTextEdit(parent)
{
setObjectName(name);
}
@@ -231,13 +231,13 @@ Qt::KeyboardModifiers tst_QShortcut::toButtons( int key )
{
Qt::KeyboardModifiers result = Qt::NoModifier;
if ( key & Qt::SHIFT )
- result |= Qt::ShiftModifier;
+ result |= Qt::ShiftModifier;
if ( key & Qt::CTRL )
- result |= Qt::ControlModifier;
- if ( key & Qt::META )
- result |= Qt::MetaModifier;
- if ( key & Qt::ALT )
- result |= Qt::AltModifier;
+ result |= Qt::ControlModifier;
+ if ( key & Qt::META )
+ result |= Qt::MetaModifier;
+ if ( key & Qt::ALT )
+ result |= Qt::AltModifier;
return result;
}
@@ -291,15 +291,15 @@ void tst_QShortcut::number_data()
Shift + Qt::Key_Plus on Qt::Key_Pluss
Qt::Key_Plus on Qt::Key_Pluss
*/
- QTest::newRow("N001 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N001 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("N001:Shift + M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N001 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ //QTest::newRow("N001:Shift + M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N001 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("N001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N001 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("N001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N001 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_M on Shift + Qt::Key_M
@@ -307,32 +307,32 @@ void tst_QShortcut::number_data()
Shift + Qt::Key_Plus on Shift + Qt::Key_Pluss
Qt::Key_Plus on Shift + Qt::Key_Pluss
*/
- QTest::newRow("N002 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N002 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N002 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N002 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N002 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N002 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_F1 on Qt::Key_F1
Qt::Key_F1 on Qt::Key_F1
*/
- QTest::newRow("N003 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N003 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("N003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N003 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("N003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N003 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_F1 on Shift + Qt::Key_F1
Qt::Key_F1 on Shift + Qt::Key_F1
*/
- QTest::newRow("N004 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N004 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N004 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N004:Shift+F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N004 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_Tab on Qt::Key_Tab
@@ -340,14 +340,14 @@ void tst_QShortcut::number_data()
Qt::Key_Backtab on Qt::Key_Tab
Shift + Qt::Key_Backtab on Qt::Key_Tab
*/
- QTest::newRow("N005a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005a:Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N005a - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005a:Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("N005a:Shift+Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ //QTest::newRow("N005a:Shift+Tab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
// (Shift+)BackTab != Tab, but Shift+BackTab == Shift+Tab
- QTest::newRow("N005a:Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005a:Shift+Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005a - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N005a:Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005a:Shift+Backtab - [Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005a - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_Tab on Shift + Qt::Key_Tab
@@ -355,12 +355,12 @@ void tst_QShortcut::number_data()
Qt::Key_Backtab on Shift + Qt::Key_Tab
Shift + Qt::Key_Backtab on Shift + Qt::Key_Tab
*/
- QTest::newRow("N005b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005b:Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005b:Shift+Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N005b:BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N005b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N005b - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005b:Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005b:Shift+Tab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N005b:BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N005b:Shift+BackTab - [Shift+Tab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N005b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_Tab on Qt::Key_Backtab
@@ -368,15 +368,15 @@ void tst_QShortcut::number_data()
Qt::Key_Backtab on Qt::Key_Backtab
Shift + Qt::Key_Backtab on Qt::Key_Backtab
*/
- QTest::newRow("N006a - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N006a:Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N006a - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N006a:Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
// This should work, since platform dependent code will transform the
// Shift+Tab into a Shift+BackTab, which should trigger the shortcut
- QTest::newRow("N006a:Shift+Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
- QTest::newRow("N006a:BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N006a:Shift+Tab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
+ QTest::newRow("N006a:BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("N006a:Shift+BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N006a - clear") << ClearAll << NoWidget<< QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("N006a:Shift+BackTab - [BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N006a - clear") << ClearAll << NoWidget<< QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_Tab on Shift + Qt::Key_Backtab
@@ -384,12 +384,12 @@ void tst_QShortcut::number_data()
Qt::Key_Backtab on Shift + Qt::Key_Backtab
Shift + Qt::Key_Backtab on Shift + Qt::Key_Backtab
*/
- QTest::newRow("N006b - slot1") << SetupAccel << TriggerSlot1 << QString("")<< int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N006b:Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N006b:BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N006b:Shift+BackTab - [Shift+BackTab]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
- QTest::newRow("N006b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N006b - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N006b:Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N006b:Shift+Tab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Tab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N006b:BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N006b:Shift+BackTab - [Shift+BackTab]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Backtab) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered; //XFAIL
+ QTest::newRow("N006b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
//===========================================
// [Shift + key] and [key] on shortcuts with
@@ -400,11 +400,11 @@ void tst_QShortcut::number_data()
Qt::Key_F1
Shift + Qt::Key_F1
*/
- QTest::newRow("N007 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N007 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N007 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N007 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N007 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N007 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_M
@@ -412,51 +412,51 @@ void tst_QShortcut::number_data()
Ctrl + Qt::Key_M
Alt + Qt::Key_M
*/
- QTest::newRow("N01 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N02 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N03 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N04 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N:Shift+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N:Ctrl+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N:Alt+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N01 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N02 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N03 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N04 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N:Shift+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N:Ctrl+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N:Alt+Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
/* Testing Single Sequence Ambiguity
Qt::Key_M on shortcut2
*/
- QTest::newRow("N05 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N:Qt::Key_M on slot") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
- QTest::newRow("N05 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N05 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N:Qt::Key_M on slot") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
+ QTest::newRow("N05 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Specialkeys
Qt::Key_aring
Qt::Key_Aring
Qt::UNICODE_ACCEL + Qt::Key_K
*/
- QTest::newRow("N06 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N07 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N08 - slot2") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N06 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N07 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N08 - slot2") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N:Qt::UNICODE_ACCEL + Qt::Key_K") << TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N09 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N:Qt::UNICODE_ACCEL + Qt::Key_K")<< TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N09 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Multiple Sequences
Qt::Key_M
Qt::Key_I, Qt::Key_M
Shift+Qt::Key_I, Qt::Key_M
*/
- QTest::newRow("N10 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N11 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("N12 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
-
- QTest::newRow("N:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("N:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("N13 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("N10 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N11 - slot2") << SetupAccel << TriggerSlot2 << QString("") << int(Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("N12 - slot1") << SetupAccel << TriggerSlot1 << QString("") << int(Qt::SHIFT + Qt::Key_I) << 0 << int(Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << NoResult;
+
+ QTest::newRow("N:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("N:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("N13 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
}
// ------------------------------------------------------------------
@@ -478,15 +478,15 @@ void tst_QShortcut::text_data()
Shift + Qt::Key_Plus on Qt::Key_Pluss
Qt::Key_Plus on Qt::Key_Pluss
*/
- QTest::newRow("T001 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T001 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("T001:Shift+M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T001 - slot2") << SetupAccel << TriggerSlot2 << QString("+") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ //QTest::newRow("T001:Shift+M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T001:M - [M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T001 - slot2") << SetupAccel << TriggerSlot2 << QString("+") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("T001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T001 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("T001:Shift++ [+]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T001:+ [+]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T001 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_M on Shift + Qt::Key_M
@@ -496,44 +496,44 @@ void tst_QShortcut::text_data()
Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Pluss
*/
- QTest::newRow("T002 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T002 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T002 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T002 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002:Shift+M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T002:M - [Shift+M]") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002:Shift++ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T002:+ [Shift++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
Ctrl + Qt::Key_Plus on Ctrl + Qt::Key_Plus
- Qt::Key_Plus on Ctrl + Qt::Key_Plus
+ Qt::Key_Plus on Ctrl + Qt::Key_Plus
*/
- QTest::newRow("T002b - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002b - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl++") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("T002b:Shift+Ctrl++ [Ctrl++]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T002b:Ctrl++ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T002b:+ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T002b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("T002b:Shift+Ctrl++ [Ctrl++]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T002b:Ctrl++ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T002b:+ [Ctrl++]") << TestAccel << NoWidget << QString("") << int(Qt::Key_Plus) << int('+') << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T002b - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_F1 on Qt::Key_F1
Qt::Key_F1 on Qt::Key_F1
*/
- QTest::newRow("T003 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T003 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
//commented out because the behaviour changed, those tests should be updated
- //QTest::newRow("T003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T003 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ //QTest::newRow("T003:Shift+F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T003:F1 - [F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T003 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Shift + Qt::Key_F1 on Shift + Qt::Key_F1
Qt::Key_F1 on Shift + Qt::Key_F1
*/
- QTest::newRow("T004 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T004:Shift+F1 - [Shift+F1]")<< TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T004 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T004 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T004:Shift+F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T004:F1 - [Shift+F1]") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T004 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
//===========================================
// [Shift + key] and [key] on shortcuts with
@@ -544,11 +544,11 @@ void tst_QShortcut::text_data()
Qt::Key_F1
Shift + Qt::Key_F1
*/
- QTest::newRow("T007 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T007 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T007 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T007 - slot1") << SetupAccel << TriggerSlot1 << QString("F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T007 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+F1") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T007:F1") << TestAccel << NoWidget << QString("") << int(Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T007:Shift + F1") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_F1) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T007 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Sequences
Qt::Key_M
@@ -556,22 +556,22 @@ void tst_QShortcut::text_data()
Ctrl + Qt::Key_M
Alt + Qt::Key_M
*/
- QTest::newRow("T01 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T02 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T03 - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T04 - slot2") << SetupAccel << TriggerSlot2 << QString("Alt+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T01 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T02 - slot2") << SetupAccel << TriggerSlot2 << QString("Shift+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T03 - slot1") << SetupAccel << TriggerSlot1 << QString("Ctrl+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T04 - slot2") << SetupAccel << TriggerSlot2 << QString("Alt+M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T:Shift + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T:Ctrl + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T:Alt + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T:Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T:Shift + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_M) << int('M') << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T:Ctrl + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::CTRL + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T:Alt + Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::ALT + Qt::Key_M) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
/* Testing Single Sequence Ambiguity
Qt::Key_M on shortcut2
*/
- QTest::newRow("T05 - slot2") << SetupAccel << TriggerSlot2 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T:Qt::Key_M on TriggerSlot2") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
- QTest::newRow("T06 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T05 - slot2") << SetupAccel << TriggerSlot2 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T:Qt::Key_M on TriggerSlot2") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Ambiguous;
+ QTest::newRow("T06 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Single Specialkeys
Qt::Key_aring
@@ -581,26 +581,26 @@ void tst_QShortcut::text_data()
/* see comments above on the #ifdef'ery */
QTest::newRow("T06 - slot1") << SetupAccel << TriggerSlot1 << QString::fromLatin1("\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
QTest::newRow("T07 - slot2") << SetupAccel << TriggerSlot2 << QString::fromLatin1("Shift+\x0C5")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T08 - slot2") << SetupAccel << TriggerSlot1 << QString("K") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T:Qt::UNICODE_ACCEL + Qt::Key_K") << TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T09 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T08 - slot2") << SetupAccel << TriggerSlot1 << QString("K") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T:Qt::Key_aring") << TestAccel << NoWidget << QString("") << int(Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T:Qt::Key_Aring") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+Qt::Key_Aring) << 0 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T:Qt::Key_aring - Text Form") << TestAccel << NoWidget << QString("") << 0 << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T:Qt::Key_Aring - Text Form") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT+0) << 0xC5 << 0 << 0 << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T:Qt::UNICODE_ACCEL + Qt::Key_K")<< TestAccel << NoWidget << QString("") << int(Qt::UNICODE_ACCEL + Qt::Key_K) << int('k') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T09 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
/* Testing Multiple Sequences
Qt::Key_M
Qt::Key_I, Qt::Key_M
Shift+Qt::Key_I, Qt::Key_M
*/
- QTest::newRow("T10 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T11 - slot2") << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T12 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
- QTest::newRow("T:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered;
- QTest::newRow("T:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered;
- QTest::newRow("T13 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
+ QTest::newRow("T10 - slot1") << SetupAccel << TriggerSlot1 << QString("M") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T11 - slot2") << SetupAccel << TriggerSlot2 << QString("I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T12 - slot1") << SetupAccel << TriggerSlot1 << QString("Shift+I, M")<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult;
+ QTest::newRow("T:Qt::Key_M (2)") << TestAccel << NoWidget << QString("") << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T:Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::Key_I) << int('i') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot2Triggered;
+ QTest::newRow("T:Shift+Qt::Key_I, Qt::Key_M") << TestAccel << NoWidget << QString("") << int(Qt::SHIFT + Qt::Key_I) << int('I') << int(Qt::Key_M) << int('m') << 0 << 0 << 0 << 0 << Slot1Triggered;
+ QTest::newRow("T13 - clear") << ClearAll << NoWidget << QString("") << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << NoResult; // Clear all
}
// ------------------------------------------------------------------
@@ -624,7 +624,7 @@ void tst_QShortcut::disabledItems()
QPushButton pb2(mainW);
pb1.setObjectName("pushbutton-1");
pb2.setObjectName("pushbutton-2");
- pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
+ pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
pb2.show();
QShortcut *cut1 = setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
@@ -700,21 +700,21 @@ void tst_QShortcut::disabledItems()
sendKeyEvents( Qt::CTRL+Qt::Key_Q, 0 );
QCOMPARE( currentResult, NoResult );
if (over_330)
- QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") );
+ QCOMPARE( sbText, QString("Ctrl+K, Ctrl+Q not defined") );
currentResult = NoResult;
sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
sendKeyEvents( Qt::CTRL+Qt::Key_M, 0 );
QCOMPARE( currentResult, NoResult );
if (over_330)
- QCOMPARE( sbText, QString::null );
+ QCOMPARE( sbText, QString::null );
currentResult = NoResult;
sendKeyEvents( Qt::CTRL+Qt::Key_K, 0 );
sendKeyEvents( Qt::CTRL+Qt::Key_L, 0 );
QCOMPARE( currentResult, Slot1Triggered );
if (over_330)
- QCOMPARE( sbText, QString::null );
+ QCOMPARE( sbText, QString::null );
#endif
clearAllShortcuts();
cut1 = 0;
@@ -876,7 +876,7 @@ void tst_QShortcut::ambiguousItems()
QPushButton pb2(mainW);
pb1.setObjectName("pushbutton-1");
pb2.setObjectName("pushbutton-2");
- pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
+ pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
pb2.show();
setupShortcut(&pb1, "shortcut1-pb1", TriggerSlot1, "M");
@@ -915,7 +915,7 @@ void tst_QShortcut::unicodeCompare()
QPushButton pb2(mainW);
pb1.setObjectName("pushbutton-1");
pb2.setObjectName("pushbutton-2");
- pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
+ pb1.show(); // Must be show for QShortcutMap::correctSubWindow to trigger
pb2.show();
QKeySequence ks1("Ctrl+M"); // Unicode
@@ -1190,25 +1190,25 @@ void tst_QShortcut::sendKeyEvents(QWidget *w, int k1, QChar c1, int k2, QChar c2
if (k1 || c1.toLatin1()) {
QString c(c1.unicode() == QChar::Null ? QString() : QString(c1));
QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k1), c, b1);
- QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1);
+ QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k1), c, b1);
}
if (k2 || c2.toLatin1()) {
QString c(c2.unicode() == QChar::Null ? QString() : QString(c2));
- QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2);
- QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2);
+ QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k2), c, b2);
+ QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k2), c, b2);
}
if (k3 || c3.toLatin1()) {
QString c(c3.unicode() == QChar::Null ? QString() : QString(c3));
- QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3);
- QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3);
+ QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k3), c, b3);
+ QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k3), c, b3);
}
if (k4 || c4.toLatin1()) {
QString c(c4.unicode() == QChar::Null ? QString() : QString(c4));
- QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4);
- QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4);
+ QTest::sendKeyEvent(QTest::Press, w, static_cast<Qt::Key>(k4), c, b4);
+ QTest::sendKeyEvent(QTest::Release, w, static_cast<Qt::Key>(k4), c, b4);
}
}
@@ -1229,9 +1229,9 @@ void tst_QShortcut::testElement()
QFETCH(tst_QShortcut::Result, result);
if (action == ClearAll) {
- clearAllShortcuts();
+ clearAllShortcuts();
} else if (action == SetupAccel) {
- setupShortcut(testWidget, txt, k1, k2, k3, k4);
+ setupShortcut(testWidget, txt, k1, k2, k3, k4);
} else {
sendKeyEvents(k1, c1, k2, c2, k3, c3, k4, c4);
QCOMPARE(currentResult, result);
diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro
index a4fcde8a34..3eedfa1d3a 100644
--- a/tests/auto/widgets/kernel/qwidget/qwidget.pro
+++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro
@@ -20,7 +20,7 @@ x11 {
LIBS += $$QMAKE_LIBS_X11
}
-!wince*:win32: LIBS += -luser32 -lgdi32
+!wince*:win32:!winrt: LIBS += -luser32 -lgdi32
mac:CONFIG+=insignificant_test # QTBUG-25300, QTBUG-23695
linux-*:system(". /etc/lsb-release && [ $DISTRIB_CODENAME = oneiric ]"):DEFINES+=UBUNTU_ONEIRIC # QTBUG-30566 \ No newline at end of file
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 9090f97ce6..21e0286086 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -117,11 +117,13 @@ static bool qt_wince_is_platform(const QString &platformString) {
}
static inline bool qt_wince_is_smartphone() { return qt_wince_is_platform(QString::fromLatin1("Smartphone")); }
# endif // Q_OS_WINCE_WM
-# else // Q_OS_WINCE
+# elif !defined(Q_OS_WINRT) // Q_OS_WINCE
# define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
QSKIP("desktop is not visible, this test would fail");
-# endif // !Q_OS_WINCE
+# else // !Q_OS_WINCE && !Q_OS_WINRT
+# define Q_CHECK_PAINTEVENTS
+# endif // Q_OS_WINRT
#else // Q_OS_WIN
# define Q_CHECK_PAINTEVENTS
#endif // else Q_OS_WIN
@@ -304,7 +306,7 @@ private slots:
void subtractOpaqueSiblings();
#endif
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void setGeometry_win();
#endif
@@ -374,7 +376,7 @@ private slots:
void quitOnCloseAttribute();
void moveRect();
-#if defined (Q_OS_WIN)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINRT)
void gdiPainting();
void paintOnScreenPossible();
#endif
@@ -592,7 +594,7 @@ void tst_QWidget::getSetCheck()
QCOMPARE(true, obj1.autoFillBackground());
var1.reset();
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
obj1.setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint);
const HWND handle = reinterpret_cast<HWND>(obj1.winId()); // explicitly create window handle
QVERIFY(GetWindowLong(handle, GWL_STYLE) & WS_POPUP);
@@ -667,7 +669,7 @@ void tst_QWidget::cleanup()
// Helper class...
BezierViewer::BezierViewer( QWidget* parent)
- : QWidget( parent )
+ : QWidget(parent)
{
setObjectName(QLatin1String("TestWidget"));
setWindowTitle(objectName());
@@ -687,9 +689,9 @@ void BezierViewer::paintEvent( QPaintEvent* )
{
if ( points.size() != 4 ) {
#if defined(QT_CHECK_RANGE)
- qWarning( "QPolygon::bezier: The array must have 4 control points" );
+ qWarning( "QPolygon::bezier: The array must have 4 control points" );
#endif
- return;
+ return;
}
/* Calculate Bezier curve */
@@ -705,18 +707,18 @@ void BezierViewer::paintEvent( QPaintEvent* )
/* Scale Bezier curve vertices */
for ( QPolygonF::Iterator it = bezier.begin(); it != bezier.end(); ++it ) {
- it->setX( (it->x()-br.x()) * scl + border );
- it->setY( (it->y()-br.y()) * scl + border );
+ it->setX( (it->x()-br.x()) * scl + border );
+ it->setY( (it->y()-br.y()) * scl + border );
}
/* Draw grid */
painter.setPen( Qt::lightGray );
- int i;
- for ( i = border; i <= pr.width(); i += scl ) {
- painter.drawLine( i, 0, i, pr.height() );
+ int i;
+ for ( i = border; i <= pr.width(); i += scl ) {
+ painter.drawLine( i, 0, i, pr.height() );
}
for ( int j = border; j <= pr.height(); j += scl ) {
- painter.drawLine( 0, j, pr.width(), j );
+ painter.drawLine( 0, j, pr.width(), j );
}
/* Write number of vertices */
@@ -734,17 +736,17 @@ void BezierViewer::paintEvent( QPaintEvent* )
/* Scale and draw control points */
painter.setPen( Qt::darkGreen );
for ( QPolygonF::Iterator p1 = points.begin(); p1 != points.end(); ++p1 ) {
- int x = (p1->x()-br.x()) * scl + border;
- int y = (p1->y()-br.y()) * scl + border;
- painter.drawLine( x-4, y-4, x+4, y+4 );
- painter.drawLine( x+4, y-4, x-4, y+4 );
+ int x = (p1->x()-br.x()) * scl + border;
+ int y = (p1->y()-br.y()) * scl + border;
+ painter.drawLine( x-4, y-4, x+4, y+4 );
+ painter.drawLine( x+4, y-4, x-4, y+4 );
}
/* Draw vertices */
painter.setPen( Qt::red );
painter.setBrush( Qt::red );
for ( QPolygonF::Iterator p2 = bezier.begin(); p2 != bezier.end(); ++p2 )
- painter.drawEllipse( p2->x()-1, p2->y()-1, 3, 3 );
+ painter.drawEllipse( p2->x()-1, p2->y()-1, 3, 3 );
}
void tst_QWidget::fontPropagation()
@@ -1283,7 +1285,7 @@ void tst_QWidget::visible_setWindowOpacity()
testWidget->hide();
QVERIFY( !testWidget->isVisible() );
testWidget->setWindowOpacity(0.5);
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
QVERIFY(!::IsWindowVisible(winHandleOf(testWidget)));
#endif
testWidget->setWindowOpacity(1.0);
@@ -1675,17 +1677,17 @@ public:
Container()
{
box = new QVBoxLayout(this);
- //(new QVBoxLayout(this))->setAutoAdd(true);
+ //(new QVBoxLayout(this))->setAutoAdd(true);
}
void tab()
{
- focusNextPrevChild(true);
+ focusNextPrevChild(true);
}
void backTab()
{
- focusNextPrevChild(false);
+ focusNextPrevChild(false);
}
};
@@ -1710,7 +1712,7 @@ public:
setFocusProxy( lineEdit );
setFocusPolicy( Qt::StrongFocus );
- setTabOrder(lineEdit, button);
+ setTabOrder(lineEdit, button);
}
private:
@@ -1759,9 +1761,9 @@ void tst_QWidget::setTabOrder()
QTRY_VERIFY(lastEdit->hasFocus());
container.tab();
do {
- QVERIFY(comp[current]->focusProxy()->hasFocus());
- container.tab();
- current--;
+ QVERIFY(comp[current]->focusProxy()->hasFocus());
+ container.tab();
+ current--;
} while (current >= 0);
QVERIFY(firstEdit->hasFocus());
@@ -3623,7 +3625,7 @@ void tst_QWidget::optimizedResize_topLevel()
topLevel.partial = false;
topLevel.paintedRegion = QRegion();
-#ifndef Q_OS_WIN
+#if !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE)
topLevel.resize(topLevel.size() + QSize(10, 10));
#else
// Static contents does not work when programmatically resizing
@@ -4555,7 +4557,7 @@ void tst_QWidget::setWindowGeometry()
}
}
-#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void tst_QWidget::setGeometry_win()
{
QWidget widget;
@@ -4573,7 +4575,7 @@ void tst_QWidget::setGeometry_win()
QVERIFY(rt.left <= 0);
QVERIFY(rt.top <= 0);
}
-#endif // defined (Q_OS_WIN) && !defined(Q_OS_WINCE)
+#endif // defined (Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
// Since X11 WindowManager operation are all async, and we have no way to know if the window
// manager has finished playing with the window geometry, this test can't be reliable on X11.
@@ -4814,73 +4816,68 @@ static inline QByteArray msgRgbMismatch(unsigned actual, unsigned expected)
QByteArrayLiteral(" != 0x") + QByteArray::number(expected, 16);
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
-QT_BEGIN_NAMESPACE
-extern Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
-QT_END_NAMESPACE
-
-// grabs the window *without including any overlapping windows*
-static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height)
-{
- const HWND hwnd = (HWND)window->winId();
-
- // Create and setup bitmap
- const HDC displayDc = ::GetDC(0);
- const HDC bitmapDc = ::CreateCompatibleDC(displayDc);
- const HBITMAP bitmap = ::CreateCompatibleBitmap(displayDc, width, height);
- const HGDIOBJ oldBitmap = ::SelectObject(bitmapDc, bitmap);
-
- // copy data
- const HDC windowDc = ::GetDC(hwnd);
- ::BitBlt(bitmapDc, 0, 0, width, height, windowDc, x, y, SRCCOPY);
-
- // clean up all but bitmap
- ::ReleaseDC(hwnd, windowDc);
- ::SelectObject(bitmapDc, oldBitmap);
- ::DeleteDC(bitmapDc);
-
- const QPixmap pixmap = qt_pixmapFromWinHBITMAP(bitmap);
-
- ::DeleteObject(bitmap);
- ::ReleaseDC(0, displayDc);
-
- return pixmap;
-}
-#else
-// fallback for other platforms.
static QPixmap grabWindow(QWindow *window, int x, int y, int width, int height)
{
QScreen *screen = window->screen();
return screen ? screen->grabWindow(window->winId(), x, y, width, height) : QPixmap();
}
-#endif //defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
-
-#define VERIFY_COLOR(child, region, color) do { \
- const QRegion r = QRegion(region); \
- QWindow *window = child.window()->windowHandle(); \
- Q_ASSERT(window); \
- const QPoint offset = child.mapTo(child.window(), QPoint(0,0)); \
- for (int i = 0; i < r.rects().size(); ++i) { \
- const QRect rect = r.rects().at(i).translated(offset); \
- for (int t = 0; t < 5; t++) { \
- const QPixmap pixmap = grabWindow(window, \
- rect.left(), rect.top(), \
- rect.width(), rect.height()); \
- QCOMPARE(pixmap.size(), rect.size()); \
- QPixmap expectedPixmap(pixmap); /* ensure equal formats */ \
- expectedPixmap.detach(); \
- expectedPixmap.fill(color); \
- QImage image = pixmap.toImage(); \
- uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; \
- uint firstPixel = image.pixel(0,0) | alphaCorrection; \
- if ( firstPixel != QColor(color).rgb() && t < 4 ) \
- { QTest::qWait(200); continue; } \
- QVERIFY2(firstPixel == QColor(color).rgb(), msgRgbMismatch(firstPixel, QColor(color).rgb())); \
- QCOMPARE(pixmap, expectedPixmap); \
- break; \
- } \
- } \
-} while (0)
+
+#define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__)
+
+bool verifyColor(QWidget &child, const QRegion &region, const QColor &color, unsigned int callerLine)
+{
+ const QRegion r = QRegion(region);
+ QWindow *window = child.window()->windowHandle();
+ Q_ASSERT(window);
+ const QPoint offset = child.mapTo(child.window(), QPoint(0,0));
+ bool grabBackingStore = false;
+ for (int i = 0; i < r.rects().size(); ++i) {
+ QRect rect = r.rects().at(i).translated(offset);
+ for (int t = 0; t < 6; t++) {
+ const QPixmap pixmap = grabBackingStore
+ ? child.grab(rect)
+ : grabWindow(window, rect.left(), rect.top(), rect.width(), rect.height());
+ if (!QTest::qCompare(pixmap.size(), rect.size(), "pixmap.size()", "rect.size()", __FILE__, callerLine))
+ return false;
+ QPixmap expectedPixmap(pixmap); /* ensure equal formats */
+ expectedPixmap.detach();
+ expectedPixmap.fill(color);
+ QImage image = pixmap.toImage();
+ uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0;
+ uint firstPixel = image.pixel(0,0) | alphaCorrection;
+ if (t < 5) {
+ /* Normal run.
+ If it succeeds: return success
+ If it fails: do not return, but wait a bit and reiterate (retry)
+ */
+ if (firstPixel == QColor(color).rgb()
+ && image == expectedPixmap.toImage()) {
+ return true;
+ } else {
+ if (t == 4) {
+ grabBackingStore = true;
+ rect = r.rects().at(i);
+ } else {
+ QTest::qWait(200);
+ }
+ }
+ } else {
+ // Last run, report failure if it still fails
+ if (!QTest::qVerify(firstPixel == QColor(color).rgb(),
+ "firstPixel == QColor(color).rgb()",
+ qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())),
+ __FILE__, callerLine))
+ return false;
+ if (!QTest::qVerify(image == expectedPixmap.toImage(),
+ "image == expectedPixmap.toImage()",
+ "grabbed pixmap differs from expected pixmap",
+ __FILE__, callerLine))
+ return false;
+ }
+ }
+ }
+ return true;
+}
void tst_QWidget::popupEnterLeave()
{
@@ -5348,17 +5345,17 @@ void tst_QWidget::setFocus()
}
}
-class EventSpy : public QObject
+template<class T> class EventSpy : public QObject
{
public:
- EventSpy(QWidget *widget, QEvent::Type event)
+ EventSpy(T *widget, QEvent::Type event)
: m_widget(widget), eventToSpy(event), m_count(0)
{
if (m_widget)
m_widget->installEventFilter(this);
}
- QWidget *widget() const { return m_widget; }
+ T *widget() const { return m_widget; }
int count() const { return m_count; }
void clear() { m_count = 0; }
@@ -5371,7 +5368,7 @@ protected:
}
private:
- QWidget *m_widget;
+ T *m_widget;
QEvent::Type eventToSpy;
int m_count;
};
@@ -5486,7 +5483,7 @@ void tst_QWidget::setCursor()
// test if CursorChange is sent
{
QWidget widget;
- EventSpy spy(&widget, QEvent::CursorChange);
+ EventSpy<QWidget> spy(&widget, QEvent::CursorChange);
QCOMPARE(spy.count(), 0);
widget.setCursor(QCursor(Qt::WaitCursor));
QCOMPARE(spy.count(), 1);
@@ -5508,7 +5505,7 @@ void tst_QWidget::setToolTip()
widget.setWindowTitle(widget.objectName());
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
- EventSpy spy(&widget, QEvent::ToolTipChange);
+ EventSpy<QWidget> spy(&widget, QEvent::ToolTipChange);
QCOMPARE(spy.count(), 0);
QCOMPARE(widget.toolTip(), QString());
@@ -5530,8 +5527,8 @@ void tst_QWidget::setToolTip()
QFrame *frame = new QFrame(popup.data());
frame->setGeometry(0, 0, 50, 50);
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
- EventSpy spy1(frame, QEvent::ToolTip);
- EventSpy spy2(popup.data(), QEvent::ToolTip);
+ EventSpy<QWidget> spy1(frame, QEvent::ToolTip);
+ EventSpy<QWidget> spy2(popup.data(), QEvent::ToolTip);
frame->setMouseTracking(pass == 0 ? false : true);
frame->setToolTip(QLatin1String("TOOLTIP FRAME"));
popup->setToolTip(QLatin1String("TOOLTIP POPUP"));
@@ -5553,7 +5550,8 @@ void tst_QWidget::setToolTip()
void tst_QWidget::testWindowIconChangeEventPropagation()
{
- typedef QSharedPointer<EventSpy> EventSpyPtr;
+ typedef QSharedPointer<EventSpy<QWidget> > EventSpyPtr;
+ typedef QSharedPointer<EventSpy<QWindow> > WindowEventSpyPtr;
// Create widget hierarchy.
QWidget topLevelWidget;
QWidget topLevelChild(&topLevelWidget);
@@ -5566,12 +5564,27 @@ void tst_QWidget::testWindowIconChangeEventPropagation()
<< &dialog << &dialogChild;
QCOMPARE(widgets.count(), 4);
+ topLevelWidget.show();
+ dialog.show();
+
+ QWindowList windows;
+ windows << topLevelWidget.windowHandle() << dialog.windowHandle();
+ QWindow otherWindow;
+ windows << &otherWindow;
+ const int lastWidgetWindow = 1; // 0 and 1 are qwidgetwindow, 2 is a pure qwindow
+
// Create spy lists.
QList <EventSpyPtr> applicationEventSpies;
QList <EventSpyPtr> widgetEventSpies;
foreach (QWidget *widget, widgets) {
- applicationEventSpies.append(EventSpyPtr(new EventSpy(widget, QEvent::ApplicationWindowIconChange)));
- widgetEventSpies.append(EventSpyPtr(new EventSpy(widget, QEvent::WindowIconChange)));
+ applicationEventSpies.append(EventSpyPtr(new EventSpy<QWidget>(widget, QEvent::ApplicationWindowIconChange)));
+ widgetEventSpies.append(EventSpyPtr(new EventSpy<QWidget>(widget, QEvent::WindowIconChange)));
+ }
+ QList <WindowEventSpyPtr> appWindowEventSpies;
+ QList <WindowEventSpyPtr> windowEventSpies;
+ foreach (QWindow *window, windows) {
+ appWindowEventSpies.append(WindowEventSpyPtr(new EventSpy<QWindow>(window, QEvent::ApplicationWindowIconChange)));
+ windowEventSpies.append(WindowEventSpyPtr(new EventSpy<QWindow>(window, QEvent::WindowIconChange)));
}
// QApplication::setWindowIcon
@@ -5595,6 +5608,20 @@ void tst_QWidget::testWindowIconChangeEventPropagation()
QCOMPARE(spy->count(), 1);
spy->clear();
}
+ for (int i = 0; i < windows.count(); ++i) {
+ // Check QEvent::ApplicationWindowIconChange (sent to QWindow)
+ // QWidgetWindows don't get this event, since the widget takes care of changing the icon
+ WindowEventSpyPtr spy = appWindowEventSpies.at(i);
+ QWindow *window = spy->widget();
+ QCOMPARE(spy->count(), i > lastWidgetWindow ? 1 : 0);
+ QCOMPARE(window->icon(), windowIcon);
+ spy->clear();
+
+ // Check QEvent::WindowIconChange (sent to QWindow)
+ spy = windowEventSpies.at(i);
+ QCOMPARE(spy->count(), 1);
+ spy->clear();
+ }
// Set icon on a top-level widget.
topLevelWidget.setWindowIcon(QIcon());
@@ -8118,7 +8145,7 @@ void tst_QWidget::moveRect()
child.move(10, 10); // Don't crash.
}
-#ifdef Q_OS_WIN
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
class GDIWidget : public QDialog
{
Q_OBJECT
@@ -8185,7 +8212,7 @@ void tst_QWidget::paintOnScreenPossible()
w2.setAttribute(Qt::WA_PaintOnScreen);
QVERIFY(w2.testAttribute(Qt::WA_PaintOnScreen));
}
-#endif // Q_OS_WIN
+#endif // Q_OS_WIN && !Q_OS_WINRT
void tst_QWidget::reparentStaticWidget()
{
diff --git a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
index 93262722b9..523fac940d 100644
--- a/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
+++ b/tests/auto/widgets/widgets/qabstractbutton/tst_qabstractbutton.cpp
@@ -419,7 +419,7 @@ void tst_QAbstractButton::setIcon()
QPixmap p2( test2_xpm );
for ( int a = 0; a<5; a++ )
- testWidget->setIcon( p2 );
+ testWidget->setIcon( p2 );
QCOMPARE( testWidget->icon().pixmap(12, 8), p2 );
diff --git a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
index 14a8496b42..a3079cdaef 100644
--- a/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
+++ b/tests/auto/widgets/widgets/qcalendarwidget/tst_qcalendarwidget.cpp
@@ -185,7 +185,7 @@ void tst_QCalendarWidget::buttonClickCheck()
int month = object.monthShown();
QToolButton *button = object.findChild<QToolButton *>("qt_calendar_prevmonth");
QTest::mouseClick(button, Qt::LeftButton);
- QCOMPARE(month > 1 ? month-1 : 12, object.monthShown());
+ QCOMPARE(month > 1 ? month-1 : 12, object.monthShown());
button = object.findChild<QToolButton *>("qt_calendar_nextmonth");
QTest::mouseClick(button, Qt::LeftButton);
QCOMPARE(month, object.monthShown());
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index eabb7aaa17..509ccc37b6 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -162,6 +162,7 @@ private slots:
void highlightedSignal();
void itemData();
void task_QTBUG_31146_popupCompletion();
+ void keyboardSelection();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@@ -1848,7 +1849,7 @@ void tst_QComboBox::flaggedItems_data()
itemList << "nine" << "ten";
keyMovementList << Qt::Key_T;
- QTest::newRow(testCase.toLatin1() + "search same start letter") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 9;
+ QTest::newRow(testCase.toLatin1() + "search same start letter") << itemList << deselectFlagList << disableFlagList << keyMovementList << bool(editable) << 2;
keyMovementList.clear();
keyMovementList << Qt::Key_T << Qt::Key_H;
@@ -2946,5 +2947,32 @@ void tst_QComboBox::task_QTBUG_31146_popupCompletion()
QCOMPARE(comboBox.currentIndex(), 0);
}
+void tst_QComboBox::keyboardSelection()
+{
+ QComboBox comboBox;
+ const int keyboardInterval = QApplication::keyboardInputInterval();
+ QStringList list;
+ list << "OA" << "OB" << "OC" << "OO" << "OP" << "PP";
+ comboBox.addItems(list);
+
+ // Clear any remaining keyboard input from previous tests.
+ QTest::qWait(keyboardInterval);
+ QTest::keyClicks(&comboBox, "oo", Qt::NoModifier, 50);
+ QCOMPARE(comboBox.currentText(), list.at(3));
+
+ QTest::qWait(keyboardInterval);
+ QTest::keyClicks(&comboBox, "op", Qt::NoModifier, 50);
+ QCOMPARE(comboBox.currentText(), list.at(4));
+
+ QTest::keyClick(&comboBox, Qt::Key_P, Qt::NoModifier, keyboardInterval);
+ QCOMPARE(comboBox.currentText(), list.at(5));
+
+ QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
+ QCOMPARE(comboBox.currentText(), list.at(0));
+
+ QTest::keyClick(&comboBox, Qt::Key_O, Qt::NoModifier, keyboardInterval);
+ QCOMPARE(comboBox.currentText(), list.at(1));
+}
+
QTEST_MAIN(tst_QComboBox)
#include "tst_qcombobox.moc"
diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
index bfffa357a8..ded3e55283 100644
--- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
+++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp
@@ -346,7 +346,7 @@ void tst_QDateTimeEdit::cleanupTestCase()
void tst_QDateTimeEdit::init()
{
QLocale::setDefault(QLocale(QLocale::C));
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
SetThreadLocale(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT));
#endif
testWidget->setDisplayFormat("dd/MM/yyyy"); // Nice default to have
diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
index a4ad18c7a6..6551a88232 100644
--- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
+++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp
@@ -87,7 +87,7 @@ private slots:
void task248604_infiniteResize();
void task258459_visibilityChanged();
void taskQTBUG_1665_closableChanged();
- void taskQTBUG_9758_undockedGeometry();
+ void taskQTBUG_9758_undockedGeometry();
};
// Testing get/set functions
@@ -588,7 +588,7 @@ void tst_QDockWidget::visibilityChanged()
QCOMPARE(spy.count(), 0);
mw.addDockWidget(Qt::RightDockWidgetArea, &dw2);
- QTest::qWait(200);
+ QTest::qWait(200);
QCOMPARE(spy.count(), 1);
QCOMPARE(spy.at(0).at(0).toBool(), true);
}
@@ -758,19 +758,19 @@ void tst_QDockWidget::task169808_setFloating()
}
};
QMainWindow mw;
- mw.setCentralWidget(new MyWidget);
- QDockWidget *dw = new QDockWidget("my dock");
- dw->setWidget(new MyWidget);
- mw.addDockWidget(Qt::LeftDockWidgetArea, dw);
- dw->setFloating(true);
- mw.show();
+ mw.setCentralWidget(new MyWidget);
+ QDockWidget *dw = new QDockWidget("my dock");
+ dw->setWidget(new MyWidget);
+ mw.addDockWidget(Qt::LeftDockWidgetArea, dw);
+ dw->setFloating(true);
+ mw.show();
QVERIFY(QTest::qWaitForWindowExposed(&mw));
QCOMPARE(dw->widget()->size(), dw->widget()->sizeHint());
//and now we try to test if the contents margin is taken into account
dw->widget()->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- dw->setFloating(false);
+ dw->setFloating(false);
QVERIFY(QTest::qWaitForWindowExposed(&mw));
qApp->processEvents(); //leave time processing events
diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
index b880ebe078..6784ee477b 100644
--- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
+++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp
@@ -145,6 +145,9 @@ private slots:
void taskQTBUG_6670_selectAllWithPrefix();
void taskQTBUG_6496_fiddlingWithPrecision();
+ void setGroupSeparatorShown_data();
+ void setGroupSeparatorShown();
+
public slots:
void valueChangedHelper(const QString &);
void valueChangedHelper(double);
@@ -156,6 +159,9 @@ private:
typedef QList<double> DoubleList;
+Q_DECLARE_METATYPE(QLocale::Language)
+Q_DECLARE_METATYPE(QLocale::Country)
+
tst_QDoubleSpinBox::tst_QDoubleSpinBox()
{
@@ -634,7 +640,7 @@ void tst_QDoubleSpinBox::setDecimals()
QTest::keyClick(&spin, Qt::Key_1);
QTest::keyClick(&spin, Qt::Key_1);
QTest::keyClick(&spin, Qt::Key_1);
- if (sizeof(qreal) == sizeof(float))
+ if (sizeof(qreal) == sizeof(float))
QCOMPARE(spin.text().left(17), expected.left(17));
else
QCOMPARE(spin.text(), expected);
@@ -1099,5 +1105,45 @@ void tst_QDoubleSpinBox::taskQTBUG_6496_fiddlingWithPrecision()
QCOMPARE(dsb.maximum(), 0.991);
}
+void tst_QDoubleSpinBox::setGroupSeparatorShown_data()
+{
+ QTest::addColumn<QLocale::Language>("lang");
+ QTest::addColumn<QLocale::Country>("country");
+
+ QTest::newRow("data0") << QLocale::English << QLocale::UnitedStates;
+ QTest::newRow("data1") << QLocale::Swedish << QLocale::Sweden;
+ QTest::newRow("data2") << QLocale::German << QLocale::Germany;
+ QTest::newRow("data3") << QLocale::Georgian << QLocale::Georgia;
+ QTest::newRow("data3") << QLocale::Macedonian << QLocale::Macedonia;
+}
+
+void tst_QDoubleSpinBox::setGroupSeparatorShown()
+{
+ QFETCH(QLocale::Language, lang);
+ QFETCH(QLocale::Country, country);
+
+ QLocale loc(lang, country);
+ QLocale::setDefault(loc);
+ DoubleSpinBox spinBox;
+ spinBox.setMaximum(99999999);
+ spinBox.setValue(1300000.00);
+ spinBox.setGroupSeparatorShown(true);
+ QCOMPARE(spinBox.lineEdit()->text(), spinBox.locale().toString(1300000.00, 'f', 2));
+ QCOMPARE(spinBox.isGroupSeparatorShown(), true);
+ QCOMPARE(spinBox.textFromValue(23421),spinBox.locale().toString(23421.00, 'f', 2));
+
+ spinBox.setGroupSeparatorShown(false);
+ QCOMPARE(spinBox.lineEdit()->text(), spinBox.locale().toString(1300000.00, 'f', 2).remove(
+ spinBox.locale().groupSeparator()));
+ QCOMPARE(spinBox.isGroupSeparatorShown(), false);
+
+ spinBox.setMaximum(72000);
+ spinBox.lineEdit()->setText(spinBox.locale().toString(32000.64, 'f', 2));
+ QCOMPARE(spinBox.value()+1000, 33000.64);
+
+ spinBox.lineEdit()->setText(spinBox.locale().toString(32000.44, 'f', 2));
+ QCOMPARE(spinBox.value()+1000, 33000.44);
+}
+
QTEST_MAIN(tst_QDoubleSpinBox)
#include "tst_qdoublespinbox.moc"
diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
index 2fd15b891a..e3aa7fda51 100644
--- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
+++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp
@@ -189,9 +189,9 @@ void tst_QLabel::init()
void tst_QLabel::cleanup()
{
if (QTest::currentTestFunction() == QLatin1String("setBuddy")) {
- testWidget->show();
+ testWidget->show();
- delete test_box; // this should delete tst_labl and test_edit as well.
+ delete test_box; // this should delete tst_labl and test_edit as well.
}
}
diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
index a9f5cb686c..45167bac60 100644
--- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
+++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp
@@ -53,7 +53,7 @@
#include "qstandarditemmodel.h"
#include <qpa/qplatformtheme.h>
#include "qstylehints.h"
-#include <private/qguiapplication_p.h>
+#include <private/qapplication_p.h>
#include "qclipboard.h"
#ifdef Q_OS_MAC
@@ -71,6 +71,7 @@
#include <qstringlistmodel.h>
#include <qsortfilterproxymodel.h>
#include <qdebug.h>
+#include <qscreen.h>
#include "qcommonstyle.h"
#include "qstyleoption.h"
@@ -87,6 +88,17 @@ QT_BEGIN_NAMESPACE
class QPainter;
QT_END_NAMESPACE
+static inline void centerOnScreen(QWidget *w, const QSize &size)
+{
+ const QPoint offset = QPoint(size.width() / 2, size.height() / 2);
+ w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset);
+}
+
+static inline void centerOnScreen(QWidget *w)
+{
+ centerOnScreen(w, w->geometry().size());
+}
+
class StyleOptionTestStyle : public QCommonStyle
{
private:
@@ -300,6 +312,9 @@ private slots:
void clearButton();
void sideWidgets();
+ void shouldShowPlaceholderText_data();
+ void shouldShowPlaceholderText();
+
protected slots:
void editingFinished();
@@ -313,6 +328,7 @@ private:
// keyClicks(..) is moved to QtTestCase
void psKeyClick(QWidget *target, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
void psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardModifiers pressState = 0);
+ QLineEdit *ensureTestWidget();
bool validInput;
QString changed_string;
@@ -322,7 +338,7 @@ private:
int selection_count;
int lastCursorPos;
int newCursorPos;
- QLineEdit *testWidget;
+ QLineEdit *m_testWidget;
int m_keyboardScheme;
PlatformInputContext m_platformInputContext;
};
@@ -351,7 +367,7 @@ void tst_QLineEdit::getSetCheck()
QCOMPARE(true, obj1.dragEnabled());
}
-tst_QLineEdit::tst_QLineEdit() : validInput(false), m_keyboardScheme(0)
+tst_QLineEdit::tst_QLineEdit() : validInput(false), m_testWidget(0), m_keyboardScheme(0)
{
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
m_keyboardScheme = theme->themeHint(QPlatformTheme::KeyboardScheme).toInt();
@@ -367,23 +383,24 @@ tst_QLineEdit::~tst_QLineEdit()
{
}
+QLineEdit *tst_QLineEdit::ensureTestWidget()
+{
+ if (!m_testWidget) {
+ m_testWidget = new QLineEdit;
+ m_testWidget->setObjectName("testWidget");
+ connect(m_testWidget, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onCursorPositionChanged(int,int)));
+ connect(m_testWidget, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
+ connect(m_testWidget, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
+ connect(m_testWidget, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
+ connect(m_testWidget, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+ connect(m_testWidget, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
+ m_testWidget->resize(200,50);
+ }
+ return m_testWidget;
+}
+
void tst_QLineEdit::initTestCase()
{
- testWidget = new QLineEdit(0);
- testWidget->setObjectName("testWidget");
- connect(testWidget, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(onCursorPositionChanged(int,int)));
- connect(testWidget, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
- connect(testWidget, SIGNAL(textEdited(QString)), this, SLOT(onTextEdited(QString)));
- connect(testWidget, SIGNAL(returnPressed()), this, SLOT(onReturnPressed()));
- connect(testWidget, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- connect(testWidget, SIGNAL(editingFinished()), this, SLOT(editingFinished()));
-
- testWidget->resize(200,50);
- testWidget->show();
- QVERIFY(QTest::qWaitForWindowExposed(testWidget));
- QApplication::setActiveWindow(testWidget);
- QTRY_VERIFY(testWidget->hasFocus());
-
changed_count = 0;
edited_count = 0;
selection_count = 0;
@@ -394,7 +411,6 @@ void tst_QLineEdit::initTestCase()
void tst_QLineEdit::cleanupTestCase()
{
- delete testWidget;
QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
inputMethodPrivate->testContext = 0;
}
@@ -402,23 +418,17 @@ void tst_QLineEdit::cleanupTestCase()
void tst_QLineEdit::init()
{
return_count = 0;
- testWidget->clear();
- testWidget->setEchoMode(QLineEdit::Normal);
- testWidget->setMaxLength(32767);
- testWidget->setReadOnly(false);
- testWidget->setText("");
- testWidget->setInputMask("");
- testWidget->setFrame(true);
- testWidget->setValidator(0);
- testWidget->setDragEnabled(true);
}
void tst_QLineEdit::cleanup()
{
+ delete m_testWidget;
+ m_testWidget = 0;
}
void tst_QLineEdit::experimental()
{
+ QLineEdit *testWidget = ensureTestWidget();
QIntValidator intValidator(3, 7, 0);
testWidget->setValidator(&intValidator);
testWidget->setText("");
@@ -436,8 +446,7 @@ void tst_QLineEdit::experimental()
void tst_QLineEdit::upperAndLowercase()
{
- testWidget->setInputMask("");
- testWidget->setText("");
+ QLineEdit *testWidget = ensureTestWidget();
QTest::keyClicks(testWidget, "aAzZ`1234567890-=~!@#$%^&*()_+[]{}\\|;:'\",.<>/?");
qApp->processEvents();
@@ -659,6 +668,7 @@ void tst_QLineEdit::setInputMask()
QEXPECT_FAIL( "insert blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
// First set the input mask
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(mask);
// then either insert using insert() or keyboard
@@ -702,12 +712,14 @@ void tst_QLineEdit::inputMask()
QFETCH(QString, mask);
QFETCH(QString, expectedMask);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(mask);
QCOMPARE(testWidget->inputMask(), expectedMask);
}
void tst_QLineEdit::clearInputMask()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask("000.000.000.000");
QVERIFY(testWidget->inputMask() != QString::null);
testWidget->setInputMask(QString::null);
@@ -789,6 +801,7 @@ void tst_QLineEdit::keypress_inputMask()
QFETCH(QString, expectedText);
QFETCH(QString, expectedDisplayText);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(mask);
keys.simulate(testWidget);
@@ -825,6 +838,7 @@ void tst_QLineEdit::hasAcceptableInputMask()
QFETCH(QString, valid);
// test that invalid input (for required) work for optionalMask
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(optionalMask);
validInput = false;
testWidget->setText(invalid);
@@ -876,6 +890,7 @@ public:
void tst_QLineEdit::hasAcceptableInputValidator()
{
+ QLineEdit *testWidget = ensureTestWidget();
QSignalSpy spyChanged(testWidget, SIGNAL(textChanged(QString)));
QSignalSpy spyEdited(testWidget, SIGNAL(textEdited(QString)));
@@ -926,6 +941,7 @@ void tst_QLineEdit::maskCharacter()
QFETCH(QString, input);
QFETCH(bool, expectedValid);
+ QLineEdit *testWidget = ensureTestWidget();
QFocusEvent lostFocus(QEvent::FocusOut);
testWidget->setInputMask(mask);
@@ -1076,6 +1092,7 @@ void tst_QLineEdit::undo()
QFETCH(QStringList, expectedString);
QFETCH(bool, use_keys);
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->isUndoAvailable());
int i;
@@ -1167,6 +1184,7 @@ void tst_QLineEdit::redo()
QFETCH(IntList, insertIndex);
QFETCH(QStringList, expectedString);
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->isUndoAvailable());
QVERIFY(!testWidget->isRedoAvailable());
@@ -1436,6 +1454,7 @@ void tst_QLineEdit::undo_keypressevents()
QFETCH(QTestEventList, keys);
QFETCH(QStringList, expectedString);
+ QLineEdit *testWidget = ensureTestWidget();
keys.simulate(testWidget);
for (int i=0; i<expectedString.size(); ++i) {
@@ -1449,7 +1468,7 @@ void tst_QLineEdit::undo_keypressevents()
void tst_QLineEdit::QTBUG5786_undoPaste()
{
if (!PlatformClipboard::isAvailable())
- QSKIP("this machine doesn't support the clipboard");
+ QSKIP("this machine doesn't support the clipboard");
QString initial("initial");
QString string("test");
QString additional("add");
@@ -1480,6 +1499,7 @@ void tst_QLineEdit::QTBUG5786_undoPaste()
void tst_QLineEdit::clear()
{
// checking that clear of empty/nullstring doesn't add to undo history
+ QLineEdit *testWidget = ensureTestWidget();
int max = 5000;
while (max > 0 && testWidget->isUndoAvailable()) {
max--;
@@ -1501,7 +1521,7 @@ void tst_QLineEdit::clear()
void tst_QLineEdit::editingFinished()
{
- if (testWidget->hasAcceptableInput())
+ if (m_testWidget->hasAcceptableInput())
validInput = true;
else
validInput = false;
@@ -1523,6 +1543,7 @@ void tst_QLineEdit::text_data()
void tst_QLineEdit::text()
{
QFETCH(QString, insertString);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(insertString);
QCOMPARE(testWidget->text(), insertString);
}
@@ -1537,6 +1558,7 @@ void tst_QLineEdit::textMask_data()
void tst_QLineEdit::textMask()
{
QFETCH( QString, insertString );
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask( "#" );
testWidget->setText( insertString );
QCOMPARE( testWidget->text(), insertString );
@@ -1544,6 +1566,7 @@ void tst_QLineEdit::textMask()
void tst_QLineEdit::setText()
{
+ QLineEdit *testWidget = ensureTestWidget();
QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString)));
QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString)));
testWidget->setText("hello");
@@ -1613,7 +1636,7 @@ void tst_QLineEdit::displayText_data()
m << bool(use_setText);
s = key_mode_str + "Password";
m = QLineEdit::Password;
- QChar passChar = qApp->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, 0, testWidget);
+ QChar passChar = qApp->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, 0, m_testWidget);
QString input;
QString pass;
input = "Hello World";
@@ -1645,6 +1668,7 @@ void tst_QLineEdit::displayText()
QFETCH(QLineEdit::EchoMode, mode);
//QFETCH(bool, use_setText); Currently unused.
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setEchoMode(mode);
testWidget->setText(insertString);
QCOMPARE(testWidget->displayText(), expectedString);
@@ -1654,11 +1678,15 @@ void tst_QLineEdit::displayText()
void tst_QLineEdit::passwordEchoOnEdit()
{
QStyleOptionFrameV2 opt;
+ QLineEdit *testWidget = ensureTestWidget();
QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
testWidget->setFocus();
+ centerOnScreen(testWidget);
+ testWidget->show();
testWidget->raise();
+ QVERIFY(QTest::qWaitForWindowExposed(testWidget));
QTRY_VERIFY(testWidget->hasFocus());
QTest::keyPress(testWidget, '0');
@@ -1683,6 +1711,7 @@ void tst_QLineEdit::passwordEchoOnEdit()
void tst_QLineEdit::passwordEchoDelay()
{
+ QLineEdit *testWidget = ensureTestWidget();
int delay = qGuiApp->styleHints()->passwordMaskDelay();
#if defined QT_BUILD_INTERNAL
QLineEditPrivate *priv = QLineEditPrivate::get(testWidget);
@@ -1698,7 +1727,10 @@ void tst_QLineEdit::passwordEchoDelay()
testWidget->setEchoMode(QLineEdit::Password);
testWidget->setFocus();
+ centerOnScreen(testWidget);
+ testWidget->show();
testWidget->raise();
+ QVERIFY(QTest::qWaitForWindowExposed(testWidget));
QTRY_VERIFY(testWidget->hasFocus());
QTest::keyPress(testWidget, '0');
@@ -1757,6 +1789,7 @@ void tst_QLineEdit::maxLength_mask()
QFETCH(QString, mask);
QFETCH(int, expectedLength);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(mask);
QCOMPARE(testWidget->maxLength(), expectedLength);
@@ -1789,6 +1822,7 @@ void tst_QLineEdit::maxLength()
QFETCH(bool, use_setText);
// in some cases we set the maxLength _before_ entering the text.
+ QLineEdit *testWidget = ensureTestWidget();
if (!insertBeforeSettingMaxLength)
testWidget->setMaxLength(length);
@@ -1820,6 +1854,7 @@ void tst_QLineEdit::maxLength()
void tst_QLineEdit::isReadOnly()
{
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->isReadOnly());
// start with a basic text
@@ -1863,6 +1898,7 @@ void tst_QLineEdit::noCursorBlinkWhenReadOnly()
if (cursorFlashTime == 0)
return;
BlinkTestLineEdit le;
+ centerOnScreen(&le);
le.show();
le.setFocus();
QTest::qWaitForWindowActive(&le);
@@ -1928,6 +1964,7 @@ void tst_QLineEdit::psKeyClick(QTestEventList &keys, Qt::Key key, Qt::KeyboardMo
void tst_QLineEdit::cursorPosition()
{
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(testWidget->cursorPosition() == 0);
// start with a basic text
@@ -2015,7 +2052,7 @@ void tst_QLineEdit::cursorPositionChanged_data()
QTestEventList keys;
keys.addKeyClick(Qt::Key_A);
- QTest::newRow("a") << keys << 0 << 1;
+ QTest::newRow("a") << keys << -1 << 1;
keys.clear();
keys.addKeyClick(Qt::Key_A);
@@ -2146,6 +2183,7 @@ void tst_QLineEdit::cursorPositionChanged()
lastCursorPos = 0;
newCursorPos = 0;
+ QLineEdit *testWidget = ensureTestWidget();
input.simulate(testWidget);
QCOMPARE(lastCursorPos, lastPos);
QCOMPARE(newCursorPos, newPos);
@@ -2156,6 +2194,7 @@ void tst_QLineEdit::selectedText()
QString testString = "Abc defg hijklmno, p 'qrst' uvw xyz";
// start with a basic text
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(testString);
selection_count = 0;
@@ -2225,6 +2264,7 @@ void tst_QLineEdit::textChangedAndTextEdited()
changed_count = 0;
edited_count = 0;
+ QLineEdit *testWidget = ensureTestWidget();
QTest::keyClick(testWidget, Qt::Key_A);
QCOMPARE(changed_count, 1);
QVERIFY(edited_count == changed_count);
@@ -2283,6 +2323,7 @@ void tst_QLineEdit::returnPressed()
{
return_count = 0;
+ QLineEdit *testWidget = ensureTestWidget();
QTest::keyClick(testWidget, Qt::Key_Return);
QVERIFY(return_count == 1);
return_count = 0;
@@ -2431,6 +2472,7 @@ void tst_QLineEdit::returnPressed_maskvalidator()
QFETCH(bool, returnPressed);
QEXPECT_FAIL("mask '999', intfix validator(0,999), input '12<cr>'", "QIntValidator has changed behaviour. Does not accept spaces. Task 43082.", Abort);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMask(inputMask);
if (hasValidator)
@@ -2451,6 +2493,7 @@ void tst_QLineEdit::onReturnPressed()
void tst_QLineEdit::setValidator()
{
// Verify that we can set and re-set a validator.
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->validator());
QIntValidator iv1(0);
@@ -2601,6 +2644,7 @@ void tst_QLineEdit::setValidator_QIntValidator()
QFETCH(bool, is_valid);
QIntValidator intValidator(mini, maxi, 0);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setValidator(&intValidator);
QVERIFY(testWidget->text().isEmpty());
//qDebug("1 input: '" + input + "' Exp: '" + expectedText + "'");
@@ -2637,6 +2681,7 @@ void tst_QLineEdit::frame_data()
void tst_QLineEdit::frame()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setFrame(false);
// verify that the editor is shown without a frame
#ifndef NO_PIXMAP_TESTS
@@ -2674,6 +2719,7 @@ void tst_QLineEdit::setAlignment_data()
void tst_QLineEdit::setAlignment()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("left");
testWidget->setAlignment(Qt::AlignLeft);
#ifndef NO_PIXMAP_TESTS
@@ -2713,6 +2759,7 @@ void tst_QLineEdit::setAlignment()
void tst_QLineEdit::isModified()
{
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->isModified());
testWidget->setText("bla");
QVERIFY(!testWidget->isModified());
@@ -2747,6 +2794,7 @@ void tst_QLineEdit::isModified()
void tst_QLineEdit::edited()
{
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(!testWidget->isModified());
testWidget->setText("bla");
QVERIFY(!testWidget->isModified());
@@ -2778,6 +2826,7 @@ void tst_QLineEdit::edited()
void tst_QLineEdit::insert()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->insert("This");
testWidget->insert(" is");
testWidget->insert(" a");
@@ -2854,6 +2903,7 @@ void tst_QLineEdit::setSelection()
QFETCH(QString, expectedText);
QFETCH(bool, expectedHasSelectedText);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(text);
testWidget->setSelection(start, length);
QCOMPARE(testWidget->hasSelectedText(), expectedHasSelectedText);
@@ -2869,6 +2919,7 @@ void tst_QLineEdit::cut()
QSKIP("Autotests run from cron and pasteboard don't get along quite ATM");
// test newlines in cut'n'paste
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("A\nB\nC\n");
testWidget->setSelection(0, 6);
testWidget->cut();
@@ -2964,6 +3015,7 @@ void tst_QLineEdit::inputMaskAndValidator()
QFETCH(QString, validateText);
QFETCH(int, validatePos);
+ QLineEdit *testWidget = ensureTestWidget();
InputMaskValidator imv(testWidget);
testWidget->setValidator(&imv);
@@ -2977,6 +3029,7 @@ void tst_QLineEdit::inputMaskAndValidator()
void tst_QLineEdit::maxLengthAndInputMask()
{
// Really a test for #30447
+ QLineEdit *testWidget = ensureTestWidget();
QVERIFY(testWidget->inputMask().isNull());
testWidget->setMaxLength(10);
QVERIFY(testWidget->maxLength() == 10);
@@ -3016,6 +3069,7 @@ Q_DECLARE_METATYPE(LineEdit::State);
void tst_QLineEdit::returnPressedKeyEvent()
{
LineEdit lineedit;
+ centerOnScreen(&lineedit);
lineedit.show();
QCOMPARE((int)lineedit.state, (int)LineEdit::Other);
QTest::keyClick(&lineedit, Qt::Key_Enter);
@@ -3032,6 +3086,7 @@ void tst_QLineEdit::returnPressedKeyEvent()
void tst_QLineEdit::keepSelectionOnTabFocusIn()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("hello world");
{
QFocusEvent e(QEvent::FocusIn, Qt::TabFocusReason);
@@ -3049,6 +3104,7 @@ void tst_QLineEdit::keepSelectionOnTabFocusIn()
void tst_QLineEdit::readOnlyStyleOption()
{
+ QLineEdit *testWidget = ensureTestWidget();
bool wasReadOnly = testWidget->isReadOnly();
QStyle *oldStyle = testWidget->style();
@@ -3071,6 +3127,7 @@ void tst_QLineEdit::readOnlyStyleOption()
void tst_QLineEdit::validateOnFocusOut()
{
+ QLineEdit *testWidget = ensureTestWidget();
QSignalSpy editingFinishedSpy(testWidget, SIGNAL(editingFinished()));
testWidget->setValidator(new QIntValidator(100, 999, 0));
QTest::keyPress(testWidget, '1');
@@ -3080,8 +3137,11 @@ void tst_QLineEdit::validateOnFocusOut()
QCOMPARE(editingFinishedSpy.count(), 0);
testWidget->setFocus();
+ centerOnScreen(testWidget);
+ testWidget->show();
testWidget->activateWindow();
- QTRY_VERIFY(testWidget->hasFocus());
+ QVERIFY(QTest::qWaitForWindowActive(testWidget));
+ QVERIFY(testWidget->hasFocus());
QTest::keyPress(testWidget, '0');
QTRY_COMPARE(testWidget->text(), QString("100"));
@@ -3092,6 +3152,7 @@ void tst_QLineEdit::validateOnFocusOut()
void tst_QLineEdit::editInvalidText()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->clear();
testWidget->setValidator(new QIntValidator(0, 120, 0));
testWidget->setText("1234");
@@ -3119,6 +3180,7 @@ void tst_QLineEdit::editInvalidText()
void tst_QLineEdit::charWithAltOrCtrlModifier()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->clear();
QCOMPARE(testWidget->text(), QString(""));
QTest::keyPress(testWidget, Qt::Key_Plus);
@@ -3133,6 +3195,7 @@ void tst_QLineEdit::charWithAltOrCtrlModifier()
void tst_QLineEdit::leftKeyOnSelectedText()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->clear();
testWidget->setText("0123");
testWidget->setCursorPosition(4);
@@ -3155,6 +3218,7 @@ void tst_QLineEdit::leftKeyOnSelectedText()
void tst_QLineEdit::inlineCompletion()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->clear();
QStandardItemModel *model = new QStandardItemModel;
QStandardItem *root = model->invisibleRootItem();
@@ -3169,6 +3233,9 @@ void tst_QLineEdit::inlineCompletion()
QCompleter *completer = new QCompleter(model);
completer->setCompletionMode(QCompleter::InlineCompletion);
completer->setCaseSensitivity(Qt::CaseInsensitive);
+ centerOnScreen(testWidget);
+ testWidget->show();
+ QTest::qWaitForWindowExposed(testWidget);
testWidget->setFocus();
QTRY_COMPARE(qApp->activeWindow(), (QWidget*)testWidget);
testWidget->setCompleter(completer);
@@ -3235,6 +3302,7 @@ void tst_QLineEdit::inlineCompletion()
void tst_QLineEdit::noTextEditedOnClear()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("Test");
QSignalSpy textEditedSpy(testWidget, SIGNAL(textEdited(QString)));
testWidget->clear();
@@ -3298,6 +3366,7 @@ void tst_QLineEdit::textMargin()
sizeHint.setHeight(sizeHint.height() + top +bottom);
QCOMPARE(testWidget.sizeHint(), sizeHint);
testWidget.setFrame(false);
+ centerOnScreen(&tlw);
tlw.show();
int l;
@@ -3317,6 +3386,7 @@ void tst_QLineEdit::textMargin()
#ifndef QTEST_NO_CURSOR
void tst_QLineEdit::cursor()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setReadOnly(false);
QCOMPARE(testWidget->cursor().shape(), Qt::IBeamCursor);
testWidget->setReadOnly(true);
@@ -3556,12 +3626,16 @@ void tst_QLineEdit::task233101_cursorPosAfterInputMethod()
void tst_QLineEdit::task241436_passwordEchoOnEditRestoreEchoMode()
{
QStyleOptionFrameV2 opt;
+ QLineEdit *testWidget = ensureTestWidget();
QChar fillChar = testWidget->style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, testWidget);
testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
testWidget->setFocus();
+ centerOnScreen(testWidget);
+ testWidget->show();
QApplication::setActiveWindow(testWidget);
- QTRY_VERIFY(testWidget->hasFocus());
+ QVERIFY(QTest::qWaitForWindowActive(testWidget));
+ QVERIFY(testWidget->hasFocus());
QTest::keyPress(testWidget, '0');
QCOMPARE(testWidget->displayText(), QString("0"));
@@ -3585,6 +3659,7 @@ void tst_QLineEdit::task241436_passwordEchoOnEditRestoreEchoMode()
void tst_QLineEdit::task248948_redoRemovedSelection()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("a");
testWidget->selectAll();
QTest::keyPress(testWidget, Qt::Key_Delete);
@@ -3599,12 +3674,15 @@ void tst_QLineEdit::taskQTBUG_4401_enterKeyClearsPassword()
{
QString password("Wanna guess?");
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(password);
testWidget->setEchoMode(QLineEdit::PasswordEchoOnEdit);
testWidget->setFocus();
testWidget->selectAll();
+ centerOnScreen(testWidget);
+ testWidget->show();
QApplication::setActiveWindow(testWidget);
- QTRY_VERIFY(testWidget->hasFocus());
+ QVERIFY(QTest::qWaitForWindowActive(testWidget));
QTest::keyPress(testWidget, Qt::Key_Enter);
QTRY_COMPARE(testWidget->text(), password);
@@ -3614,6 +3692,7 @@ void tst_QLineEdit::taskQTBUG_4679_moveToStartEndOfBlock()
{
#ifdef Q_OS_MAC
const QString text("there are no blocks for lineEdit");
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(text);
testWidget->setCursorPosition(5);
QCOMPARE(testWidget->cursorPosition(), 5);
@@ -3629,6 +3708,7 @@ void tst_QLineEdit::taskQTBUG_4679_selectToStartEndOfBlock()
{
#ifdef Q_OS_MAC
const QString text("there are no blocks for lineEdit, select all");
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText(text);
testWidget->setCursorPosition(5);
QCOMPARE(testWidget->cursorPosition(), 5);
@@ -3898,6 +3978,7 @@ void tst_QLineEdit::bidiLogicalMovement()
void tst_QLineEdit::selectAndCursorPosition()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("This is a long piece of text");
testWidget->setSelection(0, 5);
@@ -3908,6 +3989,10 @@ void tst_QLineEdit::selectAndCursorPosition()
void tst_QLineEdit::inputMethod()
{
+ QLineEdit *testWidget = ensureTestWidget();
+ centerOnScreen(testWidget);
+ testWidget->show();
+ QVERIFY(QTest::qWaitForWindowExposed(testWidget));
// widget accepts input
QInputMethodQueryEvent queryEvent(Qt::ImEnabled);
QApplication::sendEvent(testWidget, &queryEvent);
@@ -3942,6 +4027,7 @@ void tst_QLineEdit::inputMethod()
void tst_QLineEdit::inputMethodSelection()
{
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
testWidget->setSelection(0,0);
QSignalSpy selectionSpy(testWidget, SIGNAL(selectionChanged()));
@@ -3989,6 +4075,7 @@ void tst_QLineEdit::inputMethodQueryImHints_data()
void tst_QLineEdit::inputMethodQueryImHints()
{
QFETCH(Qt::InputMethodHints, hints);
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setInputMethodHints(hints);
QVariant value = testWidget->inputMethodQuery(Qt::ImHints);
@@ -4031,7 +4118,7 @@ void tst_QLineEdit::undoRedoAndEchoModes()
QFETCH(QStringList, expected);
// create some history for the QLineEdit
- testWidget->clear();
+ QLineEdit *testWidget = ensureTestWidget();
testWidget->setEchoMode(QLineEdit::EchoMode(echoMode));
testWidget->insert(input.at(0));
testWidget->selectAll();
@@ -4136,5 +4223,59 @@ void tst_QLineEdit::sideWidgets()
lineEdit->addAction(iconAction);
}
+Q_DECLARE_METATYPE(Qt::AlignmentFlag)
+void tst_QLineEdit::shouldShowPlaceholderText_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<bool>("hasFocus");
+ QTest::addColumn<Qt::AlignmentFlag>("alignment");
+ QTest::addColumn<bool>("shouldShowPlaceholderText");
+
+ QTest::newRow("empty, non-focused, left") << QString() << false << Qt::AlignLeft << true;
+ QTest::newRow("empty, focused, left") << QString() << true << Qt::AlignLeft << true;
+ QTest::newRow("non-empty, non-focused, left") << QStringLiteral("Qt") << false << Qt::AlignLeft << false;
+ QTest::newRow("non-empty, focused, left") << QStringLiteral("Qt") << true << Qt::AlignLeft << false;
+
+ QTest::newRow("empty, non-focused, center") << QString() << false << Qt::AlignHCenter << true;
+ QTest::newRow("empty, focused, center") << QString() << true << Qt::AlignHCenter << false;
+ QTest::newRow("non-empty, non-focused, center") << QStringLiteral("Qt") << false << Qt::AlignHCenter << false;
+ QTest::newRow("non-empty, focused, center") << QStringLiteral("Qt") << true << Qt::AlignHCenter << false;
+
+ QTest::newRow("empty, non-focused, right") << QString() << false << Qt::AlignRight << true;
+ QTest::newRow("empty, focused, right") << QString() << true << Qt::AlignRight << true;
+ QTest::newRow("non-empty, non-focused, right") << QStringLiteral("Qt") << false << Qt::AlignRight << false;
+ QTest::newRow("non-empty, focused, right") << QStringLiteral("Qt") << true << Qt::AlignRight << false;
+}
+
+void tst_QLineEdit::shouldShowPlaceholderText()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("This test requires a developer build.");
+#else
+ QFETCH(QString, text);
+ QFETCH(bool, hasFocus);
+ QFETCH(Qt::AlignmentFlag, alignment);
+ QFETCH(bool, shouldShowPlaceholderText);
+
+ QLineEdit lineEdit;
+
+ // avoid "Test input context to commit without focused object" warnings
+ lineEdit.setAttribute(Qt::WA_InputMethodEnabled, false);
+
+ if (hasFocus) {
+ lineEdit.show();
+ QApplicationPrivate::setFocusWidget(&lineEdit, Qt::NoFocusReason);
+ }
+ QCOMPARE(lineEdit.hasFocus(), hasFocus);
+
+ lineEdit.setText(text);
+ lineEdit.setAlignment(alignment);
+
+ QLineEditPrivate *priv = QLineEditPrivate::get(&lineEdit);
+ QCOMPARE(priv->shouldShowPlaceholderText(), shouldShowPlaceholderText);
+#endif
+
+}
+
QTEST_MAIN(tst_QLineEdit)
#include "tst_qlineedit.moc"
diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
index e5a9b570bb..d02b86bd8a 100644
--- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
+++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp
@@ -1340,8 +1340,8 @@ void tst_QMainWindow::restoreStateFromPreviousVersion()
QCOMPARE(win.restoreState(ba), true);
for( int i = 0; i < docks.size(); ++i) {
- QCOMPARE( win.dockWidgetArea(docks[i]), Qt::DockWidgetArea(1 << i%4));
- }
+ QCOMPARE( win.dockWidgetArea(docks[i]), Qt::DockWidgetArea(1 << i%4));
+ }
}
}
@@ -1426,7 +1426,7 @@ public:
QSize sizeHint() const
{
- return QSize(200, 200);
+ return QSize(200, 200);
}
};
diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
index f5d92be95d..5f4284e79a 100644
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -2596,8 +2596,8 @@ void tst_QMdiArea::nativeSubWindows()
const QString platformName = QGuiApplication::platformName();
if (platformName != QLatin1String("xcb") && platformName != QLatin1String("windows"))
QSKIP(qPrintable(QString::fromLatin1("nativeSubWindows() does not work on this platform (%1).").arg(platformName)));
-#ifdef QT_OPENGL_ES_2_ANGLE
- if (platformName == QLatin1String("windows"))
+#ifdef Q_OS_WIN
+ if (QOpenGLFunctions::isES())
QSKIP("nativeSubWindows() does not work with ANGLE on Windows, QTBUG-28545.");
#endif
{ // Add native widgets after show.
diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
index b3e50b8ba8..268638a504 100644
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -146,7 +146,7 @@ static void sendMouseDoubleClick(QWidget *widget, const QPoint &point, Qt::Mouse
}
static const Qt::WindowFlags StandardWindowFlags
- = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint;
+ = Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
static const Qt::WindowFlags DialogWindowFlags
= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
@@ -901,40 +901,12 @@ void tst_QMdiSubWindow::setWindowFlags()
QVERIFY(QTest::qWaitForWindowExposed(&workspace));
window->setWindowFlags(windowType | customFlags);
- QEXPECT_FAIL("Qt::Widget", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Window", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Dialog", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Sheet", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Drawer", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Popup", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Tool", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::ToolTip", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::SplashScreen", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Desktop", "QTBUG-27274", Continue);
QCOMPARE(window->windowType(), expectedWindowType);
- if (!expectedCustomFlags) {
- // We expect the same as 'customFlags'
+ if (!expectedCustomFlags) // We expect the same as 'customFlags'
QCOMPARE(window->windowFlags() & ~expectedWindowType, customFlags);
- } else {
- QEXPECT_FAIL("Qt::Widget", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Window", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Dialog", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Sheet", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Drawer", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Popup", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Tool", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::ToolTip", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::SplashScreen", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::Desktop", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Qt::SubWindow", "QTBUG-27274", Continue);
- QEXPECT_FAIL("StandardAndFrameless", "QTBUG-27274", Continue);
- QEXPECT_FAIL("StandardAndFramelessAndStaysOnTop", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Shade", "QTBUG-27274", Continue);
- QEXPECT_FAIL("Context", "QTBUG-27274", Continue);
- QEXPECT_FAIL("ShadeAndContext", "QTBUG-27274", Continue);
+ else
QCOMPARE(window->windowFlags() & ~expectedWindowType, expectedCustomFlags);
- }
}
void tst_QMdiSubWindow::mouseDoubleClick()
@@ -981,18 +953,12 @@ void tst_QMdiSubWindow::mouseDoubleClick()
sendMouseDoubleClick(window, mousePosition);
qApp->processEvents();
QVERIFY(!window->isShaded());
-#ifndef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-27274", Continue);
-#endif
QCOMPARE(window->geometry(), originalGeometry);
window->showMinimized();
QVERIFY(window->isMinimized());
sendMouseDoubleClick(window, mousePosition);
QVERIFY(!window->isMinimized());
-#ifndef Q_OS_MAC
- QEXPECT_FAIL("", "QTBUG-27274", Continue);
-#endif
QCOMPARE(window->geometry(), originalGeometry);
}
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index 2b8e735a0e..2e492f3a5c 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -173,22 +173,22 @@ const int RESET = 0;
/*!
Test plan:
insertItem (all flavors and combinations)
- removing menu items
- clearing the menu
-
- check the common behaviour + emitted signals for:
- accelerator keys
- navigating tru the menu and then pressing ENTER
- mouse clicks
- mouse drags
- combinations of key + mouse (if possible)
- checked / unckecked state of menu options
- active / inactive state
+ removing menu items
+ clearing the menu
+
+ check the common behaviour + emitted signals for:
+ accelerator keys
+ navigating tru the menu and then pressing ENTER
+ mouse clicks
+ mouse drags
+ combinations of key + mouse (if possible)
+ checked / unckecked state of menu options
+ active / inactive state
Can't test these without pixmap comparison...
- show and hide
- icons in a menu
- pixmaps in a menu
+ show and hide
+ icons in a menu
+ pixmaps in a menu
*/
@@ -481,17 +481,17 @@ void tst_QMenuBar::removeItemAt()
switch (removeIndex )
{
case 0:
- QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 2") );
- QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 3") );
- break;
+ QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 2") );
+ QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 3") );
+ break;
case 1:
- QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 1") );
- QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 3") );
- break;
+ QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 1") );
+ QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 3") );
+ break;
case 2:
- QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 1") );
- QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 2") );
- break;
+ QCOMPARE( menuBarActions2.at(0)->text(), QString("Menu 1") );
+ QCOMPARE( menuBarActions2.at(1)->text(), QString("Menu 2") );
+ break;
}
QVERIFY( menuBarActions2.size() == 2 );
@@ -827,7 +827,7 @@ void tst_QMenuBar::check_escKey()
// void tst_QMenuBar::check_mouse1()
// {
// if (QSystem::curStyle() == "Motif")
-// QSKIP("This fails in Motif due to a bug in the testing framework");
+// QSKIP("This fails in Motif due to a bug in the testing framework");
// QFETCH( QString, popup_item );
// QFETCH( int, itemA_count );
// QFETCH( int, itemB_count );
@@ -888,7 +888,7 @@ void tst_QMenuBar::check_escKey()
// void tst_QMenuBar::check_mouse2()
// {
// if (QSystem::curStyle() == "Motif")
-// QSKIP("This fails in Motif due to a bug in the testing framework");
+// QSKIP("This fails in Motif due to a bug in the testing framework");
// QFETCH( QString, label );
// QFETCH( int, itemA_count );
// QFETCH( int, itemB_count );
@@ -961,8 +961,8 @@ void tst_QMenuBar::allowActiveAndDisabled()
void tst_QMenuBar::check_altPress()
{
if ( !qApp->style()->styleHint(QStyle::SH_MenuBar_AltKeyNavigation) ) {
- QSKIP( QString( "this is not supposed to work in the %1 style. Skipping." ).
- arg( qApp->style()->objectName() ).toLatin1());
+ QSKIP(QString( "this is not supposed to work in the %1 style. Skipping." ).
+ arg(qApp->style()->objectName()).toLatin1());
}
QMainWindow w;
@@ -1141,7 +1141,7 @@ void tst_QMenuBar::task223138_triggered()
void tst_QMenuBar::task256322_highlight()
{
QMainWindow win;
- win.menuBar()->setNativeMenuBar(false); //we can't check the geometry of native menubars
+ win.menuBar()->setNativeMenuBar(false); //we can't check the geometry of native menubars
QMenu menu;
QAction *file = win.menuBar()->addMenu(&menu);
file->setText("file");
diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
index 11c4e238ec..61eb390fd3 100644
--- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
+++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp
@@ -149,6 +149,11 @@ private slots:
void insertAndScrollToBottom();
void inputMethodQueryImHints_data();
void inputMethodQueryImHints();
+#ifndef QT_NO_REGEXP
+ void findWithRegExp();
+ void findBackwardWithRegExp();
+ void findWithRegExpReturnsFalseIfNoMoreResults();
+#endif
private:
void createSelection();
@@ -1523,5 +1528,44 @@ void tst_QPlainTextEdit::inputMethodQueryImHints()
QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints);
}
+#ifndef QT_NO_REGEXP
+void tst_QPlainTextEdit::findWithRegExp()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegExp rx("\\w{2}xt");
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found == true);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+
+void tst_QPlainTextEdit::findBackwardWithRegExp()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QTextCursor cursor = ed->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ ed->setTextCursor(cursor);
+ QRegExp rx("a\\w*t");
+
+ bool found = ed->find(rx, QTextDocument::FindBackward);
+
+ QVERIFY(found == true);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit"));
+}
+
+void tst_QPlainTextEdit::findWithRegExpReturnsFalseIfNoMoreResults()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegExp rx("t.xt");
+ ed->find(rx);
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found == false);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+#endif
+
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"
diff --git a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
index d336d00b3e..1eccdd768b 100644
--- a/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
+++ b/tests/auto/widgets/widgets/qpushbutton/tst_qpushbutton.cpp
@@ -490,8 +490,8 @@ void tst_QPushButton::defaultAndAutoDefault()
// Adding buttons to QDialog through a layout
QDialog dialog;
- QPushButton button3;
- button3.setAutoDefault(false);
+ QPushButton button3;
+ button3.setAutoDefault(false);
QPushButton button1;
QVERIFY(!button1.autoDefault());
@@ -512,7 +512,7 @@ void tst_QPushButton::defaultAndAutoDefault()
layout.addWidget(&button2, 0, 2);
layout.addWidget(&button1, 0, 1);
dialog.setLayout(&layout);
- button3.setFocus();
+ button3.setFocus();
QVERIFY(button1.autoDefault());
QVERIFY(button1.isDefault());
QVERIFY(button2.autoDefault());
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index a21f2d70a0..21034e8f1b 100644
--- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
+++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
@@ -144,6 +144,10 @@ private slots:
void lineEditReturnPressed();
void positiveSign();
+
+ void setGroupSeparatorShown_data();
+ void setGroupSeparatorShown();
+
public slots:
void valueChangedHelper(const QString &);
void valueChangedHelper(int);
@@ -154,6 +158,9 @@ private:
typedef QList<int> IntList;
+Q_DECLARE_METATYPE(QLocale::Language)
+Q_DECLARE_METATYPE(QLocale::Country)
+
// Testing get/set functions
void tst_QSpinBox::getSetCheck()
{
@@ -1128,5 +1135,47 @@ void tst_QSpinBox::positiveSign()
QCOMPARE(spinBox.text(), QLatin1String("+20"));
}
+void tst_QSpinBox::setGroupSeparatorShown_data()
+{
+ QTest::addColumn<QLocale::Language>("lang");
+ QTest::addColumn<QLocale::Country>("country");
+
+ QTest::newRow("data0") << QLocale::English << QLocale::UnitedStates;
+ QTest::newRow("data1") << QLocale::Swedish << QLocale::Sweden;
+ QTest::newRow("data2") << QLocale::German << QLocale::Germany;
+ QTest::newRow("data3") << QLocale::Georgian << QLocale::Georgia;
+ QTest::newRow("data3") << QLocale::Macedonian << QLocale::Macedonia;
+}
+
+void tst_QSpinBox::setGroupSeparatorShown()
+{
+ QFETCH(QLocale::Language, lang);
+ QFETCH(QLocale::Country, country);
+
+ QLocale loc(lang, country);
+ QLocale::setDefault(loc);
+ SpinBox spinBox;
+ spinBox.setMaximum(99999);
+ spinBox.setValue(13000);
+ spinBox.setGroupSeparatorShown(true);
+ QCOMPARE(spinBox.lineEdit()->text(), spinBox.locale().toString(13000));
+ QCOMPARE(spinBox.isGroupSeparatorShown(), true);
+ QCOMPARE(spinBox.textFromValue(23421),spinBox.locale().toString(23421));
+
+ spinBox.setGroupSeparatorShown(false);
+ QCOMPARE(spinBox.lineEdit()->text(), QStringLiteral("13000"));
+ QCOMPARE(spinBox.isGroupSeparatorShown(), false);
+
+ spinBox.setMaximum(72000);
+ spinBox.lineEdit()->setText(spinBox.locale().toString(32000));
+ QCOMPARE(spinBox.value()+1000, 33000);
+
+ spinBox.lineEdit()->setText(QStringLiteral("32000"));
+ QCOMPARE(spinBox.value()+1000, 33000);
+
+ spinBox.lineEdit()->setText(QStringLiteral("32,000"));
+ QCOMPARE(spinBox.value()+1000, 33000);
+}
+
QTEST_MAIN(tst_QSpinBox)
#include "tst_qspinbox.moc"
diff --git a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro
index 72956a6867..c367959cbc 100644
--- a/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro
+++ b/tests/auto/widgets/widgets/qtabwidget/qtabwidget.pro
@@ -8,4 +8,4 @@ INCLUDEPATH += ../
HEADERS +=
SOURCES += tst_qtabwidget.cpp
-win32:!wince*:LIBS += -luser32
+win32:!wince*:!winrt:LIBS += -luser32
diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
index e6fe5f92c7..df11ea9b14 100644
--- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
+++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
@@ -48,7 +48,7 @@
#include <qlabel.h>
#include <QtWidgets/qboxlayout.h>
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
# include <qt_windows.h>
#define Q_CHECK_PAINTEVENTS \
if (::SwitchDesktop(::GetThreadDesktop(::GetCurrentThreadId())) == 0) \
diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
index 11bb5c88a1..53c76a0da6 100644
--- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
+++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp
@@ -203,6 +203,14 @@ private slots:
void highlightLongLine();
+ void countTextChangedOnRemove();
+
+#ifndef QT_NO_REGEXP
+ void findWithRegExp();
+ void findBackwardWithRegExp();
+ void findWithRegExpReturnsFalseIfNoMoreResults();
+#endif
+
private:
void createSelection();
int blockCount() const;
@@ -2499,6 +2507,58 @@ void tst_QTextEdit::highlightLongLine()
QVERIFY(true);
}
+//check for bug 15003, are there multiple textChanged() signals on remove?
+void tst_QTextEdit::countTextChangedOnRemove()
+{
+ QTextEdit edit;
+ edit.insertPlainText("Hello");
+
+ QSignalSpy spy(&edit, SIGNAL(textChanged()));
+
+ QKeyEvent event(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
+ QCoreApplication::instance()->notify(&edit, &event);
+
+ QCOMPARE(spy.count(), 1);
+}
+
+#ifndef QT_NO_REGEXP
+void tst_QTextEdit::findWithRegExp()
+{
+ ed->setHtml(QStringLiteral("arbitrary te<span style=\"color:#ff0000\">xt</span>"));
+ QRegExp rx("\\w{2}xt");
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found == true);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+
+void tst_QTextEdit::findBackwardWithRegExp()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QTextCursor cursor = ed->textCursor();
+ cursor.movePosition(QTextCursor::End);
+ ed->setTextCursor(cursor);
+ QRegExp rx("a\\w*t");
+
+ bool found = ed->find(rx, QTextDocument::FindBackward);
+
+ QVERIFY(found == true);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("arbit"));
+}
+
+void tst_QTextEdit::findWithRegExpReturnsFalseIfNoMoreResults()
+{
+ ed->setPlainText(QStringLiteral("arbitrary text"));
+ QRegExp rx("t.xt");
+ ed->find(rx);
+
+ bool found = ed->find(rx);
+
+ QVERIFY(found == false);
+ QCOMPARE(ed->textCursor().selectedText(), QStringLiteral("text"));
+}
+#endif
QTEST_MAIN(tst_QTextEdit)
#include "tst_qtextedit.moc"
diff --git a/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp b/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp
index a00db02c0a..13d958c8ca 100644
--- a/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp
+++ b/tests/auto/widgets/widgets/qtoolbox/tst_qtoolbox.cpp
@@ -252,9 +252,9 @@ void tst_QToolBox::change()
QVERIFY( lastItem );
for ( int c = 0; c < testWidget->count(); ++c ) {
- QString label = "Item " + QString::number(c);
- testWidget->setItemText(c, label);
- QCOMPARE( testWidget->itemText(c), label );
+ QString label = "Item " + QString::number(c);
+ testWidget->setItemText(c, label);
+ QCOMPARE( testWidget->itemText(c), label );
}
testWidget->setCurrentIndex( 0 );
diff --git a/tests/auto/xml/sax/qxmlsimplereader/parser/parser.cpp b/tests/auto/xml/sax/qxmlsimplereader/parser/parser.cpp
index c00a5c7caa..3dd733f61e 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/parser/parser.cpp
+++ b/tests/auto/xml/sax/qxmlsimplereader/parser/parser.cpp
@@ -47,70 +47,70 @@
class ContentHandler : public QXmlDefaultHandler
{
- public:
- ContentHandler();
-
- // QXmlContentHandler methods
- bool startDocument();
- bool endDocument();
- bool startElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName,
- const QXmlAttributes & atts);
- bool endElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName);
- bool characters(const QString &ch);
- void setDocumentLocator(QXmlLocator *locator);
- bool startPrefixMapping (const QString &prefix, const QString & uri);
- bool endPrefixMapping(const QString &prefix);
- bool ignorableWhitespace (const QString & ch);
- bool processingInstruction(const QString &target, const QString &data);
- bool skippedEntity (const QString & name);
-
- // QXmlErrorHandler methods
- bool warning (const QXmlParseException & exception);
- bool error (const QXmlParseException & exception);
- bool fatalError (const QXmlParseException & exception);
-
- // QXmlDTDHandler methods
- bool notationDecl ( const QString & name, const QString & publicId,
- const QString & systemId );
- bool unparsedEntityDecl ( const QString & name,
- const QString & publicId,
- const QString & systemId,
- const QString & notationName );
-
- // QXmlEntityResolver methods
- bool resolveEntity ( const QString & publicId,
- const QString & systemId,
- QXmlInputSource *&);
-
- // QXmlLexicalHandler methods
- bool startDTD ( const QString & name, const QString & publicId, const QString & systemId );
- bool endDTD ();
- bool startEntity ( const QString & name );
- bool endEntity ( const QString & name );
- bool startCDATA ();
- bool endCDATA ();
- bool comment ( const QString & ch );
-
- // QXmlDeclHandler methods
- bool attributeDecl ( const QString & eName, const QString & aName, const QString & type, const QString & valueDefault, const QString & value );
- bool internalEntityDecl ( const QString & name, const QString & value );
- bool externalEntityDecl ( const QString & name, const QString & publicId, const QString & systemId );
-
-
- const QString &result() const { return m_result; }
- const QString &errorMsg() const { return m_error_msg; }
-
- private:
- QString nestPrefix() const { return QString().fill(' ', 3*m_nest); }
- QString formatAttributes(const QXmlAttributes & atts);
- QString escapeStr(const QString &s);
-
- unsigned m_nest;
- QString m_result, m_error_msg;
+public:
+ ContentHandler();
+
+ // QXmlContentHandler methods
+ bool startDocument();
+ bool endDocument();
+ bool startElement(const QString &namespaceURI,
+ const QString &localName,
+ const QString &qName,
+ const QXmlAttributes &atts);
+ bool endElement(const QString &namespaceURI,
+ const QString &localName,
+ const QString &qName);
+ bool characters(const QString &ch);
+ void setDocumentLocator(QXmlLocator *locator);
+ bool startPrefixMapping(const QString &prefix, const QString &uri);
+ bool endPrefixMapping(const QString &prefix);
+ bool ignorableWhitespace(const QString &ch);
+ bool processingInstruction(const QString &target, const QString &data);
+ bool skippedEntity(const QString &name);
+
+ // QXmlErrorHandler methods
+ bool warning(const QXmlParseException &exception);
+ bool error(const QXmlParseException &exception);
+ bool fatalError(const QXmlParseException &exception);
+
+ // QXmlDTDHandler methods
+ bool notationDecl(const QString &name, const QString &publicId,
+ const QString &systemId);
+ bool unparsedEntityDecl(const QString &name,
+ const QString &publicId,
+ const QString &systemId,
+ const QString &notationName);
+
+ // QXmlEntityResolver methods
+ bool resolveEntity(const QString &publicId,
+ const QString &systemId,
+ QXmlInputSource *&);
+
+ // QXmlLexicalHandler methods
+ bool startDTD (const QString &name, const QString &publicId, const QString &systemId);
+ bool endDTD();
+ bool startEntity(const QString &name);
+ bool endEntity(const QString &name);
+ bool startCDATA();
+ bool endCDATA();
+ bool comment(const QString &ch);
+
+ // QXmlDeclHandler methods
+ bool attributeDecl(const QString &eName, const QString &aName, const QString &type, const QString &valueDefault, const QString &value);
+ bool internalEntityDecl(const QString &name, const QString &value);
+ bool externalEntityDecl(const QString &name, const QString &publicId, const QString &systemId);
+
+
+ const QString &result() const { return m_result; }
+ const QString &errorMsg() const { return m_error_msg; }
+
+private:
+ QString nestPrefix() const { return QString().fill(' ', 3*m_nest); }
+ QString formatAttributes(const QXmlAttributes & atts);
+ QString escapeStr(const QString &s);
+
+ unsigned m_nest;
+ QString m_result, m_error_msg;
};
ContentHandler::ContentHandler()
@@ -136,15 +136,15 @@ bool ContentHandler::endDocument()
}
bool ContentHandler::startElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName,
- const QXmlAttributes & atts)
+ const QString &localName,
+ const QString &qName,
+ const QXmlAttributes &atts)
{
m_result += nestPrefix();
m_result += "startElement(namespaceURI=\"" + escapeStr(namespaceURI)
- + "\", localName=\"" + escapeStr(localName)
- + "\", qName=\"" + escapeStr(qName)
- + "\", atts=[" + formatAttributes(atts) + "])\n";
+ + "\", localName=\"" + escapeStr(localName)
+ + "\", qName=\"" + escapeStr(qName)
+ + "\", atts=[" + formatAttributes(atts) + "])\n";
++m_nest;
return true;
}
@@ -164,25 +164,25 @@ QString ContentHandler::formatAttributes(const QXmlAttributes &atts)
{
QString result;
for (int i = 0, cnt = atts.count(); i < cnt; ++i) {
- if (i != 0) result += ", ";
- result += "{localName=\"" + escapeStr(atts.localName(i))
- + "\", qName=\"" + escapeStr(atts.qName(i))
- + "\", uri=\"" + escapeStr(atts.uri(i))
- + "\", type=\"" + escapeStr(atts.type(i))
- + "\", value=\"" + escapeStr(atts.value(i)) + "\"}";
+ if (i != 0) result += ", ";
+ result += "{localName=\"" + escapeStr(atts.localName(i))
+ + "\", qName=\"" + escapeStr(atts.qName(i))
+ + "\", uri=\"" + escapeStr(atts.uri(i))
+ + "\", type=\"" + escapeStr(atts.type(i))
+ + "\", value=\"" + escapeStr(atts.value(i)) + "\"}";
}
return result;
}
bool ContentHandler::endElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName)
+ const QString &localName,
+ const QString &qName)
{
--m_nest;
m_result += nestPrefix();
m_result += "endElement(namespaceURI=\"" + escapeStr(namespaceURI)
- + "\", localName=\"" + escapeStr(localName)
- + "\", qName=\"" + escapeStr(qName) + "\")\n";
+ + "\", localName=\"" + escapeStr(localName)
+ + "\", qName=\"" + escapeStr(qName) + "\")\n";
return true;
}
@@ -197,16 +197,16 @@ void ContentHandler::setDocumentLocator(QXmlLocator *locator)
{
m_result += nestPrefix();
m_result += "setDocumentLocator(locator={columnNumber="
- + QString::number(locator->columnNumber())
- + ", lineNumber=" + QString::number(locator->lineNumber())
- + "})\n";
+ + QString::number(locator->columnNumber())
+ + ", lineNumber=" + QString::number(locator->lineNumber())
+ + "})\n";
}
bool ContentHandler::startPrefixMapping (const QString &prefix, const QString & uri)
{
m_result += nestPrefix();
m_result += "startPrefixMapping(prefix=\"" + escapeStr(prefix)
- + "\", uri=\"" + escapeStr(uri) + "\")\n";
+ + "\", uri=\"" + escapeStr(uri) + "\")\n";
++m_nest;
return true;
}
@@ -230,7 +230,7 @@ bool ContentHandler::processingInstruction(const QString &target, const QString
{
m_result += nestPrefix();
m_result += "processingInstruction(target=\"" + escapeStr(target)
- + "\", data=\"" + escapeStr(data) + "\")\n";
+ + "\", data=\"" + escapeStr(data) + "\")\n";
return true;
}
@@ -249,13 +249,13 @@ bool ContentHandler::warning(const QXmlParseException & exception)
.arg(exception.message());
m_result += nestPrefix();
m_result += "warning(exception={columnNumber="
- + QString::number(exception.columnNumber())
- + ", lineNumber="
- + QString::number(exception.lineNumber())
- + ", publicId=\"" + escapeStr(exception.publicId())
- + "\", systemId=\"" + escapeStr(exception.systemId())
- + "\", message=\"" + escapeStr(exception.message())
- + "\"})\n";
+ + QString::number(exception.columnNumber())
+ + ", lineNumber="
+ + QString::number(exception.lineNumber())
+ + ", publicId=\"" + escapeStr(exception.publicId())
+ + "\", systemId=\"" + escapeStr(exception.systemId())
+ + "\", message=\"" + escapeStr(exception.message())
+ + "\"})\n";
return true;
}
@@ -267,13 +267,13 @@ bool ContentHandler::error(const QXmlParseException & exception)
.arg(exception.message());
m_result += nestPrefix();
m_result += "error(exception={columnNumber="
- + QString::number(exception.columnNumber())
- + ", lineNumber="
- + QString::number(exception.lineNumber())
- + ", publicId=\"" + escapeStr(exception.publicId())
- + "\", systemId=\"" + escapeStr(exception.systemId())
- + "\", message=\"" + escapeStr(exception.message())
- + "\"})\n";
+ + QString::number(exception.columnNumber())
+ + ", lineNumber="
+ + QString::number(exception.lineNumber())
+ + ", publicId=\"" + escapeStr(exception.publicId())
+ + "\", systemId=\"" + escapeStr(exception.systemId())
+ + "\", message=\"" + escapeStr(exception.message())
+ + "\"})\n";
return true;
}
@@ -285,49 +285,49 @@ bool ContentHandler::fatalError(const QXmlParseException & exception)
.arg(exception.message());
m_result += nestPrefix();
m_result += "fatalError(exception={columnNumber="
- + QString::number(exception.columnNumber())
- + ", lineNumber="
- + QString::number(exception.lineNumber())
- + ", publicId=\"" + escapeStr(exception.publicId())
- + "\", systemId=\"" + escapeStr(exception.systemId())
- + "\", message=\"" + escapeStr(exception.message())
- + "\"})\n";
+ + QString::number(exception.columnNumber())
+ + ", lineNumber="
+ + QString::number(exception.lineNumber())
+ + ", publicId=\"" + escapeStr(exception.publicId())
+ + "\", systemId=\"" + escapeStr(exception.systemId())
+ + "\", message=\"" + escapeStr(exception.message())
+ + "\"})\n";
return true;
}
-bool ContentHandler::notationDecl ( const QString & name,
- const QString & publicId,
- const QString & systemId )
+bool ContentHandler::notationDecl(const QString &name,
+ const QString &publicId,
+ const QString &systemId )
{
m_result += nestPrefix();
m_result += "notationDecl(name=\"" + escapeStr(name) + "\", publicId=\""
- + escapeStr(publicId) + "\", systemId=\""
- + escapeStr(systemId) + "\")\n";
+ + escapeStr(publicId) + "\", systemId=\""
+ + escapeStr(systemId) + "\")\n";
return true;
}
-bool ContentHandler::unparsedEntityDecl ( const QString & name,
- const QString & publicId,
- const QString & systemId,
- const QString & notationName )
+bool ContentHandler::unparsedEntityDecl(const QString &name,
+ const QString &publicId,
+ const QString &systemId,
+ const QString &notationName )
{
m_result += nestPrefix();
m_result += "unparsedEntityDecl(name=\"" + escapeStr(name)
- + "\", publicId=\"" + escapeStr(publicId)
- + "\", systemId=\"" + escapeStr(systemId)
- + "\", notationName=\"" + escapeStr(notationName)
- + "\")\n";
+ + "\", publicId=\"" + escapeStr(publicId)
+ + "\", systemId=\"" + escapeStr(systemId)
+ + "\", notationName=\"" + escapeStr(notationName)
+ + "\")\n";
return true;
}
-bool ContentHandler::resolveEntity(const QString & publicId,
- const QString & systemId,
- QXmlInputSource *&)
+bool ContentHandler::resolveEntity(const QString &publicId,
+ const QString &systemId,
+ QXmlInputSource *&)
{
m_result += nestPrefix();
m_result += "resolveEntity(publicId=\"" + escapeStr(publicId)
- + "\", systemId=\"" + escapeStr(systemId)
- + "\", ret={})\n";
+ + "\", systemId=\"" + escapeStr(systemId)
+ + "\", ret={})\n";
return true;
}
@@ -335,8 +335,8 @@ bool ContentHandler::startDTD ( const QString & name, const QString & publicId,
{
m_result += nestPrefix();
m_result += "startDTD(name=\"" + escapeStr(name)
- + "\", publicId=\"" + escapeStr(publicId)
- + "\", systemId=\"" + escapeStr(systemId) + "\")\n";
+ + "\", publicId=\"" + escapeStr(publicId)
+ + "\", systemId=\"" + escapeStr(systemId) + "\")\n";
++m_nest;
return true;
}
@@ -388,37 +388,37 @@ bool ContentHandler::comment ( const QString & ch )
return true;
}
-bool ContentHandler::attributeDecl ( const QString & eName,
- const QString & aName,
- const QString & type,
- const QString & valueDefault,
- const QString & value )
+bool ContentHandler::attributeDecl(const QString &eName,
+ const QString &aName,
+ const QString &type,
+ const QString &valueDefault,
+ const QString &value)
{
m_result += nestPrefix();
m_result += "attributeDecl(eName=\"" + escapeStr(eName) + "\", aName=\""
- + escapeStr(aName) + "\", type=\"" + escapeStr(type)
- + "\", valueDefault=\"" + escapeStr(valueDefault)
- + "\", value=\"" + escapeStr(value) + "\")\n";
+ + escapeStr(aName) + "\", type=\"" + escapeStr(type)
+ + "\", valueDefault=\"" + escapeStr(valueDefault)
+ + "\", value=\"" + escapeStr(value) + "\")\n";
return true;
}
-bool ContentHandler::internalEntityDecl ( const QString & name,
- const QString & value )
+bool ContentHandler::internalEntityDecl(const QString &name,
+ const QString &value)
{
m_result += nestPrefix();
m_result += "internatlEntityDecl(name=\"" + escapeStr(name)
- + "\", value=\"" + escapeStr(value) + "\")\n";
+ + "\", value=\"" + escapeStr(value) + "\")\n";
return true;
}
-bool ContentHandler::externalEntityDecl ( const QString & name,
- const QString & publicId,
- const QString & systemId )
+bool ContentHandler::externalEntityDecl(const QString &name,
+ const QString &publicId,
+ const QString &systemId)
{
m_result += nestPrefix();
m_result += "externalEntityDecl(name=\"" + escapeStr(name)
- + "\", publicId=\"" + escapeStr(publicId)
- + "\", systemId=\"" + escapeStr(systemId) + "\")\n";
+ + "\", publicId=\"" + escapeStr(publicId)
+ + "\", systemId=\"" + escapeStr(systemId) + "\")\n";
return true;
}
diff --git a/tests/auto/xml/sax/qxmlsimplereader/parser/parser.h b/tests/auto/xml/sax/qxmlsimplereader/parser/parser.h
index b394f0f22d..e7af7b1cb5 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/parser/parser.h
+++ b/tests/auto/xml/sax/qxmlsimplereader/parser/parser.h
@@ -49,16 +49,16 @@ class ContentHandler;
class Parser : public QXmlSimpleReader
{
- public:
- Parser();
- ~Parser();
+public:
+ Parser();
+ ~Parser();
- bool parseFile(QFile *file);
- QString result() const;
- QString errorMsg() const;
+ bool parseFile(QFile *file);
+ QString result() const;
+ QString errorMsg() const;
- private:
- ContentHandler *handler;
+private:
+ ContentHandler *handler;
};
#endif
diff --git a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
index ed909946e6..6a3bcc7a7d 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
+++ b/tests/auto/xml/sax/qxmlsimplereader/tst_qxmlsimplereader.cpp
@@ -137,17 +137,17 @@ class tst_QXmlSimpleReader : public QObject
Q_OBJECT
public:
- tst_QXmlSimpleReader();
- ~tst_QXmlSimpleReader();
+ tst_QXmlSimpleReader();
+ ~tst_QXmlSimpleReader();
private slots:
void initTestCase();
- void testGoodXmlFile();
- void testGoodXmlFile_data();
- void testBadXmlFile();
- void testBadXmlFile_data();
- void testIncrementalParsing();
- void testIncrementalParsing_data();
+ void testGoodXmlFile();
+ void testGoodXmlFile_data();
+ void testBadXmlFile();
+ void testBadXmlFile_data();
+ void testIncrementalParsing();
+ void testIncrementalParsing_data();
void setDataQString();
void inputFromQIODevice();
void inputFromString();
@@ -278,8 +278,8 @@ static QStringList findXmlFiles(QString dir_name)
QFileInfoList::const_iterator it = file_list.begin();
for (; it != file_list.end(); ++it) {
- const QFileInfo &file_info = *it;
- result.append(file_info.filePath());
+ const QFileInfo &file_info = *it;
+ result.append(file_info.filePath());
}
return result;
@@ -289,21 +289,21 @@ static QStringList findXmlFiles(QString dir_name)
void tst_QXmlSimpleReader::testGoodXmlFile_data()
{
const char * const good_data_dirs[] = {
- "xmldocs/valid/sa",
- "xmldocs/valid/not-sa",
- "xmldocs/valid/ext-sa",
- 0
+ "xmldocs/valid/sa",
+ "xmldocs/valid/not-sa",
+ "xmldocs/valid/ext-sa",
+ 0
};
const char * const *d = good_data_dirs;
QStringList good_file_list;
for (; *d != 0; ++d)
- good_file_list += findXmlFiles(*d);
+ good_file_list += findXmlFiles(*d);
QTest::addColumn<QString>("file_name");
QStringList::const_iterator it = good_file_list.begin();
for (; it != good_file_list.end(); ++it)
- QTest::newRow((*it).toLatin1()) << *it;
+ QTest::newRow((*it).toLatin1()) << *it;
}
void tst_QXmlSimpleReader::testGoodXmlFile()
@@ -331,19 +331,19 @@ void tst_QXmlSimpleReader::testGoodXmlFile()
void tst_QXmlSimpleReader::testBadXmlFile_data()
{
const char * const bad_data_dirs[] = {
- "xmldocs/not-wf/sa",
- 0
+ "xmldocs/not-wf/sa",
+ 0
};
const char * const *d = bad_data_dirs;
QStringList bad_file_list;
for (; *d != 0; ++d)
- bad_file_list += findXmlFiles(*d);
+ bad_file_list += findXmlFiles(*d);
QTest::addColumn<QString>("file_name");
QStringList::const_iterator it = bad_file_list.begin();
for (; it != bad_file_list.end(); ++it)
- QTest::newRow((*it).toLatin1()) << *it;
+ QTest::newRow((*it).toLatin1()) << *it;
}
void tst_QXmlSimpleReader::testBadXmlFile()
@@ -413,31 +413,31 @@ void tst_QXmlSimpleReader::testIncrementalParsing_data()
QTest::addColumn<int>("chunkSize");
const char * const good_data_dirs[] = {
- "xmldocs/valid/sa",
- "xmldocs/valid/not-sa",
- "xmldocs/valid/ext-sa",
- 0
+ "xmldocs/valid/sa",
+ "xmldocs/valid/not-sa",
+ "xmldocs/valid/ext-sa",
+ 0
};
const char * const *d = good_data_dirs;
QStringList good_file_list;
for (; *d != 0; ++d)
- good_file_list += findXmlFiles(*d);
+ good_file_list += findXmlFiles(*d);
for (int i=1; i<10; ++i) {
- QStringList::const_iterator it = good_file_list.begin();
- for (; it != good_file_list.end(); ++it) {
- if ( *it == "xmldocs/valid/sa/089.xml" )
- continue;// TODO: fails at the moment -- don't bother
- if ( i==1 && (
- *it == "xmldocs/valid/sa/049.xml" ||
- *it == "xmldocs/valid/sa/050.xml" ||
- *it == "xmldocs/valid/sa/051.xml" ||
- *it == "xmldocs/valid/sa/052.xml" ) ) {
- continue; // TODO: fails at the moment -- don't bother
- }
- QTest::newRow(QString("%1 %2").arg(*it).arg(i).toLatin1()) << *it << i;
- }
+ QStringList::const_iterator it = good_file_list.begin();
+ for (; it != good_file_list.end(); ++it) {
+ if ( *it == "xmldocs/valid/sa/089.xml" )
+ continue;// TODO: fails at the moment -- don't bother
+ if ( i==1 && (
+ *it == "xmldocs/valid/sa/049.xml" ||
+ *it == "xmldocs/valid/sa/050.xml" ||
+ *it == "xmldocs/valid/sa/051.xml" ||
+ *it == "xmldocs/valid/sa/052.xml" ) ) {
+ continue; // TODO: fails at the moment -- don't bother
+ }
+ QTest::newRow(QString("%1 %2").arg(*it).arg(i).toLatin1()) << *it << i;
+ }
}
}
@@ -459,7 +459,7 @@ void tst_QXmlSimpleReader::testIncrementalParsing()
first = false;
} else {
QVERIFY(parser.parseContinue());
- }
+ }
}
// detect end of document
QVERIFY(parser.parseContinue());
@@ -573,8 +573,8 @@ void tst_QXmlSimpleReader::inputFromSocket()
const bool connectionSuccess = sock.waitForConnected();
if(!connectionSuccess) {
- QTextStream out(stderr);
- out << "QTcpSocket::errorString()" << sock.errorString();
+ QTextStream out(stderr);
+ out << "QTcpSocket::errorString()" << sock.errorString();
}
QVERIFY(connectionSuccess);
diff --git a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
index eca786f688..87336aa00f 100644
--- a/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
+++ b/tests/auto/xml/sax/qxmlsimplereader/xmldocs/not-wf/sa/170.xml.ref
@@ -1,6 +1,6 @@
setDocumentLocator(locator={columnNumber=1, lineNumber=1})
startDocument()
startElement(namespaceURI="", localName="doc", qName="doc", atts=[])
- characters(ch="�")
+ characters(ch="����")
endElement(namespaceURI="", localName="doc", qName="doc")
endDocument()
diff --git a/tests/baselineserver/shared/baselineprotocol.cpp b/tests/baselineserver/shared/baselineprotocol.cpp
index cbe3ec8798..f6190f20c4 100644
--- a/tests/baselineserver/shared/baselineprotocol.cpp
+++ b/tests/baselineserver/shared/baselineprotocol.cpp
@@ -76,7 +76,11 @@ const QString PI_PulseTestrBranch(QLS("PulseTestrBranch"));
void BaselineProtocol::sysSleep(int ms)
{
#if defined(Q_OS_WIN)
+# ifndef Q_OS_WINRT
Sleep(DWORD(ms));
+# else
+ WaitForSingleObjectEx(GetCurrentThread(), ms, false);
+# endif
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
@@ -116,6 +120,7 @@ PlatformInfo PlatformInfo::localHostInfo()
pi.insert(PI_OSName, QLS("Other"));
#endif
+#ifndef QT_NO_PROCESS
QProcess git;
QString cmd;
QStringList args;
@@ -151,6 +156,7 @@ PlatformInfo PlatformInfo::localHostInfo()
pi.insert(PI_PulseGitBranch, QString::fromLatin1(gb));
}
}
+#endif // !QT_NO_PROCESS
return pi;
}
diff --git a/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp
index 49672a90bf..b2380b0e58 100644
--- a/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp
+++ b/tests/benchmarks/corelib/io/qdir/10000/bench_qdir_10000.cpp
@@ -176,7 +176,12 @@ private slots:
wcscat(appendedPath, L"\\*");
WIN32_FIND_DATA fd;
+#ifndef Q_OS_WINRT
HANDLE hSearch = FindFirstFileW(appendedPath, &fd);
+#else
+ HANDLE hSearch = FindFirstFileEx(appendedPath, FindExInfoStandard, &fd,
+ FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);
+#endif
QVERIFY(hSearch != INVALID_HANDLE_VALUE);
QBENCHMARK {
diff --git a/tests/benchmarks/corelib/io/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp
index 5188658bdb..691e822379 100644
--- a/tests/benchmarks/corelib/io/qdiriterator/main.cpp
+++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp
@@ -106,7 +106,12 @@ static int posix_helper(const wchar_t *dirpath)
wchar_t appendedPath[MAX_PATH];
wcscpy(appendedPath, dirpath);
wcscat(appendedPath, L"\\*");
+#ifndef Q_OS_WINRT
hSearch = FindFirstFile(appendedPath, &fd);
+#else
+ hSearch = FindFirstFileEx(appendedPath, FindExInfoStandard, &fd,
+ FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);
+#endif
appendedPath[origDirPathLength] = 0;
if (hSearch == INVALID_HANDLE_VALUE) {
diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp
index bb4a921fc7..82bca1541d 100644
--- a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp
+++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp
@@ -230,7 +230,12 @@ void QFileSystemIteratorPrivate::pushSubDirectory(const QByteArray &path)
wchar_t szSearchPath[MAX_PATH];
QString::fromLatin1(path).toWCharArray(szSearchPath);
wcscat(szSearchPath, L"\\*");
+#ifndef Q_OS_WINRT
HANDLE dir = FindFirstFile(szSearchPath, &m_fileSearchResult);
+#else
+ HANDLE dir = FindFirstFileEx(szSearchPath, FindExInfoStandard, &m_fileSearchResult,
+ FindExSearchLimitToDirectories, NULL, FIND_FIRST_EX_LARGE_FETCH);
+#endif
m_bFirstSearchResult = true;
#else
DIR *dir = ::opendir(path.constData());
diff --git a/tests/benchmarks/corelib/io/qfile/main.cpp b/tests/benchmarks/corelib/io/qfile/main.cpp
index 0beffebfb7..e0ae29fbee 100644
--- a/tests/benchmarks/corelib/io/qfile/main.cpp
+++ b/tests/benchmarks/corelib/io/qfile/main.cpp
@@ -310,7 +310,11 @@ void tst_qfile::readBigFile()
// ensure we don't account string conversion
wchar_t* cfilename = (wchar_t*)filename.utf16();
+#ifndef Q_OS_WINRT
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
+#else
+ hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
+#endif
Q_ASSERT(hndl);
wchar_t* nativeBuffer = new wchar_t[BUFSIZE];
DWORD numberOfBytesRead;
@@ -319,7 +323,12 @@ void tst_qfile::readBigFile()
do {
ReadFile(hndl, nativeBuffer, blockSize, &numberOfBytesRead, NULL);
} while(numberOfBytesRead != 0);
+#ifndef Q_OS_WINRT
SetFilePointer(hndl, 0, NULL, FILE_BEGIN);
+#else
+ LARGE_INTEGER offset = { 0 };
+ SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN);
+#endif
}
delete[] nativeBuffer;
CloseHandle(hndl);
@@ -400,11 +409,20 @@ void tst_qfile::seek()
// ensure we don't account string conversion
wchar_t* cfilename = (wchar_t*)filename.utf16();
+#ifndef Q_OS_WINRT
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
+#else
+ hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
+#endif
Q_ASSERT(hndl);
QBENCHMARK {
i=(i+1)%sp_size;
+#ifndef Q_OS_WINRT
SetFilePointer(hndl, seekpos[i], NULL, 0);
+#else
+ LARGE_INTEGER offset = { seekpos[i] };
+ SetFilePointerEx(hndl, offset, NULL, FILE_BEGIN);
+#endif
}
CloseHandle(hndl);
#else
@@ -489,7 +507,11 @@ void tst_qfile::open()
wchar_t* cfilename = (wchar_t*)filename.utf16();
QBENCHMARK {
+#ifndef Q_OS_WINRT
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
+#else
+ hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
+#endif
Q_ASSERT(hndl);
CloseHandle(hndl);
}
@@ -698,7 +720,11 @@ void tst_qfile::readSmallFiles()
// ensure we don't account string conversion
wchar_t* cfilename = (wchar_t*)filename.utf16();
+#ifndef Q_OS_WINRT
hndl = CreateFile(cfilename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
+#else
+ hndl = CreateFile2(cfilename, GENERIC_READ, 0, OPEN_EXISTING, 0);
+#endif
Q_ASSERT(hndl);
wchar_t* nativeBuffer = new wchar_t[BUFSIZE];
DWORD numberOfBytesRead;
diff --git a/tests/benchmarks/corelib/io/qfileinfo/main.cpp b/tests/benchmarks/corelib/io/qfileinfo/main.cpp
index 594e5b7478..de1aaea177 100644
--- a/tests/benchmarks/corelib/io/qfileinfo/main.cpp
+++ b/tests/benchmarks/corelib/io/qfileinfo/main.cpp
@@ -54,7 +54,7 @@ class qfileinfo : public QObject
private slots:
void existsTemporary();
void existsStatic();
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void symLinkTargetPerformanceLNK();
void symLinkTargetPerformanceMounpoint();
#endif
@@ -84,7 +84,7 @@ void qfileinfo::existsStatic()
QBENCHMARK { QFileInfo::exists(appPath); }
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
void qfileinfo::symLinkTargetPerformanceLNK()
{
QVERIFY(QFile::link("file","link.lnk"));
diff --git a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
index 47227ef630..52c60f9484 100644
--- a/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
+++ b/tests/benchmarks/corelib/thread/qmutex/tst_qmutex.cpp
@@ -95,7 +95,11 @@ void NativeMutexUnlock(NativeMutexType *mutex)
typedef CRITICAL_SECTION NativeMutexType;
void NativeMutexInitialize(NativeMutexType *mutex)
{
+#ifndef Q_OS_WINRT
InitializeCriticalSection(mutex);
+#else
+ InitializeCriticalSectionEx(mutex, 0, 0);
+#endif
}
void NativeMutexDestroy(NativeMutexType *mutex)
{
diff --git a/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp b/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
index 55967b9215..d5919ebe5a 100644
--- a/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
+++ b/tests/benchmarks/corelib/thread/qwaitcondition/tst_qwaitcondition.cpp
@@ -55,156 +55,88 @@ public:
}
private slots:
- void oscillate_data();
- void oscillate();
-
- void thrash_data();
- void thrash();
-
-public:
- static QWaitCondition local, remote;
- enum Turn {LocalTurn, RemoteTurn};
- static Turn turn;
+ void oscillate_mutex_data();
+ void oscillate_mutex();
+ void oscillate_writelock_data();
+ void oscillate_writelock();
};
-QWaitCondition tst_QWaitCondition::local;
-QWaitCondition tst_QWaitCondition::remote;
-tst_QWaitCondition::Turn tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
+int turn;
+const int threadCount = 10;
+QWaitCondition cond;
+
+template <class Mutex, class Locker>
class OscillateThread : public QThread
{
public:
- bool m_done;
- bool m_useMutex;
- unsigned long m_timeout;
- bool m_wakeOne;
- int count;
-
- OscillateThread(bool useMutex, unsigned long timeout, bool wakeOne)
- : m_done(false), m_useMutex(useMutex), m_timeout(timeout), m_wakeOne(wakeOne)
- {}
+ Mutex *mutex;
+ int m_threadid;
+ int timeout;
+
void run()
{
- QMutex mtx;
- QReadWriteLock rwl;
- count = 0;
-
- forever {
- if (m_done)
- break;
- if (m_useMutex) {
- mtx.lock();
- while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
- tst_QWaitCondition::remote.wait(&mtx, m_timeout);
- mtx.unlock();
- } else {
- rwl.lockForWrite();
- while (tst_QWaitCondition::turn == tst_QWaitCondition::LocalTurn)
- tst_QWaitCondition::remote.wait(&rwl, m_timeout);
- rwl.unlock();
+ for (int count = 0; count < 5000; ++count) {
+
+ Locker lock(mutex);
+ while (m_threadid != turn) {
+ cond.wait(mutex, timeout);
}
- tst_QWaitCondition::turn = tst_QWaitCondition::LocalTurn;
- if (m_wakeOne)
- tst_QWaitCondition::local.wakeOne();
- else
- tst_QWaitCondition::local.wakeAll();
- count++;
+ turn = (turn+1) % threadCount;
+ cond.wakeAll();
}
}
};
-void tst_QWaitCondition::oscillate_data()
-{
- QTest::addColumn<bool>("useMutex");
- QTest::addColumn<unsigned long>("timeout");
- QTest::addColumn<bool>("wakeOne");
-
- QTest::newRow("mutex, timeout, one") << true << 1000ul << true;
- QTest::newRow("readWriteLock, timeout, one") << false << 1000ul << true;
- QTest::newRow("mutex, timeout, all") << true << 1000ul << false;
- QTest::newRow("readWriteLock, timeout, all") << false << 1000ul << false;
- QTest::newRow("mutex, forever, one") << true << ULONG_MAX << true;
- QTest::newRow("readWriteLock, forever, one") << false << ULONG_MAX << true;
- QTest::newRow("mutex, forever, all") << true << ULONG_MAX << false;
- QTest::newRow("readWriteLock, forever, all") << false << ULONG_MAX << false;
-}
-
-void tst_QWaitCondition::oscillate()
-{
- QMutex mtx;
- QReadWriteLock rwl;
+template <class Mutex, class Locker>
+void oscillate(unsigned long timeout) {
- QFETCH(bool, useMutex);
- QFETCH(unsigned long, timeout);
- QFETCH(bool, wakeOne);
-
- turn = LocalTurn;
- OscillateThread thrd(useMutex, timeout, wakeOne);
- thrd.start();
+ OscillateThread<Mutex, Locker> thrd[threadCount];
+ Mutex m;
+ for (int i = 0; i < threadCount; ++i) {
+ thrd[i].mutex = &m;
+ thrd[i].m_threadid = i;
+ thrd[i].timeout = timeout;
+ }
QBENCHMARK {
- if (useMutex)
- mtx.lock();
- else
- rwl.lockForWrite();
- turn = RemoteTurn;
- if (wakeOne)
- remote.wakeOne();
- else
- remote.wakeAll();
- if (useMutex) {
- while (turn == RemoteTurn)
- local.wait(&mtx, timeout);
- mtx.unlock();
- } else {
- while (turn == RemoteTurn)
- local.wait(&rwl, timeout);
- rwl.unlock();
+ for (int i = 0; i < threadCount; ++i) {
+ thrd[i].start();
+ }
+ for (int i = 0; i < threadCount; ++i) {
+ thrd[i].wait();
}
}
- thrd.m_done = true;
- remote.wakeAll();
- thrd.wait();
-
- QCOMPARE(0, 0);
}
-void tst_QWaitCondition::thrash_data()
+void tst_QWaitCondition::oscillate_mutex_data()
{
- oscillate_data();
+ QTest::addColumn<unsigned long>("timeout");
+
+ QTest::newRow("0") << 0ul;
+ QTest::newRow("1") << 1ul;
+ QTest::newRow("1000") << 1000ul;
+ QTest::newRow("forever") << ULONG_MAX;
}
-void tst_QWaitCondition::thrash()
+void tst_QWaitCondition::oscillate_mutex()
{
- QMutex mtx;
- mtx.lock();
-
- QFETCH(bool, useMutex);
QFETCH(unsigned long, timeout);
- QFETCH(bool, wakeOne);
-
- turn = LocalTurn;
- OscillateThread thrd(useMutex, timeout, wakeOne);
- thrd.start();
- local.wait(&mtx, 1000ul);
- mtx.unlock();
-
- QBENCHMARK {
- turn = RemoteTurn;
- if (wakeOne)
- remote.wakeOne();
- else
- remote.wakeAll();
- }
+ oscillate<QMutex, QMutexLocker>(timeout);
+}
- thrd.m_done = true;
- turn = RemoteTurn;
- remote.wakeAll();
- thrd.wait();
+void tst_QWaitCondition::oscillate_writelock_data()
+{
+ oscillate_mutex_data();
+}
- QCOMPARE(0, 0);
+void tst_QWaitCondition::oscillate_writelock()
+{
+ QFETCH(unsigned long, timeout);
+ oscillate<QReadWriteLock, QWriteLocker>(timeout);
}
+
QTEST_MAIN(tst_QWaitCondition)
#include "tst_qwaitcondition.moc"
diff --git a/tests/benchmarks/corelib/thread/thread.pro b/tests/benchmarks/corelib/thread/thread.pro
index d7f65a911d..4e602ceb4e 100644
--- a/tests/benchmarks/corelib/thread/thread.pro
+++ b/tests/benchmarks/corelib/thread/thread.pro
@@ -3,3 +3,4 @@ SUBDIRS = \
qmutex \
qthreadstorage \
qthreadpool \
+ qwaitcondition \
diff --git a/tests/benchmarks/corelib/tools/qhash/main.cpp b/tests/benchmarks/corelib/tools/qhash/main.cpp
index a39ced19fe..b173724aed 100644
--- a/tests/benchmarks/corelib/tools/qhash/main.cpp
+++ b/tests/benchmarks/corelib/tools/qhash/main.cpp
@@ -55,13 +55,28 @@ class tst_QHash : public QObject
private slots:
void initTestCase();
+ void qhash_current_data() { data(); }
+ void qhash_current() { qhash_template<QString>(); }
+ void qhash_qt50_data() { data(); }
+ void qhash_qt50() { qhash_template<Qt50String>(); }
void qhash_qt4_data() { data(); }
- void qhash_qt4();
- void javaString_data() { data(); }
- void javaString();
+ void qhash_qt4() { qhash_template<Qt4String>(); }
+ void qhash_javaString_data() { data(); }
+ void qhash_javaString() { qhash_template<JavaString>(); }
+
+ void hashing_current_data() { data(); }
+ void hashing_current() { hashing_template<QString>(); }
+ void hashing_qt50_data() { data(); }
+ void hashing_qt50() { hashing_template<Qt50String>(); }
+ void hashing_qt4_data() { data(); }
+ void hashing_qt4() { hashing_template<Qt4String>(); }
+ void hashing_javaString_data() { data(); }
+ void hashing_javaString() { hashing_template<JavaString>(); }
private:
void data();
+ template <typename String> void qhash_template();
+ template <typename String> void hashing_template();
QStringList smallFilePaths;
QStringList uuids;
@@ -76,7 +91,7 @@ private:
void tst_QHash::initTestCase()
{
// small list of file paths
- QFile smallPathsData("paths_small_data.txt");
+ QFile smallPathsData(QFINDTESTDATA("paths_small_data.txt"));
QVERIFY(smallPathsData.open(QIODevice::ReadOnly));
smallFilePaths = QString::fromLatin1(smallPathsData.readAll()).split(QLatin1Char('\n'));
QVERIFY(!smallFilePaths.isEmpty());
@@ -133,12 +148,12 @@ void tst_QHash::data()
QTest::newRow("numbers") << numbers;
}
-void tst_QHash::qhash_qt4()
+template <typename String> void tst_QHash::qhash_template()
{
QFETCH(QStringList, items);
- QHash<Qt4String, int> hash;
+ QHash<String, int> hash;
- QList<Qt4String> realitems;
+ QList<String> realitems;
foreach (const QString &s, items)
realitems.append(s);
@@ -149,23 +164,22 @@ void tst_QHash::qhash_qt4()
}
}
-void tst_QHash::javaString()
+template <typename String> void tst_QHash::hashing_template()
{
+ // just the hashing function
QFETCH(QStringList, items);
- QHash<JavaString, int> hash;
- QList<JavaString> realitems;
+ QVector<String> realitems;
+ realitems.reserve(items.size());
foreach (const QString &s, items)
realitems.append(s);
QBENCHMARK {
- for (int i = 0, n = realitems.size(); i != n; ++i) {
- hash[realitems.at(i)] = i;
- }
+ for (int i = 0, n = realitems.size(); i != n; ++i)
+ (void)qHash(realitems.at(i));
}
}
-
QTEST_MAIN(tst_QHash)
#include "main.moc"
diff --git a/tests/benchmarks/corelib/tools/qhash/main.h b/tests/benchmarks/corelib/tools/qhash/main.h
index bd3f0db12d..86a1a3d09b 100644
--- a/tests/benchmarks/corelib/tools/qhash/main.h
+++ b/tests/benchmarks/corelib/tools/qhash/main.h
@@ -51,6 +51,16 @@ QT_BEGIN_NAMESPACE
uint qHash(const Qt4String &);
QT_END_NAMESPACE
+struct Qt50String : QString
+{
+ Qt50String() {}
+ Qt50String(const QString &s) : QString(s) {}
+};
+
+QT_BEGIN_NAMESPACE
+uint qHash(const Qt50String &, uint seed = 0);
+QT_END_NAMESPACE
+
struct JavaString : QString
{
diff --git a/tests/benchmarks/corelib/tools/qhash/outofline.cpp b/tests/benchmarks/corelib/tools/qhash/outofline.cpp
index 9ccfc11224..3a2278503d 100644
--- a/tests/benchmarks/corelib/tools/qhash/outofline.cpp
+++ b/tests/benchmarks/corelib/tools/qhash/outofline.cpp
@@ -57,6 +57,16 @@ uint qHash(const Qt4String &str)
return h;
}
+uint qHash(const Qt50String &key, uint seed)
+{
+ const QChar *p = key.unicode();
+ int len = key.size();
+ uint h = seed;
+ for (int i = 0; i < len; ++i)
+ h = 31 * h + p[i].unicode();
+ return h;
+}
+
// The Java's hashing algorithm for strings is a variation of D. J. Bernstein
// hashing algorithm appeared here http://cr.yp.to/cdb/cdb.txt
// and informally known as DJB33XX - DJB's 33 Times Xor.
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp
index 4d6a8712fd..949965adf2 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp
+++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.cpp
@@ -94,25 +94,25 @@ void ChipTester::paintEvent(QPaintEvent *event)
{
QGraphicsView::paintEvent(event);
if (++npaints == 50)
- eventLoop.quit();
+ eventLoop.quit();
}
void ChipTester::timerEvent(QTimerEvent *)
{
switch (operation) {
case Rotate360:
- rotate(1);
- break;
+ rotate(1);
+ break;
case ZoomInOut: {
- qreal s = 0.05 + (npaints / 20.0);
- setTransform(QTransform().scale(s, s));
- break;
+ qreal s = 0.05 + (npaints / 20.0);
+ setTransform(QTransform().scale(s, s));
+ break;
}
case Translate: {
- int offset = horizontalScrollBar()->minimum()
- + (npaints % (horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum()));
- horizontalScrollBar()->setValue(offset);
- break;
+ int offset = horizontalScrollBar()->minimum()
+ + (npaints % (horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum()));
+ horizontalScrollBar()->setValue(offset);
+ break;
}
}
}
diff --git a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h
index 4e5b436f8d..38133f6078 100644
--- a/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h
+++ b/tests/benchmarks/gui/graphicsview/qgraphicsview/chiptester/chiptester.h
@@ -57,9 +57,9 @@ class ChipTester : public QGraphicsView
Q_OBJECT
public:
enum Operation {
- Rotate360,
- ZoomInOut,
- Translate
+ Rotate360,
+ ZoomInOut,
+ Translate
};
ChipTester(QWidget *parent = 0);
diff --git a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
index fd12c89e80..eda46a1df0 100644
--- a/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
+++ b/tests/benchmarks/gui/image/qimageconversion/tst_qimageconversion.cpp
@@ -42,28 +42,39 @@
#include <qtest.h>
#include <QImage>
+Q_DECLARE_METATYPE(QImage::Format)
class tst_QImageConversion : public QObject
{
Q_OBJECT
private slots:
- void convertRgb888ToRGB32_data();
- void convertRgb888ToRGB32();
+ void convertRgb888ToRgb32_data();
+ void convertRgb888ToRgb32();
+
+ void convertRgb32ToRgb888_data();
+ void convertRgb32ToRgb888();
+
+ void convertGeneric_data();
+ void convertGeneric();
private:
QImage generateImageRgb888(int width, int height);
+ QImage generateImageRgb16(int width, int height);
+ QImage generateImageRgb32(int width, int height);
+ QImage generateImageArgb32(int width, int height);
};
-void tst_QImageConversion::convertRgb888ToRGB32_data()
+void tst_QImageConversion::convertRgb888ToRgb32_data()
{
QTest::addColumn<QImage>("inputImage");
+
// height = 5000 to get interesting timing.
// 3 pixels wide -> smaller than regular vector of 128bits
QTest::newRow("width: 3px; height: 5000px;") << generateImageRgb888(3, 5000);
// 8 pixels wide -> potential for 2 vectors
- QTest::newRow("width: 8px; height: 5000px;") << generateImageRgb888(3, 5000);
+ QTest::newRow("width: 8px; height: 5000px;") << generateImageRgb888(8, 5000);
// 16 pixels, minimum for the SSSE3 implementation
QTest::newRow("width: 16px; height: 5000px;") << generateImageRgb888(16, 5000);
@@ -72,10 +83,10 @@ void tst_QImageConversion::convertRgb888ToRGB32_data()
QTest::newRow("width: 50px; height: 5000px;") << generateImageRgb888(50, 5000);
// 2000 pixels -> typical values for pictures
- QTest::newRow("width: 2000px; height: 5000px;") << generateImageRgb888(2000, 5000);
+ QTest::newRow("width: 2000px; height: 2000px;") << generateImageRgb888(2000, 2000);
}
-void tst_QImageConversion::convertRgb888ToRGB32()
+void tst_QImageConversion::convertRgb888ToRgb32()
{
QFETCH(QImage, inputImage);
@@ -87,6 +98,76 @@ void tst_QImageConversion::convertRgb888ToRGB32()
}
}
+void tst_QImageConversion::convertRgb32ToRgb888_data()
+{
+ QTest::addColumn<QImage>("inputImage");
+ // height = 5000 to get interesting timing.
+
+ // 3 pixels wide -> smaller than regular vector of 128bits
+ QTest::newRow("width: 3px; height: 5000px;") << generateImageRgb32(3, 5000);
+
+ // 8 pixels wide -> potential for 2 vectors
+ QTest::newRow("width: 8px; height: 5000px;") << generateImageRgb32(8, 5000);
+
+ // 16 pixels, minimum for the SSSE3 implementation
+ QTest::newRow("width: 16px; height: 5000px;") << generateImageRgb32(16, 5000);
+
+ // 50 pixels, more realistic use case
+ QTest::newRow("width: 50px; height: 5000px;") << generateImageRgb32(50, 5000);
+
+ // 2000 pixels -> typical values for pictures
+ QTest::newRow("width: 2000px; height: 2000px;") << generateImageRgb32(2000, 2000);
+}
+
+void tst_QImageConversion::convertRgb32ToRgb888()
+{
+ QFETCH(QImage, inputImage);
+
+ QBENCHMARK {
+ volatile QImage output = inputImage.convertToFormat(QImage::Format_RGB888);
+ // we need the volatile and the following to make sure the compiler does not do
+ // anything stupid :)
+ (void)output;
+ }
+}
+
+
+void tst_QImageConversion::convertGeneric_data()
+{
+ QTest::addColumn<QImage>("inputImage");
+ QTest::addColumn<QImage::Format>("outputFormat");
+ QImage rgb16 = generateImageRgb16(1000, 1000);
+ QImage rgb32 = generateImageRgb32(1000, 1000);
+ QImage argb32 = generateImageArgb32(1000, 1000);
+
+ QTest::newRow("rgb16 -> rgb32") << rgb16 << QImage::Format_RGB32;
+ QTest::newRow("rgb16 -> rgb888") << rgb16 << QImage::Format_RGB888;
+ QTest::newRow("rgb16 -> rgb666") << rgb16 << QImage::Format_RGB666;
+ QTest::newRow("rgb16 -> rgb555") << rgb16 << QImage::Format_RGB555;
+
+ QTest::newRow("rgb32 -> rgb16") << rgb32 << QImage::Format_RGB16;
+ QTest::newRow("rgb32 -> rgb888") << rgb32 << QImage::Format_RGB888;
+ QTest::newRow("rgb32 -> rgb666") << rgb32 << QImage::Format_RGB666;
+ QTest::newRow("rgb32 -> rgb555") << rgb32 << QImage::Format_RGB555;
+
+ QTest::newRow("argb32 -> rgba8888") << argb32 << QImage::Format_RGBA8888;
+ QTest::newRow("argb32 -> rgb888") << argb32 << QImage::Format_RGB888;
+ QTest::newRow("argb32 -> rgb666") << argb32 << QImage::Format_RGB666;
+ QTest::newRow("argb32 -> argb8565pm") << argb32 << QImage::Format_ARGB8565_Premultiplied;
+ QTest::newRow("argb32 -> argb4444pm") << argb32 << QImage::Format_ARGB4444_Premultiplied;
+}
+
+void tst_QImageConversion::convertGeneric()
+{
+ QFETCH(QImage, inputImage);
+ QFETCH(QImage::Format, outputFormat);
+
+ QBENCHMARK {
+ QImage output = inputImage.convertToFormat(outputFormat);
+ output.constBits();
+ }
+}
+
/*
Fill a RGB888 image with "random" pixel values.
*/
@@ -103,5 +184,52 @@ QImage tst_QImageConversion::generateImageRgb888(int width, int height)
return image;
}
+/*
+ Fill a RGB16 image with "random" pixel values.
+ */
+QImage tst_QImageConversion::generateImageRgb16(int width, int height)
+{
+ QImage image(width, height, QImage::Format_RGB16);
+ const int byteWidth = width * 2;
+
+ for (int y = 0; y < image.height(); ++y) {
+ uchar *scanline = image.scanLine(y);
+ for (int x = 0; x < byteWidth; ++x)
+ scanline[x] = x ^ y;
+ }
+ return image;
+}
+
+/*
+ Fill a RGB32 image with "random" pixel values.
+ */
+QImage tst_QImageConversion::generateImageRgb32(int width, int height)
+{
+ QImage image(width, height, QImage::Format_RGB32);
+
+ for (int y = 0; y < image.height(); ++y) {
+ QRgb *scanline = (QRgb*)image.scanLine(y);
+ for (int x = 0; x < width; ++x)
+ scanline[x] = qRgb(x, y, x ^ y);
+ }
+ return image;
+}
+
+/*
+ Fill a ARGB32 image with "random" pixel values.
+ */
+QImage tst_QImageConversion::generateImageArgb32(int width, int height)
+{
+ QImage image(width, height, QImage::Format_ARGB32);
+ const int byteWidth = width * 4;
+
+ for (int y = 0; y < image.height(); ++y) {
+ uchar *scanline = image.scanLine(y);
+ for (int x = 0; x < byteWidth; ++x)
+ scanline[x] = x ^ y;
+ }
+ return image;
+}
+
QTEST_MAIN(tst_QImageConversion)
#include "tst_qimageconversion.moc"
diff --git a/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp
index 5ed6651052..fb95ecb5b4 100644
--- a/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp
+++ b/tests/benchmarks/network/socket/qtcpserver/tst_qtcpserver.cpp
@@ -88,7 +88,9 @@ void tst_QTcpServer::initTestCase_data()
QTest::addColumn<int>("proxyType");
QTest::newRow("WithoutProxy") << false << 0;
+#ifndef QT_NO_NETWORKPROXY
QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy);
+#endif
}
void tst_QTcpServer::initTestCase()
@@ -100,16 +102,22 @@ void tst_QTcpServer::init()
{
QFETCH_GLOBAL(bool, setProxy);
if (setProxy) {
+#ifndef QT_NO_NETWORKPROXY
QFETCH_GLOBAL(int, proxyType);
if (proxyType == QNetworkProxy::Socks5Proxy) {
QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080));
}
+#else // !QT_NO_NETWORKPROXY
+ QSKIP("No proxy support");
+#endif // QT_NO_NETWORKPROXY
}
}
void tst_QTcpServer::cleanup()
{
+#ifndef QT_NO_NETWORKPROXY
QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy);
+#endif
}
//----------------------------------------------------------------------------------
diff --git a/tests/manual/bearerex/bearerex.cpp b/tests/manual/bearerex/bearerex.cpp
index 185dbe123e..97a98bebc9 100644
--- a/tests/manual/bearerex/bearerex.cpp
+++ b/tests/manual/bearerex/bearerex.cpp
@@ -142,8 +142,8 @@ void BearerEx::on_showDetailsButton_clicked()
}
QNetworkConfiguration networkConfiguration = qvariant_cast<QNetworkConfiguration>(item->data(Qt::UserRole));
- DetailedInfoDialog infoDialog(&networkConfiguration,this);
- infoDialog.exec();
+ DetailedInfoDialog infoDialog(&networkConfiguration,this);
+ infoDialog.exec();
}
void BearerEx::on_createSessionButton_clicked()
@@ -236,12 +236,12 @@ DetailedInfoDialog::DetailedInfoDialog(QNetworkConfiguration* apNetworkConfigura
rowCount = rowCount + apNetworkConfiguration->children().count();
}
- tableWidget->setRowCount(rowCount);
- tableWidget->setColumnWidth(1,250);
- tableWidget->setItem(0, 0, new QTableWidgetItem(tr("Name")));
- tableWidget->setItem(0, 1, new QTableWidgetItem(apNetworkConfiguration->name()));
- tableWidget->setItem(1, 0, new QTableWidgetItem(tr("Id")));
- tableWidget->setItem(1, 1, new QTableWidgetItem(apNetworkConfiguration->identifier()));
+ tableWidget->setRowCount(rowCount);
+ tableWidget->setColumnWidth(1,250);
+ tableWidget->setItem(0, 0, new QTableWidgetItem(tr("Name")));
+ tableWidget->setItem(0, 1, new QTableWidgetItem(apNetworkConfiguration->name()));
+ tableWidget->setItem(1, 0, new QTableWidgetItem(tr("Id")));
+ tableWidget->setItem(1, 1, new QTableWidgetItem(apNetworkConfiguration->identifier()));
if (apNetworkConfiguration->type() == QNetworkConfiguration::ServiceNetwork) {
for (int i=0; i<apNetworkConfiguration->children().count(); i++) {
tableWidget->setItem(i+2, 0, new QTableWidgetItem(QString("IAP")+QString::number(i+1)));
diff --git a/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm b/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
index d276961b93..6919562ddc 100644
--- a/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
+++ b/tests/manual/cocoa/qmaccocoaviewcontainer/main.mm
@@ -42,6 +42,7 @@
#import "TestMouseMovedNSView.h"
#include <QtGui>
+#include <QtWidgets>
#include <QMacCocoaViewContainer>
class MyWidget : public QWidget
diff --git a/tests/manual/dialogs/printdialogpanel.cpp b/tests/manual/dialogs/printdialogpanel.cpp
index d0684f6e35..5c89055e22 100644
--- a/tests/manual/dialogs/printdialogpanel.cpp
+++ b/tests/manual/dialogs/printdialogpanel.cpp
@@ -47,6 +47,7 @@
#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
+#include <QPageSetupDialog>
#include <QApplication>
#include <QDesktopWidget>
#include <QGroupBox>
@@ -211,15 +212,9 @@ static void print(QPrinter *printer)
QPainter painter(printer);
const QRectF pageF = printer->pageRect();
- painter.drawRect(pageF);
-
- drawHorizCmRuler(painter, pageF.x(), pageF.right(), pageF.height() /2);
- drawVertCmRuler(painter, pageF.x() + pageF.width() / 2, pageF.top(), pageF.bottom());
-
QFont font = painter.font();
font.setFamily("Courier");
font.setPointSize(10);
- painter.setFont(font);
// Format message.
const int charHeight = QFontMetrics(font).boundingRect('X').height();
@@ -233,6 +228,17 @@ static void print(QPrinter *printer)
<< "\nFont: " << font.family() << ' ' << font.pointSize() << '\n'
<< *printer;
+ if (!painter.device()->logicalDpiY() || !painter.device()->logicalDpiX()) {
+ qWarning() << Q_FUNC_INFO << "Bailing out due to invalid DPI: " << msg;
+ return;
+ }
+
+ painter.drawRect(pageF);
+
+ drawHorizCmRuler(painter, pageF.x(), pageF.right(), pageF.height() /2);
+ drawVertCmRuler(painter, pageF.x() + pageF.width() / 2, pageF.top(), pageF.bottom());
+
+ painter.setFont(font);
QPointF textPoint = pageF.topLeft() + QPoint(10, charHeight + 10);
foreach (const QString &line, msg.split('\n')) {
painter.drawText(textPoint, line);
@@ -330,6 +336,9 @@ PrintDialogPanel::PrintDialogPanel(QWidget *parent)
button = new QPushButton(tr("Preview..."), m_dialogsGroupBox);
connect(button, SIGNAL(clicked()), this, SLOT(showPreviewDialog()));
vBoxLayout->addWidget(button);
+ button = new QPushButton(tr("Page Setup..."), m_dialogsGroupBox);
+ connect(button, SIGNAL(clicked()), this, SLOT(showPageSetupDialog()));
+ vBoxLayout->addWidget(button);
QGridLayout *gridLayout = new QGridLayout(this);
gridLayout->addWidget(m_creationGroupBox, 0, 0);
@@ -414,6 +423,14 @@ void PrintDialogPanel::showPreviewDialog()
retrieveSettings(m_printer.data());
}
+void PrintDialogPanel::showPageSetupDialog()
+{
+ applySettings(m_printer.data());
+ QPageSetupDialog dialog(m_printer.data(), this);
+ if (dialog.exec() == QDialog::Accepted)
+ retrieveSettings(m_printer.data());
+}
+
#include "printdialogpanel.moc"
#endif // !QT_NO_PRINTER
diff --git a/tests/manual/dialogs/printdialogpanel.h b/tests/manual/dialogs/printdialogpanel.h
index 4999504a3c..c869782769 100644
--- a/tests/manual/dialogs/printdialogpanel.h
+++ b/tests/manual/dialogs/printdialogpanel.h
@@ -69,6 +69,7 @@ private slots:
void deletePrinter();
void showPrintDialog();
void showPreviewDialog();
+ void showPageSetupDialog();
void enableCustomSizeControl();
private:
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 381922288f..62722ea62b 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -25,6 +25,7 @@ qnetworkreply \
qpainfo \
qscreen \
qssloptions \
+qsslsocket \
qtabletevent \
qtexteditlist \
qtbug-8933 \
@@ -47,6 +48,8 @@ unc
!contains(QT_CONFIG, openssl):!contains(QT_CONFIG, openssl-linked):SUBDIRS -= qssloptions
+contains(QT_CONFIG, opengl):SUBDIRS += qopengltextureblitter
+
win32 {
SUBDIRS -= network_remote_stresstest network_stresstest
# disable some tests on wince because of missing dependencies
diff --git a/tests/manual/qopengltextureblitter/main.cpp b/tests/manual/qopengltextureblitter/main.cpp
new file mode 100644
index 0000000000..3e9c30932a
--- /dev/null
+++ b/tests/manual/qopengltextureblitter/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureblitwindow.h"
+#include <QtGui/QGuiApplication>
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QOpenGLTextureBlitWindow window;
+ window.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitter.pro b/tests/manual/qopengltextureblitter/qopengltextureblitter.pro
new file mode 100644
index 0000000000..95f1c14e5a
--- /dev/null
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitter.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+TARGET = qopengltextureblitter
+INCLUDEPATH += .
+
+QT+=gui-private
+# Input
+HEADERS += \
+ qopengltextureblitwindow.h
+
+SOURCES += \
+ main.cpp \
+ qopengltextureblitwindow.cpp
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
new file mode 100644
index 0000000000..8f51f511c9
--- /dev/null
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qopengltextureblitwindow.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QOpenGLTexture>
+#include <QtGui/QMatrix4x4>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+QOpenGLTextureBlitWindow::QOpenGLTextureBlitWindow()
+ : QWindow()
+ , m_context(new QOpenGLContext(this))
+{
+ resize(500,500);
+ setSurfaceType(OpenGLSurface);
+ QSurfaceFormat surfaceFormat = format();
+ if (QCoreApplication::arguments().contains(QStringLiteral("-coreprofile"))) {
+ surfaceFormat.setVersion(3,2);
+ surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
+ }
+
+ setFormat(surfaceFormat);
+ create();
+ m_context->setFormat(surfaceFormat);
+ m_context->create();
+
+ m_context->makeCurrent(this);
+
+ m_blitter.create();
+}
+
+void QOpenGLTextureBlitWindow::render()
+{
+ m_context->makeCurrent(this);
+
+ QRect viewport(0,0,dWidth(),dHeight());
+ glViewport(0,0,dWidth(), dHeight());
+
+ glClearColor(0.f, .6f, .0f, 0.f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ QOpenGLTexture texture(m_image);
+ texture.setWrapMode(QOpenGLTexture::ClampToEdge);
+ texture.create();
+
+ QOpenGLTexture texture_mirrored(m_image_mirrord);
+ texture_mirrored.setWrapMode(QOpenGLTexture::ClampToEdge);
+ texture_mirrored.create();
+
+ QRectF topLeftOriginTopLeft(QPointF(0,0), QPointF(dWidth()/2.0, dHeight()/2.0));
+ QRectF topRightOriginTopLeft(QPointF(dWidth()/2.0,0), QPointF(dWidth(), dHeight()/2.0));
+ QRectF bottomLeftOriginTopLeft(QPointF(0, dHeight()/2.0), QPointF(dWidth() /2.0, dHeight()));
+ QRectF bottomRightOriginTopLeft(QPoint(dWidth()/2.0, dHeight()/2.0), QPointF(dWidth(), dHeight()));
+
+ QRectF topLeftOriginBottomLeft = bottomLeftOriginTopLeft; Q_UNUSED(topLeftOriginBottomLeft);
+ QRectF topRightOriginBottomLeft = bottomRightOriginTopLeft; Q_UNUSED(topRightOriginBottomLeft);
+ QRectF bottomLeftOriginBottomLeft = topLeftOriginTopLeft;
+ QRectF bottomRightOriginBottomLeft = topRightOriginTopLeft;
+
+ QOpenGLTextureBlitter::Origin topLeftOrigin = QOpenGLTextureBlitter::OriginTopLeft;
+ QOpenGLTextureBlitter::Origin bottomLeftOrigin = QOpenGLTextureBlitter::OriginBottomLeft;
+
+ QMatrix4x4 topRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(topRightOriginTopLeft, viewport);
+ QMatrix4x4 bottomLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(bottomLeftOriginTopLeft, viewport);
+ QMatrix4x4 bottomRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(bottomRightOriginTopLeft, viewport);
+
+ QMatrix3x3 texTopLeftOriginTopLeft = QOpenGLTextureBlitter::sourceTransform(topLeftOriginTopLeft, m_image.size(), topLeftOrigin);
+ QMatrix3x3 texTopRightOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(topRightOriginBottomLeft, m_image.size(), bottomLeftOrigin);
+ QMatrix3x3 texBottomLeftOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(bottomLeftOriginBottomLeft, m_image.size(), bottomLeftOrigin);
+ QMatrix3x3 texBottomRightOriginBottomLeft = QOpenGLTextureBlitter::sourceTransform(bottomRightOriginBottomLeft, m_image.size(), bottomLeftOrigin);
+
+ QSizeF subSize(topLeftOriginTopLeft.width()/2, topLeftOriginTopLeft.height()/2);
+ QRectF subTopLeftOriginTopLeft(topLeftOriginTopLeft.topLeft(), subSize);
+ QRectF subTopRightOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x() + topLeftOriginTopLeft.width() / 2,
+ topLeftOriginTopLeft.topLeft().y()), subSize);
+ QRectF subBottomLeftOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x(),
+ topLeftOriginTopLeft.topLeft().y() + topLeftOriginTopLeft.height() / 2), subSize);
+ QRectF subBottomRightOriginTopLeft(QPointF(topLeftOriginTopLeft.topLeft().x() + topLeftOriginTopLeft.width() / 2,
+ topLeftOriginTopLeft.topLeft().y() + topLeftOriginTopLeft.height() / 2), subSize);
+
+ QMatrix4x4 subTopLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subTopLeftOriginTopLeft, viewport);
+ QMatrix4x4 subTopRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subTopRightOriginTopLeft, viewport);
+ QMatrix4x4 subBottomLeftOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subBottomLeftOriginTopLeft, viewport);
+ QMatrix4x4 subBottomRightOriginTopLeftVertex = QOpenGLTextureBlitter::targetTransform(subBottomRightOriginTopLeft, viewport);
+
+ m_blitter.bind();
+ m_blitter.blit(texture_mirrored.textureId(), subTopLeftOriginTopLeftVertex, texBottomRightOriginBottomLeft);
+ m_blitter.blit(texture_mirrored.textureId(), subTopRightOriginTopLeftVertex, texBottomLeftOriginBottomLeft);
+ m_blitter.blit(texture.textureId(), subBottomLeftOriginTopLeftVertex, texTopRightOriginBottomLeft);
+ m_blitter.blit(texture.textureId(), subBottomRightOriginTopLeftVertex, texTopLeftOriginTopLeft);
+
+ m_blitter.blit(texture.textureId(), topRightOriginTopLeftVertex, topLeftOrigin);
+ m_blitter.blit(texture_mirrored.textureId(), bottomLeftOriginTopLeftVertex, topLeftOrigin);
+
+ m_blitter.setSwizzleRB(true);
+ m_blitter.blit(texture.textureId(), bottomRightOriginTopLeftVertex, texTopLeftOriginTopLeft);
+ m_blitter.setSwizzleRB(false);
+ m_blitter.release();
+
+ m_context->swapBuffers(this);
+}
+
+
+void QOpenGLTextureBlitWindow::exposeEvent(QExposeEvent *event)
+{
+ Q_UNUSED(event);
+ render();
+}
+
+void QOpenGLTextureBlitWindow::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ m_image = QImage(size() * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied);
+
+ m_image.fill(Qt::gray);
+
+ QPainter p(&m_image);
+
+ QPen pen(Qt::red);
+ pen.setWidth(5);
+ p.setPen(pen);
+
+ QFont font = p.font();
+ font.setPixelSize(qMin(m_image.height(), m_image.width()) / 20);
+ p.setFont(font);
+
+ int dx = dWidth() / 5;
+ int dy = dHeight() / 5;
+ for (int y = 0; y < 5; y++) {
+ for (int x = 0; x < 5; x++) {
+ QRect textRect(x * dx, y*dy, dx,dy);
+ QString text = QString("[%1,%2]").arg(x).arg(y);
+ p.drawText(textRect,text);
+ }
+ }
+
+ p.drawRect(QRectF(2.5,2.5,dWidth() - 5, dHeight() - 5));
+
+ m_image_mirrord = m_image.mirrored(false,true);
+}
+
diff --git a/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h
new file mode 100644
index 0000000000..31532db2cd
--- /dev/null
+++ b/tests/manual/qopengltextureblitter/qopengltextureblitwindow.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QOPENGLTEXTUREBLITWINDOW_H
+#define QOPENGLTEXTUREBLITWINDOW_H
+
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/private/qopengltextureblitter_p.h>
+
+class QOpenGLTextureBlitWindow : public QWindow
+{
+ Q_OBJECT
+public:
+ QOpenGLTextureBlitWindow();
+
+ void render();
+protected:
+ void exposeEvent(QExposeEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ qreal dWidth() const { return width() * devicePixelRatio(); }
+ qreal dHeight() const { return height() * devicePixelRatio(); }
+
+ QScopedPointer<QOpenGLContext> m_context;
+ QOpenGLTextureBlitter m_blitter;
+ QImage m_image;
+ QImage m_image_mirrord;
+};
+
+#endif
diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp
new file mode 100644
index 0000000000..68f9be7199
--- /dev/null
+++ b/tests/manual/qopenglwidget/openglwidget/main.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "openglwidget.h"
+#include <QApplication>
+#include <QPushButton>
+#include <QMdiArea>
+#include <QLCDNumber>
+#include <QTimer>
+
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ QMdiArea w;
+ w.resize(400,400);
+
+ OpenGLWidget *glw = new OpenGLWidget;
+ w.addSubWindow(glw);
+ glw->setMinimumSize(100,100);
+
+ OpenGLWidget *glw2 = new OpenGLWidget;
+ glw2->setMinimumSize(100,100);
+ w.addSubWindow(glw2);
+
+ QLCDNumber *lcd = new QLCDNumber;
+ lcd->display(1337);
+ lcd->setMinimumSize(300,100);
+ w.addSubWindow(lcd);
+
+ w.show();
+
+ return a.exec();
+}
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
new file mode 100644
index 0000000000..5752326911
--- /dev/null
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define GL_GLEXT_PROTOTYPES
+
+#include "openglwidget.h"
+#include <QtWidgets/private/qwidget_p.h>
+#include <QOpenGLFramebufferObject>
+#include <QWindow>
+#include <qpa/qplatformwindow.h>
+#include <QDebug>
+#include <QTimer>
+
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QOpenGLShaderProgram>
+#include <QtGui/QScreen>
+
+#include <QtCore/qmath.h>
+#include <qopengl.h>
+
+class OpenGLWidgetPrivate
+{
+public:
+ OpenGLWidgetPrivate()
+ : m_program(0), m_frame(0)
+ {
+
+ }
+
+ void initialize();
+ void render();
+
+
+ int width() {return w;}
+ int height() {return h;}
+
+ GLuint m_posAttr;
+ GLuint m_colAttr;
+ GLuint m_matrixUniform;
+
+ QOpenGLShaderProgram *m_program;
+ int m_frame;
+
+ int w,h;
+};
+
+
+OpenGLWidget::OpenGLWidget(QWidget *parent)
+ : QOpenGLWidget(parent)
+{
+ d = new OpenGLWidgetPrivate;
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(updateGL()));
+ timer->start(30);
+}
+
+OpenGLWidget::~OpenGLWidget()
+{
+
+}
+
+void OpenGLWidget::initializeGL()
+{
+// qDebug("*initializeGL*");
+ d->initialize();
+}
+
+void OpenGLWidget::resizeGL(int w, int h)
+{
+// qDebug("*resizeGL*");
+ d->w = w;
+ d->h = h;
+}
+void OpenGLWidget::paintGL()
+{
+// qDebug("*paintGL* %d", d->m_frame);
+ d->render();
+}
+
+
+static const char *vertexShaderSource =
+ "attribute highp vec4 posAttr;\n"
+ "attribute lowp vec4 colAttr;\n"
+ "varying lowp vec4 col;\n"
+ "uniform highp mat4 matrix;\n"
+ "void main() {\n"
+ " col = colAttr;\n"
+ " gl_Position = matrix * posAttr;\n"
+ "}\n";
+
+static const char *fragmentShaderSource =
+ "varying lowp vec4 col;\n"
+ "void main() {\n"
+ " gl_FragColor = col;\n"
+ "}\n";
+
+void OpenGLWidgetPrivate::initialize()
+{
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->link();
+ m_posAttr = m_program->attributeLocation("posAttr");
+ m_colAttr = m_program->attributeLocation("colAttr");
+ m_matrixUniform = m_program->uniformLocation("matrix");
+}
+
+void OpenGLWidgetPrivate::render()
+{
+ const qreal retinaScale = 1.0;//devicePixelRatio();
+ glViewport(0, 0, width() * retinaScale, height() * retinaScale);
+
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ m_program->bind();
+
+ QMatrix4x4 matrix;
+ matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
+ matrix.translate(0, 0, -2);
+ matrix.rotate(100.0f * m_frame / 30/*screen()->refreshRate()*/, 0, 1, 0);
+
+ m_program->setUniformValue(m_matrixUniform, matrix);
+
+ GLfloat vertices[] = {
+ 0.0f, 0.707f,
+ -0.5f, -0.5f,
+ 0.5f, -0.5f
+ };
+
+ GLfloat colors[] = {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f
+ };
+
+ glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+ glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(0);
+
+ m_program->release();
+
+ ++m_frame;
+}
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.h b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
new file mode 100644
index 0000000000..eaba27df26
--- /dev/null
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OPENGLWIDGET_H
+#define OPENGLWIDGET_H
+
+#include <QtWidgets/private/qopenglwidget_p.h>
+
+class OpenGLWidgetPrivate;
+class OpenGLWidget : public QOpenGLWidget
+{
+ Q_OBJECT
+public:
+ OpenGLWidget(QWidget *parent = 0);
+ ~OpenGLWidget();
+
+ void initializeGL();
+ void resizeGL(int w, int h);
+ void paintGL();
+
+private:
+ OpenGLWidgetPrivate *d;
+};
+
+#endif // OPENGLWIDGET_H
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.pro b/tests/manual/qopenglwidget/openglwidget/openglwidget.pro
new file mode 100644
index 0000000000..63d877e7b0
--- /dev/null
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.pro
@@ -0,0 +1,9 @@
+QT += widgets widgets-private gui-private core-private
+
+TARGET = openglwidget
+TEMPLATE = app
+
+SOURCES += main.cpp \
+ openglwidget.cpp
+
+HEADERS += openglwidget.h
diff --git a/tests/manual/qpainfo/main.cpp b/tests/manual/qpainfo/main.cpp
index 0f5119bab3..c51ca6323b 100644
--- a/tests/manual/qpainfo/main.cpp
+++ b/tests/manual/qpainfo/main.cpp
@@ -116,10 +116,8 @@ int main(int argc, char **argv)
QGuiApplication app(argc, argv);
const QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
- std::cout << "Qt " << QT_VERSION_STR << " on \"" << QGuiApplication::platformName().toStdString() << "\" "
- << QSysInfo::WordSize << " bit/"
+ std::cout << QLibraryInfo::build() << " on \"" << QGuiApplication::platformName().toStdString() << "\" "
<< (QSysInfo::ByteOrder == QSysInfo::LittleEndian ? "little endian" : "big endian") << '/'
- << (QLibraryInfo::isDebugBuild() ? "debug" : "release")
<< '\n';
#if defined(Q_OS_WIN)
@@ -180,7 +178,8 @@ int main(int argc, char **argv)
<< " startDragVelocity=" << styleHints->startDragVelocity() << " keyboardInputInterval=" << styleHints->keyboardInputInterval()
<< " keyboardAutoRepeatRate=" << styleHints->keyboardAutoRepeatRate() << " cursorFlashTime=" << styleHints->cursorFlashTime()
<< " showIsFullScreen=" << styleHints->showIsFullScreen() << " passwordMaskDelay=" << styleHints->passwordMaskDelay()
- << " fontSmoothingGamma=" << styleHints->fontSmoothingGamma() << " useRtlExtensions=" << styleHints->useRtlExtensions() << '\n';
+ << " fontSmoothingGamma=" << styleHints->fontSmoothingGamma() << " useRtlExtensions=" << styleHints->useRtlExtensions()
+ << " mousePressAndHoldInterval=" << styleHints->mousePressAndHoldInterval() << '\n';
const QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
std::cout << "\nTheme:\n Styles: " << platformTheme->themeHint(QPlatformTheme::StyleNames).toStringList();
diff --git a/tests/manual/qsslsocket/main.cpp b/tests/manual/qsslsocket/main.cpp
new file mode 100644
index 0000000000..67726b5897
--- /dev/null
+++ b/tests/manual/qsslsocket/main.cpp
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtNetwork/qsslconfiguration.h>
+#include <QtNetwork/qsslsocket.h>
+#include <QtTest/QtTest>
+
+#ifndef QT_NO_SSL
+Q_DECLARE_METATYPE(QSslConfiguration::NextProtocolNegotiationStatus)
+#endif
+
+class tst_QSslSocket : public QObject
+{
+ Q_OBJECT
+
+#ifndef QT_NO_SSL
+private slots:
+ void nextProtocolNegotiation_data();
+ void nextProtocolNegotiation();
+#endif // QT_NO_SSL
+};
+
+#ifndef QT_NO_SSL
+void tst_QSslSocket::nextProtocolNegotiation_data()
+{
+ QTest::addColumn<bool>("setConfiguration");
+ QTest::addColumn<QString>("host");
+ QTest::addColumn<QList<QByteArray> >("allowedProtocols");
+ QTest::addColumn<QByteArray>("expectedProtocol");
+ QTest::addColumn<QSslConfiguration::NextProtocolNegotiationStatus>("expectedStatus");
+
+ QList<QString> hosts = QList<QString>()
+ << QStringLiteral("www.google.com")
+ << QStringLiteral("www.facebook.com")
+ << QStringLiteral("www.twitter.com")
+ << QStringLiteral("graph.facebook.com")
+ << QStringLiteral("api.twitter.com");
+
+ foreach (QString host, hosts) {
+ QByteArray tag = host.toLocal8Bit();
+ tag.append("-none");
+ QTest::newRow(tag)
+ << false
+ << host
+ << QList<QByteArray>()
+ << QByteArray()
+ << QSslConfiguration::NextProtocolNegotiationNone;
+
+ tag = host.toLocal8Bit();
+ tag.append("-none-explicit");
+ QTest::newRow(tag)
+ << true
+ << host
+ << QList<QByteArray>()
+ << QByteArray()
+ << QSslConfiguration::NextProtocolNegotiationNone;
+
+ tag = host.toLocal8Bit();
+ tag.append("-http/1.1");
+ QTest::newRow(tag)
+ << true
+ << host
+ << (QList<QByteArray>() << QSslConfiguration::NextProtocolHttp1_1)
+ << QByteArray(QSslConfiguration::NextProtocolHttp1_1)
+ << QSslConfiguration::NextProtocolNegotiationNegotiated;
+
+ tag = host.toLocal8Bit();
+ tag.append("-spdy/3");
+ QTest::newRow(tag)
+ << true
+ << host
+ << (QList<QByteArray>() << QSslConfiguration::NextProtocolSpdy3_0)
+ << QByteArray(QSslConfiguration::NextProtocolSpdy3_0)
+ << QSslConfiguration::NextProtocolNegotiationNegotiated;
+
+ tag = host.toLocal8Bit();
+ tag.append("-spdy/3-and-http/1.1");
+ QTest::newRow(tag)
+ << true
+ << host
+ << (QList<QByteArray>() << QSslConfiguration::NextProtocolSpdy3_0 << QSslConfiguration::NextProtocolHttp1_1)
+ << QByteArray(QSslConfiguration::NextProtocolSpdy3_0)
+ << QSslConfiguration::NextProtocolNegotiationNegotiated;
+ }
+}
+
+void tst_QSslSocket::nextProtocolNegotiation()
+{
+ if (!QSslSocket::supportsSsl())
+ return;
+
+ QSslSocket socket;
+
+ QFETCH(bool, setConfiguration);
+
+ if (setConfiguration) {
+ QSslConfiguration conf = socket.sslConfiguration();
+ QFETCH(QList<QByteArray>, allowedProtocols);
+ conf.setAllowedNextProtocols(allowedProtocols);
+ socket.setSslConfiguration(conf);
+ }
+
+ QFETCH(QString, host);
+
+ socket.connectToHostEncrypted(host, 443);
+ socket.ignoreSslErrors();
+
+ QVERIFY(socket.waitForEncrypted(10000));
+
+ QFETCH(QByteArray, expectedProtocol);
+ QCOMPARE(socket.sslConfiguration().nextNegotiatedProtocol(), expectedProtocol);
+
+ QFETCH(QSslConfiguration::NextProtocolNegotiationStatus, expectedStatus);
+ QCOMPARE(socket.sslConfiguration().nextProtocolNegotiationStatus(), expectedStatus);
+
+ socket.disconnectFromHost();
+ QVERIFY(socket.waitForDisconnected());
+
+}
+
+#endif // QT_NO_SSL
+
+QTEST_MAIN(tst_QSslSocket)
+
+#include "main.moc"
diff --git a/tests/manual/qsslsocket/qsslsocket.pro b/tests/manual/qsslsocket/qsslsocket.pro
new file mode 100644
index 0000000000..c297d887ba
--- /dev/null
+++ b/tests/manual/qsslsocket/qsslsocket.pro
@@ -0,0 +1,6 @@
+CONFIG += testcase
+
+SOURCES += main.cpp
+QT = core network testlib
+
+TARGET = tst_qsslsocket
diff --git a/tests/manual/windowchildgeometry/controllerwidget.cpp b/tests/manual/windowchildgeometry/controllerwidget.cpp
new file mode 100644
index 0000000000..f1cdfbf855
--- /dev/null
+++ b/tests/manual/windowchildgeometry/controllerwidget.cpp
@@ -0,0 +1,536 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "controllerwidget.h"
+#include <controls.h>
+
+#if QT_VERSION >= 0x050000
+# include <QtWidgets>
+# include <QWindow>
+# include <QBackingStore>
+# include <QPaintDevice>
+# include <QPainter>
+#else
+# include <QtGui>
+#endif
+
+#include <QResizeEvent>
+
+CoordinateControl::CoordinateControl(const QString &sep) : m_x(new QSpinBox), m_y(new QSpinBox)
+{
+ m_x->setMinimum(-2000);
+ m_x->setMaximum(2000);
+ connect(m_x, SIGNAL(valueChanged(int)), this, SLOT(spinBoxChanged()));
+ m_y->setMinimum(-2000);
+ m_y->setMaximum(2000);
+ connect(m_y, SIGNAL(valueChanged(int)), this, SLOT(spinBoxChanged()));
+ QHBoxLayout *l = new QHBoxLayout(this);
+ l->setSpacing(2);
+ l->addWidget(m_x);
+ l->addWidget(new QLabel(sep));
+ l->addWidget(m_y);
+}
+
+void CoordinateControl::setCoordinates(int x, int y)
+{
+ m_x->blockSignals(true);
+ m_y->blockSignals(true);
+ m_x->setValue(x);
+ m_y->setValue(y);
+ m_x->blockSignals(false);
+ m_y->blockSignals(false);
+}
+
+QPair<int, int> CoordinateControl::coordinates() const
+{
+ return QPair<int, int>(m_x->value(), m_y->value());
+}
+
+void CoordinateControl::spinBoxChanged()
+{
+ const int x = m_x->value();
+ const int y = m_y->value();
+ emit pointValueChanged(QPoint(x, y));
+ emit sizeValueChanged(QSize(x, y));
+}
+
+RectControl::RectControl()
+ : m_point(new CoordinateControl(QLatin1String("+")))
+ , m_size(new CoordinateControl(QLatin1String("x")))
+{
+ QHBoxLayout *l = new QHBoxLayout(this);
+ l->setSpacing(0);
+ l->setMargin(ControlLayoutMargin);
+ connect(m_point, SIGNAL(pointValueChanged(QPoint)), this, SLOT(handleChanged()));
+ connect(m_point, SIGNAL(pointValueChanged(QPoint)), this, SIGNAL(positionChanged(QPoint)));
+ l->addWidget(m_point);
+ l->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
+ connect(m_size, SIGNAL(sizeValueChanged(QSize)), this, SLOT(handleChanged()));
+ connect(m_size, SIGNAL(sizeValueChanged(QSize)), this, SIGNAL(sizeChanged(QSize)));
+ l->addWidget(m_size);
+}
+
+void RectControl::setRectValue(const QRect &r)
+{
+ m_point->setPointValue(r.topLeft());
+ m_size->setSizeValue(r.size());
+}
+
+QRect RectControl::rectValue() const
+{
+ return QRect(m_point->pointValue(), m_size->sizeValue());
+}
+
+void RectControl::handleChanged()
+{
+ emit changed(rectValue());
+}
+
+BaseWindowControl::BaseWindowControl(QObject *w)
+ : m_layout(new QGridLayout(this))
+ , m_object(w)
+ , m_geometry(new RectControl)
+ , m_framePosition(new CoordinateControl(QLatin1String("x")))
+ , m_moveEventLabel(new QLabel(tr("Move events")))
+ , m_resizeEventLabel(new QLabel(tr("Resize events")))
+ , m_mouseEventLabel(new QLabel(tr("Mouse events")))
+ , m_moveCount(0)
+ , m_resizeCount(0)
+{
+ m_object->installEventFilter(this);
+ m_geometry->setTitle(tr("Geometry"));
+ int row = 0;
+ m_layout->addWidget(m_geometry, row, 0, 1, 2);
+ m_layout->setMargin(ControlLayoutMargin);
+ QGroupBox *frameGB = new QGroupBox(tr("Frame"));
+ QVBoxLayout *frameL = new QVBoxLayout(frameGB);
+ frameL->setSpacing(0);
+ frameL->setMargin(ControlLayoutMargin);
+ frameL->addWidget(m_framePosition);
+ m_layout->addWidget(frameGB, row, 2);
+
+ QGroupBox *eventGroupBox = new QGroupBox(tr("Events"));
+ QVBoxLayout *l = new QVBoxLayout(eventGroupBox);
+ l->setSpacing(0);
+ l->setMargin(ControlLayoutMargin);
+ l->addWidget(m_moveEventLabel);
+ l->addWidget(m_resizeEventLabel);
+ l->addWidget(m_mouseEventLabel);
+ m_layout->addWidget(eventGroupBox, ++row, 2);
+
+ connect(m_geometry, SIGNAL(positionChanged(QPoint)), this, SLOT(posChanged(QPoint)));
+ connect(m_geometry, SIGNAL(sizeChanged(QSize)), this, SLOT(sizeChanged(QSize)));
+ connect(m_framePosition, SIGNAL(pointValueChanged(QPoint)), this, SLOT(framePosChanged(QPoint)));
+}
+
+bool BaseWindowControl::eventFilter(QObject *, QEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::Resize: {
+ const QResizeEvent *re = static_cast<const QResizeEvent *>(e);
+ m_resizeEventLabel->setText(tr("Resize %1x%2 (#%3)")
+ .arg(re->size().width()).arg(re->size().height())
+ .arg(++m_resizeCount));
+ refresh();
+ }
+ break;
+ case QEvent::Move: {
+ const QMoveEvent *me = static_cast<const QMoveEvent *>(e);
+ m_moveEventLabel->setText(tr("Move %1,%2 (#%3)")
+ .arg(me->pos().x()).arg(me->pos().y())
+ .arg(++m_moveCount));
+ refresh();
+ }
+ break;
+ case QEvent::MouseMove: {
+ const QMouseEvent *me = static_cast<const QMouseEvent *>(e);
+ const QPoint pos = me->pos();
+ QPoint globalPos = objectMapToGlobal(m_object, pos);
+ m_mouseEventLabel->setText(tr("Mouse: %1,%2 Global: %3,%4 ").
+ arg(pos.x()).arg(pos.y()).arg(globalPos.x()).arg(globalPos.y()));
+ }
+ break;
+ case QEvent::WindowStateChange:
+ refresh();
+ default:
+ break;
+ }
+ return false;
+}
+
+void BaseWindowControl::posChanged(const QPoint &p)
+{
+ QRect geom = objectGeometry(m_object);
+ geom.moveTopLeft(p);
+ setObjectGeometry(m_object, geom);
+}
+
+void BaseWindowControl::sizeChanged(const QSize &s)
+{
+ QRect geom = objectGeometry(m_object);
+ geom.setSize(s);
+ setObjectGeometry(m_object, geom);
+}
+
+void BaseWindowControl::framePosChanged(const QPoint &p)
+{
+ setObjectFramePosition(m_object, p);
+}
+
+void BaseWindowControl::refresh()
+{
+ m_geometry->setRectValue(objectGeometry(m_object));
+ m_framePosition->setPointValue(objectFramePosition(m_object));
+}
+
+// A control for a QWidget
+class WidgetWindowControl : public BaseWindowControl
+{
+ Q_OBJECT
+public:
+ explicit WidgetWindowControl(QWidget *w);
+
+ virtual void refresh();
+
+private slots:
+ void statesChanged();
+
+private:
+ virtual QRect objectGeometry(const QObject *o) const
+ { return static_cast<const QWidget *>(o)->geometry(); }
+ virtual void setObjectGeometry(QObject *o, const QRect &r) const
+ { static_cast<QWidget *>(o)->setGeometry(r); }
+ virtual QPoint objectFramePosition(const QObject *o) const
+ { return static_cast<const QWidget *>(o)->pos(); }
+ virtual void setObjectFramePosition(QObject *o, const QPoint &p) const
+ { static_cast<QWidget *>(o)->move(p); }
+ virtual QPoint objectMapToGlobal(const QObject *o, const QPoint &p) const
+ { return static_cast<const QWidget *>(o)->mapToGlobal(p); }
+ virtual Qt::WindowFlags objectWindowFlags(const QObject *o) const
+ { return static_cast<const QWidget *>(o)->windowFlags(); }
+ virtual void setObjectWindowFlags(QObject *o, Qt::WindowFlags f);
+
+ WindowStatesControl *m_statesControl;
+};
+
+WidgetWindowControl::WidgetWindowControl(QWidget *w )
+ : BaseWindowControl(w)
+ , m_statesControl(new WindowStatesControl(WindowStatesControl::WantVisibleCheckBox | WindowStatesControl::WantActiveCheckBox))
+{
+ setTitle(w->windowTitle());
+ m_layout->addWidget(m_statesControl, 2, 0);
+ connect(m_statesControl, SIGNAL(changed()), this, SLOT(statesChanged()));
+}
+
+void WidgetWindowControl::setObjectWindowFlags(QObject *o, Qt::WindowFlags f)
+{
+ QWidget *w = static_cast<QWidget *>(o);
+ const bool visible = w->isVisible();
+ w->setWindowFlags(f); // hides.
+ if (visible)
+ w->show();
+}
+
+void WidgetWindowControl::refresh()
+{
+ const QWidget *w = static_cast<const QWidget *>(m_object);
+ m_statesControl->setVisibleValue(w->isVisible());
+ m_statesControl->setStates(w->windowState());
+ BaseWindowControl::refresh();
+}
+
+void WidgetWindowControl::statesChanged()
+{
+ QWidget *w = static_cast<QWidget *>(m_object);
+ w->setVisible(m_statesControl->visibleValue());
+ w->setWindowState(m_statesControl->states());
+}
+
+#if QT_VERSION >= 0x050000
+
+// Test window drawing diagonal lines
+class Window : public QWindow
+{
+public:
+ explicit Window(QWindow *parent = 0)
+ : QWindow(parent)
+ , m_backingStore(new QBackingStore(this))
+ , m_color(Qt::GlobalColor(qrand() % 18))
+ {
+ setObjectName(QStringLiteral("window"));
+ setTitle(tr("TestWindow"));
+ setFlags(flags() | Qt::MacUseNSWindow);
+ }
+
+protected:
+ void mouseMoveEvent(QMouseEvent * ev);
+ void mousePressEvent(QMouseEvent * ev);
+ void mouseReleaseEvent(QMouseEvent * e);
+ void exposeEvent(QExposeEvent *)
+ { render(); }
+
+private:
+ QBackingStore *m_backingStore;
+ Qt::GlobalColor m_color;
+ QPoint m_mouseDownPosition;
+ void render();
+};
+
+void Window::mouseMoveEvent(QMouseEvent * ev)
+{
+ if (m_mouseDownPosition.isNull())
+ return;
+
+ QPoint delta = ev->pos() - m_mouseDownPosition;
+ QPoint newPosition = position() + delta;
+ setPosition(newPosition);
+// qDebug() << "diff" << delta << newPosition;
+}
+
+void Window::mousePressEvent(QMouseEvent * ev)
+{
+ m_mouseDownPosition = ev->pos();
+}
+
+void Window::mouseReleaseEvent(QMouseEvent * e)
+{
+ m_mouseDownPosition = QPoint();
+}
+
+void Window::render()
+{
+ QRect rect(QPoint(), geometry().size());
+ m_backingStore->resize(rect.size());
+ m_backingStore->beginPaint(rect);
+ if (!rect.size().isEmpty()) {
+ QPaintDevice *device = m_backingStore->paintDevice();
+ QPainter p(device);
+ p.fillRect(rect, m_color);
+ p.drawLine(0, 0, rect.width(), rect.height());
+ p.drawLine(0, rect.height(), rect.width(), 0);
+ }
+ m_backingStore->endPaint();
+ m_backingStore->flush(rect);
+}
+
+// A control for a QWindow
+class WindowControl : public BaseWindowControl
+{
+ Q_OBJECT
+public:
+ explicit WindowControl(QWindow *w);
+
+ virtual void refresh();
+
+private slots:
+ void showWindow();
+ void hideWindow();
+ void raiseWindow();
+ void lowerWindow();
+ void toggleAttachWindow();
+ void addChildWindow();
+private:
+ virtual QRect objectGeometry(const QObject *o) const
+ { return static_cast<const QWindow *>(o)->geometry(); }
+ virtual void setObjectGeometry(QObject *o, const QRect &r) const
+ { static_cast<QWindow *>(o)->setGeometry(r); }
+ virtual QPoint objectFramePosition(const QObject *o) const
+ { return static_cast<const QWindow *>(o)->framePosition(); }
+ virtual void setObjectFramePosition(QObject *o, const QPoint &p) const
+ { static_cast<QWindow *>(o)->setFramePosition(p); }
+ virtual QPoint objectMapToGlobal(const QObject *o, const QPoint &p) const
+ { return static_cast<const QWindow *>(o)->mapToGlobal(p); }
+ virtual void setObjectWindowFlags(QObject *o, Qt::WindowFlags f)
+ { static_cast<QWindow *>(o)->setFlags(f); }
+
+ WindowStateControl *m_stateControl;
+ QWindow *m_window;
+ QWindow *m_detachedParent; // set when this window is detached. This is the window we should re-attach to.
+};
+
+WindowControl::WindowControl(QWindow *w )
+ : BaseWindowControl(w)
+ , m_stateControl(new WindowStateControl(WindowStateControl::WantVisibleCheckBox | WindowStateControl::WantMinimizeRadioButton))
+ , m_window(w)
+ , m_detachedParent(0)
+{
+ setTitle(w->title());
+
+ QPushButton *button = new QPushButton("Show Window");
+ connect(button, SIGNAL(clicked()), SLOT(showWindow()));
+ m_layout->addWidget(button, 1, 0);
+
+ button = new QPushButton("hide Window");
+ connect(button, SIGNAL(clicked()), SLOT(hideWindow()));
+ m_layout->addWidget(button, 1, 1);
+
+ button = new QPushButton("Rase Window");
+ connect(button, SIGNAL(clicked()), SLOT(raiseWindow()));
+ m_layout->addWidget(button, 2, 0);
+
+ button = new QPushButton("Lower Window");
+ connect(button, SIGNAL(clicked()), SLOT(lowerWindow()));
+ m_layout->addWidget(button, 2, 1);
+
+ button = new QPushButton("Toggle attach");
+ connect(button, SIGNAL(clicked()), SLOT(toggleAttachWindow()));
+ m_layout->addWidget(button, 3, 0);
+
+ button = new QPushButton("Add Child Window");
+ connect(button, SIGNAL(clicked()), SLOT(addChildWindow()));
+ m_layout->addWidget(button, 3, 1);
+}
+
+void WindowControl::refresh()
+{
+ const QWindow *w = static_cast<const QWindow *>(m_object);
+ BaseWindowControl::refresh();
+}
+
+void WindowControl::showWindow()
+{
+ m_window->show();
+}
+
+void WindowControl::hideWindow()
+{
+ m_window->hide();
+}
+
+void WindowControl::raiseWindow()
+{
+ m_window->raise();
+}
+
+void WindowControl::lowerWindow()
+{
+ m_window->lower();
+}
+
+void WindowControl::toggleAttachWindow()
+{
+ if (m_detachedParent) {
+ m_window->hide();
+ m_window->setParent(m_detachedParent);
+ m_window->show();
+ m_detachedParent = 0;
+ } else {
+ m_detachedParent = m_window->parent();
+ m_window->hide();
+ m_window->setParent(0);
+ m_window->show();
+ }
+}
+
+void WindowControl::addChildWindow()
+{
+ qDebug() << "WindowControl::addChildWindow";
+ Window *childWindow = new Window(m_window);
+
+ QRect childGeometry(50, 50, 40, 40);
+ childWindow->setGeometry(childGeometry);
+ WindowControl *control = new WindowControl(childWindow);
+ control->show();
+}
+
+#endif
+
+ControllerWidget::ControllerWidget(QWidget *parent)
+ : QMainWindow(parent)
+ , m_testWindow(new Window)
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("File"));
+ QAction *exitAction = fileMenu->addAction(tr("Exit"));
+ exitAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q));
+ connect(exitAction, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
+
+ QString title = QLatin1String("Child Window Geometry test, (Qt ");
+ title += QLatin1String(QT_VERSION_STR);
+ title += QLatin1String(", ");
+ title += qApp->platformName();
+ title += QLatin1Char(')');
+ setWindowTitle(title);
+
+ int x = 100;
+ int y = 100;
+ const QStringList args = QApplication::arguments();
+ const int offsetArgIndex = args.indexOf(QLatin1String("-offset"));
+ if (offsetArgIndex >=0 && offsetArgIndex < args.size() - 1) {
+ y += args.at(offsetArgIndex + 1).toInt();
+ } else {
+ if (QT_VERSION < 0x050000)
+ y += 400;
+ }
+
+ move(x, y);
+
+ x += 800;
+
+ x += 300;
+ m_testWindow->setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint
+ | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint
+ | Qt::WindowTitleHint | Qt::WindowFullscreenButtonHint);
+ m_testWindow->setFramePosition(QPoint(x, y));
+ m_testWindow->resize(200, 200);
+ m_testWindow->setTitle(tr("TestWindow"));
+
+ QWidget *central = new QWidget ;
+ QVBoxLayout *l = new QVBoxLayout(central);
+
+ const QString labelText = tr(
+ "<html><head/><body><p>This example lets you control the geometry"
+ " of QWindows and child QWindows");
+
+ l->addWidget(new QLabel(labelText));
+
+ WindowControl *windowControl = new WindowControl(m_testWindow.data());
+ l->addWidget(windowControl);
+
+ setCentralWidget(central);
+}
+
+ControllerWidget::~ControllerWidget()
+{
+
+
+}
+
+#include "controllerwidget.moc"
diff --git a/tests/manual/windowchildgeometry/controllerwidget.h b/tests/manual/windowchildgeometry/controllerwidget.h
new file mode 100644
index 0000000000..9774ca408c
--- /dev/null
+++ b/tests/manual/windowchildgeometry/controllerwidget.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CONTROLLERWIDGET_H
+#define CONTROLLERWIDGET_H
+
+#include <QMainWindow>
+#include <QGroupBox>
+#include <QScopedPointer>
+
+QT_BEGIN_NAMESPACE
+class QSpinBox;
+class QLabel;
+class QGridLayout;
+QT_END_NAMESPACE
+
+class TypeControl;
+class HintControl;
+
+// A control for editing points or sizes
+class CoordinateControl : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CoordinateControl(const QString &sep);
+
+ void setPointValue(const QPoint &p) { setCoordinates(p.x(), p.y()); }
+ QPoint pointValue() const { const QPair<int, int> t = coordinates(); return QPoint(t.first, t.second); }
+
+ void setSizeValue(const QSize &s) { setCoordinates(s.width(), s.height()); }
+ QSize sizeValue() const { const QPair<int, int> t = coordinates(); return QSize(t.first, t.second); }
+
+signals:
+ void pointValueChanged(const QPoint &p);
+ void sizeValueChanged(const QSize &s);
+
+private slots:
+ void spinBoxChanged();
+
+private:
+ void setCoordinates(int x, int y);
+ QPair<int, int> coordinates() const;
+
+ QSpinBox *m_x;
+ QSpinBox *m_y;
+};
+
+// A control for editing QRect
+class RectControl : public QGroupBox
+{
+ Q_OBJECT
+public:
+ RectControl();
+ void setRectValue(const QRect &r);
+ QRect rectValue() const;
+
+signals:
+ void changed(const QRect &r);
+ void sizeChanged(const QSize &s);
+ void positionChanged(const QPoint &s);
+
+private slots:
+ void handleChanged();
+
+private:
+ CoordinateControl *m_point;
+ CoordinateControl *m_size;
+};
+
+// Base class for controlling the position of a Window (QWindow or QWidget)
+class BaseWindowControl : public QGroupBox
+{
+ Q_OBJECT
+
+protected:
+ explicit BaseWindowControl(QObject *w);
+
+public:
+ virtual bool eventFilter(QObject *, QEvent *);
+ virtual void refresh();
+
+private slots:
+ void posChanged(const QPoint &);
+ void sizeChanged(const QSize &);
+ void framePosChanged(const QPoint &);
+
+protected:
+ QGridLayout *m_layout;
+ QObject *m_object;
+
+private:
+ virtual QRect objectGeometry(const QObject *o) const = 0;
+ virtual void setObjectGeometry(QObject *o, const QRect &) const = 0;
+
+ virtual QPoint objectFramePosition(const QObject *o) const = 0;
+ virtual void setObjectFramePosition(QObject *o, const QPoint &) const = 0;
+
+ virtual QPoint objectMapToGlobal(const QObject *o, const QPoint &) const = 0;
+
+ RectControl *m_geometry;
+ CoordinateControl *m_framePosition;
+ QLabel *m_moveEventLabel;
+ QLabel *m_resizeEventLabel;
+ QLabel *m_mouseEventLabel;
+ unsigned m_moveCount;
+ unsigned m_resizeCount;
+};
+
+class ControllerWidget : public QMainWindow
+{
+ Q_OBJECT
+public:
+ explicit ControllerWidget(QWidget *parent = 0);
+ ~ControllerWidget();
+private:
+ QScopedPointer<QWindow> m_testWindow;
+};
+
+#endif // CONTROLLERWIDGET_H
diff --git a/tests/manual/windowchildgeometry/main.cpp b/tests/manual/windowchildgeometry/main.cpp
new file mode 100644
index 0000000000..42266b777a
--- /dev/null
+++ b/tests/manual/windowchildgeometry/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include "controllerwidget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ ControllerWidget controller;
+ controller.show();
+ return a.exec();
+}
diff --git a/tests/manual/windowchildgeometry/windowchildgeometry.pro b/tests/manual/windowchildgeometry/windowchildgeometry.pro
new file mode 100644
index 0000000000..921acd8a4e
--- /dev/null
+++ b/tests/manual/windowchildgeometry/windowchildgeometry.pro
@@ -0,0 +1,10 @@
+QT += core gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+TARGET = windowchildgeometry
+TEMPLATE = app
+
+INCLUDEPATH += ../windowflags
+SOURCES += $$PWD/main.cpp controllerwidget.cpp ../windowflags/controls.cpp
+HEADERS += controllerwidget.h ../windowflags/controls.h
+
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/shared/fakedirmodel.h b/tests/shared/fakedirmodel.h
new file mode 100644
index 0000000000..ebe0e65112
--- /dev/null
+++ b/tests/shared/fakedirmodel.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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, Digia gives you certain additional
+** rights. These rights are described in the Digia 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.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef FAKEDIRMODEL_H
+#define FAKEDIRMODEL_H
+
+#include <QtGui/QStandardItemModel>
+#include <QtGui/QStandardItem>
+#include <QtGui/QIcon>
+#include <QtGui/QPixmap>
+#include <QtGui/QImage>
+#include <QtCore/QStringList>
+
+typedef QList<QStandardItem *> StandardItemList;
+
+static inline QIcon coloredIcon(Qt::GlobalColor color)
+{
+ QImage image(22, 22, QImage::Format_ARGB32);
+ image.fill(color);
+ return QPixmap::fromImage(image);
+}
+
+static void addFileEntry(const StandardItemList &directory, const QString &name, const QString &size)
+{
+ static const QIcon fileIcon = coloredIcon(Qt::blue);
+ directory.front()->appendRow(StandardItemList() << new QStandardItem(fileIcon, name) << new QStandardItem(size));
+}
+
+static StandardItemList createDirEntry(const QString &name)
+{
+ static const QIcon dirIcon = coloredIcon(Qt::red);
+ StandardItemList result;
+ result << new QStandardItem(dirIcon, name) << new QStandardItem;
+ return result;
+}
+
+static inline StandardItemList addDirEntry(const StandardItemList &directory, const QString &name)
+{
+ const StandardItemList entry = createDirEntry(name);
+ directory.front()->appendRow(entry);
+ return entry;
+}
+
+static QStandardItem *populateFakeDirModel(QStandardItemModel *model)
+{
+ enum Columns { NameColumn, SizeColumn, ColumnCount };
+
+ model->setColumnCount(ColumnCount);
+ model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("Name") << QStringLiteral("Size"));
+
+ const StandardItemList root = createDirEntry(QStringLiteral("/"));
+ model->appendRow(root);
+
+ const StandardItemList binDir = addDirEntry(root, QStringLiteral("bin"));
+ addFileEntry(binDir, QStringLiteral("ls"), QStringLiteral("100 KB"));
+ addFileEntry(binDir, QStringLiteral("bash"), QStringLiteral("200 KB"));
+
+ const StandardItemList devDir = addDirEntry(root, QStringLiteral("dev"));
+ addFileEntry(devDir, QStringLiteral("tty1"), QStringLiteral("0 B"));
+ addDirEntry(devDir, QStringLiteral("proc"));
+
+ const StandardItemList etcDir = addDirEntry(root, QStringLiteral("etc"));
+ addFileEntry(etcDir, QStringLiteral("foo1.config"), QStringLiteral("1 KB"));
+ addFileEntry(etcDir, QStringLiteral("foo2.conf"), QStringLiteral("654 B"));
+
+ const StandardItemList homeDir = addDirEntry(root, QStringLiteral("home"));
+ addFileEntry(homeDir, QStringLiteral("file1"), QStringLiteral("1 KB"));
+
+ const StandardItemList documentsDir = addDirEntry(homeDir, QStringLiteral("Documents"));
+ addFileEntry(documentsDir, QStringLiteral("txt1.odt"), QStringLiteral("2 MB"));
+ addFileEntry(documentsDir, QStringLiteral("sheet1.xls"), QStringLiteral("32 KB"));
+ addFileEntry(documentsDir, QStringLiteral("foo.doc"), QStringLiteral("214 KB"));
+
+ const StandardItemList downloadsDir = addDirEntry(homeDir, QStringLiteral("Downloads"));
+ addFileEntry(downloadsDir, QStringLiteral("package1.zip"), QStringLiteral("34 MB"));
+ addFileEntry(downloadsDir, QStringLiteral("package2.zip"), QStringLiteral("623 KB"));
+
+ const StandardItemList picturesDir = addDirEntry(homeDir, QStringLiteral("Pictures"));
+ addFileEntry(picturesDir, QStringLiteral("img0001.jpg"), QStringLiteral("4 MB"));
+ addFileEntry(picturesDir, QStringLiteral("img0002.png"), QStringLiteral("10 MB"));
+
+ // qcolumnview::moveCursor() requires an empty directory followed by another one.
+ addDirEntry(root, QStringLiteral("lost+found"));
+
+ const StandardItemList tmpDir = addDirEntry(root, QStringLiteral("tmp"));
+ addFileEntry(tmpDir, "asdujhsdjys", "435 B");
+ addFileEntry(tmpDir, "krtbldfhd", "5557 B");
+
+ return homeDir.front();
+}
+
+#endif // FAKEDIRMODEL_H
diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h
index 7aa72cc28e..2082128a09 100644
--- a/tests/shared/filesystem.h
+++ b/tests/shared/filesystem.h
@@ -92,7 +92,7 @@ public:
return file.isNull() ? qint64(-1) : file->write(relativeFileName.toUtf8());
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
static void createNtfsJunction(QString target, QString linkName)
{
typedef struct {
@@ -133,7 +133,7 @@ public:
memset( reparseInfo, 0, sizeof( *reparseInfo ));
reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
- reparseInfo->ReparseTargetLength = DWORD(target.size() * sizeof(wchar_t));
+ reparseInfo->ReparseTargetLength = WORD(target.size()) * WORD(sizeof(wchar_t));
reparseInfo->ReparseTargetMaximumLength = reparseInfo->ReparseTargetLength + sizeof(wchar_t);
target.toWCharArray(reparseInfo->ReparseTarget);
reparseInfo->ReparseDataLength = reparseInfo->ReparseTargetLength + 12;
diff --git a/tests/tests.pro b/tests/tests.pro
index 0f50930774..79bee02b65 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -4,4 +4,4 @@ SUBDIRS = auto
# benchmarks in debug mode is rarely sensible
# benchmarks are not sensible for code coverage (here with tool testcocoon)
-!testcocoon:contains(QT_CONFIG,release):SUBDIRS += benchmarks
+!ios:!testcocoon:contains(QT_CONFIG,release):SUBDIRS += benchmarks
diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw
index 1994c9a52b..db8db54888 100644
--- a/tools/configure/Makefile.mingw
+++ b/tools/configure/Makefile.mingw
@@ -60,6 +60,7 @@ OBJECTS = \
qmap.o \
qregexp.o \
qstring.o \
+ qstring_compat.o \
qstringlist.o \
qvsnprintf.o \
qvariant.o \
@@ -117,6 +118,10 @@ configureapp.o: $(CONFSRC)/configureapp.h $(CONFSRC)/environment.h $(CONFSRC)/to
environment.o: $(CONFSRC)/environment.h
tools.o: $(CONFSRC)/tools.h
+# Make sure qstring_compat.obj isn't compiled with PCH enabled
+qstring_compat.o: $(CORESRC)/tools/qstring_compat.cpp
+ $(CXX) -c $(CXXFLAGS_BARE) -o $@ $<
+
clean:
-rm -f *.o
-rm -rf *.gch
diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32
index 6b922e6693..98a2181e39 100644
--- a/tools/configure/Makefile.win32
+++ b/tools/configure/Makefile.win32
@@ -9,7 +9,7 @@ CXXFLAGS_BARE = -nologo -Zm200 -Zc:wchar_t -MT -W3 -GR -EHsc -w34100 -w34189 $(E
CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE)
LINK = link
LFLAGS = /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:"configure.intermediate.manifest"
-LIBS = ole32.lib advapi32.lib
+LIBS = ole32.lib advapi32.lib shell32.lib
TARGET = ..\..\configure.exe
@@ -58,6 +58,7 @@ OBJECTS = \
qmap.obj \
qregexp.obj \
qstring.obj \
+ qstring_compat.obj \
qstringlist.obj \
qvsnprintf.obj \
qvariant.obj \
@@ -162,3 +163,7 @@ quuid.obj: $(CORESRC)\plugin\quuid.cpp $(PCH)
$(CXX) -c $(CXXFLAGS) $<
{$(CORESRC)\xml}.cpp{}.obj::
$(CXX) -c $(CXXFLAGS) $<
+
+# Make sure qstring_compat.obj isn't compiled with PCH enabled
+qstring_compat.obj: $(CORESRC)\tools\qstring_compat.cpp
+ $(CXX) -c $(CXXFLAGS_BARE) $(CORESRC)\tools\qstring_compat.cpp
diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro
index 2163e37a58..b73a93431d 100644
--- a/tools/configure/configure.pro
+++ b/tools/configure/configure.pro
@@ -7,7 +7,7 @@ DEFINES = UNICODE QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMP
DEFINES += QT_BOOTSTRAPPED QT_BUILD_CONFIGURE
win32 : LIBS += -lole32 -ladvapi32
-win32-g++* : LIBS += -luuid
+mingw : LIBS += -luuid
win32-msvc* {
QMAKE_CFLAGS_RELEASE -= -MD
@@ -119,6 +119,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qregexp.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qstring.cpp \
+ $$QT_SOURCE_TREE/src/corelib/tools/qstring_compat.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qstringlist.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qvsnprintf.cpp \
$$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index a3e896422a..ed854a343b 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -182,6 +182,7 @@ Configure::Configure(int& argc, char** argv)
dictionary[ "QML_DEBUG" ] = "yes";
dictionary[ "PLUGIN_MANIFESTS" ] = "no";
dictionary[ "DIRECTWRITE" ] = "no";
+ dictionary[ "DIRECT2D" ] = "no";
dictionary[ "NIS" ] = "no";
dictionary[ "NEON" ] = "auto";
dictionary[ "LARGE_FILE" ] = "yes";
@@ -194,7 +195,9 @@ Configure::Configure(int& argc, char** argv)
dictionary[ "QT_CUPS" ] = "auto";
dictionary[ "CFG_GCC_SYSROOT" ] = "yes";
dictionary[ "SLOG2" ] = "no";
+ dictionary[ "QNX_IMF" ] = "no";
dictionary[ "PPS" ] = "no";
+ dictionary[ "LGMON" ] = "no";
dictionary[ "SYSTEM_PROXIES" ] = "no";
dictionary[ "WERROR" ] = "auto";
dictionary[ "QREAL" ] = "double";
@@ -256,6 +259,7 @@ Configure::Configure(int& argc, char** argv)
dictionary[ "ICU" ] = "auto";
dictionary[ "ANGLE" ] = "auto";
+ dictionary[ "DYNAMICGL" ] = "auto";
dictionary[ "GIF" ] = "auto";
dictionary[ "JPEG" ] = "auto";
@@ -679,6 +683,8 @@ void Configure::parseCmdLine()
dictionary[ "OPENGL_ES_2" ] = "yes";
} else if ( configCmdLine.at(i) == "desktop" ) {
// OPENGL=yes suffices
+ } else if ( configCmdLine.at(i) == "dynamic" ) {
+ dictionary[ "DYNAMICGL" ] = "yes";
} else {
cout << "Argument passed to -opengl option is not valid." << endl;
dictionary[ "DONE" ] = "error";
@@ -880,10 +886,18 @@ void Configure::parseCmdLine()
dictionary[ "SLOG2" ] = "no";
} else if (configCmdLine.at(i) == "-slog2") {
dictionary[ "SLOG2" ] = "yes";
+ } else if (configCmdLine.at(i) == "-no-imf") {
+ dictionary[ "QNX_IMF" ] = "no";
+ } else if (configCmdLine.at(i) == "-imf") {
+ dictionary[ "QNX_IMF" ] = "yes";
} else if (configCmdLine.at(i) == "-no-pps") {
dictionary[ "PPS" ] = "no";
} else if (configCmdLine.at(i) == "-pps") {
dictionary[ "PPS" ] = "yes";
+ } else if (configCmdLine.at(i) == "-no-lgmon") {
+ dictionary[ "LGMON" ] = "no";
+ } else if (configCmdLine.at(i) == "-lgmon") {
+ dictionary[ "LGMON" ] = "yes";
} else if (configCmdLine.at(i) == "-no-system-proxies") {
dictionary[ "SYSTEM_PROXIES" ] = "no";
} else if (configCmdLine.at(i) == "-system-proxies") {
@@ -1213,6 +1227,12 @@ void Configure::parseCmdLine()
dictionary["DIRECTWRITE"] = "no";
}
+ else if (configCmdLine.at(i) == "-direct2d") {
+ dictionary["DIRECT2D"] = "yes";
+ } else if (configCmdLine.at(i) == "-no-direct2d") {
+ dictionary["DIRECT2D"] = "no";
+ }
+
else if (configCmdLine.at(i) == "-nis") {
dictionary["NIS"] = "yes";
} else if (configCmdLine.at(i) == "-no-nis") {
@@ -1595,18 +1615,18 @@ void Configure::applySpecSpecifics()
dictionary[ "LIBJPEG" ] = "qt";
dictionary[ "LIBPNG" ] = "qt";
dictionary[ "FREETYPE" ] = "yes";
- dictionary[ "ACCESSIBILITY" ] = "no";
- dictionary[ "OPENGL" ] = "no";
- dictionary[ "OPENGL_ES_2" ] = "no";
+ dictionary[ "OPENGL" ] = "yes";
+ dictionary[ "OPENGL_ES_2" ] = "yes";
dictionary[ "OPENVG" ] = "no";
- dictionary[ "OPENSSL" ] = "auto";
+ dictionary[ "OPENSSL" ] = "no";
dictionary[ "DBUS" ] = "no";
dictionary[ "ZLIB" ] = "qt";
dictionary[ "PCRE" ] = "qt";
dictionary[ "ICU" ] = "qt";
dictionary[ "CE_CRT" ] = "yes";
dictionary[ "LARGE_FILE" ] = "no";
- dictionary[ "ANGLE" ] = "no";
+ dictionary[ "ANGLE" ] = "d3d11";
+ dictionary[ "DYNAMICGL" ] = "no";
if (dictionary.value("XQMAKESPEC").startsWith("winphone"))
dictionary[ "SQL_SQLITE" ] = "no";
} else if (dictionary.value("XQMAKESPEC").startsWith("wince")) {
@@ -1629,6 +1649,7 @@ void Configure::applySpecSpecifics()
dictionary[ "CE_CRT" ] = "yes";
dictionary[ "LARGE_FILE" ] = "no";
dictionary[ "ANGLE" ] = "no";
+ dictionary[ "DYNAMICGL" ] = "no";
// We only apply MMX/IWMMXT for mkspecs we know they work
if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) {
dictionary[ "MMX" ] = "yes";
@@ -1653,9 +1674,12 @@ void Configure::applySpecSpecifics()
} else if ((platform() == QNX) || (platform() == BLACKBERRY)) {
dictionary["STACK_PROTECTOR_STRONG"] = "auto";
dictionary["SLOG2"] = "auto";
+ dictionary["QNX_IMF"] = "auto";
dictionary["PPS"] = "auto";
+ dictionary["LGMON"] = "auto";
dictionary["QT_XKBCOMMON"] = "no";
dictionary[ "ANGLE" ] = "no";
+ dictionary[ "DYNAMICGL" ] = "no";
dictionary[ "FONT_CONFIG" ] = "auto";
} else if (platform() == ANDROID) {
dictionary[ "REDUCE_EXPORTS" ] = "yes";
@@ -1663,6 +1687,7 @@ void Configure::applySpecSpecifics()
dictionary[ "BUILDALL" ] = "no";
dictionary[ "LARGE_FILE" ] = "no";
dictionary[ "ANGLE" ] = "no";
+ dictionary[ "DYNAMICGL" ] = "no";
dictionary[ "REDUCE_RELOCATIONS" ] = "yes";
dictionary[ "QT_GETIFADDRS" ] = "no";
dictionary[ "QT_XKBCOMMON" ] = "no";
@@ -1774,9 +1799,10 @@ bool Configure::displayHelp()
desc("OPENGL", "no","-no-opengl", "Do not support OpenGL.");
desc("OPENGL", "no","-opengl <api>", "Enable OpenGL support with specified API version.\n"
"Available values for <api>:");
- desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
+ desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
+ desc("", "no", "", " dynamic - Enable support for dynamically loaded OpenGL (either desktop or ES)", ' ');
desc("OPENGL_ES_CM", "no", "", " es1 - Enable support for OpenGL ES Common Profile", ' ');
- desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
+ desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
desc("OPENVG", "no","-no-openvg", "Disables OpenVG functionality.");
desc("OPENVG", "yes","-openvg", "Enables OpenVG functionality.\n");
@@ -1865,14 +1891,17 @@ bool Configure::displayHelp()
"by setting QT_HARFBUZZ environment variable to \"old\".");
desc("HARFBUZZ", "system","-system-harfbuzz", "(experimental) Use HarfBuzz-NG from the operating system\n"
"to do text shaping. It can still be disabled\n"
- "by setting QT_HARFBUZZ environment variable to \"old\".");
+ "by setting QT_HARFBUZZ environment variable to \"old\".\n");
if ((platform() == QNX) || (platform() == BLACKBERRY)) {
desc("SLOG2", "yes", "-slog2", "Compile with slog2 support.");
desc("SLOG2", "no", "-no-slog2", "Do not compile with slog2 support.");
-
+ desc("QNX_IMF", "yes", "-imf", "Compile with imf support.");
+ desc("QNX_IMF", "no", "-no-imf", "Do not compile with imf support.");
desc("PPS", "yes", "-pps", "Compile with PPS support.");
desc("PPS", "no", "-no-pps", "Do not compile with PPS support.");
+ desc("LGMON", "yes", "-lgmon", "Compile with lgmon support.");
+ desc("LGMON", "no", "-no-lgmon", "Do not compile with lgmon support.\n");
}
desc("ANGLE", "yes", "-angle", "Use the ANGLE implementation of OpenGL ES 2.0.");
@@ -1933,6 +1962,11 @@ bool Configure::displayHelp()
desc("DIRECTWRITE", "no", "-no-directwrite", "Do not build support for DirectWrite font rendering.");
desc("DIRECTWRITE", "yes", "-directwrite", "Build support for DirectWrite font rendering (experimental, requires DirectWrite availability on target systems, e.g. Windows Vista with Platform Update, Windows 7, etc.)\n");
+ desc("DIRECT2D", "no", "-no-direct2d", "Do not build the Direct2D platform plugin.");
+ desc("DIRECT2D", "yes", "-direct2d", "Build the Direct2D platform plugin (experimental,\n"
+ "requires Direct2D availability on target systems,\n"
+ "e.g. Windows 7 with Platform Update, Windows 8, etc.)\n");
+
desc( "-no-style-<style>", "Disable <style> entirely.");
desc( "-qt-style-<style>", "Enable <style> in the Qt Library.\nAvailable styles: ");
@@ -2200,6 +2234,8 @@ bool Configure::checkAvailability(const QString &part)
available = findFile("mfapi.h") && findFile("mf.lib");
} else if (part == "DIRECTWRITE") {
available = findFile("dwrite.h") && findFile("d2d1.h") && findFile("dwrite.lib");
+ } else if (part == "DIRECT2D") {
+ available = tryCompileProject("qpa/direct2d");
} else if (part == "ICONV") {
available = tryCompileProject("unix/iconv") || tryCompileProject("unix/gnu-libiconv");
} else if (part == "INOTIFY") {
@@ -2212,8 +2248,13 @@ bool Configure::checkAvailability(const QString &part)
available = (platform() == QNX || platform() == BLACKBERRY) && compilerSupportsFlag("qcc -fstack-protector-strong");
} else if (part == "SLOG2") {
available = tryCompileProject("unix/slog2");
+ } else if (part == "QNX_IMF") {
+ available = tryCompileProject("unix/qqnx_imf");
} else if (part == "PPS") {
available = (platform() == QNX || platform() == BLACKBERRY) && tryCompileProject("unix/pps");
+ } else if (part == "LGMON") {
+ available = (platform() == QNX || platform() == BLACKBERRY)
+ && tryCompileProject("unix/lgmon");
} else if (part == "NEON") {
available = (dictionary["QT_ARCH"] == "arm") && tryCompileProject("unix/neon");
} else if (part == "FONT_CONFIG") {
@@ -2266,6 +2307,10 @@ void Configure::autoDetection()
}
}
+ // Dynamic GL. This must be explicitly requested, no autodetection.
+ if (dictionary["DYNAMICGL"] == "auto")
+ dictionary["DYNAMICGL"] = "no";
+
// Image format detection
if (dictionary["GIF"] == "auto")
dictionary["GIF"] = defaultTo("GIF");
@@ -2359,10 +2404,18 @@ void Configure::autoDetection()
dictionary["SLOG2"] = checkAvailability("SLOG2") ? "yes" : "no";
}
+ if ((platform() == QNX || platform() == BLACKBERRY) && dictionary["QNX_IMF"] == "auto") {
+ dictionary["QNX_IMF"] = checkAvailability("QNX_IMF") ? "yes" : "no";
+ }
+
if (dictionary["PPS"] == "auto") {
dictionary["PPS"] = checkAvailability("PPS") ? "yes" : "no";
}
+ if ((platform() == QNX || platform() == BLACKBERRY) && dictionary["LGMON"] == "auto") {
+ dictionary["LGMON"] = checkAvailability("LGMON") ? "yes" : "no";
+ }
+
if (dictionary["QT_EVENTFD"] == "auto")
dictionary["QT_EVENTFD"] = checkAvailability("QT_EVENTFD") ? "yes" : "no";
@@ -2429,6 +2482,13 @@ bool Configure::verifyConfiguration()
prompt = true;
}
+ if (dictionary["DIRECT2D"] == "yes" && !checkAvailability("DIRECT2D")) {
+ cout << "WARNING: To be able to build the Direct2D platform plugin you will" << endl
+ << "need the Microsoft DirectWrite and Microsoft Direct2D development" << endl
+ << "files such as headers and libraries." << endl;
+ prompt = true;
+ }
+
// -angle given on command line, but Direct X cannot be found.
if (dictionary["ANGLE"] != "no") {
QString errorMessage;
@@ -2455,6 +2515,13 @@ bool Configure::verifyConfiguration()
}
}
+ if (dictionary["DYNAMICGL"] == "yes") {
+ if (dictionary["OPENGL_ES_2"] == "yes" || dictionary["ANGLE"] != "no") {
+ cout << "ERROR: Dynamic OpenGL cannot be used together with native Angle (GLES2) builds." << endl;
+ dictionary[ "DONE" ] = "error";
+ }
+ }
+
if (prompt)
promptKeyPress();
@@ -2503,12 +2570,14 @@ void Configure::generateOutputVars()
else
qtConfig += "shared";
+ if (dictionary[ "GUI" ] == "no") {
+ qtConfig += "no-gui";
+ dictionary [ "WIDGETS" ] = "no";
+ }
+
if (dictionary[ "WIDGETS" ] == "no")
qtConfig += "no-widgets";
- if (dictionary[ "GUI" ] == "no")
- qtConfig += "no-gui";
-
// Compression --------------------------------------------------
if (dictionary[ "ZLIB" ] == "qt")
qtConfig += "zlib";
@@ -2530,6 +2599,10 @@ void Configure::generateOutputVars()
qmakeConfig += "angle_d3d11";
}
+ // Dynamic OpenGL loading ---------------------------------------
+ if (dictionary[ "DYNAMICGL" ] != "no")
+ qtConfig += "dynamicgl";
+
// Image formates -----------------------------------------------
if (dictionary[ "GIF" ] == "no")
qtConfig += "no-gif";
@@ -2718,6 +2791,9 @@ void Configure::generateOutputVars()
if (dictionary["DIRECTWRITE"] == "yes")
qtConfig += "directwrite";
+ if (dictionary["DIRECT2D"] == "yes")
+ qtConfig += "direct2d";
+
if (dictionary[ "NATIVE_GESTURES" ] == "yes")
qtConfig += "native-gestures";
@@ -2988,6 +3064,10 @@ void Configure::detectArch()
.arg(QDir::toNativeSeparators(buildPath + "/bin/qmake.exe"),
QDir::toNativeSeparators(qmakespec),
QDir::toNativeSeparators(sourcePath + "/config.tests/arch/arch.pro"));
+
+ if (qmakespec.startsWith("winrt") || qmakespec.startsWith("winphone"))
+ command.append(" QMAKE_LFLAGS+=/ENTRY:main");
+
int returnValue = 0;
Environment::execute(command, &returnValue);
if (returnValue != 0) {
@@ -3088,6 +3168,13 @@ bool Configure::tryCompileProject(const QString &projectPath, const QString &ext
.arg(QDir::toNativeSeparators(buildPath + "/bin/qmake.exe"),
QDir::toNativeSeparators(sourcePath + "/config.tests/" + projectPath),
extraOptions);
+
+ if (dictionary.contains("XQMAKESPEC")) {
+ const QString qmakespec = dictionary["XQMAKESPEC"];
+ if (qmakespec.startsWith("winrt") || qmakespec.startsWith("winphone"))
+ command.append(" QMAKE_LFLAGS+=/ENTRY:main");
+ }
+
int code = 0;
QString output = Environment::execute(command, &code);
//cout << output << endl;
@@ -3189,9 +3276,15 @@ void Configure::generateQConfigPri()
if (dictionary[ "SLOG2" ] == "yes")
configStream << " slog2";
+ if (dictionary[ "QNX_IMF" ] == "yes")
+ configStream << " qqnx_imf";
+
if (dictionary[ "PPS" ] == "yes")
configStream << " qqnx_pps";
+ if (dictionary[ "LGMON" ] == "yes")
+ configStream << " lgmon";
+
if (dictionary["DIRECTWRITE"] == "yes")
configStream << " directwrite";
@@ -3241,8 +3334,10 @@ void Configure::generateQConfigPri()
if (!dictionary["QT_NAMESPACE"].isEmpty())
configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
- if (dictionary[ "SHARED" ] == "no")
- configStream << "QT_DEFAULT_QPA_PLUGIN = q" << qpaPlatformName() << endl;
+ if (dictionary[ "SHARED" ] == "no") {
+ configStream << "QT_DEFAULT_QPA_PLUGIN = q" << qpaPlatformName() << endl
+ << "QT_DEFAULT_PRINTSUPPORTPLUGIN = " << qpaPrintSupportPluginName() << endl;
+ }
if (!configStream.flush())
dictionary[ "DONE" ] = "error";
@@ -3339,8 +3434,6 @@ void Configure::generateConfigfiles()
tmpStream << "#define QT_COMPILER_SUPPORTS_AVX2" << endl;
if (dictionary[ "IWMMXT" ] == "yes")
tmpStream << "#define QT_COMPILER_SUPPORTS_IWMMXT" << endl;
- if (dictionary[ "NEON" ] == "yes")
- tmpStream << "#define QT_COMPILER_SUPPORTS_NEON" << endl;
if (dictionary["QREAL"] != "double")
tmpStream << "#define QT_COORD_TYPE " << dictionary["QREAL"] << endl;
@@ -3390,6 +3483,7 @@ void Configure::generateConfigfiles()
if (dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1";
if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2";
+ if (dictionary["DYNAMICGL"] == "yes") qconfigList += "QT_OPENGL_DYNAMIC";
if (dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL";
if (dictionary["SQL_ODBC"] == "yes") qconfigList += "QT_SQL_ODBC";
if (dictionary["SQL_OCI"] == "yes") qconfigList += "QT_SQL_OCI";
@@ -3426,7 +3520,8 @@ void Configure::generateConfigfiles()
for (int i = 0; i < qconfigList.count(); ++i)
tmpStream << addDefine(qconfigList.at(i));
- tmpStream<<"#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\""<<endl;
+ tmpStream << "#define QT_QPA_DEFAULT_PLATFORM_NAME \"" << qpaPlatformName() << "\"" << endl
+ << "#define QT_QPA_DEFAULT_PRINTSUPPORTPLUGIN_NAME \"" << qpaPrintSupportPluginName() << "\"" << endl;
if (!tmpStream.flush())
dictionary[ "DONE" ] = "error";
@@ -3548,6 +3643,11 @@ void Configure::displayConfig()
sout << "Use system proxies.........." << dictionary[ "SYSTEM_PROXIES" ] << endl;
sout << endl;
+ sout << "QPA Backends:" << endl;
+ sout << " GDI....................." << "yes" << endl;
+ sout << " Direct2D................" << dictionary[ "DIRECT2D" ] << endl;
+ sout << endl;
+
sout << "Third Party Libraries:" << endl;
sout << " ZLIB support............" << dictionary[ "ZLIB" ] << endl;
sout << " GIF support............." << dictionary[ "GIF" ] << endl;
@@ -3560,9 +3660,12 @@ void Configure::displayConfig()
sout << " ICU support............." << dictionary[ "ICU" ] << endl;
if ((platform() == QNX) || (platform() == BLACKBERRY)) {
sout << " SLOG2 support..........." << dictionary[ "SLOG2" ] << endl;
+ sout << " IMF support............." << dictionary[ "QNX_IMF" ] << endl;
sout << " PPS support............." << dictionary[ "PPS" ] << endl;
+ sout << " LGMON support..........." << dictionary[ "LGMON" ] << endl;
}
sout << " ANGLE..................." << dictionary[ "ANGLE" ] << endl;
+ sout << " Dynamic OpenGL.........." << dictionary[ "DYNAMICGL" ] << endl;
sout << endl;
sout << "Styles:" << endl;
@@ -4351,6 +4454,11 @@ QString Configure::qpaPlatformName() const
}
}
+QString Configure::qpaPrintSupportPluginName() const
+{
+ return platform() == WINDOWS ? QStringLiteral("windowsprintersupport") : QString();
+}
+
int Configure::platform() const
{
const QString qMakeSpec = dictionary.value("QMAKESPEC");
diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h
index bf0f61639f..36668f18ba 100644
--- a/tools/configure/configureapp.h
+++ b/tools/configure/configureapp.h
@@ -88,9 +88,9 @@ public:
QString addDefine(QString def);
enum ProjectType {
- App,
- Lib,
- Subdirs
+ App,
+ Lib,
+ Subdirs
};
ProjectType projectType( const QString& proFileName );
@@ -100,6 +100,7 @@ public:
int platform() const;
QString platformName() const;
QString qpaPlatformName() const;
+ QString qpaPrintSupportPluginName() const;
private:
bool checkAngleAvailability(QString *errorMessage = 0) const;
@@ -182,10 +183,10 @@ class MakeItem
{
public:
MakeItem( const QString &d, const QString &p, const QString &t, Configure::ProjectType qt )
- : directory( d ),
- proFile( p ),
- target( t ),
- qmakeTemplate( qt )
+ : directory( d ),
+ proFile( p ),
+ target( t ),
+ qmakeTemplate( qt )
{ }
QString directory;
diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp
index 81769aa043..d0b0065d8a 100644
--- a/tools/configure/environment.cpp
+++ b/tools/configure/environment.cpp
@@ -467,8 +467,8 @@ bool Environment::cpdir(const QString &srcDir, const QString &destDir)
qDebug() << "Attempt to cpdir " << cleanSrcName << "->" << cleanDstName;
#endif
if(!QFile::exists(cleanDstName) && !QDir().mkpath(cleanDstName)) {
- qDebug() << "cpdir: Failure to create " << cleanDstName;
- return false;
+ qDebug() << "cpdir: Failure to create " << cleanDstName;
+ return false;
}
bool result = true;
@@ -476,23 +476,23 @@ bool Environment::cpdir(const QString &srcDir, const QString &destDir)
QFileInfoList allEntries = dir.entryInfoList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
for (int i = 0; result && (i < allEntries.count()); ++i) {
QFileInfo entry = allEntries.at(i);
- bool intermediate = true;
+ bool intermediate = true;
if (entry.isDir()) {
intermediate = cpdir(QString("%1/%2").arg(cleanSrcName).arg(entry.fileName()),
QString("%1/%2").arg(cleanDstName).arg(entry.fileName()));
} else {
QString destFile = QString("%1/%2").arg(cleanDstName).arg(entry.fileName());
#ifdef CONFIGURE_DEBUG_CP_DIR
- qDebug() << "About to cp (file)" << entry.absoluteFilePath() << "->" << destFile;
+ qDebug() << "About to cp (file)" << entry.absoluteFilePath() << "->" << destFile;
#endif
- QFile::remove(destFile);
+ QFile::remove(destFile);
intermediate = QFile::copy(entry.absoluteFilePath(), destFile);
SetFileAttributes((wchar_t*)destFile.utf16(), FILE_ATTRIBUTE_NORMAL);
}
- if(!intermediate) {
- qDebug() << "cpdir: Failure for " << entry.fileName() << entry.isDir();
- result = false;
- }
+ if (!intermediate) {
+ qDebug() << "cpdir: Failure for " << entry.fileName() << entry.isDir();
+ result = false;
+ }
}
return result;
}
diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp
index 1e6aa3f298..ebbb4b1e54 100644
--- a/tools/configure/main.cpp
+++ b/tools/configure/main.cpp
@@ -59,7 +59,7 @@ int runConfigure( int argc, char** argv )
if (!app.isOk())
return 3;
if( app.displayHelp() )
- return 1;
+ return 1;
// Read license now, and exit if it doesn't pass.
// This lets the user see the command-line options of configure
@@ -103,19 +103,19 @@ int runConfigure( int argc, char** argv )
app.generateOutputVars();
if( !app.isDone() )
- app.generateCachefile();
+ app.generateCachefile();
if( !app.isDone() )
- app.generateConfigfiles();
+ app.generateConfigfiles();
if (!app.isDone())
app.generateQConfigPri();
if (!app.isDone())
app.displayConfig();
if( !app.isDone() )
- app.generateMakefiles();
+ app.generateMakefiles();
if( !app.isDone() )
- app.showSummary();
+ app.showSummary();
if( !app.isOk() )
- return 2;
+ return 2;
return 0;
}
diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp
index ed0f3efb1b..e9174bf102 100644
--- a/tools/configure/tools.cpp
+++ b/tools/configure/tools.cpp
@@ -157,13 +157,13 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString
case PL('X','C'):
case PL('X','U'):
case PL('X','W'):
- case PL('X','M'): // old license key
+ case PL('X','M'): // old license key
dictionary["LICENSE_EXTENSION"] = "-ALLOS";
break;
case PL('6', 'M'):
case PL('8', 'M'):
- case PL('K', 'M'): // old license key
+ case PL('K', 'M'): // old license key
case PL('N', '7'):
case PL('N', '9'):
case PL('N', 'X'):
diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py
index be2a9c5ace..7975a82d1c 100755
--- a/util/local_database/cldr2qlocalexml.py
+++ b/util/local_database/cldr2qlocalexml.py
@@ -46,6 +46,7 @@ import enumdata
import xpathlite
from xpathlite import DraftResolution
from dateconverter import convert_date
+from xml.sax.saxutils import escape, unescape
import re
findAlias = xpathlite.findAlias
@@ -94,11 +95,20 @@ def parse_list_pattern_part_format(pattern):
def ordStr(c):
if len(c) == 1:
return str(ord(c))
+ raise xpathlite.Error("Unable to handle value \"%s\"" % addEscapes(c))
return "##########"
# the following functions are supposed to fix the problem with QLocale
# returning a character instead of strings for QLocale::exponential()
# and others. So we fallback to default values in these cases.
+def fixOrdStrMinus(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return str(ord('-'))
+def fixOrdStrPlus(c):
+ if len(c) == 1:
+ return str(ord(c))
+ return str(ord('+'))
def fixOrdStrExp(c):
if len(c) == 1:
return str(ord(c))
@@ -745,10 +755,10 @@ for key in locale_keys:
print " <locale>"
print " <language>" + l['language'] + "</language>"
- print " <languageEndonym>" + l['language_endonym'].encode('utf-8') + "</languageEndonym>"
+ print " <languageEndonym>" + escape(l['language_endonym']).encode('utf-8') + "</languageEndonym>"
print " <script>" + l['script'] + "</script>"
print " <country>" + l['country'] + "</country>"
- print " <countryEndonym>" + l['country_endonym'].encode('utf-8') + "</countryEndonym>"
+ print " <countryEndonym>" + escape(l['country_endonym']).encode('utf-8') + "</countryEndonym>"
print " <languagecode>" + l['language_code'] + "</languagecode>"
print " <scriptcode>" + l['script_code'] + "</scriptcode>"
print " <countrycode>" + l['country_code'] + "</countrycode>"
@@ -757,8 +767,8 @@ for key in locale_keys:
print " <list>" + fixOrdStrList(l['list']) + "</list>"
print " <percent>" + fixOrdStrPercent(l['percent']) + "</percent>"
print " <zero>" + ordStr(l['zero']) + "</zero>"
- print " <minus>" + ordStr(l['minus']) + "</minus>"
- print " <plus>" + ordStr(l['plus']) + "</plus>"
+ print " <minus>" + fixOrdStrMinus(l['minus']) + "</minus>"
+ print " <plus>" + fixOrdStrPlus(l['plus']) + "</plus>"
print " <exp>" + fixOrdStrExp(l['exp']) + "</exp>"
print " <quotationStart>" + l['quotationStart'].encode('utf-8') + "</quotationStart>"
print " <quotationEnd>" + l['quotationEnd'].encode('utf-8') + "</quotationEnd>"
diff --git a/util/local_database/cldr2qtimezone.py b/util/local_database/cldr2qtimezone.py
index 4e3548a387..b48f7dc43f 100755
--- a/util/local_database/cldr2qtimezone.py
+++ b/util/local_database/cldr2qtimezone.py
@@ -197,7 +197,8 @@ windowsIdList = {
96 : [ u'W. Europe Standard Time', 3600 ],
97 : [ u'West Asia Standard Time', 18000 ],
98 : [ u'West Pacific Standard Time', 36000 ],
- 99 : [ u'Yakutsk Standard Time', 36000 ]
+ 99 : [ u'Yakutsk Standard Time', 36000 ],
+ 100: [ u'Libya Standard Time', 3600 ]
}
def windowsIdToKey(windowsId):
@@ -296,7 +297,7 @@ if mapTimezones:
if attribute[0] == u'territory':
data['countryCode'] = attribute[1]
if attribute[0] == u'type':
- data['olsenList'] = attribute[1]
+ data['ianaList'] = attribute[1]
data['windowsKey'] = windowsIdToKey(data['windowsId'])
if data['windowsKey'] <= 0:
@@ -304,7 +305,7 @@ if mapTimezones:
countryId = 0
if data['countryCode'] == u'001':
- defaultDict[data['windowsKey']] = data['olsenList']
+ defaultDict[data['windowsKey']] = data['ianaList']
else:
data['countryId'] = enumdata.countryCodeToId(data['countryCode'])
if data['countryId'] < 0:
@@ -342,17 +343,17 @@ newTempFile.write("\n\
*/\n\n" % (str(datetime.date.today()), versionNumber, generationDate) )
windowsIdData = ByteArrayData()
-olsenIdData = ByteArrayData()
+ianaIdData = ByteArrayData()
-# Write Windows/Olsen table
-newTempFile.write("// Windows ID Key, Country Enum, Olsen ID Index\n")
+# Write Windows/IANA table
+newTempFile.write("// Windows ID Key, Country Enum, IANA ID Index\n")
newTempFile.write("static const QZoneData zoneDataTable[] = {\n")
for index in windowsIdDict:
data = windowsIdDict[index]
newTempFile.write(" { %6d,%6d,%6d }, // %s / %s\n" \
% (data['windowsKey'],
data['countryId'],
- olsenIdData.append(data['olsenList']),
+ ianaIdData.append(data['ianaList']),
data['windowsId'],
data['country']))
newTempFile.write(" { 0, 0, 0 } // Trailing zeroes\n")
@@ -361,13 +362,13 @@ newTempFile.write("};\n\n")
print "Done Zone Data"
# Write Windows ID key table
-newTempFile.write("// Windows ID Key, Windows ID Index, Olsen ID Index, UTC Offset\n")
+newTempFile.write("// Windows ID Key, Windows ID Index, IANA ID Index, UTC Offset\n")
newTempFile.write("static const QWindowsData windowsDataTable[] = {\n")
for windowsKey in windowsIdList:
newTempFile.write(" { %6d,%6d,%6d,%6d }, // %s\n" \
% (windowsKey,
windowsIdData.append(windowsIdList[windowsKey][0]),
- olsenIdData.append(defaultDict[windowsKey]),
+ ianaIdData.append(defaultDict[windowsKey]),
windowsIdList[windowsKey][1],
windowsIdList[windowsKey][0]))
newTempFile.write(" { 0, 0, 0, 0 } // Trailing zeroes\n")
@@ -376,12 +377,12 @@ newTempFile.write("};\n\n")
print "Done Windows Data Table"
# Write UTC ID key table
-newTempFile.write("// Olsen ID Index, UTC Offset\n")
+newTempFile.write("// IANA ID Index, UTC Offset\n")
newTempFile.write("static const QUtcData utcDataTable[] = {\n")
for index in utcIdList:
data = utcIdList[index]
newTempFile.write(" { %6d,%6d }, // %s\n" \
- % (olsenIdData.append(data[0]),
+ % (ianaIdData.append(data[0]),
data[1],
data[0]))
newTempFile.write(" { 0, 0 } // Trailing zeroes\n")
@@ -394,9 +395,9 @@ newTempFile.write("static const char windowsIdData[] = {\n")
newTempFile.write(wrap_list(windowsIdData.data))
newTempFile.write("\n};\n\n")
-# Write out Olsen ID's data
-newTempFile.write("static const char olsenIdData[] = {\n")
-newTempFile.write(wrap_list(olsenIdData.data))
+# Write out IANA ID's data
+newTempFile.write("static const char ianaIdData[] = {\n")
+newTempFile.write(wrap_list(ianaIdData.data))
newTempFile.write("\n};\n")
print "Done ID Data Table"
diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py
index 256866e177..f9c4c1daee 100644
--- a/util/local_database/enumdata.py
+++ b/util/local_database/enumdata.py
@@ -356,7 +356,10 @@ language_list = {
308 : [ "Tagbanwa", "tbw" ],
309 : [ "TaiDam", "blt" ],
310 : [ "TaiNua", "tdd" ],
- 311 : [ "Ugaritic", "uga" ]
+ 311 : [ "Ugaritic", "uga" ],
+ 312 : [ "Akoose", "bss" ],
+ 313 : [ "Lakota", "lkt" ],
+ 314 : [ "Standard Moroccan Tamazight", "zgh" ]
}
country_list = {
diff --git a/util/unicode/data/ArabicShaping.txt b/util/unicode/data/ArabicShaping.txt
index fd22f5d6e0..8add8a5a1c 100644
--- a/util/unicode/data/ArabicShaping.txt
+++ b/util/unicode/data/ArabicShaping.txt
@@ -1,5 +1,5 @@
-# ArabicShaping-6.2.0.txt
-# Date: 2012-05-15, 21:05:00 GMT [KW]
+# ArabicShaping-6.3.0.txt
+# Date: 2012-11-14, 21:48:00 GMT [KW]
#
# This file is a normative contributory data file in the
# Unicode Character Database.
@@ -11,15 +11,19 @@
# property values for Arabic, Syriac, N'Ko, and Mandaic
# positional shaping, repeating in machine readable form the
# information exemplified in Tables 8-3, 8-8, 8-9, 8-10, 8-13, 8-14,
-# 8-15, 13-5, 14-5, and 14-6 of The Unicode Standard, Version 6.2.
+# 8-15, 13-5, 14-5, and 14-6 of The Unicode Standard, Version 6.3.
+# This file also defines Joining_Type values for Mongolian and
+# Phags-pa positional shaping, which is not listed in tables in
+# the standard.
#
-# See sections 8.2, 8.3, 13.5, and 14.12 of The Unicode Standard,
-# Version 6.2 for more information.
+# See sections 8.2, 8.3, 10.4, 13.2, 13.5, and 14.12 of The Unicode Standard,
+# Version 6.3 for more information.
#
# Each line contains four fields, separated by a semicolon.
#
# Field 0: the code point, in 4-digit hexadecimal
-# form, of an Arabic, Syriac, N'Ko, or Mandaic character.
+# form, of an Arabic, Syriac, N'Ko, Mandaic, Mongolian,
+# Phags-pa, or other character.
#
# Field 1: gives a short schematic name for that character.
# The schematic name is descriptive of the shape, based as
@@ -35,7 +39,13 @@
# C Join_Causing
# U Non_Joining
# T Transparent
-# See Section 8.2, Arabic for more information on these types.
+#
+# See Section 8.2, Arabic for more information on these joining types.
+# Note that for cursive joining scripts which are typically rendered
+# top-to-bottom, rather than right-to-left, Joining_Type=L conventionally
+# refers to bottom joining, and Joining_Type=R conventionally refers
+# to top joining. See Section 10.4 Phags-pa for more information on the
+# interpretation of joining types in vertical layout.
#
# Field 3: defines the joining group (property name: Joining_Group)
#
@@ -68,8 +78,9 @@
# to jg=No_Joining_Group in this data file. Other, more specific
# joining group values will be defined only if an explicit proposal
# to define those values exactly has been approved by the UTC. This
-# is the convention exemplified by the N'Ko and Mandaic scripts. Only the Arabic
-# and Syriac scripts currently have explicit joining group values defined.
+# is the convention exemplified by the N'Ko, Mandaic, Mongolian,
+# and Phags-pa scripts. Only the Arabic and Syriac scripts
+# currently have explicit joining group values defined.
#
# Note: Code points that are not explicitly listed in this file are
# either of joining type T or U:
@@ -81,8 +92,6 @@
# For an explicit listing of characters of joining type T, see
# the derived property file DerivedJoiningType.txt.
#
-# There are currently no characters of joining type L defined in Unicode.
-#
# #############################################################
# Unicode; Schematic Name; Joining Type; Joining Group
@@ -417,9 +426,205 @@
08AB; WAW WITH DOT WITHIN; R; WAW
08AC; ROHINGYA YEH; R; ROHINGYA YEH
+# Mongolian Characters
+
+1806; MONGOLIAN TODO SOFT HYPHEN; U; No_Joining_Group
+1807; MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER; D; No_Joining_Group
+180A; MONGOLIAN NIRUGU; C; No_Joining_Group
+180E; MONGOLIAN VOWEL SEPARATOR; U; No_Joining_Group
+1820; MONGOLIAN A; D; No_Joining_Group
+1821; MONGOLIAN E; D; No_Joining_Group
+1822; MONGOLIAN I; D; No_Joining_Group
+1823; MONGOLIAN O; D; No_Joining_Group
+1824; MONGOLIAN U; D; No_Joining_Group
+1825; MONGOLIAN OE; D; No_Joining_Group
+1826; MONGOLIAN UE; D; No_Joining_Group
+1827; MONGOLIAN EE; D; No_Joining_Group
+1828; MONGOLIAN NA; D; No_Joining_Group
+1829; MONGOLIAN ANG; D; No_Joining_Group
+182A; MONGOLIAN BA; D; No_Joining_Group
+182B; MONGOLIAN PA; D; No_Joining_Group
+182C; MONGOLIAN QA; D; No_Joining_Group
+182D; MONGOLIAN GA; D; No_Joining_Group
+182E; MONGOLIAN MA; D; No_Joining_Group
+182F; MONGOLIAN LA; D; No_Joining_Group
+1830; MONGOLIAN SA; D; No_Joining_Group
+1831; MONGOLIAN SHA; D; No_Joining_Group
+1832; MONGOLIAN TA; D; No_Joining_Group
+1833; MONGOLIAN DA; D; No_Joining_Group
+1834; MONGOLIAN CHA; D; No_Joining_Group
+1835; MONGOLIAN JA; D; No_Joining_Group
+1836; MONGOLIAN YA; D; No_Joining_Group
+1837; MONGOLIAN RA; D; No_Joining_Group
+1838; MONGOLIAN WA; D; No_Joining_Group
+1839; MONGOLIAN FA; D; No_Joining_Group
+183A; MONGOLIAN KA; D; No_Joining_Group
+183B; MONGOLIAN KHA; D; No_Joining_Group
+183C; MONGOLIAN TSA; D; No_Joining_Group
+183D; MONGOLIAN ZA; D; No_Joining_Group
+183E; MONGOLIAN HAA; D; No_Joining_Group
+183F; MONGOLIAN ZRA; D; No_Joining_Group
+1840; MONGOLIAN LHA; D; No_Joining_Group
+1841; MONGOLIAN ZHI; D; No_Joining_Group
+1842; MONGOLIAN CHI; D; No_Joining_Group
+1843; MONGOLIAN TODO LONG VOWEL SIGN; D; No_Joining_Group
+1844; MONGOLIAN TODO E; D; No_Joining_Group
+1845; MONGOLIAN TODO I; D; No_Joining_Group
+1846; MONGOLIAN TODO O; D; No_Joining_Group
+1847; MONGOLIAN TODO U; D; No_Joining_Group
+1848; MONGOLIAN TODO OE; D; No_Joining_Group
+1849; MONGOLIAN TODO UE; D; No_Joining_Group
+184A; MONGOLIAN TODO ANG; D; No_Joining_Group
+184B; MONGOLIAN TODO BA; D; No_Joining_Group
+184C; MONGOLIAN TODO PA; D; No_Joining_Group
+184D; MONGOLIAN TODO QA; D; No_Joining_Group
+184E; MONGOLIAN TODO GA; D; No_Joining_Group
+184F; MONGOLIAN TODO MA; D; No_Joining_Group
+1850; MONGOLIAN TODO TA; D; No_Joining_Group
+1851; MONGOLIAN TODO DA; D; No_Joining_Group
+1852; MONGOLIAN TODO CHA; D; No_Joining_Group
+1853; MONGOLIAN TODO JA; D; No_Joining_Group
+1854; MONGOLIAN TODO TSA; D; No_Joining_Group
+1855; MONGOLIAN TODO YA; D; No_Joining_Group
+1856; MONGOLIAN TODO WA; D; No_Joining_Group
+1857; MONGOLIAN TODO KA; D; No_Joining_Group
+1858; MONGOLIAN TODO GAA; D; No_Joining_Group
+1859; MONGOLIAN TODO HAA; D; No_Joining_Group
+185A; MONGOLIAN TODO JIA; D; No_Joining_Group
+185B; MONGOLIAN TODO NIA; D; No_Joining_Group
+185C; MONGOLIAN TODO DZA; D; No_Joining_Group
+185D; MONGOLIAN SIBE E; D; No_Joining_Group
+185E; MONGOLIAN SIBE I; D; No_Joining_Group
+185F; MONGOLIAN SIBE IY; D; No_Joining_Group
+1860; MONGOLIAN SIBE UE; D; No_Joining_Group
+1861; MONGOLIAN SIBE U; D; No_Joining_Group
+1862; MONGOLIAN SIBE ANG; D; No_Joining_Group
+1863; MONGOLIAN SIBE KA; D; No_Joining_Group
+1864; MONGOLIAN SIBE GA; D; No_Joining_Group
+1865; MONGOLIAN SIBE HA; D; No_Joining_Group
+1866; MONGOLIAN SIBE PA; D; No_Joining_Group
+1867; MONGOLIAN SIBE SHA; D; No_Joining_Group
+1868; MONGOLIAN SIBE TA; D; No_Joining_Group
+1869; MONGOLIAN SIBE DA; D; No_Joining_Group
+186A; MONGOLIAN SIBE JA; D; No_Joining_Group
+186B; MONGOLIAN SIBE FA; D; No_Joining_Group
+186C; MONGOLIAN SIBE GAA; D; No_Joining_Group
+186D; MONGOLIAN SIBE HAA; D; No_Joining_Group
+186E; MONGOLIAN SIBE TSA; D; No_Joining_Group
+186F; MONGOLIAN SIBE ZA; D; No_Joining_Group
+1870; MONGOLIAN SIBE RAA; D; No_Joining_Group
+1871; MONGOLIAN SIBE CHA; D; No_Joining_Group
+1872; MONGOLIAN SIBE ZHA; D; No_Joining_Group
+1873; MONGOLIAN MANCHU I; D; No_Joining_Group
+1874; MONGOLIAN MANCHU KA; D; No_Joining_Group
+1875; MONGOLIAN MANCHU RA; D; No_Joining_Group
+1876; MONGOLIAN MANCHU FA; D; No_Joining_Group
+1877; MONGOLIAN MANCHU ZHA; D; No_Joining_Group
+1880; MONGOLIAN ALI GALI ANUSVARA ONE; U; No_Joining_Group
+1881; MONGOLIAN ALI GALI VISARGA ONE; U; No_Joining_Group
+1882; MONGOLIAN ALI GALI DAMARU; U; No_Joining_Group
+1883; MONGOLIAN ALI GALI UBADAMA; U; No_Joining_Group
+1884; MONGOLIAN ALI GALI INVERTED UBADAMA; U; No_Joining_Group
+1885; MONGOLIAN ALI GALI BALUDA; U; No_Joining_Group
+1886; MONGOLIAN ALI GALI THREE BALUDA; U; No_Joining_Group
+1887; MONGOLIAN ALI GALI A; D; No_Joining_Group
+1888; MONGOLIAN ALI GALI I; D; No_Joining_Group
+1889; MONGOLIAN ALI GALI KA; D; No_Joining_Group
+188A; MONGOLIAN ALI GALI NGA; D; No_Joining_Group
+188B; MONGOLIAN ALI GALI CA; D; No_Joining_Group
+188C; MONGOLIAN ALI GALI TTA; D; No_Joining_Group
+188D; MONGOLIAN ALI GALI TTHA; D; No_Joining_Group
+188E; MONGOLIAN ALI GALI DDA; D; No_Joining_Group
+188F; MONGOLIAN ALI GALI NNA; D; No_Joining_Group
+1890; MONGOLIAN ALI GALI TA; D; No_Joining_Group
+1891; MONGOLIAN ALI GALI DA; D; No_Joining_Group
+1892; MONGOLIAN ALI GALI PA; D; No_Joining_Group
+1893; MONGOLIAN ALI GALI PHA; D; No_Joining_Group
+1894; MONGOLIAN ALI GALI SSA; D; No_Joining_Group
+1895; MONGOLIAN ALI GALI ZHA; D; No_Joining_Group
+1896; MONGOLIAN ALI GALI ZA; D; No_Joining_Group
+1897; MONGOLIAN ALI GALI AH; D; No_Joining_Group
+1898; MONGOLIAN TODO ALI GALI TA; D; No_Joining_Group
+1899; MONGOLIAN TODO ALI GALI ZHA; D; No_Joining_Group
+189A; MONGOLIAN MANCHU ALI GALI GHA; D; No_Joining_Group
+189B; MONGOLIAN MANCHU ALI GALI NGA; D; No_Joining_Group
+189C; MONGOLIAN MANCHU ALI GALI CA; D; No_Joining_Group
+189D; MONGOLIAN MANCHU ALI GALI JHA; D; No_Joining_Group
+189E; MONGOLIAN MANCHU ALI GALI TTA; D; No_Joining_Group
+189F; MONGOLIAN MANCHU ALI GALI DDHA; D; No_Joining_Group
+18A0; MONGOLIAN MANCHU ALI GALI TA; D; No_Joining_Group
+18A1; MONGOLIAN MANCHU ALI GALI DHA; D; No_Joining_Group
+18A2; MONGOLIAN MANCHU ALI GALI SSA; D; No_Joining_Group
+18A3; MONGOLIAN MANCHU ALI GALI CYA; D; No_Joining_Group
+18A4; MONGOLIAN MANCHU ALI GALI ZHA; D; No_Joining_Group
+18A5; MONGOLIAN MANCHU ALI GALI ZA; D; No_Joining_Group
+18A6; MONGOLIAN ALI GALI HALF U; D; No_Joining_Group
+18A7; MONGOLIAN ALI GALI HALF YA; D; No_Joining_Group
+18A8; MONGOLIAN MANCHU ALI GALI BHA; D; No_Joining_Group
+18AA; MONGOLIAN MANCHU ALI GALI LHA; D; No_Joining_Group
+
# Other
200C; ZERO WIDTH NON-JOINER; U; No_Joining_Group
200D; ZERO WIDTH JOINER; C; No_Joining_Group
+2066; LEFT-TO-RIGHT ISOLATE; U; No_Joining_Group
+2067; RIGHT-TO-LEFT ISOLATE; U; No_Joining_Group
+2068; FIRST STRONG ISOLATE; U; No_Joining_Group
+2069; POP DIRECTIONAL ISOLATE; U; No_Joining_Group
+
+# Phags-Pa Characters
+
+A840; PHAGS-PA KA; D; No_Joining_Group
+A841; PHAGS-PA KHA; D; No_Joining_Group
+A842; PHAGS-PA GA; D; No_Joining_Group
+A843; PHAGS-PA NGA; D; No_Joining_Group
+A844; PHAGS-PA CA; D; No_Joining_Group
+A845; PHAGS-PA CHA; D; No_Joining_Group
+A846; PHAGS-PA JA; D; No_Joining_Group
+A847; PHAGS-PA NYA; D; No_Joining_Group
+A848; PHAGS-PA TA; D; No_Joining_Group
+A849; PHAGS-PA THA; D; No_Joining_Group
+A84A; PHAGS-PA DA; D; No_Joining_Group
+A84B; PHAGS-PA NA; D; No_Joining_Group
+A84C; PHAGS-PA PA; D; No_Joining_Group
+A84D; PHAGS-PA PHA; D; No_Joining_Group
+A84E; PHAGS-PA BA; D; No_Joining_Group
+A84F; PHAGS-PA MA; D; No_Joining_Group
+A850; PHAGS-PA TSA; D; No_Joining_Group
+A851; PHAGS-PA TSHA; D; No_Joining_Group
+A852; PHAGS-PA DZA; D; No_Joining_Group
+A853; PHAGS-PA WA; D; No_Joining_Group
+A854; PHAGS-PA ZHA; D; No_Joining_Group
+A855; PHAGS-PA ZA; D; No_Joining_Group
+A856; PHAGS-PA SMALL A; D; No_Joining_Group
+A857; PHAGS-PA YA; D; No_Joining_Group
+A858; PHAGS-PA RA; D; No_Joining_Group
+A859; PHAGS-PA LA; D; No_Joining_Group
+A85A; PHAGS-PA SHA; D; No_Joining_Group
+A85B; PHAGS-PA SA; D; No_Joining_Group
+A85C; PHAGS-PA HA; D; No_Joining_Group
+A85D; PHAGS-PA A; D; No_Joining_Group
+A85E; PHAGS-PA I; D; No_Joining_Group
+A85F; PHAGS-PA U; D; No_Joining_Group
+A860; PHAGS-PA E; D; No_Joining_Group
+A861; PHAGS-PA O; D; No_Joining_Group
+A862; PHAGS-PA QA; D; No_Joining_Group
+A863; PHAGS-PA XA; D; No_Joining_Group
+A864; PHAGS-PA FA; D; No_Joining_Group
+A865; PHAGS-PA GGA; D; No_Joining_Group
+A866; PHAGS-PA EE; D; No_Joining_Group
+A867; PHAGS-PA SUBJOINED WA; D; No_Joining_Group
+A868; PHAGS-PA SUBJOINED YA; D; No_Joining_Group
+A869; PHAGS-PA TTA; D; No_Joining_Group
+A86A; PHAGS-PA TTHA; D; No_Joining_Group
+A86B; PHAGS-PA DDA; D; No_Joining_Group
+A86C; PHAGS-PA NNA; D; No_Joining_Group
+A86D; PHAGS-PA ALTERNATE YA; D; No_Joining_Group
+A86E; PHAGS-PA VOICELESS SHA; D; No_Joining_Group
+A86F; PHAGS-PA VOICED HA; D; No_Joining_Group
+A870; PHAGS-PA ASPIRATED FA; D; No_Joining_Group
+A871; PHAGS-PA SUBJOINED RA; D; No_Joining_Group
+A872; PHAGS-PA SUPERFIXED RA; L; No_Joining_Group
+A873; PHAGS-PA CANDRABINDU; U; No_Joining_Group
# EOF
diff --git a/util/unicode/data/BidiMirroring.txt b/util/unicode/data/BidiMirroring.txt
index ec41b76937..d97c0dd961 100644
--- a/util/unicode/data/BidiMirroring.txt
+++ b/util/unicode/data/BidiMirroring.txt
@@ -1,19 +1,19 @@
-# BidiMirroring-6.2.0.txt
-# Date: 2012-05-15, 24:19:00 GMT [KW, LI]
+# BidiMirroring-6.3.0.txt
+# Date: 2013-02-12, 08:20:00 GMT [KW, LI]
#
# Bidi_Mirroring_Glyph Property
#
# This file is an informative contributory data file in the
# Unicode Character Database.
#
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# This data file lists characters that have the Bidi_Mirrored=Yes property
# value, for which there is another Unicode character that typically has a glyph
# that is the mirror image of the original character's glyph.
#
-# The repertoire covered by the file is Unicode 6.2.0.
+# The repertoire covered by the file is Unicode 6.3.0.
#
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
@@ -42,7 +42,7 @@
#
# This file was originally created by Markus Scherer.
# Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, 5.2, and 6.0 by Ken Whistler,
-# and for Unicode 6.1 and 6.2 by Ken Whistler and Laurentiu Iancu.
+# and for Unicode 6.1, 6.2, and 6.3 by Ken Whistler and Laurentiu Iancu.
#
# ############################################################
#
@@ -204,8 +204,8 @@
276F; 276E # HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
2770; 2771 # HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
2771; 2770 # HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
-2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET
-2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET
+2772; 2773 # LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+2773; 2772 # LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
2774; 2775 # MEDIUM LEFT CURLY BRACKET ORNAMENT
2775; 2774 # MEDIUM RIGHT CURLY BRACKET ORNAMENT
27C3; 27C4 # OPEN SUBSET
diff --git a/util/unicode/data/Blocks.txt b/util/unicode/data/Blocks.txt
index 6a06ab1445..d45ab0cff2 100644
--- a/util/unicode/data/Blocks.txt
+++ b/util/unicode/data/Blocks.txt
@@ -1,5 +1,5 @@
-# Blocks-6.2.0.txt
-# Date: 2012-05-14, 22:42:00 GMT [KW, LI]
+# Blocks-6.3.0.txt
+# Date: 2012-12-02, 09:45:00 GMT [KW, LI]
#
# Unicode Character Database
# Copyright (c) 1991-2012 Unicode, Inc.
diff --git a/util/unicode/data/CaseFolding.txt b/util/unicode/data/CaseFolding.txt
index df1813d2ad..cf5779f407 100644
--- a/util/unicode/data/CaseFolding.txt
+++ b/util/unicode/data/CaseFolding.txt
@@ -1,8 +1,8 @@
-# CaseFolding-6.2.0.txt
-# Date: 2012-08-14, 17:54:49 GMT [MD]
+# CaseFolding-6.3.0.txt
+# Date: 2012-12-20, 22:14:35 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
diff --git a/util/unicode/data/DerivedAge.txt b/util/unicode/data/DerivedAge.txt
index 0629232a21..6a77b82ecc 100644
--- a/util/unicode/data/DerivedAge.txt
+++ b/util/unicode/data/DerivedAge.txt
@@ -1,8 +1,8 @@
-# DerivedAge-6.2.0.txt
-# Date: 2012-09-20, 21:30:39 GMT [MD]
+# DerivedAge-6.3.0.txt
+# Date: 2013-08-27, 18:11:46 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
@@ -503,7 +503,8 @@ FFFC ; 2.1 # OBJECT REPLACEMENT CHARACTER
16A0..16F0 ; 3.0 # [81] RUNIC LETTER FEHU FEOH FE F..RUNIC BELGTHOR SYMBOL
1780..17DC ; 3.0 # [93] KHMER LETTER KA..KHMER SIGN AVAKRAHASANYA
17E0..17E9 ; 3.0 # [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
-1800..180E ; 3.0 # [15] MONGOLIAN BIRGA..MONGOLIAN VOWEL SEPARATOR
+1800..180D ; 3.0 # [14] MONGOLIAN BIRGA..MONGOLIAN FREE VARIATION SELECTOR THREE
+180E ; 3.0 # MONGOLIAN VOWEL SEPARATOR
1810..1819 ; 3.0 # [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
1820..1877 ; 3.0 # [88] MONGOLIAN LETTER A..MONGOLIAN LETTER MANCHU ZHA
1880..18A9 ; 3.0 # [42] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI DAGALGA
@@ -1304,4 +1305,15 @@ FA2E..FA2F ; 6.1 # [2] CJK COMPATIBILITY IDEOGRAPH-FA2E..CJK COMPATIBILITY
# Total code points: 1
+# ================================================
+
+# Age=V6_3
+
+# Newly assigned in Unicode 6.3.0 (September, 2013)
+
+061C ; 6.3 # ARABIC LETTER MARK
+2066..2069 ; 6.3 # [4] LEFT-TO-RIGHT ISOLATE..POP DIRECTIONAL ISOLATE
+
+# Total code points: 5
+
# EOF
diff --git a/util/unicode/data/DerivedNormalizationProps.txt b/util/unicode/data/DerivedNormalizationProps.txt
index 2ecd8e22ff..e59d17715d 100644
--- a/util/unicode/data/DerivedNormalizationProps.txt
+++ b/util/unicode/data/DerivedNormalizationProps.txt
@@ -1,8 +1,8 @@
-# DerivedNormalizationProps-6.2.0.txt
-# Date: 2012-05-23, 20:34:48 GMT [MD]
+# DerivedNormalizationProps-6.3.0.txt
+# Date: 2013-03-02, 16:07:38 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
@@ -3377,6 +3377,7 @@ FFE3 ; Expands_On_NFKC # Sk FULLWIDTH MACRON
0555 ; NFKC_CF; 0585 # L& ARMENIAN CAPITAL LETTER OH
0556 ; NFKC_CF; 0586 # L& ARMENIAN CAPITAL LETTER FEH
0587 ; NFKC_CF; 0565 0582 # L& ARMENIAN SMALL LIGATURE ECH YIWN
+061C ; NFKC_CF; # Cf ARABIC LETTER MARK
0675 ; NFKC_CF; 0627 0674 # Lo ARABIC LETTER HIGH HAMZA ALEF
0676 ; NFKC_CF; 0648 0674 # Lo ARABIC LETTER HIGH HAMZA WAW
0677 ; NFKC_CF; 06C7 0674 # Lo ARABIC LETTER U WITH HAMZA ABOVE
@@ -3468,6 +3469,7 @@ FFE3 ; Expands_On_NFKC # Sk FULLWIDTH MACRON
115F..1160 ; NFKC_CF; # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
17B4..17B5 ; NFKC_CF; # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
180B..180D ; NFKC_CF; # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+180E ; NFKC_CF; # Cf MONGOLIAN VOWEL SEPARATOR
1D2C ; NFKC_CF; 0061 # Lm MODIFIER LETTER CAPITAL A
1D2D ; NFKC_CF; 00E6 # Lm MODIFIER LETTER CAPITAL AE
1D2E ; NFKC_CF; 0062 # Lm MODIFIER LETTER CAPITAL B
@@ -3870,8 +3872,8 @@ FFE3 ; Expands_On_NFKC # Sk FULLWIDTH MACRON
2057 ; NFKC_CF; 2032 2032 2032 2032 #Po QUADRUPLE PRIME
205F ; NFKC_CF; 0020 # Zs MEDIUM MATHEMATICAL SPACE
2060..2064 ; NFKC_CF; # Cf [5] WORD JOINER..INVISIBLE PLUS
-2065..2069 ; NFKC_CF; # Cn [5] <reserved-2065>..<reserved-2069>
-206A..206F ; NFKC_CF; # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2065 ; NFKC_CF; # Cn <reserved-2065>
+2066..206F ; NFKC_CF; # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
2070 ; NFKC_CF; 0030 # No SUPERSCRIPT ZERO
2071 ; NFKC_CF; 0069 # Lm SUPERSCRIPT LATIN SMALL LETTER I
2074 ; NFKC_CF; 0034 # No SUPERSCRIPT FOUR
@@ -8403,7 +8405,7 @@ E0080..E00FF ; NFKC_CF; # Cn [128] <reserved-E0080>..<reserved-E
E0100..E01EF ; NFKC_CF; # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
E01F0..E0FFF ; NFKC_CF; # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
-# Total code points: 9944
+# Total code points: 9946
# ================================================
@@ -8698,6 +8700,7 @@ E01F0..E0FFF ; NFKC_CF; # Cn [3600] <reserved-E01F0>..<reserved-
0526 ; Changes_When_NFKC_Casefolded # L& CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER
0531..0556 ; Changes_When_NFKC_Casefolded # L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
0587 ; Changes_When_NFKC_Casefolded # L& ARMENIAN SMALL LIGATURE ECH YIWN
+061C ; Changes_When_NFKC_Casefolded # Cf ARABIC LETTER MARK
0675..0678 ; Changes_When_NFKC_Casefolded # Lo [4] ARABIC LETTER HIGH HAMZA ALEF..ARABIC LETTER HIGH HAMZA YEH
0958..095F ; Changes_When_NFKC_Casefolded # Lo [8] DEVANAGARI LETTER QA..DEVANAGARI LETTER YYA
09DC..09DD ; Changes_When_NFKC_Casefolded # Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA
@@ -8733,6 +8736,7 @@ E01F0..E0FFF ; NFKC_CF; # Cn [3600] <reserved-E01F0>..<reserved-
115F..1160 ; Changes_When_NFKC_Casefolded # Lo [2] HANGUL CHOSEONG FILLER..HANGUL JUNGSEONG FILLER
17B4..17B5 ; Changes_When_NFKC_Casefolded # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
180B..180D ; Changes_When_NFKC_Casefolded # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+180E ; Changes_When_NFKC_Casefolded # Cf MONGOLIAN VOWEL SEPARATOR
1D2C..1D2E ; Changes_When_NFKC_Casefolded # Lm [3] MODIFIER LETTER CAPITAL A..MODIFIER LETTER CAPITAL B
1D30..1D3A ; Changes_When_NFKC_Casefolded # Lm [11] MODIFIER LETTER CAPITAL D..MODIFIER LETTER CAPITAL N
1D3C..1D4D ; Changes_When_NFKC_Casefolded # Lm [18] MODIFIER LETTER CAPITAL O..MODIFIER LETTER SMALL G
@@ -8914,8 +8918,8 @@ E01F0..E0FFF ; NFKC_CF; # Cn [3600] <reserved-E01F0>..<reserved-
2057 ; Changes_When_NFKC_Casefolded # Po QUADRUPLE PRIME
205F ; Changes_When_NFKC_Casefolded # Zs MEDIUM MATHEMATICAL SPACE
2060..2064 ; Changes_When_NFKC_Casefolded # Cf [5] WORD JOINER..INVISIBLE PLUS
-2065..2069 ; Changes_When_NFKC_Casefolded # Cn [5] <reserved-2065>..<reserved-2069>
-206A..206F ; Changes_When_NFKC_Casefolded # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2065 ; Changes_When_NFKC_Casefolded # Cn <reserved-2065>
+2066..206F ; Changes_When_NFKC_Casefolded # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
2070 ; Changes_When_NFKC_Casefolded # No SUPERSCRIPT ZERO
2071 ; Changes_When_NFKC_Casefolded # Lm SUPERSCRIPT LATIN SMALL LETTER I
2074..2079 ; Changes_When_NFKC_Casefolded # No [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE
@@ -9363,6 +9367,6 @@ E0080..E00FF ; Changes_When_NFKC_Casefolded # Cn [128] <reserved-E0080>..<reser
E0100..E01EF ; Changes_When_NFKC_Casefolded # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
E01F0..E0FFF ; Changes_When_NFKC_Casefolded # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
-# Total code points: 9944
+# Total code points: 9946
# EOF
diff --git a/util/unicode/data/GraphemeBreakProperty.txt b/util/unicode/data/GraphemeBreakProperty.txt
index 948faa9d5c..55556e0c58 100644
--- a/util/unicode/data/GraphemeBreakProperty.txt
+++ b/util/unicode/data/GraphemeBreakProperty.txt
@@ -1,8 +1,8 @@
-# GraphemeBreakProperty-6.2.0.txt
-# Date: 2012-08-13, 19:12:02 GMT [MD]
+# GraphemeBreakProperty-6.3.0.txt
+# Date: 2013-03-02, 16:07:40 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
@@ -35,16 +35,18 @@
007F..009F ; Control # Cc [33] <control-007F>..<control-009F>
00AD ; Control # Cf SOFT HYPHEN
0600..0604 ; Control # Cf [5] ARABIC NUMBER SIGN..ARABIC SIGN SAMVAT
+061C ; Control # Cf ARABIC LETTER MARK
06DD ; Control # Cf ARABIC END OF AYAH
070F ; Control # Cf SYRIAC ABBREVIATION MARK
+180E ; Control # Cf MONGOLIAN VOWEL SEPARATOR
200B ; Control # Cf ZERO WIDTH SPACE
200E..200F ; Control # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
2028 ; Control # Zl LINE SEPARATOR
2029 ; Control # Zp PARAGRAPH SEPARATOR
202A..202E ; Control # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
2060..2064 ; Control # Cf [5] WORD JOINER..INVISIBLE PLUS
-2065..2069 ; Control # Cn [5] <reserved-2065>..<reserved-2069>
-206A..206F ; Control # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2065 ; Control # Cn <reserved-2065>
+2066..206F ; Control # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
D800..DFFF ; Control # Cs [2048] <surrogate-D800>..<surrogate-DFFF>
FEFF ; Control # Cf ZERO WIDTH NO-BREAK SPACE
FFF0..FFF8 ; Control # Cn [9] <reserved-FFF0>..<reserved-FFF8>
@@ -58,7 +60,7 @@ E0020..E007F ; Control # Cf [96] TAG SPACE..CANCEL TAG
E0080..E00FF ; Control # Cn [128] <reserved-E0080>..<reserved-E00FF>
E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
-# Total code points: 6023
+# Total code points: 6025
# ================================================
@@ -196,6 +198,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF>
1932 ; Extend # Mn LIMBU SMALL LETTER ANUSVARA
1939..193B ; Extend # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
1A17..1A18 ; Extend # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+1A1B ; Extend # Mn BUGINESE VOWEL SIGN AE
1A56 ; Extend # Mn TAI THAM CONSONANT SIGN MEDIAL LA
1A58..1A5E ; Extend # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
1A60 ; Extend # Mn TAI THAM SIGN SAKOT
@@ -304,7 +307,7 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT
1D242..1D244 ; Extend # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
-# Total code points: 1317
+# Total code points: 1318
# ================================================
@@ -370,7 +373,7 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
1933..1938 ; SpacingMark # Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
19B5..19B7 ; SpacingMark # Mc [3] NEW TAI LUE VOWEL SIGN E..NEW TAI LUE VOWEL SIGN O
19BA ; SpacingMark # Mc NEW TAI LUE VOWEL SIGN AY
-1A19..1A1B ; SpacingMark # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
+1A19..1A1A ; SpacingMark # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
1A55 ; SpacingMark # Mc TAI THAM CONSONANT SIGN MEDIAL RA
1A57 ; SpacingMark # Mc TAI THAM CONSONANT SIGN LA TANG LAI
1A6D..1A72 ; SpacingMark # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
@@ -427,7 +430,7 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK
1D166 ; SpacingMark # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
1D16D ; SpacingMark # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT
-# Total code points: 291
+# Total code points: 290
# ================================================
diff --git a/util/unicode/data/LineBreak.txt b/util/unicode/data/LineBreak.txt
index e309836b0e..8a72cabf78 100644
--- a/util/unicode/data/LineBreak.txt
+++ b/util/unicode/data/LineBreak.txt
@@ -1,5 +1,5 @@
-# LineBreak-6.2.0.txt
-# Date: 2012-08-08, 19:26:00 GMT [KW]
+# LineBreak-6.3.0.txt
+# Date: 2013-02-06, 19:45:00 GMT [KW, LI]
#
# Line Break Properties
#
@@ -7,12 +7,12 @@
# Unicode Character Database.
# It contains both normative and informative data.
#
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# The format is two fields separated by a semicolon.
# Field 0: Unicode value
-# Field 1: LineBreak property, consisting of one of the following values:
+# Field 1: Line_Break property, consisting of one of the following values:
# Normative:
# "BK", "CR", "LF", "CM", "SG", "GL", "CB", "SP", "ZW",
# "NL", "WJ", "JL", "JV", "JT", "H2", "H3"
@@ -20,27 +20,31 @@
# "XX", "OP", "CL", "CP", "QU", "NS", "EX", "SY",
# "IS", "PR", "PO", "NU", "AL", "ID", "IN", "HY",
# "BB", "BA", "SA", "AI", "B2", "HL", "CJ", "RI"
-# - All code points, assigned and unassigned, that are not listed
+# - All code points, assigned and unassigned, that are not listed
# explicitly are given the value "XX".
# The unassigned code points that default to "ID" include ranges in the
# following blocks:
# CJK Unified Ideographs Extension A: U+3400..U+4DBF
# CJK Unified Ideographs: U+4E00..U+9FFF
# CJK Compatibility Ideographs: U+F900..U+FAFF
-# CJK Unified Ideographs Extension B: U+20000..U+2A6DF
+# CJK Unified Ideographs Extension B: U+20000..U+2A6DF
# CJK Unified Ideographs Extension C: U+2A700..U+2B73F
# CJK Unified Ideographs Extension D: U+2B740..U+2B81F
# CJK Compatibility Ideographs Supplement: U+2F800..U+2FA1F
# and any other reserved code points on
# Planes 2 and 3: U+20000..U+2FFFD
# U+30000..U+3FFFD
-# - Characters ranges are specified as for other property files in
+# The unassigned code points that default to "PR" comprise a range in the
+# following block:
+# Currency Symbols: U+20A0..U+20CF
+# - Character ranges are specified as for other property files in
# the Unicode Character Database.
#
# The Unicode name of each character is provided in a comment for help
# in identifying the characters.
#
-# See UAX #14: Unicode Line Breaking Algorithm, for more information
+# For more information, see UAX #14: Unicode Line Breaking Algorithm,
+# at http://www.unicode.org/reports/tr14/
#
# @missing: 0000..10FFFF; XX
0000;CM # <control>
@@ -1554,6 +1558,7 @@
0619;CM # ARABIC SMALL DAMMA
061A;CM # ARABIC SMALL KASRA
061B;EX # ARABIC SEMICOLON
+061C;CM # ARABIC LETTER MARK
061E;EX # ARABIC TRIPLE DOT PUNCTUATION MARK
061F;EX # ARABIC QUESTION MARK
0620;AL # ARABIC LETTER KASHMIRI YEH
@@ -7161,6 +7166,10 @@
2062;AL # INVISIBLE TIMES
2063;AL # INVISIBLE SEPARATOR
2064;AL # INVISIBLE PLUS
+2066;CM # LEFT-TO-RIGHT ISOLATE
+2067;CM # RIGHT-TO-LEFT ISOLATE
+2068;CM # FIRST STRONG ISOLATE
+2069;CM # POP DIRECTIONAL ISOLATE
206A;CM # INHIBIT SYMMETRIC SWAPPING
206B;CM # ACTIVATE SYMMETRIC SWAPPING
206C;CM # INHIBIT ARABIC FORM SHAPING
@@ -7236,6 +7245,7 @@
20B8;PR # TENGE SIGN
20B9;PR # INDIAN RUPEE SIGN
20BA;PR # TURKISH LIRA SIGN
+20BB..20CF;PR # <reserved-20BB>..<reserved-20CF>
20D0;CM # COMBINING LEFT HARPOON ABOVE
20D1;CM # COMBINING RIGHT HARPOON ABOVE
20D2;CM # COMBINING LONG VERTICAL LINE OVERLAY
@@ -10711,7 +10721,7 @@
2FF9;ID # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT
2FFA;ID # IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT
2FFB;ID # IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
-3000;ID # IDEOGRAPHIC SPACE
+3000;BA # IDEOGRAPHIC SPACE
3001;CL # IDEOGRAPHIC COMMA
3002;CL # IDEOGRAPHIC FULL STOP
3003;ID # DITTO MARK
@@ -10764,7 +10774,7 @@
3032;ID # VERTICAL KANA REPEAT WITH VOICED SOUND MARK
3033;ID # VERTICAL KANA REPEAT MARK UPPER HALF
3034;ID # VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF
-3035;ID # VERTICAL KANA REPEAT MARK LOWER HALF
+3035;CM # VERTICAL KANA REPEAT MARK LOWER HALF
3036;ID # CIRCLED POSTAL MARK
3037;ID # IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
3038;ID # HANGZHOU NUMERAL TEN
diff --git a/util/unicode/data/NormalizationCorrections.txt b/util/unicode/data/NormalizationCorrections.txt
index b53bb408a5..aea94ca33e 100644
--- a/util/unicode/data/NormalizationCorrections.txt
+++ b/util/unicode/data/NormalizationCorrections.txt
@@ -1,10 +1,10 @@
-# NormalizationCorrections-6.2.0.txt
-# Date: 2012-05-15, 22:25:00 GMT [KW, LI]
+# NormalizationCorrections-6.3.0.txt
+# Date: 2013-01-02, 08:39:00 GMT [KW, LI]
#
# This file is a normative contributory data file in the
# Unicode Character Database.
#
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
#
# The normalization stability policy of the Unicode Consortium
diff --git a/util/unicode/data/Scripts.txt b/util/unicode/data/Scripts.txt
index 1a8e7229cc..b69716c7a6 100644
--- a/util/unicode/data/Scripts.txt
+++ b/util/unicode/data/Scripts.txt
@@ -1,8 +1,8 @@
-# Scripts-6.2.0.txt
-# Date: 2012-06-04, 17:21:29 GMT [MD]
+# Scripts-6.3.0.txt
+# Date: 2013-07-05, 14:09:02 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
@@ -136,7 +136,7 @@
2055..205E ; Common # Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
205F ; Common # Zs MEDIUM MATHEMATICAL SPACE
2060..2064 ; Common # Cf [5] WORD JOINER..INVISIBLE PLUS
-206A..206F ; Common # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2066..206F ; Common # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
2070 ; Common # No SUPERSCRIPT ZERO
2074..2079 ; Common # No [6] SUPERSCRIPT FOUR..SUPERSCRIPT NINE
207A..207C ; Common # Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
@@ -200,7 +200,10 @@
21D5..21F3 ; Common # So [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
21F4..22FF ; Common # Sm [268] RIGHT ARROW WITH SMALL CIRCLE..Z NOTATION BAG MEMBERSHIP
2300..2307 ; Common # So [8] DIAMETER SIGN..WAVY LINE
-2308..230B ; Common # Sm [4] LEFT CEILING..RIGHT FLOOR
+2308 ; Common # Ps LEFT CEILING
+2309 ; Common # Pe RIGHT CEILING
+230A ; Common # Ps LEFT FLOOR
+230B ; Common # Pe RIGHT FLOOR
230C..231F ; Common # So [20] BOTTOM RIGHT CROP..BOTTOM RIGHT CORNER
2320..2321 ; Common # Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
2322..2328 ; Common # So [7] FROWN..KEYBOARD
@@ -392,6 +395,7 @@ A830..A835 ; Common # No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC
A836..A837 ; Common # So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK
A838 ; Common # Sc NORTH INDIC RUPEE MARK
A839 ; Common # So NORTH INDIC QUANTITY MARK
+A9CF ; Common # Lm JAVANESE PANGRANGKEP
FD3E ; Common # Ps ORNATE LEFT PARENTHESIS
FD3F ; Common # Pe ORNATE RIGHT PARENTHESIS
FDFD ; Common # So ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM
@@ -576,7 +580,7 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR
E0001 ; Common # Cf LANGUAGE TAG
E0020..E007F ; Common # Cf [96] TAG SPACE..CANCEL TAG
-# Total code points: 6413
+# Total code points: 6418
# ================================================
@@ -757,6 +761,7 @@ FB46..FB4F ; Hebrew # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATU
060D ; Arabic # Po ARABIC DATE SEPARATOR
060E..060F ; Arabic # So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
0610..061A ; Arabic # Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+061C ; Arabic # Cf ARABIC LETTER MARK
061E ; Arabic # Po ARABIC TRIPLE DOT PUNCTUATION MARK
0620..063F ; Arabic # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
0641..064A ; Arabic # Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH
@@ -827,7 +832,7 @@ FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LA
1EEAB..1EEBB ; Arabic # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
1EEF0..1EEF1 ; Arabic # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
-# Total code points: 1235
+# Total code points: 1236
# ================================================
@@ -1377,7 +1382,7 @@ AB28..AB2E ; Ethiopic # Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
1806 ; Mongolian # Pd MONGOLIAN TODO SOFT HYPHEN
1807..180A ; Mongolian # Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
180B..180D ; Mongolian # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
-180E ; Mongolian # Zs MONGOLIAN VOWEL SEPARATOR
+180E ; Mongolian # Cf MONGOLIAN VOWEL SEPARATOR
1810..1819 ; Mongolian # Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
1820..1842 ; Mongolian # Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
1843 ; Mongolian # Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN
@@ -1612,7 +1617,8 @@ E0100..E01EF ; Inherited # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-2
1A00..1A16 ; Buginese # Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA
1A17..1A18 ; Buginese # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1A19..1A1B ; Buginese # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
+1A19..1A1A ; Buginese # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A1B ; Buginese # Mn BUGINESE VOWEL SIGN AE
1A1E..1A1F ; Buginese # Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
# Total code points: 30
@@ -1974,11 +1980,10 @@ A9BA..A9BB ; Javanese # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL S
A9BC ; Javanese # Mn JAVANESE VOWEL SIGN PEPET
A9BD..A9C0 ; Javanese # Mc [4] JAVANESE CONSONANT SIGN KERET..JAVANESE PANGKON
A9C1..A9CD ; Javanese # Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH
-A9CF ; Javanese # Lm JAVANESE PANGRANGKEP
A9D0..A9D9 ; Javanese # Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE
A9DE..A9DF ; Javanese # Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN
-# Total code points: 91
+# Total code points: 90
# ================================================
diff --git a/util/unicode/data/SentenceBreakProperty.txt b/util/unicode/data/SentenceBreakProperty.txt
index f29dc4e199..d714d59d3a 100644
--- a/util/unicode/data/SentenceBreakProperty.txt
+++ b/util/unicode/data/SentenceBreakProperty.txt
@@ -1,8 +1,8 @@
-# SentenceBreakProperty-6.2.0.txt
-# Date: 2012-05-23, 20:35:14 GMT [MD]
+# SentenceBreakProperty-6.3.0.txt
+# Date: 2013-09-25, 18:59:01 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
@@ -217,7 +217,8 @@
19B0..19C0 ; Extend # Mc [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
19C8..19C9 ; Extend # Mc [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
1A17..1A18 ; Extend # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1A19..1A1B ; Extend # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
+1A19..1A1A ; Extend # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A1B ; Extend # Mn BUGINESE VOWEL SIGN AE
1A55 ; Extend # Mc TAI THAM CONSONANT SIGN MEDIAL RA
1A56 ; Extend # Mn TAI THAM CONSONANT SIGN MEDIAL LA
1A57 ; Extend # Mc TAI THAM CONSONANT SIGN LA TANG LAI
@@ -396,13 +397,15 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
00AD ; Format # Cf SOFT HYPHEN
0600..0604 ; Format # Cf [5] ARABIC NUMBER SIGN..ARABIC SIGN SAMVAT
+061C ; Format # Cf ARABIC LETTER MARK
06DD ; Format # Cf ARABIC END OF AYAH
070F ; Format # Cf SYRIAC ABBREVIATION MARK
+180E ; Format # Cf MONGOLIAN VOWEL SEPARATOR
200B ; Format # Cf ZERO WIDTH SPACE
200E..200F ; Format # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
202A..202E ; Format # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
2060..2064 ; Format # Cf [5] WORD JOINER..INVISIBLE PLUS
-206A..206F ; Format # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2066..206F ; Format # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
FEFF ; Format # Cf ZERO WIDTH NO-BREAK SPACE
FFF9..FFFB ; Format # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
110BD ; Format # Cf KAITHI NUMBER SIGN
@@ -410,7 +413,7 @@ FFF9..FFFB ; Format # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANN
E0001 ; Format # Cf LANGUAGE TAG
E0020..E007F ; Format # Cf [96] TAG SPACE..CANCEL TAG
-# Total code points: 137
+# Total code points: 143
# ================================================
@@ -419,13 +422,12 @@ E0020..E007F ; Format # Cf [96] TAG SPACE..CANCEL TAG
0020 ; Sp # Zs SPACE
00A0 ; Sp # Zs NO-BREAK SPACE
1680 ; Sp # Zs OGHAM SPACE MARK
-180E ; Sp # Zs MONGOLIAN VOWEL SEPARATOR
2000..200A ; Sp # Zs [11] EN QUAD..HAIR SPACE
202F ; Sp # Zs NARROW NO-BREAK SPACE
205F ; Sp # Zs MEDIUM MATHEMATICAL SPACE
3000 ; Sp # Zs IDEOGRAPHIC SPACE
-# Total code points: 21
+# Total code points: 20
# ================================================
@@ -2246,6 +2248,10 @@ FF61 ; STerm # Po HALFWIDTH IDEOGRAPHIC FULL STOP
207E ; Close # Pe SUPERSCRIPT RIGHT PARENTHESIS
208D ; Close # Ps SUBSCRIPT LEFT PARENTHESIS
208E ; Close # Pe SUBSCRIPT RIGHT PARENTHESIS
+2308 ; Close # Ps LEFT CEILING
+2309 ; Close # Pe RIGHT CEILING
+230A ; Close # Ps LEFT FLOOR
+230B ; Close # Pe RIGHT FLOOR
2329 ; Close # Ps LEFT-POINTING ANGLE BRACKET
232A ; Close # Pe RIGHT-POINTING ANGLE BRACKET
275B..275E ; Close # So [4] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
@@ -2385,7 +2391,7 @@ FF60 ; Close # Pe FULLWIDTH RIGHT WHITE PARENTHESIS
FF62 ; Close # Ps HALFWIDTH LEFT CORNER BRACKET
FF63 ; Close # Pe HALFWIDTH RIGHT CORNER BRACKET
-# Total code points: 177
+# Total code points: 181
# ================================================
diff --git a/util/unicode/data/SpecialCasing.txt b/util/unicode/data/SpecialCasing.txt
index 994043f01b..016a756eb0 100644
--- a/util/unicode/data/SpecialCasing.txt
+++ b/util/unicode/data/SpecialCasing.txt
@@ -1,8 +1,8 @@
-# SpecialCasing-6.2.0.txt
-# Date: 2012-05-23, 20:35:15 GMT [MD]
+# SpecialCasing-6.3.0.txt
+# Date: 2013-05-08, 13:54:51 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
#
@@ -39,7 +39,7 @@
# A language ID is defined by BCP 47, with '-' and '_' treated equivalently.
#
# A context for a character C is defined by Section 3.13 Default Case
-# Operations, of The Unicode Standard, Version 5.0.
+# Algorithms, of The Unicode Standard, Version 6.3.
# (This is identical to the context defined by Unicode 4.1.0,
# as specified in http://www.unicode.org/versions/Unicode4.1.0/)
#
diff --git a/util/unicode/data/UnicodeData.txt b/util/unicode/data/UnicodeData.txt
index 086379eb4f..9fffa71a1e 100644
--- a/util/unicode/data/UnicodeData.txt
+++ b/util/unicode/data/UnicodeData.txt
@@ -1509,6 +1509,7 @@
0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;
061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
+061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;
061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;
@@ -5296,7 +5297,7 @@
180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;
180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
-180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;
+180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;
1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
@@ -5751,7 +5752,7 @@
1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;
1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
-1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
+1A1B;BUGINESE VOWEL SIGN AE;Mn;0;NSM;;;;;N;;;;;
1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;
1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;
1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
@@ -7116,6 +7117,10 @@
2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;
2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;
2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;
+2066;LEFT-TO-RIGHT ISOLATE;Cf;0;LRI;;;;;N;;;;;
+2067;RIGHT-TO-LEFT ISOLATE;Cf;0;RLI;;;;;N;;;;;
+2068;FIRST STRONG ISOLATE;Cf;0;FSI;;;;;N;;;;;
+2069;POP DIRECTIONAL ISOLATE;Cf;0;PDI;;;;;N;;;;;
206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
@@ -7738,10 +7743,10 @@
2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
2307;WAVY LINE;So;0;ON;;;;;N;;;;;
-2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;;
-2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;;
-230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;;
-230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;;
+2308;LEFT CEILING;Ps;0;ON;;;;;Y;;;;;
+2309;RIGHT CEILING;Pe;0;ON;;;;;Y;;;;;
+230A;LEFT FLOOR;Ps;0;ON;;;;;Y;;;;;
+230B;RIGHT FLOOR;Pe;0;ON;;;;;Y;;;;;
230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
@@ -18740,8 +18745,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;
12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;
12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;
-12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;-1;N;;;;;
-12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;-1;N;;;;;
+12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;2;N;;;;;
+12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;3;N;;;;;
12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;
12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;
1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;
diff --git a/util/unicode/data/WordBreakProperty.txt b/util/unicode/data/WordBreakProperty.txt
index 2caa16b46b..ad2b10992c 100644
--- a/util/unicode/data/WordBreakProperty.txt
+++ b/util/unicode/data/WordBreakProperty.txt
@@ -1,8 +1,8 @@
-# WordBreakProperty-6.2.0.txt
-# Date: 2012-08-13, 19:12:09 GMT [MD]
+# WordBreakProperty-6.3.0.txt
+# Date: 2013-07-05, 14:09:03 GMT [MD]
#
# Unicode Character Database
-# Copyright (c) 1991-2012 Unicode, Inc.
+# Copyright (c) 1991-2013 Unicode, Inc.
# For terms of use, see http://www.unicode.org/terms_of_use.html
# For documentation, see http://www.unicode.org/reports/tr44/
@@ -17,6 +17,33 @@
# ================================================
+0022 ; Double_Quote # Po QUOTATION MARK
+
+# Total code points: 1
+
+# ================================================
+
+0027 ; Single_Quote # Po APOSTROPHE
+
+# Total code points: 1
+
+# ================================================
+
+05D0..05EA ; Hebrew_Letter # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
+05F0..05F2 ; Hebrew_Letter # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
+FB1D ; Hebrew_Letter # Lo HEBREW LETTER YOD WITH HIRIQ
+FB1F..FB28 ; Hebrew_Letter # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
+FB2A..FB36 ; Hebrew_Letter # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
+FB38..FB3C ; Hebrew_Letter # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
+FB3E ; Hebrew_Letter # Lo HEBREW LETTER MEM WITH DAGESH
+FB40..FB41 ; Hebrew_Letter # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
+FB43..FB44 ; Hebrew_Letter # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
+FB46..FB4F ; Hebrew_Letter # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
+
+# Total code points: 74
+
+# ================================================
+
000D ; CR # Cc <control-000D>
# Total code points: 1
@@ -226,7 +253,8 @@
19B0..19C0 ; Extend # Mc [17] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE VOWEL SIGN IY
19C8..19C9 ; Extend # Mc [2] NEW TAI LUE TONE MARK-1..NEW TAI LUE TONE MARK-2
1A17..1A18 ; Extend # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
-1A19..1A1B ; Extend # Mc [3] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN AE
+1A19..1A1A ; Extend # Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+1A1B ; Extend # Mn BUGINESE VOWEL SIGN AE
1A55 ; Extend # Mc TAI THAM CONSONANT SIGN MEDIAL RA
1A56 ; Extend # Mn TAI THAM CONSONANT SIGN MEDIAL LA
1A57 ; Extend # Mc TAI THAM CONSONANT SIGN LA TANG LAI
@@ -403,12 +431,14 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
00AD ; Format # Cf SOFT HYPHEN
0600..0604 ; Format # Cf [5] ARABIC NUMBER SIGN..ARABIC SIGN SAMVAT
+061C ; Format # Cf ARABIC LETTER MARK
06DD ; Format # Cf ARABIC END OF AYAH
070F ; Format # Cf SYRIAC ABBREVIATION MARK
+180E ; Format # Cf MONGOLIAN VOWEL SEPARATOR
200E..200F ; Format # Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
202A..202E ; Format # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
2060..2064 ; Format # Cf [5] WORD JOINER..INVISIBLE PLUS
-206A..206F ; Format # Cf [6] INHIBIT SYMMETRIC SWAPPING..NOMINAL DIGIT SHAPES
+2066..206F ; Format # Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
FEFF ; Format # Cf ZERO WIDTH NO-BREAK SPACE
FFF9..FFFB ; Format # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
110BD ; Format # Cf KAITHI NUMBER SIGN
@@ -416,7 +446,7 @@ FFF9..FFFB ; Format # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANN
E0001 ; Format # Cf LANGUAGE TAG
E0020..E007F ; Format # Cf [96] TAG SPACE..CANCEL TAG
-# Total code points: 136
+# Total code points: 142
# ================================================
@@ -472,8 +502,6 @@ FF71..FF9D ; Katakana # Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAK
0531..0556 ; ALetter # L& [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
0559 ; ALetter # Lm ARMENIAN MODIFIER LETTER LEFT HALF RING
0561..0587 ; ALetter # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN
-05D0..05EA ; ALetter # Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
-05F0..05F2 ; ALetter # Lo [3] HEBREW LIGATURE YIDDISH DOUBLE VAV..HEBREW LIGATURE YIDDISH DOUBLE YOD
05F3 ; ALetter # Po HEBREW PUNCTUATION GERESH
0620..063F ; ALetter # Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
0640 ; ALetter # Lm ARABIC TATWEEL
@@ -774,14 +802,7 @@ D7B0..D7C6 ; ALetter # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAE
D7CB..D7FB ; ALetter # Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
FB00..FB06 ; ALetter # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
FB13..FB17 ; ALetter # L& [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
-FB1D ; ALetter # Lo HEBREW LETTER YOD WITH HIRIQ
-FB1F..FB28 ; ALetter # Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
-FB2A..FB36 ; ALetter # Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
-FB38..FB3C ; ALetter # Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
-FB3E ; ALetter # Lo HEBREW LETTER MEM WITH DAGESH
-FB40..FB41 ; ALetter # Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
-FB43..FB44 ; ALetter # Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
-FB46..FBB1 ; ALetter # Lo [108] HEBREW LETTER TSADI WITH DAGESH..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+FB50..FBB1 ; ALetter # Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
FBD3..FD3D ; ALetter # Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
FD50..FD8F ; ALetter # Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
FD92..FDC7 ; ALetter # Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
@@ -913,12 +934,13 @@ FFDA..FFDC ; ALetter # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL
1EEA5..1EEA9 ; ALetter # Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
1EEAB..1EEBB ; ALetter # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
-# Total code points: 24941
+# Total code points: 24867
# ================================================
003A ; MidLetter # Po COLON
00B7 ; MidLetter # Po MIDDLE DOT
+02D7 ; MidLetter # Sk MODIFIER LETTER MINUS SIGN
0387 ; MidLetter # Po GREEK ANO TELEIA
05F4 ; MidLetter # Po HEBREW PUNCTUATION GERSHAYIM
2027 ; MidLetter # Po HYPHENATION POINT
@@ -926,7 +948,7 @@ FE13 ; MidLetter # Po PRESENTATION FORM FOR VERTICAL COLON
FE55 ; MidLetter # Po SMALL COLON
FF1A ; MidLetter # Po FULLWIDTH COLON
-# Total code points: 8
+# Total code points: 9
# ================================================
@@ -949,7 +971,6 @@ FF1B ; MidNum # Po FULLWIDTH SEMICOLON
# ================================================
-0027 ; MidNumLet # Po APOSTROPHE
002E ; MidNumLet # Po FULL STOP
2018 ; MidNumLet # Pi LEFT SINGLE QUOTATION MARK
2019 ; MidNumLet # Pf RIGHT SINGLE QUOTATION MARK
@@ -958,7 +979,7 @@ FE52 ; MidNumLet # Po SMALL FULL STOP
FF07 ; MidNumLet # Po FULLWIDTH APOSTROPHE
FF0E ; MidNumLet # Po FULLWIDTH FULL STOP
-# Total code points: 8
+# Total code points: 7
# ================================================
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index a4d3e0f377..4f941d0eb3 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -77,6 +77,7 @@ static void initAgeMap()
{ QChar::Unicode_6_0, "6.0" },
{ QChar::Unicode_6_1, "6.1" },
{ QChar::Unicode_6_2, "6.2" },
+ { QChar::Unicode_6_3, "6.3" },
{ QChar::Unicode_Unassigned, 0 }
};
AgeMap *d = ageMap;
@@ -176,34 +177,66 @@ static void initDecompositionMap()
}
-static QHash<QByteArray, QChar::Direction> directionMap;
+enum Direction {
+ DirL = QChar::DirL,
+ DirR = QChar::DirR,
+ DirEN = QChar::DirEN,
+ DirES = QChar::DirES,
+ DirET = QChar::DirET,
+ DirAN = QChar::DirAN,
+ DirCS = QChar::DirCS,
+ DirB = QChar::DirB,
+ DirS = QChar::DirS,
+ DirWS = QChar::DirWS,
+ DirON = QChar::DirON,
+ DirLRE = QChar::DirLRE,
+ DirLRO = QChar::DirLRO,
+ DirAL = QChar::DirAL,
+ DirRLE = QChar::DirRLE,
+ DirRLO = QChar::DirRLO,
+ DirPDF = QChar::DirPDF,
+ DirNSM = QChar::DirNSM,
+ DirBN = QChar::DirBN,
+ DirLRI = QChar::DirLRI,
+ DirRLI = QChar::DirRLI,
+ DirFSI = QChar::DirFSI,
+ DirPDI = QChar::DirPDI
+
+ , Dir_Unassigned
+};
+
+static QHash<QByteArray, Direction> directionMap;
static void initDirectionMap()
{
struct Dir {
- QChar::Direction dir;
+ Direction dir;
const char *name;
} directions[] = {
- { QChar::DirL, "L" },
- { QChar::DirR, "R" },
- { QChar::DirEN, "EN" },
- { QChar::DirES, "ES" },
- { QChar::DirET, "ET" },
- { QChar::DirAN, "AN" },
- { QChar::DirCS, "CS" },
- { QChar::DirB, "B" },
- { QChar::DirS, "S" },
- { QChar::DirWS, "WS" },
- { QChar::DirON, "ON" },
- { QChar::DirLRE, "LRE" },
- { QChar::DirLRO, "LRO" },
- { QChar::DirAL, "AL" },
- { QChar::DirRLE, "RLE" },
- { QChar::DirRLO, "RLO" },
- { QChar::DirPDF, "PDF" },
- { QChar::DirNSM, "NSM" },
- { QChar::DirBN, "BN" },
- { QChar::DirL, 0 }
+ { DirL, "L" },
+ { DirR, "R" },
+ { DirEN, "EN" },
+ { DirES, "ES" },
+ { DirET, "ET" },
+ { DirAN, "AN" },
+ { DirCS, "CS" },
+ { DirB, "B" },
+ { DirS, "S" },
+ { DirWS, "WS" },
+ { DirON, "ON" },
+ { DirLRE, "LRE" },
+ { DirLRO, "LRO" },
+ { DirAL, "AL" },
+ { DirRLE, "RLE" },
+ { DirRLO, "RLO" },
+ { DirPDF, "PDF" },
+ { DirNSM, "NSM" },
+ { DirBN, "BN" },
+ { DirLRI, "LRI" },
+ { DirRLI, "RLI" },
+ { DirFSI, "FSI" },
+ { DirPDI, "PDI" },
+ { Dir_Unassigned, 0 }
};
Dir *d = directions;
while (d->name) {
@@ -213,30 +246,30 @@ static void initDirectionMap()
}
-enum Joining {
+enum JoiningType {
Joining_None,
- Joining_Left,
Joining_Causing,
Joining_Dual,
Joining_Right,
+ Joining_Left,
Joining_Transparent
, Joining_Unassigned
};
-static QHash<QByteArray, Joining> joining_map;
+static QHash<QByteArray, JoiningType> joining_map;
static void initJoiningMap()
{
struct JoiningList {
- Joining joining;
+ JoiningType joining;
const char *name;
} joinings[] = {
{ Joining_None, "U" },
- { Joining_Left, "L" },
{ Joining_Causing, "C" },
{ Joining_Dual, "D" },
{ Joining_Right, "R" },
+ { Joining_Left, "L" },
{ Joining_Transparent, "T" },
{ Joining_Unassigned, 0 }
};
@@ -323,7 +356,10 @@ static const char *word_break_class_string =
" WordBreak_Extend,\n"
" WordBreak_RegionalIndicator,\n"
" WordBreak_Katakana,\n"
+ " WordBreak_HebrewLetter,\n"
" WordBreak_ALetter,\n"
+ " WordBreak_SingleQuote,\n"
+ " WordBreak_DoubleQuote,\n"
" WordBreak_MidNumLet,\n"
" WordBreak_MidLetter,\n"
" WordBreak_MidNum,\n"
@@ -339,7 +375,10 @@ enum WordBreakClass {
WordBreak_Extend,
WordBreak_RegionalIndicator,
WordBreak_Katakana,
+ WordBreak_HebrewLetter,
WordBreak_ALetter,
+ WordBreak_SingleQuote,
+ WordBreak_DoubleQuote,
WordBreak_MidNumLet,
WordBreak_MidLetter,
WordBreak_MidNum,
@@ -365,7 +404,10 @@ static void initWordBreak()
{ WordBreak_Extend, "Format" },
{ WordBreak_RegionalIndicator, "Regional_Indicator" },
{ WordBreak_Katakana, "Katakana" },
+ { WordBreak_HebrewLetter, "Hebrew_Letter" },
{ WordBreak_ALetter, "ALetter" },
+ { WordBreak_SingleQuote, "Single_Quote" },
+ { WordBreak_DoubleQuote, "Double_Quote" },
{ WordBreak_MidNumLet, "MidNumLet" },
{ WordBreak_MidLetter, "MidLetter" },
{ WordBreak_MidNum, "MidNum" },
@@ -677,8 +719,8 @@ static const char *property_string =
" ushort category : 8; /* 5 used */\n"
" ushort direction : 8; /* 5 used */\n"
" ushort combiningClass : 8;\n"
- " ushort joining : 2;\n"
- " signed short digitValue : 6; /* 5 used */\n"
+ " ushort joining : 3;\n"
+ " signed short digitValue : 5; /* 5 used */\n"
" signed short mirrorDiff : 16;\n"
" signed short lowerCaseDiff : 16;\n"
" signed short upperCaseDiff : 16;\n"
@@ -750,7 +792,7 @@ struct PropertyFlags {
QChar::Category category : 5;
QChar::Direction direction : 5;
// from ArabicShaping.txt
- QChar::Joining joining : 2;
+ QChar::JoiningType joining : 3;
// from DerivedAge.txt
QChar::UnicodeVersion age : 4;
int digitValue;
@@ -815,6 +857,31 @@ static int appendToSpecialCaseMap(const QList<int> &map)
return pos;
}
+static inline bool isDefaultIgnorable(uint ucs4)
+{
+ // Default_Ignorable_Code_Point:
+ // Generated from
+ // Other_Default_Ignorable_Code_Point + Cf + Variation_Selector
+ // - White_Space - FFF9..FFFB (Annotation Characters)
+ // - 0600..0604, 06DD, 070F, 110BD (exceptional Cf characters that should be visible)
+ if (ucs4 <= 0xff)
+ return ucs4 == 0xad;
+
+ return ucs4 == 0x034f
+ || (ucs4 >= 0x115f && ucs4 <= 0x1160)
+ || (ucs4 >= 0x17b4 && ucs4 <= 0x17b5)
+ || (ucs4 >= 0x180b && ucs4 <= 0x180d)
+ || (ucs4 >= 0x200b && ucs4 <= 0x200f)
+ || (ucs4 >= 0x202a && ucs4 <= 0x202e)
+ || (ucs4 >= 0x2060 && ucs4 <= 0x206f)
+ || ucs4 == 0x3164
+ || (ucs4 >= 0xfe00 && ucs4 <= 0xfe0f)
+ || ucs4 == 0xfeff
+ || ucs4 == 0xffa0
+ || (ucs4 >= 0xfff0 && ucs4 <= 0xfff8)
+ || (ucs4 >= 0x1d173 && ucs4 <= 0xe0fff && (ucs4 <= 0x1d17a || ucs4 >= 0xe0000));
+}
+
struct UnicodeData {
UnicodeData(int codepoint = 0) {
p.category = QChar::Other_NotAssigned; // Cn
@@ -842,6 +909,17 @@ struct UnicodeData {
|| (codepoint >= 0x1EF00 && codepoint <= 0x1EFFF)) {
p.direction = QChar::DirR;
}
+ // The unassigned code points that default to ET are in the range:
+ // [U+20A0..U+20CF]
+ else if (codepoint >= 0x20A0 && codepoint <= 0x20CF) {
+ p.direction = QChar::DirET;
+ }
+ // The unassigned code points that default to BN have one of the following properties:
+ // Default_Ignorable_Code_Point
+ // Noncharacter_Code_Point
+ else if (QChar::isNonCharacter(codepoint) || isDefaultIgnorable(codepoint)) {
+ p.direction = QChar::DirBN;
+ }
p.lineBreakClass = LineBreak_AL; // XX -> AL
// LineBreak.txt
@@ -858,10 +936,15 @@ struct UnicodeData {
|| (codepoint >= 0x30000 && codepoint <= 0x3FFFD)) {
p.lineBreakClass = LineBreak_ID;
}
+ // The unassigned code points that default to "PR" comprise a range in the following block:
+ // [U+20A0..U+20CF]
+ else if (codepoint >= 0x20A0 && codepoint <= 0x20CF) {
+ p.lineBreakClass = LineBreak_PR;
+ }
mirroredChar = 0;
decompositionType = QChar::NoDecomposition;
- p.joining = QChar::OtherJoining;
+ p.joining = QChar::Joining_None;
p.age = QChar::Unicode_Unassigned;
p.mirrorDiff = 0;
p.digitValue = -1;
@@ -1008,7 +1091,10 @@ static void readUnicodeData()
else
++combiningClassUsage[data.p.combiningClass];
- data.p.direction = directionMap.value(properties[UD_BidiCategory], data.p.direction);
+ Direction dir = directionMap.value(properties[UD_BidiCategory], Dir_Unassigned);
+ if (dir == Dir_Unassigned)
+ qFatal("unhandled direction value: %s", properties[UD_BidiCategory].constData());
+ data.p.direction = QChar::Direction(dir);
if (!properties[UD_UpperCase].isEmpty()) {
int upperCase = properties[UD_UpperCase].toInt(&ok, 16);
@@ -1085,7 +1171,7 @@ static void readUnicodeData()
if (d[0].contains('<')) {
data.decompositionType = decompositionMap.value(d[0], QChar::NoDecomposition);
if (data.decompositionType == QChar::NoDecomposition)
- qFatal("unassigned decomposition type: %s", d[0].constData());
+ qFatal("unhandled decomposition type: %s", d[0].constData());
d.takeFirst();
} else {
data.decompositionType = QChar::Canonical;
@@ -1175,24 +1261,34 @@ static void readArabicShaping()
int codepoint = l[0].toInt(&ok, 16);
Q_ASSERT(ok);
- Joining joining = joining_map.value(l[2].trimmed(), Joining_Unassigned);
- if (joining == Joining_Unassigned)
- qFatal("unassigned or unhandled joining value: %s", l[2].constData());
+ UnicodeData &d = UnicodeData::valueRef(codepoint);
+ JoiningType joining = joining_map.value(l[2].trimmed(), Joining_Unassigned);
+ switch (joining) {
+ case Joining_Unassigned:
+ qFatal("%x: unassigned or unhandled joining type: %s", codepoint, l[2].constData());
+ break;
+ case Joining_Transparent:
+ if (d.p.category != QChar::Mark_NonSpacing && d.p.category != QChar::Mark_Enclosing && d.p.category != QChar::Other_Format) {
+ qFatal("%x: joining type '%s' was met; the current implementation needs to be revised!",
+ codepoint, l[2].constData());
+ }
+ // fall through
- if (joining == Joining_Left) {
- // There are currently no characters of joining type Left_Joining defined in Unicode.
- qFatal("%x: joining type '%s' was met; the current implementation needs to be revised!", codepoint, l[2].constData());
+ default:
+ d.p.joining = QChar::JoiningType(joining);
+ break;
}
+ }
+ // Code points that are not explicitly listed in ArabicShaping.txt are either of joining type T or U:
+ // - Those that not explicitly listed that are of General Category Mn, Me, or Cf have joining type T.
+ // - All others not explicitly listed have joining type U.
+ for (int codepoint = 0; codepoint <= QChar::LastValidCodePoint; ++codepoint) {
UnicodeData &d = UnicodeData::valueRef(codepoint);
- if (joining == Joining_Right)
- d.p.joining = QChar::Right;
- else if (joining == Joining_Dual)
- d.p.joining = QChar::Dual;
- else if (joining == Joining_Causing)
- d.p.joining = QChar::Center;
- else
- d.p.joining = QChar::OtherJoining;
+ if (d.p.joining == QChar::Joining_None) {
+ if (d.p.category == QChar::Mark_NonSpacing || d.p.category == QChar::Mark_Enclosing || d.p.category == QChar::Other_Format)
+ d.p.joining = QChar::Joining_Transparent;
+ }
}
}
@@ -2246,10 +2342,10 @@ static QByteArray createPropertyInfo()
// " ushort combiningClass : 8;\n"
out += QByteArray::number( p.combiningClass );
out += ", ";
-// " ushort joining : 2;\n"
+// " ushort joining : 3;\n"
out += QByteArray::number( p.joining );
out += ", ";
-// " signed short digitValue : 6; /* 5 used */\n"
+// " signed short digitValue : 5; /* 5 used */\n"
out += QByteArray::number( p.digitValue );
out += ", ";
// " signed short mirrorDiff : 16;\n"